Beispiel #1
0
class FavouriteItem(TracklistItemMixin, Base):

    __acl__ = (Allow(
        Parent, Create,
        Fields('favourite_id', 'favourite_provider_id', 'account_id',
               'account_provider_id', 'track_id', 'track_provider_id')),
               Allow(Owner, Read, Fields('id', 'track_id',
                                         'track_provider_id')),
               Allow(Owner, Delete), Allow(Parent, Query, Fields('favourite')))
    __table_args__ = (sql.PrimaryKeyConstraint('id'),
                      sql.ForeignKeyConstraint(
                          ['favourite_provider_id', 'favourite_id'],
                          ['favourite.provider_id', 'favourite.id']),
                      sql.ForeignKeyConstraint(
                          ['account_id', 'account_provider_id'],
                          ['account.id', 'account.provider_id']),
                      sql.ForeignKeyConstraint(['track_provider_id'],
                                               ['provider.id']))

    provider_id = orm.synonym('favourite_provider_id')

    favourite_id = sql.Column(sql.String(96), nullable=False)
    favourite_provider_id = sql.Column(sql.String(16), nullable=False)
    favourite = orm.relation('Favourite', back_populates='items')
    parent = orm.synonym('favourite')
Beispiel #2
0
class Session(Base):

    __acl__ = (
        Allow(Owner, Create, Fields(
            'account_id',
            'account_provider_id',
            'system',
            'browser',
            'screen'
        )),
        Allow(Owner, Read, Fields()),
        Deny()
    )
    __table_args__ = (
        sql.PrimaryKeyConstraint(
            'id'),
        sql.ForeignKeyConstraint(
            ['account_id', 'account_provider_id'],
            ['account.id', 'account.provider_id'])
    )

    id = sql.Column(sql.String(64), default=functools.partial(gen_token, 64))

    account_id = sql.Column(sql.String(32), nullable=False)
    account_provider_id = sql.Column(sql.String(16), nullable=False)
    account = orm.relation(
        'Account',
        back_populates='sessions',
        uselist=False,
        single_parent=True)
    parent = orm.synonym('account')

    system = sql.Column(sql.String(64), nullable=False)
    browser = sql.Column(sql.String(64), nullable=False)
    screen = sql.Column(sql.String(32), nullable=False)
Beispiel #3
0
class Token(Base):

    __acl__ = (
        Allow(Everyone, Create, Fields()),
        Allow(Everyone, Read, Fields(
            'id',
            'claimed'
        )),
        Allow(Everyone, Update, Fields(
            'claimed',
            'account_id',
            'account_provider_id'
        ))
    )
    __table_args__ = (
        sql.PrimaryKeyConstraint(
            'id'),
        sql.ForeignKeyConstraint(
            ['account_id', 'account_provider_id'],
            ['account.id', 'account.provider_id'])
    )

    id = sql.Column(sql.String(16), default=functools.partial(gen_token, 6))

    claimed = sql.Column(sql.Boolean, default=False)

    account_provider_id = sql.Column(sql.String(16))
    account_id = sql.Column(sql.String(32))
    account = orm.relation(
        'Account',
        single_parent=True)
    parent = orm.synonym('account')
Beispiel #4
0
class Provider(Base):

    __acl__ = (Allow(Everyone, Read, Fields('id', 'client_id')),
               Allow(Everyone, Query, Fields('id')))
    __table_args__ = (sql.PrimaryKeyConstraint('id'), )

    id = sql.Column(sql.String(12))

    provider_id = orm.synonym('id')

    @property
    def client_id(self):
        if self.id in opt.options['providers']:
            return opt.options[self.id]['api_key']
Beispiel #5
0
class Image(Base):

    __acl__ = (Allow(
        Everyone, Read,
        Fields('id', 'small', 'medium', 'large', 'created',
               'updated')), Deny())
    __table_args__ = (sql.PrimaryKeyConstraint('id'), )

    id = sql.Column(sql.Integer)
    small = sql.Column(sql.String(256))
    medium = sql.Column(sql.String(256))
    large = sql.Column(sql.String(256), nullable=False)

    def copy(self):
        return Image(small=self.small, medium=self.medium, large=self.large)

    @classmethod
    def from_soundcloud(cls, url):
        if isinstance(url, str):
            return cls(small=url,
                       medium=url.replace('large', 't300x300'),
                       large=url.replace('large', 't500x500'))

    @classmethod
    def from_youtube(cls, thumbnails):
        if isinstance(thumbnails, dict):
            return cls(small=thumbnails.get('default', {}).get('url'),
                       medium=thumbnails.get('medium', {}).get('url'),
                       large=thumbnails.get('high', {}).get('url'))
