Esempio n. 1
0
# Recommended naming convensions to make possible to autogenerate migrations
# See http://alembic.zzzcomputing.com/en/latest/naming.html
NAMING_CONVENSION = {
    "ix": 'ix_%(column_0_label)s',
    'uq': 'uq_%(table_name)s_%(column_0_name)s',
    'ck': 'ck_%(table_name)s_%(column_0_name)s',
    'fk': 'fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s',
    'pk': 'pk_%(table_name)s'
}

# Prevent constant migrations from sa.DateTime(timezone=True) to mysql.DATETIME().
DATETIME_TYPE = DateTime(timezone=True)
DATETIME_TYPE = DATETIME_TYPE.with_variant(mysql.DATETIME(), 'mysql')
# mysql boolean
BOOLEAN_TYPE = Boolean()
BOOLEAN_TYPE = BOOLEAN_TYPE.with_variant(mysql.TINYINT(display_width=1),
                                         'mysql')
# Unsigned integer.
UNSIGNEDINT_TYPE = Integer()
UNSIGNEDINT_TYPE = UNSIGNEDINT_TYPE.with_variant(mysql.INTEGER(unsigned=True),
                                                 'mysql')
# Unsigned integer.
UNSIGNEDSMALLINT_TYPE = SmallInteger()
UNSIGNEDSMALLINT_TYPE = UNSIGNEDSMALLINT_TYPE.with_variant(
    mysql.SMALLINT(unsigned=True), 'mysql')


# The “pre ping” feature will normally emit SQL equivalent to “SELECT 1” each time a connection is checked out
# from the pool; if an error is raised that is detected as a “disconnect” situation, the connection will be
# immediately recycled, and all other pooled connections older than the current time are invalidated, so that
Esempio n. 2
0
class DistributionCode(Audit, VersionedModel):  # pylint:disable=too-many-instance-attributes
    """This class manages all of the base data about distribution code.

    Distribution code holds details on the codes for how the collected payment is going to be distributed.
    """

    __tablename__ = 'distribution_codes'

    distribution_code_id = db.Column(db.Integer,
                                     primary_key=True,
                                     autoincrement=True)

    name = db.Column(db.String(50), nullable=True)
    client = db.Column(db.String(50), nullable=True)
    responsibility_centre = db.Column(db.String(50), nullable=True)
    service_line = db.Column(db.String(50), nullable=True)
    stob = db.Column(db.String(50), nullable=True)
    project_code = db.Column(db.String(50), nullable=True)

    start_date = db.Column(db.Date, default=date.today(), nullable=False)
    end_date = db.Column(db.Date, default=None, nullable=True)
    stop_ejv = db.Column('stop_ejv', Boolean(), default=False)

    service_fee_distribution_code_id = db.Column(
        db.Integer,
        ForeignKey('distribution_codes.distribution_code_id'),
        nullable=True)
    disbursement_distribution_code_id = db.Column(
        db.Integer,
        ForeignKey('distribution_codes.distribution_code_id'),
        nullable=True)
    # account id for distribution codes for gov account. None for distribution codes for filing types
    account_id = db.Column(db.Integer,
                           ForeignKey('payment_accounts.id'),
                           nullable=True,
                           index=True)

    @classmethod
    def find_all(cls, include_gov_account_gl_codes: bool = False):
        """Find all distribution codes."""
        valid_date = date.today()
        query = cls.query.filter(DistributionCode.start_date <= valid_date). \
            filter((DistributionCode.end_date.is_(None)) | (DistributionCode.end_date >= valid_date)). \
            order_by(DistributionCode.name.asc())

        query = query.filter(DistributionCode.account_id.isnot(None)) if include_gov_account_gl_codes \
            else query.filter(DistributionCode.account_id.is_(None))

        return query.all()

    @classmethod
    def find_by_service_fee_distribution_id(cls,
                                            service_fee_distribution_code_id):
        """Find by service fee distribution id."""
        return cls.query.filter(
            DistributionCode.service_fee_distribution_code_id ==
            service_fee_distribution_code_id).all()

    @classmethod
    def find_by_active_for_fee_schedule(cls, fee_schedule_id: int):
        """Return active distribution for fee schedule."""
        valid_date = date.today()
        query = db.session.query(DistributionCode). \
            join(DistributionCodeLink). \
            filter(DistributionCodeLink.fee_schedule_id == fee_schedule_id). \
            filter(DistributionCode.start_date <= valid_date). \
            filter((DistributionCode.end_date.is_(None)) | (DistributionCode.end_date >= valid_date))

        distribution_code = query.one_or_none()
        return distribution_code

    @classmethod
    def find_by_active_for_account(cls, account_id: int):
        """Return active distribution for account."""
        valid_date = date.today()
        query = db.session.query(DistributionCode). \
            filter(DistributionCode.account_id == account_id). \
            filter(DistributionCode.start_date <= valid_date). \
            filter((DistributionCode.end_date.is_(None)) | (DistributionCode.end_date >= valid_date))

        distribution_code = query.one_or_none()
        return distribution_code
Esempio n. 3
0
def test_alter_column_schema_schema_type_unnamed():
    context = op_fixture('mssql')
    op.alter_column("t", "c", type_=Boolean(), schema='foo')
    context.assert_('ALTER TABLE foo.t ALTER COLUMN c BIT',
                    'ALTER TABLE foo.t ADD CHECK (c IN (0, 1))')
Esempio n. 4
0
    Column('hash', String(length=64), nullable=False, unique=True),
    Column('owner_key', String(length=128), nullable=False),
    Column('signature', String(length=128), nullable=True),
    Column('path', String(length=512), nullable=True),
    Column('timestamp', TIMESTAMP, nullable=False, default=datetime.utcnow),
    Column('size', Integer()),
    Column('client_contract_address', String(length=128), nullable=False),
    Column('my_monitoring_number', Integer(), default=ColumnDefault(0)),
    Column('status',
           String(length=32),
           nullable=False,
           default=ColumnDefault('active')),
    Column('no_deposit_counter', Integer(), default=ColumnDefault(0)),
    Column('replacing_host_address', String(length=128)),
    Column('send_data_to_contract_after_uploading_body',
           Boolean(),
           default=ColumnDefault(False)),
)

