PageRenderTime 29ms CodeModel.GetById 2ms app.highlight 22ms RepoModel.GetById 2ms app.codeStats 0ms

/lib/galaxy/webapps/community/model/__init__.py

https://bitbucket.org/cistrome/cistrome-harvard/
Python | 234 lines | 224 code | 3 blank | 7 comment | 4 complexity | 597dbd9fcb0544d0352a3749d0f2ddb0 MD5 | raw file
  1"""
  2Galaxy Tool Shed data model classes
  3
  4Naming: try to use class names that have a distinct plural form so that
  5the relationship cardinalities are obvious (e.g. prefer Dataset to Data)
  6"""
  7import os.path, os, errno, sys, codecs, operator, logging, tarfile, mimetypes, ConfigParser
  8from galaxy import util
  9from galaxy.util.bunch import Bunch
 10from galaxy.util.hash_util import *
 11from galaxy.web.form_builder import *
 12from mercurial import hg, ui
 13log = logging.getLogger( __name__ )
 14
 15class User( object ):
 16    def __init__( self, email=None, password=None ):
 17        self.email = email
 18        self.password = password
 19        self.external = False
 20        self.deleted = False
 21        self.purged = False
 22        self.username = None
 23    def set_password_cleartext( self, cleartext ):
 24        """Set 'self.password' to the digest of 'cleartext'."""
 25        self.password = new_secure_hash( text_type=cleartext )
 26    def check_password( self, cleartext ):
 27        """Check if 'cleartext' matches 'self.password' when hashed."""
 28        return self.password == new_secure_hash( text_type=cleartext )
 29
 30class Group( object ):
 31    def __init__( self, name = None ):
 32        self.name = name
 33        self.deleted = False
 34
 35class Role( object ):
 36    private_id = None
 37    types = Bunch( 
 38        PRIVATE = 'private',
 39        SYSTEM = 'system',
 40        USER = 'user',
 41        ADMIN = 'admin',
 42        SHARING = 'sharing'
 43    )
 44    def __init__( self, name="", description="", type="system", deleted=False ):
 45        self.name = name
 46        self.description = description
 47        self.type = type
 48        self.deleted = deleted
 49
 50class UserGroupAssociation( object ):
 51    def __init__( self, user, group ):
 52        self.user = user
 53        self.group = group
 54
 55class UserRoleAssociation( object ):
 56    def __init__( self, user, role ):
 57        self.user = user
 58        self.role = role
 59
 60class GroupRoleAssociation( object ):
 61    def __init__( self, group, role ):
 62        self.group = group
 63        self.role = role
 64
 65class GalaxySession( object ):
 66    def __init__( self, 
 67                  id=None, 
 68                  user=None, 
 69                  remote_host=None, 
 70                  remote_addr=None, 
 71                  referer=None, 
 72                  current_history=None, 
 73                  session_key=None, 
 74                  is_valid=False, 
 75                  prev_session_id=None ):
 76        self.id = id
 77        self.user = user
 78        self.remote_host = remote_host
 79        self.remote_addr = remote_addr
 80        self.referer = referer
 81        self.current_history = current_history
 82        self.session_key = session_key
 83        self.is_valid = is_valid
 84        self.prev_session_id = prev_session_id
 85
 86class Repository( object ):
 87    file_states = Bunch( NORMAL = 'n',
 88                         NEEDS_MERGING = 'm',
 89                         MARKED_FOR_REMOVAL = 'r',
 90                         MARKED_FOR_ADDITION = 'a',
 91                         NOT_TRACKED = '?' )
 92    def __init__( self, name=None, description=None, long_description=None, user_id=None, private=False, email_alerts=None, times_downloaded=0 ):
 93        self.name = name or "Unnamed repository"
 94        self.description = description
 95        self.long_description = long_description
 96        self.user_id = user_id
 97        self.private = private
 98        self.email_alerts = email_alerts
 99        self.times_downloaded = times_downloaded
