Browse Source

environment class

get_session
pull/1/merge
Ruud 14 years ago
parent
commit
cdde98653e
  1. 23
      couchpotato/__init__.py
  2. 10
      couchpotato/api/__init__.py
  3. 33
      couchpotato/cli.py
  4. 6
      couchpotato/core/auth.py
  5. 2
      couchpotato/core/settings/__init__.py
  6. 64
      couchpotato/core/settings/db.py
  7. 24
      couchpotato/core/settings/model.py
  8. 24
      couchpotato/environment.py

23
couchpotato/__init__.py

@ -1,10 +1,14 @@
from couchpotato.core.auth import requires_auth from couchpotato.core.auth import requires_auth
from couchpotato.core.logger import CPLog from couchpotato.core.logger import CPLog
from couchpotato.environment import Env
from flask.app import Flask from flask.app import Flask
from flask.globals import request from flask.globals import request
from flask.helpers import url_for from flask.helpers import url_for
from flask.module import Module from flask.module import Module
from flask.templating import render_template from flask.templating import render_template
from sqlalchemy.engine import create_engine
from sqlalchemy.orm import scoped_session
from sqlalchemy.orm.session import sessionmaker
from werkzeug.utils import redirect from werkzeug.utils import redirect
import os import os
@ -12,6 +16,12 @@ app = Flask(__name__)
log = CPLog(__name__) log = CPLog(__name__)
web = Module(__name__, 'web') web = Module(__name__, 'web')
def get_session(engine):
engine = engine if engine else get_engine()
return scoped_session(sessionmaker(autoflush = True, transactional = True, bind = engine))
def get_engine():
return create_engine('sqlite:///' + Env.get('db_path'), echo = Env.get('debug'))
@web.route('/') @web.route('/')
@requires_auth @requires_auth
@ -23,16 +33,3 @@ def page_not_found(error):
index_url = url_for('web.index') index_url = url_for('web.index')
url = request.path[len(index_url):] url = request.path[len(index_url):]
return redirect(index_url + '#' + url) return redirect(index_url + '#' + url)
@web.route('/exit')
@requires_auth
def exit():
# stopping code
pass
@web.route('/restart')
@requires_auth
def restart():
# restart code
pass

10
couchpotato/api/__init__.py

