mirror of
https://github.com/fergalmoran/dss.api.git
synced 2025-12-22 09:18:13 +00:00
Added audio url
This commit is contained in:
0
angular_upgrade.md
Executable file → Normal file
0
angular_upgrade.md
Executable file → Normal file
0
apache/django_live.wsgi
Executable file → Normal file
0
apache/django_live.wsgi
Executable file → Normal file
0
api/__init__.py
Executable file → Normal file
0
api/__init__.py
Executable file → Normal file
0
api/pipeline.py
Executable file → Normal file
0
api/pipeline.py
Executable file → Normal file
136
api/serializers.py
Executable file → Normal file
136
api/serializers.py
Executable file → Normal file
@@ -87,6 +87,7 @@ class InlineUserProfileSerializer(serializers.ModelSerializer):
|
||||
|
||||
return n
|
||||
|
||||
|
||||
class LikeSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = UserProfile
|
||||
@@ -98,6 +99,11 @@ class LikeSerializer(serializers.ModelSerializer):
|
||||
display_name = serializers.ReadOnlyField(source='get_nice_name')
|
||||
|
||||
|
||||
class PlaylistSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Playlist
|
||||
|
||||
|
||||
class FavouriteSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = UserProfile
|
||||
@@ -160,6 +166,7 @@ class MixSerializer(serializers.ModelSerializer):
|
||||
'description',
|
||||
'user',
|
||||
'duration',
|
||||
'audio_url',
|
||||
'waveform_url',
|
||||
'waveform_progress_url',
|
||||
'mix_image',
|
||||
@@ -170,6 +177,7 @@ class MixSerializer(serializers.ModelSerializer):
|
||||
'genres',
|
||||
'likes',
|
||||
'favourites',
|
||||
'playlists',
|
||||
'plays',
|
||||
'downloads',
|
||||
'is_liked',
|
||||
@@ -179,6 +187,7 @@ class MixSerializer(serializers.ModelSerializer):
|
||||
|
||||
slug = serializers.ReadOnlyField(required=False)
|
||||
user = InlineUserProfileSerializer(read_only=True)
|
||||
audio_url = serializers.ReadOnlyField(source='get_stream_url')
|
||||
waveform_url = serializers.ReadOnlyField(source='get_waveform_url')
|
||||
waveform_progress_url = serializers.ReadOnlyField(source='get_waveform_progress_url')
|
||||
mix_image = serializers.ReadOnlyField(source='get_image_url')
|
||||
@@ -187,6 +196,7 @@ class MixSerializer(serializers.ModelSerializer):
|
||||
genres = GenreSerializer(many=True, required=False, read_only=True)
|
||||
likes = LikeSerializer(many=True, required=False, read_only=True) # slug_field='slug', many=True, read_only=True)
|
||||
favourites = FavouriteSerializer(many=True, required=False, read_only=True) # slug_field='slug', many=True, read_only=True)
|
||||
playlists = serializers.SerializerMethodField()
|
||||
plays = InlineActivityPlaySerializer(many=True, read_only=True, source='activity_plays')
|
||||
downloads = InlineActivityDownloadSerializer(read_only=True, source='activity_downloads')
|
||||
is_liked = serializers.SerializerMethodField(read_only=True)
|
||||
@@ -196,53 +206,13 @@ class MixSerializer(serializers.ModelSerializer):
|
||||
# all nested representations need to be serialized separately here
|
||||
try:
|
||||
# get any likes that aren't in passed bundle
|
||||
likes = self.initial_data['likes']
|
||||
unliked = instance.likes.exclude(user__userprofile__slug__in=[l['slug'] for l in likes])
|
||||
for ul in unliked:
|
||||
# check that the user removing the like is an instance of the current user
|
||||
# for now, only the current user can like stuff
|
||||
if ul == self.context['request'].user.userprofile:
|
||||
instance.update_liked(ul, False)
|
||||
self._update_likes(instance)
|
||||
|
||||
for like in likes:
|
||||
# check that the user adding the like is an instance of the current user
|
||||
# for now, only the current user can like stuff
|
||||
try:
|
||||
user = UserProfile.objects.get(slug=like['slug'])
|
||||
if user is not None and user == self.context['request'].user.userprofile:
|
||||
instance.update_liked(user, True)
|
||||
self._update_favourites(instance)
|
||||
|
||||
except UserProfile.DoesNotExist:
|
||||
pass
|
||||
self._update_genres(instance)
|
||||
|
||||
favourites = self.initial_data['favourites']
|
||||
unfavourited = instance.favourites.exclude(user__userprofile__slug__in=[f['slug'] for f in favourites])
|
||||
for uf in unfavourited:
|
||||
# check that the user removing the like is an instance of the current user
|
||||
# for now, only the current user can like stuff
|
||||
if uf == self.context['request'].user.userprofile:
|
||||
instance.update_favourite(uf, False)
|
||||
|
||||
for favourite in favourites:
|
||||
# check that the user adding the like is an instance of the current user
|
||||
# for now, only the current user can like stuff
|
||||
try:
|
||||
user = UserProfile.objects.get(slug=favourite['slug'])
|
||||
if user is not None and user == self.context['request'].user.userprofile:
|
||||
instance.update_favourite(user, True)
|
||||
|
||||
except UserProfile.DoesNotExist:
|
||||
pass
|
||||
|
||||
genres = self.initial_data['genres']
|
||||
instance.genres.clear()
|
||||
for genre in genres:
|
||||
try:
|
||||
g = Genre.objects.get(slug=genre.get('slug'))
|
||||
instance.genres.add(g)
|
||||
except Genre.DoesNotExist:
|
||||
""" Possibly allow adding genres here """
|
||||
pass
|
||||
self._update_playlists(instance)
|
||||
|
||||
validated_data.pop('genres', None)
|
||||
|
||||
@@ -259,6 +229,72 @@ class MixSerializer(serializers.ModelSerializer):
|
||||
except Exception as ex:
|
||||
raise ex
|
||||
|
||||
def _update_genres(self, instance):
|
||||
genres = self.initial_data['genres']
|
||||
instance.genres.clear()
|
||||
for genre in genres:
|
||||
try:
|
||||
g = Genre.objects.get(slug=genre.get('slug'))
|
||||
instance.genres.add(g)
|
||||
except Genre.DoesNotExist:
|
||||
""" Possibly allow adding genres here """
|
||||
pass
|
||||
|
||||
def _update_playlists(self, instance):
|
||||
try:
|
||||
user = self.context['request'].user
|
||||
playlists = self.initial_data['playlists']
|
||||
removed = user.userprofile.playlists.exclude(slug__in=[f['slug'] for f in playlists])
|
||||
if user.is_authenticated():
|
||||
|
||||
for r in removed:
|
||||
playlist = Playlist.objects.get(slug=r.slug)
|
||||
playlist.mixes.remove(instance)
|
||||
playlist.save()
|
||||
|
||||
for p in playlists:
|
||||
try:
|
||||
playlist = Playlist.objects.get(slug=p['slug'])
|
||||
playlist.mixes.add(instance)
|
||||
playlist.save()
|
||||
except Playlist.DoesNotExist:
|
||||
print("Playlist %s not found".format(p['slug']))
|
||||
pass
|
||||
else:
|
||||
pass
|
||||
except Exception as ex:
|
||||
print(ex)
|
||||
|
||||
def _update_favourites(self, instance):
|
||||
favourites = self.initial_data['favourites']
|
||||
unfavourited = instance.favourites.exclude(user__userprofile__slug__in=[f['slug'] for f in favourites])
|
||||
for uf in unfavourited:
|
||||
if uf == self.context['request'].user.userprofile:
|
||||
instance.update_favourite(uf, False)
|
||||
for favourite in favourites:
|
||||
try:
|
||||
user = UserProfile.objects.get(slug=favourite['slug'])
|
||||
if user is not None and user == self.context['request'].user.userprofile:
|
||||
instance.update_favourite(user, True)
|
||||
|
||||
except UserProfile.DoesNotExist:
|
||||
pass
|
||||
|
||||
def _update_likes(self, instance):
|
||||
likes = self.initial_data['likes']
|
||||
unliked = instance.likes.exclude(user__userprofile__slug__in=[l['slug'] for l in likes])
|
||||
for ul in unliked:
|
||||
if ul == self.context['request'].user.userprofile:
|
||||
instance.update_liked(ul, False)
|
||||
for like in likes:
|
||||
try:
|
||||
user = UserProfile.objects.get(slug=like['slug'])
|
||||
if user is not None and user == self.context['request'].user.userprofile:
|
||||
instance.update_liked(user, True)
|
||||
|
||||
except UserProfile.DoesNotExist:
|
||||
pass
|
||||
|
||||
def is_valid(self, raise_exception=False):
|
||||
return super(MixSerializer, self).is_valid(raise_exception)
|
||||
|
||||
@@ -284,6 +320,14 @@ class MixSerializer(serializers.ModelSerializer):
|
||||
user = self.context['request'].user
|
||||
return obj.is_liked(user) if user.is_authenticated() else False
|
||||
|
||||
def get_playlists(self, obj):
|
||||
user = self.context['request'].user
|
||||
if user.is_authenticated():
|
||||
playlists = user.userprofile.playlists.filter(mixes__in=[obj])
|
||||
return list(playlists.values('slug'))
|
||||
else:
|
||||
return []
|
||||
|
||||
|
||||
class UserProfileSerializer(serializers.ModelSerializer):
|
||||
roles = serializers.SerializerMethodField()
|
||||
@@ -581,7 +625,3 @@ class BlogSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Blog
|
||||
|
||||
|
||||
class PlaylistSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Playlist
|
||||
|
||||
0
api/tests.py
Executable file → Normal file
0
api/tests.py
Executable file → Normal file
1
api/urls.py
Executable file → Normal file
1
api/urls.py
Executable file → Normal file
@@ -22,6 +22,7 @@ router.register(r'messages', views.MessageViewSet, base_name='messages')
|
||||
router.register(r'shows', views.ShowViewSet, base_name='shows')
|
||||
router.register(r'blog', views.BlogViewSet, base_name='shows')
|
||||
router.register(r'playlist', views.PlaylistViewSet, base_name='playlists')
|
||||
router.register(r'playlist', views.PlaylistViewSet, base_name='playlists')
|
||||
|
||||
router.register(r'user', views.UserProfileViewSet)
|
||||
router.register(r'mix', views.MixViewSet)
|
||||
|
||||
2
api/views.py
Executable file → Normal file
2
api/views.py
Executable file → Normal file
@@ -384,6 +384,6 @@ class PlaylistViewSet(viewsets.ModelViewSet):
|
||||
|
||||
def get_queryset(self):
|
||||
if self.request.user.is_authenticated:
|
||||
return self.queryset.get(user=self.request.user.userprofile)
|
||||
return self.queryset.filter(user=self.request.user.userprofile)
|
||||
|
||||
return Response(status=HTTP_401_UNAUTHORIZED)
|
||||
|
||||
0
bin/wav2png
Executable file → Normal file
0
bin/wav2png
Executable file → Normal file
0
clean_thumbnails
Executable file → Normal file
0
clean_thumbnails
Executable file → Normal file
0
core/__init__.py
Executable file → Normal file
0
core/__init__.py
Executable file → Normal file
0
core/analytics/__init__.py
Executable file → Normal file
0
core/analytics/__init__.py
Executable file → Normal file
0
core/analytics/google.py
Executable file → Normal file
0
core/analytics/google.py
Executable file → Normal file
0
core/decorators.py
Executable file → Normal file
0
core/decorators.py
Executable file → Normal file
0
core/realtime/__init__.py
Executable file → Normal file
0
core/realtime/__init__.py
Executable file → Normal file
0
core/realtime/activity.py
Executable file → Normal file
0
core/realtime/activity.py
Executable file → Normal file
0
core/serialisers/__init__.py
Executable file → Normal file
0
core/serialisers/__init__.py
Executable file → Normal file
0
core/utils/__init__.py
Executable file → Normal file
0
core/utils/__init__.py
Executable file → Normal file
0
core/utils/audio/__init__.py
Executable file → Normal file
0
core/utils/audio/__init__.py
Executable file → Normal file
0
core/utils/audio/mp3.py
Executable file → Normal file
0
core/utils/audio/mp3.py
Executable file → Normal file
0
core/utils/cdn.py
Executable file → Normal file
0
core/utils/cdn.py
Executable file → Normal file
0
core/utils/file.py
Executable file → Normal file
0
core/utils/file.py
Executable file → Normal file
0
core/utils/html.py
Executable file → Normal file
0
core/utils/html.py
Executable file → Normal file
0
core/utils/ice.py
Executable file → Normal file
0
core/utils/ice.py
Executable file → Normal file
0
core/utils/live.py
Executable file → Normal file
0
core/utils/live.py
Executable file → Normal file
0
core/utils/string.py
Executable file → Normal file
0
core/utils/string.py
Executable file → Normal file
0
core/utils/url.py
Executable file → Normal file
0
core/utils/url.py
Executable file → Normal file
0
core/utils/waveform.py
Executable file → Normal file
0
core/utils/waveform.py
Executable file → Normal file
0
core/widgets/__init__.py
Executable file → Normal file
0
core/widgets/__init__.py
Executable file → Normal file
0
core/widgets/upload.py
Executable file → Normal file
0
core/widgets/upload.py
Executable file → Normal file
0
dss/__init__.py
Executable file → Normal file
0
dss/__init__.py
Executable file → Normal file
@@ -6,7 +6,7 @@ DEBUG = ast.literal_eval(os.environ.get('IS_DEBUG', 'True'))
|
||||
DSS_TEMP_PATH = os.environ.get('DSS_TEMP_PATH', '/tmp/')
|
||||
DSS_LAME_PATH = os.environ.get('DSS_LAME_PATH', '/usr/bin/sox')
|
||||
DSS_WAVE_PATH = os.environ.get('DSS_WAVE_PATH',
|
||||
'/home/fergalm/Dropbox/development/deepsouthsounds.com/dss.lib/wav2png/bin/Linux/wav2png')
|
||||
'/home/fergalm/dev/personal/deepsouthsounds.com/dss.lib/wav2png/bin/Linux/wav2png')
|
||||
GEOIP_PATH = os.environ.get('GEOIP_PATH', '/home/fergalm/Dropbox/Private/deepsouthsounds.com/working/geolite')
|
||||
|
||||
DATABASE_PASSWORD = os.environ.get('DATABASE_PASSWORD', 'deepsouthsounds')
|
||||
@@ -17,7 +17,7 @@ DATABASE_HOST = os.environ.get('DATABASE_HOST', 'localhost')
|
||||
STATIC_URL = '/assets/'
|
||||
|
||||
MEDIA_ROOT = os.environ.get('MEDIA_ROOT', '/mnt/dev/deepsouthsounds.com/media')
|
||||
STATIC_ROOT = os.environ.get('STATIC_ROOT', '/home/fergalm/Dropbox/development/deepsouthsounds.com/cache/static')
|
||||
STATIC_ROOT = os.environ.get('STATIC_ROOT', '/home/fergalm/dev/personal/deepsouthsounds.com/cache/static')
|
||||
CACHE_ROOT = os.environ.get('CACHE_ROOT', '/mnt/dev/deepsouthsounds.com/cache')
|
||||
|
||||
MEDIA_URL = os.environ.get('MEDIA_URL', 'http://localhost/DSSMedia/') # '{0}media/'.format(CDN_URL)
|
||||
@@ -40,7 +40,7 @@ MANDRILL_API_KEY = os.environ.get('MANDRILL_API_KEY', '')
|
||||
|
||||
FACEBOOK_API_VERSION = os.environ.get('FACEBOOK_API_VERSION', '2.5')
|
||||
GOOGLE_CREDENTIALS = os.environ.get('GOOGLE_CREDENTIALS',
|
||||
'/home/fergalm/Dropbox/development/deepsouthsounds.com/dss.api/googleapikey.json')
|
||||
'/home/fergalm/dev/personal/deepsouthsounds.com/dss.api/googleapikey.json')
|
||||
SOCIAL_AUTH_FACEBOOK_KEY = os.environ.get('SOCIAL_AUTH_FACEBOOK_KEY', '')
|
||||
SOCIAL_AUTH_FACEBOOK_SECRET = os.environ.get('SOCIAL_AUTH_FACEBOOK_SECRET', '')
|
||||
|
||||
|
||||
0
dss/logsettings.py
Executable file → Normal file
0
dss/logsettings.py
Executable file → Normal file
0
dss/paymentsettings.py
Executable file → Normal file
0
dss/paymentsettings.py
Executable file → Normal file
0
dss/pipelinesettings.py
Executable file → Normal file
0
dss/pipelinesettings.py
Executable file → Normal file
0
dss/psa.py
Executable file → Normal file
0
dss/psa.py
Executable file → Normal file
0
dss/settings.py
Executable file → Normal file
0
dss/settings.py
Executable file → Normal file
0
dss/urls.py
Executable file → Normal file
0
dss/urls.py
Executable file → Normal file
0
dss/warning_settings.py
Executable file → Normal file
0
dss/warning_settings.py
Executable file → Normal file
0
dss/wsgi.py
Executable file → Normal file
0
dss/wsgi.py
Executable file → Normal file
0
pip_upgrade.py
Executable file → Normal file
0
pip_upgrade.py
Executable file → Normal file
0
requirements.txt
Executable file → Normal file
0
requirements.txt
Executable file → Normal file
0
run_celery.sh
Executable file → Normal file
0
run_celery.sh
Executable file → Normal file
0
run_web.sh
Executable file → Normal file
0
run_web.sh
Executable file → Normal file
0
spa/__init__.py
Executable file → Normal file
0
spa/__init__.py
Executable file → Normal file
0
spa/admin.py
Executable file → Normal file
0
spa/admin.py
Executable file → Normal file
0
spa/blog/urls.py
Executable file → Normal file
0
spa/blog/urls.py
Executable file → Normal file
0
spa/blog/views.py
Executable file → Normal file
0
spa/blog/views.py
Executable file → Normal file
0
spa/embedding/__init__.py
Executable file → Normal file
0
spa/embedding/__init__.py
Executable file → Normal file
0
spa/embedding/urls.py
Executable file → Normal file
0
spa/embedding/urls.py
Executable file → Normal file
0
spa/embedding/views.py
Executable file → Normal file
0
spa/embedding/views.py
Executable file → Normal file
0
spa/management/__init__.py
Executable file → Normal file
0
spa/management/__init__.py
Executable file → Normal file
0
spa/management/commands/__init__.py
Executable file → Normal file
0
spa/management/commands/__init__.py
Executable file → Normal file
0
spa/management/commands/__template_Debug.py
Executable file → Normal file
0
spa/management/commands/__template_Debug.py
Executable file → Normal file
0
spa/management/commands/__timeside_waveforms.py
Executable file → Normal file
0
spa/management/commands/__timeside_waveforms.py
Executable file → Normal file
0
spa/management/commands/add_user_uid.py
Executable file → Normal file
0
spa/management/commands/add_user_uid.py
Executable file → Normal file
0
spa/management/commands/archive_mixes.py
Executable file → Normal file
0
spa/management/commands/archive_mixes.py
Executable file → Normal file
2
spa/management/commands/azure_util.py
Executable file → Normal file
2
spa/management/commands/azure_util.py
Executable file → Normal file
@@ -22,7 +22,7 @@ def _check_missing_mixes():
|
||||
for m in ms:
|
||||
url = m.get_download_url()
|
||||
if not cdn.file_exists(url):
|
||||
file = '/mnt/dev/working/Dropbox/Development/deepsouthsounds.com/media/mixes/{0}.mp3'.format(m.uid)
|
||||
file = '/mnt/dev/working/deepsouthsounds.com/media/mixes/{0}.mp3'.format(m.uid)
|
||||
if os.path.isfile(file):
|
||||
print(('* {0}'.format(file)))
|
||||
# cdn.upload_file_to_azure(file, '{0}.mp3'.format(m.uid), 'mixes')
|
||||
|
||||
0
spa/management/commands/create_notifications.py
Executable file → Normal file
0
spa/management/commands/create_notifications.py
Executable file → Normal file
0
spa/management/commands/debugHumanize.py
Executable file → Normal file
0
spa/management/commands/debugHumanize.py
Executable file → Normal file
0
spa/management/commands/debugRelations.py
Executable file → Normal file
0
spa/management/commands/debugRelations.py
Executable file → Normal file
0
spa/management/commands/debugUserProfile.py
Executable file → Normal file
0
spa/management/commands/debugUserProfile.py
Executable file → Normal file
0
spa/management/commands/deletefailed.py
Executable file → Normal file
0
spa/management/commands/deletefailed.py
Executable file → Normal file
0
spa/management/commands/deleteorphanmp3.py
Executable file → Normal file
0
spa/management/commands/deleteorphanmp3.py
Executable file → Normal file
0
spa/management/commands/fake_comment_timeindex.py
Executable file → Normal file
0
spa/management/commands/fake_comment_timeindex.py
Executable file → Normal file
0
spa/management/commands/get_avatars.py
Executable file → Normal file
0
spa/management/commands/get_avatars.py
Executable file → Normal file
0
spa/management/commands/processmix.py
Executable file → Normal file
0
spa/management/commands/processmix.py
Executable file → Normal file
0
spa/management/commands/tidy_cdn.py
Executable file → Normal file
0
spa/management/commands/tidy_cdn.py
Executable file → Normal file
0
spa/management/commands/waveforms.py
Executable file → Normal file
0
spa/management/commands/waveforms.py
Executable file → Normal file
0
spa/management/commands/zoom_convert_waveforms.py
Executable file → Normal file
0
spa/management/commands/zoom_convert_waveforms.py
Executable file → Normal file
0
spa/middleware/__init__.py
Executable file → Normal file
0
spa/middleware/__init__.py
Executable file → Normal file
0
spa/middleware/sqlprinter.py
Executable file → Normal file
0
spa/middleware/sqlprinter.py
Executable file → Normal file
0
spa/middleware/stripwhitespace.py
Executable file → Normal file
0
spa/middleware/stripwhitespace.py
Executable file → Normal file
0
spa/middleware/uploadify.py
Executable file → Normal file
0
spa/middleware/uploadify.py
Executable file → Normal file
0
spa/models/__init__.py
Executable file → Normal file
0
spa/models/__init__.py
Executable file → Normal file
0
spa/models/_lookup.py
Executable file → Normal file
0
spa/models/_lookup.py
Executable file → Normal file
0
spa/models/activity.py
Executable file → Normal file
0
spa/models/activity.py
Executable file → Normal file
0
spa/models/basemodel.py
Executable file → Normal file
0
spa/models/basemodel.py
Executable file → Normal file
0
spa/models/chatmessage.py
Executable file → Normal file
0
spa/models/chatmessage.py
Executable file → Normal file
0
spa/models/comment.py
Executable file → Normal file
0
spa/models/comment.py
Executable file → Normal file
0
spa/models/fields.py
Executable file → Normal file
0
spa/models/fields.py
Executable file → Normal file
0
spa/models/genre.py
Executable file → Normal file
0
spa/models/genre.py
Executable file → Normal file
0
spa/models/label.py
Executable file → Normal file
0
spa/models/label.py
Executable file → Normal file
0
spa/models/managers/QueuedActivityModelManager.py
Executable file → Normal file
0
spa/models/managers/QueuedActivityModelManager.py
Executable file → Normal file
0
spa/models/managers/__init__.py
Executable file → Normal file
0
spa/models/managers/__init__.py
Executable file → Normal file
0
spa/models/mix.py
Executable file → Normal file
0
spa/models/mix.py
Executable file → Normal file
0
spa/models/notification.py
Executable file → Normal file
0
spa/models/notification.py
Executable file → Normal file
6
spa/models/playlist.py
Executable file → Normal file
6
spa/models/playlist.py
Executable file → Normal file
@@ -25,6 +25,12 @@ class Playlist(BaseModel):
|
||||
|
||||
objects = PlaylistManager()
|
||||
|
||||
def __str__(self):
|
||||
return self.__unicode__().encode('utf-8')
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
|
||||
if not self.id:
|
||||
self.slug = unique_slugify(self, self.name)
|
||||
|
||||
0
spa/models/purchaselink.py
Executable file → Normal file
0
spa/models/purchaselink.py
Executable file → Normal file
0
spa/models/release.py
Executable file → Normal file
0
spa/models/release.py
Executable file → Normal file
0
spa/models/show.py
Executable file → Normal file
0
spa/models/show.py
Executable file → Normal file
0
spa/models/tracklist.py
Executable file → Normal file
0
spa/models/tracklist.py
Executable file → Normal file
0
spa/models/userprofile.py
Executable file → Normal file
0
spa/models/userprofile.py
Executable file → Normal file
0
spa/models/venue.py
Executable file → Normal file
0
spa/models/venue.py
Executable file → Normal file
0
spa/signals.py
Executable file → Normal file
0
spa/signals.py
Executable file → Normal file
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user