Exemple #1
0
def get_menu():
    categories_order = [0]
    categories = {0: {'name': 'No category', 'id': 0}}
    for cat in CategoryController(g.user.id).read().order_by('name'):
        categories_order.append(cat.id)
        categories[cat.id] = cat.dump()
    unread = ArticleController(g.user.id).count_by_feed(readed=False)
    for cat_id in categories:
        categories[cat_id]['unread'] = 0
        categories[cat_id]['feeds'] = []
    feeds = {feed.id: feed.dump() for feed in FeedController(g.user.id).read()}
    for feed_id, feed in feeds.items():
        feed['created_stamp'] = timegm(feed['created_date'].timetuple()) * 1000
        feed['last_stamp'] = timegm(feed['last_retrieved'].timetuple()) * 1000
        feed['category_id'] = feed['category_id'] or 0
        feed['unread'] = unread.get(feed['id'], 0)
        if not feed['filters']:
            feed['filters'] = []
        if feed.get('icon_url'):
            feed['icon_url'] = url_for('icon.icon', url=feed['icon_url'])
        categories[feed['category_id']]['unread'] += feed['unread']
        categories[feed['category_id']]['feeds'].append(feed_id)
    return jsonify(
        **{
            'feeds': feeds,
            'categories': categories,
            'categories_order': categories_order,
            'crawling_method': conf.CRAWLING_METHOD,
            'max_error': conf.DEFAULT_MAX_ERROR,
            'error_threshold': conf.ERROR_THRESHOLD,
            'is_admin': g.user.is_admin(),
            'all_unread_count': sum(unread.values())
        })
Exemple #2
0
def get_menu():
    categories_order = [0]
    categories = {0: {'name': 'No category', 'id': 0}}
    for cat in CategoryController(current_user.id).read().order_by('name'):
        categories_order.append(cat.id)
        categories[cat.id] = cat
    unread = ArticleController(current_user.id).count_by_feed(readed=False)
    for cat_id in categories:
        categories[cat_id]['unread'] = 0
        categories[cat_id]['feeds'] = []
    feeds = {feed.id: feed for feed in FeedController(current_user.id).read()}
    for feed_id, feed in feeds.items():
        feed['created_stamp'] = timegm(feed.created_date.timetuple()) * 1000
        feed['last_stamp'] = timegm(feed.last_retrieved.timetuple()) * 1000
        feed['category_id'] = feed.category_id or 0
        feed['unread'] = unread.get(feed.id, 0)
        if not feed.filters:
            feed['filters'] = []
        if feed.icon_url:
            feed['icon_url'] = url_for('icon.icon', url=feed.icon_url)
        categories[feed['category_id']]['unread'] += feed['unread']
        categories[feed['category_id']]['feeds'].append(feed_id)
    return {'feeds': feeds, 'categories': categories,
            'categories_order': categories_order,
            'crawling_method': conf.CRAWLING_METHOD,
            'max_error': conf.DEFAULT_MAX_ERROR,
            'error_threshold': conf.ERROR_THRESHOLD,
            'is_admin': current_user.is_admin,
            'all_unread_count': sum(unread.values())}
Exemple #3
0
def populate_db():
    db_create()
    ucontr = UserController()
    ccontr = CategoryController()
    fcontr = FeedController()
    acontr = ArticleController()
    ccontr = CategoryController()
    user1, user2 = [ucontr.create(login=name, email="*****@*****.**" % name,
                                  password=name)
                    for name in ["user1", "user2"]]

    article_total = 0
    for user in (user1, user2):
        for i in range(3):
            cat_id = None
            if i:
                cat_id = ccontr.create(user_id=user.id,
                                       name="category%d" % i).id
            feed = fcontr.create(link="feed%d" % i, user_id=user.id,
                                    category_id=cat_id,
                                    title="%s feed%d" % (user.login, i))
            for j in range(3):
                entry = "%s %s article%d" % (user.login, feed.title, j)
                article_total += 1
                acontr.create(entry_id=entry,
                        link='http://test.te/%d' % article_total,
                        feed_id=feed.id, user_id=user.id, category_id=cat_id,
                        title=entry, content="content %d" % article_total)
