def like(article_id=None): """ Mark or unmark an article as favorites. """ art_contr = ArticleController(current_user.id) article = art_contr.get(id=article_id) art_contr = art_contr.update({"id": article_id}, {"like": not article.like}) return redirect(redirect_url())
def feeds(): "Lists the subscribed feeds in a table." art_contr = ArticleController(current_user.id) return render_template( "feeds.html", feeds=FeedController(current_user.id).read().order_by("title"), unread_article_count=art_contr.count_by_feed(readed=False), article_count=art_contr.count_by_feed(), )
def list_(): "Lists the subscribed feeds in a table." art_contr = ArticleController(current_user.id) return render_template( "categories.html", categories=list( CategoryController(current_user.id).read().order_by("name")), feeds_count=FeedController(current_user.id).count_by_category(), unread_article_count=art_contr.count_by_category(readed=False), article_count=art_contr.count_by_category(), )
def article(article_id=None): """ Presents an article. """ art_contr = ArticleController(current_user.id) article = art_contr.get(id=article_id) if not article.readed: art_contr.update({"id": article.id}, {"readed": True}) return render_template("article.html", head_titles=[clear_string(article.title)], article=article)
def management(): """ Display the management page. """ if request.method == "POST": if None != request.files.get("opmlfile", None): # Import an OPML file data = request.files.get("opmlfile", None) if not misc_utils.allowed_file(data.filename): flash(gettext("File not allowed."), "danger") else: try: nb = import_opml(current_user.nickname, data.read()) if application.config["CRAWLING_METHOD"] == "classic": misc_utils.fetch(current_user.id, None) flash( str(nb) + " " + gettext("feeds imported."), "success") flash(gettext("Downloading articles..."), "info") except: flash(gettext("Impossible to import the new feeds."), "danger") elif None != request.files.get("jsonfile", None): # Import an account data = request.files.get("jsonfile", None) if not misc_utils.allowed_file(data.filename): flash(gettext("File not allowed."), "danger") else: try: nb = import_json(current_user.nickname, data.read()) flash(gettext("Account imported."), "success") except: flash(gettext("Impossible to import the account."), "danger") else: flash(gettext("File not allowed."), "danger") nb_feeds = FeedController(current_user.id).read().count() art_contr = ArticleController(current_user.id) nb_articles = art_contr.read().count() nb_unread_articles = art_contr.read(readed=False).count() nb_categories = CategoryController(current_user.id).read().count() nb_bookmarks = BookmarkController(current_user.id).read().count() return render_template( "management.html", user=current_user, nb_feeds=nb_feeds, nb_articles=nb_articles, nb_unread_articles=nb_unread_articles, nb_categories=nb_categories, nb_bookmarks=nb_bookmarks, )
def get_article(article_id, parse=False): locale = get_locale() contr = ArticleController(current_user.id) article = contr.get(id=article_id) if not article.readed: article["readed"] = True contr.update({"id": article_id}, {"readed": True}) article["category_id"] = article.category_id or 0 feed = FeedController(current_user.id).get(id=article.feed_id) article["icon_url"] = ( url_for("icon.icon", url=feed.icon_url) if feed.icon_url else None ) article["date"] = format_datetime(localize(article.date), locale=locale) return article
def history(year=None, month=None): cntr, artcles = ArticleController(current_user.id).get_history(year, month) return render_template("history.html", articles_counter=cntr, articles=artcles, year=year, month=month)
def feed_view(feed_id=None, user_id=None): feed = FeedController(user_id).get(id=feed_id) category = None if feed.category_id: category = CategoryController(user_id).get(id=feed.category_id) filters = {} filters["feed_id"] = feed_id articles = ArticleController(user_id).read_light(**filters) # Server-side pagination page, per_page, offset = get_page_args(per_page_parameter="per_page") pagination = Pagination( page=page, total=articles.count(), css_framework="bootstrap4", search=False, record_name="articles", per_page=per_page, ) today = datetime.now() try: last_article = articles[0].date first_article = articles[-1].date delta = last_article - first_article average = round(float(articles.count()) / abs(delta.days), 2) except Exception: last_article = datetime.fromtimestamp(0) first_article = datetime.fromtimestamp(0) delta = last_article - first_article average = 0 elapsed = today - last_article return render_template( "feed.html", head_titles=[utils.clear_string(feed.title)], feed=feed, category=category, articles=articles.offset(offset).limit(per_page), pagination=pagination, first_post_date=first_article, end_post_date=last_article, average=average, delta=delta, elapsed=elapsed, )
def expire(): """ Delete articles older than the given number of weeks. """ current_time = datetime.utcnow() weeks_ago = current_time - timedelta(int(request.args.get("weeks", 10))) art_contr = ArticleController(current_user.id) query = art_contr.read(__or__={ "date__lt": weeks_ago, "retrieved_date__lt": weeks_ago }) count = query.count() query.delete() db.session.commit() flash(gettext("%(count)d articles deleted", count=count), "info") return redirect(redirect_url())
def user_stream(per_page, nickname=None): """ Display the stream of a user (list of articles of public feed). """ user_contr = UserController() user = user_contr.get(nickname=nickname) if not user.is_public_profile: if current_user.is_authenticated and current_user.id == user.id: flash(gettext("You must set your profile to public."), "info") return redirect(url_for("user.profile")) category_id = int(request.args.get("category_id", 0)) category = CategoryController().read(id=category_id).first() # Load the public feeds filters = {} filters["private"] = False if category_id: filters["category_id"] = category_id feeds = FeedController().read(**filters).all() # Re-initializes the filters to load the articles filters = {} filters["feed_id__in"] = [feed.id for feed in feeds] if category: filters["category_id"] = category_id articles = ArticleController(user.id).read_ordered(**filters) # Server-side pagination page, per_page, offset = get_page_args(per_page_parameter="per_page") pagination = Pagination( page=page, total=articles.count(), css_framework="bootstrap4", search=False, record_name="articles", per_page=per_page, ) return render_template( "user_stream.html", user=user, articles=articles.offset(offset).limit(per_page), category=category, pagination=pagination, )
def history(user_id, year=None, month=None): """ Sort articles by year and month. """ articles_counter = Counter() articles = ArticleController(user_id).read() if None != year: articles = articles.filter( sqlalchemy.extract("year", "Article.date") == year) if None != month: articles = articles.filter( sqlalchemy.extract("month", "Article.date") == month) for article in articles.all(): if None != year: articles_counter[article.date.month] += 1 else: articles_counter[article.date.year] += 1 return articles_counter, articles
async def insert_articles(queue, nḅ_producers=1): """Consumer coroutines. """ nb_producers_done = 0 while True: item = await queue.get() if item is None: nb_producers_done += 1 if nb_producers_done == nḅ_producers: logger.info("All producers done.") logger.info("Process finished.") break continue user, feed, articles = item if None is articles: logger.info("None") articles = [] logger.info("Inserting articles for {}".format(feed.link)) art_contr = ArticleController(user.id) for article in articles: new_article = await construct_article(article, feed) try: existing_article_req = art_contr.read( user_id=user.id, feed_id=feed.id, entry_id=extract_id(article) ) except Exception as e: logger.exception("existing_article_req: " + str(e)) continue exist = existing_article_req.count() != 0 if exist: continue # insertion of the new article try: art_contr.create(**new_article) logger.info("New article added: {}".format(new_article["link"])) except Exception: logger.exception("Error when inserting article in database.") continue
def delete(article_id=None): """ Delete an article from the database. """ article = ArticleController(current_user.id).delete(article_id) flash( gettext("Article %(article_title)s deleted", article_title=article.title), "success", ) return redirect(url_for("home"))
def article_pub(article_id=None): """ Presents an article of a public feed if the profile of the owner is also public. """ article = ArticleController().get(id=article_id) if article.source.private or not article.source.user.is_public_profile: return render_template("errors/404.html"), 404 return render_template("article_pub.html", head_titles=[clear_string(article.title)], article=article)
def mark_as(new_value="read", feed_id=None, article_id=None): """ Mark a single article or all articles of a feed as read/unread. """ readed = new_value == "read" art_contr = ArticleController(current_user.id) filters = {"readed": not readed} if feed_id is not None: filters["feed_id"] = feed_id message = "Feed marked as %s." elif article_id is not None: filters["id"] = article_id message = "Article marked as %s." else: message = "All article marked as %s." art_contr.update(filters, {"readed": readed}) flash(gettext(message % new_value), "info") # if readed: # return redirect(redirect_url()) return redirect(url_for("home"))
def update(action, feed_id=None): readed = action == "read" filters = {"readed__ne": readed} nb_days = request.args.get("nb_days", 0, type=int) if nb_days != 0: filters["date__lt"] = datetime.now() - timedelta(days=nb_days) if feed_id: filters["feed_id"] = feed_id ArticleController(current_user.id).update(filters, {"readed": readed}) flash(gettext("Feed successfully updated."), "success") return redirect(request.referrer or url_for("home"))
def delete_read_articles(): "Delete read articles retrieved since more than 5 days ago." filter = {} filter["user_id__ne"] = 1 #filter["readed"] = True # temporary comment filter["retrieved_date__lt"] = date.today() - relativedelta(days=5) articles = ArticleController().read(**filter).limit(5000) for article in articles: try: db.session.delete(article) db.session.commit() except: db.session.rollback() print("Read articles deleted.")
def redirect_to_article(article_id): contr = ArticleController(current_user.id) article = contr.get(id=article_id) if not article.readed: contr.update({"id": article.id}, {"readed": True}) return redirect(article.link)
def mark_all_as_read(): filters = _get_filters(request.json) acontr = ArticleController(current_user.id) processed_articles = _articles_to_json(acontr.read_light(**filters)) acontr.update(filters, {"readed": True}) return processed_articles
def home(): """Displays the home page of the connected user. """ filters = _get_filters(request.args) art_contr = ArticleController(current_user.id) unread = art_contr.count_by_feed(readed=False) nb_unread = art_contr.read_light(readed=False).count() feeds = { feed.id: feed for feed in sorted( current_user.feeds, key=lambda x: x.title.lower(), reverse=False ) } filter_ = request.args.get("filter_", "unread") feed_id = int(request.args.get("feed", 0)) liked = int(request.args.get("liked", 0)) == 1 limit = request.args.get("limit", 1000) query = request.args.get("query", "") search_title = request.args.get("search_title", "off") search_content = request.args.get("search_content", "off") if filter_ in ["read", "unread"]: filters["readed"] = filter_ == "read" if feed_id: filters["feed_id"] = feed_id if liked: filters["like"] = int(liked) == 1 articles = art_contr.read_ordered(**filters) if limit != "all": limit = int(limit) articles = articles.limit(limit) in_error = { feed.id: feed.error_count for feed in FeedController(current_user.id).read(error_count__gt=0).all() } def gen_url( filter_=filter_, limit=limit, feed=feed_id, liked=liked, query=query, search_title=search_title, search_content=search_content, ): return ( "?filter_=%s&limit=%s&feed=%d&liked=%s&query=%s&search_title=%s&search_content=%s" % ( filter_, limit, feed, 1 if liked else 0, query, search_title, search_content, ) ) return render_template( "home.html", nb_unread=nb_unread, gen_url=gen_url, feed_id=feed_id, filter_=filter_, limit=limit, feeds=feeds, liked=liked, unread=dict(unread), articles=articles.all(), in_error=in_error, )