mirror of
https://github.com/samuelclay/NewsBlur.git
synced 2025-08-05 16:58:59 +00:00
280 lines
No EOL
12 KiB
Python
280 lines
No EOL
12 KiB
Python
import datetime
|
|
import pickle
|
|
import base64
|
|
import httplib2
|
|
from utils import log as logging
|
|
from oauth2client.client import OAuth2WebServerFlow, FlowExchangeError
|
|
from bson.errors import InvalidStringData
|
|
import uuid
|
|
from django.contrib.sites.models import Site
|
|
# from django.db import IntegrityError
|
|
from django.http import HttpResponse, HttpResponseRedirect
|
|
from django.conf import settings
|
|
from django.core.urlresolvers import reverse
|
|
from django.template import RequestContext
|
|
from django.contrib.auth import login as login_user
|
|
from django.shortcuts import render_to_response
|
|
from apps.reader.forms import SignupForm
|
|
from apps.reader.models import UserSubscription
|
|
from apps.feed_import.models import OAuthToken, GoogleReaderImporter
|
|
from apps.feed_import.models import OPMLImporter, OPMLExporter, UploadedOPML
|
|
from apps.feed_import.tasks import ProcessOPML, ProcessReaderImport, ProcessReaderStarredImport
|
|
from utils import json_functions as json
|
|
from utils.user_functions import ajax_login_required, get_user
|
|
from utils.feed_functions import TimeoutError
|
|
|
|
|
|
@ajax_login_required
|
|
def opml_upload(request):
|
|
xml_opml = None
|
|
message = "OK"
|
|
code = 1
|
|
payload = {}
|
|
|
|
if request.method == 'POST':
|
|
if 'file' in request.FILES:
|
|
logging.user(request, "~FR~SBOPML upload starting...")
|
|
file = request.FILES['file']
|
|
xml_opml = str(file.read().decode('utf-8', 'ignore'))
|
|
try:
|
|
UploadedOPML.objects.create(user_id=request.user.pk, opml_file=xml_opml)
|
|
except (UnicodeDecodeError, InvalidStringData):
|
|
folders = None
|
|
code = -1
|
|
message = "There was a Unicode decode error when reading your OPML file."
|
|
|
|
opml_importer = OPMLImporter(xml_opml, request.user)
|
|
try:
|
|
folders = opml_importer.try_processing()
|
|
except TimeoutError:
|
|
folders = None
|
|
ProcessOPML.delay(request.user.pk)
|
|
feed_count = opml_importer.count_feeds_in_opml()
|
|
logging.user(request, "~FR~SBOPML pload took too long, found %s feeds. Tasking..." % feed_count)
|
|
payload = dict(folders=folders, delayed=True, feed_count=feed_count)
|
|
code = 2
|
|
message = ""
|
|
except AttributeError:
|
|
code = -1
|
|
message = "OPML import failed. Couldn't parse XML file."
|
|
folders = None
|
|
|
|
if folders:
|
|
code = 1
|
|
feeds = UserSubscription.objects.filter(user=request.user).values()
|
|
payload = dict(folders=folders, feeds=feeds)
|
|
logging.user(request, "~FR~SBOPML Upload: ~SK%s~SN~SB~FR feeds" % (len(feeds)))
|
|
|
|
request.session['import_from_google_reader'] = False
|
|
else:
|
|
message = "Attach an .opml file."
|
|
code = -1
|
|
|
|
return HttpResponse(json.encode(dict(message=message, code=code, payload=payload)),
|
|
mimetype='text/html')
|
|
|
|
def opml_export(request):
|
|
user = get_user(request)
|
|
exporter = OPMLExporter(user)
|
|
opml = exporter.process()
|
|
now = datetime.datetime.now()
|
|
|
|
response = HttpResponse(opml, mimetype='text/xml')
|
|
response['Content-Disposition'] = 'attachment; filename=NewsBlur Subscriptions - %s' % (
|
|
now.strftime('%Y-%m-%d')
|
|
)
|
|
|
|
return response
|
|
|
|
|
|
def reader_authorize(request):
|
|
ip = request.META.get('HTTP_X_REAL_IP', None) or request.META.get('REMOTE_ADDR', "")
|
|
reader_importer = GoogleReaderImporter(request.user)
|
|
if reader_importer.test():
|
|
logging.user(request, "~BB~FW~SBSkipping Google Reader import, already tokened")
|
|
return render_to_response('social/social_connect.xhtml', {
|
|
}, context_instance=RequestContext(request))
|
|
|
|
domain = Site.objects.get_current().domain
|
|
STEP2_URI = "http://%s%s" % (
|
|
(domain + '.com') if not domain.endswith('.com') else domain,
|
|
reverse('google-reader-callback'),
|
|
)
|
|
|
|
FLOW = OAuth2WebServerFlow(
|
|
client_id=settings.GOOGLE_OAUTH2_CLIENTID,
|
|
client_secret=settings.GOOGLE_OAUTH2_SECRET,
|
|
scope="http://www.google.com/reader/api",
|
|
redirect_uri=STEP2_URI,
|
|
user_agent='NewsBlur Pro, www.newsblur.com',
|
|
approval_prompt="force",
|
|
)
|
|
logging.user(request, "~BB~FW~SBAuthorize Google Reader import - %s" % (
|
|
request.META.get('HTTP_X_REAL_IP', None) or request.META.get('REMOTE_ADDR', ""),
|
|
))
|
|
|
|
authorize_url = FLOW.step1_get_authorize_url(redirect_uri=STEP2_URI)
|
|
response = render_to_response('social/social_connect.xhtml', {
|
|
'next': authorize_url,
|
|
}, context_instance=RequestContext(request))
|
|
|
|
# Save request token and delete old tokens
|
|
auth_token_dict = dict()
|
|
if request.user.is_authenticated():
|
|
OAuthToken.objects.filter(user=request.user).delete()
|
|
auth_token_dict['user'] = request.user
|
|
else:
|
|
OAuthToken.objects.filter(session_id=request.session.session_key).delete()
|
|
OAuthToken.objects.filter(remote_ip=ip).delete()
|
|
auth_token_dict['uuid'] = str(uuid.uuid4())
|
|
auth_token_dict['session_id'] = request.session.session_key
|
|
auth_token_dict['remote_ip'] = ip
|
|
OAuthToken.objects.create(**auth_token_dict)
|
|
|
|
response.set_cookie('newsblur_reader_uuid', str(uuid.uuid4()))
|
|
return response
|
|
|
|
def reader_callback(request):
|
|
ip = request.META.get('HTTP_X_REAL_IP', None) or request.META.get('REMOTE_ADDR', "")
|
|
domain = Site.objects.get_current().domain
|
|
STEP2_URI = "http://%s%s" % (
|
|
(domain + '.com') if not domain.endswith('.com') else domain,
|
|
reverse('google-reader-callback'),
|
|
)
|
|
FLOW = OAuth2WebServerFlow(
|
|
client_id=settings.GOOGLE_OAUTH2_CLIENTID,
|
|
client_secret=settings.GOOGLE_OAUTH2_SECRET,
|
|
scope="http://www.google.com/reader/api",
|
|
redirect_uri=STEP2_URI,
|
|
user_agent='NewsBlur Pro, www.newsblur.com',
|
|
)
|
|
FLOW.redirect_uri = STEP2_URI
|
|
|
|
http = httplib2.Http()
|
|
http.disable_ssl_certificate_validation = True
|
|
try:
|
|
credential = FLOW.step2_exchange(request.REQUEST)
|
|
except FlowExchangeError:
|
|
logging.info(" ***> [%s] Bad token from Google Reader." % (request.user,))
|
|
return render_to_response('social/social_connect.xhtml', {
|
|
'error': 'There was an error trying to import from Google Reader. Trying again will probably fix the issue.'
|
|
}, context_instance=RequestContext(request))
|
|
|
|
user_token = None
|
|
if request.user.is_authenticated():
|
|
user_token = OAuthToken.objects.filter(user=request.user).order_by('-created_date')
|
|
if not user_token:
|
|
user_uuid = request.COOKIES.get('newsblur_reader_uuid')
|
|
if user_uuid:
|
|
user_token = OAuthToken.objects.filter(uuid=user_uuid).order_by('-created_date')
|
|
if not user_token:
|
|
session = request.session
|
|
if session.session_key:
|
|
user_token = OAuthToken.objects.filter(session_id=request.session.session_key).order_by('-created_date')
|
|
if not user_token:
|
|
user_token = OAuthToken.objects.filter(remote_ip=ip).order_by('-created_date')
|
|
|
|
if user_token:
|
|
user_token = user_token[0]
|
|
user_token.credential = base64.b64encode(pickle.dumps(credential))
|
|
user_token.session_id = request.session.session_key
|
|
user_token.save()
|
|
|
|
# Fetch imported feeds on next page load
|
|
request.session['import_from_google_reader'] = True
|
|
|
|
logging.user(request, "~BB~FW~SBFinishing Google Reader import - %s" % ip)
|
|
|
|
if request.user.is_authenticated():
|
|
return render_to_response('social/social_connect.xhtml', {}, context_instance=RequestContext(request))
|
|
|
|
return HttpResponseRedirect(reverse('import-signup'))
|
|
|
|
@json.json_view
|
|
def import_from_google_reader(request):
|
|
code = 0
|
|
feed_count = 0
|
|
starred_count = 0
|
|
delayed = False
|
|
|
|
if request.user.is_authenticated():
|
|
reader_importer = GoogleReaderImporter(request.user)
|
|
auto_active = bool(request.REQUEST.get('auto_active') or False)
|
|
|
|
try:
|
|
code = reader_importer.try_import_feeds(auto_active=auto_active)
|
|
except TimeoutError:
|
|
ProcessReaderImport.delay(request.user.pk, auto_active=auto_active)
|
|
feed_count = UserSubscription.objects.filter(user=request.user).count()
|
|
logging.user(request, "~FR~SBGoogle Reader import took too long, found %s feeds. Tasking..." % feed_count)
|
|
delayed = True
|
|
code = 2
|
|
|
|
if 'import_from_google_reader' in request.session:
|
|
del request.session['import_from_google_reader']
|
|
|
|
feed_count = UserSubscription.objects.filter(user=request.user).count()
|
|
|
|
return dict(code=code, delayed=delayed, feed_count=feed_count, starred_count=starred_count)
|
|
|
|
@json.json_view
|
|
def import_starred_stories_from_google_reader(request):
|
|
code = 0
|
|
feed_count = 0
|
|
starred_count = 0
|
|
delayed = False
|
|
|
|
if request.user.is_authenticated():
|
|
reader_importer = GoogleReaderImporter(request.user)
|
|
try:
|
|
starred_count = reader_importer.try_import_starred_stories()
|
|
except TimeoutError:
|
|
ProcessReaderStarredImport.delay(request.user.pk)
|
|
feed_count = UserSubscription.objects.filter(user=request.user).count()
|
|
logging.user(request, "~FR~SBGoogle Reader starred stories import took too long, found %s feeds, %s stories. Tasking..." % (feed_count, starred_count))
|
|
delayed = True
|
|
code = 2
|
|
|
|
feed_count = UserSubscription.objects.filter(user=request.user).count()
|
|
|
|
return dict(code=code, delayed=delayed, feed_count=feed_count, starred_count=starred_count)
|
|
|
|
def import_signup(request):
|
|
ip = request.META.get('HTTP_X_REAL_IP', None) or request.META.get('REMOTE_ADDR', "")
|
|
|
|
if request.method == "POST":
|
|
signup_form = SignupForm(prefix='signup', data=request.POST)
|
|
if signup_form.is_valid():
|
|
new_user = signup_form.save()
|
|
|
|
user_token = OAuthToken.objects.filter(user=new_user)
|
|
if not user_token:
|
|
user_uuid = request.COOKIES.get('newsblur_reader_uuid')
|
|
if user_uuid:
|
|
user_token = OAuthToken.objects.filter(uuid=user_uuid).order_by('-created_date')
|
|
if not user_token:
|
|
if request.session.session_key:
|
|
user_token = OAuthToken.objects.filter(session_id=request.session.session_key).order_by('-created_date')
|
|
if not user_token:
|
|
user_token = OAuthToken.objects.filter(remote_ip=ip).order_by('-created_date')
|
|
|
|
if user_token:
|
|
user_token = user_token[0]
|
|
user_token.session_id = request.session.session_key
|
|
user_token.user = new_user
|
|
user_token.save()
|
|
login_user(request, new_user)
|
|
if request.user.profile.is_premium:
|
|
return HttpResponseRedirect(reverse('index'))
|
|
url = "https://%s%s" % (Site.objects.get_current().domain,
|
|
reverse('stripe-form'))
|
|
return HttpResponseRedirect(url)
|
|
else:
|
|
logging.user(request, "~BR~FW ***> Can't find user token during import/signup. Re-authenticating...")
|
|
return HttpResponseRedirect(reverse('google-reader-authorize'))
|
|
else:
|
|
signup_form = SignupForm(prefix='signup')
|
|
|
|
return render_to_response('import/signup.xhtml', {
|
|
'signup_form': signup_form,
|
|
}, context_instance=RequestContext(request)) |