Example #1
0
 def _db_update(self, ok, msg):
     db = self._db_manager.get_db()
     try:
         while True:
             try:
                 if ok:
                     if msg['message_name'] == 'ExecScript':
                         db.messages.filter(
                                 db.messages.messageid == msg['messageid']).delete()
                     else:
                         db.messages.filter(db.messages.messageid == msg['messageid']).update({
                                 'status': 1,
                                 'message': '',
                                 'dtlasthandleattempt': func.now()},
                                 synchronize_session=False)
                     if msg['event_id']:
                         db.events.filter(db.events.event_id == msg['event_id']).update({
                                 db.events.msg_sent: db.events.msg_sent + 1})
                 else:
                     db.messages.filter(db.messages.messageid == msg['messageid']).update({
                             'status': 0 if msg['handle_attempts'] < 2 else 3,
                             'handle_attempts': msg['handle_attempts'] + 1,
                             'dtlasthandleattempt': func.now()},
                             synchronize_session=False)
                 db.session.commit()
                 break
             except db_exc.SQLAlchemyError:
                 db.session.remove()
                 LOG.error(helper.exc_info())
                 time.sleep(5)
     finally:
         db.session.remove()
Example #2
0
def active_duration_range(query, minimum_active_duration,
        maximum_active_duration):
    if minimum_active_duration is not None:
        minimum_active_duration = datetime.timedelta(
                seconds=minimum_active_duration)
        finished_claims = query.filter(
                models.Claim.activated != None,
                models.Claim.deactivated != None,
                models.Claim.deactivated - models.Claim.activated
                    >= minimum_active_duration)
        active_claims = query.filter(
                models.Claim.activated != None,
                models.Claim.deactivated == None,
                func.now() - models.Claim.activated
                    >= minimum_active_duration)
        query = finished_claims.union(active_claims)

    if maximum_active_duration is not None:
        maximum_active_duration = datetime.timedelta(
                seconds=maximum_active_duration)
        finished_claims = query.filter(
                models.Claim.activated != None,
                models.Claim.deactivated != None,
                models.Claim.deactivated - models.Claim.activated
                    <= maximum_active_duration)
        active_claims = query.filter(
                models.Claim.activated != None,
                models.Claim.deactivated == None,
                func.now() - models.Claim.activated
                    <= maximum_active_duration)
        query = finished_claims.union(active_claims)

    return query
def upgrade(migrate_engine):
    metadata.bind = migrate_engine
    instance_table = Table(
        "instance",
        metadata,
        Column("id", Integer, primary_key=True),
        Column("key", Unicode(20), nullable=False, unique=True),
        Column("label", Unicode(255), nullable=False),
        Column("description", UnicodeText(), nullable=True),
        Column("required_majority", Float, nullable=False),
        Column("activation_delay", Integer, nullable=False),
        Column("create_time", DateTime, default=func.now()),
        Column("access_time", DateTime, default=func.now(), onupdate=func.now()),
        Column("delete_time", DateTime, nullable=True),
        Column("creator_id", Integer, ForeignKey("user.id"), nullable=False),
        Column("default_group_id", Integer, ForeignKey("group.id"), nullable=True),
        Column("allow_adopt", Boolean, default=True),
        Column("allow_delegate", Boolean, default=True),
        Column("allow_propose", Boolean, default=True),
        Column("allow_index", Boolean, default=True),
        Column("hidden", Boolean, default=False),
        Column("locale", Unicode(7), nullable=True),
        Column("css", UnicodeText(), nullable=True),
        Column("frozen", Boolean, default=False),
        Column("milestones", Boolean, default=False),
        Column("use_norms", Boolean, nullable=True, default=True),
        Column("require_selection", Boolean, nullable=True, default=False),
        Column("is_authenticated", Boolean, nullable=True, default=False),
    )

    hide_categories = Column("hide_global_categories", Boolean, nullable=True, default=False)
    hide_categories.create(instance_table)
    u = instance_table.update(values={"hide_global_categories": False})
    migrate_engine.execute(u)
def get_dag_duration_info():
    '''get duration of currently running DagRuns
    :return dag_info
    '''
    driver = Session.bind.driver
    durations = {
        'pysqlite': func.sum(
            (func.julianday(func.current_timestamp()) - func.julianday(DagRun.start_date)) * 86400.0
        ),
        'mysqldb': func.sum(func.timestampdiff(text('second'), DagRun.start_date, func.now())),
        'default': func.sum(func.now() - DagRun.start_date)
    }
    duration = durations.get(driver, durations['default'])

    with session_scope(Session) as session:
        return session.query(
            DagRun.dag_id,
            DagRun.run_id,
            duration.label('duration')
        ).group_by(
            DagRun.dag_id,
            DagRun.run_id
        ).filter(
            DagRun.state == State.RUNNING
        ).all()
Example #5
0
    def whereInEquipement(self,fullQueryJoin,criteria):
        sensorObj = list(filter(lambda x:'FK_Sensor'==x['Column'], criteria))[0]
        sensor = sensorObj['Value']

        table = Base.metadata.tables['MonitoredSiteEquipment']
        joinTable = outerjoin(table,Sensor, table.c['FK_Sensor'] == Sensor.ID)

        if sensorObj['Operator'].lower() in ['is','is not'] and sensorObj['Value'].lower() == 'null':
            subSelect = select([table.c['FK_MonitoredSite']]
                ).select_from(joinTable).where(
                and_(MonitoredSite.ID== table.c['FK_MonitoredSite']
                    ,or_(table.c['EndDate'] >= func.now(),table.c['EndDate'] == None)
                        ))
            if sensorObj['Operator'].lower() == 'is':
                fullQueryJoin = fullQueryJoin.where(~exists(subSelect))
            else :
                fullQueryJoin = fullQueryJoin.where(exists(subSelect))
        else :
            subSelect = select([table.c['FK_MonitoredSite']]
                ).select_from(joinTable).where(
                and_(MonitoredSite.ID== table.c['FK_MonitoredSite']
                    ,and_(eval_.eval_binary_expr(Sensor.UnicIdentifier,sensorObj['Operator'],sensor)
                        ,or_(table.c['EndDate'] >= func.now(),table.c['EndDate'] == None))
                        ))
            fullQueryJoin = fullQueryJoin.where(exists(subSelect))
        return fullQueryJoin
def upgrade(migrate_engine):
    meta.bind = migrate_engine
    instance_table = Table('instance', meta,
        Column('id', Integer, primary_key=True),
        Column('key', Unicode(20), nullable=False, unique=True),
        Column('label', Unicode(255), nullable=False),
        Column('description', UnicodeText(), nullable=True),
        Column('required_majority', Float, nullable=False),
        Column('activation_delay', Integer, nullable=False),
        Column('create_time', DateTime, default=func.now()),
        Column('access_time', DateTime, default=func.now(), onupdate=func.now()),
        Column('delete_time', DateTime, nullable=True),
        Column('creator_id', Integer, ForeignKey('user.id'), nullable=False),
        Column('default_group_id', Integer, ForeignKey('group.id'), nullable=True),
        Column('allow_adopt', Boolean, default=True),       
        Column('allow_delegate', Boolean, default=True),
        Column('allow_index', Boolean, default=True),
        Column('hidden', Boolean, default=False),
        Column('locale', Unicode(7), nullable=True),
        Column('css', UnicodeText(), nullable=True),
        Column('use_norms', Boolean, nullable=True, default=True)
    )
    
    propose = Column('allow_propose', Boolean, default=True)
    propose.create(instance_table)
    u = instance_table.update(values={'allow_propose': True})
    migrate_engine.execute(u)
Example #7
0
    def run(self):
        import time
        from v2ex.service.fetcher_manager import FetcherManager

        while not self._stop_flag:
            time.sleep(1)
            nid = FetcherManager.get_task()
            ntf_token = NtfTokenDao.get_from_nid(nid)
            if ntf_token is None:
                FetcherManager.remove_task(nid)
                continue

            if self.should_check_update(ntf_token):
                if self.has_update(ntf_token):
                    logging.debug("found update for %s", ntf_token.token)
                    self.gcm_send(ntf_token.uid, gcm.send_notify)
                else:
                    logging.debug("not found update for %s", ntf_token.token)

                ntf_token.last_fetch_time = func.now()
                db.get_session().commit()
            elif self.should_ping(ntf_token):
                self.gcm_send(ntf_token.uid, gcm.send_ping)

                ntf_token.last_ping_time = func.now()
                db.get_session().commit()
Example #8
0
def advance(session, group_id, station_id):
    state = GroupStation.get(group_id, station_id)

    # The first state to set - if there is nothing yet - is "ARRIVED"
    if not state:
        group = Group.one(id=group_id)
        station = Station.one(id=station_id)
        state = GroupStation(group_id, station_id)
        state.state = STATE_ARRIVED
        session.add(state)
        return STATE_ARRIVED

    group = state.group
    station = state.station

    if state.state == STATE_UNKNOWN:
        state.state = STATE_ARRIVED
    elif state.state == STATE_ARRIVED:
        if not group.departure_time and station.is_start:
            group.departure_time = func.now()
        if not group.finish_time and station.is_end:
            group.finish_time = func.now()
            group.completed = True
        state.state = STATE_FINISHED
    elif state.state == STATE_FINISHED:
        state.state = STATE_UNKNOWN
    else:
        raise ValueError('%r is not a valid state!' % state.state)

    return state.state
Example #9
0
    def get_delay(self, update):
        """Return the minutes to delay the viewing of submission results.

        Only store information into the datebase when `update` is set.

        """
        if hasattr(self, '_delay'):
            return self._delay

        now = datetime.now(UTC())
        zero = timedelta(0)
        delay = self.project.delay - (now - self.created_at)
        if delay <= zero:  # Never delay longer than the project's delay time
            self._delay = None
        elif self.group.viewed_at is None:  # Don't delay
            if update:
                self.group.viewed_at = func.now()
            self._delay = None
        elif self.created_at <= self.group.viewed_at:  # Show older results
            self._delay = None
        else:
            pv_delay = self.project.delay - (now - self.group.viewed_at)
            if pv_delay <= zero:
                if update:  # Update the counter
                    self.group.viewed_at = func.now()
                self._delay = None
            else:
                self._delay = min(delay, pv_delay).total_seconds() / 60
        return self._delay
Example #10
0
    def group(self, group, current=None):
        # Filter by group
        sub_query = db.session.query(GroupPatient)
        sub_query = sub_query.filter(GroupPatient.group == group, GroupPatient.patient_id == Patient.id)

        if current is not None:
            if current:
                # Between from and to date
                sub_query = sub_query.filter(
                    GroupPatient.from_date <= func.now(),
                    or_(
                        GroupPatient.to_date == null(),
                        GroupPatient.to_date >= func.now(),
                    )
                )
            else:
                # Outside from or to date
                sub_query = sub_query.filter(or_(
                    GroupPatient.from_date > func.now(),
                    and_(
                        GroupPatient.to_date != null(),
                        GroupPatient.to_date < func.now()
                    )
                ))

        self.query = self.query.filter(sub_query.exists())

        return self
Example #11
0
def _recover_delete_revisions(revisions_table, event,
                              last_available_revision_ids):
  """Log an action="deleted" copy for revisions with ids in passed list."""
  if not last_available_revision_ids:
    return
  columns_to_clone = sorted(set(c.name for c in revisions_table.c) -
                            {"id", "event_id", "action", "created_at",
                             "updated_at"})
  db.session.execute(
      revisions_table.insert().from_select(
          ["event_id",
           "action",
           "created_at",
           "updated_at"] + columns_to_clone,
          select(
              [event.id,
               literal("deleted"),
               func.now(),
               func.now()] + columns_to_clone,
          ).select_from(
              revisions_table,
          ).where(
              revisions_table.c.id.in_(last_available_revision_ids),
          ),
      ),
  )
Example #12
0
def set_group_state(session, group_id, station_id, new_state):
    """
    Updates the group state for a given station
    """
    station = session.query(Station).filter_by(id=station_id).first()
    if not station:
        LOG.debug('No station found with ID %r', station_id)
        return False

    group = session.query(Group).filter_by(id=group_id).first()
    if not group:
        LOG.debug('No group found with ID %r', group_id)
        return False

    if new_state == STATE_FINISHED:
        if not group.departure_time and station.is_start:
            group.departure_time = func.now()
        if not group.finish_time and station.is_end:
            group.finish_time = func.now()
            group.completed = True

    state = GroupStation(
        group_id=group_id,
        station_id=station_id,
        state=new_state)
    state = session.merge(state)
    session.flush()
    return state
Example #13
0
    def modified(self):
        """
            Modification Timestamp
        """
        from .types.date import DateTime

        return DateTime(server_default=func.now(), server_onupdate=func.now(), info=dict(readonly=True))
Example #14
0
    def __init__(self, master, id_num):
        session = Session()
        frame = Frame(master)
        frame.pack()

        member = session.query(Member).filter_by(mid=id_num).first()

        topline = "%s\n[%s]" % (member.name, str(id_num))
        nameline = Label(frame, text=topline, bg="black", fg="white", font="Monospace 30")
        nameline.pack(fill=X)

        lastLog = session.query(CheckIn).filter_by(mid=id_num).filter_by(timeOut=None)

        if lastLog.count() == 0:
            statusline = Label(frame, text="CHECKED IN", bg="black", fg="green", font="Monospace 30")
            statusline.pack(fill=X)
            newLog = CheckIn(mid=id_num, timeIn=func.now(), timeOut=None)
            session.add(newLog)

        else:
            lastLog = lastLog.first()
            statusline = Label(frame, text="CHECKED OUT", bg="black", fg="red", font="Monospace 30")
            statusline.pack(fill=X)
            lastLog.timeOut = func.now()

        if os.path.isfile("images/%s.png" % str(id_num).replace("'", '')):
            img = PIL.Image.open("images/%s.png" % str(id_num).replace("'", ''))
            photo = PIL.ImageTk.PhotoImage(img)
            picture = Label(frame, image=photo)
            picture.image = photo
            picture.pack()

        session.commit()
        session.close()
Example #15
0
def send_profile_visitor_email(**kwargs):
    template = email_template_env.get_template('profile_visitors.html')
    senders = AccountUser.query.filter(
        extract('dow', AccountUser.date_added) == extract('dow', func.now()),
        extract('hour', AccountUser.date_added) == extract('hour', func.now()),
    ).join(
        AccountUserVisit,
        (AccountUserVisit.profile_user_id == AccountUser.id) &
        (AccountUserVisit.notified == False)
    )

    for sender in senders:
        visitors = AccountUserVisit.get_all_visits_in_last_7_days(sender, 5)

        visitors = [AccountUserVisit.visit_item(*v) for v in visitors.all()]
        if visitors:
            body = template.render(
                sender=sender,
                visitors=visitors,
                **kwargs
            )
            send_email(sender.username, body)

            try:
                db.session.query(AccountUserVisit).filter_by(profile_user_id=sender.id).update({"notified": True})
                db.session.commit()
            except:
                db.session.rollback()
                raise
 def __init__(self):
       self.create_date =func.now()
       self.write_date = func.now()
       self.write_uid = 1
       obj_conexion =  configuracion()
       engine=create_engine(obj_conexion.config())
       Session= sessionmaker(bind=engine)
       self.session=Session()
