def setUp(self): self.source = Source.objects.create(name='CNN-IBN Top Stories', link='http://www.ibnlive.com/xml/top.xml') self.user = NTUser.objects.create_user(name='Karthik', email='*****@*****.**', password='******') #A default tab will automatically be created with CNN-IBN Top Stories as the source self.tab = get_object_or_none(Tab, user=self.user, name='Headlines') if self.tab: self.tabsource = get_object_or_none(TabSource, tab=self.tab, source=self.source)
def remove_source(request, tab_id, source_name): logger.info("remove_source ajax request received(tab_id=%s, source_name=%s)" % (str(tab_id), str(source_name))) success = False tab = get_object_or_none(Tab, user=request.user, id=tab_id) if tab: source = get_object_or_none(Source, name=source_name) if source: if tab.delete_source(source): logger.debug("Removed %s from tab(%s)" % (str(source), str(tab))) success = True logger.info("Sending response(remove_source)") return simplejson.dumps({"success": success})
def get_tab_tags(request, tab_id): tab = get_object_or_none(Tab, id=tab_id, user=request.user) tags = [] if tab: tags = [tag.name for tag in tab.tags.all()] return simplejson.dumps({ "tags": tags })
def add_tag(self, tag_name): ''' Adds a tag to this article. If the tag already exists, it adds the tag to this article ''' tag = tag_name.strip().lower() db_tag = get_object_or_none(Tag, name=tag_name) if db_tag is not None: tag = db_tag self.tags.add(tag)
def change_source_priority(self, source, priority): ''' Changes the priority of the source to the specified priority. Returns the new priority is successful, None if unsuccessful ''' tabsource = get_object_or_none(TabSource, tab=self, source=source) if tabsource: tabsource = tabsource.change_priority(priority) self.clear_cache() return tabsource
def change_source_position(request, tab_id, source_name, position): logger.info( "change_source_position ajax request received(tab_id=%s, source_name=%s, position=%s)" % (str(tab_id), str(source_name), str(position)) ) success = False tab = get_object_or_none(Tab, user=request.user, id=tab_id) if tab: source = get_object_or_none(Source, name=source_name) if source: new_position = tab.change_source_priority(source, position) if new_position == position: logger.debug("%s position changed to %s" % (str(source), str(position))) success = True logger.info("Sending response(change_source_position") return simplejson.dumps({"success": success})
def delete_tag(request, tab_id, tag): success = False tab = get_object_or_none(Tab, id=tab_id, user=request.user) if tab: tab.delete_tag(tag) tab.save() success = True return simplejson.dumps({ "success": success })
def get_sources(request, tab_id): logger.info("get_sources ajax request received(tab_id=%s)" % str(tab_id)) source_names = [] tab = get_object_or_none(Tab, user=request.user, id=tab_id) if tab: source_names = [source.name for source in tab.get_sources()] logger.debug("Sources found: %s" % str(source_names)) logger.info("Sending response(get_sources)") return simplejson.dumps({"sources": source_names})
def change_tab_position(request, tab_id, position): logger.info("change_tab_position ajax request received(tab_id=%s, position=%s)" % (str(tab_id), str(position))) success = False tab = get_object_or_none(Tab, user=request.user, id=tab_id) if tab: if tab.change_order(position) == position: logger.debug("%s position changed to %s" % (str(tab), str(position))) success = True logger.info("Sending response(change_tab_position)") return simplejson.dumps({"success": success})
def test_multiple_tabs_integrity(self): ''' A user must have unique names for each tab. Name can not be left empty ''' #A user must have different names for each tab self.assertRaises(IntegrityError, Tab.objects.create_tab, user=self.user, name='Headlines') #Different users can have tabs with same names user = NTUser.objects.create_user(name='Divyansh', email='*****@*****.**', password='******') tab = get_object_or_none(Tab, user=user, name='Headlines') self.assertIsInstance(tab, Tab) #ValueError must be raised when trying to create a tab with no name self.assertRaises(ValueError, Tab.objects.create_tab, user=self.user, name='')
def delete_tab(request, tab_id): logger.info("delete_tab ajax request received(tab_id=%s)" % str(tab_id)) success = False tab = get_object_or_none(Tab, user=request.user, id=tab_id) if tab: tabsources = TabSource.objects.filter(tab=tab) tabsources.delete() tab.delete() logger.debug("%s tab deleted" % str(tab)) success = True logger.info("Sending response(delete_tab)") return simplejson.dumps({"success": success})
def reset_password(request): context = { 'form': True, #Shows the password-reset form 'verify_token': False, #If true, the operation is verify token, else send mail 'success': False, #If operation is successful, then True } if request.method == "POST": #POST request is done to send the password reset mail context['form'] = False email = request.POST.get('email', None) if email: user = get_object_or_none(NTUser, email=email) context['email'] = email #Send the email only if the user exists and is verified if user and user.verified: token = user.generate_password_reset_token() mail.send_reset_password_mail(str(user.name), str(user.email), str(token)) context['success'] = True elif request.method == "GET": #GET request is done to verify the token and reset user's password email = request.GET.get('email', None) token = request.GET.get('token', None) if email and token: context['form'] = False context['verify_token'] = True context['email'] = email user = get_object_or_none(NTUser, email=email) if user and user.get_password_reset_token() == token: context['token'] = token context['success'] = True #Token exists and valid. Let the user change the password return render(request, 'newsreader/reset-password.html', context)
def test_add_source(self): ''' add_source must associate the source with the tab. If the tab is none, no error must be displayed. The new source must automatically be assigned the last priority ''' #Adding an existing source returns None self.assertIsNone(self.tab.add_source(source=self.source)) #A new source should automatically have the lowest priority (highest number) source = Source.objects.create(name='Hindu', link='http://hindu.com') self.tab.add_source(source) tabsource = get_object_or_none(TabSource, tab=self.tab, source=source) self.assertEqual(tabsource.source_priority, self.tabsource.source_priority + 1) #Adding an empty source should not raise an exception self.assertIsNone(self.tab.add_source(None))
def test_order_number(self): ''' Tab order number must automatically increment when new tab is created. Changing the tab order must automatically reorder the rest ''' #Check auto-increment tab = Tab.objects.create_tab(user=self.user, name='Hello') self.assertEqual(tab.order, 2) #Check tab re-order self.assertEqual(tab.change_order(1), 1) c_tab = get_object_or_none(Tab, pk=self.tab.id) #Retreive the newly changed tab self.assertEqual(c_tab.order, 2) #Invalid order conditions must result in no change self.assertEqual(self.tab.change_order(100), self.tab.order) self.assertEqual(self.tab.change_order(0), self.tab.order)
def article(request, article_no=None, article_url=None): if not article_url or not article_no: raise Http404 article = get_object_or_none(Article, id=article_no) if not article: raise Http404 if not article_url == generate_seo_link(article.get_heading()): raise Http404 context = {} context['heading'] = article.get_heading() context['link'] = article.link article_viewed(request, article_no) return render(request, 'newsreader/article.html', context)
def default_tabs(sender, **kwargs): user = kwargs.get('instance', None) created = kwargs.get('created', None) #If it was a newly created record if created and user: #Create default tab logger.debug("Creating default tabs for user %s" % str(user)) tab = Tab.objects.create_tab(user=user, name='Headlines') source = get_object_or_none(Source, name='CNN-IBN Top Stories') if source: tab.add_source(source) logger.debug("Default tab created successfuly") logger.debug("Sending confirmation email to user %s" % str(user)) token = user.get_email_confirmation_token() mail.send_confirmation_mail(str(user.name), str(user.email), str(token)) logger.debug("Mail sent to %s" % str(user.email))
def change_password(request): token = request.POST.get('token', None) email = request.POST.get('email', None) password = request.POST.get('password', None) context = { 'password_changed': False } print "%s" % str(request) if token and email and password: user = get_object_or_none(NTUser, email=email) if user and user.get_password_reset_token() == token: user.set_password(password) user.save() user.delete_password_reset_token() context['password_changed'] = True return render(request, 'newsreader/change-password.html', context)
def update_feed(source): ''' Updates the feeds from source if it has not been updated for UPDATE_INTERVAL hours ''' logger.info("Checking if %s needs to be updated" % str(source)) #Get the last update time if source: last_update = source.last_update updated_articles = [] logger.debug("%s was last updated: %s" % (str(source), format_datetime(last_update))) #Update only if UPDATE_INTERVAL time has elapse since the last update if not last_update or timedelta(datetime.now(tzlocal()), last_update) >= timedelta(hours=UPDATE_INTERVAL): logger.info("Updating source %s" % str(source)) feed = fp.parse(source.link) for entry in feed.get('entries'): #Try parsing the date and if it thows an exception, default to the current date try: pub_date = date.parse(entry.get('published'), default=datetime.now(tzlocal())) except: pub_date = datetime.now(tzlocal()) link = entry.get('link') heading = entry.get('title') summary = entry.get('summary_detail').get('value') logger.debug("Parsed article: %s" % u''.join(heading).encode('utf-8').strip()) #Check if article has already been added. article = get_object_or_none(Article, link=link) if not article: try: logger.debug("Article not found in database. Adding to database") article = Article.objects.create(pub_date=pub_date, link=link, source=source, heading=heading, summary=summary) article.tag_self() updated_articles.append(article) except Exception, e: logger.exception(e) #Update the last update time of this source source.last_update = datetime.now(tzlocal()) source.save() logger.info("No of articles updated: %d" % len(updated_articles))
def test_change_tab_position(self): ''' change_tab_position changes the order of the tabs. Invalid requests must be ignored ''' #Anonymous user test response = dajaxice_post(self.client, 'newsreader', 'change_tab_position', {'tab_id': self.tabs[0].id, 'position': 2}) self.assertFalse(json.loads(response.content)['success']) #Logged in user self.client.login(email=self.user_email, password=self.user_pass) response = dajaxice_post(self.client, 'newsreader', 'change_tab_position', {'tab_id': self.tabs[0].id, 'position': 2}) self.assertTrue(json.loads(response.content)['success']) self.assertTrue(get_object_or_none(Tab, pk=self.tabs[0].id).order, 2) #Invalid tab id response = dajaxice_post(self.client, 'newsreader', 'change_tab_position', {'tab_id': 100, 'position': 2}) self.assertFalse(json.loads(response.content)['success']) #Invalid position response = dajaxice_post(self.client, 'newsreader', 'change_tab_position', {'tab_id': self.tabs[0].id, 'position': 0}) self.assertFalse(json.loads(response.content)['success']) response = dajaxice_post(self.client, 'newsreader', 'change_tab_position', {'tab_id': self.tabs[0].id, 'position': 100}) self.assertFalse(json.loads(response.content)['success'])
def get_content(user, tab_id): ''' Returns a list of articles. Loads from cache if available. ''' logger.info("Retrieving content for tab_id %s" % int(tab_id)) #Try finding articles in cache cache_key = "tab_cache" + str(user.id) + str(tab_id) articles = cache.get(cache_key, []) logger.debug("No of articles found in cache: %d (cache_key=%s)" % (len(articles), cache_key)) #If the articles are not found in the cache, then retreive the articles if not articles: logger.info("Trying to retrieve articles from database") tab = get_object_or_none(Tab, id=tab_id, user=user) articles = [] tagged_articles = [] if tab is not None: logger.debug("Tab found: %s. Getting sources and tags" % str(tab)) #Get all the sources and tags in the tab sources = tab.get_sources() #This makes sure that the articles are arranged in order of source priority tags = tab.tags.all() logger.debug("Sources: %s, Tags: %s" % (str(sources), str(tags))) #For each source, retrieve the articles for source in sources: logger.debug("Retrieving articles for source: %s" % str(source)) #Make sure the source has the latest feeds update_feed(source) source_articles = Article.objects.filter(source=source, pub_date__gt=datetime.now(tzlocal())-delta(days=1)).order_by('-pub_date') logger.debug("No of source articles found: %d" % len(source_articles)) #If tags are specified, filter articles with tags if tags: logger.debug("Filtering articles based on the tags") tagged_articles_in_source = source_articles.filter(tags__in=tags).distinct() tagged_articles += tagged_articles_in_source # source_articles -= tagged_articles_in_source temp_articles = [] temp_articles += source_articles for t_article in tagged_articles_in_source: temp_articles.remove(t_article) logger.debug("No of tagged articles: %s" % len(tagged_articles)) articles += temp_articles else: articles += source_articles articles = tagged_articles+articles logger.info("No of articles retrieved: %d" % len(articles)) logger.info("Adding articles to cache") #add the articles to cache cache.add(cache_key, articles, CACHE_EXPIRES) return articles