Beispiel #6
0
class TrackComment(Transient):

    __acl__ = (
        Allow(Everyone, Read, Fields(
            'id',
            'provider_id',
            'account.id',
            'account.provider_id',
            'account.title',
            'account.image.small',
            'account.image.medium',
            'account.image.large',
            'body',
            'timestamp',
            'track_id',
            'track_provider_id',
            'created'
        )),
    )

    id = None
    provider_id = None

    account = None

    body = None
    timestamp = None
    track_id = None
    track_provider_id = None
Beispiel #7
0
class Favourite(TracklistMixin, Base):

    __acl__ = (Allow(
        Owner, Read,
        Fields('id', 'provider_id', 'account_id', 'account_provider_id')), )

    account = orm.relation('Account',
                           back_populates='favourite',
                           viewonly=True)

    items = orm.relation('FavouriteItem',
                         cascade='all, delete-orphan',
                         order_by='FavouriteItem.created',
                         single_parent=True)
Beispiel #8
0
class Image(Base):

    __acl__ = (Allow(
        Everyone, Read,
        Fields('id', 'small', 'medium', 'large', 'created',
               'updated')), Deny())
    __table_args__ = (sql.PrimaryKeyConstraint('id'), )

    id = sql.Column(sql.Integer)
    small = sql.Column(sql.String(256))
    medium = sql.Column(sql.String(256))
    large = sql.Column(sql.String(256), nullable=False)

    def copy(self):
        return Image(small=self.small, medium=self.medium, large=self.large)
Beispiel #9
0
class User(Base):

    __acl__ = (Allow(
        Child, Read,
        Fields('id', 'provider_id', 'accounts.id', 'accounts.provider_id',
               'accounts.connected', 'accounts.favourite_id',
               'accounts.image.id', 'accounts.image.small',
               'accounts.image.medium', 'accounts.image.large',
               'accounts.title', 'created', 'updated')), )
    __table_args__ = (sql.PrimaryKeyConstraint('id'), )

    id = sql.Column(sql.Integer)
    provider_id = 'cloudplayer'

    accounts = orm.relation('Account',
                            back_populates='user',
                            uselist=True,
                            single_parent=True,
                            cascade='all, delete-orphan')
    children = orm.synonym('accounts')
Beispiel #10
0
class Track(Transient):

    __acl__ = (Allow(
        Everyone, Read,
        Fields('id', 'provider_id', 'account.id', 'account.provider_id',
               'account.title', 'account.image.small', 'account.image.medium',
               'account.image.large', 'aspect_ratio', 'duration',
               'favourite_count', 'image.small', 'image.medium', 'image.large',
               'play_count', 'title', 'created')), )

    id = None
    provider_id = None

    account = None

    aspect_ratio = None
    duration = None
    favourite_count = None
    image = None
    play_count = None
    title = None
Beispiel #11
0
class Playlist(TracklistMixin, Base):

    __acl__ = (
        Allow(Owner, Create, Fields(
            'provider_id',
            'account_id',
            'account_provider_id',
            'description',
            'public',
            'title'
        )),
        Allow(Owner, Read, Fields(
            'id',
            'provider_id',
            'account_id',
            'account_provider_id',
            'description',
            'follower_count',
            'image.id',
            'image.small',
            'image.medium',
            'image.large',
            'public',
            'title',
            'created',
            'updated'
        )),
        Allow(Owner, Update, Fields(
            'description',
            'public',
            'title'
        )),
        Allow(Owner, Delete),
        Allow(Owner, Query, Fields(
            'id',
            'provider_id',
            'account_id',
            'account_provider_id'
        )),
        Deny()
    )
    __channel__ = (
        'playlist.{provider_id}.{id}',
    )
    __fields__ = (
        'id',
        'provider_id',
        'account_id',
        'account_provider_id',
        'description',
        'follower_count',
        'image.id',
        'image.small',
        'image.medium',
        'image.large',
        'public',
        'title',
        'created',
        'updated'
    )

    @declared_attr
    def __table_args__(cls):
        return super().__table_args__ + (
            sql.ForeignKeyConstraint(
                ['image_id'],
                ['image.id']),
        )

    account = orm.relation(
        'Account',
        back_populates='playlists',
        cascade='all',
        viewonly=True)
    parent = orm.synonym('account')

    items = orm.relation(
        'PlaylistItem',
        cascade='all, delete-orphan',
        order_by='PlaylistItem.rank',
        single_parent=True)

    description = sql.Column(sql.Unicode(5120), nullable=True)
    follower_count = sql.Column(sql.Integer, default=0)
    public = sql.Column(sql.Boolean, default=False)
    title = sql.Column(sql.Unicode(256), nullable=False)

    image_id = sql.Column(sql.Integer)
    image = orm.relation(
        'Image',
        cascade='all, delete-orphan',
        single_parent=True,
        uselist=False)
