Anonymous account now can also be configured like normal user (e.g. download permissions, change visibility of sidebar) (#35)
Search now working for calibre-companion (#79), download not working yet metadata view 80% finished
This commit is contained in:
parent
beca61a596
commit
0107c52b66
|
@ -13,9 +13,9 @@
|
||||||
<th>{{_('Upload')}}</th>
|
<th>{{_('Upload')}}</th>
|
||||||
<th>{{_('Edit')}}</th>
|
<th>{{_('Edit')}}</th>
|
||||||
<th>{{_('Passwd')}}</th>
|
<th>{{_('Passwd')}}</th>
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
{% for user in content %}
|
{% for user in content %}
|
||||||
|
{% if not user.role_anonymous() or config.ANON_BROWSE %}
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="{{url_for('edit_user', user_id=user.id)}}">{{user.nickname}}</a></td>
|
<td><a href="{{url_for('edit_user', user_id=user.id)}}">{{user.nickname}}</a></td>
|
||||||
<td>{{user.email}}</td>
|
<td>{{user.email}}</td>
|
||||||
|
@ -26,7 +26,8 @@
|
||||||
<td>{% if user.role_upload() %}<span class="glyphicon glyphicon-ok"></span>{% else %}<span class="glyphicon glyphicon-remove"></span>{% endif %}</td>
|
<td>{% if user.role_upload() %}<span class="glyphicon glyphicon-ok"></span>{% else %}<span class="glyphicon glyphicon-remove"></span>{% endif %}</td>
|
||||||
<td>{% if user.role_edit() %}<span class="glyphicon glyphicon-ok"></span>{% else %}<span class="glyphicon glyphicon-remove"></span>{% endif %}</td>
|
<td>{% if user.role_edit() %}<span class="glyphicon glyphicon-ok"></span>{% else %}<span class="glyphicon glyphicon-remove"></span>{% endif %}</td>
|
||||||
<td>{% if user.role_passwd() %}<span class="glyphicon glyphicon-ok"></span>{% else %}<span class="glyphicon glyphicon-remove"></span>{% endif %}</td>
|
<td>{% if user.role_passwd() %}<span class="glyphicon glyphicon-ok"></span>{% else %}<span class="glyphicon glyphicon-remove"></span>{% endif %}</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
<div class="btn btn-default"><a href="{{url_for('new_user')}}">{{_('Add new user')}}</a></div>
|
<div class="btn btn-default"><a href="{{url_for('new_user')}}">{{_('Add new user')}}</a></div>
|
||||||
|
|
|
@ -104,11 +104,11 @@
|
||||||
{{entry.comments[0].text|safe}}
|
{{entry.comments[0].text|safe}}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if g.user.is_authenticated %}
|
|
||||||
<div class="more-stuff">
|
<div class="more-stuff">
|
||||||
<div class="btn-toolbar" role="toolbar">
|
<div class="btn-toolbar" role="toolbar">
|
||||||
|
|
||||||
<div class="btn-group" role="group" aria-label="Download, send to Kindle, reading">
|
<div class="btn-group" role="group" aria-label="Download, send to Kindle, reading">
|
||||||
|
{% if g.user.role_download() %}
|
||||||
<div class="btn-group" role="group">
|
<div class="btn-group" role="group">
|
||||||
<button id="btnGroupDrop1" type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
<button id="btnGroupDrop1" type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
<span class="glyphicon glyphicon-download"></span> {{_('Download')}}
|
<span class="glyphicon glyphicon-download"></span> {{_('Download')}}
|
||||||
|
@ -120,6 +120,9 @@
|
||||||
{%endfor%}
|
{%endfor%}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if g.user.is_authenticated %}
|
||||||
{% if g.user.kindle_mail %}
|
{% if g.user.kindle_mail %}
|
||||||
<a href="{{url_for('send_to_kindle', book_id=entry.id)}}" id="sendbtn" class="btn btn-primary" role="button"><span class="glyphicon glyphicon-send"></span> {{_('Send to Kindle')}}</a>
|
<a href="{{url_for('send_to_kindle', book_id=entry.id)}}" id="sendbtn" class="btn btn-primary" role="button"><span class="glyphicon glyphicon-send"></span> {{_('Send to Kindle')}}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -136,10 +139,11 @@
|
||||||
{%endfor%}
|
{%endfor%}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</br>
|
</br>
|
||||||
|
{% if g.user.is_authenticated %}
|
||||||
{% if g.user.shelf.all() or g.public_shelfes %}
|
{% if g.user.shelf.all() or g.public_shelfes %}
|
||||||
<div class="btn-toolbar" role="toolbar">
|
<div class="btn-toolbar" role="toolbar">
|
||||||
<div class="btn-group" role="group" aria-label="Add to shelves">
|
<div class="btn-group" role="group" aria-label="Add to shelves">
|
||||||
|
@ -180,7 +184,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
{% if g.user.role_edit() %}
|
{% if g.user.role_edit() %}
|
||||||
<div class="btn-toolbar" role="toolbar">
|
<div class="btn-toolbar" role="toolbar">
|
||||||
<div class="btn-group" role="group" aria-label="Edit/Delete book">
|
<div class="btn-group" role="group" aria-label="Edit/Delete book">
|
||||||
|
@ -189,7 +193,7 @@
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -10,12 +10,11 @@
|
||||||
<link rel="up"
|
<link rel="up"
|
||||||
href="{{url_for('feed_index')}}"
|
href="{{url_for('feed_index')}}"
|
||||||
type="application/atom+xml;profile=opds-catalog;type=feed;kind=navigation"/>
|
type="application/atom+xml;profile=opds-catalog;type=feed;kind=navigation"/>
|
||||||
|
{% if pagination.has_prev %}
|
||||||
<link rel="first"
|
<link rel="first"
|
||||||
href="{{request.script_root + request.path}}"
|
href="{{request.script_root + request.path}}"
|
||||||
type="application/atom+xml;profile=opds-catalog;type=feed;kind=navigation"/>
|
type="application/atom+xml;profile=opds-catalog;type=feed;kind=navigation"/>
|
||||||
<link rel="last"
|
{% endif %}
|
||||||
href="{{request.script_root + request.path}}?offset={{ pagination.last_offset }}"
|
|
||||||
type="application/atom+xml;profile=opds-catalog;type=feed;kind=navigation"/>
|
|
||||||
{% if pagination.has_next %}
|
{% if pagination.has_next %}
|
||||||
<link rel="next"
|
<link rel="next"
|
||||||
title="{{_('Next')}}"
|
title="{{_('Next')}}"
|
||||||
|
|
|
@ -146,10 +146,11 @@
|
||||||
<li><a href="{{url_for('show_shelf', shelf_id=shelf.id)}}"><span class="glyphicon glyphicon-list"></span> {{shelf.name}}</a></li>
|
<li><a href="{{url_for('show_shelf', shelf_id=shelf.id)}}"><span class="glyphicon glyphicon-list"></span> {{shelf.name}}</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% if not g.user.is_anonymous() %}
|
{% if not g.user.is_anonymous() %}
|
||||||
<li class="create-shelf"><a href="{{url_for('create_shelf')}}">{{_('Create a Shelf')}}</a></li>
|
<li id="nav_createshelf" class="create-shelf"><a href="{{url_for('create_shelf')}}">{{_('Create a Shelf')}}</a></li>
|
||||||
|
<li id="nav_about"><a href="{{url_for('stats')}}"><span class="glyphicon glyphicon-info-sign"></span> {{_('About')}}</a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<li><a href="{{url_for('stats')}}"><span class="glyphicon glyphicon-info-sign"></span> {{_('About')}}</a></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<label for="email">{{_('Email address')}}</label>
|
<label for="email">{{_('Email address')}}</label>
|
||||||
<input type="email" class="form-control" name="email" id="email" value="{{ content.email if content.email != None }}" autocomplete="off" required>
|
<input type="email" class="form-control" name="email" id="email" value="{{ content.email if content.email != None }}" autocomplete="off" required>
|
||||||
</div>
|
</div>
|
||||||
{% if g.user and g.user.role_passwd() or g.user.role_admin()%}
|
{% if ( g.user and g.user.role_passwd() or g.user.role_admin() ) and not content.role_anonymous() %}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="password">{{_('Password')}}</label>
|
<label for="password">{{_('Password')}}</label>
|
||||||
<input type="password" class="form-control" name="password" id="password" value="" autocomplete="off">
|
<input type="password" class="form-control" name="password" id="password" value="" autocomplete="off">
|
||||||
|
@ -23,6 +23,7 @@
|
||||||
<label for="kindle_mail">{{_('Kindle E-Mail')}}</label>
|
<label for="kindle_mail">{{_('Kindle E-Mail')}}</label>
|
||||||
<input type="email" class="form-control" name="kindle_mail" id="kindle_mail" value="{{ content.kindle_mail if content.kindle_mail != None }}">
|
<input type="email" class="form-control" name="kindle_mail" id="kindle_mail" value="{{ content.kindle_mail if content.kindle_mail != None }}">
|
||||||
</div>
|
</div>
|
||||||
|
{% if not content.role_anonymous() %}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="locale">{{_('Language')}}</label>
|
<label for="locale">{{_('Language')}}</label>
|
||||||
<select name="locale" id="locale" class="form-control">
|
<select name="locale" id="locale" class="form-control">
|
||||||
|
@ -31,6 +32,7 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="default_language">{{_('Show books with language')}}</label>
|
<label for="default_language">{{_('Show books with language')}}</label>
|
||||||
<select name="default_language" id="default_language" class="form-control">
|
<select name="default_language" id="default_language" class="form-control">
|
||||||
|
@ -62,11 +64,12 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if g.user and g.user.role_admin() and not profile %}
|
{% if g.user and g.user.role_admin() and not profile %}
|
||||||
|
{% if not content.role_anonymous() %}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input type="checkbox" name="admin_role" id="admin_role" {% if content.role_admin() %}checked{% endif %}>
|
<input type="checkbox" name="admin_role" id="admin_role" {% if content.role_admin() %}checked{% endif %}>
|
||||||
<label for="admin_role">{{_('Admin user')}}</label>
|
<label for="admin_role">{{_('Admin user')}}</label>
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input type="checkbox" name="download_role" id="download_role" {% if content.role_download() %}checked{% endif %}>
|
<input type="checkbox" name="download_role" id="download_role" {% if content.role_download() %}checked{% endif %}>
|
||||||
<label for="download_role">{{_('Allow Downloads')}}</label>
|
<label for="download_role">{{_('Allow Downloads')}}</label>
|
||||||
|
@ -79,19 +82,21 @@
|
||||||
<input type="checkbox" name="edit_role" id="edit_role" {% if content.role_edit() %}checked{% endif %}>
|
<input type="checkbox" name="edit_role" id="edit_role" {% if content.role_edit() %}checked{% endif %}>
|
||||||
<label for="edit_role">{{_('Allow Edit')}}</label>
|
<label for="edit_role">{{_('Allow Edit')}}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
{% if not content.role_anonymous() %}
|
||||||
<input type="checkbox" name="passwd_role" id="passwd_role" {% if content.role_passwd() %}checked{% endif %}>
|
<div class="form-group">
|
||||||
<label for="passwd_role">{{_('Allow Changing Password')}}</label>
|
<input type="checkbox" name="passwd_role" id="passwd_role" {% if content.role_passwd() %}checked{% endif %}>
|
||||||
</div>
|
<label for="passwd_role">{{_('Allow Changing Password')}}</label>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if g.user and g.user.role_admin() and not profile and not new_user %}
|
{% if g.user and g.user.role_admin() and not profile and not new_user and not content.role_anonymous() %}
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" name="delete"> {{_('Delete this user')}}
|
<input type="checkbox" name="delete"> {{_('Delete this user')}}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<button type="submit" class="btn btn-default">{{_('Submit')}}</button>
|
<button type="submit" id="submit" class="btn btn-default">{{_('Submit')}}</button>
|
||||||
{% if not profile %}
|
{% if not profile %}
|
||||||
<a href="{{ url_for('admin') }}" class="btn btn-default">{{_('Back')}}</a>
|
<a href="{{ url_for('admin') }}" class="btn btn-default">{{_('Back')}}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
93
cps/ub.py
93
cps/ub.py
|
@ -5,9 +5,12 @@ from sqlalchemy import *
|
||||||
from sqlalchemy import exc
|
from sqlalchemy import exc
|
||||||
from sqlalchemy.ext.declarative import declarative_base
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
from sqlalchemy.orm import *
|
from sqlalchemy.orm import *
|
||||||
|
from flask_login import AnonymousUserMixin
|
||||||
import os
|
import os
|
||||||
import config
|
import config
|
||||||
|
import traceback
|
||||||
from werkzeug.security import generate_password_hash
|
from werkzeug.security import generate_password_hash
|
||||||
|
from flask_babel import gettext as _
|
||||||
|
|
||||||
dbpath = os.path.join(config.APP_DB_ROOT, "app.db")
|
dbpath = os.path.join(config.APP_DB_ROOT, "app.db")
|
||||||
engine = create_engine('sqlite:///{0}'.format(dbpath), echo=False)
|
engine = create_engine('sqlite:///{0}'.format(dbpath), echo=False)
|
||||||
|
@ -19,28 +22,11 @@ ROLE_DOWNLOAD = 2
|
||||||
ROLE_UPLOAD = 4
|
ROLE_UPLOAD = 4
|
||||||
ROLE_EDIT = 8
|
ROLE_EDIT = 8
|
||||||
ROLE_PASSWD = 16
|
ROLE_PASSWD = 16
|
||||||
|
ROLE_ANONYMOUS = 32
|
||||||
DEFAULT_PASS = "admin123"
|
DEFAULT_PASS = "admin123"
|
||||||
|
|
||||||
|
|
||||||
class User(Base):
|
class UserBase():
|
||||||
__tablename__ = 'user'
|
|
||||||
|
|
||||||
id = Column(Integer, primary_key=True)
|
|
||||||
nickname = Column(String(64), unique=True)
|
|
||||||
email = Column(String(120), unique=True, default="")
|
|
||||||
role = Column(SmallInteger, default=ROLE_USER)
|
|
||||||
password = Column(String)
|
|
||||||
kindle_mail = Column(String(120), default="")
|
|
||||||
shelf = relationship('Shelf', backref='user', lazy='dynamic')
|
|
||||||
downloads = relationship('Downloads', backref='user', lazy='dynamic')
|
|
||||||
locale = Column(String(2), default="en")
|
|
||||||
random_books = Column(Integer, default=1)
|
|
||||||
language_books = Column(Integer, default=1)
|
|
||||||
series_books = Column(Integer, default=1)
|
|
||||||
category_books = Column(Integer, default=1)
|
|
||||||
hot_books = Column(Integer, default=1)
|
|
||||||
default_language = Column(String(3), default="all")
|
|
||||||
|
|
||||||
def is_authenticated(self):
|
def is_authenticated(self):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -74,6 +60,12 @@ class User(Base):
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def role_anonymous(self):
|
||||||
|
if self.role is not None:
|
||||||
|
return True if self.role & ROLE_ANONYMOUS == ROLE_ANONYMOUS else False
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
def is_active(self):
|
def is_active(self):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -105,6 +97,52 @@ class User(Base):
|
||||||
return '<User %r>' % self.nickname
|
return '<User %r>' % self.nickname
|
||||||
|
|
||||||
|
|
||||||
|
class User(UserBase,Base):
|
||||||
|
__tablename__ = 'user'
|
||||||
|
|
||||||
|
id = Column(Integer, primary_key=True)
|
||||||
|
nickname = Column(String(64), unique=True)
|
||||||
|
email = Column(String(120), unique=True, default="")
|
||||||
|
role = Column(SmallInteger, default=ROLE_USER)
|
||||||
|
password = Column(String)
|
||||||
|
kindle_mail = Column(String(120), default="")
|
||||||
|
shelf = relationship('Shelf', backref='user', lazy='dynamic')
|
||||||
|
downloads = relationship('Downloads', backref='user', lazy='dynamic')
|
||||||
|
locale = Column(String(2), default="en")
|
||||||
|
random_books = Column(Integer, default=1)
|
||||||
|
language_books = Column(Integer, default=1)
|
||||||
|
series_books = Column(Integer, default=1)
|
||||||
|
category_books = Column(Integer, default=1)
|
||||||
|
hot_books = Column(Integer, default=1)
|
||||||
|
default_language = Column(String(3), default="all")
|
||||||
|
|
||||||
|
|
||||||
|
class Anonymous(AnonymousUserMixin,UserBase):
|
||||||
|
def __init__(self):
|
||||||
|
self.loadSettings()
|
||||||
|
|
||||||
|
def loadSettings(self):
|
||||||
|
data=session.query(User).filter(User.role.op('&')(ROLE_ANONYMOUS) == ROLE_ANONYMOUS).first()
|
||||||
|
self.nickname = data.nickname
|
||||||
|
self.role = data.role
|
||||||
|
self.random_books = data.random_books
|
||||||
|
self.default_language = data.default_language
|
||||||
|
self.language_books = data.language_books
|
||||||
|
self.series_books = data.series_books
|
||||||
|
self.category_books = data.category_books
|
||||||
|
self.hot_books = data.hot_books
|
||||||
|
self.default_language = data.default_language
|
||||||
|
|
||||||
|
def role_admin(self):
|
||||||
|
return False
|
||||||
|
|
||||||
|
def is_active(self):
|
||||||
|
return False
|
||||||
|
|
||||||
|
def is_anonymous(self):
|
||||||
|
return config.ANON_BROWSE
|
||||||
|
|
||||||
|
|
||||||
class Shelf(Base):
|
class Shelf(Base):
|
||||||
__tablename__ = 'shelf'
|
__tablename__ = 'shelf'
|
||||||
|
|
||||||
|
@ -155,6 +193,8 @@ class Settings(Base):
|
||||||
|
|
||||||
|
|
||||||
def migrate_Database():
|
def migrate_Database():
|
||||||
|
if session.query(User).filter(User.role.op('&')(ROLE_ANONYMOUS) == ROLE_ANONYMOUS).first() is None:
|
||||||
|
create_anonymous_user()
|
||||||
try:
|
try:
|
||||||
session.query(exists().where(User.random_books)).scalar()
|
session.query(exists().where(User.random_books)).scalar()
|
||||||
session.commit()
|
session.commit()
|
||||||
|
@ -213,6 +253,20 @@ def get_mail_settings():
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
def create_anonymous_user():
|
||||||
|
user = User()
|
||||||
|
user.nickname = _("Guest")
|
||||||
|
user.email='no@email'
|
||||||
|
user.role = ROLE_ANONYMOUS
|
||||||
|
user.password = generate_password_hash('1')
|
||||||
|
|
||||||
|
session.add(user)
|
||||||
|
try:
|
||||||
|
session.commit()
|
||||||
|
except:
|
||||||
|
session.rollback()
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def create_admin_user():
|
def create_admin_user():
|
||||||
user = User()
|
user = User()
|
||||||
|
@ -236,6 +290,7 @@ if not os.path.exists(dbpath):
|
||||||
Base.metadata.create_all(engine)
|
Base.metadata.create_all(engine)
|
||||||
create_default_config()
|
create_default_config()
|
||||||
create_admin_user()
|
create_admin_user()
|
||||||
|
create_anonymous_user()
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
|
80
cps/web.py
80
cps/web.py
|
@ -14,7 +14,7 @@ from sqlalchemy.sql.expression import func
|
||||||
from sqlalchemy.sql.expression import false
|
from sqlalchemy.sql.expression import false
|
||||||
from sqlalchemy.exc import IntegrityError
|
from sqlalchemy.exc import IntegrityError
|
||||||
from math import ceil
|
from math import ceil
|
||||||
from flask_login import LoginManager, login_user, logout_user, login_required, current_user, AnonymousUserMixin
|
from flask_login import LoginManager, login_user, logout_user, login_required, current_user
|
||||||
from flask_principal import Principal, Identity, AnonymousIdentity, identity_changed
|
from flask_principal import Principal, Identity, AnonymousIdentity, identity_changed
|
||||||
from flask_babel import Babel
|
from flask_babel import Babel
|
||||||
from flask_babel import gettext as _
|
from flask_babel import gettext as _
|
||||||
|
@ -115,49 +115,10 @@ global global_queue
|
||||||
global_queue = None
|
global_queue = None
|
||||||
|
|
||||||
|
|
||||||
class Anonymous(AnonymousUserMixin):
|
|
||||||
def __init__(self):
|
|
||||||
self.nickname = 'Guest'
|
|
||||||
self.role = -1
|
|
||||||
|
|
||||||
def role_admin(self):
|
|
||||||
return False
|
|
||||||
|
|
||||||
def role_download(self):
|
|
||||||
return False
|
|
||||||
|
|
||||||
def role_upload(self):
|
|
||||||
return False
|
|
||||||
|
|
||||||
def role_edit(self):
|
|
||||||
return False
|
|
||||||
|
|
||||||
def filter_language(self):
|
|
||||||
return 'all'
|
|
||||||
|
|
||||||
def show_random_books(self):
|
|
||||||
return True
|
|
||||||
|
|
||||||
def show_hot_books(self):
|
|
||||||
return True
|
|
||||||
|
|
||||||
def show_series(self):
|
|
||||||
return True
|
|
||||||
|
|
||||||
def show_category(self):
|
|
||||||
return True
|
|
||||||
|
|
||||||
def show_language(self):
|
|
||||||
return True
|
|
||||||
|
|
||||||
def is_anonymous(self):
|
|
||||||
return config.ANON_BROWSE
|
|
||||||
|
|
||||||
|
|
||||||
lm = LoginManager(app)
|
lm = LoginManager(app)
|
||||||
lm.init_app(app)
|
lm.init_app(app)
|
||||||
lm.login_view = 'login'
|
lm.login_view = 'login'
|
||||||
lm.anonymous_user = Anonymous
|
lm.anonymous_user = ub.Anonymous
|
||||||
|
|
||||||
app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
|
app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
|
||||||
|
|
||||||
|
@ -237,9 +198,9 @@ def requires_basic_auth_if_no_ano(f):
|
||||||
# simple pagination for the feed
|
# simple pagination for the feed
|
||||||
class Pagination(object):
|
class Pagination(object):
|
||||||
def __init__(self, page, per_page, total_count):
|
def __init__(self, page, per_page, total_count):
|
||||||
self.page = page
|
self.page = int(page)
|
||||||
self.per_page = per_page
|
self.per_page = int(per_page)
|
||||||
self.total_count = total_count
|
self.total_count = int(total_count)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def next_offset(self):
|
def next_offset(self):
|
||||||
|
@ -247,7 +208,7 @@ class Pagination(object):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def previous_offset(self):
|
def previous_offset(self):
|
||||||
return int((self.page-1) * self.per_page)
|
return int((self.page-2) * self.per_page)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def last_offset(self):
|
def last_offset(self):
|
||||||
|
@ -453,11 +414,17 @@ def feed_osd():
|
||||||
response.headers["Content-Type"] = "application/xml"
|
response.headers["Content-Type"] = "application/xml"
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
@app.route("/opds/search/<query>")
|
||||||
|
def feed_cc_search(query):
|
||||||
|
return feed_search(query.strip())
|
||||||
|
|
||||||
|
|
||||||
@app.route("/opds/search", methods=["GET"])
|
@app.route("/opds/search", methods=["GET"])
|
||||||
@requires_basic_auth_if_no_ano
|
@requires_basic_auth_if_no_ano
|
||||||
def feed_search():
|
def feed_normal_search():
|
||||||
term = request.args.get("query").strip()
|
return feed_search(request.args.get("query").strip())
|
||||||
|
|
||||||
|
def feed_search(term):
|
||||||
if current_user.filter_language() != "all":
|
if current_user.filter_language() != "all":
|
||||||
filter = db.Books.languages.any(db.Languages.lang_code == current_user.filter_language())
|
filter = db.Books.languages.any(db.Languages.lang_code == current_user.filter_language())
|
||||||
else:
|
else:
|
||||||
|
@ -466,8 +433,8 @@ def feed_search():
|
||||||
entries = db.session.query(db.Books).filter(db.or_(db.Books.tags.any(db.Tags.name.like("%" + term + "%")),
|
entries = db.session.query(db.Books).filter(db.or_(db.Books.tags.any(db.Tags.name.like("%" + term + "%")),
|
||||||
db.Books.authors.any(db.Authors.name.like("%" + term + "%")),
|
db.Books.authors.any(db.Authors.name.like("%" + term + "%")),
|
||||||
db.Books.title.like("%" + term + "%"))).filter(filter).all()
|
db.Books.title.like("%" + term + "%"))).filter(filter).all()
|
||||||
|
pagination = Pagination( 1,len(entries),len(entries))
|
||||||
xml = render_template('feed.xml', searchterm=term, entries=entries)
|
xml = render_template('feed.xml', searchterm=term, entries=entries, pagination=pagination)
|
||||||
else:
|
else:
|
||||||
xml = render_template('feed.xml', searchterm="")
|
xml = render_template('feed.xml', searchterm="")
|
||||||
response = make_response(xml)
|
response = make_response(xml)
|
||||||
|
@ -1145,13 +1112,14 @@ def read_book(book_id, format):
|
||||||
|
|
||||||
|
|
||||||
@app.route("/download/<int:book_id>/<format>")
|
@app.route("/download/<int:book_id>/<format>")
|
||||||
@login_required
|
@login_required_if_no_ano
|
||||||
@download_required
|
@download_required
|
||||||
def get_download_link(book_id, format):
|
def get_download_link(book_id, format):
|
||||||
format = format.split(".")[0]
|
format = format.split(".")[0]
|
||||||
book = db.session.query(db.Books).filter(db.Books.id == book_id).first()
|
book = db.session.query(db.Books).filter(db.Books.id == book_id).first()
|
||||||
data = db.session.query(db.Data).filter(db.Data.book == book.id).filter(db.Data.format == format.upper()).first()
|
data = db.session.query(db.Data).filter(db.Data.book == book.id).filter(db.Data.format == format.upper()).first()
|
||||||
helper.update_download(book_id, int(current_user.id))
|
if current_user.is_authenticated: # collect downloaded books only for registered user and not for anonymous user
|
||||||
|
helper.update_download(book_id, int(current_user.id))
|
||||||
author = helper.get_normalized_author(book.author_sort)
|
author = helper.get_normalized_author(book.author_sort)
|
||||||
file_name = book.title
|
file_name = book.title
|
||||||
if len(author) > 0:
|
if len(author) > 0:
|
||||||
|
@ -1392,7 +1360,7 @@ def show_shelf(shelf_id):
|
||||||
|
|
||||||
|
|
||||||
@app.route("/shelf/order/<int:shelf_id>", methods=["GET", "POST"])
|
@app.route("/shelf/order/<int:shelf_id>", methods=["GET", "POST"])
|
||||||
@login_required_if_no_ano
|
@login_required
|
||||||
def order_shelf(shelf_id):
|
def order_shelf(shelf_id):
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
to_save = request.form.to_dict()
|
to_save = request.form.to_dict()
|
||||||
|
@ -1619,7 +1587,7 @@ def edit_user(user_id):
|
||||||
flash(_(u"User '%(nick)s' deleted", nick=content.nickname), category="success")
|
flash(_(u"User '%(nick)s' deleted", nick=content.nickname), category="success")
|
||||||
return redirect(url_for('admin'))
|
return redirect(url_for('admin'))
|
||||||
else:
|
else:
|
||||||
if to_save["password"]:
|
if "password" in to_save and to_save["password"]:
|
||||||
content.password = generate_password_hash(to_save["password"])
|
content.password = generate_password_hash(to_save["password"])
|
||||||
|
|
||||||
if "admin_role" in to_save and not content.role_admin():
|
if "admin_role" in to_save and not content.role_admin():
|
||||||
|
@ -1663,7 +1631,7 @@ def edit_user(user_id):
|
||||||
content.hot_books = 1
|
content.hot_books = 1
|
||||||
if "default_language" in to_save:
|
if "default_language" in to_save:
|
||||||
content.default_language = to_save["default_language"]
|
content.default_language = to_save["default_language"]
|
||||||
if to_save["locale"]:
|
if "locale" in to_save and to_save["locale"]:
|
||||||
content.locale = to_save["locale"]
|
content.locale = to_save["locale"]
|
||||||
if to_save["email"] and to_save["email"] != content.email:
|
if to_save["email"] and to_save["email"] != content.email:
|
||||||
content.email = to_save["email"]
|
content.email = to_save["email"]
|
||||||
|
@ -1680,7 +1648,7 @@ def edit_user(user_id):
|
||||||
|
|
||||||
|
|
||||||
@app.route("/admin/book/<int:book_id>", methods=['GET', 'POST'])
|
@app.route("/admin/book/<int:book_id>", methods=['GET', 'POST'])
|
||||||
@login_required
|
@login_required_if_no_ano
|
||||||
@edit_required
|
@edit_required
|
||||||
def edit_book(book_id):
|
def edit_book(book_id):
|
||||||
# create the function for sorting...
|
# create the function for sorting...
|
||||||
|
@ -1889,7 +1857,7 @@ def edit_book(book_id):
|
||||||
|
|
||||||
|
|
||||||
@app.route("/upload", methods=["GET", "POST"])
|
@app.route("/upload", methods=["GET", "POST"])
|
||||||
@login_required
|
@login_required_if_no_ano
|
||||||
@upload_required
|
@upload_required
|
||||||
def upload():
|
def upload():
|
||||||
if not config.UPLOADING:
|
if not config.UPLOADING:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user