Example #17
0
def timestamp_mixin(cls):
    """
    Model column: timestamp mixin decorator.
    """

    cls.created_at = Column(DateTime, default=func.now(), nullable=False)
    cls.updated_at = Column(DateTime, default=func.now(), onupdate=func.now(), nullable=False)
    return cls
Example #18
0
File: sql.py Project: hjalves/ines
def active_filter(columns):
    if not is_nonstr_iter(columns):
        columns = [columns]

    and_queries = []
    for column in columns:
        and_queries.append(or_(column.start_date <= func.now(), column.start_date.is_(None)))
        and_queries.append(or_(column.end_date > func.now(), column.end_date.is_(None)))
    return and_(*and_queries)
Example #19
0
def active_filter(tables):
    if not is_nonstr_iter(tables):
        tables = [tables]

    and_queries = []
    for table in tables:
        and_queries.append(or_(table.start_date <= func.now(), table.start_date.is_(None)))
        and_queries.append(or_(table.end_date > func.now(), table.end_date.is_(None)))
    return and_(*and_queries)
Example #20
0
 def _perform_sql(self):
     
     filter = {}
     filter["last_check"] = "now()"
     query = self.session.query(self.tables.monitor_obs)\
     .add_column((func.datediff(self.tables.monitor_obs.last_check, func.now())).label("test"))\
     .filter(self.tables.monitor_obs.locked == False)\
     .filter(func.datediff(self.tables.monitor_obs.last_check, func.now()) <= self.tables.monitor_obs.frequency) \
     .order_by('last_check')
     logger.debug(query)
Example #21
0
    def test_generic_now(self):
        assert isinstance(func.now().type, sqltypes.DateTime)

        for ret, dialect in [
            ('CURRENT_TIMESTAMP', sqlite.dialect()),
            ('now()', postgresql.dialect()),
            ('now()', mysql.dialect()),
            ('CURRENT_TIMESTAMP', oracle.dialect())
        ]:
            self.assert_compile(func.now(), ret, dialect=dialect)
Example #22
0
 def test_extract(self):
     fivedaysago = testing.db.scalar(select([func.now()])) - \
         datetime.timedelta(days=5)
     for field, exp in ('year', fivedaysago.year), \
             ('month', fivedaysago.month), ('day', fivedaysago.day):
         r = testing.db.execute(
             select([
                 extract(field, func.now() + datetime.timedelta(days=-5))])
         ).scalar()
         eq_(r, exp)
def downgrade():
    ### commands auto generated by Alembic - please adjust! ###
    op.add_column('contract', sa.Column('service_id', postgresql.UUID(), nullable=True))
    op.create_table('service',
    sa.Column('id', postgresql.UUID(), server_default=func.uuid_generate_v4(), autoincrement=False, nullable=False),
    sa.Column('created', postgresql.TIMESTAMP(timezone=True), server_default=func.now(), autoincrement=False, nullable=False),
    sa.Column('updated', postgresql.TIMESTAMP(timezone=True), server_default=func.now(), autoincrement=False, nullable=False),
    sa.Column('name', sa.TEXT(), autoincrement=False, nullable=False),
    sa.Column('description', sa.TEXT(), autoincrement=False, nullable=True),
    sa.PrimaryKeyConstraint('id', name=u'service_pkey')
    )
Example #24
0
def table(name, *args, **kwargs):
    return Table(
        name,
        metadata,
        Column('uuid', UUID(as_uuid=True), primary_key=True, server_default=text('gen_random_uuid()')),
        Column('created', DateTime, server_default=func.now(), nullable=False),
        Column('updated', DateTime, server_default=func.now(), onupdate=func.now(), nullable=False),
        Column('deleted', DateTime, nullable=True),
        *args,
        **kwargs
    )
 def is_in_notification_window(self, exclude_first_day=False):
     from indico.modules.rb import settings as rb_settings
     from indico.modules.rb.models.rooms import Room
     in_the_past = cast(self.start_dt, Date) < cast(func.now(), Date)
     days_until_occurrence = cast(self.start_dt, Date) - cast(func.now(), Date)
     notification_window = func.coalesce(Room.notification_before_days,
                                         rb_settings.get('notification_before_days', 1))
     if exclude_first_day:
         return (days_until_occurrence < notification_window) & ~in_the_past
     else:
         return (days_until_occurrence <= notification_window) & ~in_the_past
Example #26
0
    def _connectToDatabase(self):
        try:
            self.config = utils.get_config("MysqlLogger")
            db_name = self.config.get("db_name")
            db_user = self.config.get("db_user")
            db_pass = self.config.get("db_password")
            db_host = self.config.get("db_host")
            try:
                db_type = self.config.get("db_type")
            except:
                db_type = "mysql"

        except Exception:
            print "Could not load MysqlLogger"
            #self.disabled = True
        #DbConnect
        self.db_engine = create_engine(
            '' + db_type + '://' + db_user + ':' + db_pass + '@' + db_host +
            '/' + db_name
        )
        self.db_metadata = MetaData()
        self.db_chanlog = Table(
            'irc_chanlog', self.db_metadata,
            Column('ID', Integer, primary_key=True),
            Column('channel', String(14)),
            Column('sender', String(14), nullable=False),
            Column('sender_user', String(40)),
            Column('message', TEXT),
            Column(
                'timestamp',
                TIMESTAMP,
                nullable=False,
                default=func.now()
                )
        )
        self.db_chanevs = Table(
            'irc_chanevs', self.db_metadata,
            Column('ID', Integer, primary_key=True),
            Column('channel', String(14)),
            Column('sender', String(14), nullable=False),
            Column('sender_user', String(40)),
            Column('evtype', String(10)),
            Column(
                'timestamp',
                TIMESTAMP,
                nullable=False,
                default=func.now()
            )
        )
        try:
            self.db_conn = self.db_engine.connect()
        except OperationalError:
            print 'Nedalo sa mi pripojit sa do databazy'
Example #27
0
def ttl_range(query, minimum_ttl, maximum_ttl):
    if minimum_ttl is not None or maximum_ttl is not None:
        query = query.filter_by(status='active').join(models.Lock)

    if minimum_ttl is not None:
        query = query.filter(models.Lock.expiration_time - func.now()
                >= datetime.timedelta(seconds=minimum_ttl))

    if maximum_ttl is not None:
        query = query.filter(models.Lock.expiration_time - func.now()
                <= datetime.timedelta(seconds=maximum_ttl))

    return query
Example #28
0
def cleanup_expired_exports():
    settings = app.conf["PYRAMID_REGISTRY"].settings
    with db_session() as db:
        group(
            delete_expired_export.s(_.chat_id, _.user_id)
            for _ in db.query(ChatExport).filter(ChatExport.expires < func.now())
        ).delay()
        group(
            delete_expired_export.s(_.chat_id, _.user_id)
            for _ in db.query(ChatExport).filter(and_(
                ChatExport.generated == None,
                ChatExport.triggered < (func.now() - datetime.timedelta(settings["export.expiry_days"])),
            ))
        ).delay()