Exemple #4
0
def home():
    """Displays the home page of the connected user.
    """
    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)

    filters = {}
    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):
        return "?filter_=%s&limit=%s&feed=%d&liked=%s" % (
            filter_,
            limit,
            feed,
            1 if liked else 0,
        )

    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,
    )
Exemple #5
0
def feeds():
    "Lists the subscribed  feeds in a table."
    art_contr = ArticleController(g.user.id)
    return render_template('feeds.html',
            feeds=FeedController(g.user.id).read(),
            unread_article_count=art_contr.count_by_feed(readed=False),
            article_count=art_contr.count_by_feed())
Exemple #6
0
def populate_db():
    db_create()
    ucontr = UserController()
    ccontr = CategoryController()
    fcontr = FeedController()
    acontr = ArticleController()
    ccontr = CategoryController()
    user1, user2 = [
        ucontr.create(login=name, email="*****@*****.**" % name, password=name)
        for name in ["user1", "user2"]
    ]

    article_total = 0
    for user in (user1, user2):
        for i in range(3):
            cat_id = None
            if i:
                cat_id = ccontr.create(user_id=user.id,
                                       name="category%d" % i).id
            feed = fcontr.create(link="feed%d" % i,
                                 user_id=user.id,
                                 category_id=cat_id,
                                 title="%s feed%d" % (user.login, i))
            for j in range(3):
                entry = "%s %s article%d" % (user.login, feed.title, j)
                article_total += 1
                acontr.create(entry_id=entry,
                              link='http://test.te/%d' % article_total,
                              feed_id=feed.id,
                              user_id=user.id,
                              category_id=cat_id,
                              title=entry,
                              content="content %d" % article_total)
Exemple #7
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(),
            unread_article_count=art_contr.count_by_feed(readed=False),
            article_count=art_contr.count_by_feed())
Exemple #8
0
def list_():
    "Lists the subscribed  feeds in a table."
    art_contr = ArticleController(g.user.id)
    return render_template('categories.html',
            categories=list(CategoryController(g.user.id).read()),
            feeds_count=FeedController(g.user.id).count_by_category(),
            unread_article_count=art_contr.count_by_category(readed=False),
            article_count=art_contr.count_by_category())
Exemple #9
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())
Exemple #10
0
def get_middle_panel():
    filters = _get_filters(request.args)
    art_contr = ArticleController(g.user.id)
    fd_hash = {feed.id: {'title': feed.title,
                         'icon_url': url_for('icon.icon', url=feed.icon_url)
                                     if feed.icon_url else None}
               for feed in FeedController(g.user.id).read()}
    articles = art_contr.read(**filters).order_by(Article.date.desc())
    return _articles_to_json(articles, fd_hash)
Exemple #11
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())
Exemple #12
0
def get_article(article_id):
    contr = ArticleController(g.user.id)
    article = contr.get(id=article_id).dump()
    if not article['readed']:
        contr.update({'id': article_id}, {'readed': True})
    article['category_id'] = article['category_id'] or 0
    feed = FeedController(g.user.id).get(id=article['feed_id'])
    article['icon_url'] = url_for('icon.icon', url=feed.icon_url) \
            if feed.icon_url else None
    return jsonify(**article)
Exemple #13
0
def get_article(article_id):
    contr = ArticleController(g.user.id)
    article = contr.get(id=article_id).dump()
    if not article['readed']:
        contr.update({'id': article_id}, {'readed': True})
    article['category_id'] = article['category_id'] or 0
    feed = FeedController(g.user.id).get(id=article['feed_id'])
    article['icon_url'] = url_for('icon.icon', url=feed.icon_url) \
            if feed.icon_url else None
    return jsonify(**article)