hoster_file_m2m = Table(
    'hoster_files_m2m',
    meta,
    Column('file_id',
           Integer(),
           ForeignKey('hoster_files.id'),
           primary_key=True,
           nullable=False),
    Column('host_id',
           Integer(),
           ForeignKey('hosts.id'),
           primary_key=True,
Esempio n. 5
0
class BusinessTypeFileType(DBBASE):
    """
    Relationship table between

    :class:`autonomie.models.project.types.BusinessType`
    and
    :class:`autonomie.models.files.FileType`
    """
    __tablename__ = "business_type_file_type"
    __table_args__ = default_table_args
    file_type_id = Column(ForeignKey("file_type.id"), primary_key=True)
    business_type_id = Column(ForeignKey("business_type.id"), primary_key=True)

    # estimation/invoice/cancelinvoice/business
    doctype = Column(String(14), primary_key=True)
    file_type = relationship(
        "FileType",
        backref=backref("business_type_rel", cascade='all, delete-orphan'),
    )
    business_type = relationship(
        "BusinessType",
        backref=backref("file_type_rel", cascade='all, delete-orphan'),
    )
    # project_mandatory / business_mandatory / mandatory / optionnal /
    # recommended
    requirement_type = Column(
        String(20),
        default=False,
        info={
            'colanderalchemy': {
                'title': u"Obligatoire ?",
            }
        },
    )
    validation = Column(
        Boolean(),
        default=False,
        info={
            "colanderalchemy": {
                "title": u"Validation équipe d'appui ?",
                "description": u"Ce document doit-il être validé par l'équipe "
                u"d'appui ?"
            }
        }
    )
    PROJECT_MANDATORY = 'project_mandatory'
    BUSINESS_MANDATORY = "business_mandatory"
    MANDATORY = "mandatory"
    RECOMMENDED = "recommended"
    OPTIONNAL = "optionnal"

    # requirement qui implique un indicateur de statut
    STATUS_REQUIREMENT_TYPES = (
        PROJECT_MANDATORY,
        BUSINESS_MANDATORY,
        MANDATORY,
        RECOMMENDED,
    )

    @classmethod
    def get_file_requirements(cls, business_type_id, doctype, mandatory=False):
        """
        Collect file requirements related to a given business_type
        """
        query = cls.query().filter_by(business_type_id=business_type_id)
        query = query.filter_by(doctype=doctype)
        if mandatory:
            query = query.filter(
                cls.requirement_type.in_(cls.STATUS_REQUIREMENT_TYPES)
            )
        return query

    @classmethod
    def get_file_type_options(cls, business_type_id, doctype):
        """
        Collect FileTypes associated to (business_type_id, doctype)

        :param int business_type_id: The business type id
        :param str doctype: One of the available doctypes
        :returns: A :class:`sqlalchemy.orm.Query`
        """
        id_query = cls.query('file_type_id')
        id_query = id_query.filter_by(business_type_id=business_type_id)
        id_query = id_query.filter_by(doctype=doctype)
        ids = [i[0] for i in id_query]

        result = []
        if ids is not None:
            from autonomie.models.files import FileType
            query = FileType.query().options(load_only('id', 'label')).filter(
                FileType.id.in_(ids)
            )
            result = query.all()
        return result
Esempio n. 6
0
def test_alter_column_schema_type_existing_type_no_new_type():
    context = op_fixture('postgresql')
    op.alter_column("t", "c", nullable=False, existing_type=Boolean())
    context.assert_(
        'ALTER TABLE t ALTER COLUMN c SET NOT NULL'
    )
Esempio n. 7
0
class Member(Base):
    '''
    Data model
    '''
    __tablename__ = 'members'

    mem_id = Column(Integer, primary_key=True)
    mem_fname = Column(Unicode(255), default='')
    mem_prefix = Column(Unicode(255), default='')
    mem_lname = Column(Unicode(255), default='')
    mem_email = Column(Unicode(255), default='')
    mem_street = Column(Unicode(255), default='')
    mem_house = Column(Integer, default=0)
    mem_flatno = Column(Unicode(255), default='')
    mem_city = Column(Unicode(255), default='')
    mem_postcode = Column(Unicode(6), default='')
    mem_home_tel = Column(Unicode(25), default='')
    mem_work_tel = Column(Unicode(255), default='')
    mem_mobile = Column(Unicode(25), default='')
    mem_enc_pwd = Column(Unicode(255), default='')
    mem_pwd_url = Column(Unicode(255), default='')
    # tracking
    mem_cookie = Column(Unicode(255), default='')
    mem_ip = Column(Unicode(255), default='')
    # admin-editable
    mem_active = Column(Boolean(), default=True)
    mem_membership_paid = Column(Boolean(), default=False)
    mem_admin = Column(Boolean(), default=False)
    mem_adm_adj = Column(Boolean(), default=False)
    mem_adm_comment = Column(Unicode(255), default='')
    # unused fields - TODO: do we need them?
    mem_bank_no = Column(Unicode(255), default='')
    mem_household_size = Column(Integer, default=0)

    __acl__ = [(Allow, 'group:admins', ('view', 'edit')),
               (Allow, 'group:this-member', ('view', 'edit')),
               (Allow, 'group:members', ('view')), DENY_ALL]

    def __init__(self, request=None, fname='', prefix='', lname=''):
        ''' receiving request makes this class a factory for views '''
        self.mem_active = True
        self.exists = False
        self.mem_fname = fname
        self.mem_prefix = prefix
        self.mem_lname = lname

    def __repr__(self):
        return self.fullname

    @property
    def fullname(self):
        return "{} {} {}".format(self.mem_fname or '', self.mem_prefix or '',
                                 self.mem_lname or '')

    def addr_street(self):
        return "{} {}{}".format(self.mem_street, self.mem_house,
                                self.mem_flatno)

    def addr_city(self):
        return "{} {}".format(self.mem_postcode, self.mem_city)

    def validate(self):
        ''' checks on address, bank account, ...
        '''
        # check missing fields
        missing = []
        for f in ('mem_fname', 'mem_lname', 'mem_email'):
            if not f in self.__dict__ or self.__dict__[f] == '':
                missing.append(f)
        if len(missing) > 0:
            raise VokoValidationError('We still require you to fill in: %s'\
                                    % ', '.join([m[4:] for m in missing]))
        self.validate_email()
        # also check unique constraint on email address here for nicer error msg
        session = DBSession()
        members = session.query(Member)\
                         .filter(Member.mem_email == self.mem_email).all()
        if len(members) > 0:
            if not (len(members) == 1 and members[0].mem_id == self.mem_id):
                raise VokoValidationError('The email address already exists '\
                                          'for a member in the database.')

        # we want one telephone number, as well
        sd = self.__dict__
        if ((not 'mem_home_tel' in sd and not 'mem_work_tel' in sd
             and not 'mem_mobile' in sd)
                or (self.mem_home_tel == "" and self.mem_work_tel == ""
                    and self.mem_mobile == "")):
            raise VokoValidationError('Please specify at least one telephone '\
                                      'number.')

        # check postcode
        if self.mem_postcode and len(self.mem_postcode) > 0\
                and not (self.mem_postcode[:4].isdigit()\
                and self.mem_postcode[-2:].isalpha()):
            raise VokoValidationError('The postcode does not seem to be'\
                    ' valid (should be NNNNLL, where N=number and L=letter).')
        # check bank no
        if self.mem_bank_no:
            bank_no_clean = self.mem_bank_no.replace(' ', '').replace('-', '')
            if not len(bank_no_clean) in [0, 7, 8, 9]:
                # length of 8 is legacy data
                raise VokoValidationError('Bank number needs to consist of 7 '\
                                          '(postbank) or 9 numbers.')
            if len(bank_no_clean) > 0 and not bank_no_clean.isdigit():
                raise VokoValidationError('Bank number needs to consist of '\
                                          'only numbers.')
        # household size
        if self.mem_household_size is None or self.mem_household_size < 1:
            raise VokoValidationError('Please specify how many people live '\
                                      'in the household.')

    def validate_email(self):
        ''' check email '''
        # check general form: a valid local name + @ + some host
        # (for local name, see http://en.wikipedia.org/wiki/Email_address#Local_part)
        if not re.match('[A-Za-z0-9\-\_\.\+\$\%\#\&\*\/\=\?\{\}\|\~]+@[^@]+',
                        self.mem_email):
            raise VokoValidationError('The email address does not '\
                                      'seem to be valid.')
        # check host
        host = re.findall('[^@]+', self.mem_email)[1]
        try:
            # dns.resolver throws an exception when it can't find a mail (MX)
            # host. The point at the end makes it not try to append domains
            _ = dns.resolver.query('{}.'.format(host), 'MX')
        except:
            raise VokoValidationError('The host {} is not known in the DNS'\
                                      ' system as a mail server.'\
                                      ' Is it spelled correctly?'.format(host))

    def validate_pwd(self, req):
        '''
        Check request on password(s), and also check if it is long enough
        '''
        if not 'pwd1' in req.params:
            raise VokoValidationError('Please specify a password.')
        if not 'pwd2' in req.params:
            raise VokoValidationError('Please confirm password.')
        if not req.params['pwd2'] == req.params['pwd1']:
            raise VokoValidationError('Passwords do not match.')
        if not 6 <= len(req.params['pwd1']) <= 30:
            raise VokoValidationError('The password should be between '\
                                 '6 and 30 characters long.')

    @property
    def balance(self):
        ''' returns the account balance'''
        balance = 0
        for t in self.transactions:
            balance += t.amount
        return balance
Esempio n. 8
0
 def test_alter_column_schema_schema_type_named(self):
     context = op_fixture('mssql', native_boolean=False)
     op.alter_column("t", "c", type_=Boolean(name="xyz"), schema='foo')
     context.assert_(
         'ALTER TABLE foo.t ALTER COLUMN c BIT',
         'ALTER TABLE foo.t ADD CONSTRAINT xyz CHECK (c IN (0, 1))')
Esempio n. 9
0
class User(Base):
    id = Column(Integer, primary_key=True, index=True)
    email = Column(String, unique=True, index=True)
    hashed_password = Column(String)
    is_active = Column(Boolean(), default=True)
Esempio n. 10
0
class User(BaseModel):
    email = Column(String, unique=True, index=True)
    hashed_password = Column(String)
    is_active = Column(Boolean, default=True)
    is_superuser = Column(Boolean(), default=False)
    articles = relationship("Article", back_populates="owner")
Esempio n. 11
0
 def test_alter_column_schema_type_unnamed(self):
     context = op_fixture('mssql', native_boolean=False)
     op.alter_column("t", "c", type_=Boolean())
     context.assert_('ALTER TABLE t ALTER COLUMN c BIT',
                     'ALTER TABLE t ADD CHECK (c IN (0, 1))')
Esempio n. 12
0
class MUC(Base):
    __tablename__ = "muc"

    address = Column(
        "address",
        JID(),
        primary_key=True,
        nullable=False,
    )

    service_domain_id = Column(
        "domain_id",
        Integer(),
        ForeignKey(Domain.id_),
        nullable=False,
    )

    last_seen = Column(
        "last_seen",
        DateTime(),
        nullable=True,
    )

    nusers = Column(
        "nusers",
        Integer(),
        nullable=True,
    )

    nusers_moving_average = Column(
        "nusers_moving_average",
        Float(),
        nullable=True,
    )

    moving_average_last_update = Column(
        "moving_average_last_update",
        DateTime(),
        nullable=True,
    )

    is_open = Column(
        "is_open",
        Boolean(),
        nullable=False,
    )

    is_hidden = Column(
        "is_hidden",
        Boolean(),
        nullable=False,
        default=False,
    )

    was_kicked = Column(
        "was_kicked",
        Boolean(),
        nullable=False,
    )

    anonymity_mode = Column(
        "anonymity_mode",
        SimpleEnum(AnonymityMode),
        nullable=True,
    )

    @classmethod
    def get(cls, session, address):
        try:
            return session.query(cls).filter(cls.address == address).one()
        except sqlalchemy.orm.exc.NoResultFound:
            return None
Esempio n. 13
0
class CiCommit(Base):
    """Refers to a git commit of the code
  on which we ran some SLAM performance test (likely in the CI).
  We keep some useful data in the database, but for the rest it used gitpython.
  """
    __tablename__ = 'ci_commits'
    id = Column(Integer(), primary_key=True)
    hexsha = Column(String(), index=True, nullable=False)
    project_id = Column(String(), ForeignKey('projects.id'), index=True)

    project = relationship("Project", back_populates="ci_commits")
    __table_args__ = (UniqueConstraint('project_id',
                                       'hexsha',
                                       name='_project_hexsha'), )

    data = Column(JSON(), default={})

    authored_datetime = Column(DateTime(timezone=True), index=True)
    committer_name = Column(String(), index=True)
    message = Column(String())
    # We use as branch the first branch that the commit was seen on, or the project's reference branch if it was used.
    # TODO: we should also store the tags we witnessed the commit used with.
    branch = Column(String(), index=True)  # first added as.. we ignore tags?
    # In the end there having a commit's parents is not all that useful for QA-Board:
    # not all commits are used for runs: e.g. CI runs only on pushed commits, so
    # that info is not enough to reconstruct the commit graph.
    # Right now we don't display parents in the web application, so we also remove it from the API.
    # Instead of  JSON, we could use an Array of String instead, so that we can search for descendents. But do we really need it?
    parents = Column(JSON())

    commit_dir_override = Column(String())
    # Right now we don't really use this field, it's always "git".
    # The client uses "local" in case there is no git info, but
    # even then it doesn't send the information!
    commit_type = Column(String(), default='git')

    batches = relationship(
        "Batch",
        back_populates="ci_commit",
        cascade="all, delete-orphan",
        order_by=Batch.created_date,
    )

    latest_output_datetime = Column(DateTime(timezone=True))
    deleted = Column(Boolean(), default=False)

    @orm.reconstructor
    def init_on_load(self):
        if not self.data:
            self.data = {}

    def get_or_create_batch(self, label):
        matching_batches = [b for b in self.batches if b.label == label]
        if matching_batches: return matching_batches[0]
        return Batch(ci_commit=self, label=label)

    @property
    def ci_batch(self):
        return self.get_or_create_batch('default')

    @property
    def authored_date(self):
        return self.authored_datetime.date()

    @property
    def commit_dir(self):
        """Returns the folder in all the data for this commit is stored."""
        if self.commit_dir_override is not None:
            return Path(self.commit_dir_override)
        committer_name = self.committer_name if self.committer_name else "unknown"
        commit_dir_name = f'{int(self.authored_datetime.timestamp())}__{committer_name}__{self.hexsha[:8]}'
        out = self.project.ci_directory / self.project.id_git / 'commits' / commit_dir_name
        if self.project.id_relative:
            return out / self.project.id_relative
        else:
            return out

    @property
    def repo_commit_dir(self):
        if self.commit_dir_override is not None:
            # can we do something better?
            return Path(
                self.commit_dir_override.replace(str(self.project.id_relative),
                                                 ""))
        else:
            committer_name = self.committer_name if self.committer_name else "unknown"
            commit_dir_name = f'{int(self.authored_datetime.timestamp())}__{committer_name}__{self.hexsha[:8]}'
            return self.project.ci_directory / self.project.id_git / 'commits' / commit_dir_name

    @property
    def commit_dir_url(self):
        """The URL at which the data about this commit is stored. It's convenient."""
        if self.commit_dir_override is not None:
            relative_path = self.commit_dir_override
            return quote(f'/s{relative_path}')
        return quote(f"/s{self.commit_dir}".replace("/home/arthurf/ci", ""))

    @property
    def repo_commit_dir_url(self):
        """The URL at which the data about this commit is stored. It's convenient."""
        if self.commit_dir_override is not None:
            relative_path = self.commit_dir_override
            return quote(f'/s{relative_path}')
        return quote(f"/s{self.repo_commit_dir}")

    def __repr__(self):
        outputs = f"ci_batch.outputs={len(self.ci_batch.outputs)}" if len(
            self.ci_batch.outputs) else ''
        branch = re.sub('origin/', '', self.branch)
        return f"<CiCommit project='{self.project.id}' hexsha='{self.hexsha[:8]}' branch='{branch}' {outputs}>"

    def __init__(self,
                 hexsha,
                 *,
                 project,
                 branch=None,
                 message=None,
                 parents=None,
                 authored_datetime=None,
                 committer_name=None,
                 commit_type='git'):
        self.hexsha = hexsha
        self.project = project
        self.branch = branch
        self.message = message if message else '<NA>'
        self.parents = parents
        self.authored_datetime = authored_datetime
        self.committer_name = committer_name if committer_name else 'unknown'
        self.commit_type = commit_type
        self.latest_output_datetime = authored_datetime

    def delete(self, ignore=None, keep=None, dryrun=False):
        """
    Delete the commit's artifacts, and mark it as delete.
    NOTE: We don't touch batches/outputs, you have to deal with them yourself.
          See hard_delete() in api/webhooks.py and clean.py
    """
        manifest_dir = self.commit_dir / 'manifests'
        delete_errors = False
        if manifest_dir.exists():
            for manifest in manifest_dir.iterdir():
                if keep and manifest in keep:
                    continue
                print(f'  ...delete artifacts: {manifest.name}')
                has_error = False
                try:
                    with manifest.open() as f:
                        files = json.load(f)
                except:
                    delete_errors = True
                    continue
                for file in files.keys():
                    if keep and file in keep:
                        continue
                    if ignore:
                        if any([fnmatch.fnmatch(file, i) for i in ignore]):
                            continue
                    print(f'{self.commit_dir / file}')
                    if not dryrun:
                        try:
                            (self.commit_dir / file).unlink()
                        except:
                            has_error = True
                            print(
                                f"WARNING: Could not remove: {self.commit_dir / file}"
                            )
                    if not has_error:
                        manifest.unlink()
                delete_errors = delete_errors or has_error
        if not delete_errors:
            self.deleted = True

    @staticmethod
    def get_or_create(session, hexsha, project_id, data=None):
        try:
            ci_commit = (session.query(CiCommit).filter(
                CiCommit.project_id == project_id,
                CiCommit.hexsha.startswith(hexsha),
            ).one())
        except NoResultFound:
            # FIXME: if not cimplete hash. fallback git... ? or raise error? (then docs: ask full 32 hash..) or symetrics if hexsha.strtswith(query)
            try:
                from backend.models import Project
                project = Project.get_or_create(session=session, id=project_id)
                if data and data.get('qaboard_config'):
                    is_initialization = not project.data or 'qatools_config' not in data
                    reference_branch = data["qaboard_config"]['project'].get(
                        'reference_branch', 'master')
                    is_reference = data.get(
                        "commit_branch") == reference_branch
                    if is_initialization or is_reference:
                        # FIXME: We put in Project.data.git the content of
                        #       https://docs.gitlab.com/ee/user/project/integrations/webhooks.html#push-events
                        # FIXME: We should really have Project.data.gitlab/github/...
                        if "git" not in project.data:
                            project.data["git"] = {}
                        if "path_with_namespace" not in project.data[
                                "git"] and "name" in data["qaboard_config"].get(
                                    "project", {}
                                ):  # FIXME: it really should be Project.root
                            # FIXME: Doesn't support updates for now... again should have .id: int, name: str, root: str...
                            project.data["git"]["path_with_namespace"] = data[
                                "qaboard_config"]["project"]["name"]
                        project.data.update(
                            {'qatools_config': data['qaboard_config']})
                        if "qaboard_metrics" in data:
                            project.data.update(
                                {'qatools_metrics': data["qaboard_metrics"]})
                        flag_modified(project, "data")
                else:
                    # For backward-compatibility we fallback to reading the data from the commit itself
                    # But in regular use QA-Board doesn't require read rights on repositories
                    try:
                        git_commit = project.repo.commit(hexsha)
                    except Exception as e:
                        error = f'[ERROR] Could not find information on commit {hexsha}. {e}'
                        print(error)
                        raise ValueError(error)

                ci_commit = CiCommit(
                    hexsha,
                    project=project,
                    commit_type='git',  # we don't use anything else
                    parents=data["commit_parents"] if
                    (data and "commit_parents" in data) else
                    [c.hexsha for c in git_commit.parents],
                    message=data["commit_message"] if
                    (data
                     and "commit_message" in data) else git_commit.message,
                    committer_name=data["commit_committer_name"] if
                    (data and "commit_committer_name" in data) else
                    git_commit.committer.name,
                    authored_datetime=data["commit_authored_datetime"] if
                    (data and "commit_authored_datetime" in data) else
                    git_commit.authored_datetime,
                    # commits belong to many branches, so this is a guess
                    branch=data["commit_branch"] if
                    (data and "commit_branch" in data) else find_branch(
                        hexsha, project.repo),
                )
                if data and data.get('qaboard_config'):
                    ci_commit.data.update(
                        {'qatools_config': data['qaboard_config']})
                    if "qaboard_metrics" in data:
                        ci_commit.data.update(
                            {'qatools_metrics': data['qaboard_metrics']})
                    flag_modified(ci_commit, "data")
                session.add(ci_commit)
                session.commit()
            except ValueError:
                error = f'[ERROR] ValueError: could not create a commit for {hexsha}'
                print(error)
                raise ValueError(error)
        if not ci_commit.data:
            ci_commit.data = {}
        return ci_commit

    def to_dict(self,
                with_aggregation=None,
                with_batches=None,
                with_outputs=False):
        users_db = get_users_per_name("")
        committer_avatar_url = ''
        if users_db and self.committer_name:
            name = self.committer_name.lower()
            if name in users_db:
                committer_avatar_url = users_db[name]['avatar_url']
            elif name.replace('.', '') in users_db:
                committer_avatar_url = users_db[name.replace('.',
                                                             '')]['avatar_url']
            elif name.replace(' ', '') in users_db:
                committer_avatar_url = users_db[name.replace(' ',
                                                             '')]['avatar_url']
            else:
                name_hash = md5(name.encode('utf8')).hexdigest()
                committer_avatar_url = f'http://gravatar.com/avatar/{name_hash}'
        out = {
            'id':
            self.hexsha,
            # 'type': self.commit_type,
            'branch':
            re.sub('origin/', '', self.branch),
            # Not used anywhere in the web application, and it's not all that useful (see earlier comment)
            # 'parents': [p for p in self.parents] if self.parents else [],
            'message':
            self.message,
            'committer_name':
            self.committer_name,
            'committer_avatar_url':
            committer_avatar_url,
            'authored_datetime':
            self.authored_datetime.isoformat(),
            'authored_date':
            self.authored_date.isoformat(),
            'latest_output_datetime':
            self.latest_output_datetime.isoformat()
            if self.latest_output_datetime else None,
            'deleted':
            self.deleted,
            "data":
            self.data if with_outputs else None,
            'commit_dir_url':
            str(self.commit_dir_url),
            'repo_commit_dir_url':
            str(self.repo_commit_dir_url),
            'batches': {
                b.label: b.to_dict(with_outputs=with_outputs,
                                   with_aggregation=with_aggregation)
                for b in self.batches
                if not with_batches or b.label in with_batches
            },
        }
        if with_outputs:
            out["data"] = self.data
        return out
Esempio n. 14
0
from sqlalchemy.dialects.postgresql import ARRAY, DOUBLE_PRECISION

from credovi.schema import metadata, schema
from credovi.util.sqlalchemy import Vector3D

# RAW CHAINS
raw_chains = Table('raw_chains', metadata,
                   Column('pdb', String(4), nullable=False),
                   Column('assembly_serial', Integer, nullable=False, autoincrement=False),
                   Column('entity_serial', Integer, nullable=False, autoincrement=False),
                   Column('pdb_chain_id', String(1), nullable=False),
                   Column('pdb_chain_asu_id', String(1), nullable=False),
                   Column('chain_type', String(50)),
                   Column('rotation', ARRAY(DOUBLE_PRECISION)),
                   Column('translation', ARRAY(DOUBLE_PRECISION)),
                   Column('is_at_identity', Boolean(create_constraint=False), DefaultClause('false'), nullable=False),
                   schema=schema, prefixes=['unlogged'])

PrimaryKeyConstraint(raw_chains.c.pdb, raw_chains.c.assembly_serial,
                     raw_chains.c.entity_serial, deferrable=True, initially='deferred')

# RAW LIGANDS
raw_ligands = Table('raw_ligands', metadata,
                    Column('pdb', String(4), nullable=False, primary_key=True),
                    Column('assembly_serial', Integer, nullable=False, primary_key=True, autoincrement=False),
                    Column('entity_serial', Integer, nullable=False, autoincrement=False, primary_key=True),
                    Column('pdb_chain_id', String(1), nullable=False),
                    Column('res_num', Integer),
                    Column('ligand_name', String(64), nullable=False),
                    Column('num_hvy_atoms', Integer),
                    Column('ism', Text),
Esempio n. 15
0
class Task(Node):
    """
        Metadata pour une tâche (estimation, invoice)
    """
    __tablename__ = 'task'
    __table_args__ = default_table_args
    __mapper_args__ = {'polymorphic_identity': 'task'}
    _autonomie_service = TaskService
    file_requirement_service = TaskFileRequirementService
    mention_service = TaskMentionService

    id = Column(
        Integer,
        ForeignKey('node.id'),
        info={'export': {'exclude': True}},
        primary_key=True,
    )
    phase_id = Column(
        ForeignKey('phase.id'),
        info={"export": {'exclude': True}},
    )
    status = Column(
        String(10),
        info={
            'colanderalchemy': {'title': u"Statut"},
            'export': {'exclude': True}
        }
    )
    status_comment = Column(
        Text,
        info={
            "colanderalchemy": {"title": u"Commentaires"},
            'export': {'exclude': True}
        },
        default="",
    )
    status_person_id = Column(
        ForeignKey('accounts.id'),
        info={
            'colanderalchemy': {
                "title": u"Dernier utilisateur à avoir modifié le document",
            },
            "export": {'exclude': True},
        },
    )
    status_date = Column(
        Date(),
        default=datetime.date.today,
        info={
            'colanderalchemy': {
                "title": u"Date du dernier changement de statut",
            },
            'export': {'exclude': True}
        }
    )
    date = Column(
        Date(),
        info={"colanderalchemy": {"title": u"Date du document"}},
        default=datetime.date.today
    )
    owner_id = Column(
        ForeignKey('accounts.id'),
        info={
            "export": {'exclude': True},
        },
    )
    description = Column(
        Text,
        info={'colanderalchemy': {"title": u"Objet"}},
    )
    ht = Column(
        BigInteger(),
        info={
            'colanderalchemy': {"title": u"Montant HT (cache)"},
            'export': {'exclude': True},
        },
        default=0
    )
    tva = Column(
        BigInteger(),
        info={
            'colanderalchemy': {"title": u"Montant TVA (cache)"},
            'export': {'exclude': True},
        },
        default=0
    )
    ttc = Column(
        BigInteger(),
        info={
            'colanderalchemy': {"title": u"Montant TTC (cache)"},
            'export': {'exclude': True},
        },
        default=0
    )
    company_id = Column(
        Integer,
        ForeignKey('company.id'),
        info={
            'export': {'exclude': True},
        },
    )
    project_id = Column(
        Integer,
        ForeignKey('project.id'),
        info={
            'export': {'exclude': True},
        },
    )
    customer_id = Column(
        Integer,
        ForeignKey('customer.id'),
        info={
            'export': {'exclude': True},
        },
    )
    project_index = deferred(
        Column(
            Integer,
            info={
                'colanderalchemy': {
                    "title": u"Index dans le projet",
                },
                'export': {'exclude': True},
            },
        ),
        group='edit',
    )
    company_index = deferred(
        Column(
            Integer,
            info={
                'colanderalchemy': {
                    "title": u"Index du document à l'échelle de l'entreprise",
                },
                'export': {'exclude': True},
            },
        ),
        group='edit',
    )
    official_number = Column(
        String(255),
        info={
            'colanderalchemy': {
                "title": u"Identifiant du document (facture/avoir)",
            },
            'export': {'label': u"Numéro de facture"},
        },
        default=None,
    )

    internal_number = deferred(
        Column(
            String(255),
            default=None,
            info={
                'colanderalchemy': {
                    "title": u"Identifiant du document dans la CAE",
                },
                'export': {'exclude': True},
            }
        ),
        group='edit'
    )

    display_units = deferred(
        Column(
            Integer,
            info={
                'colanderalchemy': {
                    "title": u"Afficher le détail ?",
                    "validator": colander.OneOf((0, 1))
                },
                'export': {'exclude': True},
            },
            default=0
        ),
        group='edit'
    )

    expenses_ht = deferred(
        Column(
            BigInteger(),
            info={
                'colanderalchemy': {'title': u'Frais'},
                'export': {'exclude': True},
            },
            default=0
        ),
        group='edit',
    )
    address = deferred(
        Column(
            Text,
            default="",
            info={
                'colanderalchemy': {'title': u'Adresse'},
                'export': {'exclude': True},
            },
        ),
        group='edit',
    )
    workplace = deferred(
        Column(
            Text,
            default='',
            info={
                'colanderalchemy': {'title': u"Lieu d'éxécution des travaux"},
            }
        )
    )
    payment_conditions = deferred(
        Column(
            Text,
            info={
                'colanderalchemy': {
                    "title": u"Conditions de paiement",
                },
                'export': {'exclude': True},
            },
        ),
        group='edit',
    )
    round_floor = deferred(
        Column(
            Boolean(),
            default=False,
            info={
                'colanderalchemy': {
                    'exlude': True,
                    'title': u"Méthode d'arrondi 'à l'ancienne' ? (floor)"
                },
                'export': {'exclude': True},
            }
        ),
        group='edit',
    )
    business_type_id = Column(ForeignKey("business_type.id"))
    business_id = Column(ForeignKey("business.id"))

    # Organisationnal Relationships
    status_person = relationship(
        "User",
        primaryjoin="Task.status_person_id==User.id",
        backref=backref(
            "taskStatuses",
            info={
                'colanderalchemy': {'exclude': True},
                'export': {'exclude': True},
            },
        ),
        info={
            'colanderalchemy': {'exclude': True},
            'export': {'exclude': True},
        },
    )
    owner = relationship(
        "User",
        primaryjoin="Task.owner_id==User.id",
        backref=backref(
            "ownedTasks",
            info={
                'colanderalchemy': {'exclude': True},
                'export': {'exclude': True},
            },
        ),
        info={
            'colanderalchemy': {'exclude': True},
            'export': {'exclude': True},
        },
    )

    phase = relationship(
        "Phase",
        primaryjoin="Task.phase_id==Phase.id",
        backref=backref(
            "tasks",
            order_by='Task.date',
            info={
                'colanderalchemy': {'exclude': True},
                'export': {'exclude': True},
            },
        ),
        info={
            'colanderalchemy': {'exclude': True},
            'export': {'exclude': True},
        },
    )

    company = relationship(
        "Company",
        primaryjoin="Task.company_id==Company.id",
        info={
            'colanderalchemy': {'exclude': True},
            'export': {'related_key': "name", "label": "Entreprise"},
        },
    )

    project = relationship(
        "Project",
        primaryjoin="Task.project_id==Project.id",
        info={
            'colanderalchemy': {'exclude': True},
            'export': {'exclude': True},
        },
    )

    customer = relationship(
        "Customer",
        primaryjoin="Customer.id==Task.customer_id",
        backref=backref(
            'tasks',
            order_by='Task.date',
            info={
                'colanderalchemy': {'exclude': True},
                "export": {'exclude': True},
            },
        ),
        info={
            'colanderalchemy': {'exclude': True},
            'export': {'related_key': 'label', 'label': u"Client"},
        },
    )
    business_type = relationship(
        "BusinessType",
        info={'colanderalchemy': {'exclude': True}}
    )
    business = relationship(
        "Business",
        primaryjoin="Business.id==Task.business_id",
        info={'colanderalchemy': {'exclude': True}}
    )

    # Content relationships
    discounts = relationship(
        "DiscountLine",
        info={
            'colanderalchemy': {'title': u"Remises"},
            'export': {'exclude': True},
        },
        order_by='DiscountLine.tva',
        cascade="all, delete-orphan",
        back_populates='task',
    )

    payments = relationship(
        "Payment",
        primaryjoin="Task.id==Payment.task_id",
        info={
            'colanderalchemy': {'exclude': True},
            'export': {'exclude': True},
        },
        order_by='Payment.date',
        cascade="all, delete-orphan",
        back_populates='task',
    )

    mentions = relationship(
        "TaskMention",
        secondary=TASK_MENTION,
        order_by="TaskMention.order",
        info={'export': {'exclude': True}},
    )

    mandatory_mentions = relationship(
        "TaskMention",
        secondary=MANDATORY_TASK_MENTION,
        order_by="TaskMention.order",
        info={'export': {'exclude': True}},
    )

    line_groups = relationship(
        "TaskLineGroup",
        order_by='TaskLineGroup.order',
        cascade="all, delete-orphan",
        collection_class=ordering_list('order'),
        info={
            'colanderalchemy': {
                'title': u"Unités d'oeuvre",
                "validator": colander.Length(
                    min=1,
                    min_err=u"Une entrée est requise"
                ),
                "missing": colander.required
            },
            'export': {'exclude': True},
        },
        primaryjoin="TaskLineGroup.task_id==Task.id",
        back_populates='task',
    )

    statuses = relationship(
        "TaskStatus",
        order_by="desc(TaskStatus.status_date), desc(TaskStatus.id)",
        cascade="all, delete-orphan",
        back_populates='task',
        info={
            'colanderalchemy': {'exclude': True},
            'export': {'exclude': True},
        }
    )

    # Not used in latest invoices
    expenses = deferred(
        Column(
            BigInteger(),
            info={
                'export': {'exclude': True},
            },
            default=0
        ),
        group='edit'
    )

    _name_tmpl = u"Task {}"
    _number_tmpl = u"{s.project.code}_{s.customer.code}_T{s.project_index}\
_{s.date:%m%y}"

    state_manager = None

    def __init__(self, user, company, **kw):
        project = kw['project']
        company_index = self._get_company_index(company)
        project_index = self._get_project_index(project)

        self.status = 'draft'
        self.company = company
        if 'customer' in kw:
            customer = kw['customer']
            self.address = customer.full_address
        self.owner = user
        self.status_person = user
        self.date = datetime.date.today()
        self.set_numbers(company_index, project_index)

        for key, value in kw.items():
            setattr(self, key, value)

        # We add a default task line group
        self.line_groups.append(TaskLineGroup(order=0))

    def initialize_business_datas(self, business=None):
        """
        Initialize the business datas related to this task

        :param obj business: instance of
        :class:`autonomie.models.project.business.Business`
        """
        if business is not None:
            self.business = business

        self.file_requirement_service.populate(self)
        self.mention_service.populate(self)

    def _get_project_index(self, project):
        """
        Return the index of the current object in the associated project
        :param obj project: A Project instance in which we will look to get the
        current doc index
        :returns: The next number
        :rtype: int
        """
        return -1

    def _get_company_index(self, company):
        """
        Return the index of the current object in the associated company
        :param obj company: A Company instance in which we will look to get the
        current doc index
        :returns: The next number
        :rtype: int
        """
        return -1

    def set_numbers(self, company_index, project_index):
        """
        Handle all attributes related to the given number

        :param int company_index: The index of the task in the company
        :param int project_index: The index of the task in its project
        """
        if company_index is None or project_index is None:
            raise Exception("Indexes should not be None")

        self.company_index = company_index
        self.project_index = project_index

        self.internal_number = self._number_tmpl.format(s=self)
        self.name = self._name_tmpl.format(project_index)

    @property
    def default_line_group(self):
        return self.line_groups[0]

    def __json__(self, request):
        """
        Return the datas used by the json renderer to represent this task
        """
        return dict(
            id=self.id,
            name=self.name,
            created_at=self.created_at.isoformat(),
            updated_at=self.updated_at.isoformat(),

            phase_id=self.phase_id,
            status=self.status,
            status_comment=self.status_comment,
            status_person_id=self.status_person_id,
            # status_date=self.status_date.isoformat(),
            date=self.date.isoformat(),
            owner_id=self.owner_id,
            description=self.description,
            ht=integer_to_amount(self.ht, 5),
            tva=integer_to_amount(self.tva, 5),
            ttc=integer_to_amount(self.ttc, 5),
            company_id=self.company_id,
            project_id=self.project_id,
            customer_id=self.customer_id,
            project_index=self.project_index,
            company_index=self.company_index,
            official_number=self.official_number,
            internal_number=self.internal_number,
            display_units=self.display_units,
            expenses_ht=integer_to_amount(self.expenses_ht, 5),
            address=self.address,
            workplace=self.workplace,
            payment_conditions=self.payment_conditions,
            status_history=[
                status.__json__(request) for status in self.statuses
            ],
            discounts=[
                discount.__json__(request) for discount in self.discounts
            ],
            payments=[
                payment.__json__(request) for payment in self.payments
            ],
            mentions=[mention.id for mention in self.mentions],
            line_groups=[
                group.__json__(request) for group in self.line_groups
            ],
            attachments=[
                file_.__json__(request) for file_ in self.files
            ],
            file_requirements=[
                file_req.__json__(request)
                for file_req in self.file_requirements
            ]
        )

    def set_status(self, status, request, **kw):
        """
        set the status of a task through the state machine
        """
        return self.state_manager.process(
            status,
            self,
            request,
            **kw
        )

    def check_status_allowed(self, status, request, **kw):
        return self.state_manager.check_allowed(status, self, request)

    @validates('status')
    def change_status(self, key, status):
        """
        fired on status change, stores a new taskstatus for each status change
        """
        log.debug(u"# Task status change #")
        actual_status = self.status
        log.debug(u" + was {0}, becomes {1}".format(actual_status, status))
        return status

    def get_company(self):
        """
            Return the company owning this task
        """
        return self.company

    def get_customer(self):
        """
            Return the customer of the current task
        """
        return self.customer

    def get_company_id(self):
        """
            Return the id of the company owning this task
        """
        return self.company.id

    def __repr__(self):
        return u"<Task status:{s.status} id:{s.id}>".format(s=self)

    def get_groups(self):
        return [group for group in self.line_groups if group.lines]

    @property
    def all_lines(self):
        """
        Returns a list with all task lines of the current task
        """
        result = []
        for group in self.line_groups:
            result.extend(group.lines)
        return result

    def get_tva_objects(self):
        return self._autonomie_service.get_tva_objects(self)

    @classmethod
    def get_valid_tasks(cls, *args):
        return cls._autonomie_service.get_valid_tasks(cls, *args)

    @classmethod
    def get_waiting_estimations(cls, *args):
        return cls._autonomie_service.get_waiting_estimations(*args)

    @classmethod
    def get_waiting_invoices(cls, *args):
        return cls._autonomie_service.get_waiting_invoices(cls, *args)

    def gen_business(self):
        """
        Generate a business based on this Task

        :returns: A new business instance
        :rtype: :class:`autonomie.models.project.business.Business`
        """
        business = Business(
            name=self.name,
            project_id=self.project_id,
            business_type_id=self.business_type_id,
        )
        DBSESSION().add(business)
        DBSESSION().flush()
        business.file_requirement_service.populate(business)
        self.business_id = business.id
        DBSESSION().merge(self)
        return business

    def is_training(self):
        return self.business_type.name == 'training'
Esempio n. 16
0
# Import Table, Column, String, Integer, Float, Boolean from sqlalchemy
from sqlalchemy import Table, Column, String, Integer, Float, Boolean

# Define a new table with a name, count, amount, and valid column: data
data = Table('data', metadata,
             Column('name', String(255)),
             Column('count', Integer()),
             Column('amount', Float()),
             Column('valid', Boolean())
)

# Use the metadata to create the table
metadata.create_all(engine)

# Print table details
print(repr(engine.table_names()))



# Import Table, Column, String, Integer, Float, Boolean from sqlalchemy
from sqlalchemy import Table, Column, String, Integer, Float, Boolean

# Define a new table with a name, count, amount, and valid column: data
data = Table('data', metadata,
             Column('name', String(255), unique=True),
             Column('count', Integer(), default=1),
             Column('amount', Float()),
             Column('valid', Boolean(), default=False)
)

# Use the metadata to create the table
Esempio n. 17
0
def test_alter_column_schema_type_existing_type_no_const():
    context = op_fixture('postgresql')
    op.alter_column("t", "c", type_=String(10), existing_type=Boolean())
    context.assert_(
        'ALTER TABLE t ALTER COLUMN c TYPE VARCHAR(10)'
    )
Esempio n. 18
0
class Post(BaseModel, CommentMixin, ReactMixin):
    STATUSES = (
        STATUS_UNPUBLISHED,
        STATUS_ONLINE
    ) = range(2)

    status = Column(SmallInteger(), default=STATUS_UNPUBLISHED)

    (TYPE_ARTICLE, TYPE_PAGE) = range(2)
    
    created_at = Column(DateTime, server_default=func.now(), nullable=False)

    title = Column(String(100), unique=True)
    author_id = Column(Integer())
    slug = Column(String(100))
    summary = Column(String(255))
    can_comment = Column(Boolean(), default=True)
    type = Column(Integer(), default=TYPE_ARTICLE)
    pageview = Column(Integer(), default=0)

    kind = config.K_POST


    @cache(MC_KEY_RELATED % ('{self.id}', '{limit}'))
    async def get_related(self, limit: int=4):
        tag_ids = [tag.id for tag in await self.tags]
        if not tag_ids:
            return []
        post_ids = set([ item['post_id']
            for item in await PostTag.async_in('tag_id', tag_ids)])
        post_ids -= set([self.id])
        if not post_ids: return []
        related_posts = [
            Post(**p)
            for p in await Post.async_in('id', post_ids)
        ]
        return related_posts[:limit] if len(related_posts) >= limit else related_posts

    @classmethod
    async def acreate(cls, **kwargs):
        tags = kwargs.pop('tags', [])
        content = kwargs.pop('content')
        obj_id = await super().acreate(**kwargs)
        kwargs['id'] = obj_id
        if tags:
            try:
                await PostTag.update_multi(obj_id, tags)
            except:
                await Post.adelete(id=obj_id)
                return
        obj = cls(**(await cls.async_first(id=obj_id)))
        await obj.set_content(content)
        return obj
    
    async def update_tags(self, tagnames):
        if tagnames:
            await PostTag.update_multi(self.id, tagnames)
        return True

    @property
    @cache(MC_KEY_TAGS_BY_POST_ID % ('{self.id}'))
    async def tags(self):
        pts = await PostTag.async_filter(post_id=self.id)
        if not pts:
            return []
        ids = [item['tag_id'] for item in pts]
        tags = await Tag.async_in('id', ids)
        tags = [Tag(**t) for t in tags]
        return tags

    @property
    async def author(self):
        print('user_id', self.author_id)
        rv = await User.cache(id=self.author_id)
        return {'name': rv['name'], 'id': self.author_id, 'avatar': rv['avatar']}
    
    @property
    def is_page(self):
        return self.type == self.TYPE_PAGE

    @property
    def preview_url(self):
        return f'/{self.__class__.__name__.lower()}/{self.id}/preview'

    async def set_content(self, content):
        return await self.set_props_by_key('content', content)

    async def asave(self, *args, **kwargs):
        content = kwargs.pop('content', None)
        if content is not None:
            await self.set_content('content', content)
        return await super().asave(*args, **kwargs)

    @property
    async def content(self):
        rv = await self.get_props_by_key('content')
        if rv:
            return rv.decode('utf-8')

    @classmethod
    @cache(MC_KEY_POST_BY_SLUG % '{slug}')
    async def get_by_slug(cls, slug):
        return await cls.async_first(slug=slug) 

    @classmethod
    @cache(MC_KEY_ALL_POSTS % '{with_page}')
    async def get_all(cls, with_page=True):
        if with_page:
            posts = await Post.async_filter(status=Post.STATUS_ONLINE)
        else:
            posts = await Post.async_filter(status=Post.STATUS_ONLINE,
                                            type=Post.TYPE_ARTICLE)
        return sorted(posts, key=lambda p: p['created_at'], reverse=True)

    @property
    def url(self):
        if self.is_page:
            return f'/page/{self.slug}'
        return f'/post/{getattr(self, config.PERMALINK_TYPE) or self.id}/'

    @property
    async def html_content(self):
        content = await self.content
        if not content:
            return ''
        return markdown(content)

    @property
    async def excerpt(self):
        if self.summary:
            return self.summary
        s = MLStripper()
        s.feed(await self.html_content)
        return trunc_utf8(BQ_REGEX.sub('', s.get_data()).replace('\n', ''), 100)

    @property
    async def toc(self):
        content = await self.content
        if not content:
            return ''
        toc.reset_toc()
        toc_md.parse(content)
        return toc.render_toc(level=4)

    @classmethod
    async def cache(cls, ident):
        if str(ident).isdigit():
            return await super().cache(id=ident)
        return await cls.get_by_slug(ident)

    async def clear_mc(self):
        print('Clear POst MC', self.created_at)
        try:
            keys = [
                MC_KEY_FEED, MC_KEY_SITEMAP, MC_KEY_SEARCH, MC_KEY_ARCHIVES,
                MC_KEY_TAGS, MC_KEY_RELATED % (self.id, 4),
                MC_KEY_POST_BY_SLUG % self.slug,
                MC_KEY_ARCHIVE % self.created_at.year
            ]
        except:
            import traceback
            traceback.print_exc()
        for i in [True, False]:
            keys.append(MC_KEY_ALL_POSTS % i)

        for tag in await self.tags:
            keys.append(MC_KEY_TAG % tag.id)
        await clear_mc(*keys)

    async def incr_pageview(self, increment=1):
        redis = await self.redis
        try:
            await redis.sadd(RK_ALL_POST_IDS,self.id)
            await redis.sadd(RK_VISITED_POST_IDS, self.id)
            return await redis.hincrby(RK_PAGEVIEW.format(self.id),
                                       PAGEVIEW_FIELD, 
                                       increment)
        except:
            return self.pageview

    @property
    async def pageview_(self):
        try:
            return int(await (await self.redis).hget(
                RK_PAGEVIEW.format(self.id), PAGEVIEW_FIELD) or 0
            )
        except RedisError:
            return self.pageview
Esempio n. 19
0
def upgrade(migrate_engine):
    meta = MetaData()
    meta.bind = migrate_engine

    volumes = Table('volumes', meta, autoload=True)

    #
    # New Tables
    #
    volume_types = Table(
        'volume_types', meta, Column('created_at', DateTime(timezone=False)),
        Column('updated_at', DateTime(timezone=False)),
        Column('deleted_at', DateTime(timezone=False)),
        Column('deleted', Boolean(create_constraint=True, name=None)),
        Column('id', Integer(), primary_key=True, nullable=False),
        Column('name',
               String(length=255,
                      convert_unicode=False,
                      assert_unicode=None,
                      unicode_error=None,
                      _warn_on_bytestring=False),
               unique=True))

    volume_type_extra_specs_table = Table(
        'volume_type_extra_specs', meta,
        Column('created_at', DateTime(timezone=False)),
        Column('updated_at', DateTime(timezone=False)),
        Column('deleted_at', DateTime(timezone=False)),
        Column('deleted', Boolean(create_constraint=True, name=None)),
        Column('id', Integer(), primary_key=True, nullable=False),
        Column('volume_type_id',
               Integer(),
               ForeignKey('volume_types.id'),
               nullable=False),
        Column(
            'key',
            String(length=255,
                   convert_unicode=False,
                   assert_unicode=None,
                   unicode_error=None,
                   _warn_on_bytestring=False)),
        Column(
            'value',
            String(length=255,
                   convert_unicode=False,
                   assert_unicode=None,
                   unicode_error=None,
                   _warn_on_bytestring=False)))

    volume_metadata_table = Table(
        'volume_metadata', meta, Column('created_at',
                                        DateTime(timezone=False)),
        Column('updated_at', DateTime(timezone=False)),
        Column('deleted_at', DateTime(timezone=False)),
        Column('deleted', Boolean(create_constraint=True, name=None)),
        Column('id', Integer(), primary_key=True, nullable=False),
        Column('volume_id',
               Integer(),
               ForeignKey('volumes.id'),
               nullable=False),
        Column(
            'key',
            String(length=255,
                   convert_unicode=False,
                   assert_unicode=None,
                   unicode_error=None,
                   _warn_on_bytestring=False)),
        Column(
            'value',
            String(length=255,
                   convert_unicode=False,
                   assert_unicode=None,
                   unicode_error=None,
                   _warn_on_bytestring=False)))

    new_tables = (volume_types, volume_type_extra_specs_table,
                  volume_metadata_table)

    for table in new_tables:
        try:
            table.create()
        except Exception:
            LOG.info(repr(table))
            LOG.exception('Exception while creating table')
            raise

    #
    # New Columns
    #
    volume_type_id = Column('volume_type_id', Integer(), nullable=True)
    volumes.create_column(volume_type_id)
Esempio n. 20
0
)

permissions: Callable[[MetaData], Table] = lambda metadata: Table(
    "permissions",
    metadata,
    Column(
        "id",
        String(64),
        primary_key=True,
        nullable=False,
        unique=True,
        default=lambda: str(uuid.uuid4()),
    ),
    Column("resource", String(128), nullable=False),
    Column("action", Enum(model.PermissionActionEnum), nullable=False),
    Column("is_conditional", Boolean(), nullable=False),
    UniqueConstraint("resource", "action", "is_conditional"),
)

roles: Callable[[MetaData], Table] = lambda metadata: Table(
    "roles",
    metadata,
    Column(
        "id",
        String(64),
        primary_key=True,
        nullable=False,
        unique=True,
        default=lambda: str(uuid.uuid4()),
    ),
    Column("code", String(128), nullable=False, unique=True, primary_key=True),
Esempio n. 21
0
class UserLoginAudit(Base):
    __tablename__ = 'tb_user_login_audit'
    id = Column(Integer, primary_key=True)
    loginID = Column(Integer, ForeignKey('tb_user_master.id'))  #foreign key
    attemptedTimeStamp = Column(TIMESTAMP, nullable=False)
    statusFlag = Column(Boolean(), nullable=False)
Esempio n. 22
0
class Invoice(Task, InvoiceCompute):
    """
        Invoice Model
    """
    __tablename__ = 'invoice'
    __table_args__ = default_table_args
    __mapper_args__ = {
        'polymorphic_identity': 'invoice',
    }
    id = Column(ForeignKey('task.id'),
                primary_key=True,
                info={
                    'colanderalchemy': {
                        'exclude': True
                    },
                })

    # Common with CancelInvoice
    financial_year = Column(
        Integer,
        info={'colanderalchemy': {
            'title': u"Année fiscale de référence"
        }},
        default=0)
    exported = deferred(Column(
        Boolean(),
        info={'colanderalchemy': {
            'title': u"A déjà été exportée ?"
        }},
        default=False),
                        group="edit")

    # Specific to Invoice
    paid_status = Column(
        String(10),
        default='waiting',
        info={'colanderalchemy': {
            'title': u'Statut de la facture',
        }},
    )
    estimation_id = Column(ForeignKey('estimation.id'))
    estimation = relationship(
        "Estimation",
        primaryjoin="Invoice.estimation_id==Estimation.id",
        info={
            'colanderalchemy': forms.EXCLUDED,
            'export': {
                'exclude': True
            },
        },
    )

    state_manager = DEFAULT_ACTION_MANAGER['invoice']

    paid_states = ('resulted', )
    not_paid_states = (
        'valid',
        'paid',
    )
    valid_states = paid_states + not_paid_states

    _number_tmpl = u"{s.company.name} {s.date:%Y-%m} F{s.company_index}"

    _name_tmpl = u"Facture {0}"

    _deposit_name_tmpl = u"Facture d'acompte {0}"

    _sold_name_tmpl = u"Facture de solde {0}"

    def _get_project_index(self, project):
        """
        Return the index of the current object in the associated project
        :param obj project: A Project instance in which we will look to get the
        current doc index
        :returns: The next number
        :rtype: int
        """
        return project.get_next_invoice_index()

    def _get_company_index(self, company):
        """
        Return the index of the current object in the associated company
        :param obj company: A Company instance in which we will look to get the
        current doc index
        :returns: The next number
        :rtype: int
        """
        return company.get_next_invoice_index()

    def set_deposit_label(self):
        self.name = self._deposit_name_tmpl.format(self.project_index)

    def set_sold_label(self):
        self.name = self._sold_name_tmpl.format(self.project_index)

    def set_project(self, project):
        self.project = project

    def gen_cancelinvoice(self, user):
        """
            Return a cancel invoice with self's informations
        """
        cancelinvoice = CancelInvoice(
            user=user,
            company=self.company,
            project=self.project,
            customer=self.customer,
            phase_id=self.phase_id,
            address=self.address,
            workplace=self.workplace,
            description=self.description,
            invoice=self,
            expenses_ht=-1 * self.expenses_ht,
            financial_year=self.financial_year,
            display_units=self.display_units,
            business_type_id=self.business_type_id,
            business_id=self.business_id,
        )

        cancelinvoice.line_groups = []
        for group in self.line_groups:
            cancelinvoice.line_groups.append(group.gen_cancelinvoice_group())
        order = self.get_next_row_index()

        for discount in self.discounts:
            discount_line = TaskLine(
                cost=discount.amount,
                tva=discount.tva,
                quantity=1,
                description=discount.description,
                order=order,
                unity='',
            )
            discount_line.product_id = Product.first_by_tva_value(discount.tva)
            order += 1
            cancelinvoice.default_line_group.lines.append(discount_line)

        for index, payment in enumerate(self.payments):
            paid_line = TaskLine(
                cost=math_utils.reverse_tva(
                    payment.amount,
                    payment.tva.value,
                    False,
                ),
                tva=payment.tva.value,
                quantity=1,
                description=u"Paiement {0}".format(index + 1),
                order=order,
                unity='NONE',
            )
            paid_line.product_id = Product.first_by_tva_value(
                payment.tva.value)
            order += 1
            cancelinvoice.default_line_group.lines.append(paid_line)
        cancelinvoice.mentions = self.mentions
        cancelinvoice.payment_conditions = u"Réglé"
        return cancelinvoice

    def get_next_row_index(self):
        return len(self.default_line_group.lines) + 1

    def record_payment(self, **kw):
        """
        Record a payment for the current invoice
        """
        resulted = kw.pop('resulted', False)
        if kw['amount'] > 0:
            payment = Payment()
            for key, value in kw.iteritems():
                setattr(payment, key, value)
            logger.info(u"Amount : {0}".format(payment.amount))
            self.payments.append(payment)

        return self.check_resulted(
            force_resulted=resulted,
            user_id=kw['user_id'],
        )

    def check_resulted(self, force_resulted=False, user_id=None):
        """
        Check if the invoice is resulted or not and set the appropriate status
        """
        logger.debug(u"-> There still to pay : %s" % self.topay())
        if self.topay() <= 0 or force_resulted:
            self.paid_status = 'resulted'

        elif len(self.payments) > 0 or self.cancelinvoice_amount() > 0:
            self.paid_status = 'paid'

        else:
            self.paid_status = 'waiting'

        if user_id is not None:
            status_record = TaskStatus(status_code=self.paid_status,
                                       status_person_id=user_id,
                                       status_comment='')
            self.statuses.append(status_record)
        return self

    def duplicate(self, user, **kw):
        """
        Duplicate the current invoice

        Mandatory args :

            user

                The user duplicating this estimation

            customer

            project
        """
        invoice = Invoice(user=user, company=self.company, **kw)

        if invoice.customer.id == self.customer_id:
            invoice.address = self.address

        invoice.workplace = self.workplace

        invoice.description = self.description
        invoice.notes = self.notes

        invoice.payment_conditions = self.payment_conditions
        invoice.display_units = self.display_units
        invoice.expenses_ht = self.expenses_ht
        invoice.financial_year = datetime.date.today().year

        invoice.line_groups = []
        for group in self.line_groups:
            invoice.line_groups.append(group.duplicate())

        for line in self.discounts:
            invoice.discounts.append(line.duplicate())

        invoice.mentions = self.mentions
        return invoice

    def __repr__(self):
        return u"<Invoice id:{s.id}>".format(s=self)

    def __json__(self, request):
        datas = Task.__json__(self, request)

        datas.update(
            dict(
                financial_year=self.financial_year,
                exported=self.exported,
                estimation_id=self.estimation_id,
            ))
        return datas

    def is_tolate(self):
        """
            Return True if a payment is expected since more than
            45 days
        """
        res = False
        if self.paid_status in ('waiting', 'paid'):
            today = datetime.date.today()
            elapsed = today - self.date
            if elapsed > datetime.timedelta(days=45):
                res = True
            else:
                res = False
        return res
Esempio n. 23
0
class Instance(BASE, NovaBase):
    """Represents a guest vm."""
    __tablename__ = 'instances'
    injected_files = []

    id = Column(Integer, primary_key=True, autoincrement=True)

    @property
    def name(self):
        try:
            base_name = FLAGS.instance_name_template % self.id
        except TypeError:
            # Support templates like "uuid-%(uuid)s", etc.
            info = {}
            for key, value in self.iteritems():
                # prevent recursion if someone specifies %(name)s
                # %(name)s will not be valid.
                if key == 'name':
                    continue
                info[key] = value
            try:
                base_name = FLAGS.instance_name_template % info
            except KeyError:
                base_name = self.uuid
        if getattr(self, '_rescue', False):
            base_name += "-rescue"
        return base_name

    user_id = Column(String(255))
    project_id = Column(String(255))

    image_ref = Column(String(255))
    kernel_id = Column(String(255))
    ramdisk_id = Column(String(255))
    server_name = Column(String(255))

    #    image_ref = Column(Integer, ForeignKey('images.id'), nullable=True)
    #    kernel_id = Column(Integer, ForeignKey('images.id'), nullable=True)
    #    ramdisk_id = Column(Integer, ForeignKey('images.id'), nullable=True)
    #    ramdisk = relationship(Ramdisk, backref=backref('instances', order_by=id))
    #    kernel = relationship(Kernel, backref=backref('instances', order_by=id))
    #    project = relationship(Project, backref=backref('instances', order_by=id))

    launch_index = Column(Integer)
    key_name = Column(String(255))
    key_data = Column(Text)

    power_state = Column(Integer)
    vm_state = Column(String(255))
    task_state = Column(String(255))

    memory_mb = Column(Integer)
    vcpus = Column(Integer)
    root_gb = Column(Integer)
    ephemeral_gb = Column(Integer)

    hostname = Column(String(255))
    host = Column(String(255))  # , ForeignKey('hosts.id'))

    # *not* flavor_id
    instance_type_id = Column(Integer)

    user_data = Column(Text)

    reservation_id = Column(String(255))

    scheduled_at = Column(DateTime)
    launched_at = Column(DateTime)
    terminated_at = Column(DateTime)

    availability_zone = Column(String(255))

    # User editable field for display in user-facing UIs
    display_name = Column(String(255))
    display_description = Column(String(255))

    # To remember on which host a instance booted.
    # An instance may have moved to another host by live migraiton.
    launched_on = Column(Text)
    locked = Column(Boolean)

    os_type = Column(String(255))
    architecture = Column(String(255))
    vm_mode = Column(String(255))
    uuid = Column(String(36))

    root_device_name = Column(String(255))
    default_ephemeral_device = Column(String(255), nullable=True)
    default_swap_device = Column(String(255), nullable=True)
    config_drive = Column(String(255))

    # User editable field meant to represent what ip should be used
    # to connect to the instance
    access_ip_v4 = Column(String(255))
    access_ip_v6 = Column(String(255))

    auto_disk_config = Column(Boolean())
    progress = Column(Integer)

    # EC2 instance_initiated_shutdown_teminate
    # True: -> 'terminate'
    # False: -> 'stop'
    shutdown_terminate = Column(Boolean(), default=True, nullable=False)

    # EC2 disable_api_termination
    disable_terminate = Column(Boolean(), default=False, nullable=False)

    # Openstack zone name
    zone_name = Column(String(255))
Esempio n. 24
0
class CancelInvoice(Task, TaskCompute):
    """
        CancelInvoice model
        Could also be called negative invoice
    """
    __tablename__ = 'cancelinvoice'
    __table_args__ = default_table_args
    __mapper_args__ = {'polymorphic_identity': 'cancelinvoice'}
    id = Column(Integer,
                ForeignKey('task.id'),
                primary_key=True,
                info={
                    'colanderalchemy': {
                        'exclude': True
                    },
                })
    # Common with Invoice
    financial_year = Column(
        Integer,
        info={'colanderalchemy': {
            'title': u"Année fiscale de référence"
        }},
        default=0)
    exported = deferred(Column(
        Boolean(),
        info={'colanderalchemy': {
            "title": "A déjà été exportée ?"
        }},
        default=False),
                        group="edit")

    # Specific to CancelInvoice
    invoice_id = Column(Integer,
                        ForeignKey('invoice.id'),
                        info={
                            'colanderalchemy': {
                                'title': u"Identifiant de la facture associée",
                            }
                        },
                        default=None)
    invoice = relationship("Invoice",
                           backref=backref("cancelinvoices",
                                           info={
                                               'colanderalchemy':
                                               forms.EXCLUDED,
                                           }),
                           primaryjoin="CancelInvoice.invoice_id==Invoice.id",
                           info={
                               'colanderalchemy': forms.EXCLUDED,
                           })

    state_manager = DEFAULT_ACTION_MANAGER['cancelinvoice']
    valid_states = ('valid', )

    _number_tmpl = u"{s.company.name} {s.date:%Y-%m} A{s.company_index}"

    _name_tmpl = u"Avoir {0}"

    def _get_project_index(self, project):
        """
        Return the index of the current object in the associated project
        :param obj project: A Project instance in which we will look to get the
        current doc index
        :returns: The next number
        :rtype: int
        """
        return project.get_next_invoice_index()

    def _get_company_index(self, company):
        """
        Return the index of the current object in the associated company
        :param obj company: A Company instance in which we will look to get the
        current doc index
        :returns: The next number
        :rtype: int
        """
        return company.get_next_invoice_index()

    def is_tolate(self):
        """
        Return False
        """
        return False

    def __repr__(self):
        return u"<CancelInvoice id:{s.id}>".format(s=self)

    def __json__(self, request):
        datas = Task.__json__(self, request)

        datas.update(
            dict(
                invoice_id=self.invoice_id,
                financial_year=self.financial_year,
                exported=self.exported,
            ))
        return datas
Esempio n. 25
0
class User(db.Model):
    __tablename__ = "users"
    id = Column(Integer, primary_key=True)
    password = Column(String(128))
    active = Column(Boolean())
    confirmed_at = Column(ArrowType())
    username = Column(String(255), nullable=False, unique=True)
    email = Column(String(128), unique=True)
    profile_picture = Column(String(255))
    roles = relationship(
        "Role",
        secondary=roles_users,
        passive_deletes=True,
        backref=db.backref("user"),
        lazy="dynamic",
    )
    certificates = relationship("Certificate",
                                backref=db.backref("user"),
                                lazy="dynamic")
    pending_certificates = relationship("PendingCertificate",
                                        backref=db.backref("user"),
                                        lazy="dynamic")
    authorities = relationship("Authority",
                               backref=db.backref("user"),
                               lazy="dynamic")
    keys = relationship("ApiKey", backref=db.backref("user"), lazy="dynamic")
    logs = relationship("Log", backref=db.backref("user"), lazy="dynamic")

    sensitive_fields = ("password", )

    def check_password(self, password):
        """
        Hash a given password and check it against the stored value
        to determine it's validity.

        :param password:
        :return:
        """
        if self.password:
            return bcrypt.check_password_hash(self.password, password)

    def hash_password(self):
        """
        Generate the secure hash for the password.

        :return:
        """
        if self.password:
            self.password = bcrypt.generate_password_hash(
                self.password).decode("utf-8")

    @property
    def is_admin(self):
        """
        Determine if the current user has the 'admin' role associated
        with it.

        :return:
        """
        for role in self.roles:
            if role.name == "admin":
                return True

    def __repr__(self):
        return "User(username={username})".format(username=self.username)
Esempio n. 26
0
class Payment(DBBASE, PersistentACLMixin):
    """
        Payment entry
    """
    __tablename__ = 'payment'
    __table_args__ = default_table_args
    id = Column(Integer, primary_key=True)
    created_at = Column(
        DateTime(),
        info={'colanderalchemy': {
            'exclude': True,
            'title': u"Créé(e) le",
        }},
        default=datetime.datetime.now,
    )

    updated_at = Column(DateTime(),
                        info={
                            'colanderalchemy': {
                                'exclude': True,
                                'title': u"Mis(e) à jour le",
                            }
                        },
                        default=datetime.datetime.now,
                        onupdate=datetime.datetime.now)

    mode = Column(String(50),
                  info={'colanderalchemy': {
                      'title': u"Mode de paiement"
                  }})
    amount = Column(
        BigInteger(),
        info={'colanderalchemy': {
            "title": u"Montant"
        }},
    )
    bank_remittance_id = Column(
        String(255),
        info={
            'colanderalchemy': {
                'title': u"Identifiant de remise en banque"
            }
        },
    )
    date = Column(
        DateTime(),
        info={'colanderalchemy': {
            'title': u"Date de remise"
        }},
        default=datetime.datetime.now,
    )
    exported = Column(Boolean(), default=False)
    task_id = Column(
        Integer,
        ForeignKey('task.id', ondelete="cascade"),
        info={'colanderalchemy': {
            'title': u"Identifiant du document"
        }},
    )
    bank_id = Column(
        ForeignKey('bank_account.id'),
        info={'colanderalchemy': {
            'title': u"Compte en banque"
        }},
    )
    tva_id = Column(
        ForeignKey('tva.id'),
        info={'colanderalchemy': {
            'title': u"Tva associée à ce paiement"
        }},
        nullable=True)

    user_id = Column(
        ForeignKey('accounts.id'),
        info={'colanderalchemy': {
            'title': u"Utilisateur"
        }},
    )

    user = relationship(
        "User",
        info={'colanderalchemy': {
            'exclude': True
        }},
    )

    bank = relationship("BankAccount",
                        back_populates='payments',
                        info={'colanderalchemy': {
                            'exclude': True
                        }})
    tva = relationship("Tva", info={'colanderalchemy': {'exclude': True}})
    task = relationship(
        "Task",
        primaryjoin="Task.id==Payment.task_id",
    )
    # Formatting precision
    precision = 5

    # Usefull aliases
    @property
    def invoice(self):
        return self.task

    @property
    def parent(self):
        return self.task

    # Simple function
    def get_amount(self):
        return self.amount

    def __json__(self, request):
        """
        Build a Json representation of this object

        :rtype: dict
        """
        return dict(
            id=self.id,
            created_at=self.created_at,
            updated_at=self.updated_at,
            mode=self.mode,
            amount=math_utils.integer_to_amount(self.amount, 5),
            bank_remittance_id=self.bank_remittance_id,
            date=self.date,
            exporter=self.exported,
            task_id=self.task_id,
            bank_id=self.bank_id,
            tva_id=self.tva_id,
            user_id=self.user_id,
        )

    def __unicode__(self):
        return u"<Payment id:{s.id} task_id:{s.task_id} amount:{s.amount}\
 mode:{s.mode} date:{s.date}".format(s=self)
Esempio n. 27
0
class User(db.Model, CRUDMixin, UserMixin):
    """
    A user of the app.
    """

    __tablename__ = "users"
    user_id = Column(Integer, primary_key=True)
    username = Column(UnicodeText, unique=True, nullable=False)
    email = Column(UnicodeText, unique=True, nullable=False)
    salt = Column(UnicodeText, nullable=True)
    password = Column(UnicodeText, nullable=True)
    created_at = Column(DateTime, nullable=False, default=dt.datetime.utcnow)
    first_name = Column(UnicodeText, nullable=True)
    last_name = Column(UnicodeText, nullable=True)
    active = Column(Boolean(), default=False)
    is_admin = Column(Boolean(), default=False)
    api_token = Column(UnicodeText, nullable=True)

    reports = relationship("Report", back_populates="user")
    uploads = relationship("Upload", back_populates="user")
    roles = relationship("Role", back_populates="user")
    filters = relationship("SampleFilter", back_populates="user")
    favourite_plots = relationship("PlotFavourite", back_populates="user")
    dashboards = relationship("Dashboard", back_populates="user")

    def __init__(self, password=None, **kwargs):
        """
        Create instance.
        """
        db.Model.__init__(self, **kwargs)

        # Config adjusts the default active status
        if "active" not in kwargs:
            self.active = not current_app.config["USER_REGISTRATION_APPROVAL"]

        self.salt = getrandstr(rng, digits + letters, 80)
        self.api_token = getrandstr(rng, digits + letters, 80)
        if password:
            self.set_password(password)
        else:
            self.password = None

    def enforce_admin(self):
        """
        Enforce that the first user is an active admin.

        This is included as a method that isn't automatically called,
        because there are cases where we don't want this behaviour to
        happen, such as during testing.
        """
        if db.session.query(User).count() == 0:
            self.is_admin = True
            self.active = True

    # users = User.__table__
    #     if target.user_id == 1:
    #         connection.execute(users.update().where(users.c.user_id == 1).values(is_admin=True, active=True))

    @hybrid_property
    def full_name(self):
        return self.first_name + " " + self.last_name

    def reset_password(self):
        password = getrandstr(rng, digits + letters, 10)
        self.set_password(password)
        return password

    def set_password(self, password):
        """
        Set password.
        """
        self.password = argon2.using(rounds=4).hash(password + self.salt)

    def check_password(self, value):
        """
        Check password.
        """
        return argon2.verify(value + self.salt, self.password)

    def is_authenticated(self):
        return True

    def is_active(self):
        return self.active

    def get_id(self):
        # must return unicode
        return str(self.user_id)

    def __repr__(self):
        """
        Represent instance as a unique string.
        """
        return "<User({username!r})>".format(username=self.username)
Esempio n. 28
0
 def test_render_literal_bool(self):
     self._literal_round_trip(Boolean(), [True, False], [True, False])
Esempio n. 29
0
def test_alter_column_schema_type_named():
    context = op_fixture('mssql')
    op.alter_column("t", "c", type_=Boolean(name="xyz"))
    context.assert_('ALTER TABLE t ALTER COLUMN c BIT',
                    'ALTER TABLE t ADD CONSTRAINT xyz CHECK (c IN (0, 1))')
Esempio n. 30
0
accounts_gpgkey = Table(
    "accounts_gpgkey",
    db.metadata,
    Column("id", Integer(), primary_key=True, nullable=False),
    Column(
        "user_id",
        Integer(),
        ForeignKey(
            "accounts_user.id",
            deferrable=True,
            initially="DEFERRED",
        ),
        nullable=False,
    ),
    Column("key_id", CIText(), nullable=False),
    Column("verified", Boolean(), nullable=False),
    UniqueConstraint("key_id", name="accounts_gpgkey_key_id_key"),
    CheckConstraint(
        "key_id ~* '^[A-F0-9]{8}$'::citext",
        name="accounts_gpgkey_valid_key_id",
    ),
)

Index("accounts_gpgkey_user_id", accounts_gpgkey.c.user_id)

browse_tally = Table(
    "browse_tally",
    db.metadata,
    Column("trove_id", Integer(), primary_key=True, nullable=False),
    Column("tally", Integer()),
)