100    @property
101    def repo_path( self ):
102        # Repository locations on disk are defined in the hgweb.config file
103        # in the Galaxy install directory.  An entry looks something like:
104        # repos/test/mira_assembler = database/community_files/000/repo_123
105        # TODO: handle this using the mercurial api.
106        lhs = "repos/%s/%s" % ( self.user.username, self.name )
107        hgweb_config = "%s/hgweb.config" %  os.getcwd()
108        if not os.path.exists( hgweb_config ):
109            raise Exception( "Required file hgweb.config does not exist in directory %s" % os.getcwd() )
110        config = ConfigParser.ConfigParser()
111        config.read( hgweb_config )
112        for option in config.options( "paths" ):
113            if option == lhs:
114                return config.get( "paths", option )
115        raise Exception( "Entry for repository %s missing in %s/hgweb.config file." % ( lhs, os.getcwd() ) )
116    @property
117    def revision( self ):
118        repo = hg.repository( ui.ui(), self.repo_path )
119        tip_ctx = repo.changectx( repo.changelog.tip() )
120        return "%s:%s" % ( str( tip_ctx.rev() ), str( repo.changectx( repo.changelog.tip() ) ) )
121    @property
122    def tip( self ):
123        repo = hg.repository( ui.ui(), self.repo_path )
124        return str( repo.changectx( repo.changelog.tip() ) )
125    @property
126    def is_new( self ):
127        repo = hg.repository( ui.ui(), self.repo_path )
128        tip_ctx = repo.changectx( repo.changelog.tip() )
129        return tip_ctx.rev() < 0
130    @property
131    def allow_push( self ):
132        repo = hg.repository( ui.ui(), self.repo_path )
133        return repo.ui.config( 'web', 'allow_push' )
134    def set_allow_push( self, usernames, remove_auth='' ):
135        allow_push = util.listify( self.allow_push )
136        if remove_auth:
137            allow_push.remove( remove_auth )
138        else:
139            for username in util.listify( usernames ):
140                if username not in allow_push:
141                    allow_push.append( username )
142        allow_push = '%s\n' % ','.join( allow_push )
143        repo = hg.repository( ui.ui(), path=self.repo_path )
144        # Why doesn't the following work?
145        #repo.ui.setconfig( 'web', 'allow_push', allow_push )
146        lines = repo.opener( 'hgrc', 'rb' ).readlines()
147        fp = repo.opener( 'hgrc', 'wb' )
148        for line in lines:
149            if line.startswith( 'allow_push' ):
150                fp.write( 'allow_push = %s' % allow_push )
151            else:
152                fp.write( line )
153        fp.close()
154
155class RepositoryMetadata( object ):
156    def __init__( self, repository_id=None, changeset_revision=None, metadata=None, malicious=False ):
157        self.repository_id = repository_id
158        self.changeset_revision = changeset_revision
159        self.metadata = metadata or dict()
160        self.malicious = malicious
161    
162class ItemRatingAssociation( object ):
163    def __init__( self, id=None, user=None, item=None, rating=0, comment='' ):
164        self.id = id
165        self.user = user
166        self.item = item
167        self.rating = rating
168        self.comment = comment
169    def set_item( self, item ):
170        """ Set association's item. """
171        pass
172
173class RepositoryRatingAssociation( ItemRatingAssociation ):
174    def set_item( self, repository ):
175        self.repository = repository
176
177class Category( object ):
178    def __init__( self, name=None, description=None, deleted=False ):
179        self.name = name
180        self.description = description
181        self.deleted = deleted
182
183class RepositoryCategoryAssociation( object ):
184    def __init__( self, repository=None, category=None ):
185        self.repository = repository
186        self.category = category
187
188class Tag ( object ):
189    def __init__( self, id=None, type=None, parent_id=None, name=None ):
190        self.id = id
191        self.type = type
192        self.parent_id = parent_id
193        self.name = name
194    def __str__ ( self ):
195        return "Tag(id=%s, type=%i, parent_id=%s, name=%s)" %  ( self.id, self.type, self.parent_id, self.name )
196
197class ItemTagAssociation ( object ):
198    def __init__( self, id=None, user=None, item_id=None, tag_id=None, user_tname=None, value=None ):
199        self.id = id
200        self.user = user
201        self.item_id = item_id
202        self.tag_id = tag_id
203        self.user_tname = user_tname
204        self.value = None
205        self.user_value = None
206
207## ---- Utility methods -------------------------------------------------------
208def sort_by_attr( seq, attr ):
209    """
210    Sort the sequence of objects by object's attribute
211    Arguments:
212    seq  - the list or any sequence (including immutable one) of objects to sort.
213    attr - the name of attribute to sort by
214    """
215    # Use the "Schwartzian transform"
216    # Create the auxiliary list of tuples where every i-th tuple has form
217    # (seq[i].attr, i, seq[i]) and sort it. The second item of tuple is needed not
218    # only to provide stable sorting, but mainly to eliminate comparison of objects
219    # (which can be expensive or prohibited) in case of equal attribute values.
220    intermed = map( None, map( getattr, seq, ( attr, ) * len( seq ) ), xrange( len( seq ) ), seq )
221    intermed.sort()
222    return map( operator.getitem, intermed, ( -1, ) * len( intermed ) )
223def directory_hash_id( id ):
224    s = str( id )
225    l = len( s )
226    # Shortcut -- ids 0-999 go under ../000/
227    if l < 4:
228        return [ "000" ]
229    # Pad with zeros until a multiple of three
230    padded = ( ( ( 3 - len( s ) ) % 3 ) * "0" ) + s
231    # Drop the last three digits -- 1000 files per directory
232    padded = padded[:-3]
233    # Break into chunks of three
234    return [ padded[i*3:(i+1)*3] for i in range( len( padded ) // 3 ) ]