##// END OF EJS Templates
Fixed image search by google. Added duplicates search for images
neko259 -
r1802:5f0f8146 default
parent child Browse files
Show More
@@ -1,45 +1,48 b''
1 1 [Version]
2 2 Version = 4.0.0 2017
3 3 SiteName = Neboard DEV
4 4
5 5 [Cache]
6 6 # Timeout for caching, if cache is used
7 7 CacheTimeout = 600
8 8
9 9 [Forms]
10 10 # Max post length in characters
11 11 MaxTextLength = 30000
12 12 MaxFileSize = 8000000
13 13 LimitFirstPosting = true
14 14 LimitPostingSpeed = false
15 15 PowDifficulty = 0
16 16 # Delay in seconds
17 17 PostingDelay = 30
18 18 Autoban = false
19 19 DefaultTag = test
20 20 MaxFileCount = 1
21 21
22 22 [Messages]
23 23 # Thread bumplimit
24 24 MaxPostsPerThread = 10
25 25 ThreadArchiveDays = 300
26 26 AnonymousMode = false
27 27
28 28 [View]
29 29 DefaultTheme = md
30 30 DefaultImageViewer = simple
31 31 LastRepliesCount = 3
32 32 ThreadsPerPage = 3
33 33 PostsPerPage = 10
34 34 ImagesPerPageGallery = 20
35 35 MaxFavoriteThreads = 20
36 36 MaxLandingThreads = 20
37 37 Themes=md:Mystic Dark,md_centered:Mystic Dark (centered),sw:Snow White,pg:Photon Grey,ad:Amanita Dark,iw:Inocibe White
38 38 ImageViewers=simple:Simple,popup:Popup
39 39
40 40 [Storage]
41 41 # Enable archiving threads instead of deletion when the thread limit is reached
42 42 ArchiveThreads = true
43 43
44 44 [RSS]
45 45 MaxItems = 20
46
47 [External]
48 ImageSearchHost=http://127.0.0.1/
@@ -1,39 +1,40 b''
1 1 {% extends "boards/thread.html" %}
2 2
3 3 {% load i18n %}
4 4 {% load static from staticfiles %}
5 5 {% load board %}
6 6 {% load tz %}
7 7
8 8 {% block head %}
9 9 <meta name="robots" content="noindex">
10 10 <title>{{ thread.get_opening_post.get_title|striptags|truncatewords:10 }}
11 11 - {{ site_name }}</title>
12 12 {% endblock %}
13 13
14 14 {% block thread_content %}
15 15 {% get_current_language as LANGUAGE_CODE %}
16 16 {% get_current_timezone as TIME_ZONE %}
17 17
18 18 <div id="posts-table">
19 19 {% if posts %}
20 20 {% for post in posts %}
21 21 {% for image in post.get_images %}
22 22 <div class="gallery_image">
23 23 {% autoescape off %}
24 24 {{ image.get_view }}
25 25 <div class="gallery_image_metadata">
26 26 {{ image.get_size.0 }}x{{ image.get_size.1 }}
27 {% image_actions image.file.url request.get_host %}
27 {% image_actions image.file.url %},
28 [<a href="{% url 'feed' %}?image_hash={{ image.hash }}">{{ site_name }}</a>]
28 29 <br />
29 30 <a href="{{ post.get_absolute_url }}">>>{{ post.id }}</a>
30 31 </div>
31 32 {% endautoescape %}
32 33 </div>
33 34 {% endfor %}
34 35 {% endfor %}
35 36 {% else %}
36 37 {% trans 'No images.' %}
37 38 {% endif %}
38 39 </div>
39 40 {% endblock %}
@@ -1,119 +1,123 b''
1 1 import re
2 2
3 3 from django.shortcuts import get_object_or_404
4 4 from django import template
5 5 from django.utils.text import re_tag
6 from django.core.urlresolvers import reverse
6 7
7 8 from boards.mdx_neboard import LINE_BREAK_HTML
9 from boards import settings
8 10
9 11
10 12 IMG_ACTION_URL = '[<a href="{}">{}</a>]'
11 13 REGEX_NEWLINE = re.compile(LINE_BREAK_HTML)
12 14 TRUNCATOR = '...'
13 15 HTML4_SINGLETS =(
14 16 'br', 'col', 'link', 'base', 'img', 'param', 'area', 'hr', 'input'
15 17 )
16 18
17 19
18 20 register = template.Library()
19 21
20 22 actions = [
21 23 {
22 24 'name': 'google',
23 'link': 'http://google.com/searchbyimage?image_url=%s',
25 'link': 'https://www.google.com/searchbyimage?image_url={}',
24 26 },
25 27 {
26 28 'name': 'iqdb',
27 'link': 'http://iqdb.org/?url=%s',
29 'link': 'http://iqdb.org/?url={}',
28 30 },
29 31 ]
30 32
31 33
32 34 @register.simple_tag(name='post_url')
33 35 def post_url(*args, **kwargs):
34 36 post_id = args[0]
35 37
36 38 post = get_object_or_404('Post', id=post_id)
37 39
38 40 return post.get_absolute_url()
39 41
40 42
41 43 @register.simple_tag(name='image_actions')
42 44 def image_actions(*args, **kwargs):
43 45 image_link = args[0]
44 if len(args) > 1:
45 image_link = 'http://' + args[1] + image_link # TODO https?
46 host = settings.get('External', 'ImageSearchHost')
47 if host.endswith('/'):
48 host = host[:-1]
49 image_link = settings.get('External', 'ImageSearchHost') + image_link
46 50
47 51 return ', '.join([IMG_ACTION_URL.format(
48 action['link'] % image_link, action['name']) for action in actions])
52 action['link'].format(image_link), action['name']) for action in actions])
49 53
50 54
51 55 @register.inclusion_tag('boards/post.html', name='post_view', takes_context=True)
52 56 def post_view(context, post, *args, **kwargs):
53 57 kwargs['perms'] = context['perms']
54 58 return post.get_view_params(*args, **kwargs)
55 59
56 60
57 61 @register.simple_tag(name='page_url')
58 62 def page_url(paginator, page_number, *args, **kwargs):
59 63 if paginator.supports_urls():
60 64 return paginator.get_page_url(page_number)
61 65
62 66
63 67 @register.filter(name='truncatenewlines_html')
64 68 def truncatenewlines_html(value, arg):
65 69 end_pos = 0
66 70 start_pos = 0
67 71 match_count = 0
68 72
69 73 # Collect places for truncation
70 74 while match_count <= arg:
71 75 m = REGEX_NEWLINE.search(value, end_pos)
72 76 if m is None:
73 77 break
74 78 else:
75 79 match_count += 1
76 80 end_pos = m.end()
77 81 start_pos = m.start()
78 82
79 83 # Find and close open tags
80 84 if match_count > arg:
81 85 truncate_pos = start_pos
82 86
83 87 open_tags = []
84 88 text = value[:truncate_pos]
85 89 current_pos = 0
86 90 while True:
87 91 tag = re_tag.search(text, current_pos)
88 92 if tag is None:
89 93 break
90 94 else:
91 95 closing_tag, tagname, self_closing = tag.groups()
92 96 tagname = tagname.lower()
93 97 if self_closing or tagname in HTML4_SINGLETS:
94 98 pass
95 99 elif closing_tag:
96 100 # Check for match in open tags list
97 101 try:
98 102 i = open_tags.index(tagname)
99 103 except ValueError:
100 104 pass
101 105 else:
102 106 # SGML: An end tag closes, back to the matching start tag,
103 107 # all unclosed intervening start tags with omitted end tags
104 108 open_tags = open_tags[i + 1:]
105 109 else:
106 110 # Add it to the start of the open tags list
107 111 open_tags.insert(0, tagname)
108 112
109 113 current_pos = tag.end()
110 114
111 115 if not text.endswith(TRUNCATOR):
112 116 text += TRUNCATOR
113 117 for tag in open_tags:
114 118 text += '</{}>'.format(tag)
115 119 else:
116 120 text = value
117 121
118 122 return text
119 123
@@ -1,74 +1,123 b''
1 1 from django.core.urlresolvers import reverse
2 2 from django.shortcuts import render
3 3
4 4 from boards import settings
5 5 from boards.abstracts.paginator import get_paginator
6 6 from boards.abstracts.settingsmanager import get_settings_manager
7 7 from boards.models import Post
8 8 from boards.views.base import BaseBoardView
9 9 from boards.views.posting_mixin import PostMixin
10 10
11 11 POSTS_PER_PAGE = settings.get_int('View', 'PostsPerPage')
12 12
13 13 PARAMETER_CURRENT_PAGE = 'current_page'
14 14 PARAMETER_PAGINATOR = 'paginator'
15 15 PARAMETER_POSTS = 'posts'
16 16
17 17 PARAMETER_PREV_LINK = 'prev_page_link'
18 18 PARAMETER_NEXT_LINK = 'next_page_link'
19 19
20 20 TEMPLATE = 'boards/feed.html'
21 21 DEFAULT_PAGE = 1
22 22
23 23
24 class FeedFilter:
25 @staticmethod
26 def get_filtered_posts(request, posts):
27 return posts
28
29
30 class TripcodeFilter(FeedFilter):
31 @staticmethod
32 def get_filtered_posts(request, posts):
33 filtered_posts = posts
34 tripcode = request.GET.get('tripcode', None)
35 if tripcode:
36 filtered_posts = filtered_posts.filter(tripcode)
37 return filtered_posts
38
39
40 class FavoritesFilter(FeedFilter):
41 @staticmethod
42 def get_filtered_posts(request, posts):
43 filtered_posts = posts
44
45 favorites = 'favorites' in request.GET
46 if favorites:
47 settings_manager = get_settings_manager(request)
48 fav_thread_ops = Post.objects.filter(id__in=settings_manager.get_fav_threads().keys())
49 fav_threads = [op.get_thread() for op in fav_thread_ops]
50 filtered_posts = filtered_posts.filter(thread__in=fav_threads)
51 return filtered_posts
52
53
54 class IpFilter(FeedFilter):
55 @staticmethod
56 def get_filtered_posts(request, posts):
57 filtered_posts = posts
58
59 ip = request.GET.get('ip', None)
60 if ip and request.user.has_perm('post_delete'):
61 filtered_posts = filtered_posts.filter(poster_ip=ip)
62 return filtered_posts
63
64
65 class HashFilter(FeedFilter):
66 @staticmethod
67 def get_filtered_posts(request, posts):
68 filtered_posts = posts
69
70 image_hash = request.GET.get('image_hash', None)
71 if image_hash:
72 filtered_posts = filtered_posts.filter(attachments__hash=image_hash)
73 return filtered_posts
74
75
24 76 class FeedView(PostMixin, BaseBoardView):
77 filters = (
78 TripcodeFilter,
79 FavoritesFilter,
80 IpFilter,
81 HashFilter,
82 )
25 83
26 84 def get(self, request):
27 85 page = request.GET.get('page', DEFAULT_PAGE)
28 tripcode = request.GET.get('tripcode', None)
29 favorites = 'favorites' in request.GET
30 ip = request.GET.get('ip', None)
31 86
32 87 params = self.get_context_data(request=request)
33 88
34 89 settings_manager = get_settings_manager(request)
35 90
36 91 posts = Post.objects.exclude(
37 92 thread__tags__in=settings_manager.get_hidden_tags()).order_by(
38 93 '-pub_time').prefetch_related('attachments', 'thread')
39 if tripcode:
40 posts = posts.filter(tripcode=tripcode)
41 if favorites:
42 fav_thread_ops = Post.objects.filter(id__in=settings_manager.get_fav_threads().keys())
43 fav_threads = [op.get_thread() for op in fav_thread_ops]
44 posts = posts.filter(thread__in=fav_threads)
45 if ip and request.user.has_perm('post_delete'):
46 posts = posts.filter(poster_ip=ip)
94 for filter in self.filters:
95 posts = filter.get_filtered_posts(request, posts)
47 96
48 97 paginator = get_paginator(posts, POSTS_PER_PAGE)
49 98 paginator.current_page = int(page)
50 99
51 100 params[PARAMETER_POSTS] = paginator.page(page).object_list
52 101
53 102 paginator.set_url(reverse('feed'), request.GET.dict())
54 103
55 104 self.get_page_context(paginator, params, page)
56 105
57 106 return render(request, TEMPLATE, params)
58 107
59 108 # TODO Dedup this into PagedMixin
60 109 def get_page_context(self, paginator, params, page):
61 110 """
62 111 Get pagination context variables
63 112 """
64 113
65 114 params[PARAMETER_PAGINATOR] = paginator
66 115 current_page = paginator.page(int(page))
67 116 params[PARAMETER_CURRENT_PAGE] = current_page
68 117 if current_page.has_previous():
69 118 params[PARAMETER_PREV_LINK] = paginator.get_page_url(
70 119 current_page.previous_page_number())
71 120 if current_page.has_next():
72 121 params[PARAMETER_NEXT_LINK] = paginator.get_page_url(
73 122 current_page.next_page_number())
74 123
General Comments 0
You need to be logged in to leave comments. Login now