Add decorators.@required_feature to centralize FeatureDisabled exc.

This commit is contained in:
voussoir 2017-05-01 20:41:56 -07:00
parent af6785cead
commit 09f209719b
4 changed files with 35 additions and 27 deletions

View file

@ -154,6 +154,7 @@ DEFAULT_CONFIGURATION = {
'cache_size_tag': 1000, 'cache_size_tag': 1000,
'cache_size_user': 200, 'cache_size_user': 200,
'enable_album_edit': True,
'enable_new_album': True, 'enable_new_album': True,
'enable_new_bookmark': True, 'enable_new_bookmark': True,
'enable_new_photo': True, 'enable_new_photo': True,

View file

@ -7,6 +7,30 @@ import warnings
from . import jsonify from . import jsonify
def required_feature(features):
'''
Declare that the photodb or object method requires certain 'enable_*'
fields in the config.
'''
from . import objects
if isinstance(features, str):
features = [features]
def wrapper(function):
@functools.wraps(function)
def wrapped(self, *args, **kwargs):
if isinstance(self, objects.ObjectBase):
config = self.photodb.config
else:
config = self.config
if not all(config[key] for key in features):
raise exceptions.FeatureDisabled(function.__name__)
return function(self, *args, **kwargs)
return wrapped
return wrapper
def required_fields(fields, forbid_whitespace=False): def required_fields(fields, forbid_whitespace=False):
''' '''
Declare that the endpoint requires certain POST body fields. Without them, Declare that the endpoint requires certain POST body fields. Without them,

View file

@ -307,6 +307,7 @@ class Album(ObjectBase, GroupableMixin):
else: else:
return self.id return self.id
@decorators.required_feature('enable_album_edit')
@decorators.transaction @decorators.transaction
def edit(self, title=None, description=None, *, commit=True): def edit(self, title=None, description=None, *, commit=True):
''' '''
@ -488,11 +489,9 @@ class Photo(ObjectBase):
def _uncache(self): def _uncache(self):
self.photodb.caches['photo'].remove(self.id) self.photodb.caches['photo'].remove(self.id)
@decorators.required_feature('enable_photo_add_remove_tag')
@decorators.transaction @decorators.transaction
def add_tag(self, tag, *, commit=True): def add_tag(self, tag, *, commit=True):
if not self.photodb.config['enable_photo_add_remove_tag']:
raise exceptions.FeatureDisabled('photo.add_tag, photo.remove_tag')
tag = self.photodb.get_tag(tag) tag = self.photodb.get_tag(tag)
existing = self.has_tag(tag, check_children=False) existing = self.has_tag(tag, check_children=False)
@ -577,15 +576,13 @@ class Photo(ObjectBase):
return helpers.seconds_to_hms(self.duration) return helpers.seconds_to_hms(self.duration)
#@decorators.time_me #@decorators.time_me
@decorators.required_feature('enable_photo_generate_thumbnail')
@decorators.transaction @decorators.transaction
def generate_thumbnail(self, *, commit=True, **special): def generate_thumbnail(self, *, commit=True, **special):
''' '''
special: special:
For videos, you can provide a `timestamp` to take the thumbnail at. For videos, you can provide a `timestamp` to take the thumbnail at.
''' '''
if not self.photodb.config['enable_photo_generate_thumbnail']:
raise exceptions.FeatureDisabled('photo.generate_thumbnail')
hopeful_filepath = self.make_thumbnail_filepath() hopeful_filepath = self.make_thumbnail_filepath()
hopeful_filepath = hopeful_filepath.relative_path hopeful_filepath = hopeful_filepath.relative_path
#print(hopeful_filepath) #print(hopeful_filepath)
@ -714,14 +711,12 @@ class Photo(ObjectBase):
return hopeful_filepath return hopeful_filepath
#@decorators.time_me #@decorators.time_me
@decorators.required_feature('enable_photo_reload_metadata')
@decorators.transaction @decorators.transaction
def reload_metadata(self, *, commit=True): def reload_metadata(self, *, commit=True):
''' '''
Load the file's height, width, etc as appropriate for this type of file. Load the file's height, width, etc as appropriate for this type of file.
''' '''
if not self.photodb.config['enable_photo_reload_metadata']:
raise exceptions.FeatureDisabled('photo.reload_metadata')
self.bytes = os.path.getsize(self.real_filepath) self.bytes = os.path.getsize(self.real_filepath)
self.width = None self.width = None
self.height = None self.height = None
@ -806,11 +801,9 @@ class Photo(ObjectBase):
self.photodb.log.debug('Commit - relocate photo') self.photodb.log.debug('Commit - relocate photo')
self.photodb.commit() self.photodb.commit()
@decorators.required_feature('enable_photo_add_remove_tag')
@decorators.transaction @decorators.transaction
def remove_tag(self, tag, *, commit=True): def remove_tag(self, tag, *, commit=True):
if not self.photodb.config['enable_photo_add_remove_tag']:
raise exceptions.FeatureDisabled('photo.add_tag, photo.remove_tag')
tag = self.photodb.get_tag(tag) tag = self.photodb.get_tag(tag)
self.photodb.log.debug('Removing tag {t} from photo {p}'.format(t=repr(tag), p=repr(self))) self.photodb.log.debug('Removing tag {t} from photo {p}'.format(t=repr(tag), p=repr(self)))

View file

@ -280,6 +280,7 @@ class PDBAlbumMixin:
if album.parent() is None: if album.parent() is None:
yield album yield album
@decorators.required_feature('enable_new_album')
@decorators.transaction @decorators.transaction
def new_album( def new_album(
self, self,
@ -293,9 +294,6 @@ class PDBAlbumMixin:
''' '''
Create a new album. Photos can be added now or later. Create a new album. Photos can be added now or later.
''' '''
if not self.config['enable_new_album']:
raise exceptions.FeatureDisabled('new_album')
albumid = self.generate_id('albums') albumid = self.generate_id('albums')
title = title or '' title = title or ''
description = description or '' description = description or ''
@ -365,11 +363,9 @@ class PDBBookmarkMixin:
def get_bookmarks(self): def get_bookmarks(self):
yield from self.get_things(thing_type='bookmark') yield from self.get_things(thing_type='bookmark')
@decorators.required_feature('enable_new_bookmark')
@decorators.transaction @decorators.transaction
def new_bookmark(self, url, title=None, *, author=None, commit=True): def new_bookmark(self, url, title=None, *, author=None, commit=True):
if not self.config['enable_new_bookmark']:
raise exceptions.FeatureDisabled('new_bookmark')
if not url: if not url:
raise ValueError('Must provide a URL') raise ValueError('Must provide a URL')
@ -440,6 +436,7 @@ class PDBPhotoMixin:
if count <= 0: if count <= 0:
break break
@decorators.required_feature('enable_new_photo')
@decorators.transaction @decorators.transaction
def new_photo( def new_photo(
self, self,
@ -461,9 +458,6 @@ class PDBPhotoMixin:
Returns the Photo object. Returns the Photo object.
''' '''
if not self.config['enable_new_photo']:
raise exceptions.FeatureDisabled('new_photo')
filepath = pathclass.Path(filepath) filepath = pathclass.Path(filepath)
if not filepath.is_file: if not filepath.is_file:
raise FileNotFoundError(filepath.absolute_path) raise FileNotFoundError(filepath.absolute_path)
@ -954,14 +948,12 @@ class PDBTagMixin:
def get_tags(self): def get_tags(self):
yield from self.get_things(thing_type='tag') yield from self.get_things(thing_type='tag')
@decorators.required_feature('enable_new_tag')
@decorators.transaction @decorators.transaction
def new_tag(self, tagname, *, commit=True): def new_tag(self, tagname, *, commit=True):
''' '''
Register a new tag and return the Tag object. Register a new tag and return the Tag object.
''' '''
if not self.config['enable_new_tag']:
raise exceptions.FeatureDisabled('new_tag')
tagname = self.normalize_tagname(tagname) tagname = self.normalize_tagname(tagname)
try: try:
existing_tag = self.get_tag_by_name(tagname) existing_tag = self.get_tag_by_name(tagname)
@ -1080,11 +1072,9 @@ class PDBUserMixin:
return objects.User(self, fetch) return objects.User(self, fetch)
@decorators.required_feature('enable_new_user')
@decorators.transaction @decorators.transaction
def register_user(self, username, password, commit=True): def register_user(self, username, password, commit=True):
if not self.config['enable_new_user']:
raise exceptions.FeatureDisabled('new_user')
if len(username) < self.config['min_username_length']: if len(username) < self.config['min_username_length']:
raise exceptions.UsernameTooShort( raise exceptions.UsernameTooShort(
username=username, username=username,