mirror of
https://github.com/fergalmoran/dss.api.git
synced 2025-12-28 04:09:51 +00:00
Pre-merge
This commit is contained in:
@@ -19,10 +19,9 @@ ADD . /code/
|
||||
RUN apt-get update && apt-get install -y sox lame vim \
|
||||
libboost-program-options-dev libsox-fmt-mp3 postgresql-client rsync openssh-client
|
||||
|
||||
RUN pip uninstall azure
|
||||
RUN pip install -r requirements.txt
|
||||
|
||||
RUN adduser --disabled-password --gecos '' djworker
|
||||
RUN chown djworker /files -R
|
||||
RUN chown djworker /srv/logs -R
|
||||
RUN export PATH=$PATH:/mnt/bin/
|
||||
RUN export PATH=$PATH:/mnt/bin/
|
||||
|
||||
@@ -6,6 +6,7 @@ from dss import settings
|
||||
from spa import models
|
||||
from spa.models import Activity, Message
|
||||
from spa.models.activity import ActivityDownload, ActivityPlay
|
||||
from spa.models.blog import Blog
|
||||
from spa.models.genre import Genre
|
||||
from spa.models.notification import Notification
|
||||
from spa.models.show import Show
|
||||
@@ -509,3 +510,10 @@ class ShowSerializer(serializers.ModelSerializer):
|
||||
)
|
||||
"""
|
||||
|
||||
|
||||
class BlogSerializer(serializers.ModelSerializer):
|
||||
slug = serializers.ReadOnlyField(required=False)
|
||||
user = InlineUserProfileSerializer(read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = Blog
|
||||
|
||||
@@ -23,6 +23,7 @@ router.register(r'activity', views.ActivityViewSet, base_name='activity')
|
||||
router.register(r'genre', views.GenreViewSet, base_name='genre')
|
||||
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')
|
||||
|
||||
|
||||
class DebugView(APIView):
|
||||
|
||||
12
api/views.py
12
api/views.py
@@ -20,6 +20,7 @@ from api import serializers
|
||||
from dss import settings
|
||||
from spa import tasks
|
||||
from spa.models import Message
|
||||
from spa.models.blog import Blog
|
||||
from spa.models.genre import Genre
|
||||
from spa.models.activity import ActivityPlay
|
||||
from spa.models.mix import Mix
|
||||
@@ -217,7 +218,7 @@ class PartialMixUploadView(views.APIView):
|
||||
(
|
||||
tasks.create_waveform_task.s(input_file, uid) |
|
||||
tasks.upload_to_cdn_task.subtask(('mp3', uid, 'mixes'), immutable=True) |
|
||||
tasks.upload_to_cdn_task.subtask(('png', uid, 'waveforms'), immutable=True) |
|
||||
tasks.upload_to_cdn_task.subtask (('png', uid, 'waveforms'), immutable=True) |
|
||||
tasks.notify_subscriber.subtask((session_id, uid), immutable=True)
|
||||
).delay()
|
||||
logger.debug("Waveform task started")
|
||||
@@ -348,3 +349,12 @@ class ShowViewSet(viewsets.ModelViewSet):
|
||||
return Response(status=HTTP_400_BAD_REQUEST, data='Performer not found')
|
||||
except Exception as ex:
|
||||
return Response(status=HTTP_500_INTERNAL_SERVER_ERROR, data=ex)
|
||||
|
||||
|
||||
class BlogViewSet(viewsets.ModelViewSet):
|
||||
queryset = Blog.objects.all()
|
||||
serializer_class = serializers.BlogSerializer
|
||||
lookup_field = 'slug'
|
||||
|
||||
def perform_create(self, serializer):
|
||||
serializer.save(user=self.request.user.userprofile)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
from requests.packages.urllib3.connection import ConnectionError
|
||||
from dss import settings
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
import os
|
||||
import logging
|
||||
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
import os
|
||||
|
||||
DEBUG = True
|
||||
if os.name == 'posix':
|
||||
DSS_TEMP_PATH = "/tmp/"
|
||||
DSS_LAME_PATH = "sox"
|
||||
DSS_WAVE_PATH = "wav2png"
|
||||
else:
|
||||
DSS_TEMP_PATH = "d:\\temp\\"
|
||||
DSS_LAME_PATH = "D:\\Apps\\lame\\lame.exe"
|
||||
DSS_WAVE_PATH = "d:\\Apps\\waveformgen.exe"
|
||||
|
||||
DATABASE_NAME = 'deepsouthsounds'
|
||||
DATABASE_USER = 'deepsouthsounds'
|
||||
DATABASE_PASSWORD = ''
|
||||
# DATABASE_HOST = ''
|
||||
|
||||
PIPELINE_YUI_BINARY = ""
|
||||
FACEBOOK_APP_SECRET = ''
|
||||
|
||||
JS_SETTINGS = {
|
||||
'CHAT_HOST': "ext-test.deepsouthsounds.com:8081",
|
||||
'API_URL': "/api/v1/",
|
||||
'LIVE_STREAM_URL': "radio.deepsouthsounds.com",
|
||||
'LIVE_STREAM_PORT': "8000",
|
||||
'LIVE_STREAM_MOUNT': "mp3",
|
||||
'DEFAULT_AUDIO_VOLUME': "50",
|
||||
'SM_DEBUG_MODE': DEBUG,
|
||||
'LIVE_STREAM_INFO_URL': "radio.deepsouthsounds.com:8000/mp3"
|
||||
}
|
||||
"""
|
||||
WAVEFORM_URL = 'http://waveforms.podnoms.com/'
|
||||
IMAGE_URL = 'http://images.podnoms.com/'
|
||||
STATIC_URL = 'http://static.podnoms.com/'
|
||||
"""
|
||||
IMAGE_URL = 'http://ext-test.deepsouthsounds.com:8000/media/'
|
||||
GOOGLE_ANALYTICS_CODE = ''
|
||||
SENDFILE_BACKEND = 'sendfile.backends.development'
|
||||
#SENDFILE_BACKEND = 'sendfile.backends.xsendfile'
|
||||
#SENDFILE_BACKEND = 'sendfile.backends.nginx'
|
||||
|
||||
55
dss/localsettings.py
Normal file
55
dss/localsettings.py
Normal file
@@ -0,0 +1,55 @@
|
||||
import os
|
||||
from dss import devsettings
|
||||
|
||||
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')
|
||||
GEOIP_PATH = os.environ.get('GEOIP_PATH', '/home/fergalm/Dropbox/Private/deepsouthsounds.com/working/geolite')
|
||||
|
||||
DATABASE_PASSWORD = os.environ.get('DATABASE_PASSWORD', 'deepsouthsounds')
|
||||
DATABASE_NAME = os.environ.get('DATABASE_NAME', 'deepsouthsounds')
|
||||
DATABASE_USER = os.environ.get('DATABASE_USER', 'deepsouthsounds')
|
||||
DATABASE_HOST = os.environ.get('DATABASE_HOST', 'localhost')
|
||||
|
||||
STATIC_URL = '/assets/'
|
||||
MEDIA_ROOT = os.environ.get('MEDIA_ROOT', '/home/fergalm/Dropbox/development/deepsouthsounds.com/cache/media')
|
||||
STATIC_ROOT = os.environ.get('STATIC_ROOT', '/home/fergalm/Dropbox/development/deepsouthsounds.com/cache/static')
|
||||
CACHE_ROOT = os.environ.get('CACHE_ROOT', '/home/fergalm/Dropbox/development/deepsouthsounds.com/cache/cache')
|
||||
|
||||
MEDIA_URL = os.environ.get('MEDIA_URL', 'http://localhost/DSSMedia/') # '{0}media/'.format(CDN_URL)
|
||||
|
||||
REDIS_HOST = os.environ.get('REDIS_HOST', 'localhost')
|
||||
BROKER_URL = os.environ.get('BROKER_URL', 'amqp://guest:guest@localhost:5672//')
|
||||
CELERY_ACCEPT_CONTENT = ['pickle', 'msgpack', 'json']
|
||||
|
||||
SECRET_KEY = os.environ.get('SECRET_KEY', devsettings.SECRET_KEY)
|
||||
LIVE_ENABLED = os.environ.get('LIVE_ENABLED', False)
|
||||
|
||||
ICE_HOST = os.environ.get('ICE_HOST', 'localhost')
|
||||
ICE_MOUNT = os.environ.get('ICE_MOUNT =', 'dss')
|
||||
ICE_PORT = os.environ.get('ICE_PORT', 8000)
|
||||
|
||||
RADIO_HOST = os.environ.get('RADIO_HOST', 'localhost')
|
||||
RADIO_PORT = os.environ.get('RADIO_PORT', 8888)
|
||||
|
||||
MANDRILL_API_KEY = os.environ.get('MANDRILL_API_KEY', '')
|
||||
|
||||
SOCIAL_AUTH_FACEBOOK_KEY = os.environ.get('SOCIAL_AUTH_FACEBOOK_KEY', devsettings.SOCIAL_AUTH_FACEBOOK_KEY)
|
||||
SOCIAL_AUTH_FACEBOOK_SECRET = os.environ.get('SOCIAL_AUTH_FACEBOOK_SECRET', devsettings.SOCIAL_AUTH_FACEBOOK_SECRET)
|
||||
|
||||
SOCIAL_AUTH_TWITTER_KEY = os.environ.get('SOCIAL_AUTH_TWITTER_KEY', devsettings.SOCIAL_AUTH_TWITTER_KEY)
|
||||
SOCIAL_AUTH_TWITTER_SECRET = os.environ.get('SOCIAL_AUTH_TWITTER_SECRET', devsettings.SOCIAL_AUTH_TWITTER_SECRET)
|
||||
|
||||
SOCIAL_AUTH_GOOGLE_OAUTH_KEY = os.environ.get('SOCIAL_AUTH_GOOGLE_OAUTH_KEY', devsettings.SOCIAL_AUTH_GOOGLE_OAUTH_KEY)
|
||||
SOCIAL_AUTH_GOOGLE_OAUTH_SECRET = os.environ.get('SOCIAL_AUTH_GOOGLE_OAUTH_SECRET', devsettings.SOCIAL_AUTH_GOOGLE_OAUTH_SECRET)
|
||||
|
||||
SOCIAL_AUTH_GOOGLE_PLUS_KEY = os.environ.get('SOCIAL_AUTH_GOOGLE_PLUS_KEY', devsettings.SOCIAL_AUTH_GOOGLE_PLUS_KEY)
|
||||
SOCIAL_AUTH_GOOGLE_PLUS_SECRET = os.environ.get('SOCIAL_AUTH_GOOGLE_PLUS_SECRET', devsettings.SOCIAL_AUTH_GOOGLE_PLUS_SECRET)
|
||||
|
||||
DSS_DB_BACKUP_KEY = os.environ.get('DSS_DB_BACKUP_KEY', devsettings.DSS_DB_BACKUP_KEY)
|
||||
DSS_DB_BACKUP_SECRET = os.environ.get('DSS_DB_BACKUP_SECRET', devsettings.DSS_DB_BACKUP_SECRET)
|
||||
DSS_DB_BACKUP_TOKEN = os.environ.get('DSS_DB_BACKUP_TOKEN', devsettings.DSS_DB_BACKUP_TOKEN)
|
||||
|
||||
AZURE_ACCOUNT_KEY = os.environ.get('AZURE_ACCOUNT_KEY', devsettings.AZURE_ACCOUNT_KEY)
|
||||
@@ -1,91 +0,0 @@
|
||||
iPIPELINE_TEMPLATE_FUNC = "_.template"
|
||||
|
||||
PIPELINE_COMPILERS = (
|
||||
'pipeline.compilers.coffee.CoffeeScriptCompiler',
|
||||
)
|
||||
|
||||
PIPELINE_CSS = {
|
||||
'css': {
|
||||
'source_filenames': (
|
||||
'css/dss.overrides.css',
|
||||
|
||||
'css/ace/dropzone.css',
|
||||
'css/ace/uncompressed/jquery.gritter.css',
|
||||
'css/ace/uncompressed/bootstrap.css',
|
||||
'css/ace/uncompressed/ace.css',
|
||||
'css/ace/uncompressed/ace-ie.css',
|
||||
'css/ace/uncompressed/ace-skins.css',
|
||||
'css/ace/uncompressed/font-awesome.css',
|
||||
'css/ace/uncompressed/fullcalendar.css',
|
||||
'css/ace/uncompressed/bootstrap-editable.css',
|
||||
|
||||
'css/jasny-bootstrap.css',
|
||||
'css/select2.css',
|
||||
'css/jquery.fileupload-ui.css',
|
||||
'css/peneloplay.css',
|
||||
'css/toastr.css',
|
||||
'css/dss.main.css',
|
||||
),
|
||||
'output_filename': 'css/site.css'
|
||||
}
|
||||
}
|
||||
|
||||
PIPELINE_JS = {
|
||||
'templates': {
|
||||
'source_filenames': (
|
||||
'js/dss/templates/*.jst',
|
||||
),
|
||||
'variant': 'datauri',
|
||||
'output_filename': 'js/t.js',
|
||||
},
|
||||
|
||||
'lib': {
|
||||
'source_filenames': (
|
||||
'js/lib/jquery.js',
|
||||
'js/lib/jquery-ui.js',
|
||||
|
||||
'js/lib/moment.js',
|
||||
'js/lib/typeahead.js',
|
||||
|
||||
'js/lib/sm/soundmanager2.js',
|
||||
|
||||
'js/lib/underscore.js',
|
||||
'js/lib/underscore.templatehelpers.js',
|
||||
'js/lib/backbone.js',
|
||||
'js/lib/backbone.syphon.js',
|
||||
'js/lib/backbone.associations.js',
|
||||
'js/lib/backbone.marionette.js',
|
||||
|
||||
'js/lib/ace/uncompressed/bootstrap.js',
|
||||
'js/lib/ace/uncompressed/ace.js',
|
||||
'js/lib/ace/uncompressed/ace-elements.js',
|
||||
'js/lib/ace/uncompressed/select2.js',
|
||||
'js/lib/ace/uncompressed/fuelux/fuelux.wizard.js',
|
||||
'js/lib/ace/ace/elements.wizard.js',
|
||||
'js/lib/ace/uncompressed/bootstrap-wysiwyg.js',
|
||||
'js/lib/ace/uncompressed/jquery.gritter.js',
|
||||
'js/lib/ace/uncompressed/dropzone.js',
|
||||
'js/lib/ace/uncompressed/fullcalendar.js',
|
||||
'js/lib/ace/uncompressed/x-editable/bootstrap-editable.js',
|
||||
'js/lib/ace/uncompressed/x-editable/ace-editable.js',
|
||||
|
||||
'js/lib/ajaxfileupload.js',
|
||||
'js/lib/jasny.fileinput.js',
|
||||
'js/lib/jquery.fileupload.js',
|
||||
'js/lib/jquery.fileupload-process.js',
|
||||
'js/lib/jquery.fileupload-audio.js',
|
||||
'js/lib/jquery.fileupload-video.js',
|
||||
'js/lib/jquery.fileupload-validate.js',
|
||||
'js/lib/jquery.fileupload-ui.js',
|
||||
'js/lib/jquery.fileupload-image.js',
|
||||
'js/lib/jquery.iframe-transport.js',
|
||||
'js/lib/jquery.ui.widget.js',
|
||||
'js/lib/toastr.js',
|
||||
|
||||
'js/dss/*.coffee',
|
||||
'js/dss/**/*.coffee',
|
||||
'js/dss/apps/**/**/*.coffee',
|
||||
),
|
||||
'output_filename': 'js/a.js',
|
||||
},
|
||||
}
|
||||
@@ -19,7 +19,6 @@ SOCIAL_AUTH_PIPELINE = (
|
||||
'social.pipeline.user.get_username',
|
||||
'social.pipeline.social_auth.associate_by_email',
|
||||
'social.pipeline.user.create_user',
|
||||
'spa.pipeline.save_profile',
|
||||
'social.pipeline.social_auth.associate_user',
|
||||
'social.pipeline.social_auth.load_extra_data',
|
||||
'social.pipeline.user.user_details'
|
||||
|
||||
@@ -4,6 +4,7 @@ import mimetypes
|
||||
from datetime import timedelta
|
||||
from django.core.urlresolvers import reverse_lazy
|
||||
from django.conf import global_settings
|
||||
from dss import storagesettings
|
||||
|
||||
from utils import here
|
||||
|
||||
@@ -168,12 +169,7 @@ if DEBUG:
|
||||
REALTIME_HEADERS = {
|
||||
'content-type': 'application/json'
|
||||
}
|
||||
TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
|
||||
if 'test' in sys.argv:
|
||||
try:
|
||||
from .test_settings import *
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
REST_FRAMEWORK = {
|
||||
# Use hyperlinked styles by default.
|
||||
@@ -211,3 +207,31 @@ JWT_AUTH = {
|
||||
'JWT_ALLOW_REFRESH': True,
|
||||
'JWT_REFRESH_EXPIRATION_DELTA': timedelta(days=30),
|
||||
}
|
||||
|
||||
""" static settings """
|
||||
CDN_URL = storagesettings.AZURE_ITEM_BASE_URL
|
||||
MIXIMAGE_URL = '{0}miximages/'.format(CDN_URL)
|
||||
WAVEFORM_URL = '{0}waveforms/'.format(CDN_URL)
|
||||
STREAM_URL = '{0}mixes/'.format(CDN_URL)
|
||||
AUDIO_URL = '{0}mixes/'.format(CDN_URL)
|
||||
|
||||
|
||||
NOTIFICATIONS_FROM_ADDRESS = "admin@deepsouthsounds.com"
|
||||
|
||||
CORS_ORIGIN_ALLOW_ALL = True
|
||||
CORS_ALLOW_CREDENTIALS = True
|
||||
CORS_ALLOW_HEADERS = (
|
||||
'x-requested-with',
|
||||
'content-type',
|
||||
'cache-control',
|
||||
'accept',
|
||||
'origin',
|
||||
'authorization',
|
||||
|
||||
'upload-hash',
|
||||
'session-id',
|
||||
'auth-backend',
|
||||
'x-csrftoken'
|
||||
)
|
||||
|
||||
""" End static settings """
|
||||
6
dss/storagesettings.py
Normal file
6
dss/storagesettings.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from dss import localsettings
|
||||
|
||||
AZURE_ACCOUNT_NAME = 'dsscdn'
|
||||
AZURE_CONTAINER = 'media'
|
||||
AZURE_ACCOUNT_KEY = localsettings.AZURE_ACCOUNT_KEY
|
||||
AZURE_ITEM_BASE_URL = 'https://dsscdn.blob.core.windows.net/'
|
||||
@@ -1,10 +0,0 @@
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': 'dss_test.db',
|
||||
'USER': '',
|
||||
'PASSWORD': '',
|
||||
'HOST': '',
|
||||
'PORT': '',
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,8 @@ urlpatterns = patterns(
|
||||
url(r'^admin/', include(admin.site.urls)),
|
||||
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
|
||||
(r'^grappelli/', include('grappelli.urls')),
|
||||
(r'^social/', include('spa.social.urls')),
|
||||
(r'^__redir/blog/', include('spa.blog.urls')),
|
||||
(r'^__redir/social/', include('spa.social.urls')),
|
||||
(r'^arges/', include('spa.social.urls')),
|
||||
url(r'', include('user_sessions.urls', 'user_sessions')),
|
||||
url(r'^', include('api.urls')),
|
||||
|
||||
7
spa/blog/urls.py
Executable file
7
spa/blog/urls.py
Executable file
@@ -0,0 +1,7 @@
|
||||
from django.conf.urls import patterns, url
|
||||
|
||||
urlpatterns = patterns(
|
||||
'',
|
||||
url(r'^blog/(?P<slug>[\w\d_.-]+)/?$', 'spa.blog.views.entry', name='blog_entry_slug'),
|
||||
url(r'^$', 'spa.blog.views.index', name='blog_index')
|
||||
)
|
||||
58
spa/blog/views.py
Executable file
58
spa/blog/views.py
Executable file
@@ -0,0 +1,58 @@
|
||||
import urllib.request, urllib.error, urllib.parse
|
||||
import logging
|
||||
|
||||
from django.conf.urls import url
|
||||
from django.contrib.sites.models import Site
|
||||
from django.core.urlresolvers import resolve
|
||||
from django.http import Http404
|
||||
from django.shortcuts import render_to_response
|
||||
from django.template.context import RequestContext
|
||||
import requests
|
||||
from allauth.socialaccount.models import SocialToken
|
||||
from core.utils.url import wrap_full
|
||||
|
||||
from dss import settings
|
||||
from spa.models import Playlist, Blog
|
||||
from spa.models.mix import Mix
|
||||
from spa.models.userprofile import UserProfile
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
"""
|
||||
Handles callbacks from non javascript browsers
|
||||
"""
|
||||
|
||||
|
||||
def _getPayload(request):
|
||||
return {
|
||||
"app_id": settings.FACEBOOK_APP_ID,
|
||||
"site_url": 'http://%s' % Site.objects.get_current().domain,
|
||||
"site_image_url": '%s/img/dss-large.png' % settings.STATIC_URL,
|
||||
}
|
||||
|
||||
|
||||
def entry(request, slug):
|
||||
try:
|
||||
blog = Blog.objects.get(slug=slug)
|
||||
extras = {
|
||||
"content": blog.body,
|
||||
}
|
||||
payload = dict(list(_getPayload(request).items()) + list(extras.items()))
|
||||
response = render_to_response(
|
||||
'blog/entry.html',
|
||||
payload,
|
||||
context_instance=RequestContext(request)
|
||||
)
|
||||
return response
|
||||
except Blog.DoesNotExist:
|
||||
raise Http404
|
||||
except Exception as ex:
|
||||
logger.error(ex)
|
||||
|
||||
|
||||
def index(request):
|
||||
response = render_to_response(
|
||||
"blog/index.html",
|
||||
_getPayload(request),
|
||||
context_instance=RequestContext(request))
|
||||
return response
|
||||
@@ -1,7 +1,7 @@
|
||||
from azure.storage.blob import BlobService
|
||||
import urllib.request, urllib.error, urllib.parse
|
||||
|
||||
from allauth.socialaccount.models import SocialAccount
|
||||
from azure.storage import BlobService
|
||||
from django.core.files.base import File
|
||||
from django.core.files.temp import NamedTemporaryFile
|
||||
from django.core.management.base import NoArgsCommand
|
||||
|
||||
29
spa/migrations/0017_blog.py
Normal file
29
spa/migrations/0017_blog.py
Normal file
@@ -0,0 +1,29 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('spa', '0016_remove_show_recurrence_rrule'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Blog',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, verbose_name='ID', primary_key=True, serialize=False)),
|
||||
('object_created', models.DateTimeField(auto_now_add=True)),
|
||||
('object_updated', models.DateTimeField(auto_now=True, db_index=True)),
|
||||
('date_created', models.DateField(auto_now=True)),
|
||||
('title', models.CharField(max_length=1024)),
|
||||
('body', models.TextField()),
|
||||
('user', models.ForeignKey(blank=True, to='spa.UserProfile', null=True)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
]
|
||||
19
spa/migrations/0018_blog_published.py
Normal file
19
spa/migrations/0018_blog_published.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('spa', '0017_blog'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='blog',
|
||||
name='published',
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
]
|
||||
20
spa/migrations/0019_blog_slug.py
Normal file
20
spa/migrations/0019_blog_slug.py
Normal file
@@ -0,0 +1,20 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('spa', '0018_blog_published'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='blog',
|
||||
name='slug',
|
||||
field=models.SlugField(default='arse'),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
||||
29
spa/migrations/0020_blogcomment.py
Normal file
29
spa/migrations/0020_blogcomment.py
Normal file
@@ -0,0 +1,29 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('spa', '0019_blog_slug'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='BlogComment',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, auto_created=True, serialize=False, verbose_name='ID')),
|
||||
('object_created', models.DateTimeField(auto_now_add=True)),
|
||||
('object_updated', models.DateTimeField(auto_now=True, db_index=True)),
|
||||
('comment', models.CharField(max_length=1024)),
|
||||
('date_created', models.DateField(auto_now_add=True)),
|
||||
('blog', models.ForeignKey(to='spa.Blog')),
|
||||
('user', models.ForeignKey(null=True, to='spa.UserProfile', blank=True)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -16,3 +16,4 @@ from .release import Release
|
||||
from .playlist import Playlist
|
||||
from .message import Message
|
||||
from .show import Show
|
||||
from .blog import Blog
|
||||
|
||||
26
spa/models/blog.py
Normal file
26
spa/models/blog.py
Normal file
@@ -0,0 +1,26 @@
|
||||
from core.utils.url import unique_slugify
|
||||
from spa.models import BaseModel, UserProfile
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Blog(BaseModel):
|
||||
user = models.ForeignKey(UserProfile, null=True, blank=True)
|
||||
date_created = models.DateField(auto_now=True)
|
||||
published = models.BooleanField(default=False)
|
||||
slug = models.SlugField()
|
||||
|
||||
title = models.CharField(max_length=1024)
|
||||
body = models.TextField()
|
||||
|
||||
def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
|
||||
if not self.id:
|
||||
self.slug = unique_slugify(self, self.title)
|
||||
|
||||
super(Blog, self).save(force_insert, force_update, using, update_fields)
|
||||
|
||||
|
||||
class BlogComment(BaseModel):
|
||||
blog = models.ForeignKey(Blog)
|
||||
user = models.ForeignKey(UserProfile, null=True, blank=True)
|
||||
comment = models.CharField(max_length=1024)
|
||||
date_created = models.DateField(auto_now_add=True)
|
||||
@@ -103,7 +103,7 @@ class Mix(BaseModel):
|
||||
|
||||
self.clean_image('mix_image', Mix)
|
||||
# Check for the unlikely event that the waveform has been generated
|
||||
if cdn.file_exists('{0}{1}.png'.format(localsettings.WAVEFORM_URL, self.uid)):
|
||||
if cdn.file_exists('{0}{1}.png'.format(settings.WAVEFORM_URL, self.uid)):
|
||||
self.waveform_generated = True
|
||||
try:
|
||||
self.duration = mp3_length(self.get_absolute_path())
|
||||
@@ -153,14 +153,13 @@ class Mix(BaseModel):
|
||||
|
||||
def get_waveform_url(self, waveform_type=""):
|
||||
# TODO: Design better flow for this sort of thing
|
||||
if not self.waveform_generated and cdn.file_exists('{0}{1}.png'.format(localsettings.WAVEFORM_URL, self.uid)):
|
||||
if not self.waveform_generated and cdn.file_exists('{0}{1}.png'.format(settings.WAVEFORM_URL, self.uid)):
|
||||
self.waveform_generated = True
|
||||
self.save()
|
||||
|
||||
if self.waveform_generated:
|
||||
waveform_root = localsettings.WAVEFORM_URL \
|
||||
if hasattr(localsettings,
|
||||
'WAVEFORM_URL') else "%swaveforms" % settings.MEDIA_URL
|
||||
waveform_root = settings.WAVEFORM_URL \
|
||||
if hasattr(settings, 'WAVEFORM_URL') else "%swaveforms" % settings.MEDIA_URL
|
||||
|
||||
ret = "%s/%s%s.%s" % (waveform_root, self.uid, waveform_type, "png")
|
||||
return url.urlclean(ret)
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
from django.core.files.base import ContentFile
|
||||
from requests import request, ConnectionError
|
||||
|
||||
|
||||
def save_profile(backend, user, response, is_new, *args, **kwargs):
|
||||
if backend.name == 'google-oauth2':
|
||||
if response.get('image') and response['image'].get('url'):
|
||||
url = response['image'].get('url')
|
||||
profile = user.userprofile
|
||||
|
||||
try:
|
||||
response = request('GET', url)
|
||||
response.raise_for_status()
|
||||
except ConnectionError:
|
||||
pass
|
||||
else:
|
||||
profile.avatar_image.save('',
|
||||
ContentFile(response.content),
|
||||
save=False)
|
||||
profile.save()
|
||||
elif backend.name == 'facebook':
|
||||
profile = user.userprofile
|
||||
url = 'http://graph.facebook.com/{0}/picture'.format(response['id'])
|
||||
try:
|
||||
response = request('GET', url, params={'type': 'large'})
|
||||
response.raise_for_status()
|
||||
except ConnectionError:
|
||||
pass
|
||||
else:
|
||||
profile.avatar_image.save('',
|
||||
ContentFile(response.content),
|
||||
save=False
|
||||
)
|
||||
profile.save()
|
||||
18
templates/blog/entry.html
Normal file
18
templates/blog/entry.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:og="http://ogp.me/ns#"
|
||||
xmlns:fb="https://www.facebook.com/2008/fbml">
|
||||
<head>
|
||||
<meta property="fb:app_id" content="{{ app_id }}"/>
|
||||
<meta property="og:url" content="{{ mix_url }}/"/>
|
||||
|
||||
<meta property="og:site_name" content="Deep South Sounds"/>
|
||||
<meta property="og:type" content="deepsouthsounds:blog"/>
|
||||
<meta property="og:title" content="{{ title }}"/>
|
||||
<meta property="og:description" content="{{ description }}"/>
|
||||
<meta property="og:image" content="{{ image }}"/>
|
||||
</head>
|
||||
<body>
|
||||
{{ content }}
|
||||
</body>
|
||||
</html>
|
||||
19
templates/blog/index.html
Normal file
19
templates/blog/index.html
Normal file
@@ -0,0 +1,19 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:og="http://ogp.me/ns#"
|
||||
xmlns:fb="https://www.facebook.com/2008/fbml">
|
||||
<head>
|
||||
<meta property="fb:app_id" content="{{ app_id }}"/>
|
||||
<meta property="og:url" content="{{ mix_url }}/"/>
|
||||
|
||||
<meta property="og:site_name" content="Deep South Sounds"/>
|
||||
<meta property="og:type" content="deepsouthsounds:blog"/>
|
||||
<meta property="og:title" content="{{ title }}"/>
|
||||
<meta property="og:description" content="{{ description }}"/>
|
||||
<meta property="og:image" content="{{ image }}"/>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Blog Index</h1>
|
||||
{{ content }}
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user