Exemple #14
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())
Exemple #15
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)
Exemple #16
0
 def test_article_get_unread(self):
     self.assertEquals({
         1: 3,
         2: 3,
         3: 3
     },
                       ArticleController(2).count_by_feed(readed=False))
     self.assertEquals({
         4: 3,
         5: 3,
         6: 3
     },
                       ArticleController(3).count_by_feed(readed=False))
Exemple #17
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
Exemple #18
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(g.user.id)

    query = art_contr.read(__or__={'date__lt': weeks_ago,
                                   'retrieved_date__lt': weeks_ago})
    count = query.count()
    query.delete()
    flash(gettext('%(count)d articles deleted', count=count), 'info')
    return redirect(redirect_url())
Exemple #19
0
def get_middle_panel():
    filters = _get_filters(request.args)
    art_contr = ArticleController(g.user.id)
    fd_hash = {
        feed.id: {
            'title':
            feed.title,
            'icon_url':
            url_for('icon.icon', url=feed.icon_url) if feed.icon_url else None
        }
        for feed in FeedController(g.user.id).read()
    }
    articles = art_contr.read(**filters).order_by(Article.date.desc())
    return _articles_to_json(articles, fd_hash)
Exemple #20
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
Exemple #21
0
def user(user_id=None):
    """
    See information about a user (stations, etc.).
    """
    user = UserController().get(id=user_id)
    if user is not None:
        article_contr = ArticleController(user_id)
        return render_template('/admin/user.html', user=user, feeds=user.feeds,
                article_count=article_contr.count_by_feed(),
                unread_article_count=article_contr.count_by_feed(readed=False))

    else:
        flash(gettext('This user does not exist.'), 'danger')
        return redirect(redirect_url())
Exemple #22
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 conf.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)
Exemple #23
0
async def insert_database(user, feed):

    articles = await parse_feed(user, feed)
    if None is articles:
        return []

    logger.debug('inserting articles for {}'.format(feed.title))

    logger.info("Database insertion...")
    new_articles = []
    art_contr = ArticleController(user.id)
    for article in articles:
        existing_article_req = art_contr.read(feed_id=feed.id,
                        **extract_id(article))
        exist = existing_article_req.count() != 0
        if exist:
            # if the article has been already retrieved, we only update
            # the content or the title
            logger.debug("Article %r (%r) already in the database.",
                         article['title'], article['link'])
            existing_article = existing_article_req.first()
            new_updated_date = None
            try:
                new_updated_date = dateutil.parser.parse(article['updated'])
            except Exception as e:
                print(e)#new_updated_date = existing_article.date
            if None is existing_article.updated_date:
                existing_article.updated_date = new_updated_date.replace(tzinfo=None)
            if existing_article.updated_date.strftime('%Y-%m-%dT%H:%M:%S') != \
                                new_updated_date.strftime('%Y-%m-%dT%H:%M:%S'):
                existing_article.updated_date = \
                                        new_updated_date.replace(tzinfo=None)
                if existing_article.title != article['title']:
                    existing_article.title = article['title']
                content = get_article_content(article)
                if existing_article.content != content:
                    existing_article.content = content
                    existing_article.readed = False
                art_contr.update({'entry_id': existing_article.entry_id},
                                                        existing_article.dump())
            continue
        article = construct_article(article, feed)
        try:
            new_articles.append(art_contr.create(**article))
            logger.info("New article % (%r) added.",
                        article['title'], article['link'])
        except Exception:
            logger.exception("Error when inserting article in database:")
            continue
    return new_articles
