def twitter_return(request): """ Get the Twitter auth tokens, check them and then create all the user-related database models and subscribe to the pubsubhubbub server """ logger = get_fe_logger() logger.info('On twitter_return') if not request.session.has_key('gprofileusername'): logger.debug('User doesnt have session on twitterreturn, redirecting to /') return HttpResponseRedirect('/') request_token = request.session.get('request_token', None) if not request_token: # Redirect the user to the login page, # So the user can click on the sign-in with twitter button logger.debug('User not sent to twitter by us on twitter_return()') return HttpResponse("We didn't sent you to twitter...") token = oauth.OAuthToken.from_string(request_token) # If the token from session and token from twitter does not match # means something bad happened to tokens if token.key != request.GET.get('oauth_token', 'no-token'): del request.session['request_token'] # Redirect the user to the login page logger.debug('Tokens doesnt match for user') return HttpResponse("Something wrong! Tokens do not match...") twitter = OAuthApi(settings.CONSUMER_KEY, settings.CONSUMER_SECRET, token) try: access_token = twitter.getAccessToken() except HTTPError: logger.warning('Access denied on twitter.getAccessToken()') return HttpResponseRedirect('/') # Somewhat clumsy to create it again, but its the way oauthapi-twitter works... twitter = OAuthApi(settings.CONSUMER_KEY, settings.CONSUMER_SECRET, access_token) twuser = twitter.GetUserInfo() # Now that we have the Twitter account we can create all the user-related models googlename = request.session['gprofileusername'] userhash = hashlib.sha256( settings.MD5SALT + googlename).hexdigest() # SiteUser siteuser = SiteUser(userhash=userhash) siteuser.save() # GoogleProfile gprofile = GoogleProfile(username=googlename, siteuser=siteuser) gprofile.save() # Initialize lastbuffread_at to created_at - 2 minutes (so we account for server time diffs) gprofile.lastbuffread_at = gprofile.created_at - timedelta(minutes=2) logger.debug('GProfile created_at : %s' % str(gprofile.created_at)) logger.debug('GProfile lastbuff_at: %s' % str(gprofile.lastbuffread_at)) gprofile.save() # UserSettings usettings = UserSettings(siteuser=siteuser) usettings.save() logger.info('Saved new SiteUser %d [%s]' % (siteuser.id, googlename)) # TwitterAccount twname = twuser.GetScreenName() twitteraccount = TwitterAccount(name=twname, token = access_token.to_string(), siteuser=siteuser) twitteraccount.save() # Send the ticket for subscribing to the push server messenger = StompMessenger() messenger.sendmessage('/queue/listener', 'subscribefeed__%d' % gprofile.id) return render_to_response("settingsstep.html", {}, RequestContext(request, {'userhash': userhash}))
def parse_buzzs(atom, googleprofile, logger): messenger = StompMessenger() siteuser = googleprofile.siteuser if siteuser.usersettings.usetag: tagre = re.compile(siteuser.usersettings.mark) feedparse_result = feedparser.parse(atom) newest_date = None newentries = [] logger.info("XXX 1") for entry in feedparse_result.entries: logger.info("XXX 2") try: d = entry.published_parsed except AttributeError: # Sometimes posts doesnt have published field and are not published on Buzz :-? logger.info("XXX 3") continue logger.info("XXX 4") #pprint(entry) date_buzz = datetime(d[0], d[1], d[2], d[3], d[4], d[5]) if ( googleprofile.firsttime and date_buzz > googleprofile.created_at) or \ ((not googleprofile.firsttime) and date_buzz > googleprofile.lastbuffread_at): \ # Get links/photos (if there is any) linkscontent = [] logger.info('XXX 5') linkslist = [] buzzlink = comments = links = linkslist_str = '' logger.info("XXX 6") for link in entry.links: if link.rel == u'enclosure': if link.href not in linkscontent: # avoid duplicates linkscontent.append(link.href) linkslist.append({'href': link.href, 'title': link.title, 'type': link.type}) linkslist_str += link.href elif link.rel == u'alternate': buzzlink = link.href elif link.rel == u'replies': comments = link.href links = '|'.join(linkslist_str) buzzcontent = entry.content[0].value logger.info('XXX 7') if settings.CMDRE.search(buzzcontent): # Is a command, execute it but don't save the buzz logger.info(u'parsing command for: %s' % buzzcontent) execute_command(buzzcontent, siteuser, messenger) logger.info('XXX 8') continue # User want to publish only buzzs with tag? is there a tag? if siteuser.usersettings.paused or (siteuser.usersettings.usetag and not tagre.search(buzzcontent)): logger.info('XXX Ignoring, paused or with usetag without tag') continue newbuzz = Buzz(buzzid = entry.id, content = buzzcontent, links = links, user = siteuser, buzzlink = buzzlink) if comments != '': newbuzz.commentslink = comments msg = 'Saving new buzz: ' + unicode(buzzcontent).encode('utf-8') logger.info(msg) newbuzz.save() # Send a message for the listener.post_buzz2twitter to post the status logger.info('sending message to queue publish__%d' % newbuzz.id) messenger.sendmessage('/queue/listener', 'publish__%d' % newbuzz.id) if newest_date == None or date_buzz > newest_date: newest_date = date_buzz if len(feedparse_result.entries) == 0: logger.warning('There are 0 entries in the feed, could be a parse error') if feedparse_result.has_key('bozo_exception'): logger.warning('bozo_exception is: ' + str(feedparse_result.bozo_exception)) else: # Update the date of the last buzz read and reset the retries logger.debug('new lastbuzzread_at is: ' + str(newest_date)) if newest_date != None: googleprofile.firsttime = False googleprofile.lastbuffread_at = newest_date googleprofile.retries = 0 googleprofile.save()
def pubsub_callback(request, gprofileid): logger = get_fe_logger() logger.info('On pubsub callback, gprofileid |%s|' % str(gprofileid)) # Unsubscriptions for a GoogleProfile already deleted can arrive, so don't use get_object_or_404 googleprofile = None profiles = GoogleProfile.objects.filter(id=int(gprofileid)) if len(profiles) > 0: googleprofile = profiles[0] # POST = new item notifications if request.method == 'POST': logger.info('POST method, raw_post_data:') logger.info(str(request.raw_post_data)) # Save the atom, user data and send a request for a listener to process it so the # hub doesn't have to wait if not googleprofile: # Notification for a deleted profile logger.info('push_callback.post: received notification for deleted profile %d!' % int(gprofileid)) return HttpResponse(status=404) notif = Notification(text = request.raw_post_data, googleprofile = googleprofile) notif.save() messenger = StompMessenger() messenger.sendmessage('/queue/listener', 'notification__%d' % notif.id) return HttpResponse(status=200) # GET = subscription or unsubscription confirmation elif request.method == 'GET': rg = request.GET challenge = rg.get(u'hub.challenge', '') topic_url = rg.get(u'hub.topic', None) logger.debug('XXX topic_url en GET: %s' % topic_url) mode = rg.get(u'hub.mode', None) lease = rg.get(u'hub.lease_seconds', 0) if not mode or not topic_url: logger.warning('Returning 404 in callback/get because not mode or topic') return HttpResponse(status=404) if mode == 'subscribe': logger.debug('push_callback: its a subscription request') if not googleprofile: logger.warning('Returning 404 in callback/subscribe because no googleprofile exists') return HttpResponse(status=404) pushsub = get_object_or_404(PushSubscription, googleprofile=googleprofile) pushsub.confirmed = True pushsub.renewed_at = datetime.now() pushsub.lease_time = int(lease) pushsub.topic_url = topic_url.strip() pushsub.save() logger.info('push_callback: profile %d correctly subscribed' % int(gprofileid)) elif mode == 'unsubscribe': logger.debug('push_callback: its an unsubscription request for topic_url:') logger.debug(topic_url) if googleprofile: pushsub = PushSubscription.objects.filter(googleprofile=googleprofile)[0] logger.debug('Have profile') if pushsub.userdeleted: logger.info('push_callback: profile %d (gprofile existed) correctly unsubscribed ' % int(gprofileid)) googleprofile.delete() pushsub.delete() return HttpResponse(status=200) else: logger.info('push_callback: profile %d not deleted! returning 404' % int(gprofileid)) return HttpResponse(status=404) else: logger.debug('No profile') logger.info('push_callback: is for gprofile that doesnt exists anymore, returning 200 anyway') """ pushsubs = PushSubscription.objects.filter(topic_url=topic_url) if len(pushsubs) == 1: pushsub = pushsubs[0] logger.info('push_callback: for pususb %d:' % pushsub.id) if pushsub.userdeleted: if googleprofile: googleprofile.delete() pushsub.delete() logger.info('push_callback: profile %d correctly unsubscribed' % int(gprofileid)) else: if googleprofile: # User hasn't been deleted! logger.info('push_callback: user with profile %d is not deleted! returning 404' % int(gprofileid)) return HttpResponse(status=404) else: logger.info('push_callback: received notification for used deleted but with subscription, deleting sub') pushsub.delete() else: logger.info('push_callback: profile %d already deleted, but returning 200 anyway' % int(gprofileid)) """ return HttpResponse(challenge, status=200) else: logger.warning('No POST or GET on callback!') return HttpResponse(status=404)