mirror of
https://github.com/viq/NewsBlur.git
synced 2025-08-05 16:49:45 +00:00
Newsletters partially work. Still need to handle them during feed fetching.
This commit is contained in:
parent
f7bdd5b8c8
commit
802e9a10b0
4 changed files with 134 additions and 5 deletions
|
@ -1,3 +1,82 @@
|
|||
import datetime
|
||||
import re
|
||||
from django.db import models
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.urlresolvers import reverse
|
||||
from apps.rss_feeds.models import Feed, MStory, MFetchHistory
|
||||
from apps.reader.models import UserSubscription, UserSubscriptionFolders
|
||||
from apps.profile.models import Profile
|
||||
from utils import log as logging
|
||||
|
||||
# Create your models here.
|
||||
class EmailNewsletter:
|
||||
|
||||
def receive_newsletter(self, params):
|
||||
user = self.user_from_email(params['recipient'])
|
||||
if not user:
|
||||
return
|
||||
|
||||
sender_name, sender_domain = params['sender'].split('@')
|
||||
feed_address = self.feed_address(user, params['sender'])
|
||||
|
||||
usf = UserSubscriptionFolders.objects.get(user=user)
|
||||
usf.add_folder('', 'Newsletters')
|
||||
|
||||
try:
|
||||
feed = Feed.objects.get(feed_address=feed_address)
|
||||
except Feed.DoesNotExist:
|
||||
feed = Feed.objects.create(feed_address=feed_address,
|
||||
feed_link=sender_domain,
|
||||
feed_title=sender_name,
|
||||
fetched_once=True,
|
||||
known_good=True)
|
||||
feed.set_next_scheduled_update()
|
||||
|
||||
try:
|
||||
usersub = UserSubscription.objects.get(user=user, feed=feed)
|
||||
except UserSubscription.DoesNotExist:
|
||||
_, _, usersub = UserSubscription.add_subscription(
|
||||
user=user,
|
||||
feed_address=feed_address,
|
||||
folder='Newsletters'
|
||||
)
|
||||
|
||||
story_hash = MStory.ensure_story_hash(params['signature'], feed.pk)
|
||||
story_params = {
|
||||
"story_feed_id": feed.pk,
|
||||
"story_date": datetime.datetime.fromtimestamp(int(params['timestamp'])),
|
||||
"story_title": params['subject'],
|
||||
"story_content": params['body-html'],
|
||||
"story_author_name": sender_name,
|
||||
"story_permalink": reverse('newsletter-story',
|
||||
kwargs={'story_hash': story_hash}),
|
||||
"story_guid": params['signature'],
|
||||
}
|
||||
try:
|
||||
story = MStory.objects.get(story_hash=story_hash)
|
||||
except MStory.DoesNotExist:
|
||||
story = MStory(**story_params)
|
||||
story.save()
|
||||
|
||||
MFetchHistory.add(feed_id=feed.pk, fetch_type='push')
|
||||
|
||||
return story
|
||||
|
||||
def user_from_email(self, email):
|
||||
tokens = re.search('(\w+)\+(\w+)@newsletters.newsblur.com', email)
|
||||
if not tokens:
|
||||
return
|
||||
|
||||
username, secret_token = tokens.groups()
|
||||
try:
|
||||
profiles = Profile.objects.filter(secret_token=secret_token)
|
||||
if not profiles:
|
||||
return
|
||||
profile = profiles[0]
|
||||
except Profile.DoesNotExist:
|
||||
return
|
||||
|
||||
return profile.user
|
||||
|
||||
def feed_address(self, user, sender):
|
||||
return 'newsletter:%s:%s' % (user.pk, sender)
|
||||
|
|
@ -2,5 +2,6 @@ from django.conf.urls import *
|
|||
from apps.newsletters import views
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^/?$', views.newsletter_receive, name='newsletter-receive'),
|
||||
url(r'^receive/?$', views.newsletter_receive, name='newsletter-receive'),
|
||||
url(r'^story/(?P<story_hash>[\w:]+)/?$', views.newsletter_story, name='newsletter-story'),
|
||||
)
|
||||
|
|
|
@ -1,8 +1,50 @@
|
|||
from django.http import HttpResponse, Http404
|
||||
from utils import log as logging
|
||||
|
||||
from apps.newsletters.models import EmailNewsletter
|
||||
from apps.rss_feeds.models import Feed, MStory
|
||||
|
||||
def newsletter_receive(request):
|
||||
logging.debug(request.REQUEST)
|
||||
params = {
|
||||
'stripped-signature':'Thanks,\nBob',
|
||||
'From':'Bob <bob@newsletters.newsblur.com>',
|
||||
'attachment-count':'2',
|
||||
'To':'Alice <alice@newsletters.newsblur.com>',
|
||||
'subject':'Re: Sample POST request',
|
||||
'from':'Bob <bob@newsletters.newsblur.com>',
|
||||
'User-Agent':'Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130308 Thunderbird/17.0.4',
|
||||
'stripped-html':'<html><head><meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type"></head><body text="#000000" bgcolor="#FFFFFF">\n <div class="moz-cite-prefix">\n <div style="color: rgb(34, 34, 34); font-family: arial,\n sans-serif; font-size: 12.666666984558105px; font-style: normal;\n font-variant: normal; font-weight: normal; letter-spacing:\n normal; line-height: normal; orphans: auto; text-align: start;\n text-indent: 0px; text-transform: none; white-space: normal;\n widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto;\n -webkit-text-stroke-width: 0px; background-color: rgb(255, 255,\n 255);">Hi Alice,</div>\n <div style="color: rgb(34, 34, 34); font-family: arial,\n sans-serif; font-size: 12.666666984558105px; font-style: normal;\n font-variant: normal; font-weight: normal; letter-spacing:\n normal; line-height: normal; orphans: auto; text-align: start;\n text-indent: 0px; text-transform: none; white-space: normal;\n widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto;\n -webkit-text-stroke-width: 0px; background-color: rgb(255, 255,\n 255);"><br></div>\n <div style="color: rgb(34, 34, 34); font-family: arial,\n sans-serif; font-size: 12.666666984558105px; font-style: normal;\n font-variant: normal; font-weight: normal; letter-spacing:\n normal; line-height: normal; orphans: auto; text-align: start;\n text-indent: 0px; text-transform: none; white-space: normal;\n widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto;\n -webkit-text-stroke-width: 0px; background-color: rgb(255, 255,\n 255);">This is Bob.<span class="Apple-converted-space"> <img alt="" src="cid:part1.04060802.06030207@newsletters.newsblur.com" height="15" width="33"></span></div>\n <div style="color: rgb(34, 34, 34); font-family: arial,\n sans-serif; font-size: 12.666666984558105px; font-style: normal;\n font-variant: normal; font-weight: normal; letter-spacing:\n normal; line-height: normal; orphans: auto; text-align: start;\n text-indent: 0px; text-transform: none; white-space: normal;\n widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto;\n -webkit-text-stroke-width: 0px; background-color: rgb(255, 255,\n 255);"><br>\n I also attached a file.<br><br></div>\n <div style="color: rgb(34, 34, 34); font-family: arial,\n sans-serif; font-size: 12.666666984558105px; font-style: normal;\n font-variant: normal; font-weight: normal; letter-spacing:\n normal; line-height: normal; orphans: auto; text-align: start;\n text-indent: 0px; text-transform: none; white-space: normal;\n widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto;\n -webkit-text-stroke-width: 0px; background-color: rgb(255, 255,\n 255);">Thanks,</div>\n <div style="color: rgb(34, 34, 34); font-family: arial,\n sans-serif; font-size: 12.666666984558105px; font-style: normal;\n font-variant: normal; font-weight: normal; letter-spacing:\n normal; line-height: normal; orphans: auto; text-align: start;\n text-indent: 0px; text-transform: none; white-space: normal;\n widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto;\n -webkit-text-stroke-width: 0px; background-color: rgb(255, 255,\n 255);">Bob</div>\n <br><br></div>\n <br></body></html>',
|
||||
'In-Reply-To':'<517AC78B.5060404@newsletters.newsblur.com>',
|
||||
'Date':'Fri, 26 Apr 2013 11:50:29 -0700',
|
||||
'Message-Id':'<517ACC75.5010709@newsletters.newsblur.com>',
|
||||
'body-plain':'Hi Alice,\n\nThis is Bob.\n\nI also attached a file.\n\nThanks,\nBob\n\nOn 04/26/2013 11:29 AM, Alice wrote:\n> Hi Bob,\n>\n> This is Alice. How are you doing?\n>\n> Thanks,\n> Alice\n\n',
|
||||
'Mime-Version':'1.0',
|
||||
'Received':'from [10.20.76.69] (Unknown [50.56.129.169]) by mxa.mailgun.org with ESMTP id 517acc75.4b341f0-worker2; Fri, 26 Apr 2013 18:50:29 -0000 (UTC)',
|
||||
'content-id-map':'{"<part1.04060802.06030207@newsletters.newsblur.com>": "attachment-1"}',
|
||||
'Sender':'bob@newsletters.newsblur.com',
|
||||
'timestamp':'1455054490',
|
||||
'message-headers':'[["Received", "by luna.mailgun.net with SMTP mgrt 8788212249833; Fri, 26 Apr 2013 18:50:30 +0000"], ["Received", "from [10.20.76.69] (Unknown [50.56.129.169]) by mxa.mailgun.org with ESMTP id 517acc75.4b341f0-worker2; Fri, 26 Apr 2013 18:50:29 -0000 (UTC)"], ["Message-Id", "<517ACC75.5010709@newsletters.newsblur.com>"], ["Date", "Fri, 26 Apr 2013 11:50:29 -0700"], ["From", "Bob <bob@newsletters.newsblur.com>"], ["User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130308 Thunderbird/17.0.4"], ["Mime-Version", "1.0"], ["To", "Alice <alice@newsletters.newsblur.com>"], ["Subject", "Re: Sample POST request"], ["References", "<517AC78B.5060404@newsletters.newsblur.com>"], ["In-Reply-To", "<517AC78B.5060404@newsletters.newsblur.com>"], ["X-Mailgun-Variables", "{\\"my_var_1\\": \\"Mailgun Variable #1\\", \\"my-var-2\\": \\"awesome\\"}"], ["Content-Type", "multipart/mixed; boundary=\\"------------020601070403020003080006\\""], ["Sender", "bob@newsletters.newsblur.com"]]',
|
||||
'stripped-text':'Hi Alice,\n\nThis is Bob.\n\nI also attached a file.',
|
||||
'recipient':'alice+555551235342@newsletters.newsblur.com',
|
||||
'sender':'bob@newsletters.newsblur.com',
|
||||
'X-Mailgun-Variables':'{"my_var_1": "Mailgun Variable #1", "my-var-2": "awesome"}',
|
||||
'token':'cb2ef40ca2fee03a099f7da78ca07384228f00f023026c77a4',
|
||||
'body-html':'<html>\n <head>\n <meta content="text/html; charset=ISO-8859-1"\n http-equiv="Content-Type">\n </head>\n <body text="#000000" bgcolor="#FFFFFF">\n <div class="moz-cite-prefix">\n <div style="color: rgb(34, 34, 34); font-family: arial,\n sans-serif; font-size: 12.666666984558105px; font-style: normal;\n font-variant: normal; font-weight: normal; letter-spacing:\n normal; line-height: normal; orphans: auto; text-align: start;\n text-indent: 0px; text-transform: none; white-space: normal;\n widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto;\n -webkit-text-stroke-width: 0px; background-color: rgb(255, 255,\n 255);">Hi Alice,</div>\n <div style="color: rgb(34, 34, 34); font-family: arial,\n sans-serif; font-size: 12.666666984558105px; font-style: normal;\n font-variant: normal; font-weight: normal; letter-spacing:\n normal; line-height: normal; orphans: auto; text-align: start;\n text-indent: 0px; text-transform: none; white-space: normal;\n widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto;\n -webkit-text-stroke-width: 0px; background-color: rgb(255, 255,\n 255);"><br>\n </div>\n <div style="color: rgb(34, 34, 34); font-family: arial,\n sans-serif; font-size: 12.666666984558105px; font-style: normal;\n font-variant: normal; font-weight: normal; letter-spacing:\n normal; line-height: normal; orphans: auto; text-align: start;\n text-indent: 0px; text-transform: none; white-space: normal;\n widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto;\n -webkit-text-stroke-width: 0px; background-color: rgb(255, 255,\n 255);">This is Bob.<span class="Apple-converted-space"> <img\n alt="" src="cid:part1.04060802.06030207@newsletters.newsblur.com"\n height="15" width="33"></span></div>\n <div style="color: rgb(34, 34, 34); font-family: arial,\n sans-serif; font-size: 12.666666984558105px; font-style: normal;\n font-variant: normal; font-weight: normal; letter-spacing:\n normal; line-height: normal; orphans: auto; text-align: start;\n text-indent: 0px; text-transform: none; white-space: normal;\n widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto;\n -webkit-text-stroke-width: 0px; background-color: rgb(255, 255,\n 255);"><br>\n I also attached a file.<br>\n <br>\n </div>\n <div style="color: rgb(34, 34, 34); font-family: arial,\n sans-serif; font-size: 12.666666984558105px; font-style: normal;\n font-variant: normal; font-weight: normal; letter-spacing:\n normal; line-height: normal; orphans: auto; text-align: start;\n text-indent: 0px; text-transform: none; white-space: normal;\n widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto;\n -webkit-text-stroke-width: 0px; background-color: rgb(255, 255,\n 255);">Thanks,</div>\n <div style="color: rgb(34, 34, 34); font-family: arial,\n sans-serif; font-size: 12.666666984558105px; font-style: normal;\n font-variant: normal; font-weight: normal; letter-spacing:\n normal; line-height: normal; orphans: auto; text-align: start;\n text-indent: 0px; text-transform: none; white-space: normal;\n widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto;\n -webkit-text-stroke-width: 0px; background-color: rgb(255, 255,\n 255);">Bob</div>\n <br>\n On 04/26/2013 11:29 AM, Alice wrote:<br>\n </div>\n <blockquote cite="mid:517AC78B.5060404@newsletters.newsblur.com" type="cite">Hi\n Bob,\n <br>\n <br>\n This is Alice. How are you doing?\n <br>\n <br>\n Thanks,\n <br>\n Alice\n <br>\n </blockquote>\n <br>\n </body>\n</html>\n',
|
||||
'References':'<517AC78B.5060404@newsletters.newsblur.com>',
|
||||
'signature':'0369fa4dcc7de7fac51f5bb408bd5c9daa8730e80d394e8a128658d74e669049',
|
||||
'Content-Type':'multipart/mixed; boundary="------------020601070403020003080006"',
|
||||
'Subject':'Re: Sample POST request'
|
||||
}
|
||||
response = HttpResponse('OK')
|
||||
return response
|
||||
|
||||
email_newsletter = EmailNewsletter()
|
||||
story = email_newsletter.receive_newsletter(params)
|
||||
|
||||
if not story:
|
||||
raise Http404
|
||||
|
||||
return response
|
||||
|
||||
def newsletter_story(request, story_hash):
|
||||
story = MStory.objects.get(story_hash=story_hash)
|
||||
story = Feed.format_story(story)
|
||||
return HttpResponse(story['story_content'])
|
|
@ -149,6 +149,10 @@ class Feed(models.Model):
|
|||
if not feed_address: feed_address = ""
|
||||
if not feed_link: feed_link = ""
|
||||
return hashlib.sha1(feed_address+feed_link).hexdigest()
|
||||
|
||||
@property
|
||||
def is_newsletter(self):
|
||||
return self.feed_address.startswith('newsletter:')
|
||||
|
||||
def canonical(self, full=False, include_favicon=True):
|
||||
feed = {
|
||||
|
@ -166,6 +170,7 @@ class Feed(models.Model):
|
|||
'min_to_decay': self.min_to_decay,
|
||||
'subs': self.num_subscribers,
|
||||
'is_push': self.is_push,
|
||||
'is_newsletter': self.is_newsletter,
|
||||
'fetched_once': self.fetched_once,
|
||||
'search_indexed': self.search_indexed,
|
||||
'not_yet_fetched': not self.fetched_once, # Legacy. Doh.
|
||||
|
@ -369,6 +374,8 @@ class Feed(models.Model):
|
|||
def get_feed_from_url(cls, url, create=True, aggressive=False, fetch=True, offset=0):
|
||||
feed = None
|
||||
|
||||
if url and url.startswith('newsletter:'):
|
||||
return cls.objects.get(feed_address=url)
|
||||
if url and 'youtube.com/user/' in url:
|
||||
username = re.search('youtube.com/user/(\w+)', url).group(1)
|
||||
url = "http://gdata.youtube.com/feeds/base/users/%s/uploads" % username
|
||||
|
|
Loading…
Add table
Reference in a new issue