def upgrade():
    ### commands auto generated by Alembic - please adjust! ###
    op.create_table(u'content_stream',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('created_at', sa.DateTime(), server_default=func.now(),nullable=False),
    sa.Column('name', sa.String(length=100), nullable=False),
    sa.Column('uri', sa.String(length=200), nullable=False),
    sa.Column('description', sa.String(length=1000), nullable=True),
    sa.Column('ok_to_play', sa.Boolean(), nullable=True, default=True),
    sa.Column('created_by', sa.Integer(), nullable=True),
    sa.Column('updated_at', sa.DateTime(timezone=True), server_default=func.now(), nullable=True),
    sa.ForeignKeyConstraint(['created_by'], ['user_user.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
def upgrade():
    ### commands auto generated by Alembic - please adjust! ###
    op.add_column(u'content_communitymenu', sa.Column('date_created', sa.DateTime(timezone=True), server_default=func.now(), nullable=True))
    op.alter_column(u'content_communitymenu', 'updated_at',
               existing_type=postgresql.TIMESTAMP(),
               nullable=True, server_default=func.now())
    op.add_column(u'content_music', sa.Column('date_created', sa.DateTime(timezone=True), server_default=func.now(), nullable=True))
    op.add_column(u'content_musicalbum', sa.Column('date_created', sa.DateTime(timezone=True), server_default=func.now(), nullable=True))
    op.add_column(u'content_musicartist', sa.Column('date_created', sa.DateTime(timezone=True), server_default=func.now(), nullable=True))
    op.add_column(u'content_musicplaylist', sa.Column('date_created', sa.DateTime(timezone=True), server_default=func.now(), nullable=True))
    op.add_column(u'content_uploads', sa.Column('date_created', sa.DateTime(timezone=True), server_default=func.now(), nullable=True))
    op.alter_column(u'content_uploads', 'updated_at',
               existing_type=postgresql.TIMESTAMP(),
               nullable=True, server_default=func.now())
Example #31
0
 class PreassemblyUpdates(Base, IndraDBTable):
     __tablename__ = 'preassembly_updates'
     _always_disp = ['corpus_init', 'run_datetime']
     id = Column(Integer, primary_key=True)
     corpus_init = Column(Boolean, nullable=False)
     run_datetime = Column(DateTime, default=func.now())
Example #32
0
    def _check_running_runners(self):
        with get_session(self.db_engine) as session:
            running_runners = session.query(SchedulerRunner).filter_by(
                status=RunnerStatus.RUNNING.value).all()
            for runner in running_runners:
                if self.thread_reaper.is_full():
                    return
                lock_name = f'check_running_runner_{runner.id}_lock'
                check_lock = OpLocker(lock_name, self.db_engine).try_lock()
                if not check_lock:
                    logging.error(f'[composer] failed to lock, '
                                  f'ignore current running_runner_{runner.id}')
                    continue
                # TODO: restart runner if exit unexpectedly
                pipeline = Pipeline(**(json.loads(runner.pipeline)))
                output = json.loads(runner.output)
                context = decode_context(val=runner.context,
                                         db_engine=self.db_engine)
                current = context.internal['current']
                runner_fn = self.runner_cache.find_runner(runner.id, current)
                # check status of current one
                status, current_output = runner_fn.result(context)
                if status == RunnerStatus.RUNNING:
                    continue  # ignore
                if status == RunnerStatus.DONE:
                    output[current] = {'status': RunnerStatus.DONE.value}
                    context.set_internal(f'output_{current}', current_output)
                    current_idx = pipeline.deps.index(current)
                    if current_idx == len(pipeline.deps) - 1:  # all done
                        runner.status = RunnerStatus.DONE.value
                        runner.end_at = func.now()
                    else:  # run next one
                        next_one = pipeline.deps[current_idx + 1]
                        output[next_one] = {
                            'status': RunnerStatus.RUNNING.value
                        }
                        context.set_internal('current', next_one)
                        next_runner_fn = self.runner_cache.find_runner(
                            runner.id, next_one)
                        self.thread_reaper.enqueue(name=lock_name,
                                                   fn=next_runner_fn,
                                                   context=context)
                elif status == RunnerStatus.FAILED:
                    # TODO: abort now, need retry
                    output[current] = {'status': RunnerStatus.FAILED.value}
                    context.set_internal(f'output_{current}', current_output)
                    runner.status = RunnerStatus.FAILED.value
                    runner.end_at = func.now()

                runner.pipeline = PipelineEncoder().encode(pipeline)
                runner.output = json.dumps(output)
                runner.context = ContextEncoder().encode(context)

                updated_db = False
                try:
                    logging.info(
                        f'[composer] update runner, status: {runner.status}, '
                        f'pipeline: {runner.pipeline}, '
                        f'output: {output}, context: {runner.context}')
                    if check_lock.is_latest_version():
                        if check_lock.update_version():
                            session.commit()
                            updated_db = True
                    else:
                        logging.error(f'[composer] {lock_name} is outdated, '
                                      f'ignore updates to database')
                except Exception as e:  # pylint: disable=broad-except
                    logging.error(f'[composer] failed to update running '
                                  f'runner status, exception: {e}')
                    session.rollback()

                # delete useless runner obj in runner cache
                if status in (RunnerStatus.DONE,
                              RunnerStatus.FAILED) and updated_db:
                    self.runner_cache.del_runner(runner.id, current)
Example #33
0
class ReportStore(db.WikimetricsBase):
    """
    Stores each report node that runs in a report node tree to the database.
    Stores the necessary information to fetch the results from Celery as
    well as to re-run the node.
    """
    __tablename__ = 'report'

    id = Column(Integer, primary_key=True)
    created = Column(DateTime, default=func.now())
    user_id = Column(Integer)
    queue_result_key = Column(String(50))
    result_key = Column(String(50))
    status = Column(String(50))
    name = Column(String(2000))
    show_in_ui = Column(Boolean)
    parameters = Column(VARBINARY(4000))
    public = Column(Boolean)
    recurrent = Column(Boolean, default=False, nullable=False)
    recurrent_parent_id = Column(Integer, ForeignKey('report.id'))

    __table_args__ = (UniqueConstraint(recurrent_parent_id,
                                       created,
                                       name='uix_report'),
                      Index('ix_report_recurrent', recurrent))

    def update_status(self):
        # if we don't have the result key leave as is
        if self.queue_result_key and self.status not in (
                celery.states.READY_STATES):
            # TODO: inline import.  Can't import up above because of circular reference
            from wikimetrics.models.report_nodes import Report
            celery_task = Report.task.AsyncResult(self.queue_result_key)
            self.status = celery_task.status
            existing_session = Session.object_session(self)
            if not existing_session:
                existing_session = db.get_session()
                existing_session.add(self)
            existing_session.commit()

    @staticmethod
    def update_reports(report_ids, owner_id, public=None, recurrent=None):
        """
        Updates reports in bulk, making sure they belong to an owner

        TODO: an Admin should be able to modify any report but it does not look we
        have an admin check (that kind of check should be cached)

        Parameters:
            report_ids  : list of ids of ReportStore objects to update
            owner_id    : the person purporting to own these reports
            public      : update all reports' public attribute to this, default is None
            recurrent   : update all reports' recurrent attribute to this, default is None

        Returns:
            True if the number of updated records matches the number of report_ids
            False otherwise
        """
        db_session = db.get_session()
        values = {}
        if public is not None:
            values['public'] = public
        if recurrent is not None:
            values['recurrent'] = recurrent
        update = db_session.execute(
            ReportStore.__table__.update().values(**values).where(
                and_(ReportStore.id.in_(report_ids),
                     ReportStore.user_id == owner_id)))
        db_session.commit()

        if update and update.rowcount == len(report_ids):
            return True
        else:
            raise UnauthorizedReportAccessError(
                'Unauthorized access to report by {0}'.format(owner_id))

    @staticmethod
    def make_report_public(report_id, owner_id, file_manager, data):
        """
        Parameters:
            report_id   : id of ReportStore to update
            owner_id    : the User purporting to own this report
            file_manager: PublicReportFileManager for file management
            data        : String, report data to write out to filepath
        """
        ReportStore.set_public_report_state(report_id,
                                            owner_id,
                                            file_manager,
                                            public=True,
                                            data=data)

    @staticmethod
    def make_report_private(report_id, owner_id, file_manager):
        """
        Parameters:
            report_id   : id of ReportStore to update
            owner_id    : the User purporting to own this report
            file_manager: PublicReportFileManager for file management
        """
        ReportStore.set_public_report_state(report_id,
                                            owner_id,
                                            file_manager,
                                            public=False)

    @staticmethod
    def set_public_report_state(report_id,
                                owner_id,
                                file_manager,
                                public=True,
                                data=''):
        """
        Internal method that sets a report public/private status.
        If we are making a report private that
        was public before will remove files from disk.

        If a new report is made public it will save report to disk.

        Validation that user can update this report has already happened before
        we reach this method.

        The UI calls this method on a per report basis
        but updates can be done for a set of reports.

        TODO: This method should not have http level code and
            should be part of an API,
            not be on the controller.
        TODO: We should not open & close a session here, I think session should be
            open/closed at the beginning/end of the request
            using flask request scoped functions

        Parameters:
            report_id   : id of ReportStore to update
            owner_id    : the User purporting to own this report
            public      : True | False if True data must be present
            data        : String, report data to write out to filepath
            file_manager: PublicReportFileManager to manage io interactions

        Returns:
            Nothing

        Throws:
            Exception if there are issues making the report public or private

        A private report is has public=False
        """
        # NOTE: update_reports checks ownership and raises an exception if needed
        ReportStore.update_reports([report_id], owner_id, public=public)

        # good no exception
        try:
            path = file_manager.get_public_report_path(report_id)
            if public:
                file_manager.write_data(path, data)

            else:
                file_manager.remove_file(path)

        except (PublicReportIOError, SQLAlchemyError) as e:
            app.logger.exception(str(e))
            # if there was an IO error rollback prior changes
            # this issues a new query as now our session scope and
            # transaction scope are now the same
            ReportStore.update_reports([report_id],
                                       owner_id,
                                       public=not public)
            raise e

    def get_result_safely(self, result):
        if result and isinstance(result, dict) and self.result_key in result:
            return result[self.result_key]
        else:
            return {'failure': 'result not available'}

    def get_json_result(self, result):
        result = self.get_result_safely(result)
        return {'result': result, 'parameters': self.pretty_parameters()}

    def pretty_parameters(self):
        """
        TODO add tests for this method
        its name implies that it's generic but is looking for specific input/output
        """
        raw = json.loads(self.parameters)
        pretty = {}
        pretty['Cohort Size'] = raw['cohort']['size']
        pretty['Cohort'] = raw['cohort']['name']
        pretty['Metric'] = raw['metric']['name']
        pretty['Created On'] = self.created

        for k in ('csrf_token', 'name', 'label'):
            raw['metric'].pop(k, None)

        for k, v in raw['metric'].items():
            pretty['Metric_' + k] = v

        return pretty

    def __repr__(self):
        return '<ReportStore("{0}")>'.format(self.id)
Example #34
0
class TimestampMixin(object):
    created_on = db.Column(db.DateTime, server_default=func.now())
    updated_on = db.Column(db.DateTime,
                           server_default=func.now(),
                           onupdate=func.now())
Example #35
0
 def __init__(self, username, mess):
     from sqlalchemy import func
     self.time = func.now()
     self.author = username
     self.message = mess
Example #36
0
class Host(Base):
    __tablename__ = 'hosts'

    id = Column(INTEGER, primary_key=True, unique=True, autoincrement=True)
    hostname = Column(String(45), nullable=False, unique=True)
    created = Column(TIMESTAMP, nullable=False, server_default=func.now())
Example #37
0
class Poll(base):
    """The model for a Poll."""

    __tablename__ = "poll"

    id = Column(Integer, primary_key=True)
    uuid = Column(
        UUID(as_uuid=True),
        unique=True,
        nullable=False,
        server_default=text("gen_random_uuid()"),
    )

    created_at = Column(DateTime, server_default=func.now(), nullable=False)
    updated_at = Column(DateTime,
                        server_default=func.now(),
                        onupdate=func.now(),
                        nullable=False)

    # Options
    name = Column(String)
    description = Column(String)
    locale = Column(String, default="English")
    poll_type = Column(String, nullable=False)
    number_of_votes = Column(Integer, default=0)

    # Functionality
    anonymous = Column(Boolean, nullable=False)
    results_visible = Column(Boolean, nullable=False, default=True)
    due_date = Column(DateTime, nullable=True)
    next_notification = Column(DateTime, nullable=True)
    allow_new_options = Column(Boolean, nullable=False, default=False)
    allow_sharing = Column(Boolean, nullable=False, default=False)

    # Styling
    show_percentage = Column(Boolean, nullable=False, default=True)
    show_option_votes = Column(Boolean, nullable=False, default=True)
    european_date_format = Column(Boolean, nullable=False, default=False)
    permanently_summarized = Column(Boolean, nullable=False, default=False)
    compact_buttons = Column(Boolean, nullable=False, default=False)
    summarize = Column(Boolean, nullable=False, default=False)
    option_sorting = Column(String, nullable=False)
    user_sorting = Column(String, nullable=False)

    # Flags
    created = Column(Boolean, nullable=False, default=False)
    closed = Column(Boolean, nullable=False, default=False)
    # Set this, if the poll should be deleted.
    # There are two modes: DB_ONLY and WITH_MESSAGES.
    delete = Column(String)

    # Chat state variables
    expected_input = Column(String)
    in_settings = Column(Boolean, nullable=False, default=False)
    created_from_native = Column(Boolean,
                                 nullable=False,
                                 server_default="False",
                                 default=False)

    # ManyToOne
    user_id = Column(
        BigInteger,
        ForeignKey("user.id", ondelete="cascade", name="user"),
        nullable=False,
        index=True,
    )
    user = relationship("User", foreign_keys="Poll.user_id")

    # OneToMany
    options = relationship(
        "Option",
        order_by="asc(Option.index)",
        lazy="joined",
        passive_deletes="all",
    )
    votes = relationship("Vote", passive_deletes="all")
    references = relationship("Reference",
                              lazy="joined",
                              passive_deletes="all")
    notifications = relationship("Notification", passive_deletes="all")

    def __init__(self, user):
        """Create a new poll."""
        self.user = user
        self.poll_type = PollType.single_vote.name
        self.anonymous = False
        self.results_visible = True

        self.user_sorting = UserSorting.chrono.name
        self.option_sorting = OptionSorting.manual.name

    @staticmethod
    def create(user, session):
        """Create a poll from a user."""
        poll = Poll(user)
        poll.european_date_format = user.european_date_format
        poll.locale = user.locale
        user.current_poll = poll
        user.expected_input = ExpectedInput.name.name
        session.add(poll)
        session.commit()

        return poll

    def __repr__(self):
        """Print as string."""
        return f"Poll with Id: {self.id}, name: {self.name}, locale: {self.locale}"

    def should_show_result(self):
        """Determine, whether this results of this poll should be shown."""
        return self.results_visible or self.closed

    def is_doodle(self):
        return self.poll_type == PollType.doodle.name

    def is_priority(self):
        return self.poll_type == PollType.priority.name

    def has_date_option(self):
        """Check whether this poll has a date option."""
        for option in self.options:
            if option.is_date:
                return True
        return False

    def get_date_option(self, check_date):
        """Return whether an option with this date already exists."""
        for option in self.options:
            if option.is_date and option.as_date() == check_date:
                return option
        return None

    def get_formatted_due_date(self):
        """Get the formatted date."""
        if self.european_date_format:
            return self.due_date.strftime("%d.%m.%Y %H:%M UTC")

        return self.due_date.strftime("%Y-%m-%d %H:%M UTC")

    def set_due_date(self, date):
        """Set the due date and the next notification."""
        if date is None:
            self.due_date = None
            self.next_notification = None
            return

        # Calculate the next_notification date depending
        # on the given due date
        now = datetime.now()
        self.due_date = date
        if now < self.due_date - timedelta(days=7):
            self.next_notification = self.due_date - timedelta(days=7)
        elif now < self.due_date - timedelta(days=1):
            self.next_notification = self.due_date - timedelta(days=1)
        elif now < self.due_date - timedelta(hours=6):
            self.next_notification = self.due_date - timedelta(hours=6)
        else:
            self.next_notification = self.due_date
Example #38
0
class File(db.Model):

    __tablename__ = "release_files"

    @declared_attr
    def __table_args__(cls):  # noqa
        return (
            ForeignKeyConstraint(
                ["name", "version"],
                ["releases.name", "releases.version"],
                onupdate="CASCADE",
                ondelete="CASCADE",
            ),
            CheckConstraint("sha256_digest ~* '^[A-F0-9]{64}$'"),
            CheckConstraint("blake2_256_digest ~* '^[A-F0-9]{64}$'"),
            Index("release_files_name_version_idx", "name", "version"),
            Index("release_files_packagetype_idx", "packagetype"),
            Index("release_files_version_idx", "version"),
            Index(
                "release_files_single_sdist",
                "name",
                "version",
                "packagetype",
                unique=True,
                postgresql_where=(
                    (cls.packagetype == "sdist")
                    & (cls.allow_multiple_sdist == False)  # noqa
                ),
            ),
        )

    name = Column(Text)
    version = Column(Text)
    python_version = Column(Text)
    requires_python = Column(Text)
    packagetype = Column(
        Enum(
            "bdist_dmg",
            "bdist_dumb",
            "bdist_egg",
            "bdist_msi",
            "bdist_rpm",
            "bdist_wheel",
            "bdist_wininst",
            "sdist",
        )
    )
    comment_text = Column(Text)
    filename = Column(Text, unique=True)
    path = Column(Text, unique=True, nullable=False)
    size = Column(Integer)
    has_signature = Column(Boolean)
    md5_digest = Column(Text, unique=True, nullable=False)
    sha256_digest = Column(CIText, unique=True, nullable=False)
    blake2_256_digest = Column(CIText, unique=True, nullable=False)
    upload_time = Column(DateTime(timezone=False), server_default=func.now())
    # We need this column to allow us to handle the currently existing "double"
    # sdists that exist in our database. Eventually we should try to get rid
    # of all of them and then remove this column.
    allow_multiple_sdist = Column(Boolean, nullable=False, server_default=sql.false())

    # TODO: Once Legacy PyPI is gone, then we should remove this column
    #       completely as we no longer use it.
    downloads = Column(Integer, server_default=sql.text("0"))

    @hybrid_property
    def pgp_path(self):
        return self.path + ".asc"

    @pgp_path.expression
    def pgp_path(self):
        return func.concat(self.path, ".asc")

    @validates("requires_python")
    def validates_requires_python(self, *args, **kwargs):
        raise RuntimeError("Cannot set File.requires_python")
Example #39
0
def upgrade():
    op.add_column('images',
                  Column('created_at', DateTime, server_default=func.now()))
Example #40
0
class StickerSet(base):
    """The sqlite model for a sticker set."""

    __tablename__ = "sticker_set"
    __table_args__ = (
        Index(
            "sticker_set_name_gin_idx",
            "name",
            postgresql_using="gin",
            postgresql_ops={"name": "gin_trgm_ops"},
        ),
        Index(
            "sticker_title_name_gin_idx",
            "title",
            postgresql_using="gin",
            postgresql_ops={"title": "gin_trgm_ops"},
        ),
        CheckConstraint("NOT (reviewed AND NOT complete)"),
    )

    name = Column(String, primary_key=True)
    title = Column(String)
    international = Column(Boolean, default=False, nullable=False)
    deleted = Column(Boolean, default=False, nullable=False)

    # Flags
    animated = Column(Boolean, default=False, nullable=False)
    banned = Column(Boolean, default=False, nullable=False)
    nsfw = Column(Boolean, default=False, nullable=False)
    furry = Column(Boolean, default=False, nullable=False)
    deluxe = Column(Boolean, default=False, nullable=False)

    # Metadata
    created_at = Column(DateTime, server_default=func.now(), nullable=False)
    complete = Column(Boolean, default=False, nullable=False)
    completely_tagged = Column(Boolean, default=False, nullable=False)
    scan_scheduled = Column(
        Boolean,
        default=False,
        nullable=False,
    )
    reviewed = Column(Boolean, default=False, nullable=False)

    stickers = relationship("Sticker", order_by="desc(Sticker.file_unique_id)")
    reports = relationship("Report",
                           order_by="desc(Report.created_at)",
                           back_populates="sticker_set")
    tasks = relationship("Task",
                         order_by="asc(Task.created_at)",
                         back_populates="sticker_set")
    chats = relationship("Chat",
                         secondary=chat_sticker_set,
                         back_populates="sticker_sets")

    def __init__(self, name, stickers):
        """Create a new StickerSet instance."""
        self.name = name
        self.stickers = []

    def __str__(self):
        """Debug string for class."""
        return (
            f"StickerSet: {self.title} ({self.name}) \nStickers: {len(self.stickers)}"
        )

    @staticmethod
    def get_or_create(session, name, chat, user):
        """Get or create a new sticker set."""
        name = name.lower()
        sticker_set = session.query(StickerSet).get(name)
        if not sticker_set:
            # Create a task for adding a sticker.
            # This task will be processed by a job, since adding a sticker can take quite a while
            sticker_set = StickerSet(name, None)
            sticker_set.international = user.international
            task = Task(Task.SCAN_SET,
                        sticker_set=sticker_set,
                        chat=chat,
                        user=user)
            session.add(sticker_set)
            session.add(task)
            # Error handling: Retry in case somebody sent to stickers at the same time
            try:
                session.commit()
            except IntegrityError as e:
                session.rollback()
                sticker_set = session.query(StickerSet).get(name)
                if sticker_set is None:
                    raise e

        return sticker_set
Example #41
0
class Post(db.Model):
    __tablename__ = 'posts'

    id = db.Column(db.Integer, primary_key=True)
    uuid = db.Column(db.String(100), unique=True)
    path = db.Column(db.String(512), unique=True)
    project = db.Column(db.String(512), nullable=True)  # DEPRECATED
    repository = db.Column(db.String(512))
    revision = db.Column(db.Integer())

    title = db.Column(db.Text())
    tldr = db.Column(db.Text)
    keywords = db.Column(db.Text)
    thumbnail = db.Column(db.Text())

    private = db.Column(db.Integer())

    created_at = db.Column(db.DateTime, default=func.now())
    updated_at = db.Column(db.DateTime, default=func.now())

    _authors_assoc = db.relationship("PostAuthorAssoc",
                                     order_by='PostAuthorAssoc.order',
                                     collection_class=ordering_list('order'),
                                     cascade="all, delete-orphan")
    _authors = association_proxy(
        '_authors_assoc',
        'author',
        creator=lambda author: PostAuthorAssoc(author=author),
    )

    @hybrid_property
    def authors(self):
        return self._authors

    @authors.setter
    def authors(self, authors):
        """
        Sets the tags of the post to the tags given in comma delimited string
        form in tags_string
        """
        user_objs = []

        for author in authors:
            if not isinstance(author, User):
                author = author.strip()
                author = User(identifier=author)
            user_objs.append(author)

        self._authors = user_objs

    @hybrid_property
    def authors_string(self):
        return u', '.join([author.format_name for author in self.authors])

    @authors_string.expression
    def authors_string(self):
        raise NotImplementedError

    _tags = db.relationship("Tag",
                            secondary=assoc_post_tag,
                            backref='posts',
                            lazy='subquery')

    @hybrid_property
    def tags(self):
        return self._tags

    @tags.setter
    def tags(self, tags):
        """
        Sets the tags of the post to the tags given in comma delimited string
        form in tags_string
        """
        tag_objs = []

        for tag in tags:
            if not isinstance(tag, Tag):
                tag = tag.strip()
                if tag[0] == "#":
                    tag = tag[1:]
                tag = Tag(name=tag)
            tag_objs.append(tag)

        self._tags = tag_objs

    @property
    def contains_excluded_tag(self):
        excluded_tags = current_app.config.get('EXCLUDED_TAGS', [])
        return any([tag.name in excluded_tags for tag in self.tags])

    _groups = db.relationship("Group",
                              secondary=assoc_post_group,
                              backref='posts',
                              lazy='subquery')

    @hybrid_property
    def groups(self):
        return self._groups

    @groups.setter
    def groups(self, groups):
        # given a list of group_names, we add it.
        group_objs = []

        for group in groups:
            if not isinstance(group, Group):
                group = Group(name=group.strip())
            group_objs.append(group)

        # create an implicit group, group_post.id, to add
        # single users to
        group = Group(name=":post_group_" + str(self.id))

        # this created group should have the author associated with it
        # so they can add people to the post
        group.users = self.authors
        group_objs.append(group)

        self._groups = group_objs

    _status = db.Column('status', db.Integer(), default=0)

    @hybrid_property
    def status(self):
        return current_repo.PostStatus(self._status or 0)

    @status.expression
    def status(self):
        return func.coalesce(self._status, 0)

    @status.setter
    def status(self, status):
        if status is None:
            self._status = None
        else:
            assert isinstance(
                status, KnowledgeRepository.PostStatus
            ), "Status must be an instance of KnowledgeRepository.PostStatus.Status or None"
            self._status = status.value

    @hybrid_property
    def is_published(self):
        return self.status == current_repo.PostStatus.PUBLISHED

    @is_published.expression
    def is_published(self):
        return func.coalesce(self._status,
                             0) == current_repo.PostStatus.PUBLISHED.value

    _views = db.relationship(
        "PageView",
        lazy='dynamic',
        primaryjoin="and_(foreign(PageView.object_id)==Post.id, "
        "PageView.object_type=='post',"
        "PageView.object_action=='view')")

    @hybrid_property
    def views(self):
        return self._views.all()

    @hybrid_property
    def view_count(self):
        return self._views.count()

    @view_count.expression
    def view_count(self):
        return (select([func.count(
            PageView.id)]).where(PageView.object_id == self.id).where(
                PageView.object_type == 'post').label("view_count"))

    @hybrid_property
    def view_user_count(self):
        return (db.session.query(func.count(distinct(
            PageView.user_id))).filter(PageView.object_id == self.id).filter(
                PageView.object_type == 'post').scalar())

    @view_user_count.expression
    def view_user_count(self):
        return (select([func.count(distinct(
            PageView.user_id))]).where(PageView.object_id == self.id).where(
                PageView.object_type == 'post').label("view_user_count"))

    _votes = db.relationship(
        "Vote",
        lazy='dynamic',
        primaryjoin="and_(foreign(Vote.object_id)==Post.id, "
        "Vote.object_type=='post')")

    @hybrid_property
    def votes(self):
        return self._votes.all()

    @hybrid_property
    def vote_count(self):
        """ Given the path of a post, return the total likes """
        return self._votes.count()

    @vote_count.expression
    def vote_count(self):
        return (select([func.count(Vote.id)
                        ]).where(Vote.object_id == self.id).where(
                            Vote.object_type == 'post').label("vote_count"))

    def vote_counted_for_user(self, user_id):
        return (db_session.query(Vote).filter(
            and_(Vote.object_id == self.id, Vote.object_type == 'post',
                 Vote.user_id == user_id)).first()) is not None

    _comments = db.relationship(
        "Comment",
        lazy="dynamic",
        primaryjoin="and_(foreign(Comment.post_id)==Post.id, "
        "Comment.type=='post')")

    @hybrid_property
    def comments(self):
        return self._comments.all()

    @hybrid_property
    def comment_count(self):
        """ Given the path of the a post, return the total comments """
        return self._comments.count()

    @comment_count.expression
    def comment_count(self):
        return (select([func.count(
            Comment.id)]).where(Comment.post_id == self.id).where(
                Comment.object_type == 'post').label("comments_count"))

    @property
    def kp(self):
        return current_repo.post(self.path)

    @property
    def text(self):
        return self.kp.read()

    def update_metadata_from_kp(self, kp):
        """
        :param kp: Maps fields of the model to values
        :type kp: KnowledgePost
        :param kp: Maps fields of the model to values
        :type kr: KnowledgeRepository
        :return: None
        :rtype: None
        """
        headers = kp.headers

        self.uuid = kp.uuid
        self.path = kp.path
        self.project = headers.get('project')
        self.repository = kp.repository_uri
        self.revision = kp.revision
        self.title = headers['title']
        self.tldr = headers['tldr']
        self.authors = headers.get('authors', [])
        self.tags = headers.get('tags', [])
        self.keywords = get_keywords(self)
        self.thumbnail = kp.thumbnail_uri

        self.created_at = headers['created_at']
        self.updated_at = headers['updated_at']
        if self.created_at > self.updated_at:
            self.updated_at = self.created_at

        self.status = kp.status

        self.private = 0
        # we do this check so that no header (None) and False are treated the same
        if headers.get('private', ''):
            self.private = 1
            self.groups = headers.get('allowed_groups', [])
Example #42
0
class User(db.Model, UserMixin):
    __tablename__ = 'users'

    id = db.Column(db.Integer, primary_key=True)
    created_at = db.Column(db.DateTime, default=func.now())

    identifier = db.Column(
        db.String(500))  # Unique identifier across all login methods

    username = db.Column(
        db.String(500))  # Username used to log in (may differ from identifier)
    password = db.Column(db.String(500))  # Password for local logins

    name = db.Column(db.String(500))  # Name as determined by auth method
    preferred_name = db.Column(
        db.String(500))  # Name as determined by user preferences

    email = db.Column(db.String(500))  # Email address
    avatar_uri = db.Column(db.Text())  # Either external url or data uri
    active = db.Column(db.Boolean, default=True)

    last_login_at = db.Column(db.DateTime)  # Date of last login

    _posts_assoc = db.relationship("PostAuthorAssoc")
    posts = association_proxy(
        '_posts_assoc', 'post')  # This property should not directly modified

    # Method overrides for the UserMixin class for flask_login
    @property
    def is_active(self):
        return self.active

    @property
    def is_authenticated(self):
        return True

    @property
    def is_anonymous(self):
        return False

    def get_id(self):
        return self.identifier

    can_logout = True

    # Other useful methods
    @property
    def format_name(self):
        return self.preferred_name or self.name or self.identifier

    @property
    def subscriptions(self):  # TODO: make attribute style naming
        """Get the subscriptions associated with a user.

        Return an array of strings of tag_names
        """
        subscriptions = (db.session.query(Subscription).filter(
            Subscription.user_id == self.id).all())
        out_subscriptions = []
        for s in subscriptions:
            if s.object_type == 'tag':
                tag_obj = (db.session.query(Tag).filter(
                    Tag.id == s.object_id).first())
                if tag_obj:
                    full_name = tag_obj.name
                    out_subscriptions.append(full_name)
                else:
                    db.session.delete(s)
        return out_subscriptions

    @property
    def liked_posts(self):
        """
        :return: Posts that a user has liked
        :rtype: list
        """
        votes = (db.session.query(Vote).filter(Vote.user_id == self.id).all())
        post_ids = [vote.object_id for vote in votes]
        if len(post_ids) == 0:
            return []
        excluded_tags = current_app.config.get('EXCLUDED_TAGS', [])
        posts = (db.session.query(Post).filter(Post.id.in_(post_ids)).filter(
            ~Post.tags.any(Tag.name.in_(excluded_tags))).all())
        return posts
Example #43
0
class ForumThread(db.Model, SinglePKMixin):
    __tablename__ = 'forums_threads'
    __serializer__ = ForumThreadSerializer
    __cache_key__ = 'forums_threads_{id}'
    __cache_key_post_count__ = 'forums_threads_{id}_post_count'
    __cache_key_of_forum__ = 'forums_threads_forums_{id}'
    __cache_key_last_post__ = 'forums_threads_{id}_last_post'
    __permission_key__ = 'forumaccess_thread_{id}'
    __deletion_attr__ = 'deleted'

    _posts: List['ForumPost']

    id: int = db.Column(db.Integer, primary_key=True)
    topic: str = db.Column(db.String(150), nullable=False)
    forum_id = db.Column(
        db.Integer, db.ForeignKey('forums.id'), nullable=False, index=True
    )  # type: int
    creator_id: int = db.Column(
        db.Integer, db.ForeignKey('users.id'), nullable=False, index=True
    )
    created_time: datetime = db.Column(
        db.DateTime(timezone=True), nullable=False, server_default=func.now()
    )
    locked: bool = db.Column(db.Boolean, nullable=False, server_default='f')
    sticky: bool = db.Column(db.Boolean, nullable=False, server_default='f')
    deleted: bool = db.Column(
        db.Boolean, nullable=False, server_default='f', index=True
    )

    @declared_attr
    def __table_args__(cls):
        return (db.Index('ix_forums_threads_topic', func.lower(cls.topic)),)

    @classmethod
    def from_forum(
        cls,
        forum_id: int,
        page: int = 1,
        limit: Optional[int] = 50,
        include_dead: bool = False,
    ) -> List['ForumThread']:
        return cls.get_many(
            key=cls.__cache_key_of_forum__.format(id=forum_id),
            filter=cls.forum_id == forum_id,
            order=cls.last_updated.desc(),
            page=page,
            limit=limit,
            include_dead=include_dead,
        )

    @classmethod
    def new(
        cls, topic: str, forum_id: int, creator_id: int, post_contents: str
    ) -> Optional['ForumThread']:
        Forum.is_valid(forum_id, error=True)
        User.is_valid(creator_id, error=True)
        cache.delete(cls.__cache_key_of_forum__.format(id=forum_id))
        thread = super()._new(
            topic=topic, forum_id=forum_id, creator_id=creator_id
        )
        subscribe_users_to_new_thread(thread)
        ForumPost.new(
            thread_id=thread.id, user_id=creator_id, contents=post_contents
        )
        return thread

    @classmethod
    def get_ids_from_forum(cls, id):
        return cls.get_pks_of_many(
            key=cls.__cache_key_of_forum__.format(id=id),
            filter=cls.forum_id == id,
            order=cls.last_updated.desc(),
        )

    @classmethod
    def from_subscribed_user(cls, user_id: int) -> List['ForumThread']:
        return cls.get_many(pks=cls.subscribed_ids(user_id))

    @classmethod
    def subscribed_ids(cls, user_id: int) -> List[Union[str, int]]:
        return cls.get_pks_of_many(
            key=ForumThreadSubscription.__cache_key_of_user__.format(
                user_id=user_id
            ),
            filter=cls.id.in_(
                db.session.query(
                    ForumThreadSubscription.thread_id
                ).filter(  # type: ignore
                    ForumThreadSubscription.user_id == user_id
                )
            ),
            order=ForumThread.id.asc(),
        )  # type: ignore

    @hybrid_property
    def last_updated(cls) -> BinaryExpression:
        return (
            select([func.max(ForumPost.time)])
            .where(ForumPost.thread_id == cls.id)
            .as_scalar()
        )

    @cached_property
    def last_post(self) -> Optional['ForumPost']:
        return ForumPost.from_query(
            key=self.__cache_key_last_post__.format(id=self.id),
            filter=and_(
                ForumPost.thread_id == self.id, ForumPost.deleted == 'f'
            ),
            order=ForumPost.id.desc(),
        )  # type: ignore

    @cached_property
    def last_viewed_post(self) -> Optional['ForumPost']:
        return (
            ForumLastViewedPost.post_from_attrs(
                thread_id=self.id, user_id=flask.g.user.id
            )
            if flask.g.user
            else None
        )

    @cached_property
    def forum(self) -> 'Forum':
        return Forum.from_pk(self.forum_id)

    @cached_property
    def creator(self) -> User:
        return User.from_pk(self.creator_id)

    @cached_property
    def poll(self) -> 'ForumPoll':
        return ForumPoll.from_thread(self.id)

    @cached_property
    def post_count(self) -> int:
        return self.count(
            key=self.__cache_key_post_count__.format(id=self.id),
            attribute=ForumPost.id,
            filter=and_(
                ForumPost.thread_id == self.id, ForumPost.deleted == 'f'
            ),
        )

    @cached_property
    def thread_notes(self) -> List['ForumThreadNote']:
        return ForumThreadNote.from_thread(self.id)

    @cached_property
    def subscribed(self) -> bool:
        return (
            self.id in set(self.subscribed_ids(flask.g.user.id))
            if flask.g.user
            else False
        )

    @property
    def posts(self) -> List['ForumPost']:
        if not hasattr(self, '_posts'):
            self._posts = ForumPost.from_thread(self.id, 1, limit=50)
        return self._posts

    def set_posts(
        self, page: int = 1, limit: int = 50, include_dead: bool = False
    ) -> None:
        self._posts = ForumPost.from_thread(self.id, page, limit, include_dead)

    def can_access(self, permission: str = None, error: bool = False) -> bool:
        """Determines whether or not the user has the permissions to access the thread."""
        if flask.g.user is None:  # pragma: no cover
            if error:
                raise _403Exception
            return False

        # Explicit thread access
        permission_key = self.__permission_key__.format(id=self.id)
        if flask.g.user.has_permission(permission_key) or (
            permission is not None and flask.g.user.has_permission(permission)
        ):
            return True

        # Access to forum gives access to all threads by default.
        # If user has been ungranted the thread, they cannot view it regardless.
        ungranted_threads = [
            p
            for p, g in UserPermission.from_user(
                flask.g.user.id, prefix='forumaccess_thread'
            ).items()
            if g is False
        ]
        if permission_key not in ungranted_threads and (
            flask.g.user.has_permission(
                Forum.__permission_key__.format(id=self.forum_id)
            )
        ):
            return True
        if error:
            raise _403Exception
        return False
Example #44
0
    class TextRef(Base, IndraDBTable):
        __tablename__ = 'text_ref'
        _ref_cols = ['pmid', 'pmcid', 'doi', 'pii', 'url', 'manuscript_id']
        _always_disp = ['id', 'pmid', 'pmcid']
        _indices = [
            StringIndex('text_ref_pmid_idx', 'pmid'),
            StringIndex('text_ref_pmcid_idx', 'pmcid'),
            BtreeIndex('text_ref_pmid_num_idx', 'pmid_num'),
            BtreeIndex('text_ref_pmcid_num_idx', 'pmcid_num'),
            BtreeIndex('text_ref_doi_ns_idx', 'doi_ns'),
            BtreeIndex('text_ref_doi_id_idx', 'doi_id'),
            StringIndex('text_ref_doi_idx', 'doi')
        ]

        id = Column(Integer, primary_key=True)
        pmid = Column(String(20))
        pmid_num = Column(Integer)
        pmcid = Column(String(20))
        pmcid_num = Column(Integer)
        pmcid_version = Column(Integer)
        doi = Column(String(100))
        doi_ns = Column(Integer)
        doi_id = Column(String)
        pii = Column(String(250))
        url = Column(String, unique=True)
        manuscript_id = Column(String(100), unique=True)
        create_date = Column(DateTime, default=func.now())
        last_updated = Column(DateTime, onupdate=func.now())

        __table_args__ = (UniqueConstraint('pmid', 'doi', name='pmid-doi'),
                          UniqueConstraint('pmid', 'pmcid', name='pmid-pmcid'),
                          UniqueConstraint('pmcid', 'doi', name='pmcid-doi'))

        def __repr__(self):
            terms = [f'id={self.id}']
            for col in ['pmid', 'pmcid', 'doi', 'pii', 'url', 'manuscript_id']:
                if getattr(self, col) is not None:
                    terms.append(f'{col}={getattr(self, col)}')
                if len(terms) > 2:
                    break
            return f'{self.__class__.__name__}({", ".join(terms)})'

        @classmethod
        def new(cls,
                pmid=None,
                pmcid=None,
                doi=None,
                pii=None,
                url=None,
                manuscript_id=None):
            pmid, pmid_num = cls.process_pmid(pmid)
            pmcid, pmcid_num, pmcid_version = cls.process_pmcid(pmcid)
            doi, doi_ns, doi_id = cls.process_doi(doi)
            return cls(pmid=pmid,
                       pmid_num=pmid_num,
                       pmcid=pmcid,
                       pmcid_num=pmcid_num,
                       pmcid_version=pmcid_version,
                       doi=doi,
                       doi_ns=doi_ns,
                       doi_id=doi_id,
                       pii=pii,
                       url=url,
                       manuscript_id=manuscript_id)

        def update(self, **updates):
            for id_type, id_val in updates.items():
                if id_type == 'pmid':
                    self.pmid, self.pmid_num = self.process_pmid(id_val)
                elif id_type == 'pmcid':
                    self.pmcid, self.pmcid_num, self.pmcid_version = \
                        self.process_pmcid(id_val)
                elif id_type == 'doi':
                    self.doi, self.doi_ns, self.doi_id = \
                        self.process_doi(id_val)
                else:
                    setattr(self, id_type, id_val)
            return

        @staticmethod
        def process_pmid(pmid):
            if not pmid:
                return None, None

            if not pmid.isdigit():
                return pmid, None

            return pmid, int(pmid)

        @staticmethod
        def process_pmcid(pmcid):
            if not pmcid:
                return None, None, None

            if not pmcid.startswith('PMC'):
                return pmcid, None, None

            if '.' in pmcid:
                pmcid, version_number_str = pmcid.split('.')
                if version_number_str.isdigit():
                    version_number = int(version_number_str)
                else:
                    version_number = None
            else:
                version_number = None

            if not pmcid[3:].isdigit():
                return pmcid, None, version_number

            return pmcid, int(pmcid[3:]), version_number

        @staticmethod
        def process_doi(doi):
            # Check for invalid DOIs
            if not doi:
                return None, None, None

            # Regularize case.
            doi = doi.upper()

            if not doi.startswith('10.'):
                return doi, None, None

            # Split up the parts of the DOI
            parts = doi[3:].split('/')
            if len(parts) < 2:
                return doi, None, None

            # Check the namespace number, make it an integer.
            namespace_str = parts[0]
            if not namespace_str.isdigit():
                return doi, None, None
            namespace = int(namespace_str)

            # Join the res of the parts together.
            group_id = '/'.join(parts[1:])

            return doi, namespace, group_id

        @classmethod
        def pmid_in(cls, pmid_list, filter_ids=False):
            """Get sqlalchemy clauses for a list of pmids."""
            pmid_num_set = set()
            for pmid in pmid_list:
                _, pmid_num = cls.process_pmid(pmid)
                if pmid_num is None:
                    if filter_ids:
                        logger.warning('"%s" is not a valid pmid. Skipping.' %
                                       pmid)
                        continue
                    else:
                        ValueError('"%s" is not a valid pmid.' % pmid)
                pmid_num_set.add(pmid_num)
            return cls.pmid_num.in_(pmid_num_set)

        @classmethod
        def pmcid_in(cls, pmcid_list, filter_ids=False):
            """Get the sqlalchemy clauses for a list of pmcids."""
            pmcid_num_set = set()
            for pmcid in pmcid_list:
                _, pmcid_num, _ = cls.process_pmcid(pmcid)
                if not pmcid_num:
                    if filter_ids:
                        logger.warning('"%s" does not look like a valid '
                                       'pmcid. Skipping.' % pmcid)
                        continue
                    else:
                        raise ValueError('"%s" is not a valid pmcid.' % pmcid)
                else:
                    pmcid_num_set.add(pmcid_num)

            return cls.pmcid_num.in_(pmcid_num_set)

        @classmethod
        def doi_in(cls, doi_list, filter_ids=False):
            """Get clause for looking up a list of dois."""
            doi_tuple_set = set()
            for doi in doi_list:
                doi, doi_ns, doi_id = cls.process_doi(doi)
                if not doi_ns:
                    if filter_ids:
                        logger.warning('"%s" does not look like a normal doi. '
                                       'Skipping.' % doi)
                        continue
                    else:
                        raise ValueError('"%s" is not a valid doi.' % doi)
                else:
                    doi_tuple_set.add((doi_ns, doi_id))

            return tuple_(cls.doi_ns, cls.doi_id).in_(doi_tuple_set)

        def get_ref_dict(self):
            ref_dict = {}
            for ref in self._ref_cols:
                val = getattr(self, ref, None)
                if val:
                    ref_dict[ref.upper()] = val
            ref_dict['TRID'] = self.id
            return ref_dict
Example #45
0
class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, Sequence('user_id_seq'), primary_key=True)
    email = Column(String(50), unique=True)
    email_confirmed = Column(Boolean, default=False)
    email_token = Column(String(64), default=lambda: secrets.token_urlsafe(64))
    created_at = Column(DateTime, default=func.now())
    subscriptions = relationship("Subscription", back_populates="user")

    def __repr__(self):
        return "<User(email='%s', confirmed='%s')>" % (
                                self.email, str(self.email_confirmed))

    @classmethod
    def find_by_email(cls, session, email):
        return session.query(User).filter(User.email == email).one_or_none()

    def try_confirm(self, session, token):
        tokens_match = secrets.compare_digest(self.email_token, token)

        if not self.email_confirmed and tokens_match:
            self.email_confirmed = True
            session.add(self)
            session.commit()

        return tokens_match

    def get_mail_template(self, name):
        flask_locale = flask_get_locale()
        if flask_locale:
            language = flask_locale.language
        else:
            language = 'en'

        t = gettext.translation('messages', localedir='translations', languages=[language])

        if name == 'confirm':
            return {"subject": t.gettext("mail:confirm:subject"),
                    "message": t.gettext("mail:confirm:message")}
        elif name == 'alarm':
            return {"subject": t.gettext("mail:alarm:subject"),
                    "message": t.gettext("mail:alarm:message")}
        elif name == 'resolved':
            return {"subject": t.gettext("mail:resolved:subject"),
                    "message": t.gettext("mail:resolved:message")}
        else:
            raise Exception(f'No mail template named {name} found!')

    def send_confirm_mail(self, url):
        url = url + "?email=" + self.email + "&token=" + self.email_token
        mail_template = self.get_mail_template("confirm")

        self.send_mail(mail_template, url=url)

    def send_mail(self, mail_template, in_reply_to = None, **kwargs):
        msgid = make_msgid()

        subject = mail_template['subject'].format(**kwargs)
        message = mail_template['message'].format(**kwargs)

        msg = MIMEMultipart('alternative')
        msg['Subject'] = str(Header(subject, 'utf-8'))
        msg['From'] = str(Header(SMTP_FROM, 'utf-8'))
        msg['To'] = str(Header(self.email, 'utf-8'))
        msg['Message-ID'] = msgid
        msg['Reply-To'] = SMTP_REPLY_TO_EMAIL
        msg['Date'] = datetime.datetime.now(pytz.utc).strftime("%a, %e %b %Y %T %z")

        if in_reply_to:
            msg['In-Reply-To'] = in_reply_to
            msg['References'] = in_reply_to

        # add message
        charset = Charset('utf-8')
        # QP = quoted printable; this is better readable instead of base64, when
        # the mail is read in plaintext!
        charset.body_encoding = QP
        message_part = MIMEText(message.encode('utf-8'), 'plain', charset)
        msg.attach(message_part)

        if DEBUG:
            with open("/tmp/keepitup_mails.log", "a") as f:
                f.write(msg.as_string() + "\n")
        else:
            with smtplib.SMTP(SMTP_HOST, SMTP_PORT) as server:
                server.ehlo()
                if SMTP_USE_STARTTLS:
                    context = ssl.create_default_context()
                    server.starttls(context=context)

                server.sendmail(SMTP_FROM, self.email, msg.as_string())

        return msgid

    @property
    def subscribed_nodes(self):
        return [subscription.node for subscription in self.subscriptions]
Example #46
0
class Poll(base):
    """The model for a Poll."""

    __tablename__ = 'poll'

    id = Column(Integer, primary_key=True)
    uuid = Column(UUID(as_uuid=True),
                  unique=True,
                  nullable=False,
                  server_default=text('gen_random_uuid()'))

    created_at = Column(DateTime, server_default=func.now(), nullable=False)
    updated_at = Column(DateTime,
                        server_default=func.now(),
                        onupdate=func.now(),
                        nullable=False)

    # Options
    name = Column(String)
    description = Column(String)
    locale = Column(String, server_default='english')
    poll_type = Column(String, nullable=False)
    anonymous = Column(Boolean, nullable=False)
    number_of_votes = Column(Integer)
    allow_new_options = Column(Boolean, nullable=False, default=False)
    option_sorting = Column(String, nullable=False)
    user_sorting = Column(String, nullable=False)
    results_visible = Column(Boolean, nullable=False, default=True)
    show_percentage = Column(Boolean, nullable=False, default=True)
    european_date_format = Column(Boolean, nullable=False, default=False)

    # Flags
    created = Column(Boolean, nullable=False, default=False)
    closed = Column(Boolean, nullable=False, default=False)
    due_date = Column(DateTime, nullable=True)
    next_notification = Column(DateTime, nullable=True)

    # Chat state variables
    expected_input = Column(String)
    in_settings = Column(Boolean, nullable=False, default=False)
    current_date = Column(Date, server_default=func.now(), nullable=False)

    # OneToOne
    user_id = Column(BigInteger,
                     ForeignKey('user.id', ondelete='cascade', name='user'),
                     nullable=False,
                     index=True)
    user = relationship('User', foreign_keys='Poll.user_id')

    # OneToMany
    options = relationship('PollOption',
                           order_by='asc(PollOption.id)',
                           lazy='joined',
                           passive_deletes='all')
    votes = relationship('Vote', passive_deletes=True)
    references = relationship('Reference',
                              lazy='joined',
                              passive_deletes='all')
    notifications = relationship('Notification', passive_deletes='all')

    def __init__(self, user):
        """Create a new poll."""
        self.user = user
        self.poll_type = PollType.single_vote.name
        self.anonymous = False
        self.results_visible = True

        self.user_sorting = UserSorting.user_chrono.name
        self.option_sorting = OptionSorting.option_chrono.name

    def __repr__(self):
        """Print as string."""
        return f'Poll with Id: {self.id}, name: {self.name}'

    def should_show_result(self):
        """Determine, whether this results of this poll should be shown."""
        return self.results_visible or self.closed

    def has_date_option(self):
        """Check whether this poll has a date option."""
        for option in self.options:
            if option.is_date:
                return True
        return False

    def get_formatted_due_date(self):
        """Get the formatted date."""
        if self.european_date_format:
            return self.due_date.strftime('%d.%m.%Y %H:%M UTC')

        return self.due_date.strftime('%Y-%m-%d %H:%M UTC')

    def set_due_date(self, date):
        """Set the due date and the next notification."""
        now = datetime.now()
        self.due_date = date
        if now < self.due_date - timedelta(days=7):
            self.next_notification = self.due_date - timedelta(days=7)
        elif now < self.due_date - timedelta(days=1):
            self.next_notification = self.due_date - timedelta(days=1)
        elif now < self.due_date - timedelta(hours=6):
            self.next_notification = self.due_date - timedelta(hours=6)
        else:
            self.next_notification = self.due_date

    def clone(self, session):
        """Create a clone from the current poll."""
        poll = Poll(self.user)
        poll.created = True
        session.add(poll)

        poll.name = self.name
        poll.description = self.description
        poll.poll_type = self.poll_type
        poll.anonymous = self.anonymous
        poll.number_of_votes = self.number_of_votes
        poll.allow_new_options = self.allow_new_options
        poll.option_sorting = self.option_sorting
        poll.user_sorting = self.user_sorting
        poll.results_visible = self.results_visible
        poll.show_percentage = self.show_percentage

        from pollbot.models import PollOption
        for option in self.options:
            new_option = PollOption(poll, option.name)
            session.add(new_option)

        return poll
Example #47
0
class UserProfile(meta.Base, BaseMixin, BaseDictMixin):
    """
    Profile information is added to the 'users' table.
    """
    PALETTE_DEFAULT_NAME = 'palette'
    PALETTE_DEFAULT_FRIENDLY_NAME = 'Palette Server Admin'
    PALETTE_DEFAULT_PASSWORD = '******'

    __tablename__ = 'users'
    userid = Column(BigInteger, unique=True, nullable=False, \
                        autoincrement=True, primary_key=True)
    envid = Column(BigInteger, ForeignKey("environment.envid"), nullable=False)
    active = Column(Boolean, default=True)
    name = Column(String, unique=True, nullable=False)
    friendly_name = Column(String)
    email = Column(String)
    email_level = Column(Integer, default=1)
    phone = Column(String)
    hashed_password = Column(String)
    salt = Column(String)
    roleid = Column(BigInteger, ForeignKey("roles.roleid"), default=0)
    system_user_id = Column(Integer, unique=True)
    login_at = Column(DateTime)
    licensing_role_id = Column(Integer)
    user_admin_level = Column(Integer)
    system_admin_level = Column(Integer)
    publisher = Column(Boolean)
    system_created_at = Column(DateTime)
    timestamp = Column(DateTime)  # last active time (in Palette)
    modification_time = Column(DateTime,
                               server_default=func.now(),
                               onupdate=func.current_timestamp())

    role = relationship("Role")

    def __unicode__(self):
        if self.friendly_name:
            return unicode(self.friendly_name)
        return unicode(self.name)

    def __str__(self):
        return unicode(self).encode('utf-8')

    def display_name(self):
        return unicode(self)

    def display_role(self):
        # pylint: disable=no-member
        if self.publisher:
            if self.roleid == Role.NO_ADMIN:
                return u'Publisher'
            return u'Publisher & ' + self.role.name
        else:
            return self.role.name

    @classmethod
    def get(cls, envid, userid):
        filters = {'envid': envid, 'userid': userid}
        return cls.get_unique_by_keys(filters, default=None)

    @classmethod
    def get_by_system_user_id(cls, envid, system_user_id):
        filters = {'envid': envid, 'system_user_id': system_user_id}
        return cls.get_unique_by_keys(filters, default=None)

    @classmethod
    def get_by_name(cls, envid, name):
        try:
            query = meta.Session.query(UserProfile).\
                    filter(UserProfile.envid == envid).\
                    filter(func.lower(UserProfile.name) == name.lower())
            entry = query.one()
        except NoResultFound:
            entry = None
        return entry

    @classmethod
    def verify(cls, envid, name, password):
        entry = cls.get_by_name(envid, name)
        if not entry:
            return False
        return entry.hashed_password == tableau_hash(password, entry.salt)

    defaults = [{
        'userid': 0,
        'envid': 1,
        'name': PALETTE_DEFAULT_NAME,
        'friendly_name': PALETTE_DEFAULT_FRIENDLY_NAME,
        'email_level': 1,
        'email': None,
        'salt': '',
        'roleid': 3,  # SUPER_ADMIN
        'system_user_id': 0
    }]

    @classmethod
    def user_count(cls, envid):
        return meta.Session.query(UserProfile).\
               filter(UserProfile.envid == envid).\
               count()

    @classmethod
    def update_timestamp(cls, entry):
        entry.timestamp = datetime.datetime.utcnow()
def upgrade():
    conn = op.get_bind()
    inspector = Inspector.from_engine(conn)
    tables = inspector.get_table_names()

    if 'connection' not in tables:
        op.create_table(
            'connection',
            sa.Column('id', sa.Integer(), nullable=False),
            sa.Column('conn_id', sa.String(length=250), nullable=True),
            sa.Column('conn_type', sa.String(length=500), nullable=True),
            sa.Column('host', sa.String(length=500), nullable=True),
            sa.Column('schema', sa.String(length=500), nullable=True),
            sa.Column('login', sa.String(length=500), nullable=True),
            sa.Column('password', sa.String(length=500), nullable=True),
            sa.Column('port', sa.Integer(), nullable=True),
            sa.Column('extra', sa.String(length=5000), nullable=True),
            sa.PrimaryKeyConstraint('id')
        )
    if 'dag' not in tables:
        op.create_table(
            'dag',
            sa.Column('dag_id', sa.String(length=250), nullable=False),
            sa.Column('is_paused', sa.Boolean(), nullable=True),
            sa.Column('is_subdag', sa.Boolean(), nullable=True),
            sa.Column('is_active', sa.Boolean(), nullable=True),
            sa.Column('last_scheduler_run', sa.DateTime(), nullable=True),
            sa.Column('last_pickled', sa.DateTime(), nullable=True),
            sa.Column('last_expired', sa.DateTime(), nullable=True),
            sa.Column('scheduler_lock', sa.Boolean(), nullable=True),
            sa.Column('pickle_id', sa.Integer(), nullable=True),
            sa.Column('fileloc', sa.String(length=2000), nullable=True),
            sa.Column('owners', sa.String(length=2000), nullable=True),
            sa.PrimaryKeyConstraint('dag_id')
        )
    if 'dag_pickle' not in tables:
        op.create_table(
            'dag_pickle',
            sa.Column('id', sa.Integer(), nullable=False),
            sa.Column('pickle', sa.PickleType(), nullable=True),
            sa.Column('created_dttm', sa.DateTime(), nullable=True),
            sa.Column('pickle_hash', sa.BigInteger(), nullable=True),
            sa.PrimaryKeyConstraint('id')
        )
    if 'import_error' not in tables:
        op.create_table(
            'import_error',
            sa.Column('id', sa.Integer(), nullable=False),
            sa.Column('timestamp', sa.DateTime(), nullable=True),
            sa.Column('filename', sa.String(length=1024), nullable=True),
            sa.Column('stacktrace', sa.Text(), nullable=True),
            sa.PrimaryKeyConstraint('id')
        )
    if 'job' not in tables:
        op.create_table(
            'job',
            sa.Column('id', sa.Integer(), nullable=False),
            sa.Column('dag_id', sa.String(length=250), nullable=True),
            sa.Column('state', sa.String(length=20), nullable=True),
            sa.Column('job_type', sa.String(length=30), nullable=True),
            sa.Column('start_date', sa.DateTime(), nullable=True),
            sa.Column('end_date', sa.DateTime(), nullable=True),
            sa.Column('latest_heartbeat', sa.DateTime(), nullable=True),
            sa.Column('executor_class', sa.String(length=500), nullable=True),
            sa.Column('hostname', sa.String(length=500), nullable=True),
            sa.Column('unixname', sa.String(length=1000), nullable=True),
            sa.PrimaryKeyConstraint('id')
        )
        op.create_index(
            'job_type_heart',
            'job',
            ['job_type', 'latest_heartbeat'],
            unique=False
        )
    if 'known_event_type' not in tables:
        op.create_table(
            'known_event_type',
            sa.Column('id', sa.Integer(), nullable=False),
            sa.Column('know_event_type', sa.String(length=200), nullable=True),
            sa.PrimaryKeyConstraint('id')
        )
    if 'log' not in tables:
        op.create_table(
            'log',
            sa.Column('id', sa.Integer(), nullable=False),
            sa.Column('dttm', sa.DateTime(), nullable=True),
            sa.Column('dag_id', sa.String(length=250), nullable=True),
            sa.Column('task_id', sa.String(length=250), nullable=True),
            sa.Column('event', sa.String(length=30), nullable=True),
            sa.Column('execution_date', sa.DateTime(), nullable=True),
            sa.Column('owner', sa.String(length=500), nullable=True),
            sa.PrimaryKeyConstraint('id')
        )
    if 'sla_miss' not in tables:
        op.create_table(
            'sla_miss',
            sa.Column('task_id', sa.String(length=250), nullable=False),
            sa.Column('dag_id', sa.String(length=250), nullable=False),
            sa.Column('execution_date', sa.DateTime(), nullable=False),
            sa.Column('email_sent', sa.Boolean(), nullable=True),
            sa.Column('timestamp', sa.DateTime(), nullable=True),
            sa.Column('description', sa.Text(), nullable=True),
            sa.PrimaryKeyConstraint('task_id', 'dag_id', 'execution_date')
        )
    if 'slot_pool' not in tables:
        op.create_table(
            'slot_pool',
            sa.Column('id', sa.Integer(), nullable=False),
            sa.Column('pool', sa.String(length=50), nullable=True),
            sa.Column('slots', sa.Integer(), nullable=True),
            sa.Column('description', sa.Text(), nullable=True),
            sa.PrimaryKeyConstraint('id'),
            sa.UniqueConstraint('pool')
        )
    if 'task_instance' not in tables:
        op.create_table(
            'task_instance',
            sa.Column('task_id', sa.String(length=250), nullable=False),
            sa.Column('dag_id', sa.String(length=250), nullable=False),
            sa.Column('execution_date', sa.DateTime(), nullable=False),
            sa.Column('start_date', sa.DateTime(), nullable=True),
            sa.Column('end_date', sa.DateTime(), nullable=True),
            sa.Column('duration', sa.Integer(), nullable=True),
            sa.Column('state', sa.String(length=20), nullable=True),
            sa.Column('try_number', sa.Integer(), nullable=True),
            sa.Column('hostname', sa.String(length=1000), nullable=True),
            sa.Column('unixname', sa.String(length=1000), nullable=True),
            sa.Column('job_id', sa.Integer(), nullable=True),
            sa.Column('pool', sa.String(length=50), nullable=True),
            sa.Column('queue', sa.String(length=50), nullable=True),
            sa.Column('priority_weight', sa.Integer(), nullable=True),
            sa.PrimaryKeyConstraint('task_id', 'dag_id', 'execution_date')
        )
        op.create_index(
            'ti_dag_state',
            'task_instance',
            ['dag_id', 'state'],
            unique=False
        )
        op.create_index(
            'ti_pool',
            'task_instance',
            ['pool', 'state', 'priority_weight'],
            unique=False
        )
        op.create_index(
            'ti_state_lkp',
            'task_instance',
            ['dag_id', 'task_id', 'execution_date', 'state'],
            unique=False
        )

    if 'user' not in tables:
        op.create_table(
            'user',
            sa.Column('id', sa.Integer(), nullable=False),
            sa.Column('username', sa.String(length=250), nullable=True),
            sa.Column('email', sa.String(length=500), nullable=True),
            sa.PrimaryKeyConstraint('id'),
            sa.UniqueConstraint('username')
        )
    if 'variable' not in tables:
        op.create_table(
            'variable',
            sa.Column('id', sa.Integer(), nullable=False),
            sa.Column('key', sa.String(length=250), nullable=True),
            sa.Column('val', sa.Text(), nullable=True),
            sa.PrimaryKeyConstraint('id'),
            sa.UniqueConstraint('key')
        )
    if 'chart' not in tables:
        op.create_table(
            'chart',
            sa.Column('id', sa.Integer(), nullable=False),
            sa.Column('label', sa.String(length=200), nullable=True),
            sa.Column('conn_id', sa.String(length=250), nullable=False),
            sa.Column('user_id', sa.Integer(), nullable=True),
            sa.Column('chart_type', sa.String(length=100), nullable=True),
            sa.Column('sql_layout', sa.String(length=50), nullable=True),
            sa.Column('sql', sa.Text(), nullable=True),
            sa.Column('y_log_scale', sa.Boolean(), nullable=True),
            sa.Column('show_datatable', sa.Boolean(), nullable=True),
            sa.Column('show_sql', sa.Boolean(), nullable=True),
            sa.Column('height', sa.Integer(), nullable=True),
            sa.Column('default_params', sa.String(length=5000), nullable=True),
            sa.Column('x_is_date', sa.Boolean(), nullable=True),
            sa.Column('iteration_no', sa.Integer(), nullable=True),
            sa.Column('last_modified', sa.DateTime(), nullable=True),
            sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
            sa.PrimaryKeyConstraint('id')
        )
    if 'known_event' not in tables:
        op.create_table(
            'known_event',
            sa.Column('id', sa.Integer(), nullable=False),
            sa.Column('label', sa.String(length=200), nullable=True),
            sa.Column('start_date', sa.DateTime(), nullable=True),
            sa.Column('end_date', sa.DateTime(), nullable=True),
            sa.Column('user_id', sa.Integer(), nullable=True),
            sa.Column('known_event_type_id', sa.Integer(), nullable=True),
            sa.Column('description', sa.Text(), nullable=True),
            sa.ForeignKeyConstraint(['known_event_type_id'],
                                    ['known_event_type.id'], ),
            sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
            sa.PrimaryKeyConstraint('id')
        )
    if 'xcom' not in tables:
        op.create_table(
            'xcom',
            sa.Column('id', sa.Integer(), nullable=False),
            sa.Column('key', sa.String(length=512), nullable=True),
            sa.Column('value', sa.PickleType(), nullable=True),
            sa.Column(
                'timestamp',
                sa.DateTime(),
                default=func.now(),
                nullable=False),
            sa.Column('execution_date', sa.DateTime(), nullable=False),
            sa.Column('task_id', sa.String(length=250), nullable=False),
            sa.Column('dag_id', sa.String(length=250), nullable=False),
            sa.PrimaryKeyConstraint('id')
        )
class CrawlForexExchange(Base):
    """行情资讯类"""
    __tablename__ = 'jujin8_forex_exchange'

    id = Column(Integer, primary_key=True)
    abstractInfo = Column(String(512))
    applyId = Column(Integer)
    applyTime = Column(String(32))
    ascribe = Column(String(36))
    biggestLeverage = Column(String(64))
    cName = Column(String(32))
    checkOrNot = Column(String(32))
    checkedPass = Column(String(8))
    checkedStatus = Column(String(32))
    companyName = Column(String(128))
    condition = Column(String(128))
    createTime = Column(String(32))
    degreeOfPraise = Column(String(32))
    depositMethod = Column(String(64))
    eName = Column(String(64))
    eaDeal = Column(String(64))
    establishTime = Column(String(32))
    gold = Column(String(32))
    hedge = Column(SmallInteger)
    homeCountry = Column(String(128))
    source_id = Column(Integer)
    ids = Column(String(64))
    intro = Column(String(512))
    licenseNo = Column(String(64))
    likeCount = Column(Integer)
    mainSpread = Column(String(64))
    maxSpread = Column(String(64))
    forexExchangeCommission = Column(String(64))
    minSpread = Column(String(64))
    officialBankAddress = Column(String(256))
    officialWebsite = Column(String(256))
    orgLicense = Column(String(64))
    platformLogo = Column(String(128))
    platName = Column(String(64))
    platStatus = Column(String(64))
    platformIcon = Column(String(256))
    platformStatus = Column(String(256))
    platformType = Column(String(64))
    recommendOrNot = Column(String(16))
    relevancy = Column(String(64))
    scalp = Column(String(64))
    show = Column(SmallInteger)
    showPlatform = Column(SmallInteger)
    softwareInfo = Column(String(128))
    sortNo = Column(Integer)
    source = Column(String(64))
    spreadInfo = Column(String(64))
    supervisionOrg = Column(String(128))
    supervisionOrgName = Column(String(64))
    surveyType = Column(String(64))
    swap = Column(String(64))
    synthesisScore = Column(String(64))
    tradeVariety = Column(String(64))
    tradingModel = Column(String(64))
    trailingStop = Column(String(64))
    withdrawMethod = Column(String(64))

    created_at = Column(DateTime, default=func.now())
    updated_at = Column(DateTime, default=func.now(), onupdate=func.now())
Example #50
0
def editItem(item_title):
    """
        Edit new item and store changes in database.

        argument:
            item title
    """
    edit_item = session.query(Item).filter_by(title=item_title).one()
    category_selected = session.query(Category).filter_by(
            id=edit_item.cat_id
            ).one()
    items = session.query(Item).all()
    categories = session.query(Category).all()
    if 'username' not in login_session:
        flash('Please log in')
        return redirect(url_for('showLogin'))
    if edit_item.user_id != login_session['user_id']:
        flash('Please edit only your items!')
        return redirect(url_for('categoriesDashboard'))
    if request.method == 'POST':
        if request.form['category'] and request.form['title']:
            category_selected = session.query(Category).filter_by(
                    name=request.form['category']
                    ).one()
            if 'file' not in request.files and 'image' in request.files:
                image = request.files['image']
                if image.filename != '' and allowed_file(image.filename):
                    filename = secure_filename(image.filename)
                    if (image.filename in
                            [item.image.split('/')[-1] for item in items]):
                        flash('{} picture name already exists!'.format(
                            image.filename
                            ))
                        return render_template(
                                'newitem.html', categories=categories
                                )
                    image_resize = Image.open(image)
                    image_resize = resizeimage.resize_contain(
                            image_resize, [200, 200]
                            )
                    image_resize.save(os.path.join(
                        app.config['UPLOAD_FOLDER'], filename
                        ), image_resize.format)
                    image_path = 'item_images/' + filename
                else:
                    image_path = 'item_images/sport-goods.jpg'
            else:
                image_path = 'item_images/sport-goods.jpg'
            edit_item.image = image_path
            if request.form['title']:
                edit_item.title = request.form['title']
            if request.form['description']:
                edit_item.description = request.form['description']
            edit_item.cat_id = category_selected.id
            edit_item.init_time = func.now()
            session.add(edit_item)
            session.commit()
            session.close()
            flash('{} item has been successfully edited!'.format(
                request.form['title']
                ))
            return redirect(url_for('categoriesDashboard'))
        else:
            flash('Please choose a title and pick a category!')
            return render_template(
                    'edititem.html',
                    item=edit_item,
                    category_selected=category_selected,
                    user_profile_pic=login_session['picture'],
                    login_session_provider=login_session['provider'],
                    categories=categories
                    )
    else:
        return render_template(
                'edititem.html',
                item=edit_item,
                category_selected=category_selected,
                user_profile_pic=login_session['picture'],
                login_session_provider=login_session['provider'],
                categories=categories
                )
Example #51
0
 def archive_dataset(self, dataset_id):
     self._connection.execute(
         DATASET.update().where(DATASET.c.id == dataset_id).where(
             DATASET.c.archived == None).values(archived=func.now()))
Example #52
0
class User(BaseMixin):
    __tablename__ = 'users'

    first_name = Column(String(255), default="")
    last_name = Column(String(255), default="")
    email = Column(String(255), nullable=False, unique=True)
    role_id = Column(Integer, ForeignKey('roles.id'))
    role = relationship('Role', backref=backref('users', lazy='dynamic'))
    add_date = Column(DateTime, default=func.now())
    _pw_hash = Column(UnicodeText, nullable=False)
    age = Column(Integer)

    def __init__(self, *args, **kwargs):
        if 'first_name' in kwargs:
            self.first_name = kwargs.pop('first_name')
        if 'last_name' in kwargs:
            self.last_name = kwargs.pop('last_name')
        if 'email' in kwargs:
            self.email = kwargs.pop('email')
        if 'role' in kwargs:
            self.role = kwargs.pop('role')
        if 'role_id' in kwargs:
            self.role_id = kwargs.pop('role_id')
        if 'password' in kwargs:
            self.password = kwargs.pop('password')

    def _to_json(self):
        import json
        return json.dumps({
            'first_name': self.first_name,
            'last_name': self.last_name,
            'email': self.email,
            'age': self.age,
            'date_added': self.add_date,
        })

    @declared_attr
    def __table_args__(cls):
        return (UniqueConstraint('email', 'first_name', 'last_name'), {})

    @property
    def is_unknown(self):
        return False

    def check_password(self, pw):
        return check_password(pw, self._pw_hash)

    @classmethod
    def get_by_email(cls, email):
        return cls.query().filter_by(email=email).first()

    @property
    def password(self):
        return 'private'
        raise ValueError('Private Value!!!!')

    @password.setter
    def password(self, pw):
        self._pw_hash = encrypt_password(pw)

    @property
    def full_name(self):
        return '{} {}'.format(self.first_name.title(), self.last_name.title())

    @property
    def name(self):
        return str(self.first_name)

    def __str__(self):
        if self.first_name != "":
            rtn = self.full_name
        else:
            rtn = self.email
        return rtn

    def __repr__(self):
        return 'User<{} {}'.format(self.email, self.first_name)

    def _get_absolute_url(self):
        return url_for('member.profile', member_id=str(int(self.id)))

    @property
    def absolute_url(self):
        return str(self._get_absolute_url())

    def _get_edit_url(self):
        return '#'

    @property
    def edit_url(self):
        return str(self._get_edit_url())
Example #53
0
class User(db.Model, UserMixin):
    """
    CREATE TABLE u_user(
    id INT auto_increment PRIMARY KEY COMMENT '用户表id',
    email VARCHAR(64) NOT NULL COMMENT 'email地址',
    phone VARCHAR(16) NOT NULL DEFAULT '' COMMENT '手机',
    username VARCHAR(64) NOT NULL DEFAULT '' COMMENT '用户名,默认为邮箱前缀',
    password_hash VARCHAR(256) NOT NULL COMMENT '用户密码',
    role_id tinyint NOT NULL DEFAULT 3 COMMENT '用户角色id, 1:admin 2:leader, 3:staff',
    status tinyint NOT NULL default 0 COMMENT '用户账号状态, 0:未激活, 1:激活',
    join_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建账号时间',
    UNIQUE KEY email(email),
    KEY join_time(join_time)
    )engine=Innodb charset=utf8 COMMENT '用户表';
    """
    __tablename__ = 'u_user'
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(64), nullable=False)
    phone = db.Column(db.String(16), nullable=False, default='')
    username = db.Column(db.String(64), nullable=False)
    password_hash = db.Column(db.String(256), nullable=False)
    role_id = db.Column(db.Integer, default=3)
    status = db.Column(db.Integer, default=0)
    join_time = db.Column(db.DATETIME, server_default=func.now())

    @property
    def password(self):
        return self.password_hash

    @password.setter
    def password(self, passwd):
        self.password_hash = pbkdf2_sha256.hash(passwd)

    def check_password(self, passwd):
        return pbkdf2_sha256.verify(passwd, self.password)

    def user_groups(self):
        if self.role_id == ADMIN:
            groups = Group.query.all()
        else:
            groups = db.session.query(Group)\
                .join(UserGroup, Group.id == UserGroup.gid)\
                .join(User, UserGroup.uid == User.id)\
                .filter(User.id == self.id).all()
        groups = [g.to_dict() for g in groups]
        return groups

    def user_permissions(self):
        permissions_data = defaultdict(list)
        if self.role_id == ADMIN:
            permissions = Permission.query.all()
        else:
            permissions = db.session.query(Permission)\
                .join(UserPermission, Permission.id == UserPermission.pid)\
                .join(User, UserPermission.uid == User.id)\
                .filter(User.id == self.id).all()
        for p in permissions:
            name_prefix, name_suffix = p.name.split('_')
            p_data = p.to_dict()
            p_data['name'] = name_suffix
            permissions_data[name_prefix].append(p_data)

        return permissions_data
Example #54
0
class Keyword(Base):
    __tablename__ = 'keyword'
    id = Column(Integer, Sequence('keyword_id_seq'), primary_key=True)
    text = Column(String(256))
    create_at = Column(DateTime(timezone=True), default=func.now())
Example #55
0
class Bid(Sessionized, Base):
    __tablename__ = "bids"

    STATUS        = Enum("AUTH", "CHARGE", "REFUND", "VOID")

    # will be unique from authorize
    transaction   = Column(BigInteger, primary_key = True,
                           autoincrement = False)

    # identifying characteristics
    account_id    = Column(BigInteger, index = True, nullable = False)
    pay_id        = Column(BigInteger, index = True, nullable = False)
    thing_id      = Column(BigInteger, index = True, nullable = False)

    # breadcrumbs
    ip            = Column(Inet)
    date          = Column(DateTime(timezone = True), default = safunc.now(),
                           nullable = False)

    # bid information:
    bid           = Column(Float, nullable = False)
    charge        = Column(Float)

    status        = Column(Integer, nullable = False,
                           default = STATUS.AUTH)

    # make this a primary key as well so that we can have more than
    # one freebie per campaign
    campaign      = Column(Integer, default = 0, primary_key = True)

    @classmethod
    def _new(cls, trans_id, user, pay_id, thing_id, bid, campaign = 0):
        bid = Bid(trans_id, user, pay_id, 
                  thing_id, getattr(request, 'ip', '0.0.0.0'), bid = bid,
                  campaign = campaign)
        bid._commit()
        return bid

#    @classmethod
#    def for_transactions(cls, transids):
#        transids = filter(lambda x: x != 0, transids)
#        if transids:
#            q = cls.query()
#            q = q.filter(or_(*[cls.transaction == i for i in transids]))
#            return dict((p.transaction, p) for p in q)
#        return {}

    def set_status(self, status):
        if self.status != status:
            self.status = status
            self._commit()

    def auth(self):
        self.set_status(self.STATUS.AUTH)

    def is_auth(self):
        return (self.status == self.STATUS.AUTH)

    def void(self):
        self.set_status(self.STATUS.VOID)

    def is_void(self):
        return (self.status == self.STATUS.VOID)

    def charged(self):
        self.charge = self.bid
        self.set_status(self.STATUS.CHARGE)
        self._commit()

    def is_charged(self):
        """
        Returns True if transaction has been charged with authorize.net or is
        a freebie with "charged" status.
        """
        return (self.status == self.STATUS.CHARGE)

    def refund(self, amount):
        current_charge = self.charge or self.bid    # needed if charged() not
                                                    # setting charge attr
        self.charge = current_charge - amount
        self.set_status(self.STATUS.REFUND)
        self._commit()

    def is_refund(self):
        return (self.status == self.STATUS.REFUND)

    @property
    def charge_amount(self):
        return self.charge or self.bid
Example #56
0
class ForumPost(db.Model, SinglePKMixin):
    __tablename__ = 'forums_posts'
    __serializer__ = ForumPostSerializer
    __cache_key__ = 'forums_posts_{id}'
    __cache_key_of_thread__ = 'forums_posts_threads_{id}'
    __deletion_attr__ = 'deleted'

    id: int = db.Column(db.Integer, primary_key=True)
    thread_id: int = db.Column(
        db.Integer,
        db.ForeignKey('forums_threads.id'),
        nullable=False,
        index=True,
    )
    user_id: int = db.Column(
        db.Integer, db.ForeignKey('users.id'), nullable=False, index=True
    )
    contents: str = db.Column(db.Text, nullable=False)
    time: datetime = db.Column(
        db.DateTime(timezone=True), nullable=False, server_default=func.now()
    )
    sticky: bool = db.Column(db.Boolean, nullable=False, server_default='f')
    edited_user_id: Optional[int] = db.Column(
        db.Integer, db.ForeignKey('users.id')
    )
    edited_time: Optional[datetime] = db.Column(db.DateTime(timezone=True))
    deleted: bool = db.Column(
        db.Boolean, nullable=False, server_default='f', index=True
    )

    @classmethod
    def from_thread(
        cls,
        thread_id: int,
        page: int = 1,
        limit: int = 50,
        include_dead: bool = False,
    ) -> List['ForumPost']:
        return cls.get_many(
            key=cls.__cache_key_of_thread__.format(id=thread_id),
            filter=cls.thread_id == thread_id,
            order=cls.id.asc(),  # type: ignore
            page=page,
            limit=limit,
            include_dead=include_dead,
        )

    @classmethod
    def get_ids_from_thread(cls, id):
        return cls.get_pks_of_many(
            key=cls.__cache_key_of_thread__.format(id=id),
            filter=cls.thread_id == id,
            order=cls.id.asc(),
        )

    @classmethod
    def new(
        cls, *, thread_id: int, user_id: int, contents: str
    ) -> Optional['ForumPost']:
        ForumThread.is_valid(thread_id, error=True)
        User.is_valid(user_id, error=True)
        cache.delete(cls.__cache_key_of_thread__.format(id=thread_id))
        post = super()._new(
            thread_id=thread_id, user_id=user_id, contents=contents
        )
        send_subscription_notices(post)
        check_post_contents_for_quotes(post)
        check_post_contents_for_mentions(post)
        return post

    @cached_property
    def thread(self) -> 'ForumThread':
        return ForumThread.from_pk(self.thread_id)

    @cached_property
    def user(self) -> User:
        return User.from_pk(self.user_id)

    @cached_property
    def editor(self) -> Optional[User]:
        return User.from_pk(self.edited_user_id)

    @cached_property
    def edit_history(self) -> List['ForumPostEditHistory']:
        return ForumPostEditHistory.from_post(self.id)
def allocate(ctx, optid, optname, opttype, optreplace, opthigh, optlow, optriskmgr, optrisk):
    '''calc high low allocate
    '''
    if opthigh == 0 and 'markowitz.high' in ctx.obj:
        opthigh = ctx.obj['markowitz.high']
    if optlow == 0 and 'markowitz.low' in ctx.obj:
        optlow = ctx.obj['markowitz.low']

    if opthigh == 0 and optlow == 0:
        click.echo(click.style("ether --high or --low shoud be given, aborted!", fg="red"))
        return 0

    #
    # 处理id参数
    #
    today = datetime.now()
    if optid is not None:
        #
        # 检查id是否存在
        #
        df_existed = asset_mz_highlow.load([str(optid * 10 + x) for x in range(0, 10)])
        if not df_existed.empty:
            s = 'highlow instance [%s] existed' % str(optid)
            if optreplace:
                click.echo(click.style("%s, will replace!" % s, fg="yellow"))
            else:
                click.echo(click.style("%s, import aborted!" % s, fg="red"))
                return -1;
    else:
        #
        # 自动生成id
        #
        prefix = '70' + today.strftime("%m%d");
        between_min, between_max = ('%s00' % (prefix), '%s99' % (prefix))

        max_id = asset_mz_highlow.max_id_between(between_min, between_max)
        if max_id is None:
            max_id = between_min

        if not (isinstance(max_id, int) or isinstance(max_id, long)):
            max_id = string.atoi(max_id)

        if max_id is None:
            optid = int(between_min)
        else:
            if max_id >= int(between_max):
                if optreplace:
                    s = "run out of instance id [%d]" % max_id
                    click.echo(click.style("%s, will replace!" % s, fg="yellow"))
                else:
                    s = "run out of instance id [%d]" % max_id
                    click.echo(click.style("%s, import aborted!" % s, fg="red"))
                    return -1

            if optreplace:
                optid = str(max_id)
            else:
                optid = str(max_id + 10)

    if optname is None:
        optname = u'高低风险%s' % today.strftime("%m%d")
    #
    # 加载用到的资产
    #
    df_asset = asset_mz_markowitz_asset.load([opthigh, optlow])
    df_asset = df_asset[['mz_markowitz_id', 'mz_asset_id', 'mz_asset_name', 'mz_asset_type']]
    df_asset = df_asset.rename(columns={'mz_markowitz_id': 'mz_origin_id'})
    df_asset = df_asset.set_index(['mz_asset_id'])
    #
    # 加载用到的风控
    #
    dt_riskmgr = {}
    for k, v in df_asset.iterrows():
        if optriskmgr == False:
            dt_riskmgr[k] = 0
        else:
            df_tmp = asset_rm_riskmgr.where_asset_id(k)
            if df_tmp.empty:
                dt_riskmgr[k] = 0
            else:
                dt_riskmgr[k] = df_tmp.ix[0, 'globalid']
    df_asset['mz_riskmgr_id'] = pd.Series(dt_riskmgr)
    #
    # 加载资产池
    #
    dt_pool = {}
    for k, v in df_asset.iterrows():
        dt_pool[k] = asset_ra_pool.match_asset_pool(k)
    df_asset['mz_pool_id'] = pd.Series(dt_pool)

    if '11310100' not in df_asset.index:
        df_asset.loc['11310100'] = (0, u'货币(低)', 31, 0, '11310100')
    if '11310101' not in df_asset.index:
        df_asset.loc['11310101'] = (0, u'货币(高)', 31, 0, '11310101')

    db = database.connection('asset')
    metadata = MetaData(bind=db)
    mz_highlow        = Table('mz_highlow', metadata, autoload=True)
    mz_highlow_alloc  = Table('mz_highlow_alloc', metadata, autoload=True)
    mz_highlow_asset  = Table('mz_highlow_asset', metadata, autoload=True)
    mz_highlow_pos    = Table('mz_highlow_pos', metadata, autoload=True)
    mz_highlow_nav    = Table('mz_highlow_nav', metadata, autoload=True)

    #
    # 处理替换
    #
    if optreplace:
        mz_highlow_nav.delete(mz_highlow_nav.c.mz_highlow_id.between(optid, optid + 9)).execute()
        mz_highlow_pos.delete(mz_highlow_pos.c.mz_highlow_id.between(optid, optid + 9)).execute()
        mz_highlow_asset.delete(mz_highlow_asset.c.mz_highlow_id == optid).execute()
        mz_highlow_alloc.delete(mz_highlow_alloc.c.mz_highlow_id == optid).execute()
        mz_highlow.delete(mz_highlow.c.globalid == optid).execute()

    now = datetime.now()
    # 导入数据: highlow
    row = {
        'globalid': optid, 'mz_type':opttype, 'mz_name': optname,
        'mz_algo': 1, 'mz_high_id': opthigh, 'mz_low_id': optlow,
        'mz_persistent': 0, 'created_at': func.now(), 'updated_at': func.now()
    }
    mz_highlow.insert(row).execute()

    #
    # 加载高风险资产仓位
    #
    index = None
    if opthigh == 0:
        optrisk = '1'
    else:
        df_high = asset_mz_markowitz_pos.load_raw(opthigh)
        df_high_riskmgr = load_riskmgr(df_high.columns, df_high.index, optriskmgr)
        index = df_high.index.union(df_high_riskmgr.index)
    #
    # 加载低风险资产仓位
    #
    if optlow == 0:
        optrisk = '10'
    else:
        df_low  = asset_mz_markowitz_pos.load_raw(optlow)
        df_low_riskmgr = load_riskmgr(df_low.columns, df_low.index, optriskmgr)
        if index is None:
            index = df_low.index.union(df_low_riskmgr.index)
        else:
            index = index.union(df_low.index).union(df_low_riskmgr.index)

    #
    # 生成资产列表
    #

    for risk in [int(x) for x in optrisk.split(',')]:
        highlow_id = str(string.atoi(optid) + (risk % 10))
        name = optname + u"-等级%d" % (risk)
        # 配置比例
        ratio_h  = (risk - 1) * 1.0 / 9
        ratio_l  = 1 - ratio_h

        data_h = {}
        if not df_high.empty:
            df_high = df_high.reindex(index, method='pad')
            df_high_riskmgr = df_high_riskmgr.reindex(index, method='pad')
            for column in df_high.columns:
                data_h[column] = df_high[column] * df_high_riskmgr[column] * ratio_h
        df_h = pd.DataFrame(data_h)

        data_l = {}
        if not df_low.empty:
            df_low = df_low.reindex(index, method='pad')
            df_low_riskmgr = df_low_riskmgr.reindex(index, method='pad')
            for column in df_low.columns:
                data_l[column] = df_low[column] * df_low_riskmgr[column] * ratio_l
        df_l = pd.DataFrame(data_l)
        #
        # 用货币补足空仓部分, 因为我们的数据库结构无法表示所有资产空
        # 仓的情况(我们不存储仓位为0的资产);所以我们需要保证任何一
        # 天的持仓100%, 如果因为风控空仓,需要用货币补足。
        #
        if ratio_h > 0:
            sr = ratio_h - df_h.sum(axis=1)
            if (sr > 0.000099).any():
                df_h['11310101'] = sr

        if ratio_l > 0:
            sr = ratio_l - df_l.sum(axis=1)
            if (sr > 0.000099).any():
                df_l['11310100'] = sr
        #
        # 合并持仓
        #
        df = pd.concat([df_h, df_l], axis=1)

        #
        # 导入数据: highlow_alloc
        #
        row = {
            'globalid': highlow_id, 'mz_type':opttype, 'mz_name': name,
            'mz_highlow_id': optid, 'mz_risk': risk / 10.0, 'created_at': func.now(), 'updated_at': func.now()
        }
        mz_highlow_alloc.insert(row).execute()

        #
        # 导入数据: highlow_asset
        #
        df_asset_tosave = df_asset.copy()
        df_asset_tosave['mz_highlow_id'] = highlow_id
        df_asset_tosave = df_asset_tosave.reset_index().set_index(['mz_highlow_id', 'mz_asset_id'])
        asset_mz_highlow_asset.save([highlow_id], df_asset_tosave)

        #
        # 导入数据: highlow_pos
        #
        df = df.round(4)             # 四舍五入到万分位
        df[df.abs() < 0.0009999] = 0 # 过滤掉过小的份额
        # print df.head()
        df = df.apply(npu.np_pad_to, raw=True, axis=1) # 补足缺失
        # df = DFUtil.filter_same_with_last(df)          # 过滤掉相同
        # if turnover >= 0.01:
        #     df = DFUtil.filter_by_turnover(df, turnover)   # 基于换手率进行规律 

        df.index.name = 'mz_date'
        df.columns.name='mz_asset_id'


        # index
        df['mz_highlow_id'] = highlow_id
        df = df.reset_index().set_index(['mz_highlow_id', 'mz_date'])

        # unstack
        df_tosave = df.stack().to_frame('mz_ratio')
        df_tosave = df_tosave.loc[(df_tosave['mz_ratio'] > 0)]

        # save
        # print df_tosave
        asset_mz_highlow_pos.save(highlow_id, df_tosave)

        # click.echo(click.style("highlow allocation complement! instance id [%s]" % (optid), fg='green'))

    #
    # 在context的记录id, 以便命令两中使用
    #
    ctx.obj['highlow'] = optid

    click.echo(click.style("highlow allocation complement! instance id [%s]" % (optid), fg='green'))
Example #58
0
class CrawlerLOG(Base):
    __tablename__ = 'log'
    id = Column(Integer, Sequence('log_id_seq'), primary_key=True)
    level = Column(Integer)
    text = Column(Text)
    create_at = Column(DateTime(timezone=True), default=func.now())
Example #59
0
class PageView(db.Model):
    __tablename__ = 'pageviews'

    id = db.Column(db.Integer, primary_key=True)
    id_errorlog = db.Column(db.Integer)
    page = db.Column(db.String(512))
    endpoint = db.Column(db.String(255))
    user_id = db.Column(db.Integer)
    object_id = db.Column(db.Integer)
    object_type = db.Column(db.String(100))
    object_action = db.Column(db.String(100))
    ip_address = db.Column(db.String(64))
    created_at = db.Column(db.DateTime, default=func.now())
    version = db.Column(db.String(100), default=__version__)

    class logged(object):
        def __init__(self, route, object_extractor=None):
            self._route = route
            self._object_extractor = object_extractor

        def __getattr__(self, attr):
            return getattr(self._route, attr)

        def __call__(self, *args, **kwargs):
            if not current_app.config.get('INDEXING_ENABLED', True):
                return self._route(*args, **kwargs)

            log = PageView(page=request.full_path,
                           endpoint=request.endpoint,
                           user_id=current_user.id,
                           ip_address=request.remote_addr,
                           version=__version__)
            errorlog = None
            log.object_id, log.object_type, log.object_action, reextract_after_request = self.extract_objects(
                *args, **kwargs)
            db_session.add(
                log)  # Add log here to ensure pageviews are accurate

            try:
                return self._route(*args, **kwargs)
            except Exception as e:
                db_session.rollback(
                )  # Ensure no lingering database changes remain after crashed route
                db_session.add(log)
                errorlog = ErrorLog.from_exception(e)
                db_session.add(errorlog)
                db_session.commit()
                raise_with_traceback(e)
            finally:
                # Extract object id and type after response generated (if requested) to ensure
                # most recent data is collected
                if reextract_after_request:
                    log.object_id, log.object_type, log.object_action, _ = self.extract_objects(
                        *args, **kwargs)

                if errorlog is not None:
                    log.id_errorlog = errorlog.id
                db_session.add(log)
                db_session.commit()

        def object_extractor(self, extractor):
            self._object_extractor = extractor
            return self

        def extract_objects(self, *args, **kwargs):
            if self._object_extractor is None:
                return None, None, None, False
            try:
                object_info = self._object_extractor(*args, **kwargs)
            except Exception as e:
                logger.warning("Error using object extractor: " + str(e))
                object_info = {'id': (-1), 'type': None}
            assert isinstance(
                object_info,
                dict), "Object extractors must return a dictionary."
            assert len(set([
                'id', 'type'
            ]).difference(object_info.keys())) == 0 and len(
                set(object_info.keys()).difference(
                    ['id', 'type', 'action', 'may_change'])
            ) == 0, "Object extractors must at least include the keys 'id' and 'type', and optionally 'action' and 'may_change'. Was provided with: {}".format(
                str(list(object_info.keys())))
            object_info = defaultdict(lambda: None, object_info)
            return object_info['id'], object_info['type'], object_info[
                'action'], object_info['may_change'] or False
Example #60
0
def newItem():
    """
        Create new item and store it in database.
    """
    if 'username' not in login_session:
        flash('Please log in')
        return redirect(url_for('showLogin'))
    categories = session.query(Category).all()
    items = session.query(Item).all()
    if request.method == 'POST':
        if 'username' not in login_session:
            flash('Please log in')
            return redirect(url_for('showLogin'))
        if request.form['title'] not in [item.title for item in items]:
            if (
                    request.form['category'] != 'Choose a category...'
                    and request.form['title']
                    ):
                category = session.query(Category).filter_by(
                        name=request.form['category']
                        ).one()
                if 'file' not in request.files and 'image' in request.files:
                    image = request.files['image']
                    if image.filename != '' and allowed_file(image.filename):
                        filename = secure_filename(image.filename)
                        if (image.filename in
                                [item.image.split('/')[-1] for item in items]):
                            flash('{} picture name already exists!'.format(
                                image.filename
                                ))
                            return render_template(
                                    'newitem.html', categories=categories
                                    )
                        image_resize = Image.open(image)
                        image_resize = resizeimage.resize_contain(
                                image_resize, [200, 200]
                                )
                        image_resize.save(os.path.join(
                            app.config['UPLOAD_FOLDER'], filename
                            ), image_resize.format)
                        image_path = 'item_images/' + filename
                    else:
                        image_path = 'item_images/sport-goods.jpg'
                else:
                    image_path = 'item_images/sport-goods.jpg'
                new_item = Item(
                        title=request.form['title'],
                        description=request.form['description'],
                        user_id=login_session['user_id'],
                        image=image_path,
                        cat_id=category.id,
                        init_time=func.now()
                        )
                session.add(new_item)
                session.commit()
                flash('{} item has been created!'.format(
                    request.form['title']
                    ))
                return redirect(url_for('categoriesDashboard'))
            else:
                flash('Please, give a name and pick a category for your item!')
                return render_template(
                        'newitem.html',
                        categories=categories,
                        user_profile_pic=login_session['picture'],
                        login_session_provider=login_session['provider']
                        )
        else:
            flash('{} title already exists!'.format(request.form['title']))
            return render_template(
                    'newitem.html',
                    categories=categories,
                    user_profile_pic=login_session['picture'],
                    login_session_provider=login_session['provider']
                    )
    else:
        return render_template(
                'newitem.html',
                categories=categories,
                user_profile_pic=login_session['picture'],
                login_session_provider=login_session['provider']
                )