class Badge(TimestampMixin, Model): __tablename__ = 'badge' id = db.Column(db.BigInteger(), primary_key=True) foreign_id = db.Column(db.String(64), unique=True) name = db.Column(db.UnicodeText(), nullable=False) level_id = db.Column(db.BigInteger(), db.ForeignKey('level.id', onupdate='CASCADE', ondelete='RESTRICT'), nullable=False) level = db.relationship('Level') real_age = db.Column(db.Integer()) under_18 = db.Column(db.Boolean(), nullable=False, default=False) under_13 = db.Column(db.Boolean(), nullable=False, default=False) print_queued = db.Column(db.Boolean(), nullable=False, default=False, index=True) print_queued_by_id = db.Column( db.BigInteger(), db.ForeignKey('user.id', onupdate='CASCADE', ondelete='SET NULL')) print_queued_by = db.relationship('User') flags = db.relationship('Flag', secondary=BadgeToFlag.__table__) @property def age(self): """\ Returns an adjusted age - a real age, if set, otherwise a fake age corresponding to another age group """ if self.under_13: return 12 elif self.under_18: return 17 return self.real_age @age.setter def age(self, value): if value < 13: self.under_13 = True self.under_18 = True self.real_age = None elif value < 18: self.under_13 = False self.under_18 = True self.real_age = None else: self.under_13 = False self.under_18 = False self.real_age = value
class BadgeToFlag(Model): __tablename__ = 'badge_to_flag' __table_args__ = (db.PrimaryKeyConstraint('badge_id', 'flag_id'), ) badge_id = db.Column(db.BigInteger(), db.ForeignKey('badge.id', onupdate='CASCADE', ondelete='CASCADE'), nullable=False) flag_id = db.Column(db.BigInteger(), db.ForeignKey('flag.id', onupdate='CASCADE', ondelete='CASCADE'), nullable=False)
class BadgeTemplateToLevel(Model): __tablename__ = 'badge_template_to_level' __table_args__ = (db.PrimaryKeyConstraint('badge_template_id', 'level_id'), ) badge_template_id = db.Column(db.BigInteger(), db.ForeignKey('badge_template.id', onupdate='CASCADE', ondelete='CASCADE'), nullable=False) level_id = db.Column(db.BigInteger(), db.ForeignKey('level.id', onupdate='CASCADE', ondelete='CASCADE'), nullable=False)
class Role(db.Model, RoleMixin): id = db.Column(db.BigInteger(), primary_key=True) name = db.Column(db.String(100), unique=True) description = db.Column(db.String(255)) def __repr__(self): return self.name
class User(Base): __tablename__ = 'user' country = db.Column(db.String(128), nullable=False) region = db.Column(db.String(128), nullable=False) district = db.Column(db.String(128), nullable=False) phone = db.Column(db.BigInteger(), nullable=False) name = db.Column(db.String(128), nullable=False) email = db.Column(db.String(128), nullable=True, unique=True) password = db.Column(db.String(192), nullable=False) status = db.Column(db.SmallInteger, nullable=False) def __init__(self, country, region, district, phone, name, email, password, status): self.country = country self.region = region self.district = district self.phone = phone self.name = name self.email = email self.password = password self.status = status def __repr__(self): return '<User %r>' % (self.name)
class User(UserMixin, db.Model): id = db.Column(db.Integer(), primary_key=True) firstname = db.Column(db.String(100), nullable=False) lastname = db.Column(db.String(100), nullable=False) image_pic = db.Column(db.String(100), nullable=False, default='avatar.jpeg') phone_number = db.Column(db.BigInteger(), nullable=False) email = db.Column(db.String(50), nullable=False, unique=True) password_hash = db.Column(db.String(128)) posts = db.relationship('Post', backref='author', lazy='dynamic') def __repr__(self): return f"<User, {self.email}>" def set_password(self, password): self.password_hash = generate_password_hash(password) def check_password(self, password): return check_password_hash(self.password_hash, password) #Reset password logic def get_reset_token(self, expires_sec=1800): s = Serializer(app.config['SECRET_KEY'], expires_sec) return s.dumps({'user_id': self.id}).decode('utf-8') @staticmethod def verify_token(token): s = Serializer(app.config['SECRET_KEY']) try: user_id = s.loads(token)['user_id'] except: return None return User.query.get(user_id)
class User(db.Model): id = db.Column(db.BigInteger(), primary_key=True) matricula = db.Column(db.String()) name = db.Column(db.String(80), unique=True) email = db.Column(db.String(120), unique=True) user_type = db.Column(db.String()) cpf = db.Column(db.BigInteger, unique=True) phone_number = db.Column(db.String()) birthday = db.Column(db.Date()) def __init__(self, matricula, name, email, user_type, cpf, phone_number, birthday): self.name = name self.matricula = matricula self.email = email self.user_type = user_type self.cpf = cpf self.phone_number = phone_number self.birthday = birthday def persist(self): db.session.add(self) db.session.commit() def __repr__(self): return '<User %r>' %self.name
class Wallet(db.Model): __tablename__ = "wallets" id = db.Column(db.Integer(), primary_key=True) user_id = db.Column(db.Integer(), db.ForeignKey("users.id", ondelete="CASCADE")) address = db.Column(db.String(255)) network = db.Column(db.Enum(Networks)) balance = db.Column(db.BigInteger(), default=0)
class User(db.Model): __tablename__ = 'users' id = db.Column(db.BigInteger(), primary_key=True) nickname = db.Column(db.Unicode()) def __repr__(self): return '{}<{}>'.format(self.nickname, self.id)
class BadgePrint(TimestampMixin, Model): __tablename__ = 'badge_print' id = db.Column(db.BigInteger(), primary_key=True) badge_id = db.Column(db.BigInteger(), db.ForeignKey('badge.id', onupdate='CASCADE', ondelete='CASCADE'), nullable=False) badge = db.relationship('Badge', backref='prints') queued_by_id = db.Column( db.BigInteger(), db.ForeignKey('user.id', onupdate='CASCADE', ondelete='SET NULL')) queued_by = db.relationship('User', foreign_keys=[queued_by_id]) printed_by_id = db.Column( db.BigInteger(), db.ForeignKey('user.id', onupdate='CASCADE', ondelete='SET NULL')) printed_by = db.relationship('User', foreign_keys=[printed_by_id])
class Level(Model): __tablename__ = 'level' id = db.Column(db.BigInteger(), primary_key=True) name = db.Column(db.Unicode(32), unique=True, nullable=False) description = db.Column(db.UnicodeText()) def __str__(self): return self.name
class RegisteredUsers(db.Model): __tablename__ = 'RegisteredUsers' __table_args__ = ( CheckConstraint('phone_number >= 1000000000'), CheckConstraint('phone_number <= 9999999999'), ) phone_number = db.Column(db.BigInteger(), primary_key=True) otp = db.Column(db.Integer) bookings = db.relationship('Bookings', backref='user_ids', lazy='dynamic')
class IOPSEveryIntervalHour(db.Model): __tablename__ = 'iops_interval_hour' id = db.Column(db.Integer, primary_key=True) disk_name = db.Column(db.String(32), nullable=False) time = db.Column(db.BigInteger(), nullable=False, index=True) io = db.Column(db.Float(precision=4), nullable=False) container_id = db.Column(db.Integer , db.ForeignKey('containers.id')) disk_id = db.Column(db.Integer, db.ForeignKey('disks.id'))
class ParkingDiscount(db.Model): __tablename__ = 'parking_discount' id = db.Column(db.BigInteger().with_variant(db.Integer, "sqlite"), primary_key=True) userId = db.Column(db.BigInteger, nullable=False) code = db.Column(db.String(15), nullable=False) discountPercent = db.Column(db.Float, nullable=False) discountRank_type = db.Column(db.Enum(DiscountRank), nullable=False) validFrom = db.Column(db.DateTime, nullable=False) validUntil = db.Column(db.DateTime, nullable=False)
class Quote(db.Model): id = db.Column(db.BigInteger().with_variant(db.Integer, 'sqlite'), primary_key=True) user_id = db.Column(db.BigInteger, index=True, nullable=False) reporter_id = db.Column(db.BigInteger, index=True, nullable=False) server_id = db.Column(db.BigInteger, index=True, nullable=False) timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow) body = db.Column(db.String) def __repr__(self): return '<quote {}>'.format(self.id)
class Legalentity(db.Model): INN = db.Column(db.BigInteger(), primary_key=True) full_name = db.Column(db.String()) short_name = db.Column(db.String()) company_name = db.Column(db.String()) OGRN = db.Column(db.BigInteger()) legal_address = db.Column(db.String()) real_address = db.Column(db.String()) license_number = db.Column(db.BigInteger, db.ForeignKey('license.license_number')) employee_number = db.relationship('Employee', backref='legal', lazy='dynamic') user = db.relationship('ClientUser', backref='legalentity', lazy='dynamic') contract = db.relationship('Contract', secondary=contracts, backref=db.backref('legal', lazy='dynamic')) def __str__(self): return str(self.INN)
class PinterestData(db.Model): __tablename__ = 'pinterest_data' id = db.Column(db.Integer(), primary_key=True) user_id = db.Column(db.Integer(), db.ForeignKey('users.id', ondelete='CASCADE'), index=True) pinterest_id = db.Column(db.BigInteger()) username = db.Column(db.String(300), nullable=False, default="") full_name = db.Column(db.String(300), nullable=False, default="") pins = db.Column(db.Integer()) boards = db.Column(db.Integer()) following = db.Column(db.Integer()) followers = db.Column(db.Integer())
class LinkClick(db.Model): __tablename__ = 'linkclicks' id = db.Column(db.Integer, primary_key=True) src = db.Column(db.String()) dest = db.Column(db.String()) time = db.Column(db.BigInteger()); userid = db.Column(db.String()); def __init__(self, json): self.src = json['from'] self.dest = json['to'] self.time = json['time'] self.userid = json['userID']
class InteractionEvent(db.Model): __tablename__ = 'interactions' id = db.Column(db.Integer, primary_key=True) userid = db.Column(db.String()); event = db.Column(db.String()); url = db.Column(db.String()); time = db.Column(db.BigInteger()); target = db.Column(db.String()); def __init__(self, json): self.userid = json['userID'] self.url = json['url'] self.event = json['event'] self.time = json['time'] self.target = json['target']
class Statistic(db.Model): statistic_key = db.Column(db.String(64), unique=True, nullable=False, primary_key=True, autoincrement=False) job_count = db.Column(db.BigInteger()) event_count = db.Column(db.BigInteger()) series_count = db.Column(db.BigInteger()) user_count = db.Column(db.BigInteger()) ca_count = db.Column(db.Integer()) total_minutes = db.Column(db.BigInteger()) hosts = db.relationship('Host', backref='statistic', lazy='joined') adopter_key = db.Column(db.String(64), db.ForeignKey('adopter.adopter_key')) created = db.Column(db.DateTime, default=datetime.datetime.now) updated = db.Column(db.DateTime, default=datetime.datetime.now) version = db.Column(db.String(50)) def __init__(self): pass def update(self, values): for stat_k, stat_v in values.items(): if stat_k == 'hosts': if self.hosts is not None: for db_host in self.hosts: db.session.delete(db_host) new_host_list = [] for host in stat_v: new_host = Host() new_host.update(host) new_host_list.append(new_host) stat_v = new_host_list setattr(self, stat_k, stat_v) self.updated = datetime.datetime.now()
def model(name): name = name.encode('utf-8') ModelClass = IOPS._mapper.get(name, None) if ModelClass is None: ModelClass = type(name, (db.Model,), { '__module__': __name__, '__name__': name, '__tablename__': 'iops_' + name, 'id': db.Column(db.Integer, primary_key=True), 'disk_name': db.Column(db.String(32), nullable=False), 'time': db.Column(db.BigInteger(), nullable=False, index=True), 'io': db.Column(db.Float(precision=4), nullable=False), 'container_id': db.Column(db.Integer, db.ForeignKey('containers.id')), 'disk_id': db.Column(db.Integer, db.ForeignKey('disks.id')) }) IOPS._mapper[name] = ModelClass return ModelClass
class Bikes(db.Model): ID = db.Column(db.Integer(), primary_key=True) last_update = db.Column(db.BigInteger(), primary_key=True) day = db.Column(db.TIMESTAMP()) week = db.Column(db.Integer()) available_bikes = db.Column(db.Integer()) available_bike_stands = db.Column(db.Integer()) status = db.Column(db.VARCHAR(255)) def __init__(self, ID, last_update, day, week, available_bikes, available_bike_stands, status): self.ID = ID self.last_update = last_update self.day = day self.week = week self.available_bikes = available_bikes self.available_bike_stands = available_bike_stands self.status = status
class VW_result_codes(db.Model): __tablename__ = 'vw_result_codes' year = db.Column(db.Integer, primary_key=True) month = db.Column(db.Integer, primary_key=True) result = db.Column(db.Text, primary_key=True) total = db.Column(db.BigInteger()) def __repr__(self): return 'VW_result_codes: (month=%s, total=%s)' % (self.month, self.total) @classmethod def getResultsChart(cls, year, month): try: values = db.session.query( VW_result_codes.result, VW_result_codes.total).filter( VW_result_codes.year == year, VW_result_codes.month == month).limit(10) # print(str(values.statement.compile(dialect=postgresql.dialect()))) except Exception as e: print('Error!') print(e) return None return values @classmethod def refresh_mat_view(cls): try: db.session.flush() db.session.execute( 'REFRESH MATERIALIZED VIEW CONCURRENTLY vw_result_codes') db.session.commit() except Exception as e: print('Error refreshing views!') print(e) return None return 1
class Weather(db.Model): ID = db.Column(db.Integer(), primary_key=True) temp = db.Column(db.FLOAT()) weather = db.Column(db.VARCHAR(255)) w_description = db.Column(db.VARCHAR(255)) visibility = db.Column(db.Integer()) wind_speed = db.Column(db.Integer()) datetime = db.Column(db.BigInteger()) day = db.Column(db.TIMESTAMP()) week = db.Column(db.Integer()) def __init__(self, ID, temp, weather, w_description, visibility, wind_speed, datetime, day, week): self.ID = ID self.temp = temp self.weather = weather self.w_description = w_description self.visibility = visibility self.wind_speed = wind_speed self.datetime = datetime self.day = day self.week = week
class Date(db.Model): __tablename__ = 'dim_date' date_dim_id = db.Column(db.BigInteger(), primary_key=True, nullable=False) date_actual = db.Column(postgresql.DATE) day_suffix = db.Column(db.String(4), nullable=False) day_name = db.Column(db.String(9), nullable=False) day_of_week = db.Column(db.Integer, nullable=False) day_of_month = db.Column(db.Integer, nullable=False) day_of_quarter = db.Column(db.Integer, nullable=False) day_of_year = db.Column(db.Integer, nullable=False) week_of_month = db.Column(db.Integer, nullable=False) week_of_year = db.Column(db.Integer, nullable=False) week_of_year_iso = db.Column(db.String(10), nullable=False) month_actual = db.Column(db.Integer, nullable=False) month_name = db.Column(db.String(9), nullable=False) month_name_abbreviated = db.Column(db.String(3), nullable=False) quarter_actual = db.Column(db.Integer, nullable=False) quarter_name = db.Column(db.String(9), nullable=False) year_actual = db.Column(db.Integer, nullable=False) first_day_of_week = db.Column(db.DateTime(timezone=False), nullable=False) last_day_of_week = db.Column(db.DateTime(timezone=False), nullable=False) first_day_of_month = db.Column(db.DateTime(timezone=False), nullable=False) last_day_of_month = db.Column(db.DateTime(timezone=False), nullable=False) first_day_of_quarter = db.Column(db.DateTime(timezone=False), nullable=False) last_day_of_quarter = db.Column(db.DateTime(timezone=False), nullable=False) first_day_of_year = db.Column(db.DateTime(timezone=False), nullable=False) last_day_of_year = db.Column(db.DateTime(timezone=False), nullable=False) mmyyyy = db.Column(db.String(6), nullable=False) mmddyyyy = db.Column(db.String(10), nullable=False) weekend_indr = db.Column(db.Boolean, nullable=False) facts = db.relationship('Request', backref='fact_date', primaryjoin='Date.date_dim_id == Request.date_id') def __repr__(self): return 'Date_dim: (id=%s, date=%s)' % (self.date_dim_id, self.mmddyyyy)
class TaskModel(BaseModel, db.Model): """ 记录数据集同步信息,最近一次同步位置 字段: key,value,created_by,updated_by """ __tablename__ = 'cs_task' # 同步对象标签 task_id = db.Column(db.String(255), nullable=False, unique=True) chunks = db.Column(db.String(), default='') # 1正在上传;2正在合并 3合并完成 status = db.Column(db.Integer(), default=TASK_STATUS_UPLOADING) size = db.Column(db.BigInteger(), default=0) link = db.Column(db.JSON()) batch = db.Column(db.String(), default='') def __init__(self, **dict): self.task_id = dict.get('task_id') self.chunks = dict.get('chunks') self.status = dict.get('status') self.link = dict.get('link') self.size = dict.get('size') self.batch = dict.get('batch') self.created_by = g.user_id if hasattr(g, 'user_id') else (dict.get('created_by') or 0) self.tenant_id = g.tenant_id if hasattr(g, 'tenant_id') else (dict.get('tenant_id') or 0) @classmethod def bulk_upsert_mappings(cls, items, commit=True): for item in items: task_id = item.get('task_id') if task_id is not None: task = TaskModel.query.filter(TaskModel.task_id == task_id).first() if task is None: cls.bulk_insert_mappings([item]) else: item['id'] = task.id cls.bulk_update_mappings([item])
class Flight(db.Model): id = db.Column(db.Integer, primary_key=True) matricula_aluno = db.Column(db.BigInteger()) registerDate = db.Column(db.Date()) dateTimeFlightStart = db.Column(db.DateTime()) dateTimeFlightEnd = db.Column(db.DateTime()) grade = db.Column(db.Float()) comment = db.Column(db.Text()) def __init__(self, matricula_aluno, registerDate, dateTimeFlightStart, dateTimeFlightEnd, comment, grade): self.matricula_aluno = matricula_aluno self.registerDate = registerDate self.dateTimeFlightStart = dateTimeFlightStart self.dateTimeFlightEnd = dateTimeFlightEnd self.comment = comment self.grade = grade def persist(self): db.session.add(self) db.session.commit() def __repr__(self): return '<id {}>'.format(self.id)
class User(TimestampMixin, Model): __tablename__ = 'user' id = db.Column(db.BigInteger(), primary_key=True) username = db.Column(db.Unicode(128), nullable=False) password = db.Column( sau.PasswordType(schemes=['bcrypt'], bcrypt__min_rounds=12)) def __str__(self): return self.username # Stuff for flask login @staticmethod @login_manager.user_loader def flask_login__load_user(user_id): try: return User.query.get(int(user_id)) except (ValueError, TypeError): pass return None @property def is_authenticated(self): return True @property def is_active(self): return True @property def is_anonymous(self): return False def get_id(self): return str(self.id)
class Replay(db.Model): __tablename__ = "replays" ################# # Table columns # ################# id = db.Column(db.Integer, primary_key=True) # optional uint32 match_id = 6; local_uri = db.Column(db.String(128), index=True) state = db.Column(db.Enum("WAITING_GC", "WAITING_DOWNLOAD", "DOWNLOAD_IN_PROGRESS", "ARCHIVED", "GC_ERROR", "DOWNLOAD_ERROR"), default="WAITING_GC", index=True) gc_fails = db.Column(db.Integer, default=0) dl_fails = db.Column(db.Integer, default=0) # Timestamps for progress tracker added_to_site_time = db.Column(db.DateTime, default=datetime.datetime.utcnow, index=True) gc_done_time = db.Column(db.DateTime, index=True) dl_done_time = db.Column(db.DateTime, index=True) # Match data replay_state = db.Column( db.Enum("REPLAY_AVAILABLE", "REPLAY_NOT_RECORDED", "REPLAY_EXPIRED", "UNKNOWN"), default="UNKNOWN", index=True ) # optional .CMsgDOTAMatch.ReplayState replay_state = 34 [default = REPLAY_AVAILABLE]; replay_cluster = db.Column(db.Integer()) # optional uint32 cluster = 10; replay_salt = db.Column(db.Integer()) # optional fixed32 replay_salt = 13; game_mode = db.Column( db.SmallInteger(), index=True ) # optional .DOTA_GameMode game_mode = 31 [default = DOTA_GAMEMODE_NONE]; match_seq_num = db.Column( db.Integer()) # optional uint64 match_seq_num = 33; lobby_type = db.Column( db.SmallInteger()) # optional uint32 lobby_type = 16; league_id = db.Column(db.Integer(), db.ForeignKey("leagues.id"), nullable=True) # optional uint32 leagueid = 22; series_id = db.Column(db.Integer()) # optional uint32 series_id = 39; series_type = db.Column(db.Integer()) # optional uint32 series_type = 40; good_guys_win = db.Column(db.Boolean()) # optional bool good_guys_win = 2; duration = db.Column(db.Integer()) # optional uint32 duration = 3; start_time = db.Column(db.Integer()) # optional fixed32 startTime = 4; first_blood_time = db.Column( db.Integer()) # optional uint32 first_blood_time = 12; human_players = db.Column( db.Integer()) # optional uint32 human_players = 17; radiant_tower_status = db.Column( db.Integer()) # repeated uint32 tower_status = 8; dire_tower_status = db.Column(db.Integer()) radiant_barracks_status = db.Column( db.Integer()) # repeated uint32 barracks_status = 9; dire_barracks_status = db.Column(db.Integer()) radiant_team_id = db.Column( db.Integer(), index=True) # optional uint32 radiant_team_id = 20; radiant_team_name = db.Column( db.String(80), index=True) # optional string radiant_team_name = 23; radiant_team_logo = db.Column( db.BigInteger()) # optional uint64 radiant_team_logo = 25; radiant_team_tag = db.Column( db.String(80)) # optional string radiant_team_tag = 37; radiant_team_complete = db.Column( db.Boolean()) # optional uint32 radiant_team_complete = 27; dire_team_id = db.Column(db.Integer(), index=True) # optional uint32 dire_team_id = 21; dire_team_name = db.Column( db.String(80), index=True) # optional string dire_team_name = 24; dire_team_logo = db.Column( db.BigInteger()) # optional uint64 dire_team_logo = 26; dire_team_tag = db.Column( db.String(80)) # optional string dire_team_tag = 38; dire_team_complete = db.Column( db.Boolean()) # optional uint32 dire_team_complete = 28; radiant_guild_id = db.Column( db.Integer()) # optional uint32 radiant_guild_id = 35; dire_guild_id = db.Column( db.Integer()) # optional uint32 dire_guild_id = 36; # Not implementing # optional fixed32 server_ip = 14; # Not exposed to client # optional uint32 server_port = 15; # Not exposed to client # optional uint32 average_skill = 18; # Not exposed to client # optional float game_balance = 19; # Not exposed to client # optional uint32 positive_votes = 29; # Variable, not worth serializing to DB. Perhaps memcached with websockets GC reqs # optional uint32 negative_votes = 30; # Variable, not worth serializing to DB. ################# # Relationships # ################# # GC relationships players = db.relationship('ReplayPlayer', backref="replay", lazy="join", cascade="all, delete-orphan" ) # repeated .CMsgDOTAMatch.Player players = 5; # repeated .CMatchHeroSelectEvent picks_bans = 32; # TODO # Site relationships ratings = db.relationship('ReplayRating', backref='replay', lazy='joined', cascade="all, delete-orphan") favourites = db.relationship('ReplayFavourite', backref='replay', lazy='joined', cascade="all, delete-orphan") downloads = db.relationship('ReplayDownload', backref="replay", lazy="dynamic", cascade="all, delete-orphan") aliases = db.relationship('ReplayAlias', backref="replay", lazy="dynamic", cascade="all, delete-orphan") ############### # Static data # ############### # Game mode data interpreted from the game's protobufs: # https://github.com/SteamRE/SteamKit/blob/master/Resources/Protobufs/dota/dota_gcmessages_common.proto#L407 game_mode_strings = [ "Invalid (0)", # DOTA_GAMEMODE_NONE = 0; "All Pick", # DOTA_GAMEMODE_AP = 1; "Captain's Mode", # DOTA_GAMEMODE_CM = 2; "Random Draft", # DOTA_GAMEMODE_RD = 3; "Standard Draft", # DOTA_GAMEMODE_SD = 4; "All Random", # DOTA_GAMEM ODE_AR = 5; "Invalid (6)", # DOTA_GAMEMODE_INTRO = 6; "Diretide", # DOTA_GAMEMODE_HW = 7; "Reverse Captains Mode", # DOTA_GAMEMODE_REVERSE_CM = 8; "The Greeviling", # DOTA_GAMEMODE_XMAS = 9; "Tutorial", # DOTA_GAMEMODE_TUTORIAL = 10; "Mid Only", # DOTA_GAMEMODE_MO = 11; "Least Played", # DOTA_GAMEMODE_LP = 12; "Limited Heroes", # DOTA_GAMEMODE_POOL1 = 13; "Compendium", # DOTA_GAMEMODE_FH = 14; "Invalid (15)", # DOTA_GAMEMODE_CUSTOM = 15; "Captains Draft", # DOTA_GAMEMODE_CD = 16; "Balanced Draft", # DOTA_GAMEMODE_BD = 17; "Ability Draft", # DOTA_GAMEMODE_ABILITY_DRAFT = 18; "Invalid (19)" # DOTA_GAMEMODE_EVENT = 19; ] # Lobby data interpreted from the game's protobufs: # https://github.com/SteamRE/SteamKit/blob/master/Resources/Protobufs/dota/dota_gcmessages_common.proto#L824 lobby_type_strings = [ "Public Matchmaking", "Practice Game", "Tournament Game", "Invalid (3)", "Co-op Bot", "Team Matchmaking", "Solo Matchmaking", "Ranked Match" ] # Set default order by __mapper_args__ = {"order_by": [db.desc(added_to_site_time)]} # Object cache _team_players = None # Object cache for team_players so if it's poked before being cached we dont need to call the database for this info. def __init__(self, id=None, replay_state="UNKNOWN", state="WAITING_GC", skip_webapi=False): self.id = id self.replay_state = replay_state self.state = state if not skip_webapi: self._populate_from_webapi() def __repr__(self): return "<Replay {}>".format(self.id) def _populate_from_webapi(self, match_data=None): """ Populates a new replay object with data from WebAPI. """ try: if not match_data: match_data = steam.api.interface( "IDOTA2Match_570").GetMatchDetails( match_id=self.id).get("result") if match_data: self.good_guys_win = match_data.get('radiant_win') self.duration = match_data.get('duration') self.start_time = match_data.get('start_time') self.match_seq_num = match_data.get('match_seq_num') self.radiant_tower_status = match_data.get( 'tower_status_radiant') self.dire_tower_status = match_data.get('tower_status_dire') self.radiant_barracks_status = match_data.get( 'barracks_status_radiant') self.dire_barracks_status = match_data.get( 'barracks_status_dire') self.replay_cluster = match_data.get('cluster') self.first_blood_time = match_data.get('first_blood_time') self.lobby_type = match_data.get('lobby_type') self.human_players = match_data.get('human_players') self.league_id = match_data.get('leagueid') self.game_mode = match_data.get('game_mode') # Team info self.radiant_team_id = match_data.get('radiant_team_id') self.radiant_team_name = match_data.get('radiant_name') self.radiant_team_logo = match_data.get('radiant_logo') self.radiant_team_complete = match_data.get( 'radiant_team_complete') self.dire_team_id = match_data.get('dire_team_id') self.dire_team_name = match_data.get('dire_name') self.dire_team_logo = match_data.get('dire_logo') self.dire_team_complete = match_data.get('dire_team_complete') except steam.api.HTTPError: pass @property def url(self): return "http://replay{}.valve.net/570/{}_{}.dem.bz2".format( self.replay_cluster, self.id, self.replay_salt) @property def lobby_type_string(self): """ Returns a human-friendly string for the replay's lobby type. """ try: return Replay.lobby_type_strings[self.lobby_type] except (IndexError, TypeError): if self.lobby_type: return "Invalid ({})".format(self.lobby_type) else: return "No lobby type specificed" @property def game_mode_string(self): """ Returns a human-friendly string for the replay's game mode. """ try: return Replay.game_mode_strings[self.game_mode] except (IndexError, TypeError): if self.game_mode: return "Invalid ({})".format(self.game_mode) else: return "No game mode specified" @property def team_players(self): """ Returns a tuple (radiant, dire) after splitting the replays players into teams. """ # Sort players by their in-game slot # If we have this cached in the object then serve it. This means we can cache replays and poke # team_players without requiring extra DB calls, as long as team_players was poked pre-cache. if self._team_players: return self._team_players players = sorted(self.players, key=lambda x: x.player_slot) # Split players into teams radiant = [p for p in players if p.team == "Radiant"] # 8th bit false dire = [p for p in players if p.team == "Dire"] # 8th bit true self._team_players = (radiant, dire) return self._team_players @property def region(self): return Region.get_by_cluster(self.replay_cluster) def get_s3_file(self): key = None if self.local_uri: key = dotabank_bucket.get_key(self.local_uri) return key def get_alias(self, formatted=True): if current_user.is_anonymous() is True: return None replay_alias = current_user.replay_aliases_dict.get(self.id) if replay_alias is not None: if formatted: return "\u201C{}\u201D".decode('unicode-escape').format( replay_alias.alias) # Wrap in curly quotes else: return replay_alias.alias return None def get_state(self): """ Returns a descriptive and human-friendly representation of the replay's state. :return: String """ # TODO: Store this in a centralised string table if self.state == "ARCHIVED": return "Archived" elif self.state == "WAITING_GC": return "Waiting for GC" elif self.state == "WAITING_DOWNLOAD": return "Waiting to be archived" elif self.state == "DOWNLOAD_IN_PROGRESS": return "Archiving in progress" elif self.state == "GC_ERROR": return "Private" elif self.state == "DOWNLOAD_ERROR": if self.replay_state == "REPLAY_AVAILABLE": return "Download error" else: return "Expired" # TODO: What is this? def user_rating(self): if current_user.is_authenticated(): return next((rating for rating in self.ratings if rating.user_id == current_user.id), None) else: return None # TODO: What is this? def user_favourite(self): if current_user.is_authenticated(): return next((favourite for favourite in self.favourites if favourite.user_id == current_user.id), False) else: return False @classmethod def get_or_create(cls, **kwargs): # Get instance, filter skip_webapi from kwargs as that's the only non-database argument __init__ can take. instance = cls.query.filter_by( **{k: v for k, v in kwargs.iteritems() if k is not "skip_webapi"}).first() if instance: return instance, False else: instance = cls(**kwargs) return instance, True @staticmethod def add_gc_job(_replay, skip_commit=False): # Reset gc fails _replay.gc_fails = 0 _replay.gc_done_time = None db.session.add(_replay) if not skip_commit: db.session.commit() # Write to SQS msg = sqsMessage() msg.set_body(str(_replay.id)) return sqs_gc_queue.write(msg) @staticmethod def add_dl_job(_replay, skip_commit=False): # Reset dl fails _replay.dl_fails = 0 _replay.dl_done_time = None db.session.add(_replay) if not skip_commit: db.session.commit() # Write to SQS msg = sqsMessage() msg.set_body(str(_replay.id)) return sqs_dl_queue.write(msg)
class Result(db.Model): __tablename__ = 'results' id = db.Column(db.BigInteger(), primary_key=True) url = db.Column(db.String(), nullable=False) entities = db.Column(JSONB())