@ -1,6 +1,7 @@
from couchpotato.api.file_browser import FileBrowser from couchpotato.api.file_browser import FileBrowser
from couchpotato.core.settings import settings
from couchpotato.core.settings.loader import settings_loader from couchpotato.core.settings.loader import settings_loader
from couchpotato.core.settings.model import Resource
from couchpotato.environment import Env
from flask import Module from flask import Module
from flask.helpers import jsonify from flask.helpers import jsonify
import flask import flask
@ -16,7 +17,7 @@ def index():
def settings_view(): def settings_view():
return jsonify({ return jsonify({
'sections': settings_loader.sections, 'sections': settings_loader.sections,
'values': settings.getValues() 'values': Env.get('settings').getValues()
}) })
@api.route('setting.save/') @api.route('setting.save/')
@ -27,8 +28,8 @@ def setting_save_view():
option = a.get('name') option = a.get('name')
value = a.get('value') value = a.get('value')
settings.set(section, option, value) Env.get('settings').set(section, option, value)
settings.save() Env.get('settings').save()
return jsonify({ return jsonify({
'success': True, 'success': True,
@ -36,6 +37,7 @@ def setting_save_view():
@api.route('movie/') @api.route('movie/')
def movie(): def movie():
return jsonify({ return jsonify({
'success': True, 'success': True,
'movies': [ 'movies': [

33
couchpotato/cli.py

@ -1,6 +1,8 @@
from argparse import ArgumentParser from argparse import ArgumentParser
from couchpotato import web from couchpotato import get_engine, web
from couchpotato.api import api from couchpotato.api import api
from couchpotato.core.settings.model import *
from couchpotato.environment import Env
from libs.daemon import createDaemon from libs.daemon import createDaemon
from logging import handlers from logging import handlers
import logging import logging
@ -13,8 +15,8 @@ def cmd_couchpotato(base_path, args):
# Options # Options
parser = ArgumentParser() parser = ArgumentParser()
parser.add_argument('-s', '--datadir', default = base_path, parser.add_argument('-s', '--datadir', default = os.path.join(base_path, '_data'),
dest = 'data_dir', help = 'Absolute or ~/ path, where settings/logs/database data is saved (default ./)') dest = 'data_dir', help = 'Absolute or ~/ path, where settings/logs/database data is saved (default ./_data)')
parser.add_argument('-t', '--test', '--debug', action = 'store_true', parser.add_argument('-t', '--test', '--debug', action = 'store_true',
dest = 'debug', help = 'Debug mode') dest = 'debug', help = 'Debug mode')
parser.add_argument('-q', '--quiet', action = 'store_true', parser.add_argument('-q', '--quiet', action = 'store_true',
@ -41,12 +43,15 @@ def cmd_couchpotato(base_path, args):
createDaemon() createDaemon()
# Register settings # Register environment settings
from couchpotato.core.settings import settings Env.get('settings').setFile(os.path.join(options.data_dir, 'settings.conf'))
settings.setFile(os.path.join(options.data_dir, 'settings.conf')) Env.set('app_dir', base_path)
Env.set('data_dir', options.data_dir)
Env.set('db_path', os.path.join(options.data_dir, 'couchpotato.db'))
# Determine debug # Determine debug
debug = options.debug or settings.get('debug', default = False) debug = options.debug or Env.get('settings').get('debug', default = False)
Env.set('debug', debug)
# Logger # Logger
@ -83,15 +88,21 @@ def cmd_couchpotato(base_path, args):
settings_loader.run() settings_loader.run()
# Configure Database
from elixir import setup_all, create_all
setup_all()
create_all(get_engine())
# Create app # Create app
from couchpotato import app from couchpotato import app
api_key = settings.get('api_key') api_key = Env.get('settings').get('api_key')
url_base = '/' + settings.get('url_base') if settings.get('url_base') else '' url_base = '/' + Env.get('settings').get('url_base') if Env.get('settings').get('url_base') else ''
reloader = debug and not options.daemonize reloader = debug and not options.daemonize
# Basic config # Basic config
app.host = settings.get('host', default = '0.0.0.0') app.host = Env.get('settings').get('host', default = '0.0.0.0')
app.port = settings.get('port', default = 5000) app.port = Env.get('settings').get('port', default = 5000)
app.debug = debug app.debug = debug
app.secret_key = api_key app.secret_key = api_key
app.static_path = url_base + '/static' app.static_path = url_base + '/static'

6
couchpotato/core/auth.py

@ -1,9 +1,9 @@
from couchpotato.core.settings import settings from couchpotato.environment import Env
from flask import request, Response from flask import request, Response
from functools import wraps from functools import wraps
def check_auth(username, password): def check_auth(username, password):
return username == settings.get('username') and password == settings.get('password') return username == Env.get('settings').get('username') and password == Env.get('settings').get('password')
def authenticate(): def authenticate():
return Response( return Response(
@ -16,7 +16,7 @@ def requires_auth(f):
@wraps(f) @wraps(f)
def decorated(*args, **kwargs): def decorated(*args, **kwargs):
auth = request.authorization auth = request.authorization
if settings.get('username') and (not auth or not check_auth(auth.username, auth.password)): if Env.get('settings').get('username') and (not auth or not check_auth(auth.username, auth.password)):
return authenticate() return authenticate()
return f(*args, **kwargs) return f(*args, **kwargs)

2
couchpotato/core/settings/__init__.py

@ -94,5 +94,3 @@ class Settings():
return True return True
except ValueError: except ValueError:
return False return False
settings = Settings()

64
couchpotato/core/settings/db.py

@ -1,64 +0,0 @@
import sqlalchemy as sa
from sqlalchemy import orm
class DatabaseError(Exception):
"""Custom exceptions related to the database."""
pass
def _session_cls_cache(cache={}):
"""Holds a dictionary to cache session objects."""
return cache
def get_session(engine=None, test=False):
"""
Get the current session or create a new one based on the engine.
>>> from couchpotato import db
>>> from sqlalchemy import create_engine
>>> engine = create_engine('sqlite:///:memory:')
>>> session = db.get_session(engine)
>>> session #doctest: +ELLIPSIS
<sqlalchemy.orm.session.Session object at ...>
Once a session has been created, get_session will return session instances
of the same Session class.
>>> type(session) == type(db.get_session())
True
If you create multiple sessions for different engines, you need to
specify which session you want by passing the engine explicitely.
>>> other_engine = create_engine('sqlite:///:memory:')
>>> other_session = db.get_session(other_engine)
>>> type(other_session) is type(db.get_session(other_engine))
True
"""
cache = _session_cls_cache()
assert not(engine and test), "Cannot pass both test and engine."
# It doesn't make sense to both pass an engine and instruct the function
# to create a new engine. Decide what you want to do, but not both.
if test:
in_memory = sa.create_engine('sqlite:///:memory:')
session = orm.sessionmaker(bind=in_memory)()
# create Session class ^ ^
# create Session instance ^
elif engine:
key = (engine, )
if key not in cache:
cache[key] = orm.sessionmaker(bind=engine)
session = cache[key]()
elif len(cache) == 1:
session = (cache[key] for key in cache).next()()
# return the first element ^ ^
# instantiate session ^
elif len(cache) >= 1:
raise DatabaseError("Multiple Session classes found. Choose one.")
else:
raise DatabaseError("No session found. You need to create one.")
return session

24
couchpotato/core/settings/model.py

@ -1,7 +1,10 @@
from elixir import * from elixir.entity import Entity
from sqlalchemy import create_engine from elixir.fields import Field
from sqlalchemy.orm import scoped_session, sessionmaker from elixir.options import options_defaults
from sqlalchemy.schema import ThreadLocalMetaData from elixir.relationships import OneToMany, ManyToOne
from sqlalchemy.types import Integer, String, Unicode
options_defaults["shortnames"] = True
# We would like to be able to create this schema in a specific database at # We would like to be able to create this schema in a specific database at
# will, so we can test it easily. # will, so we can test it easily.
@ -10,12 +13,11 @@ from sqlalchemy.schema import ThreadLocalMetaData
# http://elixir.ematia.de/trac/wiki/Recipes/MultipleDatabasesOneMetadata # http://elixir.ematia.de/trac/wiki/Recipes/MultipleDatabasesOneMetadata
__session__ = None __session__ = None
class Resource(Entity): class Resource(Entity):
"""Represents a resource of movies. This recources can be online or """Represents a resource of movies.
offline.""" This resources can be online or offline."""
name = Field(UnicodeString(255)) name = Field(Unicode(255))
path = Field(UnicodeString(255)) path = Field(Unicode(255))
releases = OneToMany('Release') releases = OneToMany('Release')
@ -30,7 +32,7 @@ class Release(Entity):
class File(Entity): class File(Entity):
"""File that belongs to a release.""" """File that belongs to a release."""
history = OneToMany('RenameHistory') history = OneToMany('RenameHistory')
path = Field(UnicodeString(255), nullable = False, unique = True) path = Field(Unicode(255), nullable = False, unique = True)
# Subtitles can have multiple parts, too # Subtitles can have multiple parts, too
part = Field(Integer) part = Field(Integer)
release = ManyToOne('Release') release = ManyToOne('Release')
@ -42,7 +44,7 @@ class File(Entity):
class FileType(Entity): class FileType(Entity):
"""Types could be trailer, subtitle, movie, partial movie etc.""" """Types could be trailer, subtitle, movie, partial movie etc."""
identifier = Field(String(20), unique = True) identifier = Field(String(20), unique = True)
name = Field(UnicodeString(255), nullable = False) name = Field(Unicode(255), nullable = False)
files = OneToMany('File') files = OneToMany('File')

24
couchpotato/environment.py

@ -0,0 +1,24 @@
from couchpotato.core.settings import Settings
class Env:
_debug = False
_settings = Settings()
_options = None
_args = None
_quiet = False
_app_dir = ""
_data_dir = ""
_db_path = ""
@staticmethod
def doDebug():
return Env._debug
@staticmethod
def get(attr):
return getattr(Env, '_' + attr)
@staticmethod
def set(attr, value):
return setattr(Env, '_' + attr, value)
Loading…
Cancel
Save