Exemple #24
0
async def insert_database(user, feed):
    articles = await parse_feed(user, feed)
    if None is articles:
        return []

    logger.info('Inserting articles for {}'.format(feed.title))

    new_articles = []
    art_contr = ArticleController(user.id)
    for article in articles:
        new_article = await construct_article(article, feed)

        try:
            existing_article_req = art_contr.read(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:
            # if the article has been already retrieved, we only update
            # the content or the title
            logger.info('Article already in the database: {}'. \
                            format(article['link']))
            existing_article = existing_article_req.first()

            if new_article['date'].replace(tzinfo=None) != \
                                                        existing_article.date:
                existing_article.date = new_article['date']
                existing_article.updated_date = new_article['date']
                if existing_article.title != new_article['title']:
                    existing_article.title = new_article['title']
                content = get_article_content(article)
                if existing_article.content != content:
                    existing_article.content = content
                    existing_article.readed = False
                art_contr.update({'entry_id': existing_article.entry_id},
                                                        existing_article.dump())
                logger.info('Article updated: {}'.format(article['link']))
            continue

        # insertion of the new article
        try:
            new_articles.append(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
    return new_articles
Exemple #25
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
Exemple #26
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'))
Exemple #27
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)
Exemple #28
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 conf.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)
Exemple #29
0
def feed_view(feed_id=None, user_id=None):
    feed = FeedController(user_id).get(id=feed_id)
    word_size = 6
    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="bootstrap3",
        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 as e:
        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,
    )
Exemple #30
0
 def test_feed_rights(self):
     cat = CategoryController(2).read()[0].dump()
     self.assertTrue(3,
             ArticleController().read(category_id=cat['id']).count())
     self.assertTrue(3,
             FeedController().read(category_id=cat['id']).count())
     self._test_controller_rights(cat,
             UserController().get(id=cat['user_id']))
Exemple #31
0
def article(article_id=None):
    """
    Presents the content of an article.
    """
    article = ArticleController(g.user.id).get(id=article_id)
    previous_article = article.previous_article()
    if previous_article is None:
        previous_article = article.source.articles[0]
    next_article = article.next_article()
    if next_article is None:
        next_article = article.source.articles[-1]

    return render_template('article.html',
                           head_titles=[clear_string(article.title)],
                           article=article,
                           previous_article=previous_article,
                           next_article=next_article)
Exemple #32
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_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="bootstrap3",
        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,
    )
Exemple #33
0
def article(article_id=None):
    """
    Presents an article.
    """
    article = ArticleController(current_user.id).get(id=article_id)
    return render_template('article.html',
                           head_titles=[clear_string(article.title)],
                           article=article)
Exemple #34
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:
                print('All producers done.')
                print('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
Exemple #35
0
 def test_feed_and_article_deletion(self):
     ccontr = CategoryController(2)
     cat = ccontr.read()[0].dump()
     ccontr.delete(cat['id'])
     self.assertEquals(0,
             ArticleController().read(category_id=cat['id']).count())
     self.assertEquals(0,
             FeedController().read(category_id=cat['id']).count())
Exemple #36
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())
Exemple #37
0
def user(user_id=None):
    """
    See information about a user (stations, etc.).
    """
    user = UserController().get(id=user_id)
    if user is not None:
        article_contr = ArticleController(user_id)
        return render_template(
            '/admin/user.html',
            user=user,
            feeds=FeedController().read(user_id=user_id).order_by('title'),
            article_count=article_contr.count_by_feed(),
            unread_article_count=article_contr.count_by_feed(readed=False))

    else:
        flash(gettext('This user does not exist.'), 'warn')
        return redirect(redirect_url())
Exemple #38
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
    readability_available = bool(current_user.readability_key
                                 or conf.PLUGINS_READABILITY_KEY)
    article['date'] = format_datetime(localize(article.date), locale=locale)
    article['readability_available'] = readability_available
    if parse or (not article.readability_parsed and feed.readability_auto_parse
                 and readability_available):
        try:
            new_content = readability.parse(
                article.link, current_user.readability_key
                or conf.PLUGINS_READABILITY_KEY)
        except Exception as error:
            flash("Readability failed with %r" % error, "error")
            article['readability_parsed'] = False
        else:
            article['readability_parsed'] = True
            article['content'] = clean_urls(new_content, article['link'])
            new_attr = {'readability_parsed': True, 'content': new_content}
            contr.update({'id': article['id']}, new_attr)
    return article
