def test_markdown_column(self): text = u"""# this is going to be h1.\n- Now a list. \n- 1\n- 2\n- 3""" data = MarkdownData(value=text) self.session.add(data) self.session.commit() self.assertEqual(data.value.html, markdown(text)) self.assertEqual(data.value.text, text) self.assertEqual(data.value.__str__(), text) self.assertEqual(data.value.__html__(), markdown(text))
def test_markdown_column(self): text = u"""# this is going to be h1.\n- Now a list. \n- 1\n- 2\n- 3""" data = MarkdownData(value=text) self.session.add(data) self.session.commit() assert data.value.html == markdown(text) assert data.value.text == text assert data.value.__str__() == text assert data.value.__html__() == markdown(text)
def test_markdown_column(self): text = u"""# this is going to be h1.\n- Now a list. \n- 1\n- 2\n- 3""" data = MarkdownData(value=text) self.session.add(data) self.session.commit() self.assertEqual(data.value.html, markdown(text)) self.assertEqual(data.value.text, text) self.assertEqual(data.value.__str__(), text) self.assertEqual(data.value.__unicode__(), text) self.assertEqual(data.value.__html__(), markdown(text))
def upgrade(): connection = op.get_bind() proposal_space = table('proposal_space', column(u'id', sa.INTEGER()), column(u'description_text', sa.TEXT()), column(u'description_html', sa.TEXT()), column(u'content', JsonDict())) results = connection.execute(proposal_space.select()) for space in results: if space['content']: for (section, title) in [ ('format', u"Format"), ('criteria', u"Criteria for proposals"), ('panel', u"Editorial panel"), ('dates', u"Important dates"), ('open_source', u"Commitment to Open Source"), ('themes', u"Theme") ]: modified = False text = space['description_text'] if space['content'].get(section): modified = True text = text + '\r\n\r\n' + u"## " + title + '\r\n\r\n' + space['content'][section] if modified: html = markdown(text) connection.execute( proposal_space.update().where( proposal_space.c.id == space['id']).values( {'description_text': text, 'description_html': html, 'content': {}}))
def _discount_email(self, person, book_ticket, slot_ticket): msg = MIMEMultipart("alternative") msg["Subject"] = "%s Discount Code" % self.event_title msg["To"] = person["email"] msg["From"] = "*****@*****.**" msg["Bcc"] = "*****@*****.**" env = Environment(loader=PackageLoader("eventer", "templates")) template_name = self.doattend.event_id + "_proposal_discount_email.md" path = os.path.join("eventer", "templates", "custom", template_name) if os.path.exists(path): template = env.get_template("custom/" + template_name) else: template = env.get_template("proposal_discount_email.md") text = template.render( title=self.event_title, person=person, book_ticket=book_ticket, slot_ticket=slot_ticket, float=float, int=int, ) html = markdown(text) msg.attach(MIMEText(text.encode("utf-8"), "plain")) msg.attach(MIMEText(html.encode("utf-8"), "html")) to = [person["email"], msg["Bcc"]] self.mailer.sendmail(msg["From"], to, msg.as_string())
def _send_discounts_email(self, discount, codes): msg = MIMEMultipart('alternative') msg['Subject'] = "Your discount code%s%s" % ( "s" if len(codes) > 1 else "", " for " + self.event_title if self.event_title else "") msg['From'] = self.email_info['from_email'] msg['To'] = discount['email']['data'] if self.email_info['cc']: msg['CC'] = self.email_info['cc'] msg['BCC'] = '*****@*****.**' if self.email_info['replyto'] and self.email_info['replyto'] != self.email_info['from_email']: msg['Reply-To'] = self.email_info['replyto'] env = Environment(loader=PackageLoader('eventer', 'templates')) if os.path.exists(os.path.join('eventer', 'templates', 'custom', self.doattend.event_id + '_discount_email.md')): template = env.get_template('custom/%s_discount_email.md' % self.doattend.event_id) else: template = env.get_template('discount_email.md') text = template.render(discount=discount, title=self.event_title, codes=codes) html = markdown(text) msg.attach(MIMEText(text, 'plain')) msg.attach(MIMEText(html, 'html')) to = [discount['email']['data'], '*****@*****.**'] if self.email_info['cc'] != "": to = to + self.email_info['cc'].split(',') self.mailer.sendmail(self.email_info['from_email'], to, msg.as_string())
def upgrade(): # Copy over data conn = op.get_bind() orgs = conn.execute( sa.select([ organization_table.c.id, organization_table.c.title, organization_table.c.description, ]).where(organization_table.c.description != '')) for org in orgs: blank_profile = conn.execute( sa.select([sa.func.count(profile_table.c.id)]).where( sa.and_( profile_table.c.organization_id == org.id, profile_table.c.description_text == '', ))).first()[0] if blank_profile: print("Updating", org.title) # NOQA: T001 op.execute(profile_table.update().where( profile_table.c.organization_id == org.id).values( description_text=org.description, description_html=markdown(org.description), )) else: print("Skipping", org.title) # NOQA: T001 op.drop_column('organization', 'description')
def test_does_not_render_on_load(self): text = u"This is the text" real_html = markdown(text) fake_html = u"This is not the text" data = MarkdownData(value=text) self.session.add(data) # Insert fake rendered data for commit to db data.value._html = fake_html data.value.changed() self.session.commit() del data # Reload from db and confirm HTML is exactly as committed data = MarkdownData.query.first() self.assertEqual(data.value.text, text) self.assertEqual(data.value.html, fake_html) self.assertEqual(data.value.__str__(), text) self.assertEqual(data.value.__html__(), fake_html) # Edit text and confirm HTML was regenerated, saved and reloaded data.value.text = text db.session.commit() del data data = MarkdownData.query.first() self.assertEqual(data.value.text, text) self.assertEqual(data.value.html, real_html) self.assertEqual(data.value.__str__(), text) self.assertEqual(data.value.__html__(), real_html)
def upgrade(): connection = op.get_bind() proposal_space = table( "proposal_space", column(u"id", sa.INTEGER()), column(u"description_text", sa.TEXT()), column(u"description_html", sa.TEXT()), column(u"content", JsonDict()), ) results = connection.execute(proposal_space.select()) for space in results: if space["content"]: for (section, title) in [ ("format", u"Format"), ("criteria", u"Criteria for proposals"), ("panel", u"Editorial panel"), ("dates", u"Important dates"), ("open_source", u"Commitment to Open Source"), ("themes", u"Theme"), ]: modified = False text = space["description_text"] if space["content"].get(section): modified = True text = text + "\r\n\r\n" + u"## " + title + "\r\n\r\n" + space["content"][section] if modified: html = markdown(text) connection.execute( proposal_space.update() .where(proposal_space.c.id == space["id"]) .values({"description_text": text, "description_html": html, "content": {}}) )
def test_does_not_render_on_load(self): text = u"This is the text" real_html = markdown(text) fake_html = u"This is not the text" data = MarkdownData(value=text) self.session.add(data) # Insert fake rendered data for commit to db data.value._html = fake_html data.value.changed() self.session.commit() del data # Reload from db and confirm HTML is exactly as committed data = MarkdownData.query.first() assert data.value.text == text assert data.value.html == fake_html assert data.value.__str__() == text assert data.value.__html__() == fake_html # Edit text and confirm HTML was regenerated, saved and reloaded data.value.text = text db.session.commit() del data data = MarkdownData.query.first() assert data.value.text == text assert data.value.html == real_html assert data.value.__str__() == text assert data.value.__html__() == real_html
def test_markdown_javascript_link(self): """Markdown rendering should strip `javascript:` protocol links""" # Markdown's link processor can't handle `javascript:alert("Hello")` so it loses # link3 entirely, mashing it into link2. assert markdown( '[link1](http://example.com) ' '[link2](javascript:alert(document.cookie) ' '[link3](javascript:alert("Hello"))') == ( '<p><a href="http://example.com" rel="nofollow">link1</a> ' '<a title="Hello">link2</a>)</p>')
def render_preview(campaign, text): if campaign.stylesheet is not None and campaign.stylesheet.strip(): stylesheet = u'<style type="text/css">%s</style>\n' % escape(campaign.stylesheet) else: stylesheet = u'' if text: # email_transform uses LXML, which does not like empty strings return email_transform( Markup(stylesheet) + markdown(text, html=True, valid_tags=EMAIL_TAGS), base_url=request.url_root) else: return u''
def newspace(): form = ProposalSpaceForm() form.description.flags.markdown = True if form.validate_on_submit(): space = ProposalSpace(user=g.user) form.populate_obj(space) space.description_html = markdown(space.description) db.session.add(space) db.session.commit() flash("Your new space has been created", "info") return redirect(url_for('viewspace', name=space.name), code=303) return render_template('autoform.html', form=form, title="Create a new proposal space", submit="Create space")
def editspace(name): space = ProposalSpace.query.filter_by(name=name).first() if not space: abort(404) form = ProposalSpaceForm(obj=space) form.description.flags.markdown = True if form.validate_on_submit(): form.populate_obj(space) space.description_html = markdown(space.description) db.session.commit() flash("Your changes have been saved", "info") return redirect(url_for('viewspace', name=space.name), code=303) return render_template('autoform.html', form=form, title="Edit proposal space", submit="Save changes")
def editsession(name, slug): space = ProposalSpace.query.filter_by(name=name).first() if not space: abort(404) proposal_id = int(slug.split('-')[0]) proposal = Proposal.query.get(proposal_id) if not proposal: abort(404) if proposal.user != g.user and not lastuser.has_permission('siteadmin'): abort(403) form = ProposalForm(obj=proposal) if not proposal.session_type: del form.session_type # Remove this if we're editing a proposal that had no session type form.section.query = ProposalSpaceSection.query.filter_by(proposal_space=space, public=True).order_by('title') if len(list(form.section.query.all())) == 0: # Don't bother with sections when there aren't any del form.section # Set markdown flag to True for fields that need markdown conversion markdown_attrs = ('description', 'objective', 'requirements', 'bio') for name in markdown_attrs: attr = getattr(form, name) attr.flags.markdown = True if proposal.user != g.user: del form.speaking elif request.method == 'GET': form.speaking.data = proposal.speaker == g.user if form.validate_on_submit(): form.populate_obj(proposal) proposal.name = makename(proposal.title) if proposal.user == g.user: # Only allow the speaker to change this status if form.speaking.data: proposal.speaker = g.user else: if proposal.speaker == g.user: proposal.speaker = None # Set *_html attributes after converting markdown text for name in markdown_attrs: attr = getattr(proposal, name) html_attr = name + '_html' setattr(proposal, html_attr, markdown(attr)) proposal.edited_at = datetime.utcnow() db.session.commit() flash("Your changes have been saved", "info") return redirect(url_for('viewsession', name=space.name, slug=proposal.urlname), code=303) return render_template('autoform.html', form=form, title="Edit session proposal", submit="Save changes", breadcrumbs=[(url_for('viewspace', name=space.name), space.title), (url_for('viewsession', name=space.name, slug=proposal.urlname), proposal.title)], message=Markup( 'This form uses <a href="http://daringfireball.net/projects/markdown/">Markdown</a> for formatting.'))
def newsession(name): space = ProposalSpace.query.filter_by(name=name).first() if not space: abort(404) if space.status != SPACESTATUS.SUBMISSIONS: abort(403) form = ProposalForm() del form.session_type # We don't use this anymore # Set markdown flag to True for fields that need markdown conversion markdown_attrs = ('description', 'objective', 'requirements', 'bio') for name in markdown_attrs: attr = getattr(form, name) attr.flags.markdown = True form.section.query = ProposalSpaceSection.query.filter_by( proposal_space=space, public=True).order_by('title') if len(list(form.section.query.all())) == 0: # Don't bother with sections when there aren't any del form.section if request.method == 'GET': form.email.data = g.user.email if form.validate_on_submit(): proposal = Proposal(user=g.user, proposal_space=space) if form.speaking.data: proposal.speaker = g.user else: proposal.speaker = None proposal.votes.vote(g.user) # Vote up your own proposal by default form.populate_obj(proposal) proposal.name = makename(proposal.title) # Set *_html attributes after converting markdown text for name in markdown_attrs: attr = getattr(proposal, name) html_attr = name + '_html' setattr(proposal, html_attr, markdown(attr)) db.session.add(proposal) db.session.commit() flash("Your new session has been saved", "info") return redirect(url_for('viewsession', name=space.name, slug=proposal.urlname), code=303) return render_template( 'autoform.html', form=form, title="Submit a session proposal", submit="Submit session", breadcrumbs=[(url_for('viewspace', name=space.name), space.title)], message=Markup( 'This form uses <a href="http://daringfireball.net/projects/markdown/">Markdown</a> for formatting.' ))
def contact_exchange(event): if request.method == 'GET': return render_template('contact_exchange.html', event=event, debug=str(app.config['DEBUG']).lower(), ui_test=str(request.args.get('ui_test', False)).lower()) if request.method == 'POST': ids = tuple(request.form.getlist('ids[]')) if len(ids) < 2: return jsonify(status=False, error=u'Insufficient users to connect') users = Participant.query.filter(Participant.event_id == event.id, Participant.nfc_id.in_(ids)).all() mail = Mail(app) message = Message("You connected with " + str(len(users) - 1) + " people using ContactExchange") message.cc = list() for user in users: email = '"' + user.name + '"<' + user.email + '>' if message.reply_to is None: message.reply_to = email message.add_recipient(email) else: message.cc.append(email) message.attach( make_name(user.name) + '.vcf', 'text/vcard', render_template('user_card.vcf', user=user, event=event)) message.sender = '"HasGeek"<*****@*****.**>' message.body = render_template('connectemail.md', users=users, event=event) message.html = markdown(message.body) log = CXLog() try: mail.send(message) log.sent = True log.log_message = u"Mail delivered to postfix server" except Exception as error: log.sent = True log.log_message = unicode(error) log.users = u','.join(ids) db.session.add(log) db.session.commit() return jsonify(success=True)
def newsession(name): space = ProposalSpace.query.filter_by(name=name).first() if not space: abort(404) if space.status != SPACESTATUS.SUBMISSIONS: abort(403) form = ProposalForm() del form.session_type # We don't use this anymore # Set markdown flag to True for fields that need markdown conversion markdown_attrs = ('description', 'objective', 'requirements', 'bio') for name in markdown_attrs: attr = getattr(form, name) attr.flags.markdown = True form.section.query = ProposalSpaceSection.query.filter_by(proposal_space=space, public=True).order_by('title') if len(list(form.section.query.all())) == 0: # Don't bother with sections when there aren't any del form.section if request.method == 'GET': form.email.data = g.user.email if form.validate_on_submit(): proposal = Proposal(user=g.user, proposal_space=space) if form.speaking.data: proposal.speaker = g.user else: proposal.speaker = None proposal.votes.vote(g.user) # Vote up your own proposal by default form.populate_obj(proposal) proposal.name = makename(proposal.title) # Set *_html attributes after converting markdown text for name in markdown_attrs: attr = getattr(proposal, name) html_attr = name + '_html' setattr(proposal, html_attr, markdown(attr)) db.session.add(proposal) db.session.commit() flash("Your new session has been saved", "info") return redirect(url_for('viewsession', name=space.name, slug=proposal.urlname), code=303) return render_template('autoform.html', form=form, title="Submit a session proposal", submit="Submit session", breadcrumbs=[(url_for('viewspace', name=space.name), space.title)], message=Markup( 'This form uses <a href="http://daringfireball.net/projects/markdown/">Markdown</a> for formatting.'))
def contact_exchange(event): if request.method=='GET': return render_template('contact_exchange.html', event=event, debug=str(app.config['DEBUG']).lower(), ui_test=str(request.args.get('ui_test', False)).lower()) if request.method == 'POST': ids = tuple(request.form.getlist('ids[]')) if len(ids) < 2: return jsonify(status=False, error=u'Insufficient users to connect') users = Participant.query.filter(Participant.event_id == event.id, Participant.nfc_id.in_(ids)).all() mail = Mail(app) message = Message("You connected with " + str(len(users) - 1) + " people using ContactExchange") message.cc = list() for user in users: email = '"' + user.name + '"<' + user.email + '>' if message.reply_to is None: message.reply_to = email message.add_recipient(email) else: message.cc.append(email) message.attach(make_name(user.name) + '.vcf', 'text/vcard', render_template('user_card.vcf', user=user, event=event)) message.sender = '"HasGeek"<*****@*****.**>' message.body = render_template('connectemail.md', users=users, event=event) message.html = markdown(message.body) log = CXLog() try: mail.send(message) log.sent = True log.log_message = u"Mail delivered to postfix server" except Exception as error: log.sent = True log.log_message = unicode(error) log.users = u','.join(ids) db.session.add(log) db.session.commit() return jsonify(success=True)
def send_mail(sender, to, body, subject): msg = Message(sender=sender, subject=subject, recipients=[to]) msg.body = body msg.html = markdown(msg.body) mail.send(msg)
def editsession(name, slug): space = ProposalSpace.query.filter_by(name=name).first() if not space: abort(404) proposal_id = int(slug.split('-')[0]) proposal = Proposal.query.get(proposal_id) if not proposal: abort(404) if proposal.user != g.user and not lastuser.has_permission('siteadmin'): abort(403) form = ProposalForm(obj=proposal) if not proposal.session_type: del form.session_type # Remove this if we're editing a proposal that had no session type form.section.query = ProposalSpaceSection.query.filter_by( proposal_space=space, public=True).order_by('title') if len(list(form.section.query.all())) == 0: # Don't bother with sections when there aren't any del form.section # Set markdown flag to True for fields that need markdown conversion markdown_attrs = ('description', 'objective', 'requirements', 'bio') for name in markdown_attrs: attr = getattr(form, name) attr.flags.markdown = True if proposal.user != g.user: del form.speaking elif request.method == 'GET': form.speaking.data = proposal.speaker == g.user if form.validate_on_submit(): form.populate_obj(proposal) proposal.name = makename(proposal.title) if proposal.user == g.user: # Only allow the speaker to change this status if form.speaking.data: proposal.speaker = g.user else: if proposal.speaker == g.user: proposal.speaker = None # Set *_html attributes after converting markdown text for name in markdown_attrs: attr = getattr(proposal, name) html_attr = name + '_html' setattr(proposal, html_attr, markdown(attr)) proposal.edited_at = datetime.utcnow() db.session.commit() flash("Your changes have been saved", "info") return redirect(url_for('viewsession', name=space.name, slug=proposal.urlname), code=303) return render_template( 'autoform.html', form=form, title="Edit session proposal", submit="Save changes", breadcrumbs=[(url_for('viewspace', name=space.name), space.title), (url_for('viewsession', name=space.name, slug=proposal.urlname), proposal.title)], message=Markup( 'This form uses <a href="http://daringfireball.net/projects/markdown/">Markdown</a> for formatting.' ))
def test_sample_markdown(self): assert markdown(sample_markdown) == sample_output
def test_sample_markdown_html(self): # In HTML mode, many characters are converted to HTML entities (by Bleach; side effect), # and code highlighting is dropped, as we cannot safely distinguish between markdown # highlighting and malicious user input. assert markdown(sample_markdown, html=True) == sample_output_html
def test_markdown(self): """Markdown rendering""" self.assertEqual(markdown("hello"), "<p>hello</p>")
def field_markdown(field): html = markdown(field) return Markup(html)
def test_markdown(self): """Markdown rendering""" assert markdown('hello') == '<p>hello</p>'
def test_empty_markdown(self): """Don't choke on None""" self.assertEqual(markdown(None), None)
def test_text_markdown(self): """Markdown rendering with HTML disabled (default)""" self.assertEqual(markdown('hello <del>there</del>'), '<p>hello <del>there</del></p>')
def field_markdown(field, **kwargs): html = markdown(field) return Markup(html)
def description(self, value): self._description = value self._description_html = markdown(value)
def viewsession(name, slug): space = ProposalSpace.query.filter_by(name=name).first() if not space: abort(404) try: proposal_id = int(slug.split('-')[0]) except ValueError: abort(404) proposal = Proposal.query.get(proposal_id) if not proposal: abort(404) if proposal.proposal_space != space: return redirect(url_for('viewsession', name=proposal.proposal_space.name, slug=proposal.urlname), code=301) if slug != proposal.urlname: return redirect(url_for('viewsession', name=proposal.proposal_space.name, slug=proposal.urlname), code=301) # URL is okay. Show the proposal. comments = sorted(Comment.query.filter_by(commentspace=proposal.comments, parent=None).order_by('created_at').all(), key=lambda c: c.votes.count, reverse=True) commentform = CommentForm() commentform.message.flags.markdown = True delcommentform = DeleteCommentForm() if request.method == 'POST': if request.form.get('form.id') == 'newcomment' and commentform.validate(): send_mail_info = [] if commentform.comment_edit_id.data: comment = Comment.query.get(int(commentform.comment_edit_id.data)) if comment: if comment.user == g.user: comment.message = commentform.message.data comment.message_html = markdown(comment.message) comment.edited_at = datetime.utcnow() flash("Your comment has been edited", "info") else: flash("You can only edit your own comments", "info") else: flash("No such comment", "error") else: comment = Comment(user=g.user, commentspace=proposal.comments, message=commentform.message.data) if commentform.parent_id.data: parent = Comment.query.get(int(commentform.parent_id.data)) if parent.user.email: if parent.user == proposal.user: # check if parent comment & proposal owner are same if not g.user == parent.user: # check if parent comment is by proposal owner send_mail_info.append({'to': proposal.user.email or proposal.email, 'subject': "%s Funnel:%s" % (name, proposal.title), 'template': 'proposal_comment_reply_email.md'}) else: # send mail to parent comment owner & proposal owner if not parent.user == g.user: send_mail_info.append({'to': parent.user.email, 'subject': "%s Funnel:%s" % (name, proposal.title), 'template': 'proposal_comment_to_proposer_email.md'}) if not proposal.user == g.user: send_mail_info.append({'to': proposal.user.email or proposal.email, 'subject': "%s Funnel:%s" % (name, proposal.title), 'template': 'proposal_comment_email.md'}) if parent and parent.commentspace == proposal.comments: comment.parent = parent else: # for top level comment if not proposal.user == g.user: send_mail_info.append({'to': proposal.user.email or proposal.email, 'subject': "%s Funnel:%s" % (name, proposal.title), 'template': 'proposal_comment_email.md'}) comment.message_html = markdown(comment.message) proposal.comments.count += 1 comment.votes.vote(g.user) # Vote for your own comment db.session.add(comment) flash("Your comment has been posted", "info") db.session.commit() to_redirect = url_for('viewsession', name=space.name, slug=proposal.urlname, _external=True) + "#c" + str(comment.id) for item in send_mail_info: email_body = render_template(item.pop('template'), proposal=proposal, comment=comment, link=to_redirect) send_mail(sender=None, body=email_body, **item) # Redirect despite this being the same page because HTTP 303 is required to not break # the browser Back button return redirect(to_redirect, code=303) elif request.form.get('form.id') == 'delcomment' and delcommentform.validate(): comment = Comment.query.get(int(delcommentform.comment_id.data)) if comment: if comment.user == g.user: comment.delete() proposal.comments.count -= 1 db.session.commit() flash("Your comment was deleted.", "info") else: flash("You did not post that comment.", "error") else: flash("No such comment.", "error") return redirect(url_for('viewsession', name=space.name, slug=proposal.urlname), code=303) links = [Markup(url_re.sub(urllink, unicode(escape(l)))) for l in proposal.links.replace('\r\n', '\n').split('\n') if l] confirmform = ConfirmSessionForm() return render_template('proposal.html', space=space, proposal=proposal, comments=comments, commentform=commentform, delcommentform=delcommentform, breadcrumbs=[(url_for('viewspace', name=space.name), space.title)], links=links, confirmform=confirmform)
def email(self): self.download() title = self.doattend.get_event_title() path = os.path.join(self.emaps_dir, self.event_id + '_form_link') if os.path.exists(path): with open(path, 'r') as f: link_data = json.loads(f.read()) else: fields = ['name', 'email', 'phone', 'addr1', 'addr2', 'city', 'pincode', 'state'] link_data = dict( link=raw_input("Enter form URL for %s: " % title), fields=dict()) for field in fields: link_data['fields'][field] = dict( key=raw_input("Enter field name for buyer's %s: " % field), value="") with open(path, 'w') as f: f.write(json.dumps(link_data)) f = open('tshirts/%s.csv' % self.event_id, 'w') csv = unicodecsv.writer(f, delimiter=",", quotechar='"') for buyer in self.buyers: if buyer[4] == "0": print "Sending mail for %s..." % buyer[0].encode('utf-8') try: msg = MIMEMultipart('alternative') if not hasattr(self, 'email_tag'): self.email_tag = raw_input('Change email subject tag. [Default: Urgent]:') if self.email_tag == "": self.email_tag = "Urgent" msg['Subject'] = "[%s]Your %s T-shirt" % (self.email_tag, title) msg['To'] = buyer[1] msg['From'] = '*****@*****.**' msg['Bcc'] = '*****@*****.**' fields = ['name', 'email', 'phone', 'city'] form_fields = deepcopy(link_data['fields']) for i, field in enumerate(fields): form_fields[field]['value'] = buyer[i] if buyer[5] == "1": fields = ['addr1', 'addr2', 'city', 'pincode', 'state'] for field in fields: form_fields[field]['value'] = "International" link = "%s?%s" % ( link_data['link'], urlencode(dict((field['key'], field['value'].encode('utf-8')) for key, field in form_fields.iteritems() if field['value']))) env = Environment(loader=PackageLoader('eventer', 'templates')) if os.path.exists(os.path.join('eventer', 'templates', 'custom', self.event_id + '_tshirt_email.md')): template = env.get_template('custom/%s_tshirt_email.md' % self.event_id) else: if not hasattr(self, 'email_without_template'): self.email_without_template = False if self.no_template or yes_no('No custom template available. Send using generic email?'): self.email_without_template = True template = env.get_template('tshirt_email.md') else: sys.exit(1) text = template.render(title=title, name=buyer[0], link=link, international=bool(int(buyer[5])), source=buyer[6]) html = markdown(text) msg.attach(MIMEText(text.encode('utf-8'), 'plain')) msg.attach(MIMEText(html.encode('utf-8'), 'html')) to = [buyer[1], msg['Bcc']] self.mailer.sendmail(msg['From'], to, msg.as_string()) buyer[4] = "1" except: print "Failed sending email for %s..." % buyer[0].encode('utf-8') csv.writerow(buyer)
def viewsession(name, slug): space = ProposalSpace.query.filter_by(name=name).first() if not space: abort(404) try: proposal_id = int(slug.split('-')[0]) except ValueError: abort(404) proposal = Proposal.query.get(proposal_id) if not proposal: abort(404) if proposal.proposal_space != space: return redirect(url_for('viewsession', name=proposal.proposal_space.name, slug=proposal.urlname), code=301) if slug != proposal.urlname: return redirect(url_for('viewsession', name=proposal.proposal_space.name, slug=proposal.urlname), code=301) # URL is okay. Show the proposal. comments = sorted( Comment.query.filter_by(commentspace=proposal.comments, parent=None).order_by('created_at').all(), key=lambda c: c.votes.count, reverse=True) commentform = CommentForm() commentform.message.flags.markdown = True delcommentform = DeleteCommentForm() if request.method == 'POST': if request.form.get( 'form.id') == 'newcomment' and commentform.validate(): send_mail_info = [] if commentform.edit_id.data: comment = Comment.query.get(int(commentform.edit_id.data)) if comment: if comment.user == g.user: comment.message = commentform.message.data comment.message_html = markdown(comment.message) comment.edited_at = datetime.utcnow() flash("Your comment has been edited", "info") else: flash("You can only edit your own comments", "info") else: flash("No such comment", "error") else: comment = Comment(user=g.user, commentspace=proposal.comments, message=commentform.message.data) if commentform.parent_id.data: parent = Comment.query.get(int(commentform.parent_id.data)) if parent.user.email: if parent.user == proposal.user: # check if parent comment & proposal owner are same if not g.user == parent.user: # check if parent comment is by proposal owner send_mail_info.append({ 'to': proposal.user.email or proposal.email, 'subject': "%s Funnel:%s" % (name, proposal.title), 'template': 'proposal_comment_reply_email.md' }) else: # send mail to parent comment owner & proposal owner if not parent.user == g.user: send_mail_info.append({ 'to': parent.user.email, 'subject': "%s Funnel:%s" % (name, proposal.title), 'template': 'proposal_comment_to_proposer_email.md' }) if not proposal.user == g.user: send_mail_info.append({ 'to': proposal.user.email or proposal.email, 'subject': "%s Funnel:%s" % (name, proposal.title), 'template': 'proposal_comment_email.md' }) if parent and parent.commentspace == proposal.comments: comment.parent = parent else: # for top level comment if not proposal.user == g.user: send_mail_info.append({ 'to': proposal.user.email or proposal.email, 'subject': "%s Funnel:%s" % (name, proposal.title), 'template': 'proposal_comment_email.md' }) comment.message_html = markdown(comment.message) proposal.comments.count += 1 comment.votes.vote(g.user) # Vote for your own comment db.session.add(comment) flash("Your comment has been posted", "info") send_comment_mail(proposal, comment) db.session.commit() to_redirect = url_for('viewsession', name=space.name, slug=proposal.urlname, _external=True) + "#c" + str(comment.id) for item in send_mail_info: email_body = render_template(item.pop('template'), proposal=proposal, comment=comment, link=to_redirect) send_mail(sender=None, body=email_body, **item) # Redirect despite this being the same page because HTTP 303 is required to not break # the browser Back button return redirect(to_redirect, code=303) elif request.form.get( 'form.id') == 'delcomment' and delcommentform.validate(): comment = Comment.query.get(int(delcommentform.comment_id.data)) if comment: if comment.user == g.user: comment.delete() proposal.comments.count -= 1 db.session.commit() flash("Your comment was deleted.", "info") else: flash("You did not post that comment.", "error") else: flash("No such comment.", "error") return redirect(url_for('viewsession', name=space.name, slug=proposal.urlname), code=303) links = [ Markup(url_re.sub(urllink, unicode(escape(l)))) for l in proposal.links.replace('\r\n', '\n').split('\n') if l ] confirmform = ConfirmSessionForm() return render_template('proposal.html', space=space, proposal=proposal, comments=comments, commentform=commentform, delcommentform=delcommentform, breadcrumbs=[(url_for('viewspace', name=space.name), space.title)], links=links, confirmform=confirmform)
def test_empty_markdown(self): """Don't choke on None""" assert markdown(None) is None
def process_video(video, new=False): """ Get metadata for the video from the corresponding site """ # Parse the video url if video.video_url: parsed = urlparse(video.video_url) # Check video source and get corresponding data if parsed.netloc in ['youtube.com', 'www.youtube.com']: try: video_id = parse_qs(parsed.query)['v'][0] r = requests.get( 'https://www.googleapis.com/youtube/v3/videos?part=snippet&id={video_id}&key={api_key}' .format(video_id=video_id, api_key=app.config['YOUTUBE_API_KEY'])) try: jsondata = r.json() except ValueError as e: app.logger.error( "Error while fetching video details\n\nError: {error}\nResponse body: {response}" .format(error=e.message, response=r.text)) raise DataProcessingError( "Unable to parse video data, please try after sometime" ) if jsondata is None or len(jsondata['items']) == 0: raise DataProcessingError( "Unable to fetch data, please check the youtube url") else: jsondata = jsondata['items'][0] if new: video.title = jsondata['snippet']['title'] video.description = markdown( jsondata['snippet']['description']) thumbnail_url_request = requests.get( jsondata['snippet']['thumbnails']['medium']['url']) filestorage = return_werkzeug_filestorage( thumbnail_url_request, filename=secure_filename(video.title)) video.thumbnail_path = thumbnails.save(filestorage) video.video_sourceid = video_id video.video_source = u"youtube" except requests.ConnectionError: raise DataProcessingError("Unable to establish connection") except gaierror: raise DataProcessingError("Unable to resolve the hostname") except KeyError: raise DataProcessingError( "Supplied youtube URL doesn't contain video information") elif parsed.netloc in ['vimeo.com', 'www.vimeo.com']: try: components = parsed.path.split('/') if len(components) == 2: try: video_id = int(components[-1]) except ValueError: raise ValueError( "Invalid Video Id. Example: https://vimeo.com/42595773" ) r = requests.get("https://vimeo.com/api/v2/video/%s.json" % (video_id)) jsondata = r.json() if jsondata is None: raise DataProcessingError( "Unable to fetch, please check the vimeo url") else: if jsondata[0][u'embed_privacy'] != u'anywhere': raise DataProcessingError( "Video is not public to import.") if new: video.title, video.description = jsondata[0][ 'title'], bleach.clean( jsondata[0]['description'], tags=SANITIZE_TAGS, attributes=SANITIZE_ATTRIBUTES) if jsondata[0]['thumbnail_medium']: thumbnail_url_request = requests.get( jsondata[0]['thumbnail_large']) filestorage = return_werkzeug_filestorage( thumbnail_url_request, filename=secure_filename(jsondata[0]['title'])) video.thumbnail_path = thumbnails.save(filestorage) video.video_sourceid, video.video_source, video.video_url = video_id, u"vimeo", jsondata[ 0]['url'] else: raise DataProcessingError( "Invalid Vimeo url. Example: https://vimeo.com/42595773" ) except requests.ConnectionError: raise DataProcessingError("Unable to establish connection") except gaierror: raise DataProcessingError("Unable to resolve the hostname") except KeyError: raise DataProcessingError("") elif parsed.netloc in ["ustream.tv", "www.ustream.tv"]: try: components = [ item for item in parsed.path.split("/") if item != "" ] if len(components) == 2: try: video_id = int(components[-1]) except ValueError: raise ValueError( "Invalid Ustream Id. Example: https://www.ustream.tv/channel/6320346" ) try: r = requests.get( "https://api.ustream.tv/json/channel/%s/getInfo" % (components[1]), params={"key": app.config['USTREAM_KEY']}) except KeyError: raise DataProcessingError( "Ustream Developer key is missing") jsondata = r.json() if jsondata is None: raise DataProcessingError( "Unable to fetch, please check the ustream url") else: if new: video.title, video.description = jsondata[ 'results']['title'], markdown( jsondata['results']['description']) or "" if jsondata['results']['imageUrl']: thumbnail_url_request = requests.get( jsondata['results']['imageUrl']['medium']) filestorage = return_werkzeug_filestorage( thumbnail_url_request, filename=secure_filename( jsondata['results']['title'])) video.thumbnail_path = thumbnails.save(filestorage) video.video_sourceid, video.video_source = video_id, u"ustream" else: raise DataProcessingError( "Invalid ustream url. Example: https://www.ustream.tv/channel/6320346" ) except requests.ConnectionError: raise DataProcessingError("Unable to establish connection") except gaierror: raise DataProcessingError("Unable to resolve the hostname") except KeyError as e: raise DataProcessingError(e) else: raise ValueError("Unsupported video site") else: raise ValueError("Video URL is missing")
def field_markdown(text: str) -> Markup: """Render text as Markdown.""" return Markup(markdown(text))
def test_markdown(self): """Markdown rendering""" self.assertEqual(markdown('hello'), '<p>hello</p>')
def process_playlist(playlist, playlist_url): """ Get metadata for the playlist from the corresponding site """ # Parse the playlist url if playlist_url: parsed = urlparse(escape(playlist_url)) # Check video source and get corresponding data if parsed.netloc in ['youtube.com', 'www.youtube.com']: try: stream_playlist = playlist.channel.playlist_for_stream(create=True) # first two character of playlist id says what type of playlist, ignore them playlist_id = parse_qs(parsed.query)['list'][0][2:] youtube = build('youtube', 'v3', developerKey=app.config['YOUTUBE_API_KEY']) playlistitems_list_request = youtube.playlistItems().list( playlistId=playlist_id, part='snippet', maxResults=50 ) playlist_info_request = youtube.playlists().list( id=playlist_id, part='snippet' ) if playlist_info_request: playlist_infos = playlist_info_request.execute() for playlist_info in playlist_infos['items']: playlist.title = playlist.title or playlist_info['snippet']['title'] if playlist_info['snippet']['description']: playlist.description = playlist_info['snippet']['description'] while playlistitems_list_request: playlistitems_list_response = playlistitems_list_request.execute() for playlist_item in playlistitems_list_response['items']: with db.session.no_autoflush: video = Video.query.filter_by(video_source=u'youtube', channel=playlist.channel, video_sourceid=playlist_item['snippet']['resourceId']['videoId']).first() if video: if video not in stream_playlist.videos: stream_playlist.videos.append(video) if video not in playlist.videos: playlist.videos.append(video) else: video = Video(playlist=playlist if playlist is not None else stream_playlist) video.title = playlist_item['snippet']['title'] video.video_url = 'https://www.youtube.com/watch?v='+playlist_item['snippet']['resourceId']['videoId'] if playlist_item['snippet']['description']: video.description = markdown(playlist_item['snippet']['description']) for thumbnail in playlist_item['snippet']['thumbnails']['medium']: thumbnail_url_request = requests.get(playlist_item['snippet']['thumbnails']['medium']['url']) filestorage = return_werkzeug_filestorage(thumbnail_url_request, filename=secure_filename(playlist_item['snippet']['title']) or 'name-missing') video.thumbnail_path = thumbnails.save(filestorage) video.video_sourceid = playlist_item['snippet']['resourceId']['videoId'] video.video_source = u'youtube' video.make_name() playlist.videos.append(video) with db.session.no_autoflush: if video not in stream_playlist.videos: stream_playlist.videos.append(video) playlistitems_list_request = youtube.playlistItems().list_next( playlistitems_list_request, playlistitems_list_response) except requests.ConnectionError: raise DataProcessingError("Unable to establish connection") except gaierror: raise DataProcessingError("Unable to resolve the hostname") except KeyError: raise DataProcessingError("Supplied youtube URL doesn't contain video information") except HttpError: raise DataProcessingError("HTTPError while parsing YouTube playlist") else: raise ValueError("Unsupported video site") else: raise ValueError("Video URL is missing")
def process_video(video, new=False): """ Get metadata for the video from the corresponding site """ # Parse the video url if video.video_url: parsed = urlparse(video.video_url) # Check video source and get corresponding data if parsed.netloc in ['youtube.com', 'www.youtube.com']: try: video_id = parse_qs(parsed.query)['v'][0] r = requests.get('https://gdata.youtube.com/feeds/api/videos/%s?v=2&alt=json' % video_id) jsondata = r.json() if callable(r.json) else r.json if jsondata is None: raise DataProcessingError("Unable to fetch data, please check the youtube url") else: if new: video.title = jsondata['entry']['title']['$t'] video.description = markdown(jsondata['entry']['media$group']['media$description']['$t']) for item in jsondata['entry']['media$group']['media$thumbnail']: if item['yt$name'] == 'mqdefault': thumbnail_url_request = requests.get(item['url']) filestorage = return_werkzeug_filestorage(thumbnail_url_request, filename=secure_filename(jsondata['entry']['title']['$t'])) video.thumbnail_path = thumbnails.save(filestorage) video.video_sourceid = video_id video.video_source = u"youtube" except requests.ConnectionError: raise DataProcessingError("Unable to establish connection") except gaierror: raise DataProcessingError("Unable to resolve the hostname") except KeyError: raise DataProcessingError("Supplied youtube URL doesn't contain video information") elif parsed.netloc in ['vimeo.com', 'www.vimeo.com']: try: components = parsed.path.split('/') if len(components) == 2: try: video_id = int(components[-1]) except ValueError: raise ValueError("Invalid Video Id. Example: https://vimeo.com/42595773") r = requests.get("https://vimeo.com/api/v2/video/%s.json" % (video_id)) jsondata = r.json() if callable(r.json) else r.json if jsondata is None: raise DataProcessingError("Unable to fetch, please check the vimeo url") else: if jsondata[0][u'embed_privacy'] != u'anywhere': raise DataProcessingError("Video is not public to import.") if new: video.title, video.description = jsondata[0]['title'], bleach.clean(jsondata[0]['description'], tags=SANITIZE_TAGS, attributes=SANITIZE_ATTRIBUTES) if jsondata[0]['thumbnail_medium']: thumbnail_url_request = requests.get(jsondata[0]['thumbnail_large']) filestorage = return_werkzeug_filestorage(thumbnail_url_request, filename=secure_filename(jsondata[0]['title'])) video.thumbnail_path = thumbnails.save(filestorage) video.video_sourceid, video.video_source, video.video_url = video_id, u"vimeo", jsondata[0]['url'] else: raise DataProcessingError("Invalid Vimeo url. Example: https://vimeo.com/42595773") except requests.ConnectionError: raise DataProcessingError("Unable to establish connection") except gaierror: raise DataProcessingError("Unable to resolve the hostname") except KeyError: raise DataProcessingError("") elif parsed.netloc in ["ustream.tv", "www.ustream.tv"]: try: components = [item for item in parsed.path.split("/") if item != ""] if len(components) == 2: try: video_id = int(components[-1]) except ValueError: raise ValueError("Invalid Ustream Id. Example: https://www.ustream.tv/channel/6320346") try: r = requests.get("https://api.ustream.tv/json/channel/%s/getInfo" % (components[1]), params={"key": app.config['USTREAM_KEY']}) except KeyError: raise DataProcessingError("Ustream Developer key is missing") jsondata = r.json() if callable(r.json) else r.json if jsondata is None: raise DataProcessingError("Unable to fetch, please check the ustream url") else: if new: video.title, video.description = jsondata['results']['title'], markdown(jsondata['results']['description']) or "" if jsondata['results']['imageUrl']: thumbnail_url_request = requests.get(jsondata['results']['imageUrl']['medium']) filestorage = return_werkzeug_filestorage(thumbnail_url_request, filename=secure_filename(jsondata['results']['title'])) video.thumbnail_path = thumbnails.save(filestorage) video.video_sourceid, video.video_source = video_id, u"ustream" else: raise DataProcessingError("Invalid ustream url. Example: https://www.ustream.tv/channel/6320346") except requests.ConnectionError: raise DataProcessingError("Unable to establish connection") except gaierror: raise DataProcessingError("Unable to resolve the hostname") except KeyError as e: raise DataProcessingError(e) else: raise ValueError("Unsupported video site") else: raise ValueError("Video URL is missing")
def send_mail(sender, to, body, subject): msg = Message(sender=sender, subject=subject, recipients=[to]) msg.body = body msg.html = markdown(msg.body) # FIXME: This does not include HTML head/body tags mail.send(msg)
def process_playlist(playlist, playlist_url): """ Get metadata for the playlist from the corresponding site """ # Parse the playlist url if playlist_url: parsed = urlparse(escape(playlist_url)) # Check video source and get corresponding data if parsed.netloc in ['youtube.com', 'www.youtube.com']: try: stream_playlist = playlist.channel.playlist_for_stream( create=True) # first two character of playlist id says what type of playlist, ignore them playlist_id = parse_qs(parsed.query)['list'][0][2:] youtube = build('youtube', 'v3', developerKey=app.config['YOUTUBE_API_KEY']) playlistitems_list_request = youtube.playlistItems().list( playlistId=playlist_id, part='snippet', maxResults=50) playlist_info_request = youtube.playlists().list( id=playlist_id, part='snippet') if playlist_info_request: playlist_infos = playlist_info_request.execute() for playlist_info in playlist_infos['items']: playlist.title = playlist.title or playlist_info[ 'snippet']['title'] if playlist_info['snippet']['description']: playlist.description = playlist_info['snippet'][ 'description'] while playlistitems_list_request: playlistitems_list_response = playlistitems_list_request.execute( ) for playlist_item in playlistitems_list_response['items']: with db.session.no_autoflush: video = Video.query.filter_by( video_source=u'youtube', channel=playlist.channel, video_sourceid=playlist_item['snippet'] ['resourceId']['videoId']).first() if video: if video not in stream_playlist.videos: stream_playlist.videos.append(video) if video not in playlist.videos: playlist.videos.append(video) else: video = Video(playlist=playlist if playlist is not None else stream_playlist) video.title = playlist_item['snippet']['title'] video.video_url = 'https://www.youtube.com/watch?v=' + playlist_item[ 'snippet']['resourceId']['videoId'] if playlist_item['snippet']['description']: video.description = markdown( playlist_item['snippet']['description']) for thumbnail in playlist_item['snippet'][ 'thumbnails']['medium']: thumbnail_url_request = requests.get( playlist_item['snippet']['thumbnails'] ['medium']['url']) filestorage = return_werkzeug_filestorage( thumbnail_url_request, filename=secure_filename( playlist_item['snippet']['title']) or 'name-missing') video.thumbnail_path = thumbnails.save( filestorage) video.video_sourceid = playlist_item['snippet'][ 'resourceId']['videoId'] video.video_source = u'youtube' video.make_name() playlist.videos.append(video) with db.session.no_autoflush: if video not in stream_playlist.videos: stream_playlist.videos.append(video) playlistitems_list_request = youtube.playlistItems( ).list_next(playlistitems_list_request, playlistitems_list_response) except requests.ConnectionError: raise DataProcessingError("Unable to establish connection") except gaierror: raise DataProcessingError("Unable to resolve the hostname") except KeyError: raise DataProcessingError( "Supplied youtube URL doesn't contain video information") except HttpError: raise DataProcessingError( "HTTPError while parsing YouTube playlist") else: raise ValueError("Unsupported video site") else: raise ValueError("Video URL is missing")
def inner(start_index=1, max_result=50, total=0): """Retireves youtube playlist videos recursively :param start_index: Index to start for fetching videos in playlist :param max_result: Maximum results to return :param total: variable to keep track of total videos fetched """ r = requests.get('http://gdata.youtube.com/feeds/api/playlists/%s?v=2&alt=json&max-result=50&start-index=%d' % (playlist_id, start_index)) jsondata = r.json() if callable(r.json) else r.json if jsondata is None: raise DataProcessingError("Unable to fetch data, please check the youtube url") else: # fetch playlist info # prevent overwriting title during Extend playlist playlist.title = playlist.title or jsondata['feed']['title']['$t'] if 'media$description' in jsondata['feed']['media$group']: playlist.description = markdown(jsondata['feed']['media$group']['media$description']['$t']) for item in jsondata['feed'].get('entry', []): if item.get('app$control', {}).get('yt$state', {}).get('reasonCode'): # Is it private? continue videos = Video.query.filter_by(video_source=u"youtube", video_sourceid=item['media$group']['yt$videoid']['$t']).all() if videos: # If video isn't present in current playlist, copy the video parameters if not filter(lambda video: video.playlist == playlist, videos): new_video = Video(playlist=playlist if playlist is not None else stream_playlist) video = videos[0] new_video.name = video.name new_video.title = video.title new_video.video_url = video.video_url new_video.description = markdown(video.description) new_video.thumbnail_path = video.thumbnail_path new_video.video_source = u"youtube" new_video.video_sourceid = video.video_sourceid playlist.videos.append(new_video) if new_video not in stream_playlist.videos: stream_playlist.videos.append(new_video) else: video = Video(playlist=playlist if playlist is not None else stream_playlist) video.title = item['title']['$t'] video.video_url = item['media$group']['media$player']['url'] if 'media$description' in item['media$group']: video.description = markdown(item['media$group']['media$description']['$t']) for video_content in item['media$group']['media$thumbnail']: if video_content['yt$name'] == 'mqdefault': thumbnail_url_request = requests.get(video_content['url']) filestorage = return_werkzeug_filestorage(thumbnail_url_request, filename=secure_filename(item['title']['$t']) or 'name-missing') video.thumbnail_path = thumbnails.save(filestorage) video.video_sourceid = item['media$group']['yt$videoid']['$t'] video.video_source = u"youtube" video.make_name() playlist.videos.append(video) if video not in stream_playlist.videos: stream_playlist.videos.append(video) #When no more data is present to retrieve in playlist 'feed' is absent in json if 'entry' in jsondata['feed']: total += len(jsondata['feed']['entry']) if total <= jsondata['feed']['openSearch$totalResults']: # check for empty playlist if not jsondata['feed'].get('entry', []): raise DataProcessingError("Empty Playlist") inner(start_index=total + 1, total=total)
def message(self, value): self._message = value self._message_html = markdown(value)
def test_html_markdown(self): """Markdown rendering with HTML enabled""" self.assertEqual(markdown('hello <del>there</del>', html=True), '<p>hello <del>there</del></p>')
def send_mail(sender, to, body, subject): msg = Message(sender=sender, subject=subject, recipients=[to]) msg.body = body msg.html = markdown( msg.body) # FIXME: This does not include HTML head/body tags mail.send(msg)
def process_video(video, new=False): """ Get metadata for the video from the corresponding site """ # Parse the video url if video.video_url: parsed = urlparse(video.video_url) # Check video source and get corresponding data if parsed.netloc in ['youtube.com', 'www.youtube.com']: try: video_id = parse_qs(parsed.query)['v'][0] r = requests.get('https://www.googleapis.com/youtube/v3/videos?part=snippet&id={video_id}&key={api_key}'.format( video_id=video_id, api_key=app.config['YOUTUBE_API_KEY'] )) try: jsondata = r.json() except ValueError as e: app.logger.error("Error while fetching video details\n\nError: {error}\nResponse body: {response}".format( error=e.message, response=r.text)) raise DataProcessingError("Unable to parse video data, please try after sometime") if jsondata is None or len(jsondata['items']) == 0: raise DataProcessingError("Unable to fetch data, please check the youtube url") else: jsondata = jsondata['items'][0] if new: video.title = jsondata['snippet']['title'] video.description = markdown(jsondata['snippet']['description']) thumbnail_url_request = requests.get(jsondata['snippet']['thumbnails']['medium']['url']) filestorage = return_werkzeug_filestorage(thumbnail_url_request, filename=secure_filename(video.title)) video.thumbnail_path = thumbnails.save(filestorage) video.video_sourceid = video_id video.video_source = u"youtube" except requests.ConnectionError: raise DataProcessingError("Unable to establish connection") except gaierror: raise DataProcessingError("Unable to resolve the hostname") except KeyError: raise DataProcessingError("Supplied youtube URL doesn't contain video information") elif parsed.netloc in ['vimeo.com', 'www.vimeo.com']: try: components = parsed.path.split('/') if len(components) == 2: try: video_id = int(components[-1]) except ValueError: raise ValueError("Invalid Video Id. Example: https://vimeo.com/42595773") r = requests.get("https://vimeo.com/api/v2/video/%s.json" % (video_id)) jsondata = r.json() if jsondata is None: raise DataProcessingError("Unable to fetch, please check the vimeo url") else: if jsondata[0][u'embed_privacy'] != u'anywhere': raise DataProcessingError("Video is not public to import.") if new: video.title, video.description = jsondata[0]['title'], bleach.clean(jsondata[0]['description'], tags=SANITIZE_TAGS, attributes=SANITIZE_ATTRIBUTES) if jsondata[0]['thumbnail_medium']: thumbnail_url_request = requests.get(jsondata[0]['thumbnail_large']) filestorage = return_werkzeug_filestorage(thumbnail_url_request, filename=secure_filename(jsondata[0]['title'])) video.thumbnail_path = thumbnails.save(filestorage) video.video_sourceid, video.video_source, video.video_url = video_id, u"vimeo", jsondata[0]['url'] else: raise DataProcessingError("Invalid Vimeo url. Example: https://vimeo.com/42595773") except requests.ConnectionError: raise DataProcessingError("Unable to establish connection") except gaierror: raise DataProcessingError("Unable to resolve the hostname") except KeyError: raise DataProcessingError("") elif parsed.netloc in ["ustream.tv", "www.ustream.tv"]: try: components = [item for item in parsed.path.split("/") if item != ""] if len(components) == 2: try: video_id = int(components[-1]) except ValueError: raise ValueError("Invalid Ustream Id. Example: https://www.ustream.tv/channel/6320346") try: r = requests.get("https://api.ustream.tv/json/channel/%s/getInfo" % (components[1]), params={"key": app.config['USTREAM_KEY']}) except KeyError: raise DataProcessingError("Ustream Developer key is missing") jsondata = r.json() if jsondata is None: raise DataProcessingError("Unable to fetch, please check the ustream url") else: if new: video.title, video.description = jsondata['results']['title'], markdown(jsondata['results']['description']) or "" if jsondata['results']['imageUrl']: thumbnail_url_request = requests.get(jsondata['results']['imageUrl']['medium']) filestorage = return_werkzeug_filestorage(thumbnail_url_request, filename=secure_filename(jsondata['results']['title'])) video.thumbnail_path = thumbnails.save(filestorage) video.video_sourceid, video.video_source = video_id, u"ustream" else: raise DataProcessingError("Invalid ustream url. Example: https://www.ustream.tv/channel/6320346") except requests.ConnectionError: raise DataProcessingError("Unable to establish connection") except gaierror: raise DataProcessingError("Unable to resolve the hostname") except KeyError as e: raise DataProcessingError(e) else: raise ValueError("Unsupported video site") else: raise ValueError("Video URL is missing")