1d2a7fbce2abcde13b9741d7fa6ec83c074b7c0a — Cédric Bonhomme 4 years ago 012b2d0
Removed prototype code for bookmarks from master branch.
10 files changed, 15 insertions(+), 220 deletions(-)

M src/runserver.py
M src/web/controllers/__init__.py
D src/web/controllers/bookmark.py
M src/web/models/__init__.py
M src/web/models/article.py
D src/web/models/bookmark.py
M src/web/models/tag.py
M src/web/models/user.py
M src/web/views/__init__.py
D src/web/views/bookmark.py
M src/runserver.py => src/runserver.py +0 -2
@@ 56,8 56,6 @@ with application.app_context():

if __name__ == '__main__':

M src/web/controllers/__init__.py => src/web/controllers/__init__.py +1 -2
@@ 3,8 3,7 @@ from .category import CategoryController
from .article import ArticleController
from .user import UserController
from .icon import IconController
from .bookmark import BookmarkController

__all__ = ['FeedController', 'CategoryController', 'ArticleController',
           'UserController', 'IconController', 'BookmarkController']
           'UserController', 'IconController']

D src/web/controllers/bookmark.py => src/web/controllers/bookmark.py +0 -20
@@ 1,20 0,0 @@
import logging
import itertools
from datetime import datetime, timedelta

from bootstrap import db
from .abstract import AbstractController
from web.models import Bookmark

logger = logging.getLogger(__name__)

class BookmarkController(AbstractController):
    _db_cls = Bookmark

    def count_by_href(self, **filters):
        return self._count_by(Bookmark.href, filters)

    def update(self, filters, attrs, *args, **kwargs):
        #self.tag_objs = attrs['tags']
        return super().update(filters, attrs, *args, **kwargs)

M src/web/models/__init__.py => src/web/models/__init__.py +2 -6
@@ 32,13 32,9 @@ from .user import User
from .article import Article
from .icon import Icon
from .category import Category
#from .tag import Tag
from .tag import BookmarkTag
from .tag import ArticleTag
from .bookmark import Bookmark
from .tag import Tag

__all__ = ['Feed', 'Role', 'User', 'Article', 'Icon', 'Category', 'Tag',
            'Bookmark', 'ArticleTag', 'BookmarkTag']
__all__ = ['Feed', 'Role', 'User', 'Article', 'Icon', 'Category', 'Tag']

import os

M src/web/models/article.py => src/web/models/article.py +4 -6
@@ 34,8 34,6 @@ from sqlalchemy.ext.associationproxy import association_proxy
from web.models.right_mixin import RightMixin

class Article(db.Model, RightMixin):
    "Represent an article from a feed."
    id = db.Column(db.Integer(), primary_key=True)

