def generate_feed(gallery, medias, feed_type=None, feed_url='', nb_items=0): root_album = gallery.albums['.'] cls = Rss201rev2Feed if feed_type == 'rss' else Atom1Feed feed = cls( title=Markup.escape(root_album.title), link='/', feed_url=feed_url, description=Markup.escape(root_album.description).striptags() ) nb_medias = len(medias) nb_items = min(nb_items, nb_medias) if nb_items > 0 else nb_medias for item in medias[:nb_items]: feed.add_item( title=Markup.escape(item.title or item.url), link='%s/#%s' % (item.path, item.url), # unique_id='tag:%s,%s:%s' % (urlparse(link).netloc, # item.date.date(), # urlparse(link).path.lstrip('/')), description='<img src="%s/%s" />' % (item.path, item.thumbnail), # categories=item.tags if hasattr(item, 'tags') else None, author_name=getattr(item, 'author', ''), pubdate=item.date or datetime.now(), ) output_file = os.path.join(root_album.dst_path, feed_url.split('/')[-1]) logger.info('Generate %s feeds: %s', feed_type.upper(), output_file) encoding = 'utf-8' if not compat.PY2 else None with codecs.open(output_file, 'w', encoding) as f: feed.write(f, 'utf-8')
def get_links(self): """get all the news links in the page """ soup = BeautifulSoup(self.page) vote = 0 infos = [] links = [] for link in soup.find_all('a'): l = link['href'] if l.startswith('vote'): vote = 1 elif vote == 1: if l.startswith("item"): l = "%s/%s" % (self.surl, l) infos = [Markup.escape(link.string), Markup.escape(l.strip()), date_internet(datetime.now())] time.sleep(1) vote = 2 elif l.startswith('item') and vote == 2: infos.append("%s/%s" % (self.surl, l)) infos.append(uuid3(NAMESPACE_DNS, infos[1])) links.append(infos) vote = 0 return links
def toRSSItem(self): title = self.repo.tagname if self.message and len(self.message) > 50: title += " - " + str(Markup.escape(self.message[:50])) + "..." elif self.message: title += " - " + str(Markup.escape(self.message)) if self.dbkeywords: title += " - " + ",".join(self.dbkeywords) description = "<pre>" description += str(self.getpprint(True)) description += "</pre>" if type(title) != unicode: title = unicode(title, 'utf-8') if type(description) != unicode: description = unicode(description, 'utf-8') title = unicodedata.normalize('NFKD', title).encode('ascii', 'ignore') description = unicodedata.normalize('NFKD', description).encode('ascii', 'ignore') guid = Config.rooturl + "/commit/" + self.repo.tagname + "/" + self.uniqueid link = '' if self.repo.viewlink: link = self.repo.viewlink.replace('%ID', self.uniqueid) else: link = guid item = RSSItem( title = title, link = link, description = description, guid = Guid(guid, isPermaLink=0), pubDate = unixToDatetime(self.date) ) return item
def get_notes(task_id): ''' Get one or more analyst notes/comments associated with the specified task. ''' task = db.get_task(task_id) if not task: abort(HTTP_NOT_FOUND) if 'ts' in request.args and 'uid' in request.args: ts = request.args.get('ts', '') uid = request.args.get('uid', '') response = handler.get_notes(task.sample_id, [ts, uid]) else: response = handler.get_notes(task.sample_id) if not response: abort(HTTP_BAD_REQUEST) if 'hits' in response and 'hits' in response['hits']: response = response['hits']['hits'] try: for hit in response: hit['_source']['text'] = Markup.escape(hit['_source']['text']) except Exception as e: # TODO: log exception pass return jsonify(response)
def install(request): addon_id = request.GET.get('addon_id', None) if addon_id: try: addon_id = int(addon_id) except ValueError: addon_id = Markup.escape(addon_id) addon_key = request.GET.get('addon_key', None) addon_name = request.GET.get('addon_name', None) if addon_id in addons: addon = addons[addon_id] elif addon_key in addons: addon = addons[addon_key] elif addon_name and addon_id: xpi = prefix('/en-US/firefox/downloads/latest/%s') % addon_id icon = prefix('/en-US/firefox/images/addon_icon/%s') % addon_id addon = {'name': addon_name, 'xpi': xpi, 'icon': icon} else: return HttpResponseNotFound() addon_link = addon.get('link', None) if addon_link: return HttpResponsePermanentRedirect(addon_link) if 'xpi' not in addon: return HttpResponseNotFound() src = request.GET.get('src', 'installservice') addon['xpi'] = urlparams(addon['xpi'], src=src) addon_params = {'URL': addon['xpi']} if 'icon' in addon: addon_params['IconURL'] = addon['icon'] if 'hash' in addon: addon_params['Hash'] = addon['hash'] referrers = ' || '.join(addon.get('referrers', default_referrers)) return render(request, 'services/install.html', {'referrers': referrers, 'addon': addon, 'params': json.dumps({'name': addon_params})})
def get_default_meta_description(cls, article): summary = Markup(article.summary).striptags() description = textwrap.wrap(summary, META_DESCRIPTION_LENGTH)[0] description = Markup.escape(description) if len(summary) > META_DESCRIPTION_LENGTH: return description + '...' else: return description
def _convert_out(v, o=None): if getattr(filter_func, "is_safe", False) and isinstance(o, SafeData): v = mark_safe(v) elif isinstance(o, EscapeData): v = mark_for_escaping(v) if isinstance(v, SafeData): return Markup(v) if isinstance(v, EscapeData): return Markup.escape(v) # not 100% equivalent, see mod docs return v
def get_escaped_var_value(value): """ Encodes XML reserved chars in value (eg. &, <, >) and also replaces the control chars \n and \t control chars to their ODF counterparts. """ value = Markup.escape(value) return ( value.replace('\n', Markup('<text:line-break/>')) .replace('\t', Markup('<text:tab/>')) .replace('\x0b', '<text:space/>') .replace('\x0c', '<text:space/>') )
def tweet_content(s): def user_url(match): user_id = match.group(1) return Markup(u'<a href="%s">@%s</a>') % (Markup.escape(url_for('user', user_id=user_id.lower())), Markup.escape(user_id)) def tag_url(match): tag_id = match.group(1) return Markup(u'<a href="%s">#%s</a>') % (Markup.escape(url_for('tag', tag_id=tag_id.lower())), Markup.escape(tag_id)) content = Markup.escape(s) content = Markup(re.sub(r'@([a-zA-Z]+)', user_url, content)) content = Markup(re.sub(r'(?<!&)#([a-zA-Z0-9_]+)', tag_url, content)) return content
def create_meta_attribute(cls, article): article.meta = { 'canonical': cls.get_canonical(article), } for key in META_ATTRIBUTES: article_attrib = "meta_%s" % key if hasattr(article, article_attrib): meta_value = Markup.escape(getattr(article, article_attrib)) else: meta_value = getattr(cls, "get_default_%s" % article_attrib)(article) article.meta[key] = meta_value
def getpprint(self, htmlize=False): if not self.initialized: raise Exception("called getpprint on unitialized Commit object") if htmlize: process = lambda x : Markup.escape(x) else: process = lambda x : x eol = "\r\n" s = "" s += "Project:\t %s%s" % (self.repo.name, eol) if htmlize: s += "Project URL:\t <a href=\"%s\">%s</a>%s" % (self.repo.url, self.repo.url, eol) else: s += "Project URL:\t %s %s" % (self.repo.url, eol) s += "Commit Date:\t %s (%s)%s" % (unixToGitDateFormat(self.date), self.date, eol) s += "Log Message:\t %s%s" % (process(self.message), eol) s += eol + eol if self.files: s += "Files:\t\t %s%s" % (process(self.files[0]), eol) for p in self.files[1:14]: s += "\t\t %s%s" % (process(p), eol) if len(self.files) > 15: s += "\t\t ...%s" % (eol) if self.base_paths: plural = len(self.base_paths) > 1 s += "Base Path%s:\t %s%s" % ("s" if plural else "", process(self.base_paths[0]), eol) for p in self.base_paths[1:]: s += "\t\t %s%s" % (process(p), eol) s += "Keywords:\t %s%s" % (", ".join(self.keywords), eol) s += "ID:\t\t %s%s" % (self.uniqueid, eol) internallink = Config.rooturl + "/commit/" + self.repo.tagname + "/" + self.uniqueid if htmlize: s += "Internal:\t <a href=\"%s\">%s</a>%s" % (internallink, internallink, eol) else: s += "Internal:\t %s%s" % (internallink, eol) if self.repo.viewlink: externallink = self.repo.viewlink.replace('%ID', self.uniqueid) if htmlize: s += "External:\t <a href=\"%s\">%s</a>%s" % (externallink, externallink, eol) else: s += "External:\t %s%s" % (externallink, eol) if htmlize: return Markup(s) else: return s
def _render(self, context): result = { 'filters': sorted(self.environment.filters.keys()), 'tests': sorted(self.environment.tests.keys()), 'context': context.get_all() } # # We set the depth since the intent is basically to show the top few # names. TODO: provide user control over this? # if sys.version_info[:2] >= (3, 4): text = pprint.pformat(result, depth=3, compact=True) else: text = pprint.pformat(result, depth=3) text = Markup.escape(text) return text
def render(self, show_title=False, extra_css=None, closing_tag=True, tag='a', **kw): title = kw.get('title') or self.title attrs = { 'title': title, 'class': ' '.join(['icon', extra_css or '']).strip(), } if tag == 'a': attrs['href'] = '#' attrs.update(kw) attrs = ew._Jinja2Widget().j2_attrs(attrs) visible_title = u'' if show_title: visible_title = u' {}'.format(Markup.escape(title)) closing_tag = u'</{}>'.format(tag) if closing_tag else u'' icon = u'<{} {}><i class="{}"></i>{}{}'.format(tag, attrs, self.css, visible_title, closing_tag) return Markup(icon)
def _list_entry(self, context, model, name): parsed_url = urlparse(model.url) netloc, scheme = parsed_url.netloc, parsed_url.scheme is_scheme_valid = scheme in ('http', 'https') tag_text = [] tag_tmpl = '<a class="btn btn-default" href="{1}">{0}</a>' for tag in model.tags.split(','): if tag: tag_text.append(tag_tmpl.format(tag, url_for( 'bookmark.index_view', flt2_tags_contain=tag))) if not netloc: return Markup("""\ {0.title}<br/>{2}<br/>{1}{0.description} """.format( model, ''.join(tag_text), Markup.escape(model.url) )) netloc_tmpl = '<img src="{}{}"/> ' res = netloc_tmpl.format( 'http://www.google.com/s2/favicons?domain=', netloc) title = model.title if model.title else '<EMPTY TITLE>' if is_scheme_valid: res += '<a href="{0.url}">{1}</a>'.format(model, title) else: res += title if self.url_render_mode == 'netloc': res += ' (<a href="{1}">{0}</a>)'.format( netloc, url_for('bookmark.index_view', flt2_url_netloc_match=netloc) ) res += '<br/>' if not is_scheme_valid: res += model.url elif self.url_render_mode is None or self.url_render_mode == 'full': res += '<a href="{0.url}">{0.url}</a>'.format(model) res += '<br/>' if self.url_render_mode != 'netloc': res += tag_tmpl.format( 'netloc:{}'.format(netloc), url_for('bookmark.index_view', flt2_url_netloc_match=netloc) ) res += ''.join(tag_text) description = model.description if description: res += '<br/>' res += description.replace('\n', '<br/>') return Markup(res)
def streamer_page(streamer_name, page): streamer = Streamer.query.filter_by(reddit_username=streamer_name).first_or_404() wpc_stream = streamer.streams.filter_by(type='wpc_stream').first() streams = streamer.streams if wpc_stream: streams = streams.filter(Stream.id != wpc_stream.id) streams = streams.order_by(Stream.actual_start_time.desc().nullslast()).paginate(page, per_page=5) info_form = EditStreamerInfoForm(prefix='info') title_form = EditStreamTitleForm(prefix='title') if current_user.is_authenticated() and current_user == streamer: if request.method == 'POST': if info_form.submit_button.data: if info_form.validate_on_submit(): current_user.populate(info_form) db.session.commit() flash("Updated successfully", category='success') return redirect(url_for('.streamer_page', streamer_name=streamer_name, page=page)) else: return render_template('streamer.html', streamer=streamer, streams=streams, info_form=info_form, title_form=title_form, edit_info=True, edit_title=False, wpc_stream=wpc_stream) elif title_form.submit_button.data: if title_form.validate_on_submit(): wpc_stream.title = title_form.title.data db.session.commit() return jsonify(newTitle=Markup.escape(title_form.title.data)) else: return render_template('streamer.html', streamer=streamer, streams=streams, info_form=info_form, title_form=title_form, edit_info=False, edit_title=True, wpc_stream=wpc_stream) else: info_form.youtube_channel.data = current_user.youtube_channel info_form.twitch_channel.data = current_user.twitch_channel info_form.info.data = current_user.info if wpc_stream: title_form.title.data = wpc_stream.title return render_template('streamer.html', streamer=streamer, streams=streams, info_form=info_form, title_form=title_form, edit_info=False, edit_title=False, wpc_stream=wpc_stream)
def share_fundopp(self, request, id_=None): '''Import information about a funding opportunity into the index.''' tmpl = util.clean_list(request.values.getlist('useful_links[]')) useful_links = [] for link in tmpl: useful_links.append(util.prep_link(link)) if not id_: id_ = util.slug_id(request.values["title"]) record = { "funder": request.values.get("funder", ''), "title": request.values["title"], "residency": request.values.get("residency"), "gender": request.values.get("gender"), "id": id_, "url": util.prep_link(request.values.get("url",'')), "description": Markup.escape(request.values.get("more_info",'')), "issue_date": request.values.get('issue_date',None), "closing_date": request.values.get('closing_date',None), "funds": request.values.get('funds',''), "funds_exactly_or_upto": request.values.get('funds_exactly_or_upto',''), "useful_links": useful_links, "tags": util.clean_list(request.values.get("tags",'').split(",")), "subjects": util.clean_list(request.values.get("subjects",'').split(",")), "created": datetime.now().isoformat(), "modified": datetime.now().isoformat(), "owner": self.owner.id, "license": CROWDSOURCE_CONTRIB_LICENSE, "origin": "Crowdsourced", "origin_method": "crowdsourced" } # cause ElasticSearch exceptions if null or empty string # so just remove them from the document if not record['issue_date']: del record['issue_date'] if not record['closing_date']: del record['closing_date'] fundfind.dao.FundingOpp.upsert(record) return id_
def contact_form(): is_modal = request.args.get('modal', default=0, type=int) if request.method == "GET": return render_template("contact.html", is_modal=is_modal) field_src = request.args if request.method == "POST": field_src = request.form msg = {"msg": "Your message has been registred.", "category": "success"} try: contact = dict( user_agent = str(request.user_agent), remote_addr = request.remote_addr, created = arrow.utcnow().datetime, fullName = field_src.get('fullName'), companyName = field_src.get('companyName'), subject = field_src.get('subject'), email = field_src.get('email'), message = Markup.escape(field_src.get('message')) ) queries.col_contact().insert(contact) #flash("Your message has been registred.", "success") message = Message("Widukind - new contact from [%s]" % contact['email'], sender=current_app.config.get('MAIL_DEFAULT_SENDER'), recipients=[current_app.config.get('MAIL_ADMINS')]) message.html = '<a href="%s">Admin contacts</a>' % url_for('admin.contacts', _external=True) try: mail.send(message) except Exception as err: current_app.logger.fatal(str(err)) except Exception as err: #flash("Sorry, An unexpected error has occurred. Your message has not registred.", "error") msg = {"msg": "Sorry, An unexpected error has occurred. Your message has not registred.", "category": "error"} current_app.logger.fatal(str(err)) return jsonify({"notify": msg, "redirect": url_for('home', _external=True)})
def search(self): result = self._check_access_permissions() if result is not None: return result check_slug(self.group, self.request) result = super(GroupSearchController, self).search() result["opts"] = {"search_groupname": self.group.name} # If the group has read access only for members and the user is not in that list # return without extra info. if self.group.readable_by == ReadableBy.members and ( self.request.user not in self.group.members ): return result def user_annotation_count(aggregation, userid): for user in aggregation: if user["user"] == userid: return user["count"] return 0 members = [] moderators = [] users_aggregation = result["search_results"].aggregations.get("users", []) # If the group has members provide a list of member info, # otherwise provide a list of moderator info instead. if self.group.members: members = [ { "username": u.username, "userid": u.userid, "count": user_annotation_count(users_aggregation, u.userid), "faceted_by": _faceted_by_user( self.request, u.username, self.parsed_query_params ), } for u in self.group.members ] members = sorted(members, key=lambda k: k["username"].lower()) else: moderators = [] if self.group.creator: # Pass a list of moderators, anticipating that [self.group.creator] # will change to an actual list of moderators at some point. moderators = [ { "username": u.username, "userid": u.userid, "count": user_annotation_count(users_aggregation, u.userid), "faceted_by": _faceted_by_user( self.request, u.username, self.parsed_query_params ), } for u in [self.group.creator] ] moderators = sorted(moderators, key=lambda k: k["username"].lower()) group_annotation_count = self._get_total_annotations_in_group( result, self.request ) result["stats"] = {"annotation_count": group_annotation_count} result["group"] = { "created": utc_us_style_date(self.group.created), "description": self.group.description, "name": self.group.name, "pubid": self.group.pubid, "url": self.request.route_url( "group_read", pubid=self.group.pubid, slug=self.group.slug ), "share_subtitle": _("Share group"), "share_msg": _("Sharing the link lets people view this group:"), } if self.group.organization: result["group"]["organization"] = { "name": self.group.organization.name, "logo": self._organization_context.logo, } else: result["group"]["organization"] = None if self.group.type == "private": result["group"]["share_subtitle"] = _("Invite new members") result["group"]["share_msg"] = _( "Sharing the link lets people join this group:" ) result["group_users_args"] = [ _("Members"), moderators if self.group.type == "open" else members, self.group.creator.userid if self.group.creator else None, ] if self.request.has_permission("admin", self.group): result["group_edit_url"] = self.request.route_url( "group_edit", pubid=self.group.pubid ) result["more_info"] = "more_info" in self.request.params if not result.get("q"): result["zero_message"] = Markup( _("The group “{name}” has not made any annotations yet.").format( name=Markup.escape(self.group.name) ) ) result["show_leave_button"] = self.request.user in self.group.members return result
def _convert(v): if isinstance(v, SafeData): return Markup(v) if isinstance(v, EscapeData): return Markup.escape(v) # not 100% equivalent, see mod docs return v
def getHTMLdisplay(self): """Return an HTML string for the display of a NamedSequence and its Components on the /library page.""" # get the longName for the type longNamesSingular = { "Pr": "Promoter", "RBS": "Ribosome Binding Site", "GOI": "Gene", "Term": "Terminator", } longName = longNamesSingular[self.getType()] # get the libraryName if UserDataDB.query.get(self.getUserID()).getEmail() == "default": libraryName = "Default" isDefault = True else: libraryName = "Personal" isDefault = False # start an array that will collect multiple strings to join and return retArray = [] # add the information about the named sequence retArray.append( """<div class = "hideableTitle nameTitle" id = "{libraryName}{NSname}"> <input class = "titleLeft subtleButton" type = "button" onclick = "toggleDisplay('{libraryName}{NSname}Data'); switchToggleText(this);" value = "Name: {NSname}"> <span class = "titleRight monospaced">[Click to show]</span> </div> <div id = "{libraryName}{NSname}Data" class = "hideableDiv" style = "display: none"> <!-- info about the named sequence --> <p>{longName}: {NSname}</p> <p>Sequence:</p> <div class = "sequence monospaced">{NSseq}</div> <br>""".format( libraryName=libraryName, NSname=Markup.escape(self.getName()), longName=longName, NSseq=self.getSeq(), ) ) # get and sort all components derived from this named sequence allComps = self.getAllComponents() allComps.sort() # add the information about each component for comp in allComps: retArray.append( """<div class = "hideableTitle compTitle" id = "{libraryName}{compNameID}"> <input class = "titleLeft subtleButton" type = "button" onclick = "toggleDisplay('{libraryName}{compNameID}Data'); switchToggleText(this);" value = "ID: {compNameID}"> <span class = "titleRight monospaced">[Click to show]</span> </div> <div id = "{libraryName}{compNameID}Data" class = "hideableDiv componentData" style = "display: none"> <p>{compHTML}</p> <hr> <p><span class = 'emphasized'>Complete Sequence:</span></p> <div class = "sequence monospaced"> {seqHTML} </div> <br> <input type = "button" class = "styledButton" value = "Download Sequences" onclick = "downloadComponentSequence({compID})">""".format( libraryName=libraryName, compNameID=comp.getNameID(), compHTML=comp.getHTMLstr(), seqHTML=comp.getSeqHTML(), compID=comp.getID(), ) ) # add a "Remove Component" button if it is not the default library if not isDefault: retArray.append( """<br><hr><input type = "button" class = "styledButton" value = "Remove Component" onclick = "removeComponent({compID})">""".format( compID=comp.getID() ) ) retArray.append("""</div><div class = "hideableBottom"></div>""") # add a "Remove Sequence" button if it is not the default library if not isDefault: retArray.append( """<br><hr><input type = "button" class = "styledButton" value = "Remove Sequence" onclick = "removeSequence('{NSID}')">""".format( NSID=self.getID() ) ) # finish the HTML string retArray.append("""</div><div class = "hideableBottom"></div>""") # make a single string from retArray retStr = "".join(retArray) return Markup(retStr)
def dispatch_request(self, streamer_name, page): streamer = Streamer.query.filter_by( reddit_username=streamer_name).first_or_404() wpc_stream = streamer.streams.filter_by(type='wpc_stream').first() # glm_talkshow stuff if streamer_name == 'glm_talkshow': subscribe_form = GLMSubscribeForm(prefix='streamer_subscribe') if subscribe_form.validate_on_submit(): subscriber = get_or_create(Subscriber, email=subscribe_form.email.data) if subscriber not in streamer.subscribers: streamer.subscribers.append(subscriber) flash("Subscribed successfully!", category='success') else: flash("You're already subscribed!") db.session.commit() yt_recording_ep1 = YoutubeStream.query.filter_by( ytid='f968E8eZmvM').one() yt_recording_ep2 = YoutubeStream.query.filter_by( ytid='87SfA1sw7vY').one() yt_recording_ep3 = YoutubeStream.query.filter_by( ytid='R7z2GQr9-tg').one() yt_recording_ep4 = YoutubeStream.query.filter_by( ytid='zU7ltY9Dmnk').one() yt_recording_ep5 = YoutubeStream.query.filter_by( ytid='3A_oTuzGoeE').one() how_to_learn_programming = YoutubeStream.query.filter_by( ytid='6XtSPvjt87w').one() return render_template( 'streamers/glm_talkshow.html', streamer=streamer, wpc_stream=wpc_stream, yt_stream_ep1=yt_recording_ep1, yt_stream_ep2=yt_recording_ep2, yt_stream_ep3=yt_recording_ep3, yt_stream_ep4=yt_recording_ep4, yt_stream_ep5=yt_recording_ep5, how_to_learn_programming=how_to_learn_programming, subscribe_form=subscribe_form) # all stuff streams = streamer.streams if wpc_stream: streams = streams.filter(Stream.id != wpc_stream.id) streams = streams.order_by( Stream.actual_start_time.desc().nullslast()).paginate(page, per_page=5) check_profile_alert = False info_form = EditStreamerInfoForm(prefix='info') title_form = EditStreamTitleForm(prefix='title') if current_user.is_authenticated() and current_user == streamer: if request.method == 'POST': if info_form.submit_button.data: if info_form.validate_on_submit(): current_user.populate(info_form) db.session.commit() flash("Updated successfully", category='success') return redirect( url_for('.streamer_page', streamer_name=streamer_name, page=page)) elif title_form.submit_button.data: if title_form.validate_on_submit(): wpc_stream.title = title_form.title.data db.session.commit() return jsonify( newTitle=Markup.escape(title_form.title.data)) else: if not streamer.checked: streamer.checked = True db.session.commit() if (streamer.youtube_channel or streamer.twitch_channel): check_profile_alert = True info_form.youtube_channel.data = current_user.youtube_channel info_form.twitch_channel.data = current_user.twitch_channel info_form.info.data = current_user.info if wpc_stream: title_form.title.data = wpc_stream.title return render_template('streamer.html', streamer=streamer, streams=streams, info_form=info_form, title_form=title_form, wpc_stream=wpc_stream, check_profile_alert=check_profile_alert)
def search(self): result = self._check_access_permissions() if result is not None: return result check_slug(self.group, self.request) result = super(GroupSearchController, self).search() result['opts'] = {'search_groupname': self.group.name} # If the group has read access only for members and the user is not in that list # return without extra info. if self.group.readable_by == ReadableBy.members and (self.request.user not in self.group.members): return result def user_annotation_count(aggregation, userid): for user in aggregation: if user['user'] == userid: return user['count'] return 0 q = query.extract(self.request) members = [] moderators = [] users_aggregation = result['search_results'].aggregations.get('users', []) # If the group has members provide a list of member info, # otherwise provide a list of moderator info instead. if self.group.members: members = [{'username': u.username, 'userid': u.userid, 'count': user_annotation_count(users_aggregation, u.userid), 'faceted_by': _faceted_by_user(self.request, u.username, q)} for u in self.group.members] members = sorted(members, key=lambda k: k['username'].lower()) else: moderators = [] if self.group.creator: # Pass a list of moderators, anticipating that [self.group.creator] # will change to an actual list of moderators at some point. moderators = [{'username': u.username, 'userid': u.userid, 'count': user_annotation_count(users_aggregation, u.userid), 'faceted_by': _faceted_by_user(self.request, u.username, q)} for u in [self.group.creator]] moderators = sorted(moderators, key=lambda k: k['username'].lower()) group_annotation_count = self.request.find_service(name='annotation_stats').group_annotation_count(self.group.pubid) result['stats'] = { 'annotation_count': group_annotation_count, } result['group'] = { 'created': utc_us_style_date(self.group.created), 'description': self.group.description, 'name': self.group.name, 'pubid': self.group.pubid, 'url': self.request.route_url('group_read', pubid=self.group.pubid, slug=self.group.slug), 'share_subtitle': _('Share group'), 'share_msg': _('Sharing the link lets people view this group:'), 'organization': {'name': self.group.organization.name, 'logo': self._organization_context.logo} } if self.group.type == 'private': result['group']['share_subtitle'] = _('Invite new members') result['group']['share_msg'] = _('Sharing the link lets people join this group:') result['group_users_args'] = [ _('Members'), moderators if self.group.type == 'open' else members, self.group.creator.userid if self.group.creator else None, ] if self.request.has_permission('admin', self.group): result['group_edit_url'] = self.request.route_url( 'group_edit', pubid=self.group.pubid) result['more_info'] = 'more_info' in self.request.params if not result.get('q'): result['zero_message'] = Markup(_( 'The group “{name}” has not made any annotations yet.').format( name=Markup.escape(self.group.name))) result['show_leave_button'] = self.request.user in self.group.members return result
def _convert_out(v): if isinstance(v, SafeData): return Markup(v) if isinstance(v, EscapeData): return Markup.escape(v) # not 100% equivalent, see mod docs return v
async def info(self, req): file_id = int(req.match_info["id"]) try: alias_id = req.match_info['chat'] except: alias_id = chat_ids[0]['alias_id'] chat = [i for i in chat_ids if i['alias_id'] == alias_id] if not chat: if not enable_otg: raise web.HTTPFound('/') try: chat_id = int(alias_id) except: raise web.HTTPFound('/') else: chat = chat[0] chat_id = chat['chat_id'] try: message = await self.client.get_messages(entity=chat_id, ids=file_id) except: log.debug(f"Error in getting message {file_id} in {chat_id}", exc_info=True) message = None if not message or not isinstance(message, Message): log.debug(f"no valid entry for {file_id} in {chat_id}") return { 'found': False, 'reason': "Entry you are looking for cannot be retrived!", } return_val = {} reply_btns = [] if message.reply_markup: if isinstance(message.reply_markup, types.ReplyInlineMarkup): for button_row in message.reply_markup.rows: btns = [] for button in button_row.buttons: if isinstance(button, types.KeyboardButtonUrl): btns.append({ 'url': button.url, 'text': button.text }) reply_btns.append(btns) if message.file and not isinstance(message.media, types.MessageMediaWebPage): file_name = get_file_name(message) file_size = message.file.size human_file_size = get_human_size(file_size) media = {'type': message.file.mime_type} if 'video/' in message.file.mime_type: media.update({'video': True}) elif 'audio/' in message.file.mime_type: media['audio'] = True elif 'image/' in message.file.mime_type: media['image'] = True if message.text: caption = message.raw_text else: caption = '' caption_html = Markup.escape(caption).__str__().replace( '\n', '<br>') return_val = { 'found': True, 'name': file_name, 'file_id': file_id, 'size': file_size, 'human_size': human_file_size, 'media': media, 'caption_html': caption_html, 'caption': caption, 'title': f"Download | {file_name} | {human_file_size}", 'reply_btns': reply_btns, 'thumbnail': f"/{alias_id}/{file_id}/thumbnail", 'download_url': f"/{alias_id}/{file_id}/download", 'page_id': alias_id } elif message.message: text = message.raw_text text_html = Markup.escape(text).__str__().replace('\n', '<br>') return_val = { 'found': True, 'media': False, 'text': text, 'text_html': text_html, 'reply_btns': reply_btns, 'page_id': alias_id } else: return_val = { 'found': False, 'reason': "Some kind of entry that I cannot display", } log.debug(f"data for {file_id} in {chat_id} returned as {return_val}") return return_val
def do_autolink(environment, value): escaped_value = unicode(Markup.escape(value)) return re.sub(_re_account, '@<a href="/u/\\1">\\1</a>', escaped_value)
def open_graph_tag(item): ogtags = [] ogtags.append(("og:title", item.title)) ogtags.append(("twitter:title", item.title)) ogtags.append(("og:type", "article")) ogtags.append(("twitter:card", "summary")) image = item.metadata.get("og_image", "") if image: ogtags.append(("og:image", image)) ogtags.append(("twitter:image", image)) else: soup = BeautifulSoup(item._content, "html.parser") img_links = soup.find_all("img") img_src = "" if len(img_links) > 0: img_src = img_links[0].get("src") else: if item.settings.get("DEFAULT_OG_IMAGE", ""): img_src = item.settings.get("DEFAULT_OG_IMAGE", "") if img_src: if img_src.startswith("{attach}"): img_path = os.path.dirname(item.source_path) img_filename = img_src[8:] img_src = os.path.join(img_path, img_filename) if item.settings.get("SITEURL", ""): img_src = item.settings.get("SITEURL", "") + "/" + img_src elif img_src.startswith(("{filename}", "|filename|")): img_src = img_src[11:] if item.settings.get("SITEURL", ""): img_src = item.settings.get("SITEURL", "") + "/" + img_src elif img_src.startswith("{static}"): img_src = img_src[9:] if item.settings.get("SITEURL", ""): img_src = item.settings.get("SITEURL", "") + "/" + img_src elif img_src.startswith("/static"): img_src = img_src[8:] if item.settings.get("SITEURL", ""): img_src = item.settings.get("SITEURL", "") + "/" + img_src elif img_src.startswith("data:image"): pass elif not "http" in img_src: if item.settings.get("SITEURL", ""): img_src = item.settings.get("SITEURL", "") + "/" + img_src if img_src: ogtags.append(("og:image", img_src)) ogtags.append(("twitter:image", img_src)) url = os.path.join(item.settings.get("SITEURL", ""), item.url) ogtags.append(("og:url", url)) default_summary = Markup(item.summary).striptags() description = Markup.escape( item.metadata.get("og_description", default_summary)) ogtags.append(("og:description", description)) ogtags.append(("twitter:description", description)) default_locale = item.settings.get("LOCALE", []) if default_locale: default_locale = default_locale[0] else: default_locale = "" ogtags.append(("og:locale", item.metadata.get("og_locale", default_locale))) ogtags.append(("og:site_name", item.settings.get("SITENAME", ""))) ogtags.append(("twitter:site", item.settings.get("SITENAME", ""))) if hasattr(item, "date"): ogtags.append( ("article:published_time", strftime(item.date, "%Y-%m-%d"))) if hasattr(item, "modified"): ogtags.append( ("article:modified_time", strftime(item.modified, "%Y-%m-%d"))) if hasattr(item, "related_posts"): for related_post in item.related_posts: url = os.path.join(item.settings.get("SITEURL", ""), related_post.url) ogtags.append(("og:see_also", url)) author_fb_profiles = item.settings.get("AUTHOR_FB_ID", {}) if len(author_fb_profiles) > 0: for author in item.authors: if author.name in author_fb_profiles: ogtags.append( ("article:author", author_fb_profiles[author.name])) ogtags.append(("article:section", item.category.name)) if hasattr(item, "tags"): for tag in item.tags: ogtags.append(("article:tag", tag.name)) item.ogtags = ogtags
def get_default_meta_og_description(cls, article): if hasattr(article, 'meta_description'): return Markup.escape(article.meta_description) return cls.get_default_meta_description(article)
async def info(self, req): file_id = int(req.match_info["id"]) alias_id = req.rel_url.path.split('/')[1] chat = [i for i in chat_ids if i['alias_id'] == alias_id][0] chat_id = chat['chat_id'] message = await self.client.get_messages(entity=chat_id, ids=file_id) if not message or not isinstance(message, Message): log.debug(f"no valid entry for {file_id} in {chat_id}") return { 'found': False, 'reason': "Entry you are looking for cannot be retrived!", } return_val = {} reply_btns = [] if message.reply_markup: if isinstance(message.reply_markup, types.ReplyInlineMarkup): for button_row in message.reply_markup.rows: btns = [] for button in button_row.buttons: if isinstance(button, types.KeyboardButtonUrl): btns.append({ 'url': button.url, 'text': button.text }) reply_btns.append(btns) if message.file and not isinstance(message.media, types.MessageMediaWebPage): file_name = get_file_name(message) file_size = get_human_size(message.file.size) media = {'type': message.file.mime_type} if 'video/' in message.file.mime_type: media.update({'video': True}) elif 'audio/' in message.file.mime_type: media['audio'] = True elif 'image/' in message.file.mime_type: media['image'] = True if message.text: caption = Markup.escape(message.raw_text).__str__().replace( '\n', '<br>') else: caption = False return_val = { 'found': True, 'name': file_name, 'id': file_id, 'size': file_size, 'media': media, 'caption': caption, 'title': f"Download | {file_name} | {file_size}", 'reply_btns': reply_btns } elif message.message: text = Markup.escape(message.raw_text).__str__().replace( '\n', '<br>') return_val = { 'found': True, 'media': False, 'text': text, 'reply_btns': reply_btns } else: return_val = { 'found': False, 'reason': "Some kind of entry that I cannot display", } #return_val.update({'reply_btns': reply_btns}) log.debug(f"data for {file_id} in {chat_id} returned as {return_val}") return return_val
from jinja2 import Markup, escape markup_escape_method_using = Markup.escape( "<b>Markup 클래스의 escape 클래스 메서드를 사용합니다.</b>") escape_function_using = escape("<b>Markup 클래스의 escape 클래스 메서드를 사용합니다.</b>")
async def info(self, req): file_id = int(req.match_info["id"]) alias_id = req.match_info["chat"] chat = self.chat_ids[alias_id] chat_id = chat["chat_id"] try: message = await self.client.get_messages(entity=chat_id, ids=file_id) except Exception: log.debug(f"Error in getting message {file_id} in {chat_id}", exc_info=True) message = None if not message or not isinstance(message, Message): log.debug(f"no valid entry for {file_id} in {chat_id}") return { "found": False, "reason": "Resource you are looking for cannot be retrived!", "authenticated": req.app["is_authenticated"], } return_val = { "authenticated": req.app["is_authenticated"], } reply_btns = [] if message.reply_markup: if isinstance(message.reply_markup, types.ReplyInlineMarkup): reply_btns = [[{ "url": button.url, "text": button.text } for button in button_row.buttons if isinstance(button, types.KeyboardButtonUrl)] for button_row in message.reply_markup.rows] if message.file and not isinstance(message.media, types.MessageMediaWebPage): file_name = get_file_name(message) human_file_size = get_human_size(message.file.size) media = {"type": message.file.mime_type} if "video/" in message.file.mime_type: media["video"] = True elif "audio/" in message.file.mime_type: media["audio"] = True elif "image/" in message.file.mime_type: media["image"] = True if message.text: caption = message.raw_text else: caption = "" caption_html = Markup.escape(caption).__str__().replace( "\n", "<br>") return_val.update({ "found": True, "name": unquote(file_name), "file_id": file_id, "human_size": human_file_size, "media": media, "caption_html": caption_html, "title": f"Download | {file_name} | {human_file_size}", "reply_btns": reply_btns, "thumbnail": f"/{alias_id}/{file_id}/thumbnail", "download_url": "#" if block_downloads else f"/{alias_id}/{file_id}/{file_name}", "page_id": alias_id, "block_downloads": block_downloads, }) elif message.message: text = message.raw_text text_html = Markup.escape(text).__str__().replace("\n", "<br>") return_val.update({ "found": True, "media": False, "text_html": text_html, "reply_btns": reply_btns, "page_id": alias_id, }) else: return_val.update({ "found": False, "reason": "Some kind of resource that I cannot display", }) log.debug(f"data for {file_id} in {chat_id} returned as {return_val}") return return_val
from jinja2 import Markup escaped_markup_value = Markup.escape("<b>Markup 클래스의 escape 클래스 메서드를 사용합니다.</b>") unescape_markup_value = escaped_markup_value.unescape()
def search(self): result = self._check_access_permissions() if result is not None: return result check_slug(self.group, self.request) result = super(GroupSearchController, self).search() result['opts'] = {'search_groupname': self.group.name} if self.request.user not in self.group.members: return result def user_annotation_count(aggregation, userid): for user in aggregation: if user['user'] == userid: return user['count'] return 0 q = query.extract(self.request) users_aggregation = result['search_results'].aggregations.get( 'users', []) members = [{ 'username': u.username, 'userid': u.userid, 'count': user_annotation_count(users_aggregation, u.userid), 'faceted_by': _faceted_by_user(self.request, u.username, q) } for u in self.group.members] members = sorted(members, key=lambda k: k['username'].lower()) group_annotation_count = self.request.find_service( name='annotation_stats').group_annotation_count(self.group.pubid) result['stats'] = { 'annotation_count': group_annotation_count, } result['group'] = { 'created': self.group.created.strftime('%B, %Y'), 'description': self.group.description, 'name': self.group.name, 'pubid': self.group.pubid, 'url': self.request.route_url('group_read', pubid=self.group.pubid, slug=self.group.slug), 'members': members, } if self.request.has_permission('admin', self.group): result['group_edit_url'] = self.request.route_url( 'group_edit', pubid=self.group.pubid) result['more_info'] = 'more_info' in self.request.params if not result.get('q'): result['zero_message'] = Markup( _('The group “{name}” has not made any annotations yet.'). format(name=Markup.escape(self.group.name))) return result
def render(self): with open(self.file_path) as f: content = f.read().decode("UTF-8") return Markup("<pre>{}</pre>".format(Markup.escape(content)))
def tag_url(match): tag_id = match.group(1) return Markup(u'<a href="%s">#%s</a>') % (Markup.escape(url_for('tag', tag_id=tag_id.lower())), Markup.escape(tag_id))
def search(self): result = self._check_access_permissions() if result is not None: return result check_slug(self.group, self.request) result = super(GroupSearchController, self).search() result['opts'] = {'search_groupname': self.group.name} # If the group has a concept of members (aka joinable_by is not None) # and the user is not in the list of members, return without extra info. if self.group.joinable_by and (self.request.user not in self.group.members): return result def user_annotation_count(aggregation, userid): for user in aggregation: if user['user'] == userid: return user['count'] return 0 q = query.extract(self.request) members = None moderators = None users_aggregation = result['search_results'].aggregations.get( 'users', []) # If the group has a concept of members provide a list of member info, # otherwise provide a list of moderator info instead. if self.group.joinable_by: members = [{ 'username': u.username, 'userid': u.userid, 'count': user_annotation_count(users_aggregation, u.userid), 'faceted_by': _faceted_by_user(self.request, u.username, q) } for u in self.group.members] members = sorted(members, key=lambda k: k['username'].lower()) else: moderators = [] if self.group.creator: # Pass a list of moderators, anticipating that [self.group.creator] # will change to an actual list of moderators at some point. moderators = [{ 'username': u.username, 'userid': u.userid, 'count': user_annotation_count(users_aggregation, u.userid), 'faceted_by': _faceted_by_user(self.request, u.username, q) } for u in [self.group.creator]] moderators = sorted(moderators, key=lambda k: k['username'].lower()) group_annotation_count = self.request.find_service( name='annotation_stats').group_annotation_count(self.group.pubid) result['stats'] = { 'annotation_count': group_annotation_count, } result['group'] = { 'created': utc_us_style_date(self.group.created), 'description': self.group.description, 'name': self.group.name, 'pubid': self.group.pubid, 'url': self.request.route_url('group_read', pubid=self.group.pubid, slug=self.group.slug), 'members': members, 'moderators': moderators, 'creator': self.group.creator.userid if self.group.creator else None, } if self.request.has_permission('admin', self.group): result['group_edit_url'] = self.request.route_url( 'group_edit', pubid=self.group.pubid) result['more_info'] = 'more_info' in self.request.params if not result.get('q'): result['zero_message'] = Markup( _('The group “{name}” has not made any annotations yet.'). format(name=Markup.escape(self.group.name))) return result
def user_url(match): user_id = match.group(1) return Markup(u'<a href="%s">@%s</a>') % (Markup.escape(url_for('user', user_id=user_id.lower())), Markup.escape(user_id))
def search(self): result = self._check_access_permissions() if result is not None: return result check_slug(self.group, self.request) result = super(GroupSearchController, self).search() result['opts'] = {'search_groupname': self.group.name} # If the group has read access only for members and the user is not in that list # return without extra info. if self.group.readable_by == ReadableBy.members and ( self.request.user not in self.group.members): return result def user_annotation_count(aggregation, userid): for user in aggregation: if user['user'] == userid: return user['count'] return 0 q = query.extract(self.request) members = [] moderators = [] users_aggregation = result['search_results'].aggregations.get( 'users', []) # If the group has members provide a list of member info, # otherwise provide a list of moderator info instead. if self.group.members: members = [{ 'username': u.username, 'userid': u.userid, 'count': user_annotation_count(users_aggregation, u.userid), 'faceted_by': _faceted_by_user(self.request, u.username, q) } for u in self.group.members] members = sorted(members, key=lambda k: k['username'].lower()) else: moderators = [] if self.group.creator: # Pass a list of moderators, anticipating that [self.group.creator] # will change to an actual list of moderators at some point. moderators = [{ 'username': u.username, 'userid': u.userid, 'count': user_annotation_count(users_aggregation, u.userid), 'faceted_by': _faceted_by_user(self.request, u.username, q) } for u in [self.group.creator]] moderators = sorted(moderators, key=lambda k: k['username'].lower()) group_annotation_count = self._get_total_annotations_in_group( result, q, self.request) result['stats'] = { 'annotation_count': group_annotation_count, } result['group'] = { 'created': utc_us_style_date(self.group.created), 'description': self.group.description, 'name': self.group.name, 'pubid': self.group.pubid, 'url': self.request.route_url('group_read', pubid=self.group.pubid, slug=self.group.slug), 'share_subtitle': _('Share group'), 'share_msg': _('Sharing the link lets people view this group:') } if self.group.organization: result['group']['organization'] = { 'name': self.group.organization.name, 'logo': self._organization_context.logo } else: result['group']['organization'] = None if self.group.type == 'private': result['group']['share_subtitle'] = _('Invite new members') result['group']['share_msg'] = _( 'Sharing the link lets people join this group:') result['group_users_args'] = [ _('Members'), moderators if self.group.type == 'open' else members, self.group.creator.userid if self.group.creator else None, ] if self.request.has_permission('admin', self.group): result['group_edit_url'] = self.request.route_url( 'group_edit', pubid=self.group.pubid) result['more_info'] = 'more_info' in self.request.params if not result.get('q'): result['zero_message'] = Markup( _('The group “{name}” has not made any annotations yet.'). format(name=Markup.escape(self.group.name))) result['show_leave_button'] = self.request.user in self.group.members return result
def render(obj, *a,**kw): if hasattr(obj,"render"): return obj.render(*a,**kw) else: return Markup.escape(unicode(obj))
def search(self): result = self._check_access_permissions() if result is not None: return result check_slug(self.group, self.request) result = super(GroupSearchController, self).search() result['opts'] = {'search_groupname': self.group.name} if self.request.user not in self.group.members: return result def user_annotation_count(aggregation, userid): for user in aggregation: if user['user'] == userid: return user['count'] return 0 q = query.extract(self.request) users_aggregation = result['search_results'].aggregations.get('users', []) members = [{'username': u.username, 'userid': u.userid, 'count': user_annotation_count(users_aggregation, u.userid), 'faceted_by': _faceted_by_user(self.request, u.username, q)} for u in self.group.members] members = sorted(members, key=lambda k: k['username'].lower()) group_annotation_count = None if self.request.feature('total_shared_annotations'): group_annotation_count = self.request.find_service(name='annotation_stats').group_annotation_count(self.group.pubid) result['stats'] = { 'annotation_count': group_annotation_count, } result['group'] = { 'created': self.group.created.strftime('%B, %Y'), 'description': self.group.description, 'name': self.group.name, 'pubid': self.group.pubid, 'url': self.request.route_url('group_read', pubid=self.group.pubid, slug=self.group.slug), 'members': members, } if self.request.has_permission('admin', self.group): result['group_edit_url'] = self.request.route_url( 'group_edit', pubid=self.group.pubid) result['more_info'] = 'more_info' in self.request.params if not result.get('q'): result['zero_message'] = Markup(_( 'The group “{name}” has not made any annotations yet.').format( name=Markup.escape(self.group.name))) return result
def sanitize_fragment(fragment, *, naucse_urls=None): if isinstance(fragment, str): return Markup.escape(fragment) else: sanitize_element(fragment, naucse_urls=naucse_urls) return Markup(lxml.etree.tounicode(fragment, method='html'))
def search(self): check_slug(self.group, self.request) result = super(GroupSearchController, self).search() result["opts"] = {"search_groupname": self.group.name} if self.request.authenticated_user not in self.group.members: return result def user_annotation_count(aggregation, userid): for user in aggregation: if user["user"] == userid: return user["count"] return 0 q = query.extract(self.request) users_aggregation = result["search_results"].aggregations.get("users", []) members = [ { "username": u.username, "userid": u.userid, "count": user_annotation_count(users_aggregation, u.userid), "faceted_by": _faceted_by_user(self.request, u.username, q), } for u in self.group.members ] members = sorted(members, key=lambda k: k["username"].lower()) group_annotation_count = None if self.request.feature("total_shared_annotations"): group_annotation_count = self.request.find_service(name="annotation_stats").group_annotation_count( self.group.pubid ) result["stats"] = {"annotation_count": group_annotation_count} result["group"] = { "created": self.group.created.strftime("%B, %Y"), "description": self.group.description, "name": self.group.name, "pubid": self.group.pubid, "url": self.request.route_url("group_read", pubid=self.group.pubid, slug=self.group.slug), "members": members, } if self.request.has_permission("admin", self.group): result["group_edit_url"] = self.request.route_url("group_edit", pubid=self.group.pubid) result["more_info"] = "more_info" in self.request.params if not result.get("q"): result["zero_message"] = Markup( _("The group “{name}” has not made any annotations yet.").format(name=Markup.escape(self.group.name)) ) return result
def getHTMLdisplay(self): """Return HTML string to display the backbone on the /library page.""" # get the library name if UserDataDB.query.get(self.getUserID()).getEmail() == "default": libraryName = "Default" isDefault = True else: libraryName = "Personal" isDefault = False retArray = [] retArray.append( """<div class = "hideableTitle nameTitle" id = "{libraryName}{BBname}Backbone"> <input class = "titleLeft subtleButton" type = "button" onclick = "toggleDisplay('{libraryName}{BBname}BackboneData'); switchToggleText(this);" value = "Name: {BBname}"> <span class = "titleRight monospaced">[Click to show]</span> </div> <div id = "{libraryName}{BBname}BackboneData" class = "hideableDiv" style = "display: none"> <!-- info about the named sequence --> <p>Backbone: {BBname}</p> <p>Type: {BBtype}</p> <p>Description:</p> <p>{BBdesc}</p> <p>Sequence:</p> <div class = "sequence monospaced"> {BBseqBefore} <span class = 'insertionSeq'>INSERTION</span> {BBseqAfter} </div> <br>""".format( libraryName=libraryName, BBname=Markup.escape(self.getName()), BBtype=self.getTypeLong(), BBdesc=Markup.escape(self.getDesc()), BBseqBefore=self.getSeqBefore(), BBseqAfter=self.getSeqAfter(), ) ) # add a "Remove Backbone" button if it is not the default library if not isDefault: retArray.append( """<br><hr><input type = "button" class = "styledButton" value = "Remove Backbone" onclick = "removeBackbone('{BBID}')">""".format( BBID=self.getID() ) ) # finish the string retArray.append("""</div><div class = "hideableBottom"></div>""") retStr = "".join(retArray) return Markup(retStr)
def nl2br(eval_ctx, value): value = Markup.escape(value) result = re.sub(_paragraph_re, Markup("<br/>"), value) if eval_ctx.autoescape: result = Markup(result) return result
from jinja2 import Markup bold_markup_value = Markup.escape("<b>볼드처리를 위한 태그를 제거합니다.</b>") striptags_markup_value = bold_markup_value.striptags()