##// END OF EJS Templates
Build file search menu on the JS side
neko259 -
r1817:a7727f21 default
parent child Browse files
Show More
1 NO CONTENT: modified file, binary diff hidden
NO CONTENT: modified file, binary diff hidden
@@ -581,6 +581,3 b' msgstr "\xd0\x9c\xd0\xb0\xd0\xba\xd1\x81\xd0\xb8\xd0\xbc\xd0\xb0\xd0\xbb\xd1\x8c\xd0\xbd\xd0\xbe\xd0\xb5 \xd0\xba\xd0\xbe\xd0\xbb\xd0\xb8\xd1\x87\xd0\xb5\xd1\x81\xd1\x82\xd0\xb2\xd0\xbe \xd1\x84\xd0\xb0\xd0\xb9\xd0\xbb\xd0\xbe\xd0\xb2 %(max_files)s."'
581 msgid "Moderation"
581 msgid "Moderation"
582 msgstr "Модерация"
582 msgstr "Модерация"
583
583
584 msgid "Duplicates search"
585 msgstr "Поиск дубликатов"
586
1 NO CONTENT: modified file, binary diff hidden
NO CONTENT: modified file, binary diff hidden
@@ -54,4 +54,8 b' msgid "Server error!"'
54 msgstr "Ошибка сервера!"
54 msgstr "Ошибка сервера!"
55
55
56 msgid "Computing PoW..."
56 msgid "Computing PoW..."
57 msgstr "Расчёт PoW..." No newline at end of file
57 msgstr "Расчёт PoW..."
58
59 msgid "Duplicates search"
60 msgstr "Поиск дубликатов"
61
@@ -77,13 +77,19 b' class AbstractViewer:'
77 return True
77 return True
78
78
79 def get_view(self):
79 def get_view(self):
80 return '<div class="image" id="file{}">'\
80 search_host = settings.get('External', 'ImageSearchHost')
81 if search_host:
82 search_url = search_host + self.file.url
83 else:
84 search_url = ''
85
86 return '<div class="image">'\
81 '{}'\
87 '{}'\
82 '<div class="image-metadata"><a href="{}" download >{}, {}</a>'\
88 '<div class="image-metadata"><a href="{}" download >{}, {}</a>'\
83 ' <a class="file-menu" href="#">🔍 </a></div>'\
89 ' <a class="file-menu" href="#" data-type="{}" data-search-url="{}" data-hash="{}">🔍 </a></div>'\
84 '</div>'.format(self.hash, self.get_format_view(), self.file.url,
90 '</div>'.format(self.get_format_view(), self.file.url,
85 self.file_type, filesizeformat(self.file.size))\
91 self.file_type, filesizeformat(self.file.size),
86 + self._build_context_menu(self.get_context_menu())
92 self.file_type, search_url, self.hash)
87
93
88 def get_format_view(self):
94 def get_format_view(self):
89 image_name = PLAIN_FILE_FORMATS.get(self.file_type, self.file_type)
95 image_name = PLAIN_FILE_FORMATS.get(self.file_type, self.file_type)
@@ -100,26 +106,6 b' class AbstractViewer:'
100 '<img class="url-image" src="{}" width="{}" height="{}"/>'\
106 '<img class="url-image" src="{}" width="{}" height="{}"/>'\
101 '</a>'.format(self.file.url, static(image), w, h)
107 '</a>'.format(self.file.url, static(image), w, h)
102
108
103 def get_context_menu(self):
104 items = []
105 items.append({
106 'name': 'duplicates',
107 'label': _('Duplicates search'),
108 'url': reverse('feed') + '?image_hash=' + self.hash,
109 })
110
111 return items
112
113 def _build_context_menu(self, items):
114 if not items:
115 return ''
116
117 cm_items = []
118 for item in items:
119 cm_items.append(('{}: {{name: "{}", callback: function(key, opt) {{window.location="{}";}}}}')\
120 .format(item['name'], item['label'], item['url']))
121 return '<script>$.contextMenu({{trigger: "left", selector: "#file{} .file-menu", build: function($trigger, e) {{return {{items: {{ {} }} }}}}}});</script>'.format(self.hash, ', '.join(cm_items))
122
123
109
124 class VideoViewer(AbstractViewer):
110 class VideoViewer(AbstractViewer):
125 @staticmethod
111 @staticmethod
@@ -183,31 +169,6 b' class ImageViewer(AbstractViewer):'
183 str(pre_height), str(width), str(height),
169 str(pre_height), str(width), str(height),
184 full=self.file.url, image_meta=metadata)
170 full=self.file.url, image_meta=metadata)
185
171
186 def get_context_menu(self):
187 items = super().get_context_menu()
188
189 image_host = settings.get('External', 'ImageSearchHost')
190 if image_host:
191 image_url = image_host + self.file.url
192
193 items.append({
194 'name': 'google',
195 'label': 'Google',
196 'url': 'https://www.google.com/searchbyimage?image_url={}'.format(image_url),
197 })
198 items.append({
199 'name': 'iqdb',
200 'label': 'iqdb',
201 'url': 'http://iqdb.org/?url={}'.format(image_url)
202 })
203 items.append({
204 'name': 'tineye',
205 'label': 'TinEye',
206 'url': 'http://tineye.com/search?url={}'.format(image_url)
207 })
208
209 return items
210
211
172
212 class UrlViewer(AbstractViewer):
173 class UrlViewer(AbstractViewer):
213 @staticmethod
174 @staticmethod
@@ -240,9 +201,6 b' class UrlViewer(AbstractViewer):'
240 '<img class="url-image" src="{}" width="{}" height="{}"/>' \
201 '<img class="url-image" src="{}" width="{}" height="{}"/>' \
241 '</a>'.format(self.url, image, w, h)
202 '</a>'.format(self.url, image, w, h)
242
203
243 def get_context_menu(self):
244 return []
245
246 @cached_result()
204 @cached_result()
247 def _find_image_for_domains(self, domain):
205 def _find_image_for_domains(self, domain):
248 """
206 """
@@ -24,6 +24,7 b''
24 */
24 */
25
25
26 var ITEM_VOLUME_LEVEL = 'volumeLevel';
26 var ITEM_VOLUME_LEVEL = 'volumeLevel';
27 var IMAGE_TYPES = ['png', 'jpg', 'jpeg', 'bmp'];
27
28
28 /**
29 /**
29 * An email is a hidden file to prevent spam bots from posting. It has to be
30 * An email is a hidden file to prevent spam bots from posting. It has to be
@@ -150,6 +151,50 b' function compatibilityCrutches() {'
150 }
151 }
151 }
152 }
152
153
154 function addContextMenu() {
155 $.contextMenu({
156 selector: '.file-menu',
157 trigger: 'left',
158
159 build: function($trigger, e) {
160 var fileSearchUrl = $trigger.data('search-url');
161 var isImage = IMAGE_TYPES.indexOf($trigger.data('type')) > -1;
162 var hasUrl = fileSearchUrl.length > 0;
163 return {
164 items: {
165 duplicates: {
166 name: gettext('Duplicates search'),
167 callback: function(key, opts) {
168 window.location = '/feed/?image_hash=' + $trigger.data('hash');
169 }
170 },
171 google: {
172 name: 'Google',
173 visible: isImage && hasUrl,
174 callback: function(key, opts) {
175 window.location = 'https://www.google.com/searchbyimage?image_url=' + fileSearchUrl;
176 }
177 },
178 iqdb: {
179 name: 'IQDB',
180 visible: isImage && hasUrl,
181 callback: function(key, opts) {
182 window.location = 'http://iqdb.org/?url=' + fileSearchUrl;
183 }
184 },
185 tineye: {
186 name: 'TinEye',
187 visible: isImage && hasUrl,
188 callback: function(key, opts) {
189 window.location = 'http://tineye.com/search?url=' + fileSearchUrl;
190 }
191 }
192 },
193 };
194 }
195 });
196 }
197
153 $( document ).ready(function() {
198 $( document ).ready(function() {
154 hideEmailFromForm();
199 hideEmailFromForm();
155
200
@@ -169,5 +214,7 b' function compatibilityCrutches() {'
169 var volumeUsers = $("video,audio");
214 var volumeUsers = $("video,audio");
170 processVolumeUser(volumeUsers);
215 processVolumeUser(volumeUsers);
171
216
217 addContextMenu();
218
172 compatibilityCrutches();
219 compatibilityCrutches();
173 });
220 });
General Comments 0
You need to be logged in to leave comments. Login now