Permalink
Browse files

Merge branch 'master' into original_pages_node

* master: (81 commits)
  Adding font size choices to web preferences.
  Closing #66 with both integration of #68 and using the same fonts. Users can add an optional class if they want these other convenient fonts. Also using a few fonts as backups for non-Mac users.
  Fix default theming hook
  Add multiple targeted font stacks
  Fixing #75: shared stories should use story permalink, not story guid. Doh. Thanks @denubis!
  Categorizing preferences. Adding window title count back in.
  Adding email lookup to forgot password flow.
  Adding email lookup to forgot password flow.
  Fixing typo in logging.
  Fixing autocomplete behavior on add dialog.
  Adding broken search for feeds.
  Logging
  Switching to guid-based read story counts from range based counts. Let's see what this screws up.
  Everybody gets unread count in title.
  Backporting collections.Counter to python2.6
  Fixing broken reply interaction with links.
  Prototype of a dupe checker using real-time update times to figure out which feeds are the same. Last time I walked down this road I got run over.
  Adding delete user flow. About time, since I'm sick of doing this myself.
  Deractivating premiums.
  Adding a lock for the intelligence slider for focus stories. If the user selects focus and there are actually focus stories, lock it for the future when there are no unread focus stories.
  ...

Conflicts:
	fabfile.py
  • Loading branch information...
