Format code using black
This commit is contained in:
parent
efe4fa027e
commit
c27f020d73
85 changed files with 3238 additions and 2243 deletions
|
@ -2,7 +2,8 @@
|
|||
from django.apps import AppConfig
|
||||
from django.db.models.signals import pre_save
|
||||
|
||||
|
||||
class LibreTimeAPIConfig(AppConfig):
|
||||
name = 'libretimeapi'
|
||||
verbose_name = 'LibreTime API'
|
||||
default_auto_field = 'django.db.models.AutoField'
|
||||
name = "libretimeapi"
|
||||
verbose_name = "LibreTime API"
|
||||
default_auto_field = "django.db.models.AutoField"
|
||||
|
|
|
@ -1,21 +1,23 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from django.contrib.auth.models import BaseUserManager
|
||||
|
||||
|
||||
class UserManager(BaseUserManager):
|
||||
def create_user(self, username, type, email, first_name, last_name, password):
|
||||
user = self.model(username=username,
|
||||
type=type,
|
||||
email=email,
|
||||
first_name=first_name,
|
||||
last_name=last_name)
|
||||
user = self.model(
|
||||
username=username,
|
||||
type=type,
|
||||
email=email,
|
||||
first_name=first_name,
|
||||
last_name=last_name,
|
||||
)
|
||||
user.set_password(password)
|
||||
user.save(using=self._db)
|
||||
return user
|
||||
|
||||
def create_superuser(self, username, email, first_name, last_name, password):
|
||||
user = self.create_user(username, 'A', email, first_name, last_name, password)
|
||||
user = self.create_user(username, "A", email, first_name, last_name, password)
|
||||
return user
|
||||
|
||||
def get_by_natural_key(self, username):
|
||||
return self.get(username=username)
|
||||
|
||||
|
|
|
@ -15,18 +15,20 @@ class LoginAttempt(models.Model):
|
|||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cc_login_attempts'
|
||||
db_table = "cc_login_attempts"
|
||||
|
||||
|
||||
class Session(models.Model):
|
||||
sessid = models.CharField(primary_key=True, max_length=32)
|
||||
userid = models.ForeignKey('User', models.DO_NOTHING, db_column='userid', blank=True, null=True)
|
||||
userid = models.ForeignKey(
|
||||
"User", models.DO_NOTHING, db_column="userid", blank=True, null=True
|
||||
)
|
||||
login = models.CharField(max_length=255, blank=True, null=True)
|
||||
ts = models.DateTimeField(blank=True, null=True)
|
||||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cc_sess'
|
||||
db_table = "cc_sess"
|
||||
|
||||
|
||||
USER_TYPE_CHOICES = ()
|
||||
|
@ -35,12 +37,14 @@ for item in USER_TYPES.items():
|
|||
|
||||
|
||||
class User(AbstractBaseUser):
|
||||
username = models.CharField(db_column='login', unique=True, max_length=255)
|
||||
password = models.CharField(db_column='pass', max_length=255) # Field renamed because it was a Python reserved word.
|
||||
username = models.CharField(db_column="login", unique=True, max_length=255)
|
||||
password = models.CharField(
|
||||
db_column="pass", max_length=255
|
||||
) # Field renamed because it was a Python reserved word.
|
||||
type = models.CharField(max_length=1, choices=USER_TYPE_CHOICES)
|
||||
first_name = models.CharField(max_length=255)
|
||||
last_name = models.CharField(max_length=255)
|
||||
last_login = models.DateTimeField(db_column='lastlogin', blank=True, null=True)
|
||||
last_login = models.DateTimeField(db_column="lastlogin", blank=True, null=True)
|
||||
lastfail = models.DateTimeField(blank=True, null=True)
|
||||
skype_contact = models.CharField(max_length=1024, blank=True, null=True)
|
||||
jabber_contact = models.CharField(max_length=1024, blank=True, null=True)
|
||||
|
@ -48,13 +52,13 @@ class User(AbstractBaseUser):
|
|||
cell_phone = models.CharField(max_length=1024, blank=True, null=True)
|
||||
login_attempts = models.IntegerField(blank=True, null=True)
|
||||
|
||||
USERNAME_FIELD = 'username'
|
||||
EMAIL_FIELD = 'email'
|
||||
REQUIRED_FIELDS = ['type', 'email', 'first_name', 'last_name']
|
||||
USERNAME_FIELD = "username"
|
||||
EMAIL_FIELD = "email"
|
||||
REQUIRED_FIELDS = ["type", "email", "first_name", "last_name"]
|
||||
objects = UserManager()
|
||||
|
||||
def get_full_name(self):
|
||||
return '{} {}'.format(self.first_name, self.last_name)
|
||||
return "{} {}".format(self.first_name, self.last_name)
|
||||
|
||||
def get_short_name(self):
|
||||
return self.first_name
|
||||
|
@ -66,7 +70,7 @@ class User(AbstractBaseUser):
|
|||
self.password = hashlib.md5(password.encode()).hexdigest()
|
||||
|
||||
def is_staff(self):
|
||||
print('is_staff')
|
||||
print("is_staff")
|
||||
return self.type == ADMIN
|
||||
|
||||
def check_password(self, password):
|
||||
|
@ -82,6 +86,7 @@ class User(AbstractBaseUser):
|
|||
(managed = True), then this can be replaced with
|
||||
django.contrib.auth.models.PermissionMixin.
|
||||
"""
|
||||
|
||||
def is_superuser(self):
|
||||
return self.type == ADMIN
|
||||
|
||||
|
@ -125,7 +130,7 @@ class User(AbstractBaseUser):
|
|||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cc_subjs'
|
||||
db_table = "cc_subjs"
|
||||
|
||||
|
||||
class UserToken(models.Model):
|
||||
|
@ -139,4 +144,4 @@ class UserToken(models.Model):
|
|||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cc_subjs_token'
|
||||
db_table = "cc_subjs_token"
|
||||
|
|
|
@ -4,11 +4,13 @@ from django.db import models
|
|||
|
||||
class CeleryTask(models.Model):
|
||||
task_id = models.CharField(max_length=256)
|
||||
track_reference = models.ForeignKey('ThirdPartyTrackReference', models.DO_NOTHING, db_column='track_reference')
|
||||
track_reference = models.ForeignKey(
|
||||
"ThirdPartyTrackReference", models.DO_NOTHING, db_column="track_reference"
|
||||
)
|
||||
name = models.CharField(max_length=256, blank=True, null=True)
|
||||
dispatch_time = models.DateTimeField(blank=True, null=True)
|
||||
status = models.CharField(max_length=256)
|
||||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'celery_tasks'
|
||||
db_table = "celery_tasks"
|
||||
|
|
|
@ -8,5 +8,4 @@ class Country(models.Model):
|
|||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cc_country'
|
||||
|
||||
db_table = "cc_country"
|
||||
|
|
|
@ -6,11 +6,20 @@ class File(models.Model):
|
|||
name = models.CharField(max_length=255)
|
||||
mime = models.CharField(max_length=255)
|
||||
ftype = models.CharField(max_length=128)
|
||||
directory = models.ForeignKey('MusicDir', models.DO_NOTHING, db_column='directory', blank=True, null=True)
|
||||
directory = models.ForeignKey(
|
||||
"MusicDir", models.DO_NOTHING, db_column="directory", blank=True, null=True
|
||||
)
|
||||
filepath = models.TextField(blank=True, null=True)
|
||||
import_status = models.IntegerField()
|
||||
currently_accessing = models.IntegerField(db_column='currentlyaccessing')
|
||||
edited_by = models.ForeignKey('User', models.DO_NOTHING, db_column='editedby', blank=True, null=True, related_name='edited_files')
|
||||
currently_accessing = models.IntegerField(db_column="currentlyaccessing")
|
||||
edited_by = models.ForeignKey(
|
||||
"User",
|
||||
models.DO_NOTHING,
|
||||
db_column="editedby",
|
||||
blank=True,
|
||||
null=True,
|
||||
related_name="edited_files",
|
||||
)
|
||||
mtime = models.DateTimeField(blank=True, null=True)
|
||||
utime = models.DateTimeField(blank=True, null=True)
|
||||
lptime = models.DateTimeField(blank=True, null=True)
|
||||
|
@ -59,8 +68,10 @@ class File(models.Model):
|
|||
contributor = models.CharField(max_length=512, blank=True, null=True)
|
||||
language = models.CharField(max_length=512, blank=True, null=True)
|
||||
file_exists = models.BooleanField(blank=True, null=True)
|
||||
replay_gain = models.DecimalField(max_digits=8, decimal_places=2, blank=True, null=True)
|
||||
owner = models.ForeignKey('User', models.DO_NOTHING, blank=True, null=True)
|
||||
replay_gain = models.DecimalField(
|
||||
max_digits=8, decimal_places=2, blank=True, null=True
|
||||
)
|
||||
owner = models.ForeignKey("User", models.DO_NOTHING, blank=True, null=True)
|
||||
cuein = models.DurationField(blank=True, null=True)
|
||||
cueout = models.DurationField(blank=True, null=True)
|
||||
silan_check = models.BooleanField(blank=True, null=True)
|
||||
|
@ -77,10 +88,10 @@ class File(models.Model):
|
|||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cc_files'
|
||||
db_table = "cc_files"
|
||||
permissions = [
|
||||
('change_own_file', 'Change the files where they are the owner'),
|
||||
('delete_own_file', 'Delete the files where they are the owner'),
|
||||
("change_own_file", "Change the files where they are the owner"),
|
||||
("delete_own_file", "Delete the files where they are the owner"),
|
||||
]
|
||||
|
||||
|
||||
|
@ -92,15 +103,16 @@ class MusicDir(models.Model):
|
|||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cc_music_dirs'
|
||||
db_table = "cc_music_dirs"
|
||||
|
||||
|
||||
class CloudFile(models.Model):
|
||||
storage_backend = models.CharField(max_length=512)
|
||||
resource_id = models.TextField()
|
||||
filename = models.ForeignKey(File, models.DO_NOTHING, blank=True, null=True,
|
||||
db_column='cc_file_id')
|
||||
filename = models.ForeignKey(
|
||||
File, models.DO_NOTHING, blank=True, null=True, db_column="cc_file_id"
|
||||
)
|
||||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cloud_file'
|
||||
db_table = "cloud_file"
|
||||
|
|
|
@ -8,7 +8,7 @@ class Playlist(models.Model):
|
|||
name = models.CharField(max_length=255)
|
||||
mtime = models.DateTimeField(blank=True, null=True)
|
||||
utime = models.DateTimeField(blank=True, null=True)
|
||||
creator = models.ForeignKey('User', models.DO_NOTHING, blank=True, null=True)
|
||||
creator = models.ForeignKey("User", models.DO_NOTHING, blank=True, null=True)
|
||||
description = models.CharField(max_length=512, blank=True, null=True)
|
||||
length = models.DurationField(blank=True, null=True)
|
||||
|
||||
|
@ -17,7 +17,7 @@ class Playlist(models.Model):
|
|||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cc_playlist'
|
||||
db_table = "cc_playlist"
|
||||
|
||||
|
||||
class PlaylistContent(models.Model):
|
||||
|
@ -39,4 +39,4 @@ class PlaylistContent(models.Model):
|
|||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cc_playlistcontents'
|
||||
db_table = "cc_playlistcontents"
|
||||
|
|
|
@ -4,13 +4,13 @@ from .files import File
|
|||
|
||||
|
||||
class ListenerCount(models.Model):
|
||||
timestamp = models.ForeignKey('Timestamp', models.DO_NOTHING)
|
||||
mount_name = models.ForeignKey('MountName', models.DO_NOTHING)
|
||||
timestamp = models.ForeignKey("Timestamp", models.DO_NOTHING)
|
||||
mount_name = models.ForeignKey("MountName", models.DO_NOTHING)
|
||||
listener_count = models.IntegerField()
|
||||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cc_listener_count'
|
||||
db_table = "cc_listener_count"
|
||||
|
||||
|
||||
class LiveLog(models.Model):
|
||||
|
@ -20,18 +20,20 @@ class LiveLog(models.Model):
|
|||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cc_live_log'
|
||||
db_table = "cc_live_log"
|
||||
|
||||
|
||||
class PlayoutHistory(models.Model):
|
||||
file = models.ForeignKey(File, models.DO_NOTHING, blank=True, null=True)
|
||||
starts = models.DateTimeField()
|
||||
ends = models.DateTimeField(blank=True, null=True)
|
||||
instance = models.ForeignKey('ShowInstance', models.DO_NOTHING, blank=True, null=True)
|
||||
instance = models.ForeignKey(
|
||||
"ShowInstance", models.DO_NOTHING, blank=True, null=True
|
||||
)
|
||||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cc_playout_history'
|
||||
db_table = "cc_playout_history"
|
||||
|
||||
|
||||
class PlayoutHistoryMetadata(models.Model):
|
||||
|
@ -41,7 +43,7 @@ class PlayoutHistoryMetadata(models.Model):
|
|||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cc_playout_history_metadata'
|
||||
db_table = "cc_playout_history_metadata"
|
||||
|
||||
|
||||
class PlayoutHistoryTemplate(models.Model):
|
||||
|
@ -50,7 +52,7 @@ class PlayoutHistoryTemplate(models.Model):
|
|||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cc_playout_history_template'
|
||||
db_table = "cc_playout_history_template"
|
||||
|
||||
|
||||
class PlayoutHistoryTemplateField(models.Model):
|
||||
|
@ -63,7 +65,7 @@ class PlayoutHistoryTemplateField(models.Model):
|
|||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cc_playout_history_template_field'
|
||||
db_table = "cc_playout_history_template_field"
|
||||
|
||||
|
||||
class Timestamp(models.Model):
|
||||
|
@ -71,4 +73,4 @@ class Timestamp(models.Model):
|
|||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cc_timestamp'
|
||||
db_table = "cc_timestamp"
|
||||
|
|
|
@ -8,14 +8,14 @@ class ImportedPodcast(models.Model):
|
|||
auto_ingest = models.BooleanField()
|
||||
auto_ingest_timestamp = models.DateTimeField(blank=True, null=True)
|
||||
album_override = models.BooleanField()
|
||||
podcast = models.ForeignKey('Podcast', models.DO_NOTHING)
|
||||
podcast = models.ForeignKey("Podcast", models.DO_NOTHING)
|
||||
|
||||
def get_owner(self):
|
||||
return self.podcast.owner
|
||||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'imported_podcast'
|
||||
db_table = "imported_podcast"
|
||||
|
||||
|
||||
class Podcast(models.Model):
|
||||
|
@ -32,17 +32,19 @@ class Podcast(models.Model):
|
|||
itunes_subtitle = models.CharField(max_length=4096, blank=True, null=True)
|
||||
itunes_category = models.CharField(max_length=4096, blank=True, null=True)
|
||||
itunes_explicit = models.CharField(max_length=4096, blank=True, null=True)
|
||||
owner = models.ForeignKey(User, models.DO_NOTHING, db_column='owner', blank=True, null=True)
|
||||
owner = models.ForeignKey(
|
||||
User, models.DO_NOTHING, db_column="owner", blank=True, null=True
|
||||
)
|
||||
|
||||
def get_owner(self):
|
||||
return self.owner
|
||||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'podcast'
|
||||
db_table = "podcast"
|
||||
permissions = [
|
||||
('change_own_podcast', 'Change the podcasts where they are the owner'),
|
||||
('delete_own_podcast', 'Delete the podcasts where they are the owner'),
|
||||
("change_own_podcast", "Change the podcasts where they are the owner"),
|
||||
("delete_own_podcast", "Delete the podcasts where they are the owner"),
|
||||
]
|
||||
|
||||
|
||||
|
@ -60,10 +62,16 @@ class PodcastEpisode(models.Model):
|
|||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'podcast_episodes'
|
||||
db_table = "podcast_episodes"
|
||||
permissions = [
|
||||
('change_own_podcastepisode', 'Change the episodes of podcasts where they are the owner'),
|
||||
('delete_own_podcastepisode', 'Delete the episodes of podcasts where they are the owner'),
|
||||
(
|
||||
"change_own_podcastepisode",
|
||||
"Change the episodes of podcasts where they are the owner",
|
||||
),
|
||||
(
|
||||
"delete_own_podcastepisode",
|
||||
"Delete the episodes of podcasts where they are the owner",
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
|
@ -75,4 +83,4 @@ class StationPodcast(models.Model):
|
|||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'station_podcast'
|
||||
db_table = "station_podcast"
|
||||
|
|
|
@ -3,14 +3,16 @@ from django.db import models
|
|||
|
||||
|
||||
class Preference(models.Model):
|
||||
subjid = models.ForeignKey('User', models.DO_NOTHING, db_column='subjid', blank=True, null=True)
|
||||
subjid = models.ForeignKey(
|
||||
"User", models.DO_NOTHING, db_column="subjid", blank=True, null=True
|
||||
)
|
||||
keystr = models.CharField(unique=True, max_length=255, blank=True, null=True)
|
||||
valstr = models.TextField(blank=True, null=True)
|
||||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cc_pref'
|
||||
unique_together = (('subjid', 'keystr'),)
|
||||
db_table = "cc_pref"
|
||||
unique_together = (("subjid", "keystr"),)
|
||||
|
||||
|
||||
class MountName(models.Model):
|
||||
|
@ -18,7 +20,7 @@ class MountName(models.Model):
|
|||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cc_mount_name'
|
||||
db_table = "cc_mount_name"
|
||||
|
||||
|
||||
class StreamSetting(models.Model):
|
||||
|
@ -28,4 +30,4 @@ class StreamSetting(models.Model):
|
|||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cc_stream_setting'
|
||||
db_table = "cc_stream_setting"
|
||||
|
|
|
@ -7,14 +7,14 @@ class Schedule(models.Model):
|
|||
starts = models.DateTimeField()
|
||||
ends = models.DateTimeField()
|
||||
file = models.ForeignKey(File, models.DO_NOTHING, blank=True, null=True)
|
||||
stream = models.ForeignKey('Webstream', models.DO_NOTHING, blank=True, null=True)
|
||||
stream = models.ForeignKey("Webstream", models.DO_NOTHING, blank=True, null=True)
|
||||
clip_length = models.DurationField(blank=True, null=True)
|
||||
fade_in = models.TimeField(blank=True, null=True)
|
||||
fade_out = models.TimeField(blank=True, null=True)
|
||||
cue_in = models.DurationField()
|
||||
cue_out = models.DurationField()
|
||||
media_item_played = models.BooleanField(blank=True, null=True)
|
||||
instance = models.ForeignKey('ShowInstance', models.DO_NOTHING)
|
||||
instance = models.ForeignKey("ShowInstance", models.DO_NOTHING)
|
||||
playout_status = models.SmallIntegerField()
|
||||
broadcasted = models.SmallIntegerField()
|
||||
position = models.IntegerField()
|
||||
|
@ -24,8 +24,8 @@ class Schedule(models.Model):
|
|||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cc_schedule'
|
||||
db_table = "cc_schedule"
|
||||
permissions = [
|
||||
('change_own_schedule', 'Change the content on their shows'),
|
||||
('delete_own_schedule', 'Delete the content on their shows'),
|
||||
("change_own_schedule", "Change the content on their shows"),
|
||||
("delete_own_schedule", "Delete the content on their shows"),
|
||||
]
|
||||
|
|
|
@ -8,5 +8,4 @@ class ServiceRegister(models.Model):
|
|||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cc_service_register'
|
||||
|
||||
db_table = "cc_service_register"
|
||||
|
|
|
@ -27,7 +27,7 @@ class Show(models.Model):
|
|||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cc_show'
|
||||
db_table = "cc_show"
|
||||
|
||||
|
||||
class ShowDays(models.Model):
|
||||
|
@ -47,16 +47,16 @@ class ShowDays(models.Model):
|
|||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cc_show_days'
|
||||
db_table = "cc_show_days"
|
||||
|
||||
|
||||
class ShowHost(models.Model):
|
||||
show = models.ForeignKey(Show, models.DO_NOTHING)
|
||||
subjs = models.ForeignKey('User', models.DO_NOTHING)
|
||||
subjs = models.ForeignKey("User", models.DO_NOTHING)
|
||||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cc_show_hosts'
|
||||
db_table = "cc_show_hosts"
|
||||
|
||||
|
||||
class ShowInstance(models.Model):
|
||||
|
@ -66,7 +66,7 @@ class ShowInstance(models.Model):
|
|||
show = models.ForeignKey(Show, models.DO_NOTHING)
|
||||
record = models.SmallIntegerField(blank=True, null=True)
|
||||
rebroadcast = models.SmallIntegerField(blank=True, null=True)
|
||||
instance = models.ForeignKey('self', models.DO_NOTHING, blank=True, null=True)
|
||||
instance = models.ForeignKey("self", models.DO_NOTHING, blank=True, null=True)
|
||||
file = models.ForeignKey(File, models.DO_NOTHING, blank=True, null=True)
|
||||
time_filled = models.DurationField(blank=True, null=True)
|
||||
created = models.DateTimeField()
|
||||
|
@ -79,7 +79,7 @@ class ShowInstance(models.Model):
|
|||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cc_show_instances'
|
||||
db_table = "cc_show_instances"
|
||||
|
||||
|
||||
class ShowRebroadcast(models.Model):
|
||||
|
@ -92,4 +92,4 @@ class ShowRebroadcast(models.Model):
|
|||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cc_show_rebroadcast'
|
||||
db_table = "cc_show_rebroadcast"
|
||||
|
|
|
@ -6,7 +6,7 @@ class SmartBlock(models.Model):
|
|||
name = models.CharField(max_length=255)
|
||||
mtime = models.DateTimeField(blank=True, null=True)
|
||||
utime = models.DateTimeField(blank=True, null=True)
|
||||
creator = models.ForeignKey('User', models.DO_NOTHING, blank=True, null=True)
|
||||
creator = models.ForeignKey("User", models.DO_NOTHING, blank=True, null=True)
|
||||
description = models.CharField(max_length=512, blank=True, null=True)
|
||||
length = models.DurationField(blank=True, null=True)
|
||||
type = models.CharField(max_length=7, blank=True, null=True)
|
||||
|
@ -16,16 +16,22 @@ class SmartBlock(models.Model):
|
|||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cc_block'
|
||||
db_table = "cc_block"
|
||||
permissions = [
|
||||
('change_own_smartblock', 'Change the smartblocks where they are the owner'),
|
||||
('delete_own_smartblock', 'Delete the smartblocks where they are the owner'),
|
||||
(
|
||||
"change_own_smartblock",
|
||||
"Change the smartblocks where they are the owner",
|
||||
),
|
||||
(
|
||||
"delete_own_smartblock",
|
||||
"Delete the smartblocks where they are the owner",
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
class SmartBlockContent(models.Model):
|
||||
block = models.ForeignKey(SmartBlock, models.DO_NOTHING, blank=True, null=True)
|
||||
file = models.ForeignKey('File', models.DO_NOTHING, blank=True, null=True)
|
||||
file = models.ForeignKey("File", models.DO_NOTHING, blank=True, null=True)
|
||||
position = models.IntegerField(blank=True, null=True)
|
||||
trackoffset = models.FloatField()
|
||||
cliplength = models.DurationField(blank=True, null=True)
|
||||
|
@ -39,10 +45,16 @@ class SmartBlockContent(models.Model):
|
|||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cc_blockcontents'
|
||||
db_table = "cc_blockcontents"
|
||||
permissions = [
|
||||
('change_own_smartblockcontent', 'Change the content of smartblocks where they are the owner'),
|
||||
('delete_own_smartblockcontent', 'Delete the content of smartblocks where they are the owner'),
|
||||
(
|
||||
"change_own_smartblockcontent",
|
||||
"Change the content of smartblocks where they are the owner",
|
||||
),
|
||||
(
|
||||
"delete_own_smartblockcontent",
|
||||
"Delete the content of smartblocks where they are the owner",
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
|
@ -59,9 +71,14 @@ class SmartBlockCriteria(models.Model):
|
|||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cc_blockcriteria'
|
||||
db_table = "cc_blockcriteria"
|
||||
permissions = [
|
||||
('change_own_smartblockcriteria', 'Change the criteria of smartblocks where they are the owner'),
|
||||
('delete_own_smartblockcriteria', 'Delete the criteria of smartblocks where they are the owner'),
|
||||
(
|
||||
"change_own_smartblockcriteria",
|
||||
"Change the criteria of smartblocks where they are the owner",
|
||||
),
|
||||
(
|
||||
"delete_own_smartblockcriteria",
|
||||
"Delete the criteria of smartblocks where they are the owner",
|
||||
),
|
||||
]
|
||||
|
||||
|
|
|
@ -12,7 +12,8 @@ class ThirdPartyTrackReference(models.Model):
|
|||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'third_party_track_references'
|
||||
db_table = "third_party_track_references"
|
||||
|
||||
|
||||
class TrackType(models.Model):
|
||||
code = models.CharField(max_length=16, unique=True)
|
||||
|
@ -22,5 +23,4 @@ class TrackType(models.Model):
|
|||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cc_track_types'
|
||||
|
||||
db_table = "cc_track_types"
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
GUEST = 'G'
|
||||
DJ = 'H'
|
||||
PROGRAM_MANAGER = 'P'
|
||||
ADMIN = 'A'
|
||||
GUEST = "G"
|
||||
DJ = "H"
|
||||
PROGRAM_MANAGER = "P"
|
||||
ADMIN = "A"
|
||||
|
||||
USER_TYPES = {
|
||||
GUEST: 'Guest',
|
||||
DJ: 'DJ',
|
||||
PROGRAM_MANAGER: 'Program Manager',
|
||||
ADMIN: 'Admin',
|
||||
GUEST: "Guest",
|
||||
DJ: "DJ",
|
||||
PROGRAM_MANAGER: "Program Manager",
|
||||
ADMIN: "Admin",
|
||||
}
|
||||
|
|
|
@ -21,10 +21,10 @@ class Webstream(models.Model):
|
|||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cc_webstream'
|
||||
db_table = "cc_webstream"
|
||||
permissions = [
|
||||
('change_own_webstream', 'Change the webstreams where they are the owner'),
|
||||
('delete_own_webstream', 'Delete the webstreams where they are the owner'),
|
||||
("change_own_webstream", "Change the webstreams where they are the owner"),
|
||||
("delete_own_webstream", "Delete the webstreams where they are the owner"),
|
||||
]
|
||||
|
||||
|
||||
|
@ -38,4 +38,4 @@ class WebstreamMetadata(models.Model):
|
|||
|
||||
class Meta:
|
||||
managed = False
|
||||
db_table = 'cc_webstream_metadata'
|
||||
db_table = "cc_webstream_metadata"
|
||||
|
|
|
@ -5,98 +5,101 @@ from .models.user_constants import GUEST, DJ, PROGRAM_MANAGER, USER_TYPES
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
GUEST_PERMISSIONS = ['view_schedule',
|
||||
'view_show',
|
||||
'view_showdays',
|
||||
'view_showhost',
|
||||
'view_showinstance',
|
||||
'view_showrebroadcast',
|
||||
'view_file',
|
||||
'view_podcast',
|
||||
'view_podcastepisode',
|
||||
'view_playlist',
|
||||
'view_playlistcontent',
|
||||
'view_smartblock',
|
||||
'view_smartblockcontent',
|
||||
'view_smartblockcriteria',
|
||||
'view_webstream',
|
||||
'view_apiroot',
|
||||
]
|
||||
DJ_PERMISSIONS = GUEST_PERMISSIONS + ['add_file',
|
||||
'add_podcast',
|
||||
'add_podcastepisode',
|
||||
'add_playlist',
|
||||
'add_playlistcontent',
|
||||
'add_smartblock',
|
||||
'add_smartblockcontent',
|
||||
'add_smartblockcriteria',
|
||||
'add_webstream',
|
||||
'change_own_schedule',
|
||||
'change_own_file',
|
||||
'change_own_podcast',
|
||||
'change_own_podcastepisode',
|
||||
'change_own_playlist',
|
||||
'change_own_playlistcontent',
|
||||
'change_own_smartblock',
|
||||
'change_own_smartblockcontent',
|
||||
'change_own_smartblockcriteria',
|
||||
'change_own_webstream',
|
||||
'delete_own_schedule',
|
||||
'delete_own_file',
|
||||
'delete_own_podcast',
|
||||
'delete_own_podcastepisode',
|
||||
'delete_own_playlist',
|
||||
'delete_own_playlistcontent',
|
||||
'delete_own_smartblock',
|
||||
'delete_own_smartblockcontent',
|
||||
'delete_own_smartblockcriteria',
|
||||
'delete_own_webstream',
|
||||
]
|
||||
PROGRAM_MANAGER_PERMISSIONS = GUEST_PERMISSIONS + ['add_show',
|
||||
'add_showdays',
|
||||
'add_showhost',
|
||||
'add_showinstance',
|
||||
'add_showrebroadcast',
|
||||
'add_file',
|
||||
'add_podcast',
|
||||
'add_podcastepisode',
|
||||
'add_playlist',
|
||||
'add_playlistcontent',
|
||||
'add_smartblock',
|
||||
'add_smartblockcontent',
|
||||
'add_smartblockcriteria',
|
||||
'add_webstream',
|
||||
'change_schedule',
|
||||
'change_show',
|
||||
'change_showdays',
|
||||
'change_showhost',
|
||||
'change_showinstance',
|
||||
'change_showrebroadcast',
|
||||
'change_file',
|
||||
'change_podcast',
|
||||
'change_podcastepisode',
|
||||
'change_playlist',
|
||||
'change_playlistcontent',
|
||||
'change_smartblock',
|
||||
'change_smartblockcontent',
|
||||
'change_smartblockcriteria',
|
||||
'change_webstream',
|
||||
'delete_schedule',
|
||||
'delete_show',
|
||||
'delete_showdays',
|
||||
'delete_showhost',
|
||||
'delete_showinstance',
|
||||
'delete_showrebroadcast',
|
||||
'delete_file',
|
||||
'delete_podcast',
|
||||
'delete_podcastepisode',
|
||||
'delete_playlist',
|
||||
'delete_playlistcontent',
|
||||
'delete_smartblock',
|
||||
'delete_smartblockcontent',
|
||||
'delete_smartblockcriteria',
|
||||
'delete_webstream',
|
||||
]
|
||||
GUEST_PERMISSIONS = [
|
||||
"view_schedule",
|
||||
"view_show",
|
||||
"view_showdays",
|
||||
"view_showhost",
|
||||
"view_showinstance",
|
||||
"view_showrebroadcast",
|
||||
"view_file",
|
||||
"view_podcast",
|
||||
"view_podcastepisode",
|
||||
"view_playlist",
|
||||
"view_playlistcontent",
|
||||
"view_smartblock",
|
||||
"view_smartblockcontent",
|
||||
"view_smartblockcriteria",
|
||||
"view_webstream",
|
||||
"view_apiroot",
|
||||
]
|
||||
DJ_PERMISSIONS = GUEST_PERMISSIONS + [
|
||||
"add_file",
|
||||
"add_podcast",
|
||||
"add_podcastepisode",
|
||||
"add_playlist",
|
||||
"add_playlistcontent",
|
||||
"add_smartblock",
|
||||
"add_smartblockcontent",
|
||||
"add_smartblockcriteria",
|
||||
"add_webstream",
|
||||
"change_own_schedule",
|
||||
"change_own_file",
|
||||
"change_own_podcast",
|
||||
"change_own_podcastepisode",
|
||||
"change_own_playlist",
|
||||
"change_own_playlistcontent",
|
||||
"change_own_smartblock",
|
||||
"change_own_smartblockcontent",
|
||||
"change_own_smartblockcriteria",
|
||||
"change_own_webstream",
|
||||
"delete_own_schedule",
|
||||
"delete_own_file",
|
||||
"delete_own_podcast",
|
||||
"delete_own_podcastepisode",
|
||||
"delete_own_playlist",
|
||||
"delete_own_playlistcontent",
|
||||
"delete_own_smartblock",
|
||||
"delete_own_smartblockcontent",
|
||||
"delete_own_smartblockcriteria",
|
||||
"delete_own_webstream",
|
||||
]
|
||||
PROGRAM_MANAGER_PERMISSIONS = GUEST_PERMISSIONS + [
|
||||
"add_show",
|
||||
"add_showdays",
|
||||
"add_showhost",
|
||||
"add_showinstance",
|
||||
"add_showrebroadcast",
|
||||
"add_file",
|
||||
"add_podcast",
|
||||
"add_podcastepisode",
|
||||
"add_playlist",
|
||||
"add_playlistcontent",
|
||||
"add_smartblock",
|
||||
"add_smartblockcontent",
|
||||
"add_smartblockcriteria",
|
||||
"add_webstream",
|
||||
"change_schedule",
|
||||
"change_show",
|
||||
"change_showdays",
|
||||
"change_showhost",
|
||||
"change_showinstance",
|
||||
"change_showrebroadcast",
|
||||
"change_file",
|
||||
"change_podcast",
|
||||
"change_podcastepisode",
|
||||
"change_playlist",
|
||||
"change_playlistcontent",
|
||||
"change_smartblock",
|
||||
"change_smartblockcontent",
|
||||
"change_smartblockcriteria",
|
||||
"change_webstream",
|
||||
"delete_schedule",
|
||||
"delete_show",
|
||||
"delete_showdays",
|
||||
"delete_showhost",
|
||||
"delete_showinstance",
|
||||
"delete_showrebroadcast",
|
||||
"delete_file",
|
||||
"delete_podcast",
|
||||
"delete_podcastepisode",
|
||||
"delete_playlist",
|
||||
"delete_playlistcontent",
|
||||
"delete_smartblock",
|
||||
"delete_smartblockcontent",
|
||||
"delete_smartblockcriteria",
|
||||
"delete_webstream",
|
||||
]
|
||||
|
||||
GROUPS = {
|
||||
GUEST: GUEST_PERMISSIONS,
|
||||
|
|
|
@ -4,21 +4,22 @@ from django.conf import settings
|
|||
from .models.user_constants import DJ
|
||||
|
||||
REQUEST_PERMISSION_TYPE_MAP = {
|
||||
'GET': 'view',
|
||||
'HEAD': 'view',
|
||||
'OPTIONS': 'view',
|
||||
'POST': 'change',
|
||||
'PUT': 'change',
|
||||
'DELETE': 'delete',
|
||||
'PATCH': 'change',
|
||||
"GET": "view",
|
||||
"HEAD": "view",
|
||||
"OPTIONS": "view",
|
||||
"POST": "change",
|
||||
"PUT": "change",
|
||||
"DELETE": "delete",
|
||||
"PATCH": "change",
|
||||
}
|
||||
|
||||
|
||||
def get_own_obj(request, view):
|
||||
user = request.user
|
||||
if user is None or user.type != DJ:
|
||||
return ''
|
||||
if request.method == 'GET':
|
||||
return ''
|
||||
return ""
|
||||
if request.method == "GET":
|
||||
return ""
|
||||
qs = view.queryset.all()
|
||||
try:
|
||||
model_owners = []
|
||||
|
@ -27,32 +28,34 @@ def get_own_obj(request, view):
|
|||
if owner not in model_owners:
|
||||
model_owners.append(owner)
|
||||
if len(model_owners) == 1 and user in model_owners:
|
||||
return 'own_'
|
||||
return "own_"
|
||||
except AttributeError:
|
||||
return ''
|
||||
return ''
|
||||
return ""
|
||||
return ""
|
||||
|
||||
|
||||
def get_permission_for_view(request, view):
|
||||
try:
|
||||
permission_type = REQUEST_PERMISSION_TYPE_MAP[request.method]
|
||||
if view.__class__.__name__ == 'APIRootView':
|
||||
return '{}_apiroot'.format(permission_type)
|
||||
if view.__class__.__name__ == "APIRootView":
|
||||
return "{}_apiroot".format(permission_type)
|
||||
model = view.model_permission_name
|
||||
own_obj = get_own_obj(request, view)
|
||||
return '{permission_type}_{own_obj}{model}'.format(permission_type=permission_type,
|
||||
own_obj=own_obj,
|
||||
model=model)
|
||||
return "{permission_type}_{own_obj}{model}".format(
|
||||
permission_type=permission_type, own_obj=own_obj, model=model
|
||||
)
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
def check_authorization_header(request):
|
||||
auth_header = request.META.get('Authorization')
|
||||
if not auth_header:
|
||||
auth_header = request.META.get('HTTP_AUTHORIZATION', '')
|
||||
|
||||
if auth_header.startswith('Api-Key'):
|
||||
def check_authorization_header(request):
|
||||
auth_header = request.META.get("Authorization")
|
||||
if not auth_header:
|
||||
auth_header = request.META.get("HTTP_AUTHORIZATION", "")
|
||||
|
||||
if auth_header.startswith("Api-Key"):
|
||||
token = auth_header.split()[1]
|
||||
if token == settings.CONFIG.get('general', 'api_key'):
|
||||
if token == settings.CONFIG.get("general", "api_key"):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
@ -63,6 +66,7 @@ class IsAdminOrOwnUser(BasePermission):
|
|||
Django's standard permission system. For details see
|
||||
https://www.django-rest-framework.org/api-guide/permissions/#custom-permissions
|
||||
"""
|
||||
|
||||
def has_permission(self, request, view):
|
||||
if request.user.is_superuser():
|
||||
return True
|
||||
|
@ -84,6 +88,7 @@ class IsSystemTokenOrUser(BasePermission):
|
|||
an API-Key header. All standard-users (i.e. not using the API-Key) have their
|
||||
permissions checked against Django's standard permission system.
|
||||
"""
|
||||
|
||||
def has_permission(self, request, view):
|
||||
if request.user and request.user.is_authenticated:
|
||||
perm = get_permission_for_view(request, view)
|
||||
|
@ -91,7 +96,7 @@ class IsSystemTokenOrUser(BasePermission):
|
|||
# model. This use-case allows users to view the base of the API
|
||||
# explorer. Their assigned group permissions determine further access
|
||||
# into the explorer.
|
||||
if perm == 'view_apiroot':
|
||||
if perm == "view_apiroot":
|
||||
return True
|
||||
return request.user.has_perm(perm)
|
||||
return check_authorization_header(request)
|
||||
|
|
|
@ -3,264 +3,305 @@ from django.contrib.auth import get_user_model
|
|||
from rest_framework import serializers
|
||||
from .models import *
|
||||
|
||||
|
||||
class UserSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = get_user_model()
|
||||
fields = [
|
||||
'item_url',
|
||||
'username',
|
||||
'type',
|
||||
'first_name',
|
||||
'last_name',
|
||||
'lastfail',
|
||||
'skype_contact',
|
||||
'jabber_contact',
|
||||
'email',
|
||||
'cell_phone',
|
||||
'login_attempts',
|
||||
"item_url",
|
||||
"username",
|
||||
"type",
|
||||
"first_name",
|
||||
"last_name",
|
||||
"lastfail",
|
||||
"skype_contact",
|
||||
"jabber_contact",
|
||||
"email",
|
||||
"cell_phone",
|
||||
"login_attempts",
|
||||
]
|
||||
|
||||
|
||||
class SmartBlockSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = SmartBlock
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class SmartBlockContentSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = SmartBlockContent
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class SmartBlockCriteriaSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = SmartBlockCriteria
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class CountrySerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = Country
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class FileSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = File
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class ListenerCountSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = ListenerCount
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class LiveLogSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = LiveLog
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class LoginAttemptSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = LoginAttempt
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class MountNameSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = MountName
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class MusicDirSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = MusicDir
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class PlaylistSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = Playlist
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class PlaylistContentSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = PlaylistContent
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class PlayoutHistorySerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = PlayoutHistory
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class PlayoutHistoryMetadataSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = PlayoutHistoryMetadata
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class PlayoutHistoryTemplateSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = PlayoutHistoryTemplate
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class PlayoutHistoryTemplateFieldSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = PlayoutHistoryTemplateField
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class PreferenceSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = Preference
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class ScheduleSerializer(serializers.HyperlinkedModelSerializer):
|
||||
file_id = serializers.IntegerField(source='file.id', read_only=True)
|
||||
stream_id = serializers.IntegerField(source='stream.id', read_only=True)
|
||||
instance_id = serializers.IntegerField(source='instance.id', read_only=True)
|
||||
file_id = serializers.IntegerField(source="file.id", read_only=True)
|
||||
stream_id = serializers.IntegerField(source="stream.id", read_only=True)
|
||||
instance_id = serializers.IntegerField(source="instance.id", read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = Schedule
|
||||
fields = [
|
||||
'item_url',
|
||||
'id',
|
||||
'starts',
|
||||
'ends',
|
||||
'clip_length',
|
||||
'fade_in',
|
||||
'fade_out',
|
||||
'cue_in',
|
||||
'cue_out',
|
||||
'media_item_played',
|
||||
'file',
|
||||
'file_id',
|
||||
'stream',
|
||||
'stream_id',
|
||||
'instance',
|
||||
'instance_id',
|
||||
"item_url",
|
||||
"id",
|
||||
"starts",
|
||||
"ends",
|
||||
"clip_length",
|
||||
"fade_in",
|
||||
"fade_out",
|
||||
"cue_in",
|
||||
"cue_out",
|
||||
"media_item_played",
|
||||
"file",
|
||||
"file_id",
|
||||
"stream",
|
||||
"stream_id",
|
||||
"instance",
|
||||
"instance_id",
|
||||
]
|
||||
|
||||
|
||||
class ServiceRegisterSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = ServiceRegister
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class SessionSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = Session
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class ShowSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = Show
|
||||
fields = [
|
||||
'item_url',
|
||||
'id',
|
||||
'name',
|
||||
'url',
|
||||
'genre',
|
||||
'description',
|
||||
'color',
|
||||
'background_color',
|
||||
'linked',
|
||||
'is_linkable',
|
||||
'image_path',
|
||||
'has_autoplaylist',
|
||||
'autoplaylist_repeat',
|
||||
'autoplaylist',
|
||||
"item_url",
|
||||
"id",
|
||||
"name",
|
||||
"url",
|
||||
"genre",
|
||||
"description",
|
||||
"color",
|
||||
"background_color",
|
||||
"linked",
|
||||
"is_linkable",
|
||||
"image_path",
|
||||
"has_autoplaylist",
|
||||
"autoplaylist_repeat",
|
||||
"autoplaylist",
|
||||
]
|
||||
|
||||
|
||||
class ShowDaysSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = ShowDays
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class ShowHostSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = ShowHost
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class ShowInstanceSerializer(serializers.HyperlinkedModelSerializer):
|
||||
show_id = serializers.IntegerField(source='show.id', read_only=True)
|
||||
file_id = serializers.IntegerField(source='file.id', read_only=True)
|
||||
show_id = serializers.IntegerField(source="show.id", read_only=True)
|
||||
file_id = serializers.IntegerField(source="file.id", read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = ShowInstance
|
||||
fields = [
|
||||
'item_url',
|
||||
'id',
|
||||
'description',
|
||||
'starts',
|
||||
'ends',
|
||||
'record',
|
||||
'rebroadcast',
|
||||
'time_filled',
|
||||
'created',
|
||||
'last_scheduled',
|
||||
'modified_instance',
|
||||
'autoplaylist_built',
|
||||
'show',
|
||||
'show_id',
|
||||
'instance',
|
||||
'file',
|
||||
'file_id',
|
||||
"item_url",
|
||||
"id",
|
||||
"description",
|
||||
"starts",
|
||||
"ends",
|
||||
"record",
|
||||
"rebroadcast",
|
||||
"time_filled",
|
||||
"created",
|
||||
"last_scheduled",
|
||||
"modified_instance",
|
||||
"autoplaylist_built",
|
||||
"show",
|
||||
"show_id",
|
||||
"instance",
|
||||
"file",
|
||||
"file_id",
|
||||
]
|
||||
|
||||
|
||||
class ShowRebroadcastSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = ShowRebroadcast
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class StreamSettingSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = StreamSetting
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class UserTokenSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = UserToken
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class TimestampSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = Timestamp
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class WebstreamSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = Webstream
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class WebstreamMetadataSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = WebstreamMetadata
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class CeleryTaskSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = CeleryTask
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class CloudFileSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = CloudFile
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class ImportedPodcastSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = ImportedPodcast
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class PodcastSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = Podcast
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class PodcastEpisodeSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = PodcastEpisode
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class StationPodcastSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = StationPodcast
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class ThirdPartyTrackReferenceSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = ThirdPartyTrackReference
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class TrackTypeSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = TrackType
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
|
|
@ -3,10 +3,11 @@ import configparser
|
|||
import os
|
||||
from .utils import read_config_file, get_random_string
|
||||
|
||||
LIBRETIME_CONF_DIR = os.getenv('LIBRETIME_CONF_DIR', '/etc/airtime')
|
||||
DEFAULT_CONFIG_PATH = os.getenv('LIBRETIME_CONF_FILE',
|
||||
os.path.join(LIBRETIME_CONF_DIR, 'airtime.conf'))
|
||||
API_VERSION = '2.0.0'
|
||||
LIBRETIME_CONF_DIR = os.getenv("LIBRETIME_CONF_DIR", "/etc/airtime")
|
||||
DEFAULT_CONFIG_PATH = os.getenv(
|
||||
"LIBRETIME_CONF_FILE", os.path.join(LIBRETIME_CONF_DIR, "airtime.conf")
|
||||
)
|
||||
API_VERSION = "2.0.0"
|
||||
|
||||
try:
|
||||
CONFIG = read_config_file(DEFAULT_CONFIG_PATH)
|
||||
|
@ -18,70 +19,70 @@ except IOError:
|
|||
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY = get_random_string(CONFIG.get('general', 'api_key', fallback=''))
|
||||
SECRET_KEY = get_random_string(CONFIG.get("general", "api_key", fallback=""))
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = os.getenv('LIBRETIME_DEBUG', False)
|
||||
DEBUG = os.getenv("LIBRETIME_DEBUG", False)
|
||||
|
||||
ALLOWED_HOSTS = ['*']
|
||||
ALLOWED_HOSTS = ["*"]
|
||||
|
||||
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
'libretimeapi.apps.LibreTimeAPIConfig',
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'rest_framework',
|
||||
'url_filter',
|
||||
"libretimeapi.apps.LibreTimeAPIConfig",
|
||||
"django.contrib.admin",
|
||||
"django.contrib.auth",
|
||||
"django.contrib.contenttypes",
|
||||
"django.contrib.sessions",
|
||||
"django.contrib.messages",
|
||||
"django.contrib.staticfiles",
|
||||
"rest_framework",
|
||||
"url_filter",
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
"django.middleware.security.SecurityMiddleware",
|
||||
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||
"django.middleware.common.CommonMiddleware",
|
||||
"django.middleware.csrf.CsrfViewMiddleware",
|
||||
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||
"django.contrib.messages.middleware.MessageMiddleware",
|
||||
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
||||
]
|
||||
|
||||
ROOT_URLCONF = 'libretimeapi.urls'
|
||||
ROOT_URLCONF = "libretimeapi.urls"
|
||||
|
||||
TEMPLATES = [
|
||||
{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [],
|
||||
'APP_DIRS': True,
|
||||
'OPTIONS': {
|
||||
'context_processors': [
|
||||
'django.template.context_processors.debug',
|
||||
'django.template.context_processors.request',
|
||||
'django.contrib.auth.context_processors.auth',
|
||||
'django.contrib.messages.context_processors.messages',
|
||||
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
||||
"DIRS": [],
|
||||
"APP_DIRS": True,
|
||||
"OPTIONS": {
|
||||
"context_processors": [
|
||||
"django.template.context_processors.debug",
|
||||
"django.template.context_processors.request",
|
||||
"django.contrib.auth.context_processors.auth",
|
||||
"django.contrib.messages.context_processors.messages",
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
WSGI_APPLICATION = 'libretimeapi.wsgi.application'
|
||||
WSGI_APPLICATION = "libretimeapi.wsgi.application"
|
||||
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.postgresql',
|
||||
'NAME': CONFIG.get('database', 'dbname', fallback=''),
|
||||
'USER': CONFIG.get('database', 'dbuser', fallback=''),
|
||||
'PASSWORD': CONFIG.get('database', 'dbpass', fallback=''),
|
||||
'HOST': CONFIG.get('database', 'host', fallback=''),
|
||||
'PORT': '5432',
|
||||
"default": {
|
||||
"ENGINE": "django.db.backends.postgresql",
|
||||
"NAME": CONFIG.get("database", "dbname", fallback=""),
|
||||
"USER": CONFIG.get("database", "dbuser", fallback=""),
|
||||
"PASSWORD": CONFIG.get("database", "dbpass", fallback=""),
|
||||
"HOST": CONFIG.get("database", "host", fallback=""),
|
||||
"PORT": "5432",
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,40 +92,40 @@ DATABASES = {
|
|||
|
||||
AUTH_PASSWORD_VALIDATORS = [
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
||||
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
||||
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
||||
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
||||
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
|
||||
},
|
||||
]
|
||||
|
||||
REST_FRAMEWORK = {
|
||||
'DEFAULT_AUTHENTICATION_CLASSES': (
|
||||
'rest_framework.authentication.SessionAuthentication',
|
||||
'rest_framework.authentication.BasicAuthentication',
|
||||
"DEFAULT_AUTHENTICATION_CLASSES": (
|
||||
"rest_framework.authentication.SessionAuthentication",
|
||||
"rest_framework.authentication.BasicAuthentication",
|
||||
),
|
||||
'DEFAULT_PERMISSION_CLASSES': [
|
||||
'libretimeapi.permissions.IsSystemTokenOrUser',
|
||||
"DEFAULT_PERMISSION_CLASSES": [
|
||||
"libretimeapi.permissions.IsSystemTokenOrUser",
|
||||
],
|
||||
'DEFAULT_FILTER_BACKENDS': [
|
||||
'url_filter.integrations.drf.DjangoFilterBackend',
|
||||
"DEFAULT_FILTER_BACKENDS": [
|
||||
"url_filter.integrations.drf.DjangoFilterBackend",
|
||||
],
|
||||
'URL_FIELD_NAME': 'item_url',
|
||||
"URL_FIELD_NAME": "item_url",
|
||||
}
|
||||
|
||||
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/3.0/topics/i18n/
|
||||
|
||||
LANGUAGE_CODE = 'en-us'
|
||||
LANGUAGE_CODE = "en-us"
|
||||
|
||||
TIME_ZONE = 'UTC'
|
||||
TIME_ZONE = "UTC"
|
||||
|
||||
USE_I18N = True
|
||||
|
||||
|
@ -136,50 +137,53 @@ USE_TZ = True
|
|||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/3.0/howto/static-files/
|
||||
|
||||
STATIC_URL = '/api/static/'
|
||||
STATIC_URL = "/api/static/"
|
||||
if not DEBUG:
|
||||
STATIC_ROOT = os.getenv('LIBRETIME_STATIC_ROOT', '/usr/share/airtime/api')
|
||||
STATIC_ROOT = os.getenv("LIBRETIME_STATIC_ROOT", "/usr/share/airtime/api")
|
||||
|
||||
AUTH_USER_MODEL = 'libretimeapi.User'
|
||||
AUTH_USER_MODEL = "libretimeapi.User"
|
||||
|
||||
TEST_RUNNER = 'libretimeapi.tests.runners.ManagedModelTestRunner'
|
||||
TEST_RUNNER = "libretimeapi.tests.runners.ManagedModelTestRunner"
|
||||
|
||||
LOGGING = {
|
||||
'version': 1,
|
||||
'disable_existing_loggers': False,
|
||||
'formatters': {
|
||||
'simple': {
|
||||
'format': '{levelname} {message}',
|
||||
'style': '{',
|
||||
"version": 1,
|
||||
"disable_existing_loggers": False,
|
||||
"formatters": {
|
||||
"simple": {
|
||||
"format": "{levelname} {message}",
|
||||
"style": "{",
|
||||
},
|
||||
'verbose': {
|
||||
'format': '{asctime} {module} {levelname} {message}',
|
||||
'style': '{',
|
||||
}
|
||||
},
|
||||
'handlers': {
|
||||
'file': {
|
||||
'level': 'DEBUG',
|
||||
'class': 'logging.FileHandler',
|
||||
'filename': os.path.join(CONFIG.get('pypo', 'log_base_dir', fallback='.').replace('\'',''), 'api.log'),
|
||||
'formatter': 'verbose',
|
||||
},
|
||||
'console': {
|
||||
'level': 'INFO',
|
||||
'class': 'logging.StreamHandler',
|
||||
'formatter': 'simple',
|
||||
"verbose": {
|
||||
"format": "{asctime} {module} {levelname} {message}",
|
||||
"style": "{",
|
||||
},
|
||||
},
|
||||
'loggers': {
|
||||
'django': {
|
||||
'handlers': ['file', 'console'],
|
||||
'level': 'INFO',
|
||||
'propogate': True,
|
||||
"handlers": {
|
||||
"file": {
|
||||
"level": "DEBUG",
|
||||
"class": "logging.FileHandler",
|
||||
"filename": os.path.join(
|
||||
CONFIG.get("pypo", "log_base_dir", fallback=".").replace("'", ""),
|
||||
"api.log",
|
||||
),
|
||||
"formatter": "verbose",
|
||||
},
|
||||
'libretimeapi': {
|
||||
'handlers': ['file', 'console'],
|
||||
'level': 'INFO',
|
||||
'propogate': True,
|
||||
"console": {
|
||||
"level": "INFO",
|
||||
"class": "logging.StreamHandler",
|
||||
"formatter": "simple",
|
||||
},
|
||||
},
|
||||
"loggers": {
|
||||
"django": {
|
||||
"handlers": ["file", "console"],
|
||||
"level": "INFO",
|
||||
"propogate": True,
|
||||
},
|
||||
"libretimeapi": {
|
||||
"handlers": ["file", "console"],
|
||||
"level": "INFO",
|
||||
"propogate": True,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -8,18 +8,17 @@ class ManagedModelTestRunner(DiscoverRunner):
|
|||
project managed for the duration of the test run, so that one doesn't need
|
||||
to execute the SQL manually to create them.
|
||||
"""
|
||||
|
||||
def setup_test_environment(self, *args, **kwargs):
|
||||
from django.apps import apps
|
||||
self.unmanaged_models = [m for m in apps.get_models()
|
||||
if not m._meta.managed]
|
||||
|
||||
self.unmanaged_models = [m for m in apps.get_models() if not m._meta.managed]
|
||||
for m in self.unmanaged_models:
|
||||
m._meta.managed = True
|
||||
super(ManagedModelTestRunner, self).setup_test_environment(*args,
|
||||
**kwargs)
|
||||
super(ManagedModelTestRunner, self).setup_test_environment(*args, **kwargs)
|
||||
|
||||
def teardown_test_environment(self, *args, **kwargs):
|
||||
super(ManagedModelTestRunner, self).teardown_test_environment(*args,
|
||||
**kwargs)
|
||||
super(ManagedModelTestRunner, self).teardown_test_environment(*args, **kwargs)
|
||||
# reset unmanaged models
|
||||
for m in self.unmanaged_models:
|
||||
m._meta.managed = False
|
||||
|
|
|
@ -9,33 +9,40 @@ from libretimeapi.permission_constants import GROUPS
|
|||
|
||||
class TestUserManager(APITestCase):
|
||||
def test_create_user(self):
|
||||
user = User.objects.create_user('test',
|
||||
email='test@example.com',
|
||||
password='test',
|
||||
type=DJ,
|
||||
first_name='test',
|
||||
last_name='user')
|
||||
user = User.objects.create_user(
|
||||
"test",
|
||||
email="test@example.com",
|
||||
password="test",
|
||||
type=DJ,
|
||||
first_name="test",
|
||||
last_name="user",
|
||||
)
|
||||
db_user = User.objects.get(pk=user.pk)
|
||||
self.assertEqual(db_user.username, user.username)
|
||||
|
||||
def test_create_superuser(self):
|
||||
user = User.objects.create_superuser('test',
|
||||
email='test@example.com',
|
||||
password='test',
|
||||
first_name='test',
|
||||
last_name='user')
|
||||
user = User.objects.create_superuser(
|
||||
"test",
|
||||
email="test@example.com",
|
||||
password="test",
|
||||
first_name="test",
|
||||
last_name="user",
|
||||
)
|
||||
db_user = User.objects.get(pk=user.pk)
|
||||
self.assertEqual(db_user.username, user.username)
|
||||
|
||||
|
||||
class TestUser(APITestCase):
|
||||
def test_guest_get_group_perms(self):
|
||||
user = User.objects.create_user('test',
|
||||
email='test@example.com',
|
||||
password='test',
|
||||
type=GUEST,
|
||||
first_name='test',
|
||||
last_name='user')
|
||||
user = User.objects.create_user(
|
||||
"test",
|
||||
email="test@example.com",
|
||||
password="test",
|
||||
type=GUEST,
|
||||
first_name="test",
|
||||
last_name="user",
|
||||
)
|
||||
permissions = user.get_group_permissions()
|
||||
# APIRoot permission hardcoded in the check as it isn't a Permission object
|
||||
str_perms = [p.codename for p in permissions] + ['view_apiroot']
|
||||
str_perms = [p.codename for p in permissions] + ["view_apiroot"]
|
||||
self.assertCountEqual(str_perms, GROUPS[GUEST])
|
||||
|
|
|
@ -6,7 +6,11 @@ from django.conf import settings
|
|||
from rest_framework.test import APITestCase, APIRequestFactory
|
||||
from model_bakery import baker
|
||||
from libretimeapi.permissions import IsSystemTokenOrUser
|
||||
from libretimeapi.permission_constants import GUEST_PERMISSIONS, DJ_PERMISSIONS, PROGRAM_MANAGER_PERMISSIONS
|
||||
from libretimeapi.permission_constants import (
|
||||
GUEST_PERMISSIONS,
|
||||
DJ_PERMISSIONS,
|
||||
PROGRAM_MANAGER_PERMISSIONS,
|
||||
)
|
||||
from libretimeapi.models.user_constants import GUEST, DJ, PROGRAM_MANAGER, ADMIN
|
||||
|
||||
|
||||
|
@ -16,54 +20,56 @@ class TestIsSystemTokenOrUser(APITestCase):
|
|||
cls.path = "/api/v2/files/"
|
||||
|
||||
def test_unauthorized(self):
|
||||
response = self.client.get(self.path.format('files'))
|
||||
response = self.client.get(self.path.format("files"))
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
def test_token_incorrect(self):
|
||||
token = 'doesnotexist'
|
||||
token = "doesnotexist"
|
||||
request = APIRequestFactory().get(self.path)
|
||||
request.user = AnonymousUser()
|
||||
request.META['Authorization'] = 'Api-Key {token}'.format(token=token)
|
||||
request.META["Authorization"] = "Api-Key {token}".format(token=token)
|
||||
allowed = IsSystemTokenOrUser().has_permission(request, None)
|
||||
self.assertFalse(allowed)
|
||||
|
||||
def test_token_correct(self):
|
||||
token = settings.CONFIG.get('general', 'api_key')
|
||||
token = settings.CONFIG.get("general", "api_key")
|
||||
request = APIRequestFactory().get(self.path)
|
||||
request.user = AnonymousUser()
|
||||
request.META['Authorization'] = 'Api-Key {token}'.format(token=token)
|
||||
request.META["Authorization"] = "Api-Key {token}".format(token=token)
|
||||
allowed = IsSystemTokenOrUser().has_permission(request, None)
|
||||
self.assertTrue(allowed)
|
||||
|
||||
|
||||
class TestPermissions(APITestCase):
|
||||
URLS = [
|
||||
'schedule',
|
||||
'shows',
|
||||
'show-days',
|
||||
'show-hosts',
|
||||
'show-instances',
|
||||
'show-rebroadcasts',
|
||||
'files',
|
||||
'playlists',
|
||||
'playlist-contents',
|
||||
'smart-blocks',
|
||||
'smart-block-contents',
|
||||
'smart-block-criteria',
|
||||
'webstreams',
|
||||
"schedule",
|
||||
"shows",
|
||||
"show-days",
|
||||
"show-hosts",
|
||||
"show-instances",
|
||||
"show-rebroadcasts",
|
||||
"files",
|
||||
"playlists",
|
||||
"playlist-contents",
|
||||
"smart-blocks",
|
||||
"smart-block-contents",
|
||||
"smart-block-criteria",
|
||||
"webstreams",
|
||||
]
|
||||
|
||||
def logged_in_test_model(self, model, name, user_type, fn):
|
||||
path = self.path.format(model)
|
||||
user_created = get_user_model().objects.filter(username=name)
|
||||
if not user_created:
|
||||
user = get_user_model().objects.create_user(name,
|
||||
email='test@example.com',
|
||||
password='test',
|
||||
type=user_type,
|
||||
first_name='test',
|
||||
last_name='user')
|
||||
self.client.login(username=name, password='test')
|
||||
user = get_user_model().objects.create_user(
|
||||
name,
|
||||
email="test@example.com",
|
||||
password="test",
|
||||
type=user_type,
|
||||
first_name="test",
|
||||
last_name="user",
|
||||
)
|
||||
self.client.login(username=name, password="test")
|
||||
return fn(path)
|
||||
|
||||
@classmethod
|
||||
|
@ -72,49 +78,57 @@ class TestPermissions(APITestCase):
|
|||
|
||||
def test_guest_permissions_success(self):
|
||||
for model in self.URLS:
|
||||
response = self.logged_in_test_model(model, 'guest', GUEST, self.client.get)
|
||||
self.assertEqual(response.status_code, 200,
|
||||
msg='Invalid for model {}'.format(model))
|
||||
response = self.logged_in_test_model(model, "guest", GUEST, self.client.get)
|
||||
self.assertEqual(
|
||||
response.status_code, 200, msg="Invalid for model {}".format(model)
|
||||
)
|
||||
|
||||
def test_guest_permissions_failure(self):
|
||||
for model in self.URLS:
|
||||
response = self.logged_in_test_model(model, 'guest', GUEST, self.client.post)
|
||||
self.assertEqual(response.status_code, 403,
|
||||
msg='Invalid for model {}'.format(model))
|
||||
response = self.logged_in_test_model('users', 'guest', GUEST, self.client.get)
|
||||
self.assertEqual(response.status_code, 403, msg='Invalid for model users')
|
||||
response = self.logged_in_test_model(
|
||||
model, "guest", GUEST, self.client.post
|
||||
)
|
||||
self.assertEqual(
|
||||
response.status_code, 403, msg="Invalid for model {}".format(model)
|
||||
)
|
||||
response = self.logged_in_test_model("users", "guest", GUEST, self.client.get)
|
||||
self.assertEqual(response.status_code, 403, msg="Invalid for model users")
|
||||
|
||||
def test_dj_get_permissions(self):
|
||||
for model in self.URLS:
|
||||
response = self.logged_in_test_model(model, 'dj', DJ, self.client.get)
|
||||
self.assertEqual(response.status_code, 200,
|
||||
msg='Invalid for model {}'.format(model))
|
||||
response = self.logged_in_test_model(model, "dj", DJ, self.client.get)
|
||||
self.assertEqual(
|
||||
response.status_code, 200, msg="Invalid for model {}".format(model)
|
||||
)
|
||||
|
||||
def test_dj_post_permissions(self):
|
||||
user = get_user_model().objects.create_user('test-dj',
|
||||
email='test@example.com',
|
||||
password='test',
|
||||
type=DJ,
|
||||
first_name='test',
|
||||
last_name='user')
|
||||
f = baker.make('libretimeapi.File',
|
||||
owner=user)
|
||||
model = 'files/{}'.format(f.id)
|
||||
user = get_user_model().objects.create_user(
|
||||
"test-dj",
|
||||
email="test@example.com",
|
||||
password="test",
|
||||
type=DJ,
|
||||
first_name="test",
|
||||
last_name="user",
|
||||
)
|
||||
f = baker.make("libretimeapi.File", owner=user)
|
||||
model = "files/{}".format(f.id)
|
||||
path = self.path.format(model)
|
||||
self.client.login(username='test-dj', password='test')
|
||||
response = self.client.patch(path, {'name': 'newFilename'})
|
||||
self.client.login(username="test-dj", password="test")
|
||||
response = self.client.patch(path, {"name": "newFilename"})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_dj_post_permissions_failure(self):
|
||||
user = get_user_model().objects.create_user('test-dj',
|
||||
email='test@example.com',
|
||||
password='test',
|
||||
type=DJ,
|
||||
first_name='test',
|
||||
last_name='user')
|
||||
f = baker.make('libretimeapi.File')
|
||||
model = 'files/{}'.format(f.id)
|
||||
user = get_user_model().objects.create_user(
|
||||
"test-dj",
|
||||
email="test@example.com",
|
||||
password="test",
|
||||
type=DJ,
|
||||
first_name="test",
|
||||
last_name="user",
|
||||
)
|
||||
f = baker.make("libretimeapi.File")
|
||||
model = "files/{}".format(f.id)
|
||||
path = self.path.format(model)
|
||||
self.client.login(username='test-dj', password='test')
|
||||
response = self.client.patch(path, {'name': 'newFilename'})
|
||||
self.client.login(username="test-dj", password="test")
|
||||
response = self.client.patch(path, {"name": "newFilename"})
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
|
|
@ -11,29 +11,32 @@ class TestFileViewSet(APITestCase):
|
|||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
cls.path = "/api/v2/files/{id}/download/"
|
||||
cls.token = settings.CONFIG.get('general', 'api_key')
|
||||
cls.token = settings.CONFIG.get("general", "api_key")
|
||||
|
||||
def test_invalid(self):
|
||||
path = self.path.format(id='a')
|
||||
self.client.credentials(HTTP_AUTHORIZATION='Api-Key {}'.format(self.token))
|
||||
path = self.path.format(id="a")
|
||||
self.client.credentials(HTTP_AUTHORIZATION="Api-Key {}".format(self.token))
|
||||
response = self.client.get(path)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
def test_does_not_exist(self):
|
||||
path = self.path.format(id='1')
|
||||
self.client.credentials(HTTP_AUTHORIZATION='Api-Key {}'.format(self.token))
|
||||
path = self.path.format(id="1")
|
||||
self.client.credentials(HTTP_AUTHORIZATION="Api-Key {}".format(self.token))
|
||||
response = self.client.get(path)
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def test_exists(self):
|
||||
music_dir = baker.make('libretimeapi.MusicDir',
|
||||
directory=os.path.join(os.path.dirname(__file__),
|
||||
'resources'))
|
||||
f = baker.make('libretimeapi.File',
|
||||
directory=music_dir,
|
||||
mime='audio/mp3',
|
||||
filepath='song.mp3')
|
||||
music_dir = baker.make(
|
||||
"libretimeapi.MusicDir",
|
||||
directory=os.path.join(os.path.dirname(__file__), "resources"),
|
||||
)
|
||||
f = baker.make(
|
||||
"libretimeapi.File",
|
||||
directory=music_dir,
|
||||
mime="audio/mp3",
|
||||
filepath="song.mp3",
|
||||
)
|
||||
path = self.path.format(id=str(f.pk))
|
||||
self.client.credentials(HTTP_AUTHORIZATION='Api-Key {}'.format(self.token))
|
||||
self.client.credentials(HTTP_AUTHORIZATION="Api-Key {}".format(self.token))
|
||||
response = self.client.get(path)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
|
|
@ -5,48 +5,48 @@ from rest_framework import routers
|
|||
from .views import *
|
||||
|
||||
router = routers.DefaultRouter()
|
||||
router.register('smart-blocks', SmartBlockViewSet)
|
||||
router.register('smart-block-contents', SmartBlockContentViewSet)
|
||||
router.register('smart-block-criteria', SmartBlockCriteriaViewSet)
|
||||
router.register('countries', CountryViewSet)
|
||||
router.register('files', FileViewSet)
|
||||
router.register('listener-counts', ListenerCountViewSet)
|
||||
router.register('live-logs', LiveLogViewSet)
|
||||
router.register('login-attempts', LoginAttemptViewSet)
|
||||
router.register('mount-names', MountNameViewSet)
|
||||
router.register('music-dirs', MusicDirViewSet)
|
||||
router.register('playlists', PlaylistViewSet)
|
||||
router.register('playlist-contents', PlaylistContentViewSet)
|
||||
router.register('playout-history', PlayoutHistoryViewSet)
|
||||
router.register('playout-history-metadata', PlayoutHistoryMetadataViewSet)
|
||||
router.register('playout-history-templates', PlayoutHistoryTemplateViewSet)
|
||||
router.register('playout-history-template-fields', PlayoutHistoryTemplateFieldViewSet)
|
||||
router.register('preferences', PreferenceViewSet)
|
||||
router.register('schedule', ScheduleViewSet)
|
||||
router.register('service-registers', ServiceRegisterViewSet)
|
||||
router.register('sessions', SessionViewSet)
|
||||
router.register('shows', ShowViewSet)
|
||||
router.register('show-days', ShowDaysViewSet)
|
||||
router.register('show-hosts', ShowHostViewSet)
|
||||
router.register('show-instances', ShowInstanceViewSet)
|
||||
router.register('show-rebroadcasts', ShowRebroadcastViewSet)
|
||||
router.register('stream-settings', StreamSettingViewSet)
|
||||
router.register('users', UserViewSet)
|
||||
router.register('user-tokens', UserTokenViewSet)
|
||||
router.register('timestamps', TimestampViewSet)
|
||||
router.register('webstreams', WebstreamViewSet)
|
||||
router.register('webstream-metadata', WebstreamMetadataViewSet)
|
||||
router.register('celery-tasks', CeleryTaskViewSet)
|
||||
router.register('cloud-files', CloudFileViewSet)
|
||||
router.register('imported-podcasts', ImportedPodcastViewSet)
|
||||
router.register('podcasts', PodcastViewSet)
|
||||
router.register('podcast-episodes', PodcastEpisodeViewSet)
|
||||
router.register('station-podcasts', StationPodcastViewSet)
|
||||
router.register('third-party-track-references', ThirdPartyTrackReferenceViewSet)
|
||||
router.register('track-types', TrackTypeViewSet)
|
||||
router.register("smart-blocks", SmartBlockViewSet)
|
||||
router.register("smart-block-contents", SmartBlockContentViewSet)
|
||||
router.register("smart-block-criteria", SmartBlockCriteriaViewSet)
|
||||
router.register("countries", CountryViewSet)
|
||||
router.register("files", FileViewSet)
|
||||
router.register("listener-counts", ListenerCountViewSet)
|
||||
router.register("live-logs", LiveLogViewSet)
|
||||
router.register("login-attempts", LoginAttemptViewSet)
|
||||
router.register("mount-names", MountNameViewSet)
|
||||
router.register("music-dirs", MusicDirViewSet)
|
||||
router.register("playlists", PlaylistViewSet)
|
||||
router.register("playlist-contents", PlaylistContentViewSet)
|
||||
router.register("playout-history", PlayoutHistoryViewSet)
|
||||
router.register("playout-history-metadata", PlayoutHistoryMetadataViewSet)
|
||||
router.register("playout-history-templates", PlayoutHistoryTemplateViewSet)
|
||||
router.register("playout-history-template-fields", PlayoutHistoryTemplateFieldViewSet)
|
||||
router.register("preferences", PreferenceViewSet)
|
||||
router.register("schedule", ScheduleViewSet)
|
||||
router.register("service-registers", ServiceRegisterViewSet)
|
||||
router.register("sessions", SessionViewSet)
|
||||
router.register("shows", ShowViewSet)
|
||||
router.register("show-days", ShowDaysViewSet)
|
||||
router.register("show-hosts", ShowHostViewSet)
|
||||
router.register("show-instances", ShowInstanceViewSet)
|
||||
router.register("show-rebroadcasts", ShowRebroadcastViewSet)
|
||||
router.register("stream-settings", StreamSettingViewSet)
|
||||
router.register("users", UserViewSet)
|
||||
router.register("user-tokens", UserTokenViewSet)
|
||||
router.register("timestamps", TimestampViewSet)
|
||||
router.register("webstreams", WebstreamViewSet)
|
||||
router.register("webstream-metadata", WebstreamMetadataViewSet)
|
||||
router.register("celery-tasks", CeleryTaskViewSet)
|
||||
router.register("cloud-files", CloudFileViewSet)
|
||||
router.register("imported-podcasts", ImportedPodcastViewSet)
|
||||
router.register("podcasts", PodcastViewSet)
|
||||
router.register("podcast-episodes", PodcastEpisodeViewSet)
|
||||
router.register("station-podcasts", StationPodcastViewSet)
|
||||
router.register("third-party-track-references", ThirdPartyTrackReferenceViewSet)
|
||||
router.register("track-types", TrackTypeViewSet)
|
||||
|
||||
urlpatterns = [
|
||||
path('api/v2/', include(router.urls)),
|
||||
path('api/v2/version/', version),
|
||||
path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
|
||||
path("api/v2/", include(router.urls)),
|
||||
path("api/v2/version/", version),
|
||||
path("api-auth/", include("rest_framework.urls", namespace="rest_framework")),
|
||||
]
|
||||
|
|
|
@ -4,23 +4,27 @@ import sys
|
|||
import string
|
||||
import random
|
||||
|
||||
|
||||
def read_config_file(config_path):
|
||||
"""Parse the application's config file located at config_path."""
|
||||
config = configparser.ConfigParser()
|
||||
try:
|
||||
config.readfp(open(config_path))
|
||||
except IOError as e:
|
||||
print("Failed to open config file at {}: {}".format(config_path, e.strerror),
|
||||
file=sys.stderr)
|
||||
print(
|
||||
"Failed to open config file at {}: {}".format(config_path, e.strerror),
|
||||
file=sys.stderr,
|
||||
)
|
||||
raise e
|
||||
except Exception as e:
|
||||
print(e.strerror, file=sys.stderr)
|
||||
raise e
|
||||
return config
|
||||
|
||||
|
||||
def get_random_string(seed):
|
||||
"""Generates a random string based on the given seed"""
|
||||
choices = string.ascii_letters + string.digits + string.punctuation
|
||||
seed = seed.encode('utf-8')
|
||||
seed = seed.encode("utf-8")
|
||||
rand = random.Random(seed)
|
||||
return [rand.choice(choices) for i in range(16)]
|
||||
|
|
|
@ -10,220 +10,261 @@ from rest_framework.response import Response
|
|||
from .serializers import *
|
||||
from .permissions import IsAdminOrOwnUser
|
||||
|
||||
|
||||
class UserViewSet(viewsets.ModelViewSet):
|
||||
queryset = get_user_model().objects.all()
|
||||
serializer_class = UserSerializer
|
||||
permission_classes = [IsAdminOrOwnUser]
|
||||
model_permission_name = 'user'
|
||||
model_permission_name = "user"
|
||||
|
||||
|
||||
class SmartBlockViewSet(viewsets.ModelViewSet):
|
||||
queryset = SmartBlock.objects.all()
|
||||
serializer_class = SmartBlockSerializer
|
||||
model_permission_name = 'smartblock'
|
||||
model_permission_name = "smartblock"
|
||||
|
||||
|
||||
class SmartBlockContentViewSet(viewsets.ModelViewSet):
|
||||
queryset = SmartBlockContent.objects.all()
|
||||
serializer_class = SmartBlockContentSerializer
|
||||
model_permission_name = 'smartblockcontent'
|
||||
model_permission_name = "smartblockcontent"
|
||||
|
||||
|
||||
class SmartBlockCriteriaViewSet(viewsets.ModelViewSet):
|
||||
queryset = SmartBlockCriteria.objects.all()
|
||||
serializer_class = SmartBlockCriteriaSerializer
|
||||
model_permission_name = 'smartblockcriteria'
|
||||
model_permission_name = "smartblockcriteria"
|
||||
|
||||
|
||||
class CountryViewSet(viewsets.ModelViewSet):
|
||||
queryset = Country.objects.all()
|
||||
serializer_class = CountrySerializer
|
||||
model_permission_name = 'country'
|
||||
model_permission_name = "country"
|
||||
|
||||
|
||||
class FileViewSet(viewsets.ModelViewSet):
|
||||
queryset = File.objects.all()
|
||||
serializer_class = FileSerializer
|
||||
model_permission_name = 'file'
|
||||
model_permission_name = "file"
|
||||
|
||||
@action(detail=True, methods=['GET'])
|
||||
@action(detail=True, methods=["GET"])
|
||||
def download(self, request, pk=None):
|
||||
if pk is None:
|
||||
return Response('No file requested', status=status.HTTP_400_BAD_REQUEST)
|
||||
return Response("No file requested", status=status.HTTP_400_BAD_REQUEST)
|
||||
try:
|
||||
pk = int(pk)
|
||||
except ValueError:
|
||||
return Response('File ID should be an integer',
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
return Response(
|
||||
"File ID should be an integer", status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
|
||||
filename = get_object_or_404(File, pk=pk)
|
||||
directory = filename.directory
|
||||
path = os.path.join(directory.directory, filename.filepath)
|
||||
response = FileResponse(open(path, 'rb'), content_type=filename.mime)
|
||||
response = FileResponse(open(path, "rb"), content_type=filename.mime)
|
||||
return response
|
||||
|
||||
|
||||
class ListenerCountViewSet(viewsets.ModelViewSet):
|
||||
queryset = ListenerCount.objects.all()
|
||||
serializer_class = ListenerCountSerializer
|
||||
model_permission_name = 'listenercount'
|
||||
model_permission_name = "listenercount"
|
||||
|
||||
|
||||
class LiveLogViewSet(viewsets.ModelViewSet):
|
||||
queryset = LiveLog.objects.all()
|
||||
serializer_class = LiveLogSerializer
|
||||
model_permission_name = 'livelog'
|
||||
model_permission_name = "livelog"
|
||||
|
||||
|
||||
class LoginAttemptViewSet(viewsets.ModelViewSet):
|
||||
queryset = LoginAttempt.objects.all()
|
||||
serializer_class = LoginAttemptSerializer
|
||||
model_permission_name = 'loginattempt'
|
||||
model_permission_name = "loginattempt"
|
||||
|
||||
|
||||
class MountNameViewSet(viewsets.ModelViewSet):
|
||||
queryset = MountName.objects.all()
|
||||
serializer_class = MountNameSerializer
|
||||
model_permission_name = 'mountname'
|
||||
model_permission_name = "mountname"
|
||||
|
||||
|
||||
class MusicDirViewSet(viewsets.ModelViewSet):
|
||||
queryset = MusicDir.objects.all()
|
||||
serializer_class = MusicDirSerializer
|
||||
model_permission_name = 'musicdir'
|
||||
model_permission_name = "musicdir"
|
||||
|
||||
|
||||
class PlaylistViewSet(viewsets.ModelViewSet):
|
||||
queryset = Playlist.objects.all()
|
||||
serializer_class = PlaylistSerializer
|
||||
model_permission_name = 'playlist'
|
||||
model_permission_name = "playlist"
|
||||
|
||||
|
||||
class PlaylistContentViewSet(viewsets.ModelViewSet):
|
||||
queryset = PlaylistContent.objects.all()
|
||||
serializer_class = PlaylistContentSerializer
|
||||
model_permission_name = 'playlistcontent'
|
||||
model_permission_name = "playlistcontent"
|
||||
|
||||
|
||||
class PlayoutHistoryViewSet(viewsets.ModelViewSet):
|
||||
queryset = PlayoutHistory.objects.all()
|
||||
serializer_class = PlayoutHistorySerializer
|
||||
model_permission_name = 'playouthistory'
|
||||
model_permission_name = "playouthistory"
|
||||
|
||||
|
||||
class PlayoutHistoryMetadataViewSet(viewsets.ModelViewSet):
|
||||
queryset = PlayoutHistoryMetadata.objects.all()
|
||||
serializer_class = PlayoutHistoryMetadataSerializer
|
||||
model_permission_name = 'playouthistorymetadata'
|
||||
model_permission_name = "playouthistorymetadata"
|
||||
|
||||
|
||||
class PlayoutHistoryTemplateViewSet(viewsets.ModelViewSet):
|
||||
queryset = PlayoutHistoryTemplate.objects.all()
|
||||
serializer_class = PlayoutHistoryTemplateSerializer
|
||||
model_permission_name = 'playouthistorytemplate'
|
||||
model_permission_name = "playouthistorytemplate"
|
||||
|
||||
|
||||
class PlayoutHistoryTemplateFieldViewSet(viewsets.ModelViewSet):
|
||||
queryset = PlayoutHistoryTemplateField.objects.all()
|
||||
serializer_class = PlayoutHistoryTemplateFieldSerializer
|
||||
model_permission_name = 'playouthistorytemplatefield'
|
||||
model_permission_name = "playouthistorytemplatefield"
|
||||
|
||||
|
||||
class PreferenceViewSet(viewsets.ModelViewSet):
|
||||
queryset = Preference.objects.all()
|
||||
serializer_class = PreferenceSerializer
|
||||
model_permission_name = 'perference'
|
||||
model_permission_name = "perference"
|
||||
|
||||
|
||||
class ScheduleViewSet(viewsets.ModelViewSet):
|
||||
queryset = Schedule.objects.all()
|
||||
serializer_class = ScheduleSerializer
|
||||
filter_fields = ('starts', 'ends', 'playout_status', 'broadcasted')
|
||||
model_permission_name = 'schedule'
|
||||
filter_fields = ("starts", "ends", "playout_status", "broadcasted")
|
||||
model_permission_name = "schedule"
|
||||
|
||||
|
||||
class ServiceRegisterViewSet(viewsets.ModelViewSet):
|
||||
queryset = ServiceRegister.objects.all()
|
||||
serializer_class = ServiceRegisterSerializer
|
||||
model_permission_name = 'serviceregister'
|
||||
model_permission_name = "serviceregister"
|
||||
|
||||
|
||||
class SessionViewSet(viewsets.ModelViewSet):
|
||||
queryset = Session.objects.all()
|
||||
serializer_class = SessionSerializer
|
||||
model_permission_name = 'session'
|
||||
model_permission_name = "session"
|
||||
|
||||
|
||||
class ShowViewSet(viewsets.ModelViewSet):
|
||||
queryset = Show.objects.all()
|
||||
serializer_class = ShowSerializer
|
||||
model_permission_name = 'show'
|
||||
model_permission_name = "show"
|
||||
|
||||
|
||||
class ShowDaysViewSet(viewsets.ModelViewSet):
|
||||
queryset = ShowDays.objects.all()
|
||||
serializer_class = ShowDaysSerializer
|
||||
model_permission_name = 'showdays'
|
||||
model_permission_name = "showdays"
|
||||
|
||||
|
||||
class ShowHostViewSet(viewsets.ModelViewSet):
|
||||
queryset = ShowHost.objects.all()
|
||||
serializer_class = ShowHostSerializer
|
||||
model_permission_name = 'showhost'
|
||||
model_permission_name = "showhost"
|
||||
|
||||
|
||||
class ShowInstanceViewSet(viewsets.ModelViewSet):
|
||||
queryset = ShowInstance.objects.all()
|
||||
serializer_class = ShowInstanceSerializer
|
||||
model_permission_name = 'showinstance'
|
||||
model_permission_name = "showinstance"
|
||||
|
||||
|
||||
class ShowRebroadcastViewSet(viewsets.ModelViewSet):
|
||||
queryset = ShowRebroadcast.objects.all()
|
||||
serializer_class = ShowRebroadcastSerializer
|
||||
model_permission_name = 'showrebroadcast'
|
||||
model_permission_name = "showrebroadcast"
|
||||
|
||||
|
||||
class StreamSettingViewSet(viewsets.ModelViewSet):
|
||||
queryset = StreamSetting.objects.all()
|
||||
serializer_class = StreamSettingSerializer
|
||||
model_permission_name = 'streamsetting'
|
||||
model_permission_name = "streamsetting"
|
||||
|
||||
|
||||
class UserTokenViewSet(viewsets.ModelViewSet):
|
||||
queryset = UserToken.objects.all()
|
||||
serializer_class = UserTokenSerializer
|
||||
model_permission_name = 'usertoken'
|
||||
model_permission_name = "usertoken"
|
||||
|
||||
|
||||
class TimestampViewSet(viewsets.ModelViewSet):
|
||||
queryset = Timestamp.objects.all()
|
||||
serializer_class = TimestampSerializer
|
||||
model_permission_name = 'timestamp'
|
||||
model_permission_name = "timestamp"
|
||||
|
||||
|
||||
class WebstreamViewSet(viewsets.ModelViewSet):
|
||||
queryset = Webstream.objects.all()
|
||||
serializer_class = WebstreamSerializer
|
||||
model_permission_name = 'webstream'
|
||||
model_permission_name = "webstream"
|
||||
|
||||
|
||||
class WebstreamMetadataViewSet(viewsets.ModelViewSet):
|
||||
queryset = WebstreamMetadata.objects.all()
|
||||
serializer_class = WebstreamMetadataSerializer
|
||||
model_permission_name = 'webstreametadata'
|
||||
model_permission_name = "webstreametadata"
|
||||
|
||||
|
||||
class CeleryTaskViewSet(viewsets.ModelViewSet):
|
||||
queryset = CeleryTask.objects.all()
|
||||
serializer_class = CeleryTaskSerializer
|
||||
model_permission_name = 'celerytask'
|
||||
model_permission_name = "celerytask"
|
||||
|
||||
|
||||
class CloudFileViewSet(viewsets.ModelViewSet):
|
||||
queryset = CloudFile.objects.all()
|
||||
serializer_class = CloudFileSerializer
|
||||
model_permission_name = 'cloudfile'
|
||||
model_permission_name = "cloudfile"
|
||||
|
||||
|
||||
class ImportedPodcastViewSet(viewsets.ModelViewSet):
|
||||
queryset = ImportedPodcast.objects.all()
|
||||
serializer_class = ImportedPodcastSerializer
|
||||
model_permission_name = 'importedpodcast'
|
||||
model_permission_name = "importedpodcast"
|
||||
|
||||
|
||||
class PodcastViewSet(viewsets.ModelViewSet):
|
||||
queryset = Podcast.objects.all()
|
||||
serializer_class = PodcastSerializer
|
||||
model_permission_name = 'podcast'
|
||||
model_permission_name = "podcast"
|
||||
|
||||
|
||||
class PodcastEpisodeViewSet(viewsets.ModelViewSet):
|
||||
queryset = PodcastEpisode.objects.all()
|
||||
serializer_class = PodcastEpisodeSerializer
|
||||
model_permission_name = 'podcastepisode'
|
||||
model_permission_name = "podcastepisode"
|
||||
|
||||
|
||||
class StationPodcastViewSet(viewsets.ModelViewSet):
|
||||
queryset = StationPodcast.objects.all()
|
||||
serializer_class = StationPodcastSerializer
|
||||
model_permission_name = 'station'
|
||||
model_permission_name = "station"
|
||||
|
||||
|
||||
class ThirdPartyTrackReferenceViewSet(viewsets.ModelViewSet):
|
||||
queryset = ThirdPartyTrackReference.objects.all()
|
||||
serializer_class = ThirdPartyTrackReferenceSerializer
|
||||
model_permission_name = 'thirdpartytrackreference'
|
||||
model_permission_name = "thirdpartytrackreference"
|
||||
|
||||
|
||||
class TrackTypeViewSet(viewsets.ModelViewSet):
|
||||
queryset = TrackType.objects.all()
|
||||
serializer_class = TrackTypeSerializer
|
||||
model_permission_name = 'tracktype'
|
||||
model_permission_name = "tracktype"
|
||||
|
||||
@api_view(['GET'])
|
||||
@permission_classes((AllowAny, ))
|
||||
|
||||
@api_view(["GET"])
|
||||
@permission_classes((AllowAny,))
|
||||
def version(request, *args, **kwargs):
|
||||
return Response({'api_version': settings.API_VERSION})
|
||||
return Response({"api_version": settings.API_VERSION})
|
||||
|
|
|
@ -12,6 +12,6 @@ import os
|
|||
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'libretimeapi.settings')
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "libretimeapi.settings")
|
||||
|
||||
application = get_wsgi_application()
|
||||
|
|
32
api/setup.py
32
api/setup.py
|
@ -8,26 +8,26 @@ print(script_path)
|
|||
os.chdir(script_path)
|
||||
|
||||
setup(
|
||||
name='libretime-api',
|
||||
version='2.0.0a1',
|
||||
name="libretime-api",
|
||||
version="2.0.0a1",
|
||||
packages=find_packages(),
|
||||
include_package_data=True,
|
||||
description='LibreTime API backend server',
|
||||
url='https://github.com/LibreTime/libretime',
|
||||
author='LibreTime Contributors',
|
||||
scripts=['bin/libretime-api'],
|
||||
description="LibreTime API backend server",
|
||||
url="https://github.com/LibreTime/libretime",
|
||||
author="LibreTime Contributors",
|
||||
scripts=["bin/libretime-api"],
|
||||
install_requires=[
|
||||
'coreapi',
|
||||
'Django~=3.0',
|
||||
'djangorestframework',
|
||||
'django-url-filter',
|
||||
'markdown',
|
||||
'model_bakery',
|
||||
'psycopg2',
|
||||
"coreapi",
|
||||
"Django~=3.0",
|
||||
"djangorestframework",
|
||||
"django-url-filter",
|
||||
"markdown",
|
||||
"model_bakery",
|
||||
"psycopg2",
|
||||
],
|
||||
project_urls={
|
||||
'Bug Tracker': 'https://github.com/LibreTime/libretime/issues',
|
||||
'Documentation': 'https://libretime.org',
|
||||
'Source Code': 'https://github.com/LibreTime/libretime',
|
||||
"Bug Tracker": "https://github.com/LibreTime/libretime/issues",
|
||||
"Documentation": "https://libretime.org",
|
||||
"Source Code": "https://github.com/LibreTime/libretime",
|
||||
},
|
||||
)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue