first take on TS group manager

introduce TS manager classes
This commit is contained in:
Martin Cech
2015-06-09 16:13:07 -04:00
parent 6c9f924baf
commit 7378e445c4
4 changed files with 223 additions and 41 deletions
+45 -41
View File
@@ -3,12 +3,14 @@ import os
from galaxy import util
from galaxy import web
from galaxy import exceptions
from galaxy.exceptions import RequestParameterMissingException
from galaxy.exceptions import AdminRequiredException
from galaxy.web import require_admin as require_admin
from galaxy.web import _future_expose_api as expose_api
from galaxy.web import _future_expose_api_anonymous as expose_api_anonymous
from galaxy.web import _future_expose_api_anonymous_and_sessionless as expose_api_anonymous_and_sessionless
from galaxy.web.base.controller import BaseAPIController
from tool_shed.managers import groups
import tool_shed.util.shed_util_common as suc
log = logging.getLogger( __name__ )
@@ -17,10 +19,49 @@ log = logging.getLogger( __name__ )
class GroupsController( BaseAPIController ):
"""RESTful controller for interactions with groups in the Tool Shed."""
def __init__( self, app ):
super( GroupsController, self ).__init__( app )
self.group_manager = groups.GroupManager()
def __get_value_mapper( self, trans ):
value_mapper = { 'id' : trans.security.encode_id }
return value_mapper
@expose_api_anonymous_and_sessionless
def index( self, trans, deleted=False, **kwd ):
"""
GET /api/groups
Return a list of dictionaries that contain information about each Group.
:param deleted: flag used to include deleted groups
Example: GET localhost:9009/api/groups
"""
model = trans.app.model
group_dicts = []
deleted = util.asbool( deleted )
if deleted and not trans.user_is_admin():
raise AdminRequiredException( 'Only administrators can query deleted groups.' )
for group in self.group_manager.list( trans ):
group_dict = group.to_dict( view='collection', value_mapper=self.__get_value_mapper( trans ) )
group_members = []
for uga in group.users:
member = ( trans.sa_session.query( model.User ).filter( model.User.table.c.id == uga.user_id ).one() )
member_repositories = []
for repo in trans.sa_session.query( model.Repository ) \
.filter( model.Repository.table.c.user_id == uga.user_id ) \
.join( model.RepositoryMetadata.table ) \
.join( model.User.table ) \
.outerjoin( model.RepositoryCategoryAssociation.table ) \
.outerjoin( model.Category.table ):
member_repositories.append( { 'name': repo.name, 'times_downloaded': repo.times_downloaded } )
member_dict = { 'username' : member.username, 'repositories': member_repositories }
group_members.append( member_dict )
group_dict[ 'members' ] = group_members
group_dicts.append( group_dict )
return group_dicts
@expose_api
@require_admin
def create( self, trans, payload, **kwd ):
@@ -53,48 +94,9 @@ class GroupsController( BaseAPIController ):
group_dict = group.to_dict( view='element',
value_mapper=self.__get_value_mapper( trans ) )
else:
raise exceptions.RequestParameterMissingException( 'Missing required parameter "name".' )
raise RequestParameterMissingException( 'Missing required parameter "name".' )
return group_dict
@expose_api_anonymous_and_sessionless
def index( self, trans, deleted=False, **kwd ):
"""
GET /api/groups
Return a list of dictionaries that contain information about each Group.
:param deleted: flag used to include deleted groups
Example: GET localhost:9009/api/groups
"""
model = trans.app.model
group_dicts = []
deleted = util.asbool( deleted )
if deleted and not trans.user_is_admin():
raise exceptions.AdminRequiredException( 'Only administrators can query deleted groups.' )
for group in trans.sa_session.query( model.Group ) \
# .enable_eagerloads( True ) \
.filter( model.Group.table.c.deleted == deleted ) \
.order_by( model.Group.table.c.name ):
group_dict = group.to_dict( view='collection', value_mapper=self.__get_value_mapper( trans ) )
group_members = []
for uga in group.users:
member = ( trans.sa_session.query( model.User ).filter( model.User.table.c.id == uga.user_id ).one() )
member_repositories = []
for repo in trans.sa_session.query( model.Repository ) \
.filter( model.Repository.table.c.user_id == uga.user_id ) \
.join( model.RepositoryMetadata.table ) \
.join( model.User.table ) \
.outerjoin( model.RepositoryCategoryAssociation.table ) \
.outerjoin( model.Category.table ):
member_repositories.append( { 'name': repo.name, 'times_downloaded': repo.times_downloaded } )
member_dict = { 'username' : member.username, 'repositories': member_repositories }
group_members.append( member_dict )
group_dict[ 'members' ] = group_members
group_dicts.append( group_dict )
return group_dicts
@expose_api_anonymous_and_sessionless
def show( self, trans, id, **kwd ):
"""
@@ -112,3 +114,5 @@ class GroupsController( BaseAPIController ):
return group_dict
group_dict = group.to_dict( view='element', value_mapper=self.__get_value_mapper( trans ) )
return group_dict
View File
+110
View File
@@ -0,0 +1,110 @@
"""
Manager and Serializer for TS groups.
"""
from galaxy.exceptions import InconsistentDatabase
from galaxy.exceptions import RequestParameterInvalidException
from galaxy.exceptions import InternalServerError
from galaxy.exceptions import ItemAccessibilityException
from sqlalchemy.orm.exc import MultipleResultsFound
from sqlalchemy.orm.exc import NoResultFound
import logging
log = logging.getLogger( __name__ )
# =============================================================================
class GroupManager( object ):
"""
Interface/service object for interacting with TS groups.
"""
def __init__( self, *args, **kwargs ):
super( GroupManager, self ).__init__( *args, **kwargs )
def get( self, trans, decoded_group_id ):
"""
Get the group from the DB.
:param decoded_group_id: decoded group id
:type decoded_group_id: int
:returns: the requested group
:rtype: Group
"""
try:
group = trans.sa_session.query( trans.app.model.Group ).filter( trans.app.model.Group.table.c.id == decoded_group_id ).one()
except MultipleResultsFound:
raise InconsistentDatabase( 'Multiple groups found with the same id.' )
except NoResultFound:
raise RequestParameterInvalidException( 'No group found with the id provided.' )
except Exception, e:
raise InternalServerError( 'Error loading from the database.' )
return group
def create( self, trans, name, description=''):
"""
Create a new group.
"""
if not trans.user_is_admin:
raise ItemAccessibilityException( 'Only administrators can create groups.' )
else:
group = trans.app.model.Group( name=name, description=description )
trans.sa_session.add( group )
trans.sa_session.flush()
return group
def update( self, trans, group, name=None, description=None ):
"""
Update the given group
"""
changed = False
if not trans.user_is_admin():
raise ItemAccessibilityException( 'Only administrators can update groups.' )
if group.deleted:
raise RequestParameterInvalidException( 'You cannot modify a deleted group. Undelete it first.' )
if name is not None:
group.name = name
changed = True
if description is not None:
group.description = description
changed = True
if changed:
trans.sa_session.add( group )
trans.sa_session.flush()
return group
def delete( self, trans, group, undelete=False ):
"""
Mark given group deleted/undeleted based on the flag.
"""
if not trans.user_is_admin():
raise ItemAccessibilityException( 'Only administrators can delete and undelete groups.' )
if undelete:
group.deleted = False
else:
group.deleted = True
trans.sa_session.add( group )
trans.sa_session.flush()
return group
def list( self, trans, deleted=False ):
"""
Return a list of groups from the DB.
:returns: query that will emit all groups
:rtype: sqlalchemy query
"""
is_admin = trans.user_is_admin()
query = trans.sa_session.query( trans.app.model.Group )
if is_admin:
if deleted is None:
# Flag is not specified, do not filter on it.
pass
elif deleted:
query = query.filter( trans.app.model.Group.table.c.deleted == True )
else:
query = query.filter( trans.app.model.Group.table.c.deleted == False )
else:
query = query.filter( trans.app.model.Group.table.c.deleted == False )
return query
+68
View File
@@ -0,0 +1,68 @@
"""
Manager and Serializer for TS repositories.
"""
from galaxy.exceptions import InconsistentDatabase
from galaxy.exceptions import RequestParameterInvalidException
from galaxy.exceptions import InternalServerError
from galaxy.exceptions import ItemAccessibilityException
from sqlalchemy.orm.exc import MultipleResultsFound
from sqlalchemy.orm.exc import NoResultFound
import logging
log = logging.getLogger( __name__ )
# =============================================================================
class RepoManager( object ):
"""
Interface/service object for interacting with TS repositories.
"""
def __init__( self, *args, **kwargs ):
super( RepoManager, self ).__init__( *args, **kwargs )
def get( self, trans, decoded_repo_id ):
"""
Get the repo from the DB.
:param decoded_repo_id: decoded repo id
:type decoded_repo_id: int
:returns: the requested repo
:rtype: Repository
"""
try:
repo = trans.sa_session.query( trans.app.model.Repository ).filter( trans.app.model.Repository.table.c.id == decoded_repo_id ).one()
except MultipleResultsFound:
raise exceptions.InconsistentDatabase( 'Multiple repositories found with the same id.' )
except NoResultFound:
raise exceptions.RequestParameterInvalidException( 'No repository found with the id provided.' )
except Exception, e:
raise exceptions.InternalServerError( 'Error loading from the database.' )
return repo
def list_by_owner( self, trans, user_id ):
"""
Return a list of of repositories owned by a given TS user from the DB.
:returns: query that will emit repositories owned by given user
:rtype: sqlalchemy query
"""
query = trans.sa_session.query( trans.app.model.Repository ).filter( trans.app.model.Repository.table.c.user_id == user_id )
return query
def create( self, trans, name, description=''):
"""
Create a new group.
"""
def update( self, trans, group, name=None, description=None ):
"""
Update the given group
"""
def delete( self, trans, group, undelete=False ):
"""
Mark given group deleted/undeleted based on the flag.
"""