def redact_message(message, user): real_content = message.get_real_content().replace("\r\n", "\n") redacted_content = message.get_content().replace("\r\n", "\n") c_1, c_2 = split_text_by_separator(real_content) r_1, r_2 = split_text_by_separator(redacted_content) if message.request.user == user or user.is_staff: content_1 = mark_differences(c_1, r_1, attrs=u' class="redacted redacted-hover"' ' data-toggle="tooltip" title="{title}"'.format( title=_('Only visible to you') )) content_2 = mark_differences(c_2, r_2, attrs=u' class="redacted redacted-hover"' ' data-toggle="tooltip" title="{title}"'.format( title=_('Only visible to you') )) else: content_1 = mark_differences(r_1, c_1) content_2 = mark_differences(r_2, c_2) content_1 = urlizetrunc(content_1, 40, autoescape=False) content_2 = urlizetrunc(content_2, 40, autoescape=False) if content_2: return u''.join([ content_1, u'<a href="#" class="show-text">…</a><div class="hidden-text">', content_2, u'</div>' ]) return content_1
def parse(s, type='twitter'): if type == 'twitter': s = s.split(': ', 1)[1] s = hash_tag(s, type) s = at_reply(s, type) s = urlizetrunc(s, 45) return s
def workspace_acceptable(self): allowed_cql_filters = self.featureline_set.filter( visible=True).values_list('name', flat=True) # A ValuesListQuerySet is not serializable to JSON, # A list is. description = self.description or '' # TODO: Do it with a template instead of hacked string tags. if self.metadata: description += '<dl>' for key, value in self.metadata_for_display: description += '<dt>%s</dt><dd>%s</dd>' % ( key, urlizetrunc(value, 35)) description += '</dl>' result = WmsWorkspaceAcceptable( name=self.display_name, description=description, filter_page_url=self.filter_page_url, adapter_layer_json=json.dumps( {'wms_source_id': self.id, 'name': self.layer_name, 'url': self.proxied_url, 'params': self.params, 'legend_url': self.proxied_legend_url, 'options': self.options, 'cql_filters': list(allowed_cql_filters), 'timepositions': self.timepositions, }), adapter_name=ADAPTER_CLASS_WMS) return result
def disarm_user_input(html): """ Returns html without posible harm In addition - urlizes text if no links are used - breaks lines if no paragraphs are used """ html = defaultfilters.removetags(html, "script style comment") # remove javascript events and style attributes from tags re_comments = re.compile(r'<!--[\s\S]*?(-->|$)') re_tags = re.compile(r'(<[^>\s]+)([^>]+)(>)') re_attrs = re.compile( r"""\s+(on[^=]+|style)=([^"'\s]+|"[^"]*"|'[^']*')""", ) def remove_js_events(match): return "".join(( match.group(1), re_attrs.sub('', match.group(2)), match.group(3), )) html = re_comments.sub("", html) html = re_tags.sub(remove_js_events, html) if "</a>" not in html: html = defaultfilters.urlizetrunc(html, "30") if "</p>" not in html: html = defaultfilters.linebreaks(html) html = defaultfilters.safe(html) return html
def test_non_string_input(self): # Filters shouldn't break if passed non-strings self.assertEqual(addslashes(123), '123') self.assertEqual(linenumbers(123), '1. 123') self.assertEqual(lower(123), '123') self.assertEqual(make_list(123), ['1', '2', '3']) self.assertEqual(slugify(123), '123') self.assertEqual(title(123), '123') self.assertEqual(truncatewords(123, 2), '123') self.assertEqual(upper(123), '123') self.assertEqual(urlencode(123), '123') self.assertEqual(urlize(123), '123') self.assertEqual(urlizetrunc(123, 1), '123') self.assertEqual(wordcount(123), 1) self.assertEqual(wordwrap(123, 2), '123') self.assertEqual(ljust('123', 4), '123 ') self.assertEqual(rjust('123', 4), ' 123') self.assertEqual(center('123', 5), ' 123 ') self.assertEqual(center('123', 6), ' 123 ') self.assertEqual(cut(123, '2'), '13') self.assertEqual(escape(123), '123') self.assertEqual(linebreaks_filter(123), '<p>123</p>') self.assertEqual(linebreaksbr(123), '123') self.assertEqual(removetags(123, 'a'), '123') self.assertEqual(striptags(123), '123')
def display_film_link(self, obj): if not obj.film_link: return '---' link = urlizetrunc(obj.film_link, 20) if obj.film_link_pwd: link = '%s<br />Password: %s' % (link, escape(obj.film_link_pwd)) return link
def reshare(self, entry, args={}): sid = args.get('sid', None) as_me = int(args.get('as_me', False)) user = args.get('user', None) un = utcnow() guid = '%s/entry/%s' % (settings.FEED_TAGURI, un.strftime('%Y-%m-%dT%H:%M:%SZ')) if sid: s = Service.objects.get(id=sid, api='selfposts') else: s = Service.objects.filter(api='selfposts').order_by('id')[0] e = Entry(service=s, guid=guid) e.date_published = un e.date_updated = un if as_me: if user and user.first_name and user.last_name: e.author_name = user.first_name + ' ' + user.last_name else: e.author_name = '' e.author_email = '' e.author_uri = '' if entry.service.api == 'greader': e.link = entry.link else: e.link = settings.BASE_URL + '/' if entry.service.api == 'twitter': entry.content = entry.content.split(': ', 1)[1] else: e.author_name = entry.author_name e.author_email = entry.author_email e.author_uri = entry.author_uri e.link = entry.link e.geolat = entry.geolat e.geolng = entry.geolng e.mblob = entry.mblob e.title = entry.title if entry.service.api == 'greader': e.content = '<a href="%s" rel="nofollow">%s</a>' % ( e.link, e.title) elif entry.service.api in ('youtube', 'vimeo'): e.content = '<p>%s</p>%s' % (df_title(e.title), entry.content) else: e.content = urlizetrunc(entry.content, 45) try: media.transform_to_local(e) media.extract_and_register(e) e.save() return e except: pass
def pull_feed(feed_url, posts_to_show=None, cache_expires=None): if not hasattr(settings, 'FB_API_ACCESS_TOKEN'): return [] if posts_to_show is None: posts_to_show = FEEDUTIL_NUM_POSTS if cache_expires is None: cache_expires = FEEDUTIL_CACHE_MIN cachename = 'feed_cache_' + template.defaultfilters.slugify(feed_url) posts = [] data = None if cache_expires > 0: data = cache.get(cachename) if data is None: # load feed try: graph = facebook.GraphAPI( access_token=settings.FB_API_ACCESS_TOKEN, version='2.7') # we need to fetch more than posts_to_show posts since # non-birthday posts are filtered out json_posts = graph.request('/GrandComicsDatabase/posts', args={'fields': 'full_picture, link, message, application,' ' created_time', 'limit': 4*posts_to_show}) entries = json_posts.items()[1][1] if posts_to_show > 0 and len(entries) > posts_to_show: entries = entries[:4*posts_to_show] posts = [{ 'author': 'Grand Comics Database', 'summary_html': summarize_html(entry['message']), 'content': linebreaksbr(urlizetrunc(entry['message'], 75)), 'mail_body': urlquote(entry['message']), 'mail_subject': urlquote('From the %s' % settings.SITE_NAME), 'url': entry['link'], 'picture': entry['full_picture'], 'published': entry['created_time']} for entry in entries if all (k in entry for k in ('message', 'full_picture'))] # one used to get info about application via entry['application'] # post['application']['name'] would filter those from hootsuite # # this is now restricted to admins / or site owner, and it is # not clear how to do that now via the API posts = posts[:posts_to_show] except: if settings.DEBUG: raise return [] if cache_expires > 0: cache.set(cachename, posts, cache_expires*60) else: #load feed from cache posts = data return posts
def parse(self): if not self.soup: return out = [] for tr in select(self.soup, '#content table tr'): td = select(tr, 'td') if len(td) != 3: continue name = select(td[1], 'strong')[0].string msg = urlizetrunc(striptags(select(td[2], 'div')[0].renderContents()), 30) out.append((name, msg)) self.data = out[:]
def test_truncate(self): uri = 'http://31characteruri.com/test/' self.assertEqual(len(uri), 31) self.assertEqual( urlizetrunc(uri, 31), '<a href="http://31characteruri.com/test/" rel="nofollow">' 'http://31characteruri.com/test/</a>', ) self.assertEqual( urlizetrunc(uri, 30), '<a href="http://31characteruri.com/test/" rel="nofollow">' 'http://31characteruri.com/t...</a>', ) self.assertEqual( urlizetrunc(uri, 2), '<a href="http://31characteruri.com/test/"' ' rel="nofollow">...</a>', )
def test_urlizetrunc(self): self.assertEqual(urlizetrunc('http://short.com/', 20), '<a href=' '"http://short.com/" rel="nofollow">http://short.com/</a>') self.assertEqual(urlizetrunc('http://www.google.co.uk/search?hl=en' '&q=some+long+url&btnG=Search&meta=', 20), '<a href="http://' 'www.google.co.uk/search?hl=en&q=some+long+url&btnG=Search&' 'meta=" rel="nofollow">http://www.google...</a>') self.assertEqual(urlizetrunc('http://www.google.co.uk/search?hl=en' '&q=some+long+url&btnG=Search&meta=', 20), '<a href="http://' 'www.google.co.uk/search?hl=en&q=some+long+url&btnG=Search' '&meta=" rel="nofollow">http://www.google...</a>') # Check truncating of URIs which are the exact length uri = 'http://31characteruri.com/test/' self.assertEqual(len(uri), 31) self.assertEqual(urlizetrunc(uri, 31), '<a href="http://31characteruri.com/test/" rel="nofollow">' 'http://31characteruri.com/test/</a>') self.assertEqual(urlizetrunc(uri, 30), '<a href="http://31characteruri.com/test/" rel="nofollow">' 'http://31characteruri.com/t...</a>') self.assertEqual(urlizetrunc(uri, 2), '<a href="http://31characteruri.com/test/"' ' rel="nofollow">...</a>')
def pull_feed(feed_url, posts_to_show=None, cache_expires=None): if not hasattr(settings, 'FB_API_ACCESS_TOKEN'): return [] if posts_to_show is None: posts_to_show = FEEDUTIL_NUM_POSTS if cache_expires is None: cache_expires = FEEDUTIL_CACHE_MIN cachename = 'feed_cache_' + template.defaultfilters.slugify(feed_url) posts = [] data = None if cache_expires > 0: data = cache.get(cachename) if data is None: # load feed try: graph = facebook.GraphAPI( access_token=settings.FB_API_ACCESS_TOKEN, version='2.7') # we need to fetch more than posts_to_show posts since # non-birthday posts are filtered out json_posts = graph.request('/GrandComicsDatabase/posts', args={'fields': 'full_picture, link, message, application,' ' created_time', 'limit': 4*posts_to_show}) entries = json_posts.items()[1][1] if posts_to_show > 0 and len(entries) > posts_to_show: entries = entries[:4*posts_to_show] posts = [{ 'author': 'Grand Comics Database', 'summary_html': summarize_html(entry['message']), 'content': linebreaksbr(urlizetrunc(entry['message'], 75)), 'url': entry['link'], 'picture': entry['full_picture'], 'published': entry['created_time'], 'application': entry['application']} for entry in entries if all (k in entry for k in ('message', 'full_picture', 'application')) ] # only use posts coming via hootsuite for post in reversed(posts): if post['application']['name'] != 'Hootsuite': posts.remove(post) posts = posts[:posts_to_show] except: if settings.DEBUG: raise return [] if cache_expires > 0: cache.set(cachename, posts, cache_expires*60) else: #load feed from cache posts = data return posts
def markup_redacted_content(real_content, redacted_content, authenticated_read=False, message_id=None): c_1, c_2 = split_text_by_separator(real_content) r_1, r_2 = split_text_by_separator(redacted_content) if authenticated_read: content_1 = mark_differences(c_1, r_1, attrs='class="redacted-dummy redacted-hover"' ' data-toggle="tooltip" title="{title}"'.format( title=_('Only visible to you') )) content_2 = mark_differences(c_2, r_2, attrs='class="redacted-dummy redacted-hover"' ' data-toggle="tooltip" title="{title}"'.format( title=_('Only visible to you') )) else: content_1 = mark_differences(r_1, c_1, attrs='class="redacted"') content_2 = mark_differences(r_2, c_2, attrs='class="redacted"') content_1 = urlizetrunc(content_1, 40, autoescape=False) content_2 = urlizetrunc(content_2, 40, autoescape=False) if content_2 and message_id: return mark_safe(''.join([ '<div class="text-content-visible">', content_1, ('</div><a class="btn btn-sm btn-light btn-block" href="#message-footer-{message_id}" data-toggle="collapse" ' ' aria-expanded="false" aria-controls="message-footer-{message_id}">{label}</a>' '<div id="message-footer-{message_id}" class="collapse">' .format( message_id=message_id, label=_('Show the quoted message') )), content_2, '</div>' ])) return mark_safe(content_1)
def highlight_request(message): content = unescape(message.get_content().replace("\r\n", "\n")) description = message.request.description description = description.replace("\r\n", "\n") try: index = content.index(description) except ValueError: return content offset = index + len(description) return mark_safe('<div class="foldin">%s</div><div class="highlight">%s</div><div class="foldin-bottom print-show" style="display:none" id="letter_end">%s</div>' % ( escape(content[:index]), urlizetrunc(escape(description), 40), escape(content[offset:])) )
def convert_to_html(body): if not body: return body return safe( re.sub( r'<a([^>]+)>(?:http|ftp)s?://([^<]+)</a>', '<a\\1>\\2</a>', re.sub( r'<a([^>]+)(?<!target=)>', '<a target="_blank"\\1>', urlizetrunc(re.sub(r'(<br\s*/>)?\n', '<br/>', body, flags=re.IGNORECASE), limit=50, autoescape=False), flags=re.IGNORECASE ), re.IGNORECASE ) )
def rm_facebook_url(text): found = True # the URLs in the feed go via facebook, remove this redirect while(found): pos_first = text.find('<a href="http://l.facebook.com/l.php?u=') if pos_first >= 0: pos_second = pos_first \ + text[pos_first:].find('target="_blank">') \ + len('target="_blank">') pos_third = pos_second + text[pos_second:].find('</a>') text = text[:pos_first] \ + urlizetrunc(text[pos_second:pos_third], 75) \ + text[pos_third + 4:] else: found = False text = text.replace('s130x130', 'p200x200', 1) # some images have /v/ in them, there just the replace above is not enough if text.find('/v/') >= 0: text = text.replace('/v/', '/', 1) return text
def pull_feed(feed_url, posts_to_show=None, cache_expires=None): if not hasattr(settings, 'FB_API_ACCESS_TOKEN'): return [] if posts_to_show is None: posts_to_show = FEEDUTIL_NUM_POSTS if cache_expires is None: cache_expires = FEEDUTIL_CACHE_MIN cachename = 'feed_cache_' + template.defaultfilters.slugify(feed_url) posts = [] data = None if cache_expires > 0: data = cache.get(cachename) if data is None: # load feed try: graph = facebook.GraphAPI(access_token=settings.FB_API_ACCESS_TOKEN) json_posts = graph.request('/GrandComicsDatabase/posts', args={'fields': 'full_picture, link, message', 'limit': 10}) entries = json_posts.items()[1][1] if posts_to_show > 0 and len(entries) > posts_to_show: entries = entries[:posts_to_show] posts = [ { 'author': 'Grand Comics Database', 'mail_body': urlquote(entry['message']), 'mail_subject': urlquote('From the %s' % settings.SITE_NAME), 'summary_html': summarize_html(entry['message']), 'content': linebreaksbr(urlizetrunc(entry['message'], 75)), 'url': entry['link'], 'picture': entry['full_picture'], 'published': entry['created_time'], } for entry in entries if all (k in entry for k in ('message', 'full_picture')) ] except: if settings.DEBUG: raise return [] if cache_expires > 0: cache.set(cachename, posts, cache_expires*60) else: #load feed from cache posts = data return posts
def format_post(value): """ Takes cleaned text from above and creates HTML-formatted, web-friendly version. - converts links to images and video to actual media objects. - Make raw links clickable (and truncated, if necessary). - Converts smilies and markdown to valid HTML. _ Bleaches output (again) to catch any stray HTML inserted by markdown. TO-DO: convert linebreaks """ # convert media links value = convert_links(value) value = urlizetrunc(value, 30) for x in emoticon_replacements: value = value.replace(x[0], '<span class="emoticon-%s"></span>' % x[1]) markedup = markdown.markdown(value).replace('</p>\n<p>', '</p><p>') with_linebreaks = linebreaks(markedup) bleached = bleach.clean(with_linebreaks, tags=ALLOWED_TAGS, attributes=ALLOWED_ATTRIBUTES, strip=True) return mark_safe(bleached)
def rm_facebook_url(text): found = True # the URLs in the feed go via facebook, remove this redirect while(found): pos_first = text.find('<a href="http://www.facebook.com/l.php?u=') if pos_first >= 0: pos_second = pos_first \ + text[pos_first:].find('target="_blank">') \ + len('target="_blank">') pos_third = pos_second + text[pos_second:].find('</a>') text = text[:pos_first] \ + urlizetrunc(text[pos_second:pos_third], 75) \ + text[pos_third + 4:] else: found = False # arguably hackish way of showing larger images from facebook on our page text = text.replace('_s.jpg', '_n.jpg', 1) pos = text.find('hphotos') + len('hphotos') pos = pos + text[pos:].find('/') + 1 text = text[:pos] + 'p200x200/' + text[pos:] return text
def format_text(value): """ Takes cleaned text and creates HTML-formatted, web-friendly version. - converts links to images and video to actual media objects. - Make raw links clickable (and truncated, if necessary). - Converts smilies and markdown to valid HTML. _ Bleaches output (again) to catch any stray HTML inserted by markdown. ALWAYS PASS CLEANED TEXT. """ # convert media links value = convert_links(value) value = urlizetrunc(value, 30) for x in EMOTICON_REPLACEMENTS: value = value.replace(x[0], '<span class="emoticon-{}"></span>'.format(x[1])) markedup = markdown.markdown(value).replace('</p>\n<p>', '</p><p>') with_linebreaks = markedup.replace('\n* ', '<br>* ') bleached = bleach.clean(with_linebreaks, tags=ALLOWED_TAGS, attributes=ALLOWED_ATTRIBUTES, strip=True) return mark_safe(bleached)
def test_query_string(self): self.assertEqual( urlizetrunc('http://www.google.co.uk/search?hl=en&q=some+long+url&btnG=Search&meta=', 20), '<a href="http://www.google.co.uk/search?hl=en&q=some+long+url&btnG=Search&' 'meta=" rel="nofollow">http://www.google...</a>', )
def test_overtruncate(self): self.assertEqual( urlizetrunc('http://short.com/', 20), '<a href=' '"http://short.com/" rel="nofollow">http://short.com/</a>', )
def formatted_msg(self): from textile import textile from django.template.defaultfilters import urlizetrunc return textile(urlizetrunc(self.msg, 20))
def get_urlized_text(self, obj): return insert_magic_links(urlizetrunc(obj.text, 45))
def preview_content_rendered(self): return mark_safe(truncatewords_html(urlizetrunc(self.content_rendered, 30), CONTENT_PREVIEW_WORDS))
def preview_content(self): return truncatewords(urlizetrunc(self.content, 30), CONTENT_PREVIEW_WORDS)
def test_autoescape_off(self): self.assertEqual( urlizetrunc('foo<a href=" google.com ">bar</a>buz', 9, autoescape=False), 'foo<a href=" <a href="http://google.com" rel="nofollow">google...</a> ">bar</a>buz', )
def test_non_string_input(self): self.assertEqual(urlizetrunc(123, 1), '123')
def get_urlized_text(self, obj): return urlizetrunc(obj.text, 45)
def preview_content_rendered(self): return mark_safe( truncatewords_html(urlizetrunc(self.content_rendered, 30), CONTENT_PREVIEW_WORDS))
def display_film_link(self, obj): if not obj.film_link: return '---' return urlizetrunc(obj.film_link, 20)
def test_autoescape(self): self.assertEqual( urlizetrunc('foo<a href=" google.com ">bar</a>buz', 10), 'foo<a href=" <a href="http://google.com" rel="nofollow">google.com</a> ">bar</a>buz' )
def check_resource_view(queryset, test_case): # paths elemenets for which the path is skipped skip_path_elements = ( 'email', 'metaShareId', 'downloadLocation', 'executionLocation', ) # path suffixes where to apply a URL transformation on the value url_paths = ( '/url', '/downloadLocation', '/executionLocation', '/samplesLocation', '/targetResourceNameURI', '/documentation', ) # path suffixes where to apply a number transformation on the value number_paths = ( '/size', '/fee', ) # path suffixes where to apply data transformation on the value date_paths = ( '/metadataCreationDate', '/annotationStartDate', '/annotationEndDate', '/availabilityStartDate', '/availabilityEndDate', '/creationStartDate', '/creationEndDate', '/projectStartDate', '/projectEndDate', '/lastDateUpdated', '/metadataLastDateUpdated', ) count = 0 for _res in queryset: parent_dict = {} _res.export_to_elementtree(pretty=True, parent_dict=parent_dict) count += 1 LOGGER.info("calling {}. resource at {}".format( count, _res.get_absolute_url())) # always create a new client to force a new session client = Client() response = client.get(_res.get_absolute_url(), follow=True) test_case.assertEquals(200, response.status_code) test_case.assertTemplateUsed(response, 'repository/resource_view/lr_view.html') for _ele in parent_dict: if not _ele.text: continue path = path_to_root(_ele, parent_dict) text = smart_str(xml_utils.html_escape(_ele.text.strip()), response._charset) # skip boolean values, as they cannot reasonably be verified if text.lower() in ("true", "false"): continue # check if path should be skipped skip = False for path_ele in skip_path_elements: if path_ele in path: skip = True break if skip: continue # apply number transformation if required for _np in number_paths: if path.endswith(_np): text = unicode(humanize.intcomma(text)).encode("utf-8") if text == '0': skip = True break if skip: continue # apply URL transformation if required for _up in url_paths: if path.endswith( _up) and not path.endswith('identificationInfo/url'): text = unicode(urlizetrunc(text, 23)).encode("utf-8") # apply date transformation if required for _dp in date_paths: if path.endswith(_dp): date_object = datetime.strptime(text, '%Y-%m-%d') text = unicode( date_format(date_object, format='SHORT_DATE_FORMAT', use_l10n=True)).encode("utf-8") real_count = response.content.count(text) beauty_real_count = 0 mime_label_real_count = 0 if real_count == 0: # try with beautified string beauty_real_count = response.content.count( prettify_camel_case_string(text)) if beauty_real_count == 0 and _ele.tag == u"dataFormat": # text may be a mime type, so try to get the label e.g. text/xml -> XML mime_label_real_count = response.content.count( mimetype_label.mimetype_label(text)) if real_count == 0 and beauty_real_count == 0 and mime_label_real_count == 0: test_case.fail(u"missing {}: {}".format(path, _ele.text))
def format_text(value): return twitterize(urlizetrunc(value, 30))
def share(self, args={}): content = args.get('content', '') sid = args.get('sid', None) title = args.get('title', None) link = args.get('link', None) images = args.get('images', None) files = args.get('files', MultiValueDict()) source = args.get('source', '') user = args.get('user', None) un = utcnow() guid = '%s/entry/%s' % (settings.FEED_TAGURI, un.strftime('%Y-%m-%dT%H:%M:%SZ')) if sid: s = Service.objects.get(id=sid, api='selfposts') else: s = Service.objects.filter(api='selfposts').order_by('id')[0] e = Entry(service=s, guid=guid) e.link = link if link else settings.BASE_URL + '/' e.date_published = un e.date_updated = un e.draft = int(args.get('draft', False)) e.friends_only = int(args.get('friends_only', False)) if user and user.first_name and user.last_name: e.author_name = user.first_name + ' ' + user.last_name content = smart_text(content) editor_syntax = getattr(settings, 'EDITOR_SYNTAX', 'markdown') if source == 'bookmarklet': editor_syntax = 'html' if editor_syntax == 'markdown' and markdown: e.content = expand.all(markdown.markdown(content)) else: e.content = expand.all(content.replace('\n', '<br/>')) e.content = urlizetrunc(e.content, 45) e.content = strip_script(e.content) e.content = expand.imgloc(e.content) e.content = smart_text(e.content) if images: thumbs = '\n<p class="thumbnails">\n' for img in images: img = media.save_image(img, force=True, downscale=True) thumbs += """ <a href="%s" rel="nofollow"><img src="%s" alt="thumbnail" /></a>\n""" % ( e.link, img) thumbs += '</p>\n' e.content += thumbs if title: e.title = smart_text(title) else: e.title = truncate.smart(strip_tags(e.content)).strip() if e.title == '': e.title = truncate.smart(strip_tags(content)).strip() mblob = media.mrss_scan(e.content) e.mblob = media.mrss_gen_json(mblob) try: e.save() pictures = [] docs = [] for f in files.getlist('docs'): md = Media(entry=e) md.file.save(f.name, f) md.save() if f.content_type.startswith('image/'): pictures.append((md, f)) else: docs.append((md, f)) if len(pictures): thumbs = '\n<p class="thumbnails">\n' for o in pictures: thumb, orig = media.downsave_uploaded_image(o[0].file) thumbs += ' <a href="%s"><img src="%s" alt="thumbnail" /></a>\n' % ( orig, thumb) mrss = { 'url': orig, 'medium': 'image', 'fileSize': o[1].size } if orig.lower().endswith('.jpg'): mrss['type'] = 'image/jpeg' mblob['content'].append([mrss]) thumbs += '</p>\n' e.content += thumbs if len(docs): doc = '\n<ul class="files">\n' for o in docs: target = '[GLS-UPLOAD]/%s' % o[0].file.name.replace( 'upload/', '') doc += ' <li><a href="%s">%s</a> ' % (target, o[1].name) doc += '<span class="size">%s</span></li>\n' % \ bytes_to_human(o[1].size) mrss = {'url': target, 'fileSize': o[1].size} target = target.lower() if target.endswith('.mp3'): mrss['medium'] = 'audio' mrss['type'] = 'audio/mpeg' elif target.endswith('.ogg'): mrss['medium'] = 'audio' mrss['type'] = 'audio/ogg' elif target.endswith('.avi'): mrss['medium'] = 'video' mrss['type'] = 'video/avi' elif target.endswith('.pdf'): mrss['medium'] = 'document' mrss['type'] = 'application/pdf' else: mrss['medium'] = 'document' mblob['content'].append([mrss]) doc += '</ul>\n' e.content += doc e.mblob = media.mrss_gen_json(mblob) if len(pictures) or len(docs): e.save() media.extract_and_register(e) return e except: pass
def format_text(value): return twitterize(urlizetrunc(markdown(value), 30))
def check_resource_view(queryset, test_case): # paths elemenets for which the path is skipped skip_path_elements = ( 'email', 'metaShareId', 'downloadLocation', 'executionLocation', ) # path suffixes where to apply a URL transformation on the value url_paths = ( '/url', '/downloadLocation', '/executionLocation', '/samplesLocation', '/targetResourceNameURI', '/documentation', ) # path suffixes where to apply a number transformation on the value number_paths = ( '/size', '/fee', ) # path suffixes where to apply data transformation on the value date_paths = ( '/metadataCreationDate', '/annotationStartDate', '/annotationEndDate', '/availabilityStartDate', '/availabilityEndDate', '/creationStartDate', '/creationEndDate', '/projectStartDate', '/projectEndDate', '/lastDateUpdated', '/metadataLastDateUpdated', ) count = 0 for _res in queryset: parent_dict = {} _res.export_to_elementtree(pretty=True, parent_dict=parent_dict) count += 1 LOGGER.info("calling {}. resource at {}".format( count, _res.get_absolute_url())) # always create a new client to force a new session client = Client() response = client.get(_res.get_absolute_url(), follow = True) test_case.assertEquals(200, response.status_code) test_case.assertTemplateUsed(response, 'repository/resource_view/lr_view.html') for _ele in parent_dict: if not _ele.text: continue path = path_to_root(_ele, parent_dict) text = smart_str(xml_utils.html_escape(_ele.text.strip()), response._charset) # skip boolean values, as they cannot reasonably be verified if text.lower() in ("true", "false"): continue # check if path should be skipped skip = False for path_ele in skip_path_elements: if path_ele in path: skip = True break if skip: continue # apply number transformation if required for _np in number_paths: if path.endswith(_np): text = unicode(humanize.intcomma(text)).encode("utf-8") if text == '0': skip = True break if skip: continue # apply URL transformation if required for _up in url_paths: if path.endswith(_up) and not path.endswith('identificationInfo/url'): text = unicode(urlizetrunc(text, 23)).encode("utf-8") # apply date transformation if required for _dp in date_paths: if path.endswith(_dp): date_object = datetime.strptime(text, '%Y-%m-%d') text = unicode( date_format(date_object, format='SHORT_DATE_FORMAT', use_l10n=True)).encode("utf-8") real_count = response.content.count(text) if real_count == 0: # try with beautified string beauty_real_count = response.content.count( prettify_camel_case_string(text)) if real_count == 0 and beauty_real_count == 0: test_case.fail(u"missing {}: {}".format(path, _ele.text))
def test_query_string(self): self.assertEqual( urlizetrunc('http://www.google.co.uk/search?hl=en&q=some+long+url&btnG=Search&meta=', 20), '<a href="http://www.google.co.uk/search?hl=en&q=some+long+url&btnG=Search&' 'meta=" rel="nofollow">http://www.google...</a>', )