~cedric/newspipe

5b32fab4e13a7924b1561b6af6f583c2aedc6955 — Cédric Bonhomme 1 year, 1 month ago 667d59b + e547063
Merge branch 'master' of git.sr.ht:~cedric/newspipe
M README.md => README.md +2 -0
@@ 6,6 6,8 @@

[Newspipe](https://git.sr.ht/~cedric/newspipe) is a web news aggregator.

![Newspipe Home page](docs/static/newspipe_home-page.png "Newspipe Home page")

Newspipe is written in Python. The core technologies are
[Flask](http://flask.pocoo.org),
[asyncio](https://www.python.org/dev/peps/pep-3156/) and

A docs/static/newspipe_home-page.png => docs/static/newspipe_home-page.png +0 -0
M newspipe/bootstrap.py => newspipe/bootstrap.py +0 -1
@@ 45,7 45,6 @@ def set_logging(
        logger.setLevel(log_level)



# Create Flask application
application = Flask(__name__, instance_relative_config=True)
if os.environ.get("Newspipe_TESTING", False) == "true":

M newspipe/crawler/default_crawler.py => newspipe/crawler/default_crawler.py +1 -1
@@ 39,7 39,7 @@ from newspipe.controllers import ArticleController, FeedController
from newspipe.lib.article_utils import (
    construct_article,
    extract_id,
    get_article_content
    get_article_content,
)
from newspipe.lib.feed_utils import construct_feed_from, is_parsing_ok
from newspipe.lib.utils import newspipe_get

M newspipe/models/__init__.py => newspipe/models/__init__.py +1 -3
@@ 32,7 32,7 @@ from sqlalchemy.schema import (
    DropTable,
    ForeignKeyConstraint,
    MetaData,
    Table
    Table,
)

from .article import Article


@@ 57,8 57,6 @@ __all__ = [
]




def db_empty(db):
    "Will drop every datas stocked in db."
    # From http://www.sqlalchemy.org/trac/wiki/UsageRecipes/DropEverything

M newspipe/templates/home.html => newspipe/templates/home.html +7 -3
@@ 38,8 38,8 @@
            <li class="nav-item feed-commands"><span class="nav-link">
                <a href="/feed/{{ fid }}"><i class="fa fa-info" aria-hidden="true" title="{{ _('Details') }}"></i></a>
                <a href="{{ url_for('feed.form', feed_id=fid) }}"><i class="fa fa-pencil-square-o" aria-hidden="true" title="{{ _('Edit this feed') }}"></i></a>
                <a href="{{ url_for('article.mark_as', new_value='read', feed_id=fid) }}"><i class="fa fa-check-square-o" aria-hidden="true" title="{{ _('Mark this feed as read') }}"></i></a>
                <a href="{{ url_for('article.mark_as', new_value='unread', feed_id=fid) }}"><i class="fa fa-square-o" aria-hidden="true" title="{{ _('Mark this feed as unread') }}"></i></a>
                <a href="{{ url_for('article.mark_as', new_value='read', feed_id=fid) }}"><i class="fa fa-check-square-o" aria-hidden="true" title="{{ _('Mark this feed as read') }}"></i></a>
                <a href="{{ url_for('feed.delete', feed_id=fid) }}"><i class="fa fa-times" aria-hidden="true" title="{{ _('Delete this feed') }}" onclick="return confirm('{{ _('You are going to delete this feed.') }}');"></i></a>
            </span></li>
        {% endfor %}


@@ 57,8 57,8 @@
            <li class="nav-item feed-commands"><span class="nav-link">
                <a href="/feed/{{ fid }}"><i class="fa fa-info" aria-hidden="true" title="{{ _('Details') }}"></i></a>
                <a href="{{ url_for('feed.form', feed_id=fid) }}"><i class="fa fa-pencil-square-o" aria-hidden="true" title="{{ _('Edit this feed') }}"></i></a>
                <a href="{{ url_for('article.mark_as', new_value='read', feed_id=fid) }}"><i class="fa fa-check-square-o" aria-hidden="true" title="{{ _('Mark this feed as read') }}"></i></a>
                <a href="{{ url_for('article.mark_as', new_value='unread', feed_id=fid) }}"><i class="fa fa-square-o" aria-hidden="true" title="{{ _('Mark this feed as unread') }}"></i></a>
                <a href="{{ url_for('article.mark_as', new_value='read', feed_id=fid) }}"><i class="fa fa-check-square-o" aria-hidden="true" title="{{ _('Mark this feed as read') }}"></i></a>
                <a href="{{ url_for('feed.delete', feed_id=fid) }}"><i class="fa fa-times" aria-hidden="true" title="{{ _('Delete this feed') }}" onclick="return confirm('{{ _('You are going to delete this feed.') }}');"></i></a>
            </span></li>
        {% endfor %}


@@ 94,7 94,11 @@
                <table class="table table-striped strict-table">
                    <thead>
                        <tr>
                            <th></th>
                            <th>
                                {% if feed_id %}
                                    <a href="{{ url_for('article.mark_as', new_value='read', feed_id=feed_id) }}"><i class="fa fa-check-square-o" aria-hidden="true" title="{{ _('Mark this feed as read') }}"></i></a>
                                {% endif%}
                            </th>
                            <th>{{ _('Feed') }}</th>
                            <th>{{ _('Article') }}</th>
                            <th>{{ _('Date') }}</th>

M newspipe/web/forms.py => newspipe/web/forms.py +1 -1
@@ 39,7 39,7 @@ from wtforms import (
    SubmitField,
    TextAreaField,
    TextField,
    validators
    validators,
)
from wtforms.fields.html5 import EmailField, URLField


M newspipe/web/views/api/v2/article.py => newspipe/web/views/api/v2/article.py +1 -1
@@ 10,7 10,7 @@ from newspipe.web.views.api.v2.common import (
    PyAggAbstractResource,
    PyAggResourceExisting,
    PyAggResourceMulti,
    PyAggResourceNew
    PyAggResourceNew,
)
from newspipe.web.views.common import api_permission


M newspipe/web/views/api/v2/category.py => newspipe/web/views/api/v2/category.py +1 -1
@@ 6,7 6,7 @@ from newspipe.controllers.category import CategoryController
from newspipe.web.views.api.v2.common import (
    PyAggResourceExisting,
    PyAggResourceMulti,
    PyAggResourceNew
    PyAggResourceNew,
)



M newspipe/web/views/api/v2/common.py => newspipe/web/views/api/v2/common.py +1 -1
@@ 31,7 31,7 @@ from newspipe.web.views.common import (
    admin_permission,
    api_permission,
    jsonify,
    login_user_bundle
    login_user_bundle,
)

logger = logging.getLogger(__name__)

M newspipe/web/views/api/v2/feed.py => newspipe/web/views/api/v2/feed.py +2 -6
@@ 2,16 2,12 @@ from flask import current_app
from flask_restful import Api

from newspipe.bootstrap import application
from newspipe.controllers.feed import (
    DEFAULT_LIMIT,
    DEFAULT_MAX_ERROR,
    FeedController
)
from newspipe.controllers.feed import DEFAULT_LIMIT, DEFAULT_MAX_ERROR, FeedController
from newspipe.web.views.api.v2.common import (
    PyAggAbstractResource,
    PyAggResourceExisting,
    PyAggResourceMulti,
    PyAggResourceNew
    PyAggResourceNew,
)
from newspipe.web.views.common import api_permission


M newspipe/web/views/article.py => newspipe/web/views/article.py +2 -6
@@ 8,17 8,13 @@ from flask import (
    redirect,
    render_template,
    request,
    url_for
    url_for,
)
from flask_babel import gettext
from flask_login import current_user, login_required

from newspipe.bootstrap import db
from newspipe.controllers import (
    ArticleController,
    CategoryController,
    UserController
)
from newspipe.controllers import ArticleController, CategoryController, UserController
from newspipe.lib.data import export_json
from newspipe.lib.utils import clear_string, redirect_url
from newspipe.web.lib.view_utils import etag_match

M newspipe/web/views/bookmark.py => newspipe/web/views/bookmark.py +1 -1
@@ 35,7 35,7 @@ from flask import (
    redirect,
    render_template,
    request,
    url_for
    url_for,
)
from flask_babel import gettext
from flask_login import current_user, login_required

M newspipe/web/views/category.py => newspipe/web/views/category.py +1 -5
@@ 2,11 2,7 @@ from flask import Blueprint, flash, redirect, render_template, url_for
from flask_babel import gettext
from flask_login import current_user, login_required

from newspipe.controllers import (
    ArticleController,
    CategoryController,
    FeedController
)
from newspipe.controllers import ArticleController, CategoryController, FeedController
from newspipe.lib.utils import redirect_url
from newspipe.web.forms import CategoryForm
from newspipe.web.lib.view_utils import etag_match

M newspipe/web/views/common.py => newspipe/web/views/common.py +1 -1
@@ 9,7 9,7 @@ from flask_principal import (
    Permission,
    RoleNeed,
    identity_changed,
    session_identity_loader
    session_identity_loader,
)

from newspipe.controllers import UserController

M newspipe/web/views/feed.py => newspipe/web/views/feed.py +2 -2
@@ 9,7 9,7 @@ from flask import (
    redirect,
    render_template,
    request,
    url_for
    url_for,
)
from flask_babel import gettext
from flask_login import current_user, login_required


@@ 21,7 21,7 @@ from newspipe.controllers import (
    ArticleController,
    CategoryController,
    FeedController,
    UserController
    UserController,
)
from newspipe.lib import misc_utils, utils
from newspipe.lib.feed_utils import construct_feed_from

M newspipe/web/views/home.py => newspipe/web/views/home.py +25 -19
@@ 3,23 3,12 @@ from datetime import datetime

import pytz
from babel.dates import format_datetime, format_timedelta
from flask import (
    current_app,
    flash,
    redirect,
    render_template,
    request,
    url_for
)
from flask import current_app, flash, redirect, render_template, request, url_for
from flask_babel import get_locale, gettext
from flask_login import current_user, login_required

from newspipe.bootstrap import application
from newspipe.controllers import (
    ArticleController,
    CategoryController,
    FeedController
)
from newspipe.controllers import ArticleController, CategoryController, FeedController
from newspipe.lib import misc_utils
from newspipe.lib.utils import redirect_url
from newspipe.web.lib.view_utils import etag_match


@@ 52,6 41,9 @@ def home():
    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"


@@ 71,12 63,26 @@ def home():
        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,
    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(

M newspipe/web/views/session_mgmt.py => newspipe/web/views/session_mgmt.py +2 -2
@@ 8,7 8,7 @@ from flask import (
    render_template,
    request,
    session,
    url_for
    url_for,
)
from flask_babel import gettext, lazy_gettext
from flask_login import LoginManager, current_user, login_required, logout_user


@@ 18,7 18,7 @@ from flask_principal import (
    UserNeed,
    identity_changed,
    identity_loaded,
    session_identity_loader
    session_identity_loader,
)
from werkzeug.security import generate_password_hash


M newspipe/web/views/user.py => newspipe/web/views/user.py +2 -10
@@ 1,12 1,4 @@
from flask import (
    Blueprint,
    flash,
    g,
    redirect,
    render_template,
    request,
    url_for
)
from flask import Blueprint, flash, g, redirect, render_template, request, url_for
from flask_babel import gettext
from flask_login import current_user, login_required
from flask_paginate import Pagination, get_page_args


@@ 17,7 9,7 @@ from newspipe.controllers import (
    BookmarkController,
    CategoryController,
    FeedController,
    UserController
    UserController,
)
from newspipe.lib import misc_utils
from newspipe.lib.data import import_json, import_opml

M newspipe/web/views/views.py => newspipe/web/views/views.py +1 -8
@@ 3,14 3,7 @@ import operator
import sys
from datetime import datetime, timedelta

from flask import (
    current_app,
    flash,
    redirect,
    render_template,
    request,
    url_for
)
from flask import current_app, flash, redirect, render_template, request, url_for
from flask_babel import gettext
from sqlalchemy import desc