class RelayStatistic(Base): __tablename__ = 'relay_statistics' relaystat = Column(Integer(unsigned=True), primary_key=True, autoincrement=True) statistic_id = Column( "statistic", Integer(unsigned=True), ForeignKey('statistics.statistic', onupdate="CASCADE", ondelete="RESTRICT")) statistic = relationship("Statistic", cascade="all") relay_id = Column( "relay", Integer(unsigned=True), ForeignKey('relays.relay', onupdate="CASCADE", ondelete="RESTRICT")) relay = relationship("Relay", cascade="all") type = Column(Integer(unsigned=True)) TYPE = ENUM(['TRAFFIC', 'LISTENERCOUNT']) @staticmethod def get_relaystatistic(relay, type): try: return RelayStatistic.query.filter( RelayStatistic.relay == relay, RelayStatistic.type == type).one() except exc.NoResultFound: s = Statistic(name='{0}:{1}-{2}'.format(relay.address, relay.port, type), identifier='{0}:{1}-{2}'.format( relay.address, relay.port, type)) rfk.database.session.add(s) rs = RelayStatistic(relay=relay, type=type, statistic=s) rfk.database.session.add(rs) rfk.database.session.flush() return rs
class UserShow(Base): """connection between users and show""" __tablename__ = 'user_shows' userShow = Column(Integer(unsigned=True), primary_key=True, autoincrement=True) user_id = Column("user", Integer(unsigned=True), ForeignKey('users.user', onupdate="CASCADE", ondelete="CASCADE"), nullable=False) user = relationship("User", backref=backref('shows', cascade="all, delete-orphan")) show_id = Column("show", Integer(unsigned=True), ForeignKey('shows.show', onupdate="CASCADE", ondelete="CASCADE"), nullable=False) show = relationship("Show", backref=backref('users', cascade="all, delete-orphan")) role_id = Column("role", Integer(unsigned=True), ForeignKey('roles.role', onupdate="CASCADE", ondelete="RESTRICT"), nullable=False) role = relationship("Role") status = Column(Integer(unsigned=True), default=0) STATUS = ENUM(['UNKNOWN', 'STREAMING', 'STREAMED'])
class Donation(Base): __tablename__ = 'donations' donation = Column(Integer(unsigned=True), primary_key=True, autoincrement=True) value = Column(String(10), nullable=False) currency = Column(String(10), nullable=False) method = Column(Integer(unsigned=True), nullable=False) reference = Column(String(255)) date = Column(UTCDateTime, default=now, nullable=False) country = Column(String(3)) comment = Column(String(255)) METHOD = ENUM(['BTC', 'MANUAL'])
class StreamRelay(Base): __tablename__ = 'stream_relays' stream_relay = Column(Integer(unsigned=True), primary_key=True, autoincrement=True) stream_id = Column("stream", Integer(unsigned=True), ForeignKey('streams.stream', onupdate="CASCADE", ondelete="RESTRICT")) stream = relationship("Stream", backref=backref('relays', cascade="all, delete-orphan")) relay_id = Column("relay", Integer(unsigned=True), ForeignKey('relays.relay', onupdate="CASCADE", ondelete="RESTRICT")) relay = relationship("Relay", backref=backref('streams', cascade="all, delete-orphan")) status = Column(Integer(unsigned=True)) statistic_id = Column("statistic", Integer(unsigned=True), ForeignKey('statistics.statistic', onupdate="CASCADE", ondelete="RESTRICT")) statistic = relationship("Statistic") STATUS = ENUM(['UNKNOWN', 'DISABLED', 'OFFLINE', 'ONLINE']) def __init__(self, relay=None, stream=None): assert relay or stream self.relay = relay self.stream = stream def set_offline(self): """sets this combination of stream and relay to offline""" self.status = StreamRelay.STATUS.OFFLINE connected_listeners = Listener.query.filter(Listener.stream_relay == self, Listener.disconnect == None).all() for listener in connected_listeners: listener.disconnect = now() def get_statistic(self): if self.statistic is None: stat = Statistic(name='Listeners on SR %s' % (self.stream_relay), identifier='lst-sr-%s' % (self.stream_relay)) rfk.database.session.add(stat) self.statistic = stat rfk.database.session.flush() return self.statistic def get_current_listeners(self): return Listener.query.filter(Listener.stream_relay == self, Listener.disconnect == None).count() def update_statistic(self): stat = self.get_statistic() stat.set(now(), self.get_current_listeners())
class Setting(Base): __tablename__ = 'settings' setting = Column(Integer(unsigned=True), primary_key=True, autoincrement=True) code = Column(String(25), unique=True) name = Column(String(50)) val_type = Column(Integer(unsigned=True)) TYPES = ENUM(['INT', 'STR']) @staticmethod def get_setting(code): return Setting.query.filter(Setting.code == code).one() @staticmethod def add_setting(code, name, val_type): try: return Setting.query.filter(Setting.code == code).one() except exc.NoResultFound: return Setting(code=code, name=name, val_type=val_type)
class Stream(Base): """database representation of an outputStream""" __tablename__ = 'streams' stream = Column(Integer(unsigned=True), primary_key=True, autoincrement=True) mount = Column(String(25)) code = Column(String(25)) name = Column(String(25)) type = Column(Integer(unsigned=True)) quality = Column(Integer) statistic_id = Column("statistic", Integer(unsigned=True), ForeignKey('statistics.statistic', onupdate="CASCADE", ondelete="RESTRICT")) statistic = relationship("Statistic", cascade="all") TYPES = ENUM(['UNKNOWN', 'MP3', 'AACP', 'OGG', 'OPUS']) code_pattern = re.compile('^[0-9A-Za-z_-]+$') @staticmethod def add_stream(code, name, mount, type, quality): try: Stream.query.filter(Stream.mount == mount).one() raise MountpointTakenException() except exc.NoResultFound: pass try: Stream.query.filter(Stream.code == code).one() raise CodeTakenException() except exc.NoResultFound: pass if not Stream.code_pattern.match(code): raise InvalidCodeException() stream = Stream(code=code, name=name, mount=mount, type=type, quality=quality) rfk.database.session.add(stream) rfk.database.session.flush() return stream @staticmethod def get_stream(id=None, mount=None): """returns a Stream by id or mountpoint""" assert id or mount if id: return Stream.query.get(id) else: return Stream.query.filter(Stream.mount == mount).one() def add_relay(self, relay): """adds a Relay to this Stream""" try: StreamRelay.query.filter(StreamRelay.stream == self, StreamRelay.relay == relay).one() return False except exc.NoResultFound: self.relays.append(StreamRelay(relay=relay)) rfk.database.session.flush() return True def get_statistic(self): if self.statistic is None: stat = Statistic(name='Listeners on %s' % (self.code), identifier='lst-%s' % (self.code)) rfk.database.session.add(stat) self.statistic = stat rfk.database.session.flush() return self.statistic def get_current_listeners(self): return Listener.query.join(StreamRelay).filter(StreamRelay.stream == self, Listener.disconnect == None).count() def update_statistic(self): stat = self.get_statistic() stat.set(now(), self.get_current_listeners()) def get_status(self): available = False for sr in self.relays: if sr.status == StreamRelay.STATUS.ONLINE: available = True return available def get_relay(self): relays = Relay.query.join(StreamRelay).filter(StreamRelay.stream == self, StreamRelay.status == StreamRelay.STATUS.ONLINE).all() minload = 2 minrelay = None for relay in relays: if relay.status == Relay.STATUS.ONLINE: load = relay.get_load() if relay.type == Relay.TYPE.MASTER: load = load * 2 if relay.get_load() <= minload: minload = relay.get_load() minrelay = relay return minrelay
class Relay(Base): """database representation of a RelayServer""" __tablename__ = 'relays' relay = Column(Integer(unsigned=True), primary_key=True, autoincrement=True) address = Column(String(50)) port = Column(Integer(unsigned=True)) flag = Column(Integer(unsigned=True)) bandwidth = Column(Integer(unsigned=True)) usage = Column(Integer(unsigned=True)) admin_username = Column(String(50)) admin_password = Column(String(50)) auth_username = Column(String(50)) auth_password = Column(String(50)) relay_username = Column(String(50)) relay_password = Column(String(50)) type = Column(Integer(unsigned=True)) status = Column(Integer(unsigned=True), default=0) statistic_id = Column("statistic", Integer(unsigned=True), ForeignKey('statistics.statistic', onupdate="CASCADE", ondelete="RESTRICT")) statistic = relationship("Statistic", cascade="all") STATUS = ENUM(['UNKNOWN', 'DISABLED', 'OFFLINE', 'ONLINE']) TYPE = ENUM(['MASTER', 'RELAY']) @staticmethod def add_relay(address, port, bandwidth, admin_username, admin_password, auth_username, auth_password, relay_username, relay_password, type): try: Relay.query.filter(Relay.address == address, Relay.port == port).one() raise AddressTakenException() except exc.NoResultFound: pass relay = Relay(address=address, port=port, bandwidth=bandwidth, admin_username=admin_username, admin_password=admin_password, auth_username=auth_username, auth_password=auth_password, relay_username=relay_username, relay_password=relay_password, type=type) rfk.database.session.add(relay) rfk.database.session.flush() return relay @staticmethod def get_master(): """returns the master server""" return Relay.query.filter(Relay.type == Relay.TYPE.MASTER).one() @staticmethod def get_relay(id=None, address=None, port=None): """returns a Relay either by id or by address and port""" assert id or (address and port) if id: return Relay.query.get(id) else: return Relay.query.filter(Relay.address == address, Relay.port == port).one() def get_icecast_config(self, all_streams=False): """returns the configuration XML for this Relay""" conf = rfk.icecast.IcecastConfig() conf.address = self.address conf.port = self.port conf.admin = self.admin_username conf.password = self.admin_password conf.hostname = self.address api_url = "http://%s%s" % (CONFIG.get('site', 'url'), '/backend/icecast/') if all_streams: for stream in Stream.query.all(): mount = rfk.icecast.Mount() mount.api_url = api_url mount.mount = stream.mount mount.username = self.auth_username mount.password = self.auth_password conf.mounts.append(mount) else: for stream in self.streams: mount = rfk.icecast.Mount() mount.api_url = api_url mount.mount = stream.stream.mount mount.username = self.auth_username mount.password = self.auth_password conf.mounts.append(mount) if self.type == Relay.TYPE.RELAY: master = Relay.get_master() conf.master = master.address conf.master_user = master.relay_username conf.master_password = master.relay_password conf.master_port = master.port elif self.type == Relay.TYPE.MASTER: conf.relay_user = self.relay_username conf.relay_password = self.relay_password return conf.get_xml() def add_stream(self, stream): """adds a Stream to this Relay""" try: return StreamRelay.query.filter(StreamRelay.relay == self, StreamRelay.stream == stream).one() except exc.NoResultFound: return self.streams.append(StreamRelay(stream=stream)) def get_stream_relay(self, stream): """returns the StreamRelay combination for the given Stream and this Relay""" return StreamRelay.query.filter(StreamRelay.relay == self, StreamRelay.stream == stream).one() def get_statistic(self): if self.statistic is None: stat = Statistic(name='Listeners on %s:%s' % (self.address, self.port), identifier='lst-%s:%s' % (self.address, self.port)) rfk.database.session.add(stat) self.statistic = stat rfk.database.session.flush() return self.statistic def get_current_listeners(self): return Listener.query.join(StreamRelay).filter(StreamRelay.relay == self, Listener.disconnect == None).count() def update_statistic(self): stat = self.get_statistic() stat.set(now(), self.get_current_listeners()) def get_load(self): try: return self.usage / float(self.bandwidth) except TypeError: return 0