2 parents 9f896d0 + b256088 commit a90518fd3180e661c1e9c7e02e81925c6a38524d @samuelclay committed Jan 7, 2013
Showing with 37,372 additions and 26,669 deletions.
  1. +1 −0 .gitignore
  2. +28 −0 apps/profile/forms.py
  3. +24 −11 apps/profile/management/commands/fp.py
  4. +11 −10 apps/profile/models.py
  5. +1 −1 apps/profile/tasks.py
  6. +1 −0 apps/profile/urls.py
  7. +26 −2 apps/profile/views.py
  8. +8 −6 apps/reader/models.py
  9. +19 −2 apps/reader/tasks.py
  10. +42 −18 apps/reader/views.py
  11. +80 −0 apps/rss_feeds/migrations/0061_address_length.py
  12. +239 −106 apps/rss_feeds/models.py
  13. +5 −5 apps/rss_feeds/page_importer.py
  14. +28 −6 apps/rss_feeds/tasks.py
  15. +27 −11 apps/rss_feeds/views.py
  16. 0 node/node_modules/mongodb/node_modules/bson/README → apps/search/__init__.py
  17. +208 −0 apps/search/models.py
  18. +16 −0 apps/search/tests.py
  19. +1 −0 apps/search/views.py
  20. +8 −8 apps/social/models.py
  21. +7 −23 apps/social/views.py
  22. +3 −2 apps/statistics/models.py
  23. +4 −4 apps/statistics/tasks.py
  24. +1 −1 config/hosts
  25. +6 −0 config/munin.conf
  26. +3 −1 config/munin/mongo_lock
  27. +23 −12 config/nginx.newsblur.conf
  28. +119 −0 config/spawn_fcgi_munin_graph.conf
  29. +1 −1 config/supervisor_celeryd_beat.conf
  30. +2 −2 config/supervisor_node_favicons.conf
  31. +3 −2 config/supervisor_node_unread.conf
  32. +11 −0 config/supervisor_node_unread_ssl.conf
  33. +60 −25 fabfile.py
  34. +2 −0 local_settings.py.template
  35. +6 −6 media/css/modals.css
  36. +23 −23 media/css/payments.css
  37. +218 −52 media/css/reader.css
  38. +5 −1 media/css/status.css
  39. +5 −0 media/ios/Classes/FeedDetailMenuViewController.m
  40. +1 −0 media/ios/Classes/FeedDetailViewController.h
  41. +15 −4 media/ios/Classes/FeedDetailViewController.m
  42. +9 −4 media/ios/Classes/FontSettingsViewController.m
  43. +1 −0 media/ios/Classes/NBContainerViewController.h
  44. +35 −6 media/ios/Classes/NBContainerViewController.m
  45. +17 −0 media/ios/Classes/NewsBlurAppDelegate.h
  46. +232 −10 media/ios/Classes/NewsBlurAppDelegate.m
  47. +10 −10 media/ios/Classes/NewsBlurViewController.h
  48. +102 −313 media/ios/Classes/NewsBlurViewController.m
  49. +1 −1 media/ios/Classes/ShareViewController.m
  50. +1 −2 media/ios/Classes/ShareViewController~ipad.xib
  51. +2 −3 media/ios/Classes/StoryDetailViewController.h
  52. +68 −118 media/ios/Classes/StoryDetailViewController.m
  53. +11 −50 media/ios/Classes/StoryPageControl.m
  54. +4,394 −13 media/ios/Classes/StoryPageControl.xib
  55. +54 −0 media/ios/Classes/TrainerViewController.h
  56. +480 −0 media/ios/Classes/TrainerViewController.m
  57. BIN media/ios/NewsBlur.ipa
  58. +48 −18 media/ios/NewsBlur.xcodeproj/project.pbxproj
  59. +28 −0 media/ios/NewsBlur.xcodeproj/xcuserdata/sclay.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist
  60. +2 −2 media/ios/NewsBlur_Prefix.pch
  61. +2 −1,478 media/ios/Resources-iPad/Classes/MoveSiteViewController~ipad.xib
  62. +10 −13 media/ios/Resources-iPad/Classes/OriginalStoryViewController~ipad.xib
  63. +4,396 −7 media/ios/Resources-iPad/Classes/StoryPageControl~ipad.xib
  64. +6,106 −0 media/ios/Resources-iPad/Classes/TrainerViewController~ipad.xib
  65. BIN media/ios/Resources-iPad/Images/bricks.png
  66. +111 −16 media/ios/Resources-iPad/MainWindow~ipad.xib
  67. +2 −2,191 media/ios/Resources-iPhone/FeedDetailViewController.xib
  68. +136 −61 media/ios/Resources-iPhone/MainWindow.xib
  69. +14 −1,502 media/ios/Resources-iPhone/MoveSiteViewController.xib
  70. +2 −1,454 media/ios/Resources-iPhone/ShareViewController.xib
  71. +6,104 −0 media/ios/Resources-iPhone/TrainerViewController.xib
  72. 0 media/ios/{ → Resources}/reader.css
  73. +0 −8 media/ios/{ → Resources}/storyDetailView.css
  74. +95 −0 media/ios/Resources/storyDetailView.js
  75. 0 media/ios/{ → Resources}/zepto.js
  76. +1 −1 media/ios/ShareKit/Configuration/DefaultSHKConfigurator.m
  77. +1 −1 media/ios/ShareKit/SHKConfig.h
  78. +2 −2 media/ios/ShareKit/Sharers/Services/Read It Later/SHKReadItLater.m
  79. +581 −0 media/ios/static/fastTouch.js
  80. +309 −0 media/ios/static/reader.css
  81. +1 −1 media/ios/{ → static}/sample_text.html
  82. +602 −0 media/ios/static/storyDetailView.css
  83. +8 −0 media/ios/{ → static}/storyDetailView.js
  84. +262 −0 media/ios/static/trainer.css
  85. +20 −0 media/ios/static/trainer.js
  86. +33 −0 media/ios/static/zepto.js
  87. +14 −8 media/js/newsblur/common/assetmodel.js
  88. +6 −4 media/js/newsblur/common/modal.js
  89. +9 −2 media/js/newsblur/models/comments.js
  90. +24 −3 media/js/newsblur/models/feeds.js
  91. +49 −2 media/js/newsblur/models/folders.js
  92. +79 −23 media/js/newsblur/reader/reader.js
  93. +9 −0 media/js/newsblur/reader/reader_account.js
  94. +19 −5 media/js/newsblur/reader/reader_add_feed.js
  95. +6 −3 media/js/newsblur/reader/reader_classifier.js
  96. +54 −23 media/js/newsblur/reader/reader_feed_exception.js
  97. +21 −16 media/js/newsblur/reader/reader_friends.js
  98. +8 −4 media/js/newsblur/reader/reader_intro.js
  99. +270 −242 media/js/newsblur/reader/reader_preferences.js
  100. +53 −0 media/js/newsblur/reader/reader_send_email.js
  101. +5 −5 media/js/newsblur/reader/reader_statistics.js
  102. +1 −0 media/js/newsblur/reader/reader_utils.js
  103. +2 −2 media/js/newsblur/social_page/social_page_comment.js
  104. +1 −0 media/js/newsblur/views/feed_list_view.js
  105. +87 −0 media/js/newsblur/views/feed_search_view.js
  106. +18 −1 media/js/newsblur/views/feed_title_view.js
  107. +21 −2 media/js/newsblur/views/folder_view.js
  108. +21 −19 media/js/newsblur/views/sidebar_header_view.js
  109. +3 −2 media/js/newsblur/views/story_comment_view.js
  110. +1 −0 media/js/newsblur/views/story_detail_view.js
  111. +18 −2 media/js/newsblur/views/story_titles_header_view.js
  112. +14 −5 node/favicons.coffee
  113. +22 −7 node/favicons.js
  114. +2 −2 node/node_modules/mongodb/.travis.yml
  115. +23 −0 node/node_modules/mongodb/CONTRIBUTING.md
  116. +12 −19 node/node_modules/mongodb/Makefile
  117. +442 −0 node/node_modules/mongodb/Readme.md
  118. +0 −45 node/node_modules/mongodb/external-libs/bson/Makefile
  119. +0 −2,165 node/node_modules/mongodb/external-libs/bson/bson.cc
  120. +0 −105 node/node_modules/mongodb/external-libs/bson/bson.h
  121. +0 −20 node/node_modules/mongodb/external-libs/bson/index.js
  122. +0 −349 node/node_modules/mongodb/external-libs/bson/test/test_bson.js
  123. +0 −218 node/node_modules/mongodb/external-libs/bson/test/test_full_bson.js
  124. +0 −132 node/node_modules/mongodb/external-libs/bson/test/test_stackless_bson.js
  125. +0 −39 node/node_modules/mongodb/external-libs/bson/wscript
  126. +87 −139 node/node_modules/mongodb/lib/mongodb/admin.js
  127. +471 −276 node/node_modules/mongodb/lib/mongodb/collection.js
  128. +4 −2 node/node_modules/mongodb/lib/mongodb/commands/base_command.js
  129. +69 −34 node/node_modules/mongodb/lib/mongodb/commands/db_command.js
  130. +9 −6 node/node_modules/mongodb/lib/mongodb/commands/delete_command.js
  131. +18 −12 node/node_modules/mongodb/lib/mongodb/commands/insert_command.js
  132. +81 −29 node/node_modules/mongodb/lib/mongodb/commands/query_command.js
  133. +50 −0 node/node_modules/mongodb/lib/mongodb/connection/base.js
  134. +92 −66 node/node_modules/mongodb/lib/mongodb/connection/connection.js
  135. +55 −63 node/node_modules/mongodb/lib/mongodb/connection/connection_pool.js
  136. +333 −0 node/node_modules/mongodb/lib/mongodb/connection/mongos.js
  137. +66 −0 node/node_modules/mongodb/lib/mongodb/connection/read_preference.js
  138. +1,311 −0 node/node_modules/mongodb/lib/mongodb/connection/repl_set.js
  139. +0 −972 node/node_modules/mongodb/lib/mongodb/connection/repl_set_servers.js
  140. +445 −225 node/node_modules/mongodb/lib/mongodb/connection/server.js
  141. +135 −72 node/node_modules/mongodb/lib/mongodb/connection/strategies/ping_strategy.js
  142. +63 −25 node/node_modules/mongodb/lib/mongodb/connection/strategies/statistics_strategy.js
  143. +223 −0 node/node_modules/mongodb/lib/mongodb/connection/url_parser.js
  144. +301 −122 node/node_modules/mongodb/lib/mongodb/cursor.js
  145. +17 −7 node/node_modules/mongodb/lib/mongodb/cursorstream.js
  146. +919 −502 node/node_modules/mongodb/lib/mongodb/db.js
  147. +28 −23 node/node_modules/mongodb/lib/mongodb/gridfs/chunk.js
  148. +12 −12 node/node_modules/mongodb/lib/mongodb/gridfs/grid.js
  149. +611 −253 node/node_modules/mongodb/lib/mongodb/gridfs/gridstore.js
  150. +28 −19 node/node_modules/mongodb/lib/mongodb/gridfs/readstream.js
  151. +27 −100 node/node_modules/mongodb/lib/mongodb/index.js
  152. +116 −0 node/node_modules/mongodb/lib/mongodb/mongo_client.js
  153. +43 −34 node/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js
  154. +23 −0 node/node_modules/mongodb/lib/mongodb/utils.js
  155. +2 −2 node/node_modules/mongodb/node_modules/bson/.travis.yml
  156. +7 −22 node/node_modules/mongodb/node_modules/bson/Makefile
  157. +1 −0 node/node_modules/mongodb/node_modules/bson/README.md
  158. +130 −0 node/node_modules/mongodb/node_modules/bson/benchmarks/benchmarks.js
  159. +17 −0 node/node_modules/mongodb/node_modules/bson/binding.gyp
  160. +0 −9 node/node_modules/mongodb/node_modules/bson/ext/.lock-wscript
  161. +1,020 −2,165 node/node_modules/mongodb/node_modules/bson/ext/bson.cc
  162. +273 −105 node/node_modules/mongodb/node_modules/bson/ext/bson.h
  163. BIN node/node_modules/mongodb/node_modules/bson/ext/bson.node
  164. +12 −2 node/node_modules/mongodb/node_modules/bson/ext/index.js
  165. BIN node/node_modules/mongodb/node_modules/bson/ext/win32/ia32/bson.node
  166. BIN node/node_modules/mongodb/node_modules/bson/ext/win32/x64/bson.node
  167. +22 −7 node/node_modules/mongodb/node_modules/bson/install.js
  168. +3 −7 node/node_modules/mongodb/node_modules/bson/lib/bson/binary.js
  169. +1 −3 node/node_modules/mongodb/node_modules/bson/lib/bson/binary_parser.js
  170. +45 −33 node/node_modules/mongodb/node_modules/bson/lib/bson/bson.js
  171. +1 −3 node/node_modules/mongodb/node_modules/bson/lib/bson/code.js
  172. +1 −3 node/node_modules/mongodb/node_modules/bson/lib/bson/db_ref.js
  173. +1 −3 node/node_modules/mongodb/node_modules/bson/lib/bson/double.js
  174. +2 −4 node/node_modules/mongodb/node_modules/bson/lib/bson/float_parser.js
  175. +1 −3 node/node_modules/mongodb/node_modules/bson/lib/bson/long.js
  176. +1 −3 node/node_modules/mongodb/node_modules/bson/lib/bson/max_key.js
  177. +1 −3 node/node_modules/mongodb/node_modules/bson/lib/bson/min_key.js
  178. +78 −76 node/node_modules/mongodb/node_modules/bson/lib/bson/objectid.js
  179. +1 −3 node/node_modules/mongodb/node_modules/bson/lib/bson/symbol.js
  180. +1 −3 node/node_modules/mongodb/node_modules/bson/lib/bson/timestamp.js
  181. +11 −8 node/node_modules/mongodb/node_modules/bson/package.json
  182. +19 −1 node/node_modules/mongodb/node_modules/bson/test/browser/bson_test.js
  183. +88 −65 node/node_modules/mongodb/node_modules/bson/test/node/bson_parser_comparision_test.js
  184. +83 −3 node/node_modules/mongodb/node_modules/bson/test/node/bson_test.js
  185. +55 −35 node/node_modules/mongodb/node_modules/bson/test/node/test_full_bson.js
  186. +109 −0 node/node_modules/mongodb/node_modules/bson/test/node/to_bson_test.js
  187. +13 −0 node/node_modules/mongodb/node_modules/bson/tools/gleak.js
  188. +20 −9 node/node_modules/mongodb/package.json
  189. +2,347 −0 node/node_modules/mongodb/upload.py
  190. +0 −9,928 node/node_modules/mongodb/valgrind.log
  191. +14 −2 node/unread_counts.coffee
  192. +17 −4 node/unread_counts.js
  193. +12 −0 settings.py
  194. +4 −1 templates/base.html
  195. +6 −6 templates/mail/email_new_account.xhtml
  196. +87 −0 templates/maintenance_off.html
  197. +42 −0 templates/profile/delete_account.xhtml
  198. +2 −2 templates/profile/stripe_form.xhtml
  199. +1 −1 templates/reader/activities_module.xhtml
  200. +1 −1 templates/reader/feeds_skeleton.xhtml
  201. +7 −3 templates/rss_feeds/status.xhtml
  202. +25 −16 templates/static/about.xhtml
  203. +37 −24 templates/static/faq.xhtml
  204. +193 −1 utils/feed_functions.py
  205. +11 −1 utils/kill_celery.sh
  206. +11 −1 utils/kill_gunicorn.sh
  207. +1 −1 utils/story_functions.py
