#!/usr/bin/env python # -*- coding: utf-8 -*- from sqlalchemy import * from sqlalchemy import exc from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import * from flask_login import AnonymousUserMixin import os import traceback import logging from werkzeug.security import generate_password_hash from flask_babel import gettext as _ dbpath = os.path.join(os.path.normpath(os.path.dirname(os.path.realpath(__file__)) + os.sep + ".." + os.sep), "app.db") engine = create_engine('sqlite:///{0}'.format(dbpath), echo=False) Base = declarative_base() ROLE_USER = 0 ROLE_ADMIN = 1 ROLE_DOWNLOAD = 2 ROLE_UPLOAD = 4 ROLE_EDIT = 8 ROLE_PASSWD = 16 ROLE_ANONYMOUS = 32 DETAIL_RANDOM = 1 SIDEBAR_LANGUAGE = 2 SIDEBAR_SERIES = 4 SIDEBAR_CATEGORY = 8 SIDEBAR_HOT = 16 SIDEBAR_RANDOM = 32 SIDEBAR_AUTHOR = 64 SIDEBAR_BEST_RATED = 128 DEFAULT_PASS = "admin123" DEFAULT_PORT = int(os.environ.get("CALIBRE_PORT", 8083)) DEVELOPMENT = False class UserBase: @staticmethod def is_authenticated(self): return True def role_admin(self): if self.role is not None: return True if self.role & ROLE_ADMIN == ROLE_ADMIN else False else: return False def role_download(self): if self.role is not None: return True if self.role & ROLE_DOWNLOAD == ROLE_DOWNLOAD else False else: return False def role_upload(self): if self.role is not None: return True if self.role & ROLE_UPLOAD == ROLE_UPLOAD else False else: return False def role_edit(self): if self.role is not None: return True if self.role & ROLE_EDIT == ROLE_EDIT else False else: return False def role_passwd(self): if self.role is not None: return True if self.role & ROLE_PASSWD == ROLE_PASSWD else False else: 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): return True def is_anonymous(self): return False def get_id(self): return unicode(self.id) def filter_language(self): return self.default_language def show_random_books(self): if self.sidebar_view is not None: return True if self.sidebar_view & SIDEBAR_RANDOM == SIDEBAR_RANDOM else False else: return False def show_language(self): if self.sidebar_view is not None: return True if self.sidebar_view & SIDEBAR_LANGUAGE == SIDEBAR_LANGUAGE else False else: return False def show_hot_books(self): if self.sidebar_view is not None: return True if self.sidebar_view & SIDEBAR_HOT == SIDEBAR_HOT else False else: return False def show_series(self): if self.sidebar_view is not None: return True if self.sidebar_view & SIDEBAR_SERIES == SIDEBAR_SERIES else False else: return False def show_category(self): if self.sidebar_view is not None: return True if self.sidebar_view & SIDEBAR_CATEGORY == SIDEBAR_CATEGORY else False else: return False def show_author(self): if self.sidebar_view is not None: return True if self.sidebar_view & SIDEBAR_AUTHOR == SIDEBAR_AUTHOR else False else: return False def show_best_rated_books(self): if self.sidebar_view is not None: return True if self.sidebar_view & SIDEBAR_BEST_RATED == SIDEBAR_BEST_RATED else False else: return False def show_detail_random(self): if self.sidebar_view is not None: return True if self.sidebar_view & DETAIL_RANDOM == DETAIL_RANDOM else False else: return False def __repr__(self): return '' % self.nickname # Baseclass for Users in Calibre-web, settings which are depending on certain users are stored here. It is derived from # User Base (all access methods are declared there) 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") sidebar_view = 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 for anonymous user is derived from User base and complets overrides methods and properties for the # anonymous user 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() settings = session.query(Settings).first() self.nickname = data.nickname self.role = data.role self.sidebar_view = data.sidebar_view 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 self.locale = data.locale self.anon_browse = settings.config_anonbrowse def role_admin(self): return False def is_active(self): return False def is_anonymous(self): return self.anon_browse # Baseclass representing Shelfs in calibre-web inapp.db class Shelf(Base): __tablename__ = 'shelf' id = Column(Integer, primary_key=True) name = Column(String) is_public = Column(Integer, default=0) user_id = Column(Integer, ForeignKey('user.id')) def __repr__(self): return '' % self.name # Baseclass representing Relationship between books and Shelfs in Calibre-web in app.db (N:M) class BookShelf(Base): __tablename__ = 'book_shelf_link' id = Column(Integer, primary_key=True) book_id = Column(Integer) order = Column(Integer) shelf = Column(Integer, ForeignKey('shelf.id')) def __repr__(self): return '' % self.id # Baseclass representing Downloads from calibre-web in app.db class Downloads(Base): __tablename__ = 'downloads' id = Column(Integer, primary_key=True) book_id = Column(Integer) user_id = Column(Integer, ForeignKey('user.id')) def __repr__(self): return '