Exemplo n.º 1
0
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())
Exemplo n.º 2
0
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(),
    )
Exemplo n.º 3
0
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(),
    )
Exemplo n.º 4
0
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)
Exemplo n.º 5
0
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,
    )
Exemplo n.º 6
0
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
Exemplo n.º 7
0
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)
Exemplo n.º 8
0
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,
    )
Exemplo n.º 9
0
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())
Exemplo n.º 10
0
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,
    )
Exemplo n.º 11
0
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
Exemplo n.º 12
0
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
Exemplo n.º 13
0
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"))
Exemplo n.º 14
0
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)
Exemplo n.º 15
0
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"))
Exemplo n.º 16
0
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"))
Exemplo n.º 17
0
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.")
Exemplo n.º 18
0
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)
Exemplo n.º 19
0
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
Exemplo n.º 20
0
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,
    )