Beispiel #12
0
class Track(Transient):

    __acl__ = (
        Allow(Everyone, Read, Fields(
            'id',
            'provider_id',
            'account.id',
            'account.provider_id',
            'account.title',
            'account.image.small',
            'account.image.medium',
            'account.image.large',
            'aspect_ratio',
            'duration',
            'favourite_count',
            'image.small',
            'image.medium',
            'image.large',
            'play_count',
            'title',
            'created'
        )),
    )

    id = None
    provider_id = None

    account = None

    aspect_ratio = None
    duration = None
    favourite_count = None
    image = None
    play_count = None
    title = None

    @classmethod
    def from_provider(cls, provider_id, track):
        if provider_id == 'soundcloud':
            return cls.from_soundcloud(track)
        elif provider_id == 'youtube':
            return cls.from_youtube(track)
        else:
            raise ValueError('unsupported provider')

    @classmethod
    def from_soundcloud(cls, track):
        user = track['user']
        artist = Account(
            id=user['id'],
            provider_id='soundcloud',
            title=user['username'],
            image=Image.from_soundcloud(user.get('avatar_url')))

        return cls(
            id=track['id'],
            provider_id='soundcloud',
            account=artist,
            aspect_ratio=1.0,
            duration=int(track['duration'] / 1000.0),
            favourite_count=track.get('favoritings_count', 0),
            image=Image.from_soundcloud(track.get('artwork_url')),
            play_count=track.get('playback_count', 0),
            title=track['title'],
            created=datetime.datetime.strptime(
                track['created_at'], '%Y/%m/%d %H:%M:%S %z'))

    @classmethod
    def from_youtube(cls, track):
        snippet = track['snippet']
        player = track['player']
        statistics = track['statistics']
        duration = isodate.parse_duration(track['contentDetails']['duration'])

        artist = Account(
            id=snippet['channelId'],
            provider_id='youtube',
            image=None,
            title=snippet['channelTitle'])

        return cls(
            id=track['id'],
            provider_id='youtube',
            account=artist,
            aspect_ratio=(
                float(player['embedHeight']) / float(player['embedWidth'])),
            duration=int(duration.total_seconds()),
            favourite_count=statistics.get('likeCount', 0),
            image=Image.from_youtube(snippet.get('thumbnails')),
            play_count=statistics.get('viewCount', 0),
            title=snippet['title'],
            created=datetime.datetime.strptime(
                snippet['publishedAt'], '%Y-%m-%dT%H:%M:%S.%fZ'))
Beispiel #13
0
class Account(Base):

    __acl__ = (Allow(
        Owner, Read,
        Fields('id', 'provider_id', 'user_id', 'connected', 'favourite_id',
               'image.id', 'image.small', 'image.medium', 'image.large',
               'title', 'created', 'updated')),
               Allow(Owner, Update, Fields('image', 'title')),
               Allow(
                   Everyone, Read,
                   Fields('id', 'provider_id', 'image.id', 'image.small',
                          'image.medium', 'image.large', 'title')),
               Allow(Everyone, Query, Fields('id', 'provider_id',
                                             'title')), Deny())
    __fields__ = ('id', 'provider_id', 'user_id', 'connected', 'favourite_id',
                  'image_id', 'title', 'created', 'updated')
    __channel__ = ('account.{provider_id}.{id}', )
    __table_args__ = (sql.PrimaryKeyConstraint('id', 'provider_id'),
                      sql.ForeignKeyConstraint(['provider_id'],
                                               ['provider.id']),
                      sql.ForeignKeyConstraint(['user_id'], ['user.id']),
                      sql.ForeignKeyConstraint(['image_id'], ['image.id']))

    id = sql.Column(sql.String(32))
    account_id = orm.synonym('id')

    provider_id = sql.Column(sql.String(16), nullable=False)
    provider = orm.relation('Provider',
                            cascade=None,
                            uselist=False,
                            viewonly=True)
    account_provider_id = orm.synonym('provider_id')

    user_id = sql.Column(sql.Integer, nullable=False)
    user = orm.relation('User',
                        back_populates='accounts',
                        uselist=False,
                        viewonly=True)
    parent = orm.synonym('user')

    sessions = orm.relation('Session',
                            back_populates='account',
                            cascade='all, delete-orphan',
                            single_parent=True,
                            uselist=True)

    image_id = sql.Column(sql.Integer)
    image = orm.relation('Image',
                         cascade='all, delete-orphan',
                         single_parent=True,
                         uselist=False)

    @property
    def favourite_id(self):
        if self.favourite:
            return self.favourite.id

    favourite = orm.relation('Favourite',
                             back_populates='account',
                             cascade='all, delete-orphan',
                             single_parent=True,
                             uselist=False)

    playlists = orm.relation('Playlist',
                             back_populates='account',
                             cascade='all, delete-orphan',
                             single_parent=True,
                             uselist=True)

    title = sql.Column('title', sql.Unicode(64))

    access_token = sql.Column(sql.String(256))
    refresh_token = sql.Column(sql.String(256))
    token_expiration = sql.Column(sql.DateTime())

    @property
    def connected(self):
        return self.provider_id == 'cloudplayer' or all(
            [self.access_token, self.refresh_token])