def render(self, content, list_mode=False): self.handler.display["individual_content"] = type(content) is not list self.handler.display["referrer"] = content_remote.sanitize( self.handler.get_argument('referrer', "")) self.handler.display['favorites'] = [] self.handler.display['list_mode'] = list_mode if not self.handler.display["individual_content"]: self.handler.display["feed"] = content for item in content: if item.is_remote: continue item.view = re.sub(r'(<[^<]*class="hw-read-more".*)', \ r'<a class="hw-read-more" href="' \ + self.handler.content_url(item) + r'">' \ + self.locale.translate('read more...') \ + r'</a>', \ item.view) else: self.handler.display["content"] = content if content.favorites: self.handler.display['favorites'] = \ self.handler.models.content_remote.get( to_username=content.username, local_content_name=content.name, type='favorite')[:] return self.render_string("content.html", **self.handler.display)
def comment(self): commented_content = self.models.content.get( username=self.get_argument('local_user'), name=self.get_argument('local_name'))[0] self.display["user"] = commented_user = self.models.users.get( username=commented_content.username)[0] comment = self.get_argument('comment') sanitized_comment = content_remote.sanitize(comment) is_spam = spam.guess(comment, self.application.settings["private_path"], commented_content.username) post_remote = self.models.content_remote() post_remote.to_username = commented_content.username post_remote.from_user = self.current_user["email"] post_remote.username = self.current_user["email"].split('@')[0] local_url = ('/' + commented_content.username + '/remote-comments/comment-' + str(uuid.uuid4())) post_remote.post_id = ('tag:' + self.request.host + ',' + self.display["tag_date"] + ':' + local_url) post_remote.link = 'http://' + self.request.host + local_url from_username = post_remote.username if self.current_user["user"]: profile = self.get_author_user() post_remote.avatar = profile.logo if profile.logo else profile.favicon else: post_remote.avatar = ('http://www.gravatar.com/avatar/' + hashlib.md5(self.current_user["email"].lower()).hexdigest()) post_remote.date_created = datetime.datetime.utcnow() if is_spam: post_remote.is_spam = True else: spam.train_ham(comment, self.application.settings["private_path"], commented_content.username) post_remote.type = 'comment' post_remote.local_content_name = commented_content.name post_remote.view = sanitized_comment post_remote.save() commented_content.comments_count += 1 commented_content.comments_updated = datetime.datetime.utcnow() commented_content.save() cache.remove(self, self.content_url(commented_content)) socialize.socialize(self, commented_content) smtp.comment(self, from_username, post_remote.from_user, commented_user.email, self.content_url(commented_content, host=True), sanitized_comment)
def render(self, content, simple=True, template_type=None, sanitize=False): content.restricted = False content.is_remote = False content.comments_list = [] if content.comments_count: content.comments_list = content_remote.get_comments( self.handler, content) is_forum = self.handler.display["section_template"] == 'forum' content.comments_list.sort(key=lambda x: x.date_created, reverse=(not is_forum)) try: if not self.handler.authenticate(content=content, auto_login=(not simple)): if simple: content.restricted = True content.view = ( '"You need to <a href="' + self.handler.nav_url(host=True, section="login") + '">login</a> to view this content.') return content else: raise tornado.web.HTTPError(401) except tornado.web.HTTPError as ex: if simple: content.restricted = True content.view = \ '<span style="color:red">Sorry, you don\'t have access to view this content.</span>' return content else: # re-raise raise ex if sanitize: content.view = content_remote.sanitize(content.view) return content
def render(self, content, simple=True, template_type=None, sanitize=False): content.restricted = False content.is_remote = False content.comments_list = [] if content.comments_count: content.comments_list = content_remote.get_comments( self.handler, content) is_forum = self.handler.display["section_template"] == 'forum' content.comments_list.sort(key=lambda x: x.date_created, reverse=( not is_forum)) try: if not self.handler.authenticate(content=content, auto_login=(not simple)): if simple: content.restricted = True content.view = ('"You need to <a href="' + self.handler.nav_url(host=True, section="login") + '">login</a> to view this content.') return content else: raise tornado.web.HTTPError(401) except tornado.web.HTTPError as ex: if simple: content.restricted = True content.view = \ '<span style="color:red">Sorry, you don\'t have access to view this content.</span>' return content else: # re-raise raise ex if sanitize: content.view = content_remote.sanitize(content.view) return content
def timeline_result(self, response): # Check if our OAuth key has expired if (response.has_key('error') and response['error']['type'] == 'OAuthException'): self.delete() return posts = response['data'] for post in posts: exists = self.models.content_remote.get(to_username=self.user.username, type='facebook', post_id=post['id'])[0] date_updated = None if post.has_key('updated_time'): date_updated = datetime.datetime.strptime(post['updated_time'][:-5], '%Y-%m-%dT%H:%M:%S') if exists: if date_updated and date_updated != exists.date_updated \ or post['comments']['count'] != exists.comments_count: new_post = exists else: continue else: new_post = self.models.content_remote() new_post.to_username = self.user.username new_post.username = post['from']['name'] if post.has_key('actions'): new_post.from_user = post['actions'][0]['link'] #new_post.avatar = tweet['user']['profile_image_url'] parsed_date = datetime.datetime.strptime(post['created_time'][:-5], '%Y-%m-%dT%H:%M:%S') # we don't keep items that are over 30 days old if parsed_date < datetime.datetime.utcnow() - datetime.timedelta( days=self.constants['feed_max_days_old']): continue new_post.date_created = parsed_date new_post.date_updated = date_updated new_post.comments_count = 0 new_post.comments_updated = None new_post.type = 'facebook' new_post.title = '' new_post.post_id = post['id'] new_post.comments_count = post['comments']['count'] if post['comments']['count'] and post['comments']['data']: last_updated = post['comments']['data'][len( post['comments']['data']) - 1]['created_time'] new_post.comments_updated = datetime.datetime.strptime( last_updated[:-5], '%Y-%m-%dT%H:%M:%S') if post.has_key('actions'): new_post.link = post['actions'][0]['link'] elif post.has_key('link'): new_post.link = post['link'] view = "" if post.has_key('message'): view += post['message'] + "<br>" if post.has_key('caption'): view += post['caption'] + "<br>" if post.has_key('description'): view += post['description'] + "<br>" if post.has_key('story'): view += post['story'] + "<br>" view = tornado.escape.linkify(view) if post.has_key('picture'): view = '<img src="' + post['picture'] + '">' + view new_post.view = content_remote.sanitize(tornado.escape.xhtml_unescape( view)) new_post.save() # comments if post['comments']['count']: for comment in post['comments']['data']: exists = self.models.content_remote.get( to_username=self.user.username, post_id=comment['id'])[0] if exists: continue else: new_comment = self.models.content_remote() new_comment.to_username = self.user.username new_comment.username = comment['from']['name'] new_comment.from_user = ('http://facebook.com/' + comment['from']['id']) date_created = datetime.datetime.strptime( comment['created_time'][:-5], '%Y-%m-%dT%H:%M:%S') new_comment.date_created = date_created new_comment.type = 'remote-comment' new_comment.thread = post['id'] new_comment.post_id = comment['id'] if post.has_key('actions'): new_comment.link = post['actions'][0]['link'] new_comment.view = comment['message'] new_comment.save() count = self.models.content_remote.get(to_username=self.user.username, type='facebook', deleted=False).count() self.write(json.dumps({ 'count': count }))
def timeline_result(self, response): posts = response['response']['posts'] for post in posts: exists = self.models.content_remote.get( to_username=self.user.username, type='tumblr', post_id=str(post['id']))[0] if exists: continue else: new_post = self.models.content_remote() new_post.to_username = self.user.username new_post.username = post['blog_name'] new_post.from_user = '******' + post['blog_name'] #new_post.avatar = post['user']['profile_image_url'] parsed_date = datetime.datetime.utcfromtimestamp(post['timestamp']) # we don't keep items that are over 30 days old if parsed_date < datetime.datetime.utcnow() - datetime.timedelta( days=self.constants['feed_max_days_old']): continue new_post.date_created = parsed_date new_post.date_updated = None new_post.comments_count = post['note_count'] new_post.comments_updated = None new_post.type = 'tumblr' new_post.post_id = str(post['id']) new_post.link = post['post_url'] if post['type'] == 'text': new_post.title = post['title'] new_post.view = content_remote.sanitize( tornado.escape.xhtml_unescape(post['body'])) elif post['type'] == 'photo': html = "" for photo in post['photos']: chosen_photo = None for size in photo['alt_sizes']: if (not chosen_photo or (size['width'] <= 720 and chosen_photo['width'] < size['width'])): chosen_photo = size html += '<img src="' + content_remote.sanitize( tornado.escape.xhtml_unescape( chosen_photo['url'])) + '">' html += content_remote.sanitize( tornado.escape.xhtml_unescape(post['caption'])) new_post.view = html elif post['type'] == 'quote': new_post.view = content_remote.sanitize( tornado.escape.xhtml_unescape(post['text'] + '<br>' + post['source'])) elif post['type'] == 'link': new_post.title = post['title'] new_post.view = content_remote.sanitize( tornado.escape.xhtml_unescape('<a href="' + post['url'] + '">' + post['url'] + '</a><br>' + post['description'])) elif post['type'] == 'chat': new_post.title = post['title'] new_post.view = content_remote.sanitize( tornado.escape.xhtml_unescape(post['body'].replace( '\r\n', '<br>'))) elif post['type'] == 'audio': html = "" html += content_remote.sanitize( tornado.escape.xhtml_unescape(post['player'])) html += content_remote.sanitize( tornado.escape.xhtml_unescape(post['caption'])) new_post.view = html elif post['type'] == 'video': chosen_video = None for video in post['player']: if (not chosen_video or (video['width'] <= 720 and chosen_video['width'] < video['width'])): chosen_video = video html = "" html += content_remote.sanitize( tornado.escape.xhtml_unescape(chosen_video['embed_code'])) html += content_remote.sanitize( tornado.escape.xhtml_unescape(post['caption'])) new_post.view = html elif post['type'] == 'answer': new_post.title = post['question'] new_post.view = content_remote.sanitize( tornado.escape.xhtml_unescape(post['answer'])) new_post.save() count = self.models.content_remote.get(to_username=self.user.username, type='tumblr', deleted=False).count() self.write(json.dumps({'count': count}))
def timeline_result(self, tweets): for tweet in tweets: exists = self.models.content_remote.get( to_username=self.user.username, type='twitter', post_id=str(tweet['id']))[0] if exists: continue else: new_tweet = self.models.content_remote() new_tweet.to_username = self.user.username new_tweet.username = tweet['user']['screen_name'] new_tweet.from_user = ('http://twitter.com/' + tweet['user']['screen_name']) new_tweet.avatar = tweet['user']['profile_image_url'] parsed_date = re.compile(r'\+.....').sub('', tweet['created_at']) parsed_date = datetime.datetime.strptime(parsed_date, '%a %b %d %H:%M:%S %Y') # we don't keep items that are over 30 days old if parsed_date < datetime.datetime.utcnow() - datetime.timedelta( days=self.constants['feed_max_days_old']): continue new_tweet.date_created = parsed_date new_tweet.date_updated = None new_tweet.comments_count = 0 new_tweet.comments_updated = None new_tweet.type = 'twitter' new_tweet.title = '' new_tweet.post_id = str(tweet['id']) new_tweet.link = ('http://twitter.com/' + tweet['user']['screen_name'] + '/status/' + str(tweet['id'])) if tweet.has_key('retweeted_status'): text = tornado.escape.linkify( tweet['retweeted_status']['text']) text += ( '<br><span class="hw-retweeted-by">' + self.locale.translate( 'retweeted by <a href="%(link)s">%(tweeter)s</a>') % { 'link': 'http://twitter.com/' + tweet['user']['screen_name'], 'tweeter': tweet['user']['screen_name'] } + '</span>') new_tweet.username = tweet['retweeted_status']['user'][ 'screen_name'] new_tweet.from_user = ( 'http://twitter.com/' + tweet['retweeted_status']['user']['screen_name']) new_tweet.avatar = \ tweet['retweeted_status']['user']['profile_image_url'] else: text = tornado.escape.linkify(tweet['text']) text = re.compile(r'#(\w+)', re.M | re.U).sub( r'<a href="https://twitter.com/#!/search/%23\1" rel="tag">#\1</a>', text) text = re.compile(r'@(\w+)', re.M | re.U).sub( r'<a href="https://twitter.com/#!/\1">@\1</a>', text) new_tweet.view = content_remote.sanitize( tornado.escape.xhtml_unescape(text)) new_tweet.save() count = self.models.content_remote.get(to_username=self.user.username, type='twitter', deleted=False).count() self.write(json.dumps({'count': count}))
def timeline_result(self, tweets): for tweet in tweets: exists = self.models.content_remote.get(to_username=self.user.username, type='twitter', post_id=str(tweet['id']))[0] if exists: continue else: new_tweet = self.models.content_remote() new_tweet.to_username = self.user.username new_tweet.username = tweet['user']['screen_name'] new_tweet.from_user = ('http://twitter.com/' + tweet['user']['screen_name']) new_tweet.avatar = tweet['user']['profile_image_url'] parsed_date = re.compile(r'\+.....').sub('', tweet['created_at']) parsed_date = datetime.datetime.strptime(parsed_date, '%a %b %d %H:%M:%S %Y') # we don't keep items that are over 30 days old if parsed_date < datetime.datetime.utcnow() - datetime.timedelta( days=self.constants['feed_max_days_old']): continue new_tweet.date_created = parsed_date new_tweet.date_updated = None new_tweet.comments_count = 0 new_tweet.comments_updated = None new_tweet.type = 'twitter' new_tweet.title = '' new_tweet.post_id = str(tweet['id']) new_tweet.link = ('http://twitter.com/' + tweet['user']['screen_name'] + '/status/' + str(tweet['id'])) if tweet.has_key('retweeted_status'): text = tornado.escape.linkify(tweet['retweeted_status']['text']) text += ('<br><span class="hw-retweeted-by">' + self.locale.translate( 'retweeted by <a href="%(link)s">%(tweeter)s</a>') % { 'link': 'http://twitter.com/' + tweet['user']['screen_name'], 'tweeter': tweet['user']['screen_name'] } + '</span>') new_tweet.username = tweet['retweeted_status']['user']['screen_name'] new_tweet.from_user = ('http://twitter.com/' + tweet['retweeted_status']['user']['screen_name']) new_tweet.avatar = \ tweet['retweeted_status']['user']['profile_image_url'] else: text = tornado.escape.linkify(tweet['text']) text = re.compile(r'#(\w+)', re.M | re.U).sub( r'<a href="https://twitter.com/#!/search/%23\1" rel="tag">#\1</a>', text) text = re.compile(r'@(\w+)', re.M | re.U).sub( r'<a href="https://twitter.com/#!/\1">@\1</a>', text) new_tweet.view = content_remote.sanitize( tornado.escape.xhtml_unescape(text)) new_tweet.save() count = self.models.content_remote.get(to_username=self.user.username, type='twitter', deleted=False).count() self.write(json.dumps({ 'count': count }))
def handle_mention(self, local_content_url, local_content, target_url, source_url): source_html = urllib2.urlopen(source_url) source_html = content_remote.sanitize( tornado.escape.xhtml_unescape(source_html.read())) source_doc = BeautifulSoup(source_html) hEntry = source_doc.find(attrs={'class':re.compile(r'\bh-entry\b')}) if not hEntry: return remote_content = hEntry.find( attrs={'class':re.compile(r'\be-content\b')}) existing_content = self.models.content_remote.get( to_username=self.display["user"].username, from_user=source_url, view=remote_content)[0] import logging logging.error(remote_content) # TODO(mime): source_url should actually point to the user's url # Should look at webfinger for url. this_user_url = self.nav_url(host=True, username=self.display["user"].username) thread = target_url != this_user_url if thread: try: local_content.comments_count += 1 local_content.comments_updated = datetime.datetime.utcnow() local_content.save() except Exception as ex: import logging logging.error("something wrong with thread") logging.error(ex) is_spam = False # TODO(mime): spam.guess(remote_content, #self.application.settings["private_path"], #self.display["user"].username) if existing_content: # possible that it's picked up via feed, before we get the salmon call post_remote = existing_content else: post_remote = self.models.content_remote() post_remote.to_username = self.display["user"].username post_remote.from_user = source_url post_remote.username = '******' post_remote.avatar = '' # TODO(mime): user_remote.avatar current_datetime = datetime.datetime.utcnow() published = hEntry.find( attrs={'class':re.compile(r'\bdt-published\b'), 'datetime':re.compile('.+')}) if published: post_remote.date_created = datetime.datetime.strptime( published['datetime'].string[:-6], '%Y-%m-%dT%H:%M:%S') else: post_remote.date_created = current_datetime updated = hEntry.find( attrs={'class':re.compile(r'\bdt-updated\b'), 'datetime':re.compile('.+')}) if updated: post_remote.date_updated = datetime.datetime.strptime( updated['datetime'].string[:-6], '%Y-%m-%dT%H:%M:%S') else: post_remote.date_updated = current_datetime #if is_spam: # post_remote.is_spam = True #else: # spam.train_ham(remote_content, self.application.settings["private_path"], # self.display["user"].username) post_remote.type = 'comment' if thread or (existing_content and existing_content.type == 'comment') else 'post' title = hEntry.find( attrs={'class':re.compile(r'\bp-summary\b')}) if title: post_remote.title = title.string post_remote.post_id = source_url post_remote.link = source_url post_remote.local_content_name = local_content.name if thread else '' post_remote.view = remote_content post_remote.save() if thread: smtp.comment(self, post_remote.username, post_remote.from_user, self.display["user"].email, self.content_url(local_content, host=True), remote_content) else: smtp.comment(self, post_remote.username, post_remote.from_user, self.display["user"].email, post_remote.link, remote_content, this_user_mentioned=True)
def handle_activity_verb(self, env, signer_uri): salmon_doc = BeautifulSoup(env) activity_verb = salmon_doc.find(re.compile('.+:verb$')).string user_remote = self.models.users_remote.get( local_username=self.display["user"].username, profile_url=signer_uri)[0] if (activity_verb == 'http://activitystrea.ms/schema/1.0/follow'): user = users.get_remote_user_info(self, signer_uri, user_remote.local_username) user.follower = 1 user.save() smtp.follow(self, user.username, self.display["user"].email, user.profile_url) elif (activity_verb == 'http://ostatus.org/schema/1.0/unfollow' or activity_verb == 'http://activitystrea.ms/schema/1.0/stop-following'): user_remote.follower = 0 user_remote.save() elif (activity_verb == 'http://activitystrea.ms/schema/1.0/favorite'): activity_object = salmon_doc.find(re.compile('.+:object$')) atom_id = activity_object.find('atom:id').string local_url = atom_id.split(':')[2] content_url = url_factory.load_basic_parameters(self, url=local_url) already_favorited = self.models.content_remote.get( to_username=self.display["user"].username, from_user=signer_uri, type='favorite', local_content_name=content_url['name'])[0] if already_favorited: return content = self.models.content.get( username=self.display["user"].username, name=content_url['name'])[0] if not content: raise tornado.web.HTTPError(400) content.favorites += 1 content.save() favorite_record = self.models.content_remote() favorite_record.to_username = self.display["user"].username favorite_record.from_user = signer_uri favorite_record.username = user_remote.username favorite_record.date_created = datetime.datetime.strptime( salmon_doc.find('atom:updated').string[:-6], '%Y-%m-%dT%H:%M:%S') favorite_record.type = 'favorite' favorite_record.local_content_name = content.name favorite_record.save() elif (activity_verb == 'http://activitystrea.ms/schema/1.0/unfavorite' or activity_verb == 'http://ostatus.org/schema/1.0/unfavorite'): # TODO no activity object at least with ostatus?? pass elif (activity_verb == 'http://activitystrea.ms/schema/1.0/share'): # TODO pass elif (activity_verb == 'http://activitystrea.ms/schema/1.0/post'): atom_content = salmon_doc.find('atom:content').string sanitized_atom_content = content_remote.sanitize( tornado.escape.xhtml_unescape(atom_content)) existing_content = self.models.content_remote.get( to_username=self.display["user"].username, from_user=signer_uri, view=sanitized_atom_content)[0] thread = salmon_doc.find('thr:in-reply-to') ref = '' if thread: try: local_url = thread['ref'].split(':')[2] content_url = url_factory.load_basic_parameters( self, url=local_url) content = self.models.content.get( username=self.display["user"].username, name=content_url['name'])[0] if not content: raise tornado.web.HTTPError(400) ref = content_url['name'] content.comments_count += 1 content.comments_updated = datetime.datetime.utcnow() content.save() except Exception as ex: import logging logging.error("something wrong with thread") logging.error(ex) replies = salmon_doc.find('thr:replies') comments_count = 0 comments_updated = None if replies: if replies.has_key('count'): comments_count = int(replies['count']) if replies.has_key('updated'): comments_updated = replies['updated'] comments_response = urllib2.urlopen(replies['href']) content_remote.parse_feed(self.models, user_remote, comments_response.read(), remote_comments=True) mentioned = salmon_doc.findAll('atom:link', rel='mentioned') if not mentioned: mentioned = salmon_doc.findAll('atom:link', rel='ostatus:attention') this_user_mentioned = False if mentioned: this_user_url = self.nav_url( host=True, username=self.display["user"].username) for mentions in mentioned: if mentions['href'] == this_user_url: # hey, you've been mentioned. cool. this_user_mentioned = True break is_spam = spam.guess(atom_content, self.application.settings["private_path"], self.display["user"].username) if existing_content: # possible that it's picked up via feed, before we get the salmon call post_remote = existing_content else: post_remote = self.models.content_remote() post_remote.to_username = self.display["user"].username post_remote.from_user = signer_uri post_remote.username = user_remote.username post_remote.avatar = user_remote.avatar post_remote.date_created = datetime.datetime.strptime( salmon_doc.find('atom:published').string[:-6], '%Y-%m-%dT%H:%M:%S') post_remote.date_updated = datetime.datetime.strptime( salmon_doc.find('atom:updated').string[:-6], '%Y-%m-%dT%H:%M:%S') post_remote.comments_count = comments_count if comments_updated: post_remote.comments_updated = datetime.datetime.strptime( comments_updated[:-6], '%Y-%m-%dT%H:%M:%S') else: post_remote.comments_updated = None if is_spam: post_remote.is_spam = True else: spam.train_ham(atom_content, self.application.settings["private_path"], self.display["user"].username) post_remote.type = 'comment' if ref or ( existing_content and existing_content.type == 'comment') else 'post' post_remote.title = salmon_doc.find('atom:title').string post_remote.post_id = salmon_doc.find('atom:id').string post_remote.link = salmon_doc.find('atom:link', rel='alternate')['href'] post_remote.local_content_name = content.name if ref else '' post_remote.view = sanitized_atom_content post_remote.save() if ref: socialize.socialize(self, content) if ref: smtp.comment(self, post_remote.username, post_remote.from_user, self.display["user"].email, self.content_url(content, host=True), sanitized_atom_content) elif this_user_mentioned: smtp.comment(self, post_remote.username, post_remote.from_user, self.display["user"].email, post_remote.link, sanitized_atom_content, this_user_mentioned=True)
def timeline_result(self, response): # Check if our OAuth key has expired if (response.has_key('error') and response['error']['type'] == 'OAuthException'): self.delete() return posts = response['data'] for post in posts: exists = self.models.content_remote.get( to_username=self.user.username, type='facebook', post_id=post['id'])[0] date_updated = None if post.has_key('updated_time'): date_updated = datetime.datetime.strptime( post['updated_time'][:-5], '%Y-%m-%dT%H:%M:%S') if exists: if date_updated and date_updated != exists.date_updated \ or post['comments']['count'] != exists.comments_count: new_post = exists else: continue else: new_post = self.models.content_remote() new_post.to_username = self.user.username new_post.username = post['from']['name'] if post.has_key('actions'): new_post.from_user = post['actions'][0]['link'] #new_post.avatar = tweet['user']['profile_image_url'] parsed_date = datetime.datetime.strptime(post['created_time'][:-5], '%Y-%m-%dT%H:%M:%S') # we don't keep items that are over 30 days old if parsed_date < datetime.datetime.utcnow() - datetime.timedelta( days=self.constants['feed_max_days_old']): continue new_post.date_created = parsed_date new_post.date_updated = date_updated new_post.comments_count = 0 new_post.comments_updated = None new_post.type = 'facebook' new_post.title = '' new_post.post_id = post['id'] new_post.comments_count = post['comments']['count'] if post['comments']['count'] and post['comments']['data']: last_updated = post['comments']['data'][ len(post['comments']['data']) - 1]['created_time'] new_post.comments_updated = datetime.datetime.strptime( last_updated[:-5], '%Y-%m-%dT%H:%M:%S') if post.has_key('actions'): new_post.link = post['actions'][0]['link'] elif post.has_key('link'): new_post.link = post['link'] view = "" if post.has_key('message'): view += post['message'] + "<br>" if post.has_key('caption'): view += post['caption'] + "<br>" if post.has_key('description'): view += post['description'] + "<br>" if post.has_key('story'): view += post['story'] + "<br>" view = tornado.escape.linkify(view) if post.has_key('picture'): view = '<img src="' + post['picture'] + '">' + view new_post.view = content_remote.sanitize( tornado.escape.xhtml_unescape(view)) new_post.save() # comments if post['comments']['count']: for comment in post['comments']['data']: exists = self.models.content_remote.get( to_username=self.user.username, post_id=comment['id'])[0] if exists: continue else: new_comment = self.models.content_remote() new_comment.to_username = self.user.username new_comment.username = comment['from']['name'] new_comment.from_user = ('http://facebook.com/' + comment['from']['id']) date_created = datetime.datetime.strptime( comment['created_time'][:-5], '%Y-%m-%dT%H:%M:%S') new_comment.date_created = date_created new_comment.type = 'remote-comment' new_comment.thread = post['id'] new_comment.post_id = comment['id'] if post.has_key('actions'): new_comment.link = post['actions'][0]['link'] new_comment.view = comment['message'] new_comment.save() count = self.models.content_remote.get(to_username=self.user.username, type='facebook', deleted=False).count() self.write(json.dumps({'count': count}))
def handle_activity_verb(self, env, signer_uri): salmon_doc = BeautifulSoup(env) activity_verb = salmon_doc.find(re.compile('.+:verb$')).string user_remote = self.models.users_remote.get( local_username=self.display["user"].username, profile_url=signer_uri)[0] if (activity_verb == 'http://activitystrea.ms/schema/1.0/follow'): user = users.get_remote_user_info(self, signer_uri, user_remote.local_username) user.follower = 1 user.save() smtp.follow(self, user.username, self.display["user"].email, user.profile_url) elif (activity_verb == 'http://ostatus.org/schema/1.0/unfollow' or activity_verb == 'http://activitystrea.ms/schema/1.0/stop-following'): user_remote.follower = 0 user_remote.save() elif (activity_verb == 'http://activitystrea.ms/schema/1.0/favorite'): activity_object = salmon_doc.find(re.compile('.+:object$')) atom_id = activity_object.find('atom:id').string local_url = atom_id.split(':')[2] content_url = url_factory.load_basic_parameters(self, url=local_url) already_favorited = self.models.content_remote.get( to_username=self.display["user"].username, from_user=signer_uri, type='favorite', local_content_name=content_url['name'])[0] if already_favorited: return content = self.models.content.get(username=self.display["user"].username, name=content_url['name'])[0] if not content: raise tornado.web.HTTPError(400) content.favorites += 1 content.save() favorite_record = self.models.content_remote() favorite_record.to_username = self.display["user"].username favorite_record.from_user = signer_uri favorite_record.username = user_remote.username favorite_record.date_created = datetime.datetime.strptime( salmon_doc.find('atom:updated').string[:-6], '%Y-%m-%dT%H:%M:%S') favorite_record.type = 'favorite' favorite_record.local_content_name = content.name favorite_record.save() elif (activity_verb == 'http://activitystrea.ms/schema/1.0/unfavorite' or activity_verb == 'http://ostatus.org/schema/1.0/unfavorite'): # TODO no activity object at least with ostatus?? pass elif (activity_verb == 'http://activitystrea.ms/schema/1.0/share'): # TODO pass elif (activity_verb == 'http://activitystrea.ms/schema/1.0/post'): atom_content = salmon_doc.find('atom:content').string sanitized_atom_content = content_remote.sanitize( tornado.escape.xhtml_unescape(atom_content)) existing_content = self.models.content_remote.get( to_username=self.display["user"].username, from_user=signer_uri, view=sanitized_atom_content)[0] thread = salmon_doc.find('thr:in-reply-to') ref = '' if thread: try: local_url = thread['ref'].split(':')[2] content_url = url_factory.load_basic_parameters(self, url=local_url) content = self.models.content.get( username=self.display["user"].username, name=content_url['name'])[0] if not content: raise tornado.web.HTTPError(400) ref = content_url['name'] content.comments_count += 1 content.comments_updated = datetime.datetime.utcnow() content.save() except Exception as ex: import logging logging.error("something wrong with thread") logging.error(ex) replies = salmon_doc.find('thr:replies') comments_count = 0 comments_updated = None if replies: if replies.has_key('count'): comments_count = int(replies['count']) if replies.has_key('updated'): comments_updated = replies['updated'] comments_response = urllib2.urlopen(replies['href']) content_remote.parse_feed(self.models, user_remote, comments_response.read(), remote_comments=True) mentioned = salmon_doc.findAll('atom:link', rel='mentioned') if not mentioned: mentioned = salmon_doc.findAll('atom:link', rel='ostatus:attention') this_user_mentioned = False if mentioned: this_user_url = self.nav_url(host=True, username=self.display["user"].username) for mentions in mentioned: if mentions['href'] == this_user_url: # hey, you've been mentioned. cool. this_user_mentioned = True break is_spam = spam.guess(atom_content, self.application.settings["private_path"], self.display["user"].username) if existing_content: # possible that it's picked up via feed, before we get the salmon call post_remote = existing_content else: post_remote = self.models.content_remote() post_remote.to_username = self.display["user"].username post_remote.from_user = signer_uri post_remote.username = user_remote.username post_remote.avatar = user_remote.avatar post_remote.date_created = datetime.datetime.strptime( salmon_doc.find('atom:published').string[:-6], '%Y-%m-%dT%H:%M:%S') post_remote.date_updated = datetime.datetime.strptime( salmon_doc.find('atom:updated').string[:-6], '%Y-%m-%dT%H:%M:%S') post_remote.comments_count = comments_count if comments_updated: post_remote.comments_updated = datetime.datetime.strptime( comments_updated[:-6], '%Y-%m-%dT%H:%M:%S') else: post_remote.comments_updated = None if is_spam: post_remote.is_spam = True else: spam.train_ham(atom_content, self.application.settings["private_path"], self.display["user"].username) post_remote.type = 'comment' if ref or (existing_content and existing_content.type == 'comment') else 'post' post_remote.title = salmon_doc.find('atom:title').string post_remote.post_id = salmon_doc.find('atom:id').string post_remote.link = salmon_doc.find('atom:link', rel='alternate')['href'] post_remote.local_content_name = content.name if ref else '' post_remote.view = sanitized_atom_content post_remote.save() if ref: socialize.socialize(self, content) if ref: smtp.comment(self, post_remote.username, post_remote.from_user, self.display["user"].email, self.content_url(content, host=True), sanitized_atom_content) elif this_user_mentioned: smtp.comment(self, post_remote.username, post_remote.from_user, self.display["user"].email, post_remote.link, sanitized_atom_content, this_user_mentioned=True)
def timeline_result(self, response): posts = response['response']['posts'] for post in posts: exists = self.models.content_remote.get(to_username=self.user.username, type='tumblr', post_id=str(post['id']))[0] if exists: continue else: new_post = self.models.content_remote() new_post.to_username = self.user.username new_post.username = post['blog_name'] new_post.from_user = '******' + post['blog_name'] #new_post.avatar = post['user']['profile_image_url'] parsed_date = datetime.datetime.utcfromtimestamp(post['timestamp']) # we don't keep items that are over 30 days old if parsed_date < datetime.datetime.utcnow() - datetime.timedelta( days=self.constants['feed_max_days_old']): continue new_post.date_created = parsed_date new_post.date_updated = None new_post.comments_count = post['note_count'] new_post.comments_updated = None new_post.type = 'tumblr' new_post.post_id = str(post['id']) new_post.link = post['post_url'] if post['type'] == 'text': new_post.title = post['title'] new_post.view = content_remote.sanitize( tornado.escape.xhtml_unescape(post['body'])) elif post['type'] == 'photo': html = "" for photo in post['photos']: chosen_photo = None for size in photo['alt_sizes']: if (not chosen_photo or (size['width'] <= 720 and chosen_photo['width'] < size['width'])): chosen_photo = size html += '<img src="' + content_remote.sanitize( tornado.escape.xhtml_unescape(chosen_photo['url'])) + '">' html += content_remote.sanitize(tornado.escape.xhtml_unescape( post['caption'])) new_post.view = html elif post['type'] == 'quote': new_post.view = content_remote.sanitize(tornado.escape.xhtml_unescape( post['text'] + '<br>' + post['source'])) elif post['type'] == 'link': new_post.title = post['title'] new_post.view = content_remote.sanitize(tornado.escape.xhtml_unescape( '<a href="' + post['url'] + '">' + post['url'] + '</a><br>' + post['description'])) elif post['type'] == 'chat': new_post.title = post['title'] new_post.view = content_remote.sanitize(tornado.escape.xhtml_unescape( post['body'].replace('\r\n', '<br>'))) elif post['type'] == 'audio': html = "" html += content_remote.sanitize(tornado.escape.xhtml_unescape( post['player'])) html += content_remote.sanitize(tornado.escape.xhtml_unescape( post['caption'])) new_post.view = html elif post['type'] == 'video': chosen_video = None for video in post['player']: if (not chosen_video or (video['width'] <= 720 and chosen_video['width'] < video['width'])): chosen_video = video html = "" html += content_remote.sanitize(tornado.escape.xhtml_unescape( chosen_video['embed_code'])) html += content_remote.sanitize(tornado.escape.xhtml_unescape( post['caption'])) new_post.view = html elif post['type'] == 'answer': new_post.title = post['question'] new_post.view = content_remote.sanitize(tornado.escape.xhtml_unescape( post['answer'])) new_post.save() count = self.models.content_remote.get(to_username=self.user.username, type='tumblr', deleted=False).count() self.write(json.dumps({ 'count': count }))