2012-04-24 12:54:37 -07:00
|
|
|
import time
|
2011-12-15 09:10:37 -08:00
|
|
|
import datetime
|
2011-12-17 13:05:11 -08:00
|
|
|
import zlib
|
2012-07-06 13:48:06 -07:00
|
|
|
import random
|
2012-11-27 11:59:54 -08:00
|
|
|
import re
|
2012-07-27 18:58:35 -07:00
|
|
|
from bson.objectid import ObjectId
|
2015-07-07 13:34:06 -07:00
|
|
|
from mongoengine.queryset import NotUniqueError
|
2020-06-12 01:27:07 -04:00
|
|
|
from django.shortcuts import get_object_or_404, render
|
2020-06-17 03:47:15 -04:00
|
|
|
from django.urls import reverse
|
2011-12-17 13:05:11 -08:00
|
|
|
from django.contrib.auth.models import User
|
2012-10-18 11:11:26 -07:00
|
|
|
from django.contrib.sites.models import Site
|
2012-04-19 19:09:31 -07:00
|
|
|
from django.template.loader import render_to_string
|
2012-10-29 12:25:28 -07:00
|
|
|
from django.http import HttpResponse, HttpResponseRedirect, Http404, HttpResponseForbidden
|
2011-12-20 11:49:49 -08:00
|
|
|
from django.conf import settings
|
2012-10-18 11:11:26 -07:00
|
|
|
from django.utils import feedgenerator
|
2012-01-26 08:43:46 -08:00
|
|
|
from apps.rss_feeds.models import MStory, Feed, MStarredStory
|
2012-03-22 19:37:19 -07:00
|
|
|
from apps.social.models import MSharedStory, MSocialServices, MSocialProfile, MSocialSubscription, MCommentReply
|
2012-10-24 18:52:24 -07:00
|
|
|
from apps.social.models import MInteraction, MActivity, MFollowRequest
|
2012-07-05 19:50:02 -07:00
|
|
|
from apps.social.tasks import PostToService, EmailCommentReplies, EmailStoryReshares
|
2013-04-22 15:24:38 -07:00
|
|
|
from apps.social.tasks import UpdateRecalcForSubscription, EmailFirstShare
|
2012-01-26 08:43:46 -08:00
|
|
|
from apps.analyzer.models import MClassifierTitle, MClassifierAuthor, MClassifierFeed, MClassifierTag
|
|
|
|
from apps.analyzer.models import apply_classifier_titles, apply_classifier_feeds, apply_classifier_authors, apply_classifier_tags
|
2012-05-29 11:48:40 -07:00
|
|
|
from apps.analyzer.models import get_classifiers_for_user, sort_classifiers_by_feed
|
2013-05-03 17:47:38 -07:00
|
|
|
from apps.reader.models import UserSubscription
|
2012-07-05 18:29:38 -07:00
|
|
|
from apps.profile.models import Profile
|
2011-12-15 09:10:37 -08:00
|
|
|
from utils import json_functions as json
|
|
|
|
from utils import log as logging
|
2012-01-24 09:02:23 -08:00
|
|
|
from utils.user_functions import get_user, ajax_login_required
|
2012-10-24 16:09:47 -07:00
|
|
|
from utils.view_functions import render_to, is_true
|
2012-12-12 13:58:10 -08:00
|
|
|
from utils.view_functions import required_params
|
2012-01-24 09:02:23 -08:00
|
|
|
from utils.story_functions import format_story_link_date__short
|
|
|
|
from utils.story_functions import format_story_link_date__long
|
2012-07-23 13:08:48 -07:00
|
|
|
from utils.story_functions import strip_tags
|
2014-12-08 14:59:23 -08:00
|
|
|
from utils.ratelimit import ratelimit
|
2012-07-06 13:48:06 -07:00
|
|
|
from utils import jennyholzer
|
2012-01-24 09:02:23 -08:00
|
|
|
from vendor.timezones.utilities import localtime_for_timezone
|
2011-12-17 13:05:11 -08:00
|
|
|
|
2012-08-20 14:51:32 -07:00
|
|
|
|
2012-01-24 09:02:23 -08:00
|
|
|
@json.json_view
|
2012-01-31 10:15:11 -08:00
|
|
|
def load_social_stories(request, user_id, username=None):
|
2012-07-19 23:29:11 -07:00
|
|
|
user = get_user(request)
|
2012-01-31 10:15:11 -08:00
|
|
|
social_user_id = int(user_id)
|
2012-07-19 23:29:11 -07:00
|
|
|
social_user = get_object_or_404(User, pk=social_user_id)
|
2020-06-07 08:04:23 -04:00
|
|
|
offset = int(request.GET.get('offset', 0))
|
|
|
|
limit = int(request.GET.get('limit', 6))
|
2020-07-02 18:31:13 -04:00
|
|
|
page = int(request.GET.get('page', 1))
|
2020-06-07 08:04:23 -04:00
|
|
|
order = request.GET.get('order', 'newest')
|
|
|
|
read_filter = request.GET.get('read_filter', 'all')
|
|
|
|
query = request.GET.get('query', '').strip()
|
|
|
|
include_story_content = is_true(request.GET.get('include_story_content', True))
|
2012-07-24 17:16:01 -07:00
|
|
|
stories = []
|
2013-07-25 17:05:32 -07:00
|
|
|
message = None
|
2012-07-24 17:16:01 -07:00
|
|
|
|
2012-01-24 09:02:23 -08:00
|
|
|
if page: offset = limit * (int(page) - 1)
|
|
|
|
now = localtime_for_timezone(datetime.datetime.now(), user.profile.timezone)
|
2012-07-06 14:19:41 -07:00
|
|
|
|
2012-07-25 23:57:10 -07:00
|
|
|
social_profile = MSocialProfile.get_user(social_user.pk)
|
2012-07-19 23:29:11 -07:00
|
|
|
try:
|
|
|
|
socialsub = MSocialSubscription.objects.get(user_id=user.pk, subscription_user_id=social_user_id)
|
|
|
|
except MSocialSubscription.DoesNotExist:
|
|
|
|
socialsub = None
|
2012-01-24 09:02:23 -08:00
|
|
|
|
2012-10-24 16:09:47 -07:00
|
|
|
if social_profile.private and not social_profile.is_followed_by_user(user.pk):
|
|
|
|
message = "%s has a private blurblog and you must be following them in order to read it." % social_profile.username
|
2013-07-25 11:10:56 -07:00
|
|
|
elif query:
|
2013-07-25 17:05:32 -07:00
|
|
|
if user.profile.is_premium:
|
|
|
|
stories = social_profile.find_stories(query, offset=offset, limit=limit)
|
|
|
|
else:
|
|
|
|
stories = []
|
|
|
|
message = "You must be a premium subscriber to search."
|
2012-10-24 16:09:47 -07:00
|
|
|
elif socialsub and (read_filter == 'unread' or order == 'oldest'):
|
2017-01-10 20:25:02 -08:00
|
|
|
cutoff_date = max(socialsub.mark_read_date, user.profile.unread_cutoff)
|
|
|
|
story_hashes = socialsub.get_stories(order=order, read_filter=read_filter, offset=offset, limit=limit, cutoff_date=cutoff_date)
|
2012-07-19 23:29:11 -07:00
|
|
|
story_date_order = "%sshared_date" % ('' if order == 'oldest' else '-')
|
2013-04-29 15:27:22 -07:00
|
|
|
if story_hashes:
|
2012-07-24 17:16:01 -07:00
|
|
|
mstories = MSharedStory.objects(user_id=social_user.pk,
|
2013-04-29 15:27:22 -07:00
|
|
|
story_hash__in=story_hashes).order_by(story_date_order)
|
2019-01-20 14:12:28 -05:00
|
|
|
for story in mstories: story.extract_image_urls()
|
2012-07-24 17:16:01 -07:00
|
|
|
stories = Feed.format_stories(mstories)
|
2012-07-19 23:29:11 -07:00
|
|
|
else:
|
|
|
|
mstories = MSharedStory.objects(user_id=social_user.pk).order_by('-shared_date')[offset:offset+limit]
|
2019-01-20 14:12:28 -05:00
|
|
|
for story in mstories: story.extract_image_urls()
|
2012-07-19 23:29:11 -07:00
|
|
|
stories = Feed.format_stories(mstories)
|
|
|
|
|
2017-01-10 20:25:02 -08:00
|
|
|
if not stories or False: # False is to force a recount even if 0 stories
|
2012-10-24 16:09:47 -07:00
|
|
|
return dict(stories=[], message=message)
|
2012-07-06 14:19:41 -07:00
|
|
|
|
2012-06-29 21:06:33 -07:00
|
|
|
stories, user_profiles = MSharedStory.stories_with_comments_and_profiles(stories, user.pk, check_all=True)
|
2012-01-26 08:43:46 -08:00
|
|
|
|
2012-02-03 11:41:01 -08:00
|
|
|
story_feed_ids = list(set(s['story_feed_id'] for s in stories))
|
2012-01-26 09:32:24 -08:00
|
|
|
usersubs = UserSubscription.objects.filter(user__pk=user.pk, feed__pk__in=story_feed_ids)
|
2012-01-26 09:54:48 -08:00
|
|
|
usersubs_map = dict((sub.feed_id, sub) for sub in usersubs)
|
2012-01-26 18:59:40 -08:00
|
|
|
unsub_feed_ids = list(set(story_feed_ids).difference(set(usersubs_map.keys())))
|
|
|
|
unsub_feeds = Feed.objects.filter(pk__in=unsub_feed_ids)
|
2012-05-29 11:48:40 -07:00
|
|
|
unsub_feeds = [feed.canonical(include_favicon=False) for feed in unsub_feeds]
|
2013-09-16 16:42:49 -07:00
|
|
|
date_delta = user.profile.unread_cutoff
|
2012-03-14 12:38:59 -07:00
|
|
|
if socialsub and date_delta < socialsub.mark_read_date:
|
2012-02-15 18:00:10 -08:00
|
|
|
date_delta = socialsub.mark_read_date
|
2012-01-26 09:32:24 -08:00
|
|
|
|
2012-01-26 08:43:46 -08:00
|
|
|
# Get intelligence classifier for user
|
2012-02-15 18:00:10 -08:00
|
|
|
classifier_feeds = list(MClassifierFeed.objects(user_id=user.pk, social_user_id=social_user_id))
|
|
|
|
classifier_authors = list(MClassifierAuthor.objects(user_id=user.pk, social_user_id=social_user_id))
|
|
|
|
classifier_titles = list(MClassifierTitle.objects(user_id=user.pk, social_user_id=social_user_id))
|
|
|
|
classifier_tags = list(MClassifierTag.objects(user_id=user.pk, social_user_id=social_user_id))
|
2012-03-22 15:27:28 -07:00
|
|
|
# Merge with feed specific classifiers
|
|
|
|
classifier_feeds = classifier_feeds + list(MClassifierFeed.objects(user_id=user.pk, feed_id__in=story_feed_ids))
|
|
|
|
classifier_authors = classifier_authors + list(MClassifierAuthor.objects(user_id=user.pk, feed_id__in=story_feed_ids))
|
|
|
|
classifier_titles = classifier_titles + list(MClassifierTitle.objects(user_id=user.pk, feed_id__in=story_feed_ids))
|
|
|
|
classifier_tags = classifier_tags + list(MClassifierTag.objects(user_id=user.pk, feed_id__in=story_feed_ids))
|
2012-02-24 10:12:32 -08:00
|
|
|
|
2013-05-02 17:42:04 -07:00
|
|
|
unread_story_hashes = []
|
2013-07-29 15:11:20 -07:00
|
|
|
if (read_filter == 'all' or query) and socialsub:
|
2013-09-16 16:42:49 -07:00
|
|
|
unread_story_hashes = socialsub.get_stories(read_filter='unread', limit=500, cutoff_date=user.profile.unread_cutoff)
|
2013-05-02 17:42:04 -07:00
|
|
|
story_hashes = [story['story_hash'] for story in stories]
|
2012-02-24 10:12:32 -08:00
|
|
|
|
2012-01-26 08:43:46 -08:00
|
|
|
starred_stories = MStarredStory.objects(user_id=user.pk,
|
2013-05-02 17:42:04 -07:00
|
|
|
story_hash__in=story_hashes)\
|
2013-08-13 17:21:41 -07:00
|
|
|
.only('story_hash', 'starred_date', 'user_tags')
|
2012-01-26 08:43:46 -08:00
|
|
|
shared_stories = MSharedStory.objects(user_id=user.pk,
|
2013-05-02 17:42:04 -07:00
|
|
|
story_hash__in=story_hashes)\
|
2016-11-09 11:28:53 -08:00
|
|
|
.hint([('story_hash', 1)])\
|
2013-05-02 17:42:04 -07:00
|
|
|
.only('story_hash', 'shared_date', 'comments')
|
2013-08-13 17:21:41 -07:00
|
|
|
starred_stories = dict([(story.story_hash, dict(starred_date=story.starred_date,
|
|
|
|
user_tags=story.user_tags))
|
|
|
|
for story in starred_stories])
|
2013-05-02 17:42:04 -07:00
|
|
|
shared_stories = dict([(story.story_hash, dict(shared_date=story.shared_date,
|
|
|
|
comments=story.comments))
|
2012-01-26 08:43:46 -08:00
|
|
|
for story in shared_stories])
|
2012-01-26 09:54:48 -08:00
|
|
|
|
2013-11-06 23:39:20 -08:00
|
|
|
nowtz = localtime_for_timezone(now, user.profile.timezone)
|
2012-01-24 09:02:23 -08:00
|
|
|
for story in stories:
|
2016-11-20 19:23:53 -08:00
|
|
|
if not include_story_content:
|
|
|
|
del story['story_content']
|
2012-02-03 11:41:01 -08:00
|
|
|
story['social_user_id'] = social_user_id
|
2012-02-16 18:36:52 -08:00
|
|
|
# story_date = localtime_for_timezone(story['story_date'], user.profile.timezone)
|
2012-01-24 09:02:23 -08:00
|
|
|
shared_date = localtime_for_timezone(story['shared_date'], user.profile.timezone)
|
2013-11-06 23:39:20 -08:00
|
|
|
story['short_parsed_date'] = format_story_link_date__short(shared_date, nowtz)
|
|
|
|
story['long_parsed_date'] = format_story_link_date__long(shared_date, nowtz)
|
2012-02-24 10:12:32 -08:00
|
|
|
|
2013-05-02 17:42:04 -07:00
|
|
|
story['read_status'] = 1
|
2015-09-03 15:18:13 -07:00
|
|
|
if story['story_date'] < user.profile.unread_cutoff:
|
|
|
|
story['read_status'] = 1
|
|
|
|
elif (read_filter == 'all' or query) and socialsub:
|
2013-05-10 13:50:38 -07:00
|
|
|
story['read_status'] = 1 if story['story_hash'] not in unread_story_hashes else 0
|
2013-07-29 15:11:20 -07:00
|
|
|
elif read_filter == 'unread' and socialsub:
|
|
|
|
story['read_status'] = 0
|
2012-03-07 17:34:22 -08:00
|
|
|
|
2013-05-02 17:42:04 -07:00
|
|
|
if story['story_hash'] in starred_stories:
|
2012-01-26 08:43:46 -08:00
|
|
|
story['starred'] = True
|
2013-08-13 17:21:41 -07:00
|
|
|
starred_date = localtime_for_timezone(starred_stories[story['story_hash']]['starred_date'],
|
2013-05-02 17:42:04 -07:00
|
|
|
user.profile.timezone)
|
2012-01-26 08:43:46 -08:00
|
|
|
story['starred_date'] = format_story_link_date__long(starred_date, now)
|
2013-08-13 17:21:41 -07:00
|
|
|
story['user_tags'] = starred_stories[story['story_hash']]['user_tags']
|
2013-05-02 17:42:04 -07:00
|
|
|
if story['story_hash'] in shared_stories:
|
2012-01-26 08:43:46 -08:00
|
|
|
story['shared'] = True
|
2013-05-02 17:42:04 -07:00
|
|
|
story['shared_comments'] = strip_tags(shared_stories[story['story_hash']]['comments'])
|
2012-01-26 08:43:46 -08:00
|
|
|
|
2012-01-24 09:02:23 -08:00
|
|
|
story['intelligence'] = {
|
2012-04-12 11:18:56 -07:00
|
|
|
'feed': apply_classifier_feeds(classifier_feeds, story['story_feed_id'],
|
2012-09-24 17:38:46 -07:00
|
|
|
social_user_ids=social_user_id),
|
2012-01-26 08:43:46 -08:00
|
|
|
'author': apply_classifier_authors(classifier_authors, story),
|
|
|
|
'tags': apply_classifier_tags(classifier_tags, story),
|
|
|
|
'title': apply_classifier_titles(classifier_titles, story),
|
2012-01-24 09:02:23 -08:00
|
|
|
}
|
2012-04-24 12:54:37 -07:00
|
|
|
|
2012-05-29 11:48:40 -07:00
|
|
|
|
|
|
|
classifiers = sort_classifiers_by_feed(user=user, feed_ids=story_feed_ids,
|
|
|
|
classifier_feeds=classifier_feeds,
|
|
|
|
classifier_authors=classifier_authors,
|
|
|
|
classifier_titles=classifier_titles,
|
|
|
|
classifier_tags=classifier_tags)
|
2012-04-24 12:54:37 -07:00
|
|
|
if socialsub:
|
|
|
|
socialsub.feed_opens += 1
|
2012-08-10 14:22:51 -07:00
|
|
|
socialsub.needs_unread_recalc = True
|
2012-04-24 12:54:37 -07:00
|
|
|
socialsub.save()
|
|
|
|
|
2013-07-25 17:13:46 -07:00
|
|
|
search_log = "~SN~FG(~SB%s~SN)" % query if query else ""
|
|
|
|
logging.user(request, "~FYLoading ~FMshared stories~FY: ~SB%s%s %s" % (
|
|
|
|
social_profile.title[:22], ('~SN/p%s' % page) if page > 1 else '', search_log))
|
2012-07-06 14:19:41 -07:00
|
|
|
|
2012-05-29 11:48:40 -07:00
|
|
|
return {
|
|
|
|
"stories": stories,
|
|
|
|
"user_profiles": user_profiles,
|
|
|
|
"feeds": unsub_feeds,
|
|
|
|
"classifiers": classifiers,
|
|
|
|
}
|
2012-08-07 14:37:07 -07:00
|
|
|
|
|
|
|
@json.json_view
|
|
|
|
def load_river_blurblog(request):
|
2012-08-07 23:55:03 -07:00
|
|
|
limit = 10
|
2012-08-07 14:37:07 -07:00
|
|
|
start = time.time()
|
|
|
|
user = get_user(request)
|
2020-06-07 08:04:23 -04:00
|
|
|
social_user_ids = request.GET.getlist('social_user_ids') or request.GET.getlist('social_user_ids[]')
|
2017-04-04 17:13:43 -07:00
|
|
|
social_user_ids = [int(uid) for uid in social_user_ids if uid]
|
2012-08-07 14:37:07 -07:00
|
|
|
original_user_ids = list(social_user_ids)
|
2020-06-07 08:04:23 -04:00
|
|
|
page = int(request.GET.get('page', 1))
|
|
|
|
order = request.GET.get('order', 'newest')
|
|
|
|
read_filter = request.GET.get('read_filter', 'unread')
|
|
|
|
relative_user_id = request.GET.get('relative_user_id', None)
|
|
|
|
global_feed = request.GET.get('global_feed', None)
|
2012-08-07 14:37:07 -07:00
|
|
|
now = localtime_for_timezone(datetime.datetime.now(), user.profile.timezone)
|
2013-05-03 16:48:17 -07:00
|
|
|
|
2012-11-30 14:28:55 -08:00
|
|
|
if global_feed:
|
2012-11-30 15:42:15 -08:00
|
|
|
global_user = User.objects.get(username='popular')
|
2012-11-30 14:28:55 -08:00
|
|
|
relative_user_id = global_user.pk
|
2012-10-19 18:33:28 -07:00
|
|
|
|
2012-08-07 14:37:07 -07:00
|
|
|
if not relative_user_id:
|
2012-11-30 15:42:15 -08:00
|
|
|
relative_user_id = user.pk
|
2012-08-07 14:37:07 -07:00
|
|
|
|
2013-10-07 13:36:10 -07:00
|
|
|
socialsubs = MSocialSubscription.objects.filter(user_id=relative_user_id)
|
|
|
|
if social_user_ids:
|
|
|
|
socialsubs = socialsubs.filter(subscription_user_id__in=social_user_ids)
|
|
|
|
|
2012-08-07 14:37:07 -07:00
|
|
|
if not social_user_ids:
|
|
|
|
social_user_ids = [s.subscription_user_id for s in socialsubs]
|
|
|
|
|
|
|
|
offset = (page-1) * limit
|
|
|
|
limit = page * limit - 1
|
|
|
|
|
2013-10-07 13:36:10 -07:00
|
|
|
story_hashes, story_dates, unread_feed_story_hashes = MSocialSubscription.feed_stories(
|
|
|
|
user.pk, social_user_ids,
|
|
|
|
offset=offset, limit=limit,
|
|
|
|
order=order, read_filter=read_filter,
|
|
|
|
relative_user_id=relative_user_id,
|
|
|
|
socialsubs=socialsubs,
|
|
|
|
cutoff_date=user.profile.unread_cutoff)
|
2013-04-29 15:27:22 -07:00
|
|
|
mstories = MStory.find_by_story_hashes(story_hashes)
|
2020-06-17 03:47:15 -04:00
|
|
|
story_hashes_to_dates = dict(list(zip(story_hashes, story_dates)))
|
2013-04-29 15:27:22 -07:00
|
|
|
def sort_stories_by_hash(a, b):
|
|
|
|
return (int(story_hashes_to_dates[str(b.story_hash)]) -
|
|
|
|
int(story_hashes_to_dates[str(a.story_hash)]))
|
2020-06-17 03:47:15 -04:00
|
|
|
sorted_mstories = sorted(mstories, key=sort_stories_by_hash)
|
2012-08-08 19:13:10 -07:00
|
|
|
stories = Feed.format_stories(sorted_mstories)
|
2012-08-07 23:55:03 -07:00
|
|
|
for s, story in enumerate(stories):
|
2013-04-30 15:49:44 -07:00
|
|
|
timestamp = story_hashes_to_dates[story['story_hash']]
|
|
|
|
story['story_date'] = datetime.datetime.fromtimestamp(timestamp)
|
2012-11-30 15:42:15 -08:00
|
|
|
share_relative_user_id = relative_user_id
|
2012-11-30 16:14:22 -08:00
|
|
|
if global_feed:
|
2012-11-30 15:42:15 -08:00
|
|
|
share_relative_user_id = user.pk
|
2012-08-09 21:13:57 -07:00
|
|
|
stories, user_profiles = MSharedStory.stories_with_comments_and_profiles(stories,
|
2012-11-30 15:42:15 -08:00
|
|
|
share_relative_user_id,
|
2012-08-07 14:37:07 -07:00
|
|
|
check_all=True)
|
2012-01-24 09:02:23 -08:00
|
|
|
|
2012-08-07 14:37:07 -07:00
|
|
|
story_feed_ids = list(set(s['story_feed_id'] for s in stories))
|
|
|
|
usersubs = UserSubscription.objects.filter(user__pk=user.pk, feed__pk__in=story_feed_ids)
|
|
|
|
usersubs_map = dict((sub.feed_id, sub) for sub in usersubs)
|
|
|
|
unsub_feed_ids = list(set(story_feed_ids).difference(set(usersubs_map.keys())))
|
|
|
|
unsub_feeds = Feed.objects.filter(pk__in=unsub_feed_ids)
|
|
|
|
unsub_feeds = [feed.canonical(include_favicon=False) for feed in unsub_feeds]
|
|
|
|
|
|
|
|
if story_feed_ids:
|
2013-05-02 17:42:04 -07:00
|
|
|
story_hashes = [story['story_hash'] for story in stories]
|
2012-08-07 14:37:07 -07:00
|
|
|
starred_stories = MStarredStory.objects(
|
|
|
|
user_id=user.pk,
|
2013-05-02 17:42:04 -07:00
|
|
|
story_hash__in=story_hashes
|
2013-08-13 17:21:41 -07:00
|
|
|
).only('story_hash', 'starred_date', 'user_tags')
|
|
|
|
starred_stories = dict([(story.story_hash, dict(starred_date=story.starred_date,
|
|
|
|
user_tags=story.user_tags))
|
2012-08-07 14:37:07 -07:00
|
|
|
for story in starred_stories])
|
2012-08-09 23:33:54 -07:00
|
|
|
shared_stories = MSharedStory.objects(user_id=user.pk,
|
2013-05-02 17:42:04 -07:00
|
|
|
story_hash__in=story_hashes)\
|
2016-11-09 11:28:53 -08:00
|
|
|
.hint([('story_hash', 1)])\
|
2013-05-02 17:42:04 -07:00
|
|
|
.only('story_hash', 'shared_date', 'comments')
|
|
|
|
shared_stories = dict([(story.story_hash, dict(shared_date=story.shared_date,
|
|
|
|
comments=story.comments))
|
2013-05-03 14:46:44 -07:00
|
|
|
for story in shared_stories])
|
2012-08-07 14:37:07 -07:00
|
|
|
else:
|
|
|
|
starred_stories = {}
|
2012-08-09 23:33:54 -07:00
|
|
|
shared_stories = {}
|
2012-08-07 14:37:07 -07:00
|
|
|
|
|
|
|
# Intelligence classifiers for all feeds involved
|
|
|
|
if story_feed_ids:
|
|
|
|
classifier_feeds = list(MClassifierFeed.objects(user_id=user.pk,
|
2012-09-24 17:38:46 -07:00
|
|
|
social_user_id__in=social_user_ids))
|
|
|
|
classifier_feeds = classifier_feeds + list(MClassifierFeed.objects(user_id=user.pk,
|
2012-08-07 14:37:07 -07:00
|
|
|
feed_id__in=story_feed_ids))
|
|
|
|
classifier_authors = list(MClassifierAuthor.objects(user_id=user.pk,
|
|
|
|
feed_id__in=story_feed_ids))
|
|
|
|
classifier_titles = list(MClassifierTitle.objects(user_id=user.pk,
|
|
|
|
feed_id__in=story_feed_ids))
|
|
|
|
classifier_tags = list(MClassifierTag.objects(user_id=user.pk,
|
|
|
|
feed_id__in=story_feed_ids))
|
|
|
|
else:
|
|
|
|
classifier_feeds = []
|
|
|
|
classifier_authors = []
|
|
|
|
classifier_titles = []
|
|
|
|
classifier_tags = []
|
|
|
|
|
|
|
|
# Just need to format stories
|
2013-11-06 23:39:20 -08:00
|
|
|
nowtz = localtime_for_timezone(now, user.profile.timezone)
|
2012-08-07 14:37:07 -07:00
|
|
|
for story in stories:
|
2013-05-03 16:48:17 -07:00
|
|
|
story['read_status'] = 0
|
2013-10-07 13:36:10 -07:00
|
|
|
if story['story_hash'] not in unread_feed_story_hashes:
|
2012-08-07 14:37:07 -07:00
|
|
|
story['read_status'] = 1
|
|
|
|
story_date = localtime_for_timezone(story['story_date'], user.profile.timezone)
|
2013-11-06 23:39:20 -08:00
|
|
|
story['short_parsed_date'] = format_story_link_date__short(story_date, nowtz)
|
|
|
|
story['long_parsed_date'] = format_story_link_date__long(story_date, nowtz)
|
2013-05-03 16:50:16 -07:00
|
|
|
if story['story_hash'] in starred_stories:
|
2012-08-07 14:37:07 -07:00
|
|
|
story['starred'] = True
|
2013-08-13 17:21:41 -07:00
|
|
|
starred_date = localtime_for_timezone(starred_stories[story['story_hash']]['starred_date'], user.profile.timezone)
|
2012-08-07 14:37:07 -07:00
|
|
|
story['starred_date'] = format_story_link_date__long(starred_date, now)
|
2013-08-13 17:21:41 -07:00
|
|
|
story['user_tags'] = starred_stories[story['story_hash']]['user_tags']
|
2012-08-07 14:37:07 -07:00
|
|
|
story['intelligence'] = {
|
2012-09-24 17:38:46 -07:00
|
|
|
'feed': apply_classifier_feeds(classifier_feeds, story['story_feed_id'],
|
|
|
|
social_user_ids=story['friend_user_ids']),
|
2012-08-07 14:37:07 -07:00
|
|
|
'author': apply_classifier_authors(classifier_authors, story),
|
|
|
|
'tags': apply_classifier_tags(classifier_tags, story),
|
|
|
|
'title': apply_classifier_titles(classifier_titles, story),
|
|
|
|
}
|
2013-05-03 16:50:16 -07:00
|
|
|
if story['story_hash'] in shared_stories:
|
2012-08-09 23:33:54 -07:00
|
|
|
story['shared'] = True
|
2013-05-03 16:50:16 -07:00
|
|
|
shared_date = localtime_for_timezone(shared_stories[story['story_hash']]['shared_date'],
|
2012-08-09 23:33:54 -07:00
|
|
|
user.profile.timezone)
|
|
|
|
story['shared_date'] = format_story_link_date__long(shared_date, now)
|
2013-05-03 16:50:16 -07:00
|
|
|
story['shared_comments'] = strip_tags(shared_stories[story['story_hash']]['comments'])
|
2013-09-16 16:42:49 -07:00
|
|
|
if (shared_stories[story['story_hash']]['shared_date'] < user.profile.unread_cutoff or
|
2013-10-07 13:36:10 -07:00
|
|
|
story['story_hash'] not in unread_feed_story_hashes):
|
2013-05-03 16:48:17 -07:00
|
|
|
story['read_status'] = 1
|
|
|
|
|
2012-09-24 17:38:46 -07:00
|
|
|
classifiers = sort_classifiers_by_feed(user=user, feed_ids=story_feed_ids,
|
|
|
|
classifier_feeds=classifier_feeds,
|
|
|
|
classifier_authors=classifier_authors,
|
|
|
|
classifier_titles=classifier_titles,
|
|
|
|
classifier_tags=classifier_tags)
|
2012-08-07 14:37:07 -07:00
|
|
|
|
|
|
|
diff = time.time() - start
|
|
|
|
timediff = round(float(diff), 2)
|
2012-12-26 20:03:46 -08:00
|
|
|
logging.user(request, "~FYLoading ~FCriver ~FMblurblogs~FC stories~FY: ~SBp%s~SN (%s/%s "
|
2012-08-07 14:37:07 -07:00
|
|
|
"stories, ~SN%s/%s/%s feeds)" %
|
|
|
|
(page, len(stories), len(mstories), len(story_feed_ids),
|
|
|
|
len(social_user_ids), len(original_user_ids)))
|
|
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
"stories": stories,
|
|
|
|
"user_profiles": user_profiles,
|
|
|
|
"feeds": unsub_feeds,
|
|
|
|
"classifiers": classifiers,
|
|
|
|
"elapsed_time": timediff,
|
|
|
|
}
|
|
|
|
|
2012-07-06 17:47:06 -07:00
|
|
|
def load_social_page(request, user_id, username=None, **kwargs):
|
2013-01-23 14:39:03 -08:00
|
|
|
user = get_user(request.user)
|
2012-01-31 10:15:11 -08:00
|
|
|
social_user_id = int(user_id)
|
|
|
|
social_user = get_object_or_404(User, pk=social_user_id)
|
2020-06-07 08:04:23 -04:00
|
|
|
offset = int(request.GET.get('offset', 0))
|
|
|
|
limit = int(request.GET.get('limit', 6))
|
2013-07-05 17:27:48 -07:00
|
|
|
try:
|
2020-06-07 08:04:23 -04:00
|
|
|
page = int(request.GET.get('page', 1))
|
2013-07-05 17:27:48 -07:00
|
|
|
except ValueError:
|
|
|
|
page = 1
|
2020-06-07 08:04:23 -04:00
|
|
|
format = request.GET.get('format', None)
|
2012-07-06 00:34:21 -07:00
|
|
|
has_next_page = False
|
2020-06-07 08:04:23 -04:00
|
|
|
feed_id = kwargs.get('feed_id') or request.GET.get('feed_id')
|
2013-01-23 16:05:43 -08:00
|
|
|
if page:
|
2013-02-20 11:15:10 -08:00
|
|
|
offset = limit * (page-1)
|
2015-04-07 10:55:29 -07:00
|
|
|
social_services = None
|
2012-07-02 15:40:03 -07:00
|
|
|
user_social_profile = None
|
2012-08-14 00:42:32 -07:00
|
|
|
user_social_services = None
|
2012-08-15 18:35:55 -07:00
|
|
|
user_following_social_profile = None
|
2013-01-23 14:21:16 -08:00
|
|
|
relative_user_id = user_id
|
2020-06-11 15:13:12 -04:00
|
|
|
if user.is_authenticated:
|
2012-07-25 23:57:10 -07:00
|
|
|
user_social_profile = MSocialProfile.get_user(user.pk)
|
2012-08-14 00:26:42 -07:00
|
|
|
user_social_services = MSocialServices.get_user(user.pk)
|
2012-08-15 18:35:55 -07:00
|
|
|
user_following_social_profile = user_social_profile.is_following_user(social_user_id)
|
2012-07-25 23:57:10 -07:00
|
|
|
social_profile = MSocialProfile.get_user(social_user_id)
|
2013-01-23 14:21:16 -08:00
|
|
|
|
2013-01-23 14:31:08 -08:00
|
|
|
if '.dev' in username:
|
|
|
|
username = username.replace('.dev', '')
|
2013-01-23 14:21:16 -08:00
|
|
|
current_tab = "blurblogs"
|
|
|
|
global_feed = False
|
|
|
|
if username == "popular":
|
|
|
|
current_tab = username
|
|
|
|
elif username == "popular.global":
|
|
|
|
current_tab = "global"
|
|
|
|
global_feed = True
|
2013-05-22 18:44:56 -07:00
|
|
|
|
2020-06-11 15:13:12 -04:00
|
|
|
if social_profile.private and (not user.is_authenticated or
|
2012-10-24 16:09:47 -07:00
|
|
|
not social_profile.is_followed_by_user(user.pk)):
|
|
|
|
stories = []
|
2013-01-23 14:21:16 -08:00
|
|
|
elif global_feed:
|
|
|
|
socialsubs = MSocialSubscription.objects.filter(user_id=relative_user_id)
|
|
|
|
social_user_ids = [s.subscription_user_id for s in socialsubs]
|
2013-05-10 12:29:38 -07:00
|
|
|
story_ids, story_dates, _ = MSocialSubscription.feed_stories(user.pk, social_user_ids,
|
2013-01-31 17:36:48 -08:00
|
|
|
offset=offset, limit=limit+1,
|
2013-01-23 14:21:16 -08:00
|
|
|
# order=order, read_filter=read_filter,
|
|
|
|
relative_user_id=relative_user_id,
|
2020-06-11 15:13:12 -04:00
|
|
|
cache=request.user.is_authenticated,
|
2013-09-16 16:42:49 -07:00
|
|
|
cutoff_date=user.profile.unread_cutoff)
|
2013-02-20 11:15:10 -08:00
|
|
|
if len(story_ids) > limit:
|
2013-01-23 16:05:43 -08:00
|
|
|
has_next_page = True
|
|
|
|
story_ids = story_ids[:-1]
|
2013-05-08 17:46:50 -07:00
|
|
|
mstories = MStory.find_by_story_hashes(story_ids)
|
2020-06-17 03:47:15 -04:00
|
|
|
story_id_to_dates = dict(list(zip(story_ids, story_dates)))
|
2013-01-23 14:21:16 -08:00
|
|
|
def sort_stories_by_id(a, b):
|
2013-05-08 17:48:04 -07:00
|
|
|
return int(story_id_to_dates[str(b.story_hash)]) - int(story_id_to_dates[str(a.story_hash)])
|
2020-06-17 03:47:15 -04:00
|
|
|
sorted_mstories = sorted(mstories, key=sort_stories_by_id)
|
2013-01-23 14:21:16 -08:00
|
|
|
stories = Feed.format_stories(sorted_mstories)
|
|
|
|
for story in stories:
|
|
|
|
story['shared_date'] = story['story_date']
|
2012-10-24 16:09:47 -07:00
|
|
|
else:
|
|
|
|
params = dict(user_id=social_user.pk)
|
|
|
|
if feed_id:
|
|
|
|
params['story_feed_id'] = feed_id
|
2020-06-17 03:47:15 -04:00
|
|
|
if 'story_db_id' in params:
|
2016-11-10 17:49:52 -08:00
|
|
|
params.pop('story_db_id')
|
2013-02-20 11:31:21 -08:00
|
|
|
mstories = MSharedStory.objects(**params).order_by('-shared_date')[offset:offset+limit+1]
|
2013-05-14 16:36:03 -07:00
|
|
|
stories = Feed.format_stories(mstories, include_permalinks=True)
|
2013-05-14 16:38:28 -07:00
|
|
|
|
2013-02-20 11:15:10 -08:00
|
|
|
if len(stories) > limit:
|
2013-01-23 16:05:43 -08:00
|
|
|
has_next_page = True
|
|
|
|
stories = stories[:-1]
|
2012-07-06 00:41:36 -07:00
|
|
|
|
2012-01-31 10:15:11 -08:00
|
|
|
if not stories:
|
2012-07-06 11:20:13 -07:00
|
|
|
params = {
|
2012-06-28 19:47:30 -07:00
|
|
|
"user": user,
|
|
|
|
"stories": [],
|
|
|
|
"feeds": {},
|
|
|
|
"social_user": social_user,
|
2012-07-30 21:39:21 -07:00
|
|
|
"social_profile": social_profile,
|
2012-08-14 00:26:42 -07:00
|
|
|
"user_social_services": user_social_services,
|
2012-07-06 17:47:06 -07:00
|
|
|
'user_social_profile' : json.encode(user_social_profile and user_social_profile.page()),
|
2012-08-15 18:35:55 -07:00
|
|
|
'user_following_social_profile': user_following_social_profile,
|
2012-06-28 19:47:30 -07:00
|
|
|
}
|
2012-07-06 11:20:13 -07:00
|
|
|
template = 'social/social_page.xhtml'
|
2020-06-12 01:27:07 -04:00
|
|
|
return render(request, template, params)
|
2012-01-31 10:15:11 -08:00
|
|
|
|
|
|
|
story_feed_ids = list(set(s['story_feed_id'] for s in stories))
|
|
|
|
feeds = Feed.objects.filter(pk__in=story_feed_ids)
|
|
|
|
feeds = dict((feed.pk, feed.canonical(include_favicon=False)) for feed in feeds)
|
|
|
|
for story in stories:
|
2012-03-29 19:01:04 -07:00
|
|
|
if story['story_feed_id'] in feeds:
|
|
|
|
# Feed could have been deleted.
|
|
|
|
story['feed'] = feeds[story['story_feed_id']]
|
2013-01-23 14:39:03 -08:00
|
|
|
shared_date = localtime_for_timezone(story['shared_date'], user.profile.timezone)
|
2012-03-29 19:01:04 -07:00
|
|
|
story['shared_date'] = shared_date
|
2012-01-31 10:15:11 -08:00
|
|
|
|
2012-07-01 18:34:34 -07:00
|
|
|
stories, profiles = MSharedStory.stories_with_comments_and_profiles(stories, social_user.pk,
|
|
|
|
check_all=True)
|
|
|
|
|
2020-06-11 15:13:12 -04:00
|
|
|
if user.is_authenticated:
|
2012-07-02 15:40:03 -07:00
|
|
|
for story in stories:
|
2012-08-09 10:34:41 -07:00
|
|
|
if user.pk in story['share_user_ids']:
|
2012-07-02 15:40:03 -07:00
|
|
|
story['shared_by_user'] = True
|
2016-11-10 17:59:47 -08:00
|
|
|
shared_story = MSharedStory.objects.hint([('story_hash', 1)])\
|
|
|
|
.get(user_id=user.pk,
|
2012-07-02 15:40:03 -07:00
|
|
|
story_feed_id=story['story_feed_id'],
|
2016-11-10 17:59:47 -08:00
|
|
|
story_hash=story['story_hash'])
|
2012-07-02 15:40:03 -07:00
|
|
|
story['user_comments'] = shared_story.comments
|
2012-07-01 18:34:34 -07:00
|
|
|
|
|
|
|
stories = MSharedStory.attach_users_to_stories(stories, profiles)
|
2012-10-16 13:40:27 -07:00
|
|
|
|
|
|
|
active_story = None
|
|
|
|
path = request.META['PATH_INFO']
|
|
|
|
if '/story/' in path and format != 'html':
|
2012-11-27 11:59:54 -08:00
|
|
|
story_id = re.sub(r"^/story/.*?/(.*?)/?", "", path)
|
|
|
|
if not story_id or '/story' in story_id:
|
|
|
|
story_id = path.replace('/story/', '')
|
2015-04-07 10:55:29 -07:00
|
|
|
social_services = MSocialServices.get_user(social_user.pk)
|
2012-01-31 10:15:11 -08:00
|
|
|
|
2012-10-16 13:40:27 -07:00
|
|
|
active_story_db = MSharedStory.objects.filter(user_id=social_user.pk,
|
2016-11-09 11:32:51 -08:00
|
|
|
story_hash=story_id)\
|
|
|
|
.hint([('story_hash', 1)])\
|
|
|
|
.limit(1)
|
2012-11-26 17:26:01 -08:00
|
|
|
if active_story_db:
|
2012-10-16 13:40:27 -07:00
|
|
|
active_story_db = active_story_db[0]
|
2013-09-09 12:01:21 -07:00
|
|
|
if user_social_profile.bb_permalink_direct:
|
|
|
|
return HttpResponseRedirect(active_story_db.story_permalink)
|
2012-10-16 13:40:27 -07:00
|
|
|
active_story = Feed.format_story(active_story_db)
|
|
|
|
if active_story_db.image_count:
|
2012-11-26 14:07:46 -08:00
|
|
|
active_story['image_url'] = active_story_db.image_sizes[0]['src']
|
2012-10-16 13:40:27 -07:00
|
|
|
active_story['tags'] = ', '.join(active_story_db.story_tags)
|
2012-11-26 14:17:28 -08:00
|
|
|
active_story['blurblog_permalink'] = active_story_db.blurblog_permalink()
|
2012-11-26 14:23:28 -08:00
|
|
|
active_story['iso8601'] = active_story_db.story_date.isoformat()
|
2012-10-16 13:40:27 -07:00
|
|
|
if active_story['story_feed_id']:
|
|
|
|
feed = Feed.get_by_id(active_story['story_feed_id'])
|
|
|
|
if feed:
|
|
|
|
active_story['feed'] = feed.canonical()
|
|
|
|
|
2012-01-31 10:15:11 -08:00
|
|
|
params = {
|
2012-07-01 20:51:34 -07:00
|
|
|
'social_user' : social_user,
|
|
|
|
'stories' : stories,
|
2012-08-06 17:52:33 -07:00
|
|
|
'user_social_profile' : user_social_profile,
|
|
|
|
'user_social_profile_page' : json.encode(user_social_profile and user_social_profile.page()),
|
2012-08-14 00:26:42 -07:00
|
|
|
'user_social_services' : user_social_services,
|
2013-06-12 13:52:43 -07:00
|
|
|
'user_social_services_page' : json.encode(user_social_services and user_social_services.canonical()),
|
2012-08-15 18:35:55 -07:00
|
|
|
'user_following_social_profile': user_following_social_profile,
|
2012-07-06 19:54:33 -07:00
|
|
|
'social_profile': social_profile,
|
2012-07-01 20:51:34 -07:00
|
|
|
'feeds' : feeds,
|
|
|
|
'user_profile' : hasattr(user, 'profile') and user.profile,
|
2012-07-06 00:34:21 -07:00
|
|
|
'has_next_page' : has_next_page,
|
2012-10-16 13:40:27 -07:00
|
|
|
'holzer_truism' : random.choice(jennyholzer.TRUISMS), #if not has_next_page else None
|
|
|
|
'facebook_app_id': settings.FACEBOOK_APP_ID,
|
|
|
|
'active_story' : active_story,
|
2013-01-23 14:21:16 -08:00
|
|
|
'current_tab' : current_tab,
|
2015-04-07 10:55:29 -07:00
|
|
|
'social_services': social_services,
|
2012-01-31 10:15:11 -08:00
|
|
|
}
|
2012-07-06 00:41:36 -07:00
|
|
|
|
2015-07-29 13:43:18 -07:00
|
|
|
logging.user(request, "~FYLoading ~FMsocial page~FY: ~SB%s%s ~FM%s/%s" % (
|
2015-07-29 13:37:12 -07:00
|
|
|
social_profile.title[:22], ('~SN/p%s' % page) if page > 1 else '',
|
2015-07-29 13:43:18 -07:00
|
|
|
request.META.get('HTTP_USER_AGENT', "")[:40],
|
|
|
|
request.META.get('HTTP_X_FORWARDED_FOR', "")))
|
2012-07-06 00:34:21 -07:00
|
|
|
if format == 'html':
|
|
|
|
template = 'social/social_stories.xhtml'
|
|
|
|
else:
|
|
|
|
template = 'social/social_page.xhtml'
|
|
|
|
|
2020-06-12 01:27:07 -04:00
|
|
|
return render(request, template, params)
|
2012-12-12 13:58:10 -08:00
|
|
|
|
|
|
|
@required_params('story_id', feed_id=int)
|
2012-06-29 21:25:35 -07:00
|
|
|
def story_public_comments(request):
|
2020-06-07 08:04:23 -04:00
|
|
|
format = request.GET.get('format', 'json')
|
|
|
|
relative_user_id = request.GET.get('user_id', None)
|
|
|
|
feed_id = int(request.GET.get('feed_id'))
|
|
|
|
story_id = request.GET.get('story_id')
|
2012-06-29 21:06:33 -07:00
|
|
|
|
|
|
|
if not relative_user_id:
|
|
|
|
relative_user_id = get_user(request).pk
|
2012-02-03 11:41:01 -08:00
|
|
|
|
2012-12-12 13:58:10 -08:00
|
|
|
story, _ = MStory.find_story(story_feed_id=feed_id, story_id=story_id)
|
|
|
|
if not story:
|
|
|
|
return json.json_response(request, {
|
|
|
|
'message': "Story not found.",
|
|
|
|
'code': -1,
|
|
|
|
})
|
|
|
|
|
|
|
|
story = Feed.format_story(story)
|
|
|
|
stories, profiles = MSharedStory.stories_with_comments_and_profiles([story],
|
|
|
|
relative_user_id,
|
2012-10-24 17:01:22 -07:00
|
|
|
check_all=True)
|
2012-12-12 13:58:10 -08:00
|
|
|
|
2012-06-29 21:06:33 -07:00
|
|
|
if format == 'html':
|
2012-07-01 20:51:34 -07:00
|
|
|
stories = MSharedStory.attach_users_to_stories(stories, profiles)
|
2020-06-12 01:27:07 -04:00
|
|
|
return render(request, 'social/story_comments.xhtml', {
|
2012-06-29 21:06:33 -07:00
|
|
|
'story': stories[0],
|
2020-06-12 01:27:07 -04:00
|
|
|
})
|
2012-06-29 21:06:33 -07:00
|
|
|
else:
|
|
|
|
return json.json_response(request, {
|
2012-07-23 13:08:48 -07:00
|
|
|
'comments': stories[0]['public_comments'],
|
2012-06-29 21:06:33 -07:00
|
|
|
'user_profiles': profiles,
|
|
|
|
})
|
2012-02-03 11:41:01 -08:00
|
|
|
|
|
|
|
@ajax_login_required
|
|
|
|
def mark_story_as_shared(request):
|
|
|
|
code = 1
|
|
|
|
feed_id = int(request.POST['feed_id'])
|
|
|
|
story_id = request.POST['story_id']
|
|
|
|
comments = request.POST.get('comments', '')
|
2012-04-30 11:52:19 -07:00
|
|
|
source_user_id = request.POST.get('source_user_id')
|
2012-08-06 17:52:33 -07:00
|
|
|
relative_user_id = request.POST.get('relative_user_id') or request.user.pk
|
2017-04-04 17:13:43 -07:00
|
|
|
post_to_services = request.POST.getlist('post_to_services') or request.POST.getlist('post_to_services[]')
|
2020-06-07 08:04:23 -04:00
|
|
|
format = request.POST.get('format', 'json')
|
2013-11-06 23:39:20 -08:00
|
|
|
now = datetime.datetime.now()
|
|
|
|
nowtz = localtime_for_timezone(now, request.user.profile.timezone)
|
2012-02-03 11:41:01 -08:00
|
|
|
|
2012-07-25 23:57:10 -07:00
|
|
|
MSocialProfile.get_user(request.user.pk)
|
|
|
|
|
2012-07-26 22:12:48 -07:00
|
|
|
story, original_story_found = MStory.find_story(feed_id, story_id)
|
|
|
|
|
2012-02-03 11:41:01 -08:00
|
|
|
if not story:
|
2012-07-26 22:12:48 -07:00
|
|
|
return json.json_response(request, {
|
|
|
|
'code': -1,
|
|
|
|
'message': 'Could not find the original story and no copies could be found.'
|
|
|
|
})
|
2012-02-03 11:41:01 -08:00
|
|
|
|
2016-03-17 11:22:05 -07:00
|
|
|
feed = Feed.get_by_id(feed_id)
|
|
|
|
if feed and feed.is_newsletter:
|
|
|
|
return json.json_response(request, {
|
|
|
|
'code': -1,
|
|
|
|
'message': 'You cannot share newsletters. Somebody could unsubscribe you!'
|
|
|
|
})
|
|
|
|
|
2017-03-21 12:54:20 -07:00
|
|
|
if not request.user.profile.is_premium and MSharedStory.feed_quota(request.user.pk, story.story_hash, feed_id=feed_id):
|
2014-06-16 15:49:49 -07:00
|
|
|
return json.json_response(request, {
|
|
|
|
'code': -1,
|
|
|
|
'message': 'Only premium users can share multiple stories per day from the same site.'
|
|
|
|
})
|
2017-03-21 12:54:20 -07:00
|
|
|
|
2017-03-23 08:53:49 -07:00
|
|
|
quota = 100
|
2017-03-21 12:54:20 -07:00
|
|
|
if not request.user.profile.is_premium:
|
|
|
|
quota = 3
|
|
|
|
if MSharedStory.feed_quota(request.user.pk, story.story_hash, quota=quota):
|
|
|
|
logging.user(request, "~FRNOT ~FCSharing ~FM%s~FC, over quota: ~SB~FB%s" % (story.story_title[:20], comments[:30]))
|
|
|
|
message = 'You can only share up to %s stories per day.' % quota
|
|
|
|
if not request.user.profile.is_premium:
|
|
|
|
message = 'You can only share up to %s stories per day as a free user. Upgrade to premium to share more.' % quota
|
|
|
|
return json.json_response(request, {
|
|
|
|
'code': -1,
|
|
|
|
'message': message
|
|
|
|
})
|
|
|
|
|
2012-04-12 11:18:56 -07:00
|
|
|
shared_story = MSharedStory.objects.filter(user_id=request.user.pk,
|
|
|
|
story_feed_id=feed_id,
|
2016-11-09 11:32:51 -08:00
|
|
|
story_hash=story['story_hash'])\
|
|
|
|
.hint([('story_hash', 1)])\
|
|
|
|
.limit(1).first()
|
2012-02-03 11:41:01 -08:00
|
|
|
if not shared_story:
|
2012-12-11 18:27:51 -08:00
|
|
|
story_db = {
|
|
|
|
"story_guid": story.story_guid,
|
2013-05-02 17:42:04 -07:00
|
|
|
"story_hash": story.story_hash,
|
2013-01-06 16:09:58 -08:00
|
|
|
"story_permalink": story.story_permalink,
|
2012-12-11 18:27:51 -08:00
|
|
|
"story_title": story.story_title,
|
|
|
|
"story_feed_id": story.story_feed_id,
|
2016-11-21 13:15:50 -08:00
|
|
|
"story_content_z": getattr(story, 'story_latest_content_z', None) or story.story_content_z,
|
2012-12-12 09:08:00 -08:00
|
|
|
"story_author_name": story.story_author_name,
|
|
|
|
"story_tags": story.story_tags,
|
|
|
|
"story_date": story.story_date,
|
2012-12-11 18:27:51 -08:00
|
|
|
"user_id": request.user.pk,
|
|
|
|
"comments": comments,
|
|
|
|
"has_comments": bool(comments),
|
|
|
|
}
|
2014-08-04 15:46:24 -07:00
|
|
|
try:
|
|
|
|
shared_story = MSharedStory.objects.create(**story_db)
|
2015-07-07 13:34:06 -07:00
|
|
|
except NotUniqueError:
|
2014-08-04 15:46:24 -07:00
|
|
|
shared_story = MSharedStory.objects.get(story_guid=story_db['story_guid'],
|
|
|
|
user_id=story_db['user_id'])
|
|
|
|
except MSharedStory.DoesNotExist:
|
|
|
|
return json.json_response(request, {
|
|
|
|
'code': -1,
|
|
|
|
'message': 'Story already shared but then not shared. I don\'t really know. Did you submit this twice very quickly?'
|
|
|
|
})
|
2012-06-26 19:19:57 -07:00
|
|
|
if source_user_id:
|
|
|
|
shared_story.set_source_user_id(int(source_user_id))
|
2020-10-05 00:45:20 +07:00
|
|
|
UpdateRecalcForSubscription().delay(subscription_user_id=request.user.pk,
|
2013-03-19 16:14:19 -07:00
|
|
|
shared_story_id=str(shared_story.id))
|
2012-05-01 18:00:54 -07:00
|
|
|
logging.user(request, "~FCSharing ~FM%s: ~SB~FB%s" % (story.story_title[:20], comments[:30]))
|
2012-02-03 11:41:01 -08:00
|
|
|
else:
|
|
|
|
shared_story.comments = comments
|
|
|
|
shared_story.has_comments = bool(comments)
|
|
|
|
shared_story.save()
|
2012-05-01 18:00:54 -07:00
|
|
|
logging.user(request, "~FCUpdating shared story ~FM%s: ~SB~FB%s" % (
|
|
|
|
story.story_title[:20], comments[:30]))
|
2012-02-03 11:41:01 -08:00
|
|
|
|
2012-07-02 10:15:17 -07:00
|
|
|
if original_story_found:
|
|
|
|
story.count_comments()
|
2012-02-03 11:41:01 -08:00
|
|
|
|
|
|
|
story = Feed.format_story(story)
|
2012-07-02 10:15:17 -07:00
|
|
|
check_all = not original_story_found
|
2012-08-06 17:52:33 -07:00
|
|
|
stories, profiles = MSharedStory.stories_with_comments_and_profiles([story], relative_user_id,
|
2012-07-02 10:15:17 -07:00
|
|
|
check_all=check_all)
|
2012-03-22 19:37:19 -07:00
|
|
|
story = stories[0]
|
2014-05-21 12:24:22 -07:00
|
|
|
starred_stories = MStarredStory.objects(user_id=request.user.pk,
|
|
|
|
story_feed_id=story['story_feed_id'],
|
|
|
|
story_hash=story['story_hash'])\
|
|
|
|
.only('story_hash', 'starred_date', 'user_tags').limit(1)
|
|
|
|
if starred_stories:
|
|
|
|
story['user_tags'] = starred_stories[0]['user_tags']
|
|
|
|
story['starred'] = True
|
|
|
|
starred_date = localtime_for_timezone(starred_stories[0]['starred_date'],
|
|
|
|
request.user.profile.timezone)
|
|
|
|
story['starred_date'] = format_story_link_date__long(starred_date, now)
|
2012-07-21 16:38:37 -07:00
|
|
|
story['shared_comments'] = strip_tags(shared_story['comments'] or "")
|
2012-08-06 17:52:33 -07:00
|
|
|
story['shared_by_user'] = True
|
2013-10-04 13:05:31 -07:00
|
|
|
story['shared'] = True
|
2012-11-13 12:28:16 -08:00
|
|
|
shared_date = localtime_for_timezone(shared_story['shared_date'], request.user.profile.timezone)
|
2013-11-06 23:39:20 -08:00
|
|
|
story['short_parsed_date'] = format_story_link_date__short(shared_date, nowtz)
|
|
|
|
story['long_parsed_date'] = format_story_link_date__long(shared_date, nowtz)
|
2012-11-13 12:28:16 -08:00
|
|
|
|
2012-06-27 23:57:57 -07:00
|
|
|
if post_to_services:
|
|
|
|
for service in post_to_services:
|
|
|
|
if service not in shared_story.posted_to_services:
|
2020-10-05 00:45:20 +07:00
|
|
|
PostToService().delay(shared_story_id=str(shared_story.id), service=service)
|
2012-07-01 20:51:34 -07:00
|
|
|
|
2012-07-27 18:58:35 -07:00
|
|
|
if shared_story.source_user_id and shared_story.comments:
|
2020-10-05 00:45:20 +07:00
|
|
|
EmailStoryReshares().apply_async(kwargs=dict(shared_story_id=str(shared_story.id)),
|
2012-08-06 17:52:33 -07:00
|
|
|
countdown=settings.SECONDS_TO_DELAY_CELERY_EMAILS)
|
2012-07-05 19:50:02 -07:00
|
|
|
|
2020-10-05 00:45:20 +07:00
|
|
|
EmailFirstShare().apply_async(kwargs=dict(user_id=request.user.pk))
|
2013-04-22 15:24:38 -07:00
|
|
|
|
2012-07-01 20:51:34 -07:00
|
|
|
if format == 'html':
|
|
|
|
stories = MSharedStory.attach_users_to_stories(stories, profiles)
|
2020-06-12 01:27:07 -04:00
|
|
|
return render(request, 'social/social_story.xhtml', {
|
2012-07-01 20:51:34 -07:00
|
|
|
'story': story,
|
2020-06-12 01:27:07 -04:00
|
|
|
})
|
2012-07-01 20:51:34 -07:00
|
|
|
else:
|
|
|
|
return json.json_response(request, {
|
|
|
|
'code': code,
|
|
|
|
'story': story,
|
|
|
|
'user_profiles': profiles,
|
|
|
|
})
|
2012-03-22 19:37:19 -07:00
|
|
|
|
2012-06-20 20:53:32 -07:00
|
|
|
@ajax_login_required
|
|
|
|
def mark_story_as_unshared(request):
|
|
|
|
feed_id = int(request.POST['feed_id'])
|
|
|
|
story_id = request.POST['story_id']
|
2012-08-06 17:52:33 -07:00
|
|
|
relative_user_id = request.POST.get('relative_user_id') or request.user.pk
|
2020-06-07 08:04:23 -04:00
|
|
|
format = request.POST.get('format', 'json')
|
2012-07-02 10:40:45 -07:00
|
|
|
original_story_found = True
|
2012-06-20 20:53:32 -07:00
|
|
|
|
2013-02-20 16:08:14 -08:00
|
|
|
story, original_story_found = MStory.find_story(story_feed_id=feed_id,
|
2013-06-04 15:39:50 -07:00
|
|
|
story_id=story_id)
|
2013-02-20 16:08:14 -08:00
|
|
|
|
2012-07-02 10:40:45 -07:00
|
|
|
shared_story = MSharedStory.objects(user_id=request.user.pk,
|
|
|
|
story_feed_id=feed_id,
|
2013-05-02 17:42:04 -07:00
|
|
|
story_hash=story['story_hash']).limit(1).first()
|
2012-07-02 10:40:45 -07:00
|
|
|
if not shared_story:
|
2012-07-02 10:15:17 -07:00
|
|
|
return json.json_response(request, {'code': -1, 'message': 'Shared story not found.'})
|
2012-06-20 20:53:32 -07:00
|
|
|
|
2012-09-10 11:55:42 -07:00
|
|
|
shared_story.unshare_story()
|
2012-06-20 20:53:32 -07:00
|
|
|
|
2012-07-02 10:40:45 -07:00
|
|
|
if original_story_found:
|
|
|
|
story.count_comments()
|
|
|
|
else:
|
|
|
|
story = shared_story
|
2012-06-20 20:53:32 -07:00
|
|
|
|
|
|
|
story = Feed.format_story(story)
|
|
|
|
stories, profiles = MSharedStory.stories_with_comments_and_profiles([story],
|
2012-08-06 17:52:33 -07:00
|
|
|
relative_user_id,
|
2012-06-20 20:53:32 -07:00
|
|
|
check_all=True)
|
2012-07-02 10:40:45 -07:00
|
|
|
|
2012-07-01 20:51:34 -07:00
|
|
|
if format == 'html':
|
|
|
|
stories = MSharedStory.attach_users_to_stories(stories, profiles)
|
2020-06-12 01:27:07 -04:00
|
|
|
return render(request, 'social/social_story.xhtml', {
|
2012-07-02 10:40:45 -07:00
|
|
|
'story': stories[0],
|
2020-06-12 01:27:07 -04:00
|
|
|
})
|
2012-07-01 20:51:34 -07:00
|
|
|
else:
|
|
|
|
return json.json_response(request, {
|
|
|
|
'code': 1,
|
|
|
|
'message': "Story unshared.",
|
2012-07-02 10:40:45 -07:00
|
|
|
'story': stories[0],
|
2012-07-01 20:51:34 -07:00
|
|
|
'user_profiles': profiles,
|
|
|
|
})
|
2012-06-20 20:53:32 -07:00
|
|
|
|
2012-03-22 19:37:19 -07:00
|
|
|
@ajax_login_required
|
|
|
|
def save_comment_reply(request):
|
|
|
|
code = 1
|
|
|
|
feed_id = int(request.POST['story_feed_id'])
|
|
|
|
story_id = request.POST['story_id']
|
|
|
|
comment_user_id = request.POST['comment_user_id']
|
|
|
|
reply_comments = request.POST.get('reply_comments')
|
2012-07-27 18:58:35 -07:00
|
|
|
reply_id = request.POST.get('reply_id')
|
2020-06-07 08:04:23 -04:00
|
|
|
format = request.POST.get('format', 'json')
|
2012-07-28 12:37:16 -07:00
|
|
|
original_message = None
|
2012-03-22 19:37:19 -07:00
|
|
|
|
|
|
|
if not reply_comments:
|
2012-10-25 11:59:23 -07:00
|
|
|
return json.json_response(request, {
|
|
|
|
'code': -1,
|
|
|
|
'message': 'Reply comments cannot be empty.',
|
|
|
|
})
|
|
|
|
|
|
|
|
commenter_profile = MSocialProfile.get_user(comment_user_id)
|
|
|
|
if commenter_profile.protected and not commenter_profile.is_followed_by_user(request.user.pk):
|
|
|
|
return json.json_response(request, {
|
|
|
|
'code': -1,
|
|
|
|
'message': 'You must be following %s to reply to them.' % commenter_profile.username,
|
|
|
|
})
|
|
|
|
|
2018-06-29 14:01:48 -04:00
|
|
|
try:
|
|
|
|
shared_story = MSharedStory.objects.get(user_id=comment_user_id,
|
|
|
|
story_feed_id=feed_id,
|
|
|
|
story_guid=story_id)
|
|
|
|
except MSharedStory.DoesNotExist:
|
|
|
|
return json.json_response(request, {
|
|
|
|
'code': -1,
|
|
|
|
'message': 'Shared story cannot be found.',
|
|
|
|
})
|
|
|
|
|
2012-03-22 19:37:19 -07:00
|
|
|
reply = MCommentReply()
|
|
|
|
reply.user_id = request.user.pk
|
|
|
|
reply.publish_date = datetime.datetime.now()
|
|
|
|
reply.comments = reply_comments
|
2012-05-01 18:00:54 -07:00
|
|
|
|
2012-07-27 18:58:35 -07:00
|
|
|
if reply_id:
|
2012-05-01 18:00:54 -07:00
|
|
|
replies = []
|
|
|
|
for story_reply in shared_story.replies:
|
|
|
|
if (story_reply.user_id == reply.user_id and
|
2012-07-27 18:58:35 -07:00
|
|
|
story_reply.reply_id == ObjectId(reply_id)):
|
2012-05-01 18:00:54 -07:00
|
|
|
reply.publish_date = story_reply.publish_date
|
2012-07-27 18:58:35 -07:00
|
|
|
reply.reply_id = story_reply.reply_id
|
|
|
|
original_message = story_reply.comments
|
2012-05-01 18:00:54 -07:00
|
|
|
replies.append(reply)
|
|
|
|
else:
|
|
|
|
replies.append(story_reply)
|
|
|
|
shared_story.replies = replies
|
|
|
|
logging.user(request, "~FCUpdating comment reply in ~FM%s: ~SB~FB%s~FM" % (
|
2012-05-10 08:30:34 -07:00
|
|
|
shared_story.story_title[:20], reply_comments[:30]))
|
2012-05-01 18:00:54 -07:00
|
|
|
else:
|
2012-07-27 18:58:35 -07:00
|
|
|
reply.reply_id = ObjectId()
|
2012-05-01 18:00:54 -07:00
|
|
|
logging.user(request, "~FCReplying to comment in: ~FM%s: ~SB~FB%s~FM" % (
|
2012-05-10 08:30:34 -07:00
|
|
|
shared_story.story_title[:20], reply_comments[:30]))
|
2012-05-01 18:00:54 -07:00
|
|
|
shared_story.replies.append(reply)
|
2012-03-22 19:37:19 -07:00
|
|
|
shared_story.save()
|
2012-04-10 17:28:00 -07:00
|
|
|
|
2012-07-28 19:53:38 -07:00
|
|
|
comment, profiles = shared_story.comment_with_author_and_profiles()
|
2012-02-03 11:41:01 -08:00
|
|
|
|
2012-04-10 17:28:00 -07:00
|
|
|
# Interaction for every other replier and original commenter
|
2012-04-16 11:21:52 -07:00
|
|
|
MActivity.new_comment_reply(user_id=request.user.pk,
|
|
|
|
comment_user_id=comment['user_id'],
|
|
|
|
reply_content=reply_comments,
|
2012-05-01 18:15:58 -07:00
|
|
|
original_message=original_message,
|
2012-07-28 12:37:16 -07:00
|
|
|
story_id=story_id,
|
2012-07-28 16:41:17 -07:00
|
|
|
story_feed_id=feed_id,
|
2012-07-28 12:37:16 -07:00
|
|
|
story_title=shared_story.story_title)
|
2012-04-16 11:21:52 -07:00
|
|
|
if comment['user_id'] != request.user.pk:
|
2012-04-11 17:43:05 -07:00
|
|
|
MInteraction.new_comment_reply(user_id=comment['user_id'],
|
|
|
|
reply_user_id=request.user.pk,
|
|
|
|
reply_content=reply_comments,
|
2012-05-01 18:15:58 -07:00
|
|
|
original_message=original_message,
|
2012-07-28 12:37:16 -07:00
|
|
|
story_id=story_id,
|
2012-07-28 16:41:17 -07:00
|
|
|
story_feed_id=feed_id,
|
2012-07-28 12:37:16 -07:00
|
|
|
story_title=shared_story.story_title)
|
2012-07-28 19:53:38 -07:00
|
|
|
|
2012-07-28 22:36:50 -07:00
|
|
|
reply_user_ids = list(r['user_id'] for r in comment['replies'])
|
2012-04-11 12:14:18 -07:00
|
|
|
for user_id in set(reply_user_ids).difference([comment['user_id']]):
|
2012-04-11 17:43:05 -07:00
|
|
|
if request.user.pk != user_id:
|
|
|
|
MInteraction.new_reply_reply(user_id=user_id,
|
2012-07-28 16:41:17 -07:00
|
|
|
comment_user_id=comment['user_id'],
|
2012-04-11 17:43:05 -07:00
|
|
|
reply_user_id=request.user.pk,
|
|
|
|
reply_content=reply_comments,
|
2012-05-01 18:15:58 -07:00
|
|
|
original_message=original_message,
|
2012-07-28 12:37:16 -07:00
|
|
|
story_id=story_id,
|
2012-07-28 16:41:17 -07:00
|
|
|
story_feed_id=feed_id,
|
2012-07-28 12:37:16 -07:00
|
|
|
story_title=shared_story.story_title)
|
2012-07-27 18:58:35 -07:00
|
|
|
|
2020-10-05 00:45:20 +07:00
|
|
|
EmailCommentReplies().apply_async(kwargs=dict(shared_story_id=str(shared_story.id),
|
2020-06-29 20:17:00 -04:00
|
|
|
reply_id=str(reply.reply_id)),
|
2012-08-06 17:52:33 -07:00
|
|
|
countdown=settings.SECONDS_TO_DELAY_CELERY_EMAILS)
|
2012-04-10 17:28:00 -07:00
|
|
|
|
2012-07-03 17:00:09 -07:00
|
|
|
if format == 'html':
|
|
|
|
comment = MSharedStory.attach_users_to_comment(comment, profiles)
|
2020-06-12 01:27:07 -04:00
|
|
|
return render(request, 'social/story_comment.xhtml', {
|
2012-07-03 17:00:09 -07:00
|
|
|
'comment': comment,
|
2020-06-12 01:27:07 -04:00
|
|
|
})
|
2012-07-03 17:00:09 -07:00
|
|
|
else:
|
|
|
|
return json.json_response(request, {
|
|
|
|
'code': code,
|
|
|
|
'comment': comment,
|
2012-07-30 13:53:31 -07:00
|
|
|
'reply_id': reply.reply_id,
|
2012-07-03 17:00:09 -07:00
|
|
|
'user_profiles': profiles
|
|
|
|
})
|
2012-07-05 18:29:38 -07:00
|
|
|
|
2012-07-28 19:53:38 -07:00
|
|
|
@ajax_login_required
|
|
|
|
def remove_comment_reply(request):
|
|
|
|
code = 1
|
|
|
|
feed_id = int(request.POST['story_feed_id'])
|
|
|
|
story_id = request.POST['story_id']
|
|
|
|
comment_user_id = request.POST['comment_user_id']
|
|
|
|
reply_id = request.POST.get('reply_id')
|
2020-06-07 08:04:23 -04:00
|
|
|
format = request.POST.get('format', 'json')
|
2012-07-28 19:53:38 -07:00
|
|
|
original_message = None
|
|
|
|
|
|
|
|
shared_story = MSharedStory.objects.get(user_id=comment_user_id,
|
|
|
|
story_feed_id=feed_id,
|
|
|
|
story_guid=story_id)
|
|
|
|
replies = []
|
|
|
|
for story_reply in shared_story.replies:
|
|
|
|
if ((story_reply.user_id == request.user.pk or request.user.is_staff) and
|
|
|
|
story_reply.reply_id == ObjectId(reply_id)):
|
|
|
|
original_message = story_reply.comments
|
|
|
|
# Skip reply
|
|
|
|
else:
|
|
|
|
replies.append(story_reply)
|
|
|
|
shared_story.replies = replies
|
|
|
|
shared_story.save()
|
|
|
|
|
|
|
|
logging.user(request, "~FCRemoving comment reply in ~FM%s: ~SB~FB%s~FM" % (
|
2012-07-28 22:36:50 -07:00
|
|
|
shared_story.story_title[:20], original_message and original_message[:30]))
|
2012-07-28 19:53:38 -07:00
|
|
|
|
|
|
|
comment, profiles = shared_story.comment_with_author_and_profiles()
|
|
|
|
|
2012-07-28 22:36:50 -07:00
|
|
|
# Interaction for every other replier and original commenter
|
|
|
|
MActivity.remove_comment_reply(user_id=request.user.pk,
|
|
|
|
comment_user_id=comment['user_id'],
|
|
|
|
reply_content=original_message,
|
|
|
|
story_id=story_id,
|
|
|
|
story_feed_id=feed_id)
|
|
|
|
MInteraction.remove_comment_reply(user_id=comment['user_id'],
|
|
|
|
reply_user_id=request.user.pk,
|
|
|
|
reply_content=original_message,
|
|
|
|
story_id=story_id,
|
|
|
|
story_feed_id=feed_id)
|
|
|
|
|
|
|
|
reply_user_ids = [reply['user_id'] for reply in comment['replies']]
|
|
|
|
for user_id in set(reply_user_ids).difference([comment['user_id']]):
|
|
|
|
if request.user.pk != user_id:
|
|
|
|
MInteraction.remove_reply_reply(user_id=user_id,
|
|
|
|
comment_user_id=comment['user_id'],
|
|
|
|
reply_user_id=request.user.pk,
|
|
|
|
reply_content=original_message,
|
|
|
|
story_id=story_id,
|
|
|
|
story_feed_id=feed_id)
|
2012-07-28 19:53:38 -07:00
|
|
|
|
|
|
|
if format == 'html':
|
|
|
|
comment = MSharedStory.attach_users_to_comment(comment, profiles)
|
2020-06-12 01:27:07 -04:00
|
|
|
return render(request, 'social/story_comment.xhtml', {
|
2012-07-28 19:53:38 -07:00
|
|
|
'comment': comment,
|
2020-06-12 01:27:07 -04:00
|
|
|
})
|
2012-07-28 19:53:38 -07:00
|
|
|
else:
|
|
|
|
return json.json_response(request, {
|
|
|
|
'code': code,
|
|
|
|
'comment': comment,
|
|
|
|
'user_profiles': profiles
|
|
|
|
})
|
|
|
|
|
2012-07-05 18:29:38 -07:00
|
|
|
@render_to('social/mute_story.xhtml')
|
|
|
|
def mute_story(request, secret_token, shared_story_id):
|
|
|
|
user_profile = Profile.objects.get(secret_token=secret_token)
|
|
|
|
shared_story = MSharedStory.objects.get(id=shared_story_id)
|
|
|
|
shared_story.mute_for_user(user_profile.user_id)
|
|
|
|
|
|
|
|
return {}
|
2012-02-03 11:41:01 -08:00
|
|
|
|
|
|
|
def shared_stories_public(request, username):
|
|
|
|
try:
|
|
|
|
user = User.objects.get(username=username)
|
|
|
|
except User.DoesNotExist:
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
shared_stories = MSharedStory.objects.filter(user_id=user.pk)
|
|
|
|
|
|
|
|
return HttpResponse("There are %s stories shared by %s." % (shared_stories.count(), username))
|
2011-12-20 11:49:49 -08:00
|
|
|
|
2011-12-25 20:50:59 -08:00
|
|
|
@json.json_view
|
|
|
|
def profile(request):
|
2012-05-14 16:43:27 -07:00
|
|
|
user = get_user(request.user)
|
2012-11-30 14:28:55 -08:00
|
|
|
user_id = int(request.GET.get('user_id', user.pk))
|
2017-04-04 17:13:43 -07:00
|
|
|
categories = request.GET.getlist('category') or request.GET.getlist('category[]')
|
2020-06-07 08:04:23 -04:00
|
|
|
include_activities_html = request.GET.get('include_activities_html', None)
|
2012-07-09 12:41:25 -07:00
|
|
|
|
2012-07-25 23:57:10 -07:00
|
|
|
user_profile = MSocialProfile.get_user(user_id)
|
2012-06-27 16:46:30 -07:00
|
|
|
user_profile.count_follows()
|
2012-11-29 10:21:33 -08:00
|
|
|
|
2012-10-24 16:09:47 -07:00
|
|
|
activities = []
|
|
|
|
if not user_profile.private or user_profile.is_followed_by_user(user.pk):
|
|
|
|
activities, _ = MActivity.user(user_id, page=1, public=True, categories=categories)
|
|
|
|
|
2013-06-12 13:52:43 -07:00
|
|
|
user_profile = user_profile.canonical(include_follows=True, common_follows_with_user=user.pk)
|
2012-04-21 16:14:53 -07:00
|
|
|
profile_ids = set(user_profile['followers_youknow'] + user_profile['followers_everybody'] +
|
|
|
|
user_profile['following_youknow'] + user_profile['following_everybody'])
|
2012-03-12 18:11:13 -07:00
|
|
|
profiles = MSocialProfile.profiles(profile_ids)
|
2012-10-24 16:09:47 -07:00
|
|
|
|
2012-04-21 16:14:53 -07:00
|
|
|
logging.user(request, "~BB~FRLoading social profile: %s" % user_profile['username'])
|
|
|
|
|
2012-02-22 09:11:35 -08:00
|
|
|
payload = {
|
2012-04-21 16:14:53 -07:00
|
|
|
'user_profile': user_profile,
|
|
|
|
'followers_youknow': user_profile['followers_youknow'],
|
|
|
|
'followers_everybody': user_profile['followers_everybody'],
|
|
|
|
'following_youknow': user_profile['following_youknow'],
|
|
|
|
'following_everybody': user_profile['following_everybody'],
|
2012-10-24 16:09:47 -07:00
|
|
|
'requested_follow': user_profile['requested_follow'],
|
2013-06-12 13:52:43 -07:00
|
|
|
'profiles': dict([(p.user_id, p.canonical(compact=True)) for p in profiles]),
|
2012-04-19 19:09:31 -07:00
|
|
|
'activities': activities,
|
2012-02-22 09:11:35 -08:00
|
|
|
}
|
2012-11-30 14:28:55 -08:00
|
|
|
|
2012-07-09 12:41:25 -07:00
|
|
|
if include_activities_html:
|
|
|
|
payload['activities_html'] = render_to_string('reader/activities_module.xhtml', {
|
|
|
|
'activities': activities,
|
|
|
|
'username': user_profile['username'],
|
|
|
|
'public': True,
|
|
|
|
})
|
|
|
|
|
2012-02-22 09:11:35 -08:00
|
|
|
return payload
|
2012-04-04 16:09:01 -07:00
|
|
|
|
|
|
|
@ajax_login_required
|
|
|
|
@json.json_view
|
|
|
|
def load_user_profile(request):
|
2012-07-25 23:57:10 -07:00
|
|
|
social_profile = MSocialProfile.get_user(request.user.pk)
|
2015-07-20 16:44:50 -07:00
|
|
|
try:
|
|
|
|
social_services = MSocialServices.objects.get(user_id=request.user.pk)
|
|
|
|
except MSocialServices.DoesNotExist:
|
|
|
|
social_services = MSocialServices.objects.create(user_id=request.user.pk)
|
2012-04-10 17:28:00 -07:00
|
|
|
|
2012-07-10 00:17:45 -07:00
|
|
|
logging.user(request, "~BB~FRLoading social profile and blurblog settings")
|
|
|
|
|
2012-04-04 16:09:01 -07:00
|
|
|
return {
|
|
|
|
'services': social_services,
|
2013-06-12 13:52:43 -07:00
|
|
|
'user_profile': social_profile.canonical(include_follows=True, include_settings=True),
|
2012-04-04 16:09:01 -07:00
|
|
|
}
|
2011-12-25 20:50:59 -08:00
|
|
|
|
2012-04-04 16:09:01 -07:00
|
|
|
@ajax_login_required
|
|
|
|
@json.json_view
|
|
|
|
def save_user_profile(request):
|
2011-12-25 20:50:59 -08:00
|
|
|
data = request.POST
|
2012-07-31 23:42:43 -07:00
|
|
|
website = data['website']
|
|
|
|
|
|
|
|
if website and not website.startswith('http'):
|
|
|
|
website = 'http://' + website
|
|
|
|
|
2012-07-25 23:57:10 -07:00
|
|
|
profile = MSocialProfile.get_user(request.user.pk)
|
2011-12-25 20:50:59 -08:00
|
|
|
profile.location = data['location']
|
|
|
|
profile.bio = data['bio']
|
2012-07-31 23:42:43 -07:00
|
|
|
profile.website = website
|
2012-10-24 16:09:47 -07:00
|
|
|
profile.protected = is_true(data.get('protected', False))
|
|
|
|
profile.private = is_true(data.get('private', False))
|
2011-12-25 20:50:59 -08:00
|
|
|
profile.save()
|
|
|
|
|
2018-08-10 15:21:02 -04:00
|
|
|
social_services = MSocialServices.get_user(user_id=request.user.pk)
|
2012-04-04 20:54:54 -07:00
|
|
|
profile = social_services.set_photo(data['photo_service'])
|
2011-12-25 20:50:59 -08:00
|
|
|
|
2012-03-07 17:34:22 -08:00
|
|
|
logging.user(request, "~BB~FRSaving social profile")
|
|
|
|
|
2013-06-12 13:52:43 -07:00
|
|
|
return dict(code=1, user_profile=profile.canonical(include_follows=True))
|
2012-01-04 09:42:35 -08:00
|
|
|
|
2013-01-08 14:11:59 -08:00
|
|
|
|
|
|
|
@ajax_login_required
|
|
|
|
@json.json_view
|
|
|
|
def upload_avatar(request):
|
|
|
|
photo = request.FILES['photo']
|
|
|
|
profile = MSocialProfile.get_user(request.user.pk)
|
|
|
|
social_services = MSocialServices.objects.get(user_id=request.user.pk)
|
2013-01-08 14:30:41 -08:00
|
|
|
|
|
|
|
logging.user(request, "~FC~BM~SBUploading photo...")
|
|
|
|
|
2013-01-08 14:11:59 -08:00
|
|
|
image_url = social_services.save_uploaded_photo(photo)
|
|
|
|
if image_url:
|
|
|
|
profile = social_services.set_photo('upload')
|
|
|
|
|
|
|
|
return {
|
|
|
|
"code": 1 if image_url else -1,
|
|
|
|
"uploaded": image_url,
|
|
|
|
"services": social_services,
|
2013-06-12 13:52:43 -07:00
|
|
|
"user_profile": profile.canonical(include_follows=True),
|
2013-01-08 14:11:59 -08:00
|
|
|
}
|
|
|
|
|
2012-07-10 00:17:45 -07:00
|
|
|
@ajax_login_required
|
|
|
|
@json.json_view
|
|
|
|
def save_blurblog_settings(request):
|
|
|
|
data = request.POST
|
|
|
|
|
2012-07-25 23:57:10 -07:00
|
|
|
profile = MSocialProfile.get_user(request.user.pk)
|
2013-08-13 14:01:46 -07:00
|
|
|
profile.custom_css = strip_tags(data.get('custom_css', None))
|
|
|
|
profile.custom_bgcolor = strip_tags(data.get('custom_bgcolor', None))
|
|
|
|
profile.blurblog_title = strip_tags(data.get('blurblog_title', None))
|
2013-09-09 12:01:21 -07:00
|
|
|
profile.bb_permalink_direct = is_true(data.get('bb_permalink_direct', False))
|
2012-07-10 00:17:45 -07:00
|
|
|
profile.save()
|
|
|
|
|
|
|
|
logging.user(request, "~BB~FRSaving blurblog settings")
|
|
|
|
|
2013-06-12 13:52:43 -07:00
|
|
|
return dict(code=1, user_profile=profile.canonical(include_follows=True, include_settings=True))
|
2012-07-10 00:17:45 -07:00
|
|
|
|
2012-10-24 18:52:24 -07:00
|
|
|
@json.json_view
|
|
|
|
def load_follow_requests(request):
|
|
|
|
user = get_user(request.user)
|
|
|
|
follow_request_users = MFollowRequest.objects.filter(followee_user_id=user.pk)
|
|
|
|
follow_request_user_ids = [f.follower_user_id for f in follow_request_users]
|
|
|
|
request_profiles = MSocialProfile.profiles(follow_request_user_ids)
|
2013-06-12 13:52:43 -07:00
|
|
|
request_profiles = [p.canonical(include_following_user=user.pk) for p in request_profiles]
|
2012-10-24 18:52:24 -07:00
|
|
|
|
|
|
|
if len(request_profiles):
|
|
|
|
logging.user(request, "~BB~FRLoading Follow Requests (%s requests)" % (
|
|
|
|
len(request_profiles),
|
|
|
|
))
|
|
|
|
|
|
|
|
return {
|
|
|
|
'request_profiles': request_profiles,
|
|
|
|
}
|
|
|
|
|
2016-05-27 08:58:27 -07:00
|
|
|
@ratelimit(minutes=1, requests=100)
|
2012-04-04 16:09:01 -07:00
|
|
|
@json.json_view
|
|
|
|
def load_user_friends(request):
|
2012-05-14 16:43:27 -07:00
|
|
|
user = get_user(request.user)
|
2012-08-31 13:51:24 -07:00
|
|
|
social_profile = MSocialProfile.get_user(user_id=user.pk)
|
|
|
|
social_services = MSocialServices.get_user(user_id=user.pk)
|
2012-04-04 16:09:01 -07:00
|
|
|
following_profiles = MSocialProfile.profiles(social_profile.following_user_ids)
|
2012-07-13 15:32:27 -07:00
|
|
|
follower_profiles = MSocialProfile.profiles(social_profile.follower_user_ids)
|
|
|
|
recommended_users = social_profile.recommended_users()
|
2013-06-12 13:52:43 -07:00
|
|
|
following_profiles = [p.canonical(include_following_user=user.pk) for p in following_profiles]
|
|
|
|
follower_profiles = [p.canonical(include_following_user=user.pk) for p in follower_profiles]
|
2012-07-13 15:32:27 -07:00
|
|
|
|
|
|
|
logging.user(request, "~BB~FRLoading Friends (%s following, %s followers)" % (
|
|
|
|
social_profile.following_count,
|
|
|
|
social_profile.follower_count,
|
|
|
|
))
|
2012-04-04 16:09:01 -07:00
|
|
|
|
|
|
|
return {
|
|
|
|
'services': social_services,
|
|
|
|
'autofollow': social_services.autofollow,
|
2013-06-12 13:52:43 -07:00
|
|
|
'user_profile': social_profile.canonical(include_follows=True),
|
2012-04-04 16:09:01 -07:00
|
|
|
'following_profiles': following_profiles,
|
|
|
|
'follower_profiles': follower_profiles,
|
2012-05-15 16:35:09 -07:00
|
|
|
'recommended_users': recommended_users,
|
2012-04-04 16:09:01 -07:00
|
|
|
}
|
|
|
|
|
2012-01-04 09:42:35 -08:00
|
|
|
@ajax_login_required
|
|
|
|
@json.json_view
|
|
|
|
def follow(request):
|
2012-07-25 23:57:10 -07:00
|
|
|
profile = MSocialProfile.get_user(request.user.pk)
|
2012-04-04 20:54:54 -07:00
|
|
|
user_id = request.POST['user_id']
|
2012-03-19 17:16:59 -07:00
|
|
|
try:
|
2012-04-04 20:54:54 -07:00
|
|
|
follow_user_id = int(user_id)
|
2012-03-19 17:16:59 -07:00
|
|
|
except ValueError:
|
2012-04-04 20:54:54 -07:00
|
|
|
try:
|
|
|
|
follow_user_id = int(user_id.replace('social:', ''))
|
2012-07-25 23:57:10 -07:00
|
|
|
follow_profile = MSocialProfile.get_user(follow_user_id)
|
2012-04-04 20:54:54 -07:00
|
|
|
except (ValueError, MSocialProfile.DoesNotExist):
|
|
|
|
follow_username = user_id.replace('social:', '')
|
|
|
|
try:
|
|
|
|
follow_profile = MSocialProfile.objects.get(username=follow_username)
|
|
|
|
except MSocialProfile.DoesNotExist:
|
|
|
|
raise Http404
|
|
|
|
follow_user_id = follow_profile.user_id
|
2012-03-19 17:16:59 -07:00
|
|
|
|
2012-01-04 09:42:35 -08:00
|
|
|
profile.follow_user(follow_user_id)
|
2012-07-25 23:57:10 -07:00
|
|
|
follow_profile = MSocialProfile.get_user(follow_user_id)
|
2012-01-04 09:42:35 -08:00
|
|
|
|
2012-02-10 12:48:14 -08:00
|
|
|
social_params = {
|
|
|
|
'user_id': request.user.pk,
|
|
|
|
'subscription_user_id': follow_user_id,
|
|
|
|
'include_favicon': True,
|
|
|
|
'update_counts': True,
|
|
|
|
}
|
2012-08-01 18:52:54 -07:00
|
|
|
follow_subscription = MSocialSubscription.feeds(calculate_all_scores=True, **social_params)
|
2012-02-10 12:48:14 -08:00
|
|
|
|
2012-10-24 16:09:47 -07:00
|
|
|
if follow_profile.protected:
|
2012-10-24 18:52:24 -07:00
|
|
|
logging.user(request, "~BB~FR~SBRequested~SN follow from: ~SB%s" % follow_profile.username)
|
2012-10-24 16:09:47 -07:00
|
|
|
else:
|
2012-10-24 18:52:24 -07:00
|
|
|
logging.user(request, "~BB~FRFollowing: ~SB%s" % follow_profile.username)
|
2012-03-07 17:34:22 -08:00
|
|
|
|
2012-02-10 12:48:14 -08:00
|
|
|
return {
|
2013-06-12 13:52:43 -07:00
|
|
|
"user_profile": profile.canonical(include_follows=True),
|
|
|
|
"follow_profile": follow_profile.canonical(common_follows_with_user=request.user.pk),
|
2012-02-10 12:48:14 -08:00
|
|
|
"follow_subscription": follow_subscription,
|
|
|
|
}
|
2012-01-04 09:42:35 -08:00
|
|
|
|
|
|
|
@ajax_login_required
|
|
|
|
@json.json_view
|
|
|
|
def unfollow(request):
|
2012-07-25 23:57:10 -07:00
|
|
|
profile = MSocialProfile.get_user(request.user.pk)
|
2012-04-04 20:54:54 -07:00
|
|
|
user_id = request.POST['user_id']
|
2012-03-19 17:16:59 -07:00
|
|
|
try:
|
2012-04-04 20:54:54 -07:00
|
|
|
unfollow_user_id = int(user_id)
|
2012-03-19 17:16:59 -07:00
|
|
|
except ValueError:
|
2012-04-04 20:54:54 -07:00
|
|
|
try:
|
|
|
|
unfollow_user_id = int(user_id.replace('social:', ''))
|
2012-07-25 23:57:10 -07:00
|
|
|
unfollow_profile = MSocialProfile.get_user(unfollow_user_id)
|
2012-04-04 20:54:54 -07:00
|
|
|
except (ValueError, MSocialProfile.DoesNotExist):
|
|
|
|
unfollow_username = user_id.replace('social:', '')
|
|
|
|
try:
|
|
|
|
unfollow_profile = MSocialProfile.objects.get(username=unfollow_username)
|
|
|
|
except MSocialProfile.DoesNotExist:
|
|
|
|
raise Http404
|
|
|
|
unfollow_user_id = unfollow_profile.user_id
|
2012-03-19 17:16:59 -07:00
|
|
|
|
2012-01-04 09:42:35 -08:00
|
|
|
profile.unfollow_user(unfollow_user_id)
|
2012-07-25 23:57:10 -07:00
|
|
|
unfollow_profile = MSocialProfile.get_user(unfollow_user_id)
|
2012-01-05 20:54:24 -08:00
|
|
|
|
2012-10-24 18:52:24 -07:00
|
|
|
logging.user(request, "~BB~FRUnfollowing: ~SB%s" % unfollow_profile.username)
|
2012-03-07 17:34:22 -08:00
|
|
|
|
2012-04-21 16:14:53 -07:00
|
|
|
return {
|
2013-06-12 13:52:43 -07:00
|
|
|
'user_profile': profile.canonical(include_follows=True),
|
|
|
|
'unfollow_profile': unfollow_profile.canonical(common_follows_with_user=request.user.pk),
|
2012-04-21 16:14:53 -07:00
|
|
|
}
|
2012-03-13 16:58:50 -07:00
|
|
|
|
2012-10-24 18:52:24 -07:00
|
|
|
|
|
|
|
@ajax_login_required
|
|
|
|
@json.json_view
|
|
|
|
def approve_follower(request):
|
|
|
|
profile = MSocialProfile.get_user(request.user.pk)
|
|
|
|
user_id = int(request.POST['user_id'])
|
|
|
|
follower_profile = MSocialProfile.get_user(user_id)
|
|
|
|
code = -1
|
|
|
|
|
|
|
|
logging.user(request, "~BB~FRApproving follow: ~SB%s" % follower_profile.username)
|
|
|
|
|
|
|
|
if user_id in profile.requested_follow_user_ids:
|
|
|
|
follower_profile.follow_user(request.user.pk, force=True)
|
|
|
|
code = 1
|
|
|
|
|
|
|
|
return {'code': code}
|
|
|
|
|
|
|
|
@ajax_login_required
|
|
|
|
@json.json_view
|
|
|
|
def ignore_follower(request):
|
|
|
|
profile = MSocialProfile.get_user(request.user.pk)
|
|
|
|
user_id = int(request.POST['user_id'])
|
|
|
|
follower_profile = MSocialProfile.get_user(user_id)
|
|
|
|
code = -1
|
|
|
|
|
|
|
|
logging.user(request, "~BB~FR~SK~SBNOT~SN approving follow: ~SB%s" % follower_profile.username)
|
|
|
|
|
|
|
|
if user_id in profile.requested_follow_user_ids:
|
|
|
|
follower_profile.unfollow_user(request.user.pk)
|
|
|
|
code = 1
|
|
|
|
|
|
|
|
return {'code': code}
|
|
|
|
|
|
|
|
|
2012-12-12 14:24:51 -08:00
|
|
|
@required_params('query')
|
2012-03-13 16:58:50 -07:00
|
|
|
@json.json_view
|
|
|
|
def find_friends(request):
|
2012-12-12 14:24:51 -08:00
|
|
|
query = request.GET['query']
|
2012-07-30 21:39:21 -07:00
|
|
|
limit = int(request.GET.get('limit', 3))
|
2014-03-14 11:04:15 -07:00
|
|
|
profiles = []
|
|
|
|
|
|
|
|
if '@' in query:
|
2014-03-14 11:51:04 -07:00
|
|
|
results = re.search(r'[\w\.-]+@[\w\.-]+', query)
|
|
|
|
if results:
|
|
|
|
email = results.group(0)
|
|
|
|
profiles = MSocialProfile.objects.filter(email__iexact=email)[:limit]
|
2014-09-05 10:46:46 -07:00
|
|
|
if query.isdigit() and request.user.is_staff:
|
|
|
|
profiles = MSocialProfile.objects.filter(user_id=int(query))[:limit]
|
2014-03-14 11:04:15 -07:00
|
|
|
if not profiles:
|
|
|
|
profiles = MSocialProfile.objects.filter(username__iexact=query)[:limit]
|
2013-06-28 18:30:20 -07:00
|
|
|
if not profiles:
|
|
|
|
profiles = MSocialProfile.objects.filter(username__icontains=query)[:limit]
|
2014-03-14 11:44:46 -07:00
|
|
|
if not profiles and request.user.is_staff:
|
2012-07-30 21:39:21 -07:00
|
|
|
profiles = MSocialProfile.objects.filter(email__icontains=query)[:limit]
|
2012-03-13 16:58:50 -07:00
|
|
|
if not profiles:
|
2012-07-30 21:39:21 -07:00
|
|
|
profiles = MSocialProfile.objects.filter(blurblog_title__icontains=query)[:limit]
|
2012-09-13 14:13:15 -07:00
|
|
|
if not profiles:
|
|
|
|
profiles = MSocialProfile.objects.filter(location__icontains=query)[:limit]
|
2012-03-13 16:58:50 -07:00
|
|
|
|
2013-06-12 13:52:43 -07:00
|
|
|
profiles = [p.canonical(include_following_user=request.user.pk) for p in profiles]
|
2012-07-31 23:42:43 -07:00
|
|
|
profiles = sorted(profiles, key=lambda p: -1 * p['shared_stories_count'])
|
|
|
|
|
2012-03-13 16:58:50 -07:00
|
|
|
return dict(profiles=profiles)
|
2012-07-15 17:59:19 -07:00
|
|
|
|
|
|
|
@ajax_login_required
|
|
|
|
def like_comment(request):
|
|
|
|
code = 1
|
|
|
|
feed_id = int(request.POST['story_feed_id'])
|
|
|
|
story_id = request.POST['story_id']
|
2013-01-11 15:51:21 -08:00
|
|
|
comment_user_id = int(request.POST['comment_user_id'])
|
2020-06-07 08:04:23 -04:00
|
|
|
format = request.POST.get('format', 'json')
|
2012-07-15 17:59:19 -07:00
|
|
|
|
2012-07-15 19:29:05 -07:00
|
|
|
if comment_user_id == request.user.pk:
|
|
|
|
return json.json_response(request, {'code': -1, 'message': 'You cannot favorite your own shared story comment.'})
|
2015-07-07 13:28:08 -07:00
|
|
|
|
|
|
|
try:
|
|
|
|
shared_story = MSharedStory.objects.get(user_id=comment_user_id,
|
|
|
|
story_feed_id=feed_id,
|
|
|
|
story_guid=story_id)
|
|
|
|
except MSharedStory.DoesNotExist:
|
|
|
|
return json.json_response(request, {'code': -1, 'message': 'The shared comment cannot be found.'})
|
2012-07-15 19:29:05 -07:00
|
|
|
|
2012-07-15 17:59:19 -07:00
|
|
|
shared_story.add_liking_user(request.user.pk)
|
|
|
|
comment, profiles = shared_story.comment_with_author_and_profiles()
|
|
|
|
|
|
|
|
comment_user = User.objects.get(pk=shared_story.user_id)
|
|
|
|
logging.user(request, "~BB~FMLiking comment by ~SB%s~SN: %s" % (
|
|
|
|
comment_user.username,
|
|
|
|
shared_story.comments[:30],
|
|
|
|
))
|
|
|
|
|
2012-07-28 12:37:16 -07:00
|
|
|
MActivity.new_comment_like(liking_user_id=request.user.pk,
|
2012-07-15 19:29:05 -07:00
|
|
|
comment_user_id=comment['user_id'],
|
|
|
|
story_id=story_id,
|
2015-06-04 15:38:21 -07:00
|
|
|
story_feed_id=feed_id,
|
2012-07-15 19:29:05 -07:00
|
|
|
story_title=shared_story.story_title,
|
|
|
|
comments=shared_story.comments)
|
2012-07-28 12:37:16 -07:00
|
|
|
MInteraction.new_comment_like(liking_user_id=request.user.pk,
|
|
|
|
comment_user_id=comment['user_id'],
|
2012-07-15 19:29:05 -07:00
|
|
|
story_id=story_id,
|
2015-06-04 15:38:21 -07:00
|
|
|
story_feed_id=feed_id,
|
2012-07-15 19:29:05 -07:00
|
|
|
story_title=shared_story.story_title,
|
|
|
|
comments=shared_story.comments)
|
|
|
|
|
2012-07-15 17:59:19 -07:00
|
|
|
if format == 'html':
|
|
|
|
comment = MSharedStory.attach_users_to_comment(comment, profiles)
|
2020-06-12 01:27:07 -04:00
|
|
|
return render(request, 'social/story_comment.xhtml', {
|
2012-07-15 17:59:19 -07:00
|
|
|
'comment': comment,
|
2020-06-12 01:27:07 -04:00
|
|
|
})
|
2012-07-15 17:59:19 -07:00
|
|
|
else:
|
|
|
|
return json.json_response(request, {
|
|
|
|
'code': code,
|
|
|
|
'comment': comment,
|
|
|
|
'user_profiles': profiles,
|
|
|
|
})
|
|
|
|
|
|
|
|
@ajax_login_required
|
|
|
|
def remove_like_comment(request):
|
|
|
|
code = 1
|
|
|
|
feed_id = int(request.POST['story_feed_id'])
|
|
|
|
story_id = request.POST['story_id']
|
|
|
|
comment_user_id = request.POST['comment_user_id']
|
2020-06-07 08:04:23 -04:00
|
|
|
format = request.POST.get('format', 'json')
|
2012-07-15 17:59:19 -07:00
|
|
|
|
|
|
|
shared_story = MSharedStory.objects.get(user_id=comment_user_id,
|
|
|
|
story_feed_id=feed_id,
|
|
|
|
story_guid=story_id)
|
|
|
|
shared_story.remove_liking_user(request.user.pk)
|
|
|
|
comment, profiles = shared_story.comment_with_author_and_profiles()
|
|
|
|
comment_user = User.objects.get(pk=shared_story.user_id)
|
|
|
|
logging.user(request, "~BB~FMRemoving like on comment by ~SB%s~SN: %s" % (
|
|
|
|
comment_user.username,
|
|
|
|
shared_story.comments[:30],
|
|
|
|
))
|
2011-12-25 20:50:59 -08:00
|
|
|
|
2012-07-15 17:59:19 -07:00
|
|
|
if format == 'html':
|
|
|
|
comment = MSharedStory.attach_users_to_comment(comment, profiles)
|
2020-06-12 01:27:07 -04:00
|
|
|
return render(request, 'social/story_comment.xhtml', {
|
2012-07-15 17:59:19 -07:00
|
|
|
'comment': comment,
|
2020-06-12 01:27:07 -04:00
|
|
|
})
|
2012-07-15 17:59:19 -07:00
|
|
|
else:
|
|
|
|
return json.json_response(request, {
|
|
|
|
'code': code,
|
|
|
|
'comment': comment,
|
|
|
|
'user_profiles': profiles,
|
|
|
|
})
|
2020-06-17 05:34:34 -04:00
|
|
|
def get_subdomain(request):
|
|
|
|
host = request.META.get('HTTP_HOST')
|
|
|
|
if host.count(".") == 2:
|
|
|
|
return host.split(".")[0]
|
|
|
|
else:
|
|
|
|
return None
|
|
|
|
|
2014-01-02 12:32:16 -08:00
|
|
|
def shared_stories_rss_feed_noid(request):
|
|
|
|
index = HttpResponseRedirect('http://%s%s' % (
|
|
|
|
Site.objects.get_current().domain,
|
|
|
|
reverse('index')))
|
2020-06-17 05:34:34 -04:00
|
|
|
if get_subdomain(request):
|
|
|
|
username = get_subdomain(request)
|
2014-01-02 12:32:16 -08:00
|
|
|
try:
|
|
|
|
if '.' in username:
|
|
|
|
username = username.split('.')[0]
|
|
|
|
user = User.objects.get(username__iexact=username)
|
|
|
|
except User.DoesNotExist:
|
|
|
|
return index
|
|
|
|
return shared_stories_rss_feed(request, user_id=user.pk, username=request.subdomain)
|
|
|
|
|
|
|
|
return index
|
|
|
|
|
2020-07-14 18:39:42 -04:00
|
|
|
@ratelimit(minutes=1, requests=5)
|
2012-02-02 17:43:17 -08:00
|
|
|
def shared_stories_rss_feed(request, user_id, username):
|
|
|
|
try:
|
|
|
|
user = User.objects.get(pk=user_id)
|
|
|
|
except User.DoesNotExist:
|
|
|
|
raise Http404
|
|
|
|
|
2012-07-30 13:53:31 -07:00
|
|
|
username = username and username.lower()
|
|
|
|
profile = MSocialProfile.get_user(user.pk)
|
2012-10-18 11:11:26 -07:00
|
|
|
params = {'username': profile.username_slug, 'user_id': user.pk}
|
2012-07-30 13:53:31 -07:00
|
|
|
if not username or profile.username_slug.lower() != username:
|
2012-02-03 11:41:01 -08:00
|
|
|
return HttpResponseRedirect(reverse('shared-stories-rss-feed', kwargs=params))
|
2012-02-02 17:43:17 -08:00
|
|
|
|
2012-07-25 23:57:10 -07:00
|
|
|
social_profile = MSocialProfile.get_user(user_id)
|
2012-10-18 11:11:26 -07:00
|
|
|
current_site = Site.objects.get_current()
|
|
|
|
current_site = current_site and current_site.domain
|
|
|
|
|
2012-10-29 09:18:03 -07:00
|
|
|
if social_profile.private:
|
2012-12-12 14:24:51 -08:00
|
|
|
return HttpResponseForbidden()
|
2012-10-29 09:18:03 -07:00
|
|
|
|
2012-02-02 17:43:17 -08:00
|
|
|
data = {}
|
2012-06-20 17:13:34 -07:00
|
|
|
data['title'] = social_profile.title
|
2012-07-30 21:39:21 -07:00
|
|
|
data['link'] = social_profile.blurblog_url
|
2012-02-02 17:43:17 -08:00
|
|
|
data['description'] = "Stories shared by %s on NewsBlur." % user.username
|
|
|
|
data['lastBuildDate'] = datetime.datetime.utcnow()
|
2013-12-19 11:57:58 -08:00
|
|
|
data['generator'] = 'NewsBlur - %s' % settings.NEWSBLUR_URL
|
2012-02-02 17:43:17 -08:00
|
|
|
data['docs'] = None
|
2012-10-18 11:11:26 -07:00
|
|
|
data['author_name'] = user.username
|
|
|
|
data['feed_url'] = "http://%s%s" % (
|
|
|
|
current_site,
|
|
|
|
reverse('shared-stories-rss-feed', kwargs=params),
|
|
|
|
)
|
|
|
|
rss = feedgenerator.Atom1Feed(**data)
|
2012-02-02 17:43:17 -08:00
|
|
|
|
2012-07-30 13:25:44 -07:00
|
|
|
shared_stories = MSharedStory.objects.filter(user_id=user.pk).order_by('-shared_date')[:25]
|
2012-02-02 17:43:17 -08:00
|
|
|
for shared_story in shared_stories:
|
2012-10-18 11:11:26 -07:00
|
|
|
feed = Feed.get_by_id(shared_story.story_feed_id)
|
|
|
|
content = render_to_string('social/rss_story.xhtml', {
|
|
|
|
'feed': feed,
|
|
|
|
'user': user,
|
|
|
|
'social_profile': social_profile,
|
|
|
|
'shared_story': shared_story,
|
|
|
|
'content': (shared_story.story_content_z and
|
|
|
|
zlib.decompress(shared_story.story_content_z))
|
|
|
|
})
|
2012-02-02 17:43:17 -08:00
|
|
|
story_data = {
|
|
|
|
'title': shared_story.story_title,
|
|
|
|
'link': shared_story.story_permalink,
|
2012-10-18 11:11:26 -07:00
|
|
|
'description': content,
|
|
|
|
'author_name': shared_story.story_author_name,
|
2012-07-30 21:39:21 -07:00
|
|
|
'categories': shared_story.story_tags,
|
2014-01-02 12:32:16 -08:00
|
|
|
'unique_id': shared_story.story_permalink,
|
2012-10-18 11:11:26 -07:00
|
|
|
'pubdate': shared_story.shared_date,
|
2012-02-02 17:43:17 -08:00
|
|
|
}
|
2012-10-18 11:11:26 -07:00
|
|
|
rss.add_item(**story_data)
|
2012-02-02 17:43:17 -08:00
|
|
|
|
2012-10-18 11:11:26 -07:00
|
|
|
logging.user(request, "~FBGenerating ~SB%s~SN's RSS feed: ~FM%s" % (
|
|
|
|
user.username,
|
2013-05-02 17:52:21 -07:00
|
|
|
request.META.get('HTTP_USER_AGENT', "")[:24]
|
2012-10-18 11:11:26 -07:00
|
|
|
))
|
2013-03-19 08:12:48 -04:00
|
|
|
return HttpResponse(rss.writeString('utf-8'), content_type='application/rss+xml')
|
2012-02-13 11:07:32 -08:00
|
|
|
|
2012-12-12 14:24:51 -08:00
|
|
|
@required_params('user_id')
|
2012-02-13 11:07:32 -08:00
|
|
|
@json.json_view
|
|
|
|
def social_feed_trainer(request):
|
2020-06-07 08:04:23 -04:00
|
|
|
social_user_id = request.GET['user_id']
|
2012-07-25 23:57:10 -07:00
|
|
|
social_profile = MSocialProfile.get_user(social_user_id)
|
2012-02-13 11:07:32 -08:00
|
|
|
social_user = get_object_or_404(User, pk=social_user_id)
|
|
|
|
user = get_user(request)
|
|
|
|
|
|
|
|
social_profile.count_stories()
|
2013-06-12 13:52:43 -07:00
|
|
|
classifier = social_profile.canonical()
|
2012-02-14 10:34:10 -08:00
|
|
|
classifier['classifiers'] = get_classifiers_for_user(user, social_user_id=classifier['id'])
|
2012-02-13 11:07:32 -08:00
|
|
|
classifier['num_subscribers'] = social_profile.follower_count
|
|
|
|
classifier['feed_tags'] = []
|
|
|
|
classifier['feed_authors'] = []
|
|
|
|
|
2012-04-12 11:18:56 -07:00
|
|
|
logging.user(user, "~FGLoading social trainer on ~SB%s: %s" % (
|
|
|
|
social_user.username, social_profile.title))
|
2012-02-13 11:07:32 -08:00
|
|
|
|
|
|
|
return [classifier]
|
2012-02-02 17:43:17 -08:00
|
|
|
|
2012-02-16 18:36:52 -08:00
|
|
|
|
|
|
|
@json.json_view
|
|
|
|
def load_social_statistics(request, social_user_id, username=None):
|
|
|
|
stats = dict()
|
2012-07-25 23:57:10 -07:00
|
|
|
social_profile = MSocialProfile.get_user(social_user_id)
|
2012-02-16 18:36:52 -08:00
|
|
|
social_profile.save_feed_story_history_statistics()
|
|
|
|
social_profile.save_classifier_counts()
|
|
|
|
|
|
|
|
# Stories per month - average and month-by-month breakout
|
|
|
|
stats['average_stories_per_month'] = social_profile.average_stories_per_month
|
|
|
|
stats['story_count_history'] = social_profile.story_count_history
|
2016-01-05 11:32:36 -08:00
|
|
|
stats['story_hours_history'] = social_profile.story_hours_history
|
|
|
|
stats['story_days_history'] = social_profile.story_days_history
|
2012-02-16 18:36:52 -08:00
|
|
|
|
|
|
|
# Subscribers
|
|
|
|
stats['subscriber_count'] = social_profile.follower_count
|
|
|
|
stats['num_subscribers'] = social_profile.follower_count
|
|
|
|
|
|
|
|
# Classifier counts
|
|
|
|
stats['classifier_counts'] = social_profile.feed_classifier_counts
|
|
|
|
|
2013-08-15 16:32:44 -07:00
|
|
|
# Feeds
|
|
|
|
feed_ids = [c['feed_id'] for c in stats['classifier_counts'].get('feed', [])]
|
|
|
|
feeds = Feed.objects.filter(pk__in=feed_ids).only('feed_title')
|
|
|
|
titles = dict([(f.pk, f.feed_title) for f in feeds])
|
|
|
|
for stat in stats['classifier_counts'].get('feed', []):
|
|
|
|
stat['feed_title'] = titles.get(stat['feed_id'], "")
|
|
|
|
|
2012-04-12 11:18:56 -07:00
|
|
|
logging.user(request, "~FBStatistics social: ~SB%s ~FG(%s subs)" % (
|
|
|
|
social_profile.user_id, social_profile.follower_count))
|
2012-02-16 18:36:52 -08:00
|
|
|
|
|
|
|
return stats
|
|
|
|
|
|
|
|
@json.json_view
|
|
|
|
def load_social_settings(request, social_user_id, username=None):
|
2012-07-25 23:57:10 -07:00
|
|
|
social_profile = MSocialProfile.get_user(social_user_id)
|
2012-02-16 18:36:52 -08:00
|
|
|
|
2013-06-12 13:52:43 -07:00
|
|
|
return social_profile.canonical()
|
2012-04-12 11:18:56 -07:00
|
|
|
|
2012-07-28 23:02:35 -07:00
|
|
|
@ajax_login_required
|
2012-04-12 11:18:56 -07:00
|
|
|
def load_interactions(request):
|
2020-06-07 08:04:23 -04:00
|
|
|
user_id = request.GET.get('user_id', None)
|
2017-04-04 17:13:43 -07:00
|
|
|
categories = request.GET.getlist('category') or request.GET.getlist('category[]')
|
2012-10-31 13:31:37 -07:00
|
|
|
if not user_id or 'null' in user_id:
|
2012-07-09 12:41:25 -07:00
|
|
|
user_id = get_user(request).pk
|
2020-06-07 08:04:23 -04:00
|
|
|
page = max(1, int(request.GET.get('page', 1)))
|
|
|
|
limit = request.GET.get('limit')
|
2012-08-14 00:26:42 -07:00
|
|
|
interactions, has_next_page = MInteraction.user(user_id, page=page, limit=limit,
|
|
|
|
categories=categories)
|
2020-06-07 08:04:23 -04:00
|
|
|
format = request.GET.get('format', None)
|
2012-07-09 12:41:25 -07:00
|
|
|
|
|
|
|
data = {
|
2012-04-12 11:18:56 -07:00
|
|
|
'interactions': interactions,
|
|
|
|
'page': page,
|
2012-07-18 23:06:43 -07:00
|
|
|
'has_next_page': has_next_page
|
2012-06-20 17:12:46 -04:00
|
|
|
}
|
2012-07-09 12:41:25 -07:00
|
|
|
|
2013-01-31 12:20:53 -08:00
|
|
|
logging.user(request, "~FBLoading interactions ~SBp/%s" % page)
|
|
|
|
|
2012-07-09 12:41:25 -07:00
|
|
|
if format == 'html':
|
2020-06-12 01:27:07 -04:00
|
|
|
return render(request, 'reader/interactions_module.xhtml', data)
|
2012-07-09 12:41:25 -07:00
|
|
|
else:
|
|
|
|
return json.json_response(request, data)
|
2012-07-28 23:02:35 -07:00
|
|
|
|
|
|
|
@ajax_login_required
|
2012-07-11 17:45:55 -07:00
|
|
|
def load_activities(request):
|
2020-06-07 08:04:23 -04:00
|
|
|
user_id = request.GET.get('user_id', None)
|
2017-04-04 17:13:43 -07:00
|
|
|
categories = request.GET.getlist('category') or request.GET.getlist('category[]')
|
2012-10-31 13:31:37 -07:00
|
|
|
if user_id and 'null' not in user_id:
|
2012-07-11 17:45:55 -07:00
|
|
|
user_id = int(user_id)
|
|
|
|
user = User.objects.get(pk=user_id)
|
|
|
|
else:
|
|
|
|
user = get_user(request)
|
|
|
|
user_id = user.pk
|
|
|
|
|
|
|
|
public = user_id != request.user.pk
|
2020-06-07 08:04:23 -04:00
|
|
|
page = max(1, int(request.GET.get('page', 1)))
|
|
|
|
limit = request.GET.get('limit', 4)
|
2012-08-14 00:26:42 -07:00
|
|
|
activities, has_next_page = MActivity.user(user_id, page=page, limit=limit, public=public,
|
|
|
|
categories=categories)
|
2020-06-07 08:04:23 -04:00
|
|
|
format = request.GET.get('format', None)
|
2012-07-11 17:45:55 -07:00
|
|
|
|
|
|
|
data = {
|
|
|
|
'activities': activities,
|
|
|
|
'page': page,
|
2012-07-18 23:06:43 -07:00
|
|
|
'has_next_page': has_next_page,
|
2012-07-11 17:45:55 -07:00
|
|
|
'username': (user.username if public else 'You'),
|
|
|
|
}
|
|
|
|
|
2013-01-31 12:20:53 -08:00
|
|
|
logging.user(request, "~FBLoading activities ~SBp/%s" % page)
|
|
|
|
|
2012-07-11 17:45:55 -07:00
|
|
|
if format == 'html':
|
2020-06-12 01:27:07 -04:00
|
|
|
return render(request, 'reader/activities_module.xhtml', data,
|
|
|
|
)
|
2012-07-11 17:45:55 -07:00
|
|
|
else:
|
|
|
|
return json.json_response(request, data)
|
2012-08-06 17:52:33 -07:00
|
|
|
|
|
|
|
@json.json_view
|
|
|
|
def comment(request, comment_id):
|
|
|
|
try:
|
|
|
|
shared_story = MSharedStory.objects.get(id=comment_id)
|
|
|
|
except MSharedStory.DoesNotExist:
|
|
|
|
raise Http404
|
2013-01-10 20:50:43 -08:00
|
|
|
return shared_story.comments_with_author()
|
|
|
|
|
|
|
|
@json.json_view
|
|
|
|
def comment_reply(request, comment_id, reply_id):
|
|
|
|
try:
|
|
|
|
shared_story = MSharedStory.objects.get(id=comment_id)
|
|
|
|
except MSharedStory.DoesNotExist:
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
for story_reply in shared_story.replies:
|
|
|
|
if story_reply.reply_id == ObjectId(reply_id):
|
2013-01-23 14:21:16 -08:00
|
|
|
return story_reply
|
2013-03-19 08:12:48 -04:00
|
|
|
return shared_story.comments_with_author()
|