Example #1
0
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()
Example #2
0
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()
Example #3
0
 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)
Example #4
0
 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)
Example #5
0
 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)
Example #6
0
 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, )))
Example #7
0
 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))
Example #8
0
 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))
Example #9
0
 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)
Example #10
0
 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))
Example #11
0
 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
             ]
         )
Example #12
0
 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,))
             )
Example #13
0
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
Example #14
0
 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))
Example #15
0
 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))
Example #16
0
 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))
Example #17
0
 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)
Example #18
0
 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))
Example #19
0
 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),
         )
Example #20
0
    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)
Example #21
0
    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)
Example #22
0
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
Example #23
0
 def open_collections(self):
     return [
         collection
         for collection in DBSession.query(Collection).all()
         if collection.license.is_open
         ]
Example #24
0
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
Example #25
0
 def roles(self):
     return [
         (role.id, role.id.title())
         for role in DBSession.query(Role)
         ]