@@ 54,10 52,10 @@ class Article(db.Model, RightMixin):
    category_id = db.Column(db.Integer(), db.ForeignKey('category.id'))

    # relationships
    tag_objs = db.relationship('ArticleTag', back_populates='article',
    tag_objs = db.relationship('Tag', back_populates='article',
    tags = association_proxy('tag_objs', 'text')

    # index

D src/web/models/bookmark.py => src/web/models/bookmark.py +0 -75
@@ 1,75 0,0 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-

# Newspipe - A Web based news aggregator.
# Copyright (C) 2010-2016  Cédric Bonhomme - https://www.cedricbonhomme.org
# For more information : https://github.com/newspipe/newspipe
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# GNU Affero General Public License for more details.
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

__author__ = "Cedric Bonhomme"
__version__ = "$Revision: 0.1 $"
__date__ = "$Date: 2016/12/07 $"
__revision__ = "$Date: 2016/12/07 $"
__copyright__ = "Copyright (c) Cedric Bonhomme"
__license__ = "GPLv3"

from bootstrap import db
from datetime import datetime
from sqlalchemy.orm import validates
from sqlalchemy.ext.associationproxy import association_proxy

from web.models.right_mixin import RightMixin

bookmarktags_table = db.Table('bookmarktags', db.metadata,
    db.Column('bookmark_id', db.Integer, db.ForeignKey("bookmark.id"),
    db.Column('tag_text', db.String, db.ForeignKey("BookmarkTag.text"),

class Bookmark(db.Model, RightMixin):
    Represent a bookmark.
    id = db.Column(db.Integer(), primary_key=True)
    href = db.Column(db.String(), default="")
    title = db.Column(db.String(), default="")
    description = db.Column(db.String(), default="FR")
    shared = db.Column(db.Boolean(), default=False)
    to_read = db.Column(db.Boolean(), default=False)
    time = db.Column(db.DateTime(), default=datetime.utcnow)
    user_id = db.Column(db.Integer(), db.ForeignKey('user.id'))

    # relationships
    tag_objs = db.relationship("BookmarkTag", secondary=lambda: bookmarktags_table)
    # tag_objs = db.relationship('BookmarkTag', back_populates='bookmark',
    #                         cascade='all,delete-orphan',
    #                         lazy=False,
    #                         foreign_keys='[BookmarkTag.bookmark_id]')
    tags = association_proxy('tag_objs', 'text')

    def validates_title(self, key, value):
        return str(value).strip()

    def validates_description(self, key, value):
        return str(value).strip()

    def __repr__(self):
        return '<Bookmark %r>' % (self.href)

M src/web/models/tag.py => src/web/models/tag.py +7 -23
@@ 1,38 1,22 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-

from sqlalchemy import Column, ForeignKey, Integer, String
from sqlalchemy.orm import relationship

from bootstrap import db

class ArticleTag(db.Model):
    text = db.Column(db.String, primary_key=True, unique=False)
class Tag(db.Model):
    text = Column(String, primary_key=True, unique=False)

    # foreign keys
    article_id = db.Column(db.Integer, db.ForeignKey('article.id', ondelete='CASCADE'),
    article_id = Column(Integer, ForeignKey('article.id', ondelete='CASCADE'),

    # relationships
    article = db.relationship('Article', back_populates='tag_objs',
    article = relationship('Article', back_populates='tag_objs',

    def __init__(self, text):
        self.text = text

class BookmarkTag(db.Model):
    __tablename__ = 'BookmarkTag'
    #id = db.Column(db.Integer, primary_key=True)
    text = db.Column(db.String, primary_key=True)

    # foreign keys
    # bookmark_id = db.Column(db.Integer, db.ForeignKey('bookmark.id', ondelete='CASCADE'),
    #                     primary_key=True)

    # relationships
    # bookmark = db.relationship('Bookmark', back_populates='tag_objs',
    #                             single_parent=True,
    #                             cascade="all, delete-orphan",
    #                             foreign_keys=[bookmark_id])

    def __init__(self, text):
        self.text = text

M src/web/models/user.py => src/web/models/user.py +0 -4
@@ 38,7 38,6 @@ from bootstrap import db
from web.models.right_mixin import RightMixin
from web.models.category import Category
from web.models.feed import Feed
from web.models.bookmark import Bookmark

class User(db.Model, UserMixin, RightMixin):

@@ 72,9 71,6 @@ class User(db.Model, UserMixin, RightMixin):
    feeds = db.relationship('Feed', backref='user',
                         cascade='all, delete-orphan',
    bookmarks = db.relationship('Bookmark', backref='user',
                         cascade='all, delete-orphan',

    def _fields_base_write():

M src/web/views/__init__.py => src/web/views/__init__.py +1 -2
@@ 6,12 6,11 @@ from web.views.category import category_bp, categories_bp
from web.views.icon import icon_bp
from web.views.admin import admin_bp
from web.views.user import user_bp, users_bp
from web.views.bookmark import bookmark_bp, bookmarks_bp

__all__ = ['views', 'home', 'session_mgmt', 'v2', 'v3',
           'article_bp', 'articles_bp', 'feed_bp', 'feeds_bp',
           'category_bp', 'categories_bp', 'icon_bp',
           'admin_bp', 'user_bp', 'users_bp', 'bookmark_bp', 'bookmarks_bp']
           'admin_bp', 'user_bp', 'users_bp']

import conf
from flask import request

D src/web/views/bookmark.py => src/web/views/bookmark.py +0 -80
@@ 1,80 0,0 @@
import logging
from werkzeug.exceptions import BadRequest

from flask import Blueprint, render_template, flash, \
                  redirect, request, url_for
from flask_babel import gettext
from flask_login import login_required, current_user

import conf
from bootstrap import db
from web.forms import BookmarkForm
from web.controllers import BookmarkController
from web.models.tag import BookmarkTag

logger = logging.getLogger(__name__)
bookmarks_bp = Blueprint('bookmarks', __name__, url_prefix='/bookmarks')
bookmark_bp = Blueprint('bookmark', __name__, url_prefix='/bookmark')

@bookmarks_bp.route('/', methods=['GET'])
def list():
    "Lists the bookmarks."
    bookmark_contr = BookmarkController(current_user.id)
    return render_template('bookmarks.html',

@bookmark_bp.route('/create', methods=['GET'])
@bookmark_bp.route('/edit/<int:bookmark_id>', methods=['GET'])
def form(bookmark_id=None):
    action = gettext("Add a bookmark")
    head_titles = [action]
    if bookmark_id is None:
        return render_template('edit_bookmark.html', action=action,
                               head_titles=head_titles, form=BookmarkForm())
    bookmark = BookmarkController(current_user.id).get(id=bookmark_id)
    action = gettext('Edit bookmark')
    head_titles = [action]
    form = BookmarkForm(obj=bookmark)
    form.tags.data = bookmark.tags
    return render_template('edit_bookmark.html', action=action,
                           head_titles=head_titles, bookmark=bookmark,

@bookmark_bp.route('/create', methods=['POST'])
@bookmark_bp.route('/edit/<int:bookmark_id>', methods=['POST'])
def process_form(bookmark_id=None):
    form = BookmarkForm()
    bookmark_contr = BookmarkController(current_user.id)

    if not form.validate():
        return render_template('edit_bookmark.html', form=form)

    # Edit an existing bookmark
    bookmark_attr = {'href': form.href.data,
                    'description': form.description.data,
                    'title': form.title.data,
                    'tags': [tag.strip() for tag in form.tags.data.split(',')],
                    'shared': form.shared.data,
                    'to_read': form.to_read.data}

    if bookmark_id is not None:
        # bookmark = BookmarkController(current_user.id).get(id=bookmark_id)
        # form.populate_obj(bookmark)
        # bookmark.tags = [tag.strip() for tag in form.tags.data.split(',')],
        # db.session.commit()
        bookmark_contr.update({'id': bookmark_id}, bookmark_attr)
        flash(gettext('Bookmark successfully updated.'), 'success')
        return redirect(url_for('bookmark.form', bookmark_id=bookmark_id))

    # Create a new bookmark
    new_bookmark = bookmark_contr.create(**bookmark_attr)

    flash(gettext('Bookmark successfully created.'), 'success')

    return redirect(url_for('bookmark.form', bookmark_id=new_bookmark.id))