Exemple #39
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
Exemple #40
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 utils.allowed_file(data.filename):
                flash(gettext("File not allowed."), "danger")
            else:
                try:
                    nb = utils.import_opml(g.user.email, data.read())
                    if conf.CRAWLING_METHOD == "classic":
                        utils.fetch(g.user.email, 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 utils.allowed_file(data.filename):
                flash(gettext("File not allowed."), "danger")
            else:
                try:
                    nb = utils.import_json(g.user.email, 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(g.user.id).read().count()
    art_contr = ArticleController(g.user.id)
    nb_articles = art_contr.read().count()
    nb_unread_articles = art_contr.read(readed=False).count()
    return render_template(
        "management.html",
        user=g.user,
        nb_feeds=nb_feeds,
        nb_articles=nb_articles,
        nb_unread_articles=nb_unread_articles,
    )
Exemple #41
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)
Exemple #42
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"))
Exemple #43
0
def get_menu():
    now, locale = datetime.now(), get_locale()
    categories_order = [0]
    categories = {0: {'name': 'No category', 'id': 0}}
    for cat in CategoryController(current_user.id).read().order_by('name'):
        categories_order.append(cat.id)
        categories[cat.id] = cat
    unread = ArticleController(current_user.id).count_by_feed(readed=False)
    for cat_id in categories:
        categories[cat_id]['unread'] = 0
        categories[cat_id]['feeds'] = []
    feeds = {feed.id: feed for feed in FeedController(current_user.id).read()}
    for feed_id, feed in feeds.items():
        feed['created_rel'] = format_timedelta(feed.created_date - now,
                                               add_direction=True,
                                               locale=locale)
        feed['last_rel'] = format_timedelta(feed.last_retrieved - now,
                                            add_direction=True,
                                            locale=locale)
        feed['created_date'] = format_datetime(localize(feed.created_date),
                                               locale=locale)
        feed['last_retrieved'] = format_datetime(localize(feed.last_retrieved),
                                                 locale=locale)
        feed['category_id'] = feed.category_id or 0
        feed['unread'] = unread.get(feed.id, 0)
        if not feed.filters:
            feed['filters'] = []
        if feed.icon_url:
            feed['icon_url'] = url_for('icon.icon', url=feed.icon_url)
        categories[feed['category_id']]['unread'] += feed['unread']
        categories[feed['category_id']]['feeds'].append(feed_id)
    return {
        'feeds': feeds,
        'categories': categories,
        'categories_order': categories_order,
        'crawling_method': conf.CRAWLER_TYPE,
        'max_error': conf.FEED_ERROR_MAX,
        'error_threshold': conf.FEED_ERROR_THRESHOLD,
        'is_admin': current_user.is_admin,
        'all_unread_count': sum(unread.values())
    }
Exemple #44
0
async def insert_database(user, feed):

    articles = await parse_feed(user, feed)
    if None is articles:
        return []

    logger.debug('inserting articles for {}'.format(feed.title))

    logger.info("Database insertion...")
    new_articles = []
    art_contr = ArticleController(user.id)
    for article in articles:
        existing_article_req = art_contr.read(feed_id=feed.id,
                        **extract_id(article))
        exist = existing_article_req.count() != 0
        if exist:
            existing_article = existing_article_req.first()
            is_updated = False
            logger.debug("Article %r (%r) already in the database.",
                         article['title'], article['link'])
            content = get_article_content(article)
            if existing_article.title != article['title']:
                existing_article.title = article['title']
                is_updated = True
            if existing_article.content != content:
                existing_article.content = content
                existing_article.readed = False
                is_updated = True
            if is_updated:
                art_contr.update({'entry_id': existing_article.entry_id},
                                 existing_article.dump())
            continue
        article = construct_article(article, feed.dump())
        try:
            new_articles.append(art_contr.create(**article))
            logger.info("New article % (%r) added.",
                        article['title'], article['link'])
        except Exception:
            logger.exception("Error when inserting article in database:")
            continue
    return new_articles
Exemple #45
0
def mark_as(new_value='read', feed_id=None, article_id=None):
    """
    Mark all unreaded articles as read.
    """
    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('home')
Exemple #46
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"))
Exemple #47
0
def mark_as(new_value='read', feed_id=None, article_id=None):
    """
    Mark all unreaded articles as read.
    """
    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('home')
Exemple #48
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
    readability_available = bool(current_user.readability_key
                                 or conf.PLUGINS_READABILITY_KEY)
    article['date'] = format_datetime(localize(article.date), locale=locale)
    article['readability_available'] = readability_available
    if parse or (not article.readability_parsed
            and feed.readability_auto_parse and readability_available):
        try:
            new_content = readability.parse(article.link,
                    current_user.readability_key
                    or conf.PLUGINS_READABILITY_KEY)
        except Exception as error:
            flash("Readability failed with %r" % error, "error")
            article['readability_parsed'] = False
        else:
            article['readability_parsed'] = True
            article['content'] = clean_urls(new_content, article['link'])
            new_attr = {'readability_parsed': True, 'content': new_content}
            contr.update({'id': article['id']}, new_attr)
    return article
Exemple #49
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'))
Exemple #50
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_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='bootstrap3',
                            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)