View
@@ -28,6 +28,7 @@ static.tgz
media/css/circular
config/settings
config/secrets
+templates/maintenance_on.html
# ----------------------
# Android
View
@@ -1,6 +1,7 @@
from django import forms
from vendor.zebra.forms import StripePaymentForm
from django.utils.safestring import mark_safe
+from django.contrib.auth import authenticate
PLANS = [
("newsblur-premium-12", mark_safe("$12 / year <span class='NB-small'>($1/month)</span>")),
@@ -31,3 +32,30 @@ def __init__(self, *args, **kwargs):
required=False)
plan = forms.ChoiceField(required=False, widget=forms.RadioSelect(renderer=HorizRadioRenderer),
choices=PLANS, label='Plan')
+
+
+class DeleteAccountForm(forms.Form):
+ password = forms.CharField(widget=forms.PasswordInput(),
+ label="Confirm your password",
+ required=False)
+ confirm = forms.CharField(label="Type \"Delete\" to confirm",
+ widget=forms.TextInput(),
+ required=False)
+
+ def __init__(self, *args, **kwargs):
+ self.user = kwargs.pop('user')
+ super(DeleteAccountForm, self).__init__(*args, **kwargs)
+
+ def clean_password(self):
+ user_auth = authenticate(username=self.user.username,
+ password=self.cleaned_data['password'])
+ if not user_auth:
+ raise forms.ValidationError('Your password doesn\'t match.')
+
+ return self.cleaned_data
+
+ def clean_confirm(self):
+ if self.cleaned_data.get('confirm', "").lower() != "delete":
+ raise forms.ValidationError('Please type "DELETE" to confirm deletion.')
+
+ return self.cleaned_data
@@ -9,20 +9,33 @@ class Command(BaseCommand):
)
def handle(self, *args, **options):
- username = options['username']
+ username = options.get('username')
+ email = options.get('email')
user = None
- try:
- user = User.objects.get(username__icontains=username)
- except User.MultipleObjectsFound:
- user = User.objects.get(username__iexact=username)
- except User.DoesNotExist:
- user = User.objects.get(email__icontains=username)
- except User.DoesNotExist:
- print " ---> No user/email found at: %s" % username
-
+ if username:
+ try:
+ user = User.objects.get(username__icontains=username)
+ except User.MultipleObjectsReturned:
+ user = User.objects.get(username__iexact=username)
+ except User.DoesNotExist:
+ user = User.objects.get(email__iexact=username)
+ except User.DoesNotExist:
+ print " ---> No user found at: %s" % username
+ elif email:
+ try:
+ user = User.objects.get(email__icontains=email)
+ except User.MultipleObjectsReturned:
+ user = User.objects.get(email__iexact=email)
+ except User.MultipleObjectsReturned:
+ users = User.objects.filter(email__iexact=email)
+ user = users[0]
+ except User.DoesNotExist:
+ print " ---> No email found at: %s" % email
+
if user:
email = options.get("email") or user.email
user.profile.send_forgot_password_email(email)
-
+ else:
+ print " ---> No user/email found at: %s/%s" % (username, email)
View
@@ -79,20 +79,21 @@ def delete_user(self, confirm=False):
from apps.social.models import MActivity, MInteraction
try:
social_profile = MSocialProfile.objects.get(user_id=self.user.pk)
- print " ---> Unfollowing %s followings and %s followers" % (social_profile.following_count,
- social_profile.follower_count)
+ logging.user(self.user, "Unfollowing %s followings and %s followers" %
+ (social_profile.following_count,
+ social_profile.follower_count))
for follow in social_profile.following_user_ids:
social_profile.unfollow_user(follow)
for follower in social_profile.follower_user_ids:
follower_profile = MSocialProfile.objects.get(user_id=follower)
follower_profile.unfollow_user(self.user.pk)
social_profile.delete()
except MSocialProfile.DoesNotExist:
- print " ***> No social profile found. S'ok, moving on."
+ logging.user(self.user, " ***> No social profile found. S'ok, moving on.")
pass
shared_stories = MSharedStory.objects.filter(user_id=self.user.pk)
- print " ---> Deleting %s shared stories" % shared_stories.count()
+ logging.user(self.user, "Deleting %s shared stories" % shared_stories.count())
for story in shared_stories:
try:
original_story = MStory.objects.get(pk=story.story_db_id)
@@ -102,26 +103,26 @@ def delete_user(self, confirm=False):
story.delete()
subscriptions = MSocialSubscription.objects.filter(subscription_user_id=self.user.pk)
- print " ---> Deleting %s social subscriptions" % subscriptions.count()
+ logging.user(self.user, "Deleting %s social subscriptions" % subscriptions.count())
subscriptions.delete()
interactions = MInteraction.objects.filter(user_id=self.user.pk)
- print " ---> Deleting %s interactions for user." % interactions.count()
+ logging.user(self.user, "Deleting %s interactions for user." % interactions.count())
interactions.delete()
interactions = MInteraction.objects.filter(with_user_id=self.user.pk)
- print " ---> Deleting %s interactions with user." % interactions.count()
+ logging.user(self.user, "Deleting %s interactions with user." % interactions.count())
interactions.delete()
activities = MActivity.objects.filter(user_id=self.user.pk)
- print " ---> Deleting %s activities for user." % activities.count()
+ logging.user(self.user, "Deleting %s activities for user." % activities.count())
activities.delete()
activities = MActivity.objects.filter(with_user_id=self.user.pk)
- print " ---> Deleting %s activities with user." % activities.count()
+ logging.user(self.user, "Deleting %s activities with user." % activities.count())
activities.delete()
- print " ---> Deleting user: %s" % self.user
+ logging.user(self.user, "Deleting user: %s" % self.user)
self.user.delete()
def activate_premium(self):
View
@@ -35,4 +35,4 @@ def run(self, **kwargs):
logging.debug(" ---> %s users have expired premiums, deactivating and emailing..." % expired_profiles.count())
for profile in expired_profiles:
profile.send_premium_expire_email()
- # profile.deactive_premium()
+ profile.deactive_premium()
View
@@ -15,4 +15,5 @@
url(r'^stripe_form/?', views.stripe_form, name='stripe-form'),
url(r'^activities/?', views.load_activities, name='profile-activities'),
url(r'^payment_history/?', views.payment_history, name='profile-payment-history'),
+ url(r'^delete_account/?', views.delete_account, name='profile-delete-account'),
)
View
@@ -2,6 +2,7 @@
import datetime
from django.contrib.auth.decorators import login_required
from django.views.decorators.http import require_POST
+from django.contrib.auth import logout as logout_user
from django.http import HttpResponse, HttpResponseRedirect
from django.contrib.sites.models import Site
from django.contrib.auth.models import User
@@ -12,7 +13,7 @@
from django.conf import settings
from apps.profile.models import Profile, change_password, PaymentHistory
from apps.reader.models import UserSubscription
-from apps.profile.forms import StripePlusPaymentForm, PLANS
+from apps.profile.forms import StripePlusPaymentForm, PLANS, DeleteAccountForm
from apps.social.models import MSocialServices, MActivity, MSocialProfile
from utils import json_functions as json
from utils.user_functions import ajax_login_required
@@ -287,4 +288,27 @@ def load_activities(request):
def payment_history(request):
history = PaymentHistory.objects.filter(user=request.user)
- return {'payments': history}
+ return {'payments': history}
+
+@login_required
+@render_to('profile/delete_account.xhtml')
+def delete_account(request):
+ if request.method == 'POST':
+ form = DeleteAccountForm(request.POST, user=request.user)
+ if form.is_valid():
+ logging.user(request.user, "~SK~BC~FRDeleting ~SB%s~SN's account." %
+ request.user.username)
+ request.user.profile.delete_user(confirm=True)
+ logout_user(request)
+ return HttpResponseRedirect(reverse('index'))
+ else:
+ logging.user(request.user, "~BC~FRFailed attempt to delete ~SB%s~SN's account." %
+ request.user.username)
+ else:
+ logging.user(request.user, "~BC~FRAttempting to delete ~SB%s~SN's account." %
+ request.user.username)
+ form = DeleteAccountForm(user=request.user)
+
+ return {
+ 'delete_form': form,
+ }
View
@@ -393,16 +393,17 @@ def calculate_feed_scores(self, silent=False, stories=None):
date_delta = self.mark_read_date
else:
self.mark_read_date = date_delta
-
- read_stories = MUserStory.objects(user_id=self.user_id,
- feed_id=self.feed_id,
- read_date__gte=self.mark_read_date)
- read_stories_ids = [us.story_id for us in read_stories]
if not stories:
stories_db = MStory.objects(story_feed_id=self.feed_id,
story_date__gte=date_delta)
stories = Feed.format_stories(stories_db, self.feed_id)
+
+ story_ids = [s['id'] for s in stories]
+ read_stories = MUserStory.objects(user_id=self.user_id,
+ feed_id=self.feed_id,
+ story_id__in=story_ids)
+ read_stories_ids = [us.story_id for us in read_stories]
oldest_unread_story_date = now
unread_stories = []
@@ -469,7 +470,7 @@ def calculate_feed_scores(self, silent=False, stories=None):
self.mark_feed_read()
if not silent:
- logging.info(' ---> [%s] Computing scores: %s (%s/%s/%s)' % (self.user, self.feed, feed_scores['negative'], feed_scores['neutral'], feed_scores['positive']))
+ logging.user(self.user, '~FC~SNComputing scores: %s (~SB%s~SN/~SB%s~SN/~SB%s~SN)' % (self.feed, feed_scores['negative'], feed_scores['neutral'], feed_scores['positive']))
return self
@@ -584,6 +585,7 @@ class MUserStory(mongo.Document):
story_date = mongo.DateTimeField()
story = mongo.ReferenceField(MStory, dbref=True)
found_story = mongo.GenericReferenceField()
+ shared = mongo.BooleanField()
meta = {
'collection': 'userstories',
View
@@ -3,7 +3,7 @@
from utils import log as logging
from django.contrib.auth.models import User
from django.conf import settings
-from apps.reader.models import UserSubscription
+from apps.reader.models import UserSubscription, MUserStory
from apps.social.models import MSocialSubscription
@@ -46,4 +46,21 @@ def run(self, **kwargs):
})
settings.MONGOANALYTICSDB.nbanalytics.page_loads.remove({
"date": {"$lt": day_ago},
- })
+ })
+
+class CleanStories(Task):
+ name = 'clean-stories'
+
+ def run(self, **kwargs):
+ days_ago = (datetime.datetime.utcnow() -
+ datetime.timedelta(days=settings.DAYS_OF_UNREAD*5))
+ old_stories = MUserStory.objects.filter(read_date__lte=days_ago)
+ logging.debug(" ---> Cleaning stories from %s days ago... %s/%s read stories" % (
+ settings.DAYS_OF_UNREAD*5,
+ MUserStory.objects.count(),
+ old_stories.count()
+ ))
+ for s, story in enumerate(old_stories):
+ if (s+1) % 1000 == 0:
+ logging.debug(" ---> %s stories removed..." % (s+1))
+ story.delete()
Oops, something went wrong.

0 comments on commit a90518f

Please sign in to comment.