def main(argv=sys.argv): if len(argv) != 2: usage(argv) config_uri = argv[1] setup_logging(config_uri) settings = get_appsettings(config_uri) engine = engine_from_config(settings, 'sqlalchemy.') DBSession.configure(bind=engine) Base.metadata.create_all(engine) init_instances()
def verify_email(self): email = self.request.params["email"] verification = EmailVerification(email) DBSession.add(verification) DBSession.flush() user = verification.email.user mailer = self.request.registry["mailer"] message = Message( recipients=[email], subject="%s email verification" % self.request.registry.settings["site_title"], body=render_template( "../templates/account/verify_email.txt", view=self, request=self.request, verification=verification ), ) mailer.send(message) return dict(verification=verification)
def __init__(self, collection): self.collection = collection self.delimiter = self._delimiter_map[csv.excel.delimiter] self.lineterminator = self._lineterminator_map[ csv.excel.lineterminator] self.quotechar = self._quotechar_map[csv.excel.quotechar] self.quoting = self._quoting_map[csv.excel.quoting] self.doublequote = csv.excel.doublequote self.dateformat = '%Y-%m-%d' self.all_columns = [ ('id', 'Identifier'), ('description', 'Description'), ('created', 'Created'), ('destroyed', 'Destroyed'), ('location', 'Location'), # XXX Figure out a reasonable cross-database way of including this # (SQLite supports GROUP_CONCAT, PostgreSQL has a string_agg but # only in 9+, or we could use Python expressions if we don't care # about efficieny...) #('parents' , 'Parents') , #('children' , 'Children') , ] self.all_columns.extend( DBSession.query('code_' + SampleCode.name, SampleCode.name).\ join(Sample).\ join(Collection).\ filter(Collection.id==collection.id).\ distinct().all()) self.columns = [name for (name, title) in self.all_columns] self.all_columns = dict(self.all_columns)
def __init__(self, collection): self.collection = collection self.delimiter = self._delimiter_map[csv.excel.delimiter] self.lineterminator = self._lineterminator_map[csv.excel.lineterminator] self.quotechar = self._quotechar_map[csv.excel.quotechar] self.quoting = self._quoting_map[csv.excel.quoting] self.doublequote = csv.excel.doublequote self.dateformat = '%Y-%m-%d' self.all_columns = [ ('id' , 'Identifier') , ('description' , 'Description') , ('created' , 'Created') , ('destroyed' , 'Destroyed') , ('location' , 'Location') , # XXX Figure out a reasonable cross-database way of including this # (SQLite supports GROUP_CONCAT, PostgreSQL has a string_agg but # only in 9+, or we could use Python expressions if we don't care # about efficieny...) #('parents' , 'Parents') , #('children' , 'Children') , ] self.all_columns.extend( DBSession.query('code_' + SampleCode.name, SampleCode.name).\ join(Sample).\ join(Collection).\ filter(Collection.id==collection.id).\ distinct().all()) self.columns = [name for (name, title) in self.all_columns] self.all_columns = dict(self.all_columns)
def __init__(self, request): super(CollectionContextFactory, self).__init__(request) self.collection = DBSession.query(Collection).\ filter_by(id=request.matchdict['collection_id']).one() # If the collection has an open-license grant view permission to anyone if self.collection.license.is_open: self.__acl__.append((Allow, Everyone, (VIEW_COLLECTION, )))
def create(self): # TODO Determine user timezone as default form = Form(self.request, schema=AccountCreateSchema) if form.validate(): new_user = form.bind(User()) DBSession.add(new_user) new_email = form.bind(EmailAddress()) new_email.user = new_user DBSession.add(new_email) new_collection = Collection() new_collection.name = 'Default' new_collection.owner = new_user.full_name owner_role = DBSession.query(Role).filter(Role.id == 'owner').one() new_user.collections[new_collection] = owner_role return HTTPFound(location=self.request.route_url( 'account_verify_email', _query=dict(email=form.data['email']))) return dict(form=FormRenderer(form))
def create(self): form = Form( self.request, schema=CollectionCreateSchema, variable_decode=True, defaults=dict(owner=self.request.user.full_name)) if form.validate(): new_collection = form.bind(Collection()) # Hard-code ownership to currently authenticated user new_collection.users[self.request.user] = DBSession.query(Role).\ filter(Role.id==OWNER_ROLE).one() DBSession.add(new_collection) DBSession.flush() return HTTPFound( location=self.request.route_url( 'collections_view', collection_id=new_collection.id)) return dict(form=FormRenderer(form))
def verify_email(self): email = self.request.params['email'] verification = EmailVerification(email) DBSession.add(verification) DBSession.flush() user = verification.email.user mailer = self.request.registry['mailer'] message = Message( recipients=[email], subject='%s email verification' % self.request.registry.settings['site_title'], body=render(renderer_name='../templates/account/verify_email.txt', value=dict(view=self, request=self.request, verification=verification), request=self.request)) mailer.send(message) return dict(verification=verification)
def create(self): # TODO Determine user timezone as default form = Form(self.request, schema=AccountCreateSchema) if form.validate(): new_user = form.bind(User()) DBSession.add(new_user) new_email = form.bind(EmailAddress()) new_email.user = new_user DBSession.add(new_email) new_collection = Collection() new_collection.name = "Default" new_collection.owner = new_user.full_name owner_role = DBSession.query(Role).filter(Role.id == "owner").one() new_user.collections[new_collection] = owner_role return HTTPFound( location=self.request.route_url("account_verify_email", _query=dict(email=form.data["email"])) ) return dict(form=FormRenderer(form))
def open(self): return dict( title='Open Collections', # XXX Perform the open filter with a query collections=[ collection for collection in DBSession.query(Collection) if collection.license.is_open ] )
def __init__(self, request): super(CollectionContextFactory, self).__init__(request) self.collection = DBSession.query(Collection).\ filter_by(id=request.matchdict['collection_id']).one() # If the collection has an open-license grant view permission to anyone if self.collection.license.is_open: self.__acl__.append( (Allow, Everyone, (VIEW_COLLECTION,)) )
def main(global_config, **settings): """Returns the Pyramid WSGI application""" # Ensure that the production configuration has been updated with "real" # values (at least where required for security) for key in ("authn.secret", "session.secret"): if settings.get(key) == "CHANGEME": raise ValueError("You must specify a new value for %s" % key) mimetypes.init() session_factory = session_factory_from_settings(settings) mailer_factory = mailer_factory_from_settings(settings) licenses_factory = licenses_factory_from_settings(settings) authn_policy = authentication_policy_from_settings(settings) authz_policy = ACLAuthorizationPolicy() engine = engine_from_config(settings, "sqlalchemy.") DBSession.configure(bind=engine) config = Configurator( settings=settings, root_factory=RootContextFactory, authentication_policy=authn_policy, authorization_policy=authz_policy, session_factory=session_factory, ) config.registry["mailer"] = mailer_factory config.registry["licenses"] = licenses_factory # XXX Deprecated in 1.4 config.set_request_property(get_user, b"user", reify=True) # XXX For 1.4: # config.add_request_method(get_user, b'user', reify=True) config.add_static_view("static", "static", cache_max_age=3600) for name, url in ROUTES.items(): if "{collection_id:" in url: factory = CollectionContextFactory elif "{sample_id:" in url: factory = SampleContextFactory else: factory = RootContextFactory config.add_route(name, url, factory=factory) config.scan() app = config.make_wsgi_app() # XXX Dirty horrid hack for functional testing if settings.get("testing", "0") == "1": app.engine = engine return app
def split(self): sample = self.context.sample form = Form( self.request, schema=SampleSplitSchema, obj=sample, defaults=dict(aliquots=2), variable_decode=True) if form.validate(): # XXX Check for EDIT_COLLECTION on new collection aliquots = sample.split( self.request.user, form.data['collection'], form.data['aliquots'], form.data['aliquant'], location=form.data['location']) for aliquot in aliquots: DBSession.add(aliquot) return HTTPFound( location=self.request.route_url( 'samples_view', sample_id=sample.id)) return dict(form=FormRenderer(form))
def create(self): form = Form( self.request, schema=SampleCreateSchema, variable_decode=True, multipart=True) if form.validate(): # XXX Check for EDIT_COLLECTION on selected collection # XXX Should be using form collection below new_sample = form.bind( Sample.create(self.request.user, self.context.collection)) DBSession.add(new_sample) DBSession.flush() # to generate sample.id for storage in self.request.POST.getall('attachments'): if storage: new_sample.attachments.create(storage.filename, storage.file) return HTTPFound( location=self.request.route_url( 'samples_view', sample_id=new_sample.id)) return dict(form=FormRenderer(form))
def verify_email(self): email = self.request.params['email'] verification = EmailVerification(email) DBSession.add(verification) DBSession.flush() user = verification.email.user mailer = self.request.registry['mailer'] message = Message( recipients=[email], subject='%s email verification' % self.request.registry.settings['site_title'], body=render( renderer_name='../templates/account/verify_email.txt', value=dict( view=self, request=self.request, verification=verification ), request=self.request)) mailer.send(message) return dict(verification=verification)
def edit(self): collection = self.context.collection form = Form( self.request, schema=CollectionEditSchema, obj=collection, variable_decode=True) if form.validate(): form.bind(collection) # Ensure the edit cannot change ownership by current user collection.users[self.request.user] = DBSession.query(Role).\ filter(Role.id==OWNER_ROLE).one() return HTTPFound(location=form.came_from) return dict(form=FormRenderer(form))
def combine(self): form = Form( self.request, schema=SampleCombineSchema, variable_decode=True) if form.validate(): new_sample = Sample.combine( self.request.user, form.data['collection'], form.data['aliquots']) return HTTPFound( location=self.request.route_url( 'samples_view', sample_id=new_sample.id)) return dict( form=FormRenderer(form), samples=DBSession.query(Sample).\ filter(Sample.collection==self.context.collection).\ filter(Sample.destroyed==None), )
def export(self, output_file): """ Export the collection to the specified file. `output_file` : a file-like object which the CSV will be written to """ columns = [] aliases = [] for column in self.columns: if column.startswith('code_'): alias = aliased(SampleCode) aliases.append((alias, column[len('code_'):])) columns.append(getattr(alias, 'value')) elif column in ('parents', 'children'): raise NotImplementedError else: columns.append(Sample.__table__.columns[column]) query = DBSession.query(*columns).select_from(Sample).\ filter(Sample.collection_id==self.collection.id) for alias, name in aliases: query = query.\ outerjoin(alias, (Sample.id==getattr(alias, 'sample_id')) & (getattr(alias, 'name')==name) ) writer = csv.writer(output_file, delimiter=self._delimiter_inv[self.delimiter], lineterminator=self._lineterminator_inv[self.lineterminator], quotechar=self._quotechar_inv[self.quotechar], quoting=self._quoting_inv[self.quoting], doublequote=self.doublequote) for row in query: # Rewrite the format of datetime values to exclude microseconds # (which confuse several spreadsheet parsers and which it's # unlikely anyone cares about) row = [ value.strftime(self.dateformat) if isinstance(value, datetime) else value for value in row ] writer.writerow(row)
def export(self, output_file): """ Export the collection to the specified file. `output_file` : a file-like object which the CSV will be written to """ columns = [] aliases = [] for column in self.columns: if column.startswith('code_'): alias = aliased(SampleCode) aliases.append((alias, column[len('code_'):])) columns.append(getattr(alias, 'value')) elif column in ('parents', 'children'): raise NotImplementedError else: columns.append(Sample.__table__.columns[column]) query = DBSession.query(*columns).select_from(Sample).\ filter(Sample.collection_id==self.collection.id) for alias, name in aliases: query = query.\ outerjoin(alias, (Sample.id==getattr(alias, 'sample_id')) & (getattr(alias, 'name')==name) ) writer = csv.writer( output_file, delimiter=self._delimiter_inv[self.delimiter], lineterminator=self._lineterminator_inv[self.lineterminator], quotechar=self._quotechar_inv[self.quotechar], quoting=self._quoting_inv[self.quoting], doublequote=self.doublequote) for row in query: # Rewrite the format of datetime values to exclude microseconds # (which confuse several spreadsheet parsers and which it's # unlikely anyone cares about) row = [ value.strftime(self.dateformat) if isinstance(value, datetime) else value for value in row ] writer.writerow(row)
def init_instances(): with transaction.manager: admins_group = Group( id=ADMINS_GROUP, description='Group of administrators') unlimited_limit = UserLimit( id='unlimited', collections_limit=1000000, samples_limit=1000000, templates_limit=1000000, storage_limit=50000 * 1000000) commercial_limit = UserLimit( id='commercial', collections_limit=1000, samples_limit=10000, templates_limit=10, storage_limit=10000 * 1000000) academic_limit = UserLimit( id='academic', collections_limit=10, samples_limit=250, templates_limit=5, storage_limit=100 * 1000000, email_pattern=r'.*\.(edu|ac\.[a-z][a-z])$') free_limit = UserLimit( id='free', collections_limit=3, samples_limit=50, templates_limit=2, storage_limit=1 * 1000000) admin_user = User( salutation='', given_name='Administrator', surname='', limits_id='unlimited') admin_email = EmailAddress( email='*****@*****.**', verified=datetime.utcnow()) admin_collection = Collection(name='Default', owner='Administrator') owner_role = Role( id=OWNER_ROLE, description='Owner and administrator of the collection') editor_role = Role( id=EDITOR_ROLE, description='Can add and remove samples from a collection, but ' 'cannot administer members of the collection') auditor_role = Role( id=AUDITOR_ROLE, description='Can audit samples within the collection but cannot ' 'manipulate the collection') viewer_role = Role( id=VIEWER_ROLE, description='Can view samples within the collection but cannot ' 'manipulate the collection') DBSession.add(admins_group) DBSession.add(unlimited_limit) DBSession.add(commercial_limit) DBSession.add(academic_limit) DBSession.add(free_limit) DBSession.add(admin_user) DBSession.add(admin_email) DBSession.add(admin_collection) DBSession.add(owner_role) DBSession.add(editor_role) DBSession.add(auditor_role) DBSession.add(viewer_role) admins_group.users.append(admin_user) admin_user.emails.append(admin_email) admin_user.password = '******' admin_user.collections[admin_collection] = owner_role
def open_collections(self): return [ collection for collection in DBSession.query(Collection).all() if collection.license.is_open ]
def init_instances(): with transaction.manager: admins_group = Group(id=ADMINS_GROUP, description='Group of administrators') unlimited_limit = UserLimit(id='unlimited', collections_limit=1000000, samples_limit=1000000, templates_limit=1000000, storage_limit=50000 * 1000000) commercial_limit = UserLimit(id='commercial', collections_limit=1000, samples_limit=10000, templates_limit=10, storage_limit=10000 * 1000000) academic_limit = UserLimit(id='academic', collections_limit=10, samples_limit=250, templates_limit=5, storage_limit=100 * 1000000, email_pattern=r'.*\.(edu|ac\.[a-z][a-z])$') free_limit = UserLimit(id='free', collections_limit=3, samples_limit=50, templates_limit=2, storage_limit=1 * 1000000) admin_user = User(salutation='', given_name='Administrator', surname='', limits_id='unlimited') admin_email = EmailAddress(email='*****@*****.**', verified=datetime.utcnow()) admin_collection = Collection(name='Default', owner='Administrator') owner_role = Role( id=OWNER_ROLE, description='Owner and administrator of the collection') editor_role = Role( id=EDITOR_ROLE, description='Can add and remove samples from a collection, but ' 'cannot administer members of the collection') auditor_role = Role( id=AUDITOR_ROLE, description='Can audit samples within the collection but cannot ' 'manipulate the collection') viewer_role = Role( id=VIEWER_ROLE, description='Can view samples within the collection but cannot ' 'manipulate the collection') DBSession.add(admins_group) DBSession.add(unlimited_limit) DBSession.add(commercial_limit) DBSession.add(academic_limit) DBSession.add(free_limit) DBSession.add(admin_user) DBSession.add(admin_email) DBSession.add(admin_collection) DBSession.add(owner_role) DBSession.add(editor_role) DBSession.add(auditor_role) DBSession.add(viewer_role) admins_group.users.append(admin_user) admin_user.emails.append(admin_email) admin_user.password = '******' admin_user.collections[admin_collection] = owner_role
def roles(self): return [ (role.id, role.id.title()) for role in DBSession.query(Role) ]