Exemple #51
0
def get_menu():
    now, locale = datetime.now(), get_locale()
    categories_order = [0]
    categories = {0: {'name': 'No category', 'id': 0}}
    for cat in CategoryController(current_user.id).read().order_by('name'):
        categories_order.append(cat.id)
        categories[cat.id] = cat
    unread = ArticleController(current_user.id).count_by_feed(readed=False)
    for cat_id in categories:
        categories[cat_id]['unread'] = 0
        categories[cat_id]['feeds'] = []
    feeds = {feed.id: feed for feed in FeedController(current_user.id).read()}
    for feed_id, feed in feeds.items():
        feed['created_rel'] = format_timedelta(feed.created_date - now,
                add_direction=True, locale=locale)
        feed['last_rel'] = format_timedelta(feed.last_retrieved - now,
                add_direction=True, locale=locale)
        feed['created_date'] = format_datetime(localize(feed.created_date),
                                               locale=locale)
        feed['last_retrieved'] = format_datetime(localize(feed.last_retrieved),
                                                 locale=locale)
        feed['category_id'] = feed.category_id or 0
        feed['unread'] = unread.get(feed.id, 0)
        if not feed.filters:
            feed['filters'] = []
        if feed.icon_url:
            feed['icon_url'] = url_for('icon.icon', url=feed.icon_url)
        categories[feed['category_id']]['unread'] += feed['unread']
        categories[feed['category_id']]['feeds'].append(feed_id)
    return {'feeds': feeds, 'categories': categories,
            'categories_order': categories_order,
            'crawling_method': conf.CRAWLER_TYPE,
            'max_error': conf.FEED_ERROR_MAX,
            'error_threshold': conf.FEED_ERROR_THRESHOLD,
            'is_admin': current_user.is_admin,
            'all_unread_count': sum(unread.values())}
Exemple #52
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)
Exemple #53
0
 def execute(self):
     counts = ArticleController(ignore_context=True).count_by_user_id()
     print("articles.value %s" % sum(counts.values()))
     for user, count in counts.items():
         print("articles_user_%s.value %s" % (user, count))
Exemple #54
0
def get_middle_panel():
    filters = _get_filters(request.args)
    art_contr = ArticleController(current_user.id)
    articles = art_contr.read_light(**filters)
    return _articles_to_json(articles)
Exemple #55
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