diff --git a/apps/profile/middleware.py b/apps/profile/middleware.py index ad447e60c..2a4c003fd 100644 --- a/apps/profile/middleware.py +++ b/apps/profile/middleware.py @@ -187,6 +187,7 @@ class UserAgentBanMiddleware: if 'profile' in request.path: return if 'haproxy' in request.path: return + if getattr(settings, 'TEST_DEBUG'): return if any(ua in user_agent for ua in BANNED_USER_AGENTS): data = { diff --git a/apps/reader/fixtures/subscriptions.json b/apps/reader/fixtures/subscriptions.json index 34d05528c..21533daa7 100644 --- a/apps/reader/fixtures/subscriptions.json +++ b/apps/reader/fixtures/subscriptions.json @@ -17,7 +17,7 @@ "pk": 1, "model": "reader.usersubscriptionfolders", "fields": { - "folders": "[1, {\"Tech\": [4, 5, {\"Deep Tech\": [6, 7]}]}, 2, 3, 8, 9, {\"Blogs\": [8, 9]}]", + "folders": "[{\"Tech\": [1, 4, 5, {\"Deep Tech\": [6, 7]}]}, 2, 3, 8, 9, {\"Blogs\": [8, 9]}, 1]", "user": 1 } }, diff --git a/apps/reader/models.py b/apps/reader/models.py index 5d71fb856..9117a6c98 100644 --- a/apps/reader/models.py +++ b/apps/reader/models.py @@ -917,7 +917,25 @@ class UserSubscriptionFolders(models.Model): user_sub_folders = add_object_to_folder(obj, parent_folder, user_sub_folders) self.folders = json.encode(user_sub_folders) self.save() + + def arranged_folders(self): + user_sub_folders = json.decode(self.folders) + def _arrange_folder(folder): + folder_feeds = [] + folder_folders = [] + for item in folder: + if isinstance(item, int): + folder_feeds.append(item) + elif isinstance(item, dict): + for f_k, f_v in item.items(): + arranged_folder = _arrange_folder(f_v) + folder_folders.append({f_k: arranged_folder}) + + arranged_folder = folder_feeds + folder_folders + return arranged_folder + return _arrange_folder(user_sub_folders) + def delete_feed(self, feed_id, in_folder, commit_delete=True): def _find_feed_in_folders(old_folders, folder_name='', multiples_found=False, deleted=False): new_folders = [] @@ -944,7 +962,7 @@ class UserSubscriptionFolders(models.Model): return new_folders, multiples_found, deleted - user_sub_folders = json.decode(self.folders) + user_sub_folders = self.arranged_folders() user_sub_folders, multiples_found, deleted = _find_feed_in_folders(user_sub_folders) self.folders = json.encode(user_sub_folders) self.save() diff --git a/apps/reader/tests.py b/apps/reader/tests.py index 4a9bebbf6..f9c173650 100644 --- a/apps/reader/tests.py +++ b/apps/reader/tests.py @@ -6,7 +6,9 @@ from django.conf import settings from mongoengine.connection import connect, disconnect class ReaderTest(TestCase): - fixtures = ['subscriptions.json', 'stories.json', '../../rss_feeds/fixtures/gawker1.json'] + fixtures = ['../../rss_feeds/fixtures/rss_feeds.json', + 'subscriptions.json', 'stories.json', + '../../rss_feeds/fixtures/gawker1.json'] def setUp(self): @@ -23,16 +25,16 @@ class ReaderTest(TestCase): response = self.client.get(reverse('load-feeds')) content = json.decode(response.content) - self.assertEquals(len(content['feeds']), 1) + self.assertEquals(len(content['feeds']), 10) self.assertEquals(content['feeds']['1']['feed_title'], 'Gawker') - self.assertEquals(content['folders'], [1, {'Tech': [4, 5, {'Deep Tech': [6, 7]}]}, 2, 3, 8, 9, {'Blogs': [8, 9]}]) + self.assertEquals(content['folders'], [{'Tech': [1, 4, 5, {'Deep Tech': [6, 7]}]}, 2, 3, 8, 9, {'Blogs': [8, 9]}, 1]) def test_delete_feed(self): self.client.login(username='conesus', password='test') response = self.client.get(reverse('load-feeds')) feeds = json.decode(response.content) - self.assertEquals(feeds['folders'], [1, {'Tech': [4, 5, {'Deep Tech': [6, 7]}]}, 2, 3, 8, 9, {'Blogs': [8, 9]}]) + self.assertEquals(feeds['folders'], [{'Tech': [1, 4, 5, {'Deep Tech': [6, 7]}]}, 2, 3, 8, 9, {'Blogs': [8, 9]}, 1]) # Delete feed response = self.client.post(reverse('delete-feed'), {'feed_id': 1, 'in_folder': ''}) @@ -41,7 +43,7 @@ class ReaderTest(TestCase): response = self.client.get(reverse('load-feeds')) feeds = json.decode(response.content) - self.assertEquals(feeds['folders'], [{'Tech': [4, 5, {'Deep Tech': [6, 7]}]}, 2, 3, 8, 9, {'Blogs': [8, 9]}]) + self.assertEquals(feeds['folders'], [2, 3, 8, 9, {'Tech': [1, 4, 5, {'Deep Tech': [6, 7]}]}, {'Blogs': [8, 9]}]) # Delete feed response = self.client.post(reverse('delete-feed'), {'feed_id': 9, 'in_folder': 'Blogs'}) @@ -50,7 +52,7 @@ class ReaderTest(TestCase): response = self.client.get(reverse('load-feeds')) feeds = json.decode(response.content) - self.assertEquals(feeds['folders'], [{'Tech': [4, 5, {'Deep Tech': [6, 7]}]}, 2, 3, 8, 9, {'Blogs': [8]}]) + self.assertEquals(feeds['folders'], [2, 3, 8, 9, {'Tech': [1, 4, 5, {'Deep Tech': [6, 7]}]}, {'Blogs': [8]}]) # Delete feed response = self.client.post(reverse('delete-feed'), {'feed_id': 5, 'in_folder': 'Tech'}) @@ -59,7 +61,7 @@ class ReaderTest(TestCase): response = self.client.get(reverse('load-feeds')) feeds = json.decode(response.content) - self.assertEquals(feeds['folders'], [{'Tech': [4, {'Deep Tech': [6, 7]}]}, 2, 3, 8, 9, {'Blogs': [8]}]) + self.assertEquals(feeds['folders'], [2, 3, 8, 9, {'Tech': [1, 4, {'Deep Tech': [6, 7]}]}, {'Blogs': [8]}]) # Delete feed response = self.client.post(reverse('delete-feed'), {'feed_id': 4, 'in_folder': 'Tech'}) @@ -68,7 +70,7 @@ class ReaderTest(TestCase): response = self.client.get(reverse('load-feeds')) feeds = json.decode(response.content) - self.assertEquals(feeds['folders'], [{'Tech': [{'Deep Tech': [6, 7]}]}, 2, 3, 8, 9, {'Blogs': [8]}]) + self.assertEquals(feeds['folders'], [2, 3, 8, 9, {'Tech': [1, {'Deep Tech': [6, 7]}]}, {'Blogs': [8]}]) # Delete feed response = self.client.post(reverse('delete-feed'), {'feed_id': 8, 'in_folder': ''}) @@ -77,7 +79,23 @@ class ReaderTest(TestCase): response = self.client.get(reverse('load-feeds')) feeds = json.decode(response.content) - self.assertEquals(feeds['folders'], [{'Tech': [{'Deep Tech': [6, 7]}]}, 2, 3, 9, {'Blogs': [8]}]) + self.assertEquals(feeds['folders'], [2, 3, 9, {'Tech': [1, {'Deep Tech': [6, 7]}]}, {'Blogs': [8]}]) + + def test_delete_feed__multiple_folders(self): + self.client.login(username='conesus', password='test') + + response = self.client.get(reverse('load-feeds')) + feeds = json.decode(response.content) + self.assertEquals(feeds['folders'], [{'Tech': [1, 4, 5, {'Deep Tech': [6, 7]}]}, 2, 3, 8, 9, {'Blogs': [8, 9]}, 1]) + + # Delete feed + response = self.client.post(reverse('delete-feed'), {'feed_id': 1}) + response = json.decode(response.content) + self.assertEquals(response['code'], 1) + + response = self.client.get(reverse('load-feeds')) + feeds = json.decode(response.content) + self.assertEquals(feeds['folders'], [2, 3, 8, 9, {'Tech': [1, 4, 5, {'Deep Tech': [6, 7]}]}, {'Blogs': [8, 9]}]) def test_load_single_feed(self): # from django.conf import settings diff --git a/apps/reader/views.py b/apps/reader/views.py index 6ae047d12..0d7928890 100644 --- a/apps/reader/views.py +++ b/apps/reader/views.py @@ -607,8 +607,9 @@ def load_single_feed(request, feed_id): if not include_story_content: del story['story_content'] story_date = localtime_for_timezone(story['story_date'], user.profile.timezone) - story['short_parsed_date'] = format_story_link_date__short(story_date) - story['long_parsed_date'] = format_story_link_date__long(story_date, now) + nowtz = localtime_for_timezone(now, user.profile.timezone) + story['short_parsed_date'] = format_story_link_date__short(story_date, nowtz) + story['long_parsed_date'] = format_story_link_date__long(story_date, nowtz) if usersub: story['read_status'] = 1 if (read_filter == 'all' or query) and usersub: @@ -782,12 +783,13 @@ def load_starred_stories(request): comments=story.comments)) for story in shared_stories]) + nowtz = localtime_for_timezone(now, user.profile.timezone) for story in stories: story_date = localtime_for_timezone(story['story_date'], user.profile.timezone) - story['short_parsed_date'] = format_story_link_date__short(story_date) - story['long_parsed_date'] = format_story_link_date__long(story_date, now) + story['short_parsed_date'] = format_story_link_date__short(story_date, nowtz) + story['long_parsed_date'] = format_story_link_date__long(story_date, nowtz) starred_date = localtime_for_timezone(story['starred_date'], user.profile.timezone) - story['starred_date'] = format_story_link_date__long(starred_date, now) + story['starred_date'] = format_story_link_date__long(starred_date, nowtz) story['read_status'] = 1 story['starred'] = True story['intelligence'] = { @@ -939,6 +941,7 @@ def load_river_stories__redis(request): # Just need to format stories + nowtz = localtime_for_timezone(now, user.profile.timezone) for story in stories: story['read_status'] = 0 if read_filter == 'all': @@ -946,8 +949,8 @@ def load_river_stories__redis(request): story['story_hash'] not in unread_feed_story_hashes): story['read_status'] = 1 story_date = localtime_for_timezone(story['story_date'], user.profile.timezone) - story['short_parsed_date'] = format_story_link_date__short(story_date) - story['long_parsed_date'] = format_story_link_date__long(story_date, now) + story['short_parsed_date'] = format_story_link_date__short(story_date, nowtz) + story['long_parsed_date'] = format_story_link_date__long(story_date, nowtz) if story['story_hash'] in starred_stories: story['starred'] = True starred_date = localtime_for_timezone(starred_stories[story['story_hash']], @@ -1399,7 +1402,7 @@ def add_folder(request): def delete_feed(request): feed_id = int(request.POST['feed_id']) in_folder = request.POST.get('in_folder', None) - if in_folder == ' ': + if not in_folder or in_folder == ' ': in_folder = "" user_sub_folders = get_object_or_404(UserSubscriptionFolders, user=request.user) diff --git a/apps/rss_feeds/fixtures/rss_feeds.json b/apps/rss_feeds/fixtures/rss_feeds.json index 5ffc0cf06..1f96192a8 100644 --- a/apps/rss_feeds/fixtures/rss_feeds.json +++ b/apps/rss_feeds/fixtures/rss_feeds.json @@ -136,5 +136,302 @@ "email": "samuel@newsblur.com", "date_joined": "2009-01-04 17:32:58" } + }, + + { + "pk": 2, + "model": "rss_feeds.feed", + "fields": { + "premium_subscribers": -1, + "creation": "2011-08-27", + "exception_code": 0, + "last_load_time": 0, + "active_subscribers": 1, + "feed_address": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker2.xml", + "feed_link": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker2.html", + "hash_address_and_link": "2", + "feed_link_locked": true, + "last_update": "2011-08-27 02:45:21", + "etag": null, + "average_stories_per_month": 0, + "feed_title": "Gawker", + "last_modified": null, + "next_scheduled_update": "2011-08-28 14:33:50", + "favicon_color": null, + "stories_last_month": 0, + "active": true, + "favicon_not_found": false, + "has_page_exception": false, + "fetched_once": false, + "days_to_trim": 90, + "num_subscribers": 1, + "last_story_date": "2011-08-28 00:03:50", + "min_to_decay": 720, + "has_feed_exception": false + } + }, + + { + "pk": 3, + "model": "rss_feeds.feed", + "fields": { + "premium_subscribers": -1, + "creation": "2011-08-27", + "exception_code": 0, + "last_load_time": 0, + "active_subscribers": 1, + "feed_address": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker3.xml", + "feed_link": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker3.html", + "hash_address_and_link": "3", + "feed_link_locked": true, + "last_update": "2011-08-27 02:45:21", + "etag": null, + "average_stories_per_month": 0, + "feed_title": "Gawker", + "last_modified": null, + "next_scheduled_update": "2011-08-28 14:33:50", + "favicon_color": null, + "stories_last_month": 0, + "active": true, + "favicon_not_found": false, + "has_page_exception": false, + "fetched_once": false, + "days_to_trim": 90, + "num_subscribers": 1, + "last_story_date": "2011-08-28 00:03:50", + "min_to_decay": 720, + "has_feed_exception": false + } + }, + + { + "pk": 4, + "model": "rss_feeds.feed", + "fields": { + "premium_subscribers": -1, + "creation": "2011-08-27", + "exception_code": 0, + "last_load_time": 0, + "active_subscribers": 1, + "feed_address": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker4.xml", + "feed_link": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker4.html", + "hash_address_and_link": "4", + "feed_link_locked": true, + "last_update": "2011-08-27 02:45:21", + "etag": null, + "average_stories_per_month": 0, + "feed_title": "Gawker", + "last_modified": null, + "next_scheduled_update": "2011-08-28 14:33:50", + "favicon_color": null, + "stories_last_month": 0, + "active": true, + "favicon_not_found": false, + "has_page_exception": false, + "fetched_once": false, + "days_to_trim": 90, + "num_subscribers": 1, + "last_story_date": "2011-08-28 00:03:50", + "min_to_decay": 720, + "has_feed_exception": false + } + }, + + { + "pk": 5, + "model": "rss_feeds.feed", + "fields": { + "premium_subscribers": -1, + "creation": "2011-08-27", + "exception_code": 0, + "last_load_time": 0, + "active_subscribers": 1, + "feed_address": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker5.xml", + "feed_link": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker5.html", + "hash_address_and_link": "5", + "feed_link_locked": true, + "last_update": "2011-08-27 02:45:21", + "etag": null, + "average_stories_per_month": 0, + "feed_title": "Gawker", + "last_modified": null, + "next_scheduled_update": "2011-08-28 14:33:50", + "favicon_color": null, + "stories_last_month": 0, + "active": true, + "favicon_not_found": false, + "has_page_exception": false, + "fetched_once": false, + "days_to_trim": 90, + "num_subscribers": 1, + "last_story_date": "2011-08-28 00:03:50", + "min_to_decay": 720, + "has_feed_exception": false + } + }, + + { + "pk": 6, + "model": "rss_feeds.feed", + "fields": { + "premium_subscribers": -1, + "creation": "2011-08-27", + "exception_code": 0, + "last_load_time": 0, + "active_subscribers": 1, + "feed_address": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker6.xml", + "feed_link": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker6.html", + "hash_address_and_link": "6", + "feed_link_locked": true, + "last_update": "2011-08-27 02:45:21", + "etag": null, + "average_stories_per_month": 0, + "feed_title": "Gawker", + "last_modified": null, + "next_scheduled_update": "2011-08-28 14:33:50", + "favicon_color": null, + "stories_last_month": 0, + "active": true, + "favicon_not_found": false, + "has_page_exception": false, + "fetched_once": false, + "days_to_trim": 90, + "num_subscribers": 1, + "last_story_date": "2011-08-28 00:03:50", + "min_to_decay": 720, + "has_feed_exception": false + } + }, + + { + "pk": 7, + "model": "rss_feeds.feed", + "fields": { + "premium_subscribers": -1, + "creation": "2011-08-27", + "exception_code": 0, + "last_load_time": 0, + "active_subscribers": 1, + "feed_address": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker7.xml", + "feed_link": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker7.html", + "hash_address_and_link": "7", + "feed_link_locked": true, + "last_update": "2011-08-27 02:45:21", + "etag": null, + "average_stories_per_month": 0, + "feed_title": "Gawker", + "last_modified": null, + "next_scheduled_update": "2011-08-28 14:33:50", + "favicon_color": null, + "stories_last_month": 0, + "active": true, + "favicon_not_found": false, + "has_page_exception": false, + "fetched_once": false, + "days_to_trim": 90, + "num_subscribers": 1, + "last_story_date": "2011-08-28 00:03:50", + "min_to_decay": 720, + "has_feed_exception": false + } + }, + + { + "pk": 8, + "model": "rss_feeds.feed", + "fields": { + "premium_subscribers": -1, + "creation": "2011-08-27", + "exception_code": 0, + "last_load_time": 0, + "active_subscribers": 1, + "feed_address": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker8.xml", + "feed_link": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker8.html", + "hash_address_and_link": "8", + "feed_link_locked": true, + "last_update": "2011-08-27 02:45:21", + "etag": null, + "average_stories_per_month": 0, + "feed_title": "Gawker", + "last_modified": null, + "next_scheduled_update": "2011-08-28 14:33:50", + "favicon_color": null, + "stories_last_month": 0, + "active": true, + "favicon_not_found": false, + "has_page_exception": false, + "fetched_once": false, + "days_to_trim": 90, + "num_subscribers": 1, + "last_story_date": "2011-08-28 00:03:50", + "min_to_decay": 720, + "has_feed_exception": false + } + }, + + { + "pk": 9, + "model": "rss_feeds.feed", + "fields": { + "premium_subscribers": -1, + "creation": "2011-08-27", + "exception_code": 0, + "last_load_time": 0, + "active_subscribers": 1, + "feed_address": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker9.xml", + "feed_link": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker9.html", + "hash_address_and_link": "9", + "feed_link_locked": true, + "last_update": "2011-08-27 02:45:21", + "etag": null, + "average_stories_per_month": 0, + "feed_title": "Gawker", + "last_modified": null, + "next_scheduled_update": "2011-08-28 14:33:50", + "favicon_color": null, + "stories_last_month": 0, + "active": true, + "favicon_not_found": false, + "has_page_exception": false, + "fetched_once": false, + "days_to_trim": 90, + "num_subscribers": 1, + "last_story_date": "2011-08-28 00:03:50", + "min_to_decay": 720, + "has_feed_exception": false + } + }, + + { + "pk": 56, + "model": "rss_feeds.feed", + "fields": { + "premium_subscribers": -1, + "creation": "2011-08-27", + "exception_code": 0, + "last_load_time": 0, + "active_subscribers": 1, + "feed_address": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker56.xml", + "feed_link": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker56.html", + "hash_address_and_link": "56", + "feed_link_locked": true, + "last_update": "2011-08-27 02:45:21", + "etag": null, + "average_stories_per_month": 0, + "feed_title": "Gawker", + "last_modified": null, + "next_scheduled_update": "2011-08-28 14:33:50", + "favicon_color": null, + "stories_last_month": 0, + "active": true, + "favicon_not_found": false, + "has_page_exception": false, + "fetched_once": false, + "days_to_trim": 90, + "num_subscribers": 1, + "last_story_date": "2011-08-28 00:03:50", + "min_to_decay": 720, + "has_feed_exception": false + } } ] \ No newline at end of file diff --git a/apps/rss_feeds/models.py b/apps/rss_feeds/models.py index 0c4f1cc25..f54cf4bc3 100644 --- a/apps/rss_feeds/models.py +++ b/apps/rss_feeds/models.py @@ -912,6 +912,7 @@ class Feed(models.Model): story_content = strip_comments(story_content) story_tags = self.get_tags(story) story_link = self.get_permalink(story) + replace_story_date = False try: existing_story, story_has_changed = _1(story, story_content, existing_stories) @@ -937,11 +938,18 @@ class Feed(models.Model): try: s.save() ret_values['new'] += 1 - except (IntegrityError, OperationError), e: + except (IntegrityError), e: ret_values['error'] += 1 if settings.DEBUG: logging.info(' ---> [%-30s] ~SN~FRIntegrityError on new story: %s - %s' % (self.feed_title[:30], story.get('guid'), e)) - elif existing_story and story_has_changed: + except OperationError, e: + existing_story, _ = MStory.find_story(self.pk, + story.get('guid'), + original_only=True) + story_has_changed = True + replace_story_date = True + + if existing_story and story_has_changed: # update story original_content = None try: @@ -993,7 +1001,8 @@ class Feed(models.Model): existing_story.story_tags = story_tags # Do not allow publishers to change the story date once a story is published. # Leads to incorrect unread story counts. - # existing_story.story_date = story.get('published') # No, don't + if replace_story_date: + existing_story.story_date = story.get('published') # Really shouldn't do this. existing_story.extract_image_urls() try: diff --git a/apps/social/models.py b/apps/social/models.py index 2d15b1c77..a0fc6492a 100644 --- a/apps/social/models.py +++ b/apps/social/models.py @@ -3001,14 +3001,17 @@ class MActivity(mongo.Document): @classmethod def remove_shared_story(cls, user_id, story_feed_id, story_id): + params = dict(user_id=user_id, + category='sharedstory', + feed_id="social:%s" % user_id, + story_feed_id=story_feed_id, + content_id=story_id) try: - a = cls.objects.get(user_id=user_id, - category='sharedstory', - feed_id="social:%s" % user_id, - story_feed_id=story_feed_id, - content_id=story_id) + a = cls.objects.get(**params) except cls.DoesNotExist: return + except cls.MultipleObjectsReturned: + a = cls.objects.filter(**params) a.delete() diff --git a/apps/social/views.py b/apps/social/views.py index ec57a45fc..465e23f49 100644 --- a/apps/social/views.py +++ b/apps/social/views.py @@ -119,12 +119,13 @@ def load_social_stories(request, user_id, username=None): comments=story.comments)) for story in shared_stories]) + nowtz = localtime_for_timezone(now, user.profile.timezone) for story in stories: story['social_user_id'] = social_user_id # story_date = localtime_for_timezone(story['story_date'], user.profile.timezone) shared_date = localtime_for_timezone(story['shared_date'], user.profile.timezone) - story['short_parsed_date'] = format_story_link_date__short(shared_date) - story['long_parsed_date'] = format_story_link_date__long(shared_date) + story['short_parsed_date'] = format_story_link_date__short(shared_date, nowtz) + story['long_parsed_date'] = format_story_link_date__long(shared_date, nowtz) story['read_status'] = 1 if (read_filter == 'all' or query) and socialsub: @@ -270,13 +271,14 @@ def load_river_blurblog(request): classifier_tags = [] # Just need to format stories + nowtz = localtime_for_timezone(now, user.profile.timezone) for story in stories: story['read_status'] = 0 if story['story_hash'] not in unread_feed_story_hashes: story['read_status'] = 1 story_date = localtime_for_timezone(story['story_date'], user.profile.timezone) - story['short_parsed_date'] = format_story_link_date__short(story_date) - story['long_parsed_date'] = format_story_link_date__long(story_date, now) + story['short_parsed_date'] = format_story_link_date__short(story_date, nowtz) + story['long_parsed_date'] = format_story_link_date__long(story_date, nowtz) if story['story_hash'] in starred_stories: story['starred'] = True starred_date = localtime_for_timezone(starred_stories[story['story_hash']], user.profile.timezone) @@ -521,7 +523,9 @@ def mark_story_as_shared(request): source_user_id = request.POST.get('source_user_id') relative_user_id = request.POST.get('relative_user_id') or request.user.pk post_to_services = request.POST.getlist('post_to_services') - format = request.REQUEST.get('format', 'json') + format = request.REQUEST.get('format', 'json') + now = datetime.datetime.now() + nowtz = localtime_for_timezone(now, request.user.profile.timezone) MSocialProfile.get_user(request.user.pk) @@ -576,8 +580,8 @@ def mark_story_as_shared(request): story['shared_by_user'] = True story['shared'] = True shared_date = localtime_for_timezone(shared_story['shared_date'], request.user.profile.timezone) - story['short_parsed_date'] = format_story_link_date__short(shared_date) - story['long_parsed_date'] = format_story_link_date__long(shared_date) + story['short_parsed_date'] = format_story_link_date__short(shared_date, nowtz) + story['long_parsed_date'] = format_story_link_date__long(shared_date, nowtz) if post_to_services: for service in post_to_services: diff --git a/clients/android/NewsBlur/AndroidManifest.xml b/clients/android/NewsBlur/AndroidManifest.xml index 8606a4d83..0cf3a91d0 100644 --- a/clients/android/NewsBlur/AndroidManifest.xml +++ b/clients/android/NewsBlur/AndroidManifest.xml @@ -1,8 +1,8 @@ + android:versionCode="44" + android:versionName="3.0.0" > - + - + - - - + + + + + + + + + + diff --git a/clients/android/NewsBlur/libs/ActionBarSherlock/ActionBarSherlock.iml b/clients/android/NewsBlur/libs/ActionBarSherlock/ActionBarSherlock.iml index d89c425a1..28fe8856f 100644 --- a/clients/android/NewsBlur/libs/ActionBarSherlock/ActionBarSherlock.iml +++ b/clients/android/NewsBlur/libs/ActionBarSherlock/ActionBarSherlock.iml @@ -11,12 +11,11 @@ - + - + - diff --git a/clients/android/NewsBlur/libs/ActionBarSherlock/project.properties b/clients/android/NewsBlur/libs/ActionBarSherlock/project.properties index 0e58ae1c0..5ca7d6247 100755 --- a/clients/android/NewsBlur/libs/ActionBarSherlock/project.properties +++ b/clients/android/NewsBlur/libs/ActionBarSherlock/project.properties @@ -9,4 +9,4 @@ android.library=true # Project target. -target=android-17 +target=android-14 diff --git a/clients/android/NewsBlur/project.properties b/clients/android/NewsBlur/project.properties index 8ee7b6a46..134b0ba31 100644 --- a/clients/android/NewsBlur/project.properties +++ b/clients/android/NewsBlur/project.properties @@ -11,5 +11,5 @@ #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt # Project target. -target=android-17 +target=android-14 android.library.reference.1=libs/ActionBarSherlock diff --git a/clients/android/NewsBlur/res/drawable-hdpi/clock.png b/clients/android/NewsBlur/res/drawable-hdpi/clock.png new file mode 100644 index 000000000..3dbcdfd3a Binary files /dev/null and b/clients/android/NewsBlur/res/drawable-hdpi/clock.png differ diff --git a/clients/android/NewsBlur/res/drawable-hdpi/share.png b/clients/android/NewsBlur/res/drawable-hdpi/share.png deleted file mode 100644 index c329f58da..000000000 Binary files a/clients/android/NewsBlur/res/drawable-hdpi/share.png and /dev/null differ diff --git a/clients/android/NewsBlur/res/drawable-hdpi/share_icon.png b/clients/android/NewsBlur/res/drawable-hdpi/share_icon.png new file mode 100644 index 000000000..17738db3e Binary files /dev/null and b/clients/android/NewsBlur/res/drawable-hdpi/share_icon.png differ diff --git a/clients/android/NewsBlur/res/drawable-mdpi/share.png b/clients/android/NewsBlur/res/drawable-mdpi/share.png deleted file mode 100644 index 056deb57b..000000000 Binary files a/clients/android/NewsBlur/res/drawable-mdpi/share.png and /dev/null differ diff --git a/clients/android/NewsBlur/res/drawable/barbutton_refresh.png b/clients/android/NewsBlur/res/drawable/barbutton_refresh.png index fadfd0450..51978518d 100644 Binary files a/clients/android/NewsBlur/res/drawable/barbutton_refresh.png and b/clients/android/NewsBlur/res/drawable/barbutton_refresh.png differ diff --git a/clients/android/NewsBlur/res/drawable/clock.png b/clients/android/NewsBlur/res/drawable/clock.png index 3dbcdfd3a..06793f656 100644 Binary files a/clients/android/NewsBlur/res/drawable/clock.png and b/clients/android/NewsBlur/res/drawable/clock.png differ diff --git a/clients/android/NewsBlur/res/drawable/clock_half.png b/clients/android/NewsBlur/res/drawable/clock_half.png deleted file mode 100644 index 06793f656..000000000 Binary files a/clients/android/NewsBlur/res/drawable/clock_half.png and /dev/null differ diff --git a/clients/android/NewsBlur/res/drawable/feed_background_highlight.xml b/clients/android/NewsBlur/res/drawable/feed_background_highlight.xml new file mode 100644 index 000000000..f52202068 --- /dev/null +++ b/clients/android/NewsBlur/res/drawable/feed_background_highlight.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + diff --git a/clients/android/NewsBlur/res/drawable/folder_background_default.xml b/clients/android/NewsBlur/res/drawable/folder_background_default.xml new file mode 100644 index 000000000..a5b80ba5a --- /dev/null +++ b/clients/android/NewsBlur/res/drawable/folder_background_default.xml @@ -0,0 +1,9 @@ + + + + diff --git a/clients/android/NewsBlur/res/drawable/folder_background_highlight.xml b/clients/android/NewsBlur/res/drawable/folder_background_highlight.xml new file mode 100644 index 000000000..7ffc2c396 --- /dev/null +++ b/clients/android/NewsBlur/res/drawable/folder_background_highlight.xml @@ -0,0 +1,9 @@ + + + + diff --git a/clients/android/NewsBlur/res/drawable/logo.png b/clients/android/NewsBlur/res/drawable/logo.png index 64e827fed..56b5112c9 100644 Binary files a/clients/android/NewsBlur/res/drawable/logo.png and b/clients/android/NewsBlur/res/drawable/logo.png differ diff --git a/clients/android/NewsBlur/res/drawable/logo_newsblur_blur.png b/clients/android/NewsBlur/res/drawable/logo_newsblur_blur.png index 66fb4b8ed..e445de924 100644 Binary files a/clients/android/NewsBlur/res/drawable/logo_newsblur_blur.png and b/clients/android/NewsBlur/res/drawable/logo_newsblur_blur.png differ diff --git a/clients/android/NewsBlur/res/drawable/selector_feed_background.xml b/clients/android/NewsBlur/res/drawable/selector_feed_background.xml index d5a2a0bb7..9ef6ef52a 100644 --- a/clients/android/NewsBlur/res/drawable/selector_feed_background.xml +++ b/clients/android/NewsBlur/res/drawable/selector_feed_background.xml @@ -1,5 +1,5 @@ - + diff --git a/clients/android/NewsBlur/res/drawable/selector_folder_background.xml b/clients/android/NewsBlur/res/drawable/selector_folder_background.xml index 7ce753d96..bd8ddc87b 100644 --- a/clients/android/NewsBlur/res/drawable/selector_folder_background.xml +++ b/clients/android/NewsBlur/res/drawable/selector_folder_background.xml @@ -1,5 +1,5 @@ - - + + diff --git a/clients/android/NewsBlur/res/drawable/selector_story_background.xml b/clients/android/NewsBlur/res/drawable/selector_story_background.xml new file mode 100644 index 000000000..8c840f5f7 --- /dev/null +++ b/clients/android/NewsBlur/res/drawable/selector_story_background.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/clients/android/NewsBlur/res/drawable/share_half.png b/clients/android/NewsBlur/res/drawable/share_icon.png similarity index 100% rename from clients/android/NewsBlur/res/drawable/share_half.png rename to clients/android/NewsBlur/res/drawable/share_icon.png diff --git a/clients/android/NewsBlur/res/drawable/story_background_default.xml b/clients/android/NewsBlur/res/drawable/story_background_default.xml new file mode 100644 index 000000000..51e919d78 --- /dev/null +++ b/clients/android/NewsBlur/res/drawable/story_background_default.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/clients/android/NewsBlur/res/drawable/story_background_highlight.xml b/clients/android/NewsBlur/res/drawable/story_background_highlight.xml new file mode 100644 index 000000000..21e1ef44d --- /dev/null +++ b/clients/android/NewsBlur/res/drawable/story_background_highlight.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + diff --git a/clients/android/NewsBlur/res/layout/activity_settings.xml b/clients/android/NewsBlur/res/layout/activity_settings.xml index c4321598d..3f2c9eaeb 100644 --- a/clients/android/NewsBlur/res/layout/activity_settings.xml +++ b/clients/android/NewsBlur/res/layout/activity_settings.xml @@ -19,4 +19,13 @@ android:defaultValue="@string/default_read_filter_value" /> + + + + + \ No newline at end of file diff --git a/clients/android/NewsBlur/res/layout/include_comment.xml b/clients/android/NewsBlur/res/layout/include_comment.xml index 280d72827..34ec6ecf7 100644 --- a/clients/android/NewsBlur/res/layout/include_comment.xml +++ b/clients/android/NewsBlur/res/layout/include_comment.xml @@ -91,7 +91,7 @@ android:layout_toRightOf="@id/comment_user_image" android:textColor="@color/newsblur_blue" android:textSize="14sp" /> - + + + @@ -129,6 +142,6 @@ android:layout_width="match_parent" android:layout_height="1dp" android:layout_marginBottom="5dp" - android:background="#A6A6A6" /> + android:background="#F0F0F0" /> \ No newline at end of file diff --git a/clients/android/NewsBlur/res/layout/include_reading_item_comment.xml b/clients/android/NewsBlur/res/layout/include_reading_item_comment.xml index 6a1fcfbec..5638f15e5 100644 --- a/clients/android/NewsBlur/res/layout/include_reading_item_comment.xml +++ b/clients/android/NewsBlur/res/layout/include_reading_item_comment.xml @@ -5,7 +5,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" - android:layout_marginTop="15dp" > + android:layout_marginTop="15dp" + android:layout_marginBottom="15dp" >