Stashing changes pre media element branch

This commit is contained in:
Fergal Moran
2014-05-12 19:32:43 +01:00
parent 73cf378d82
commit 25ccc29d87
28 changed files with 754 additions and 371 deletions

View File

@@ -49,13 +49,6 @@ s = True
SITE_ROOT = here('') SITE_ROOT = here('')
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': '127.0.0.1:11211',
}
}
ADMIN_MEDIA_PREFIX = STATIC_URL + "grappelli/" ADMIN_MEDIA_PREFIX = STATIC_URL + "grappelli/"
TINYMCE_JS_URL = os.path.join(STATIC_ROOT, "js/libs/tiny_mce/tiny_mce.js") TINYMCE_JS_URL = os.path.join(STATIC_ROOT, "js/libs/tiny_mce/tiny_mce.js")
@@ -98,12 +91,6 @@ STATICFILES_DIRS = (
here('static'), here('static'),
) )
TEMPLATE_LOADERS = (
('django.template.loaders.cached.Loader', (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)),
)
TEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS + ( TEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS + (
'django_facebook.context_processors.facebook', 'django_facebook.context_processors.facebook',
'django.core.context_processors.request', 'django.core.context_processors.request',

View File

@@ -1,6 +1,6 @@
from django.conf.urls import patterns, include, url from django.conf.urls import patterns, include, url
from django.contrib import admin from django.contrib import admin
from django.views.generic import TemplateView from django.views.generic import TemplateView, RedirectView
from dss import settings from dss import settings
@@ -10,19 +10,20 @@ admin.autodiscover()
# from django.contrib import admin # from django.contrib import admin
# admin.autodiscover() # admin.autodiscover()
urlpatterns = patterns('', urlpatterns = patterns(
url(r'^admin/', include(admin.site.urls)), '',
#(r'^favicon\.ico$', 'django.views.generic.simple.redirect_to', {'url': '/static/img/favicon.ico'}), url(r'^favicon\.ico$', RedirectView.as_view(url='/static/img/favicon.ico')),
(r'^channel\.html$', TemplateView.as_view(template_name='boiler/fb_channel.html')), url(r'^admin/', include(admin.site.urls)),
(r'^privacy\.html$', TemplateView.as_view(template_name='boiler/privacy.html')), (r'^channel\.html$', TemplateView.as_view(template_name='boiler/fb_channel.html')),
(r'^robots\.txt', TemplateView.as_view(template_name='boiler/robots.txt')), (r'^privacy\.html$', TemplateView.as_view(template_name='boiler/privacy.html')),
(r'^tos\.html$', TemplateView.as_view(template_name='boiler/tos.html')), (r'^robots\.txt', TemplateView.as_view(template_name='boiler/robots.txt')),
(r'^test\.html$', TemplateView.as_view(template_name='boiler/test.html')), (r'^tos\.html$', TemplateView.as_view(template_name='boiler/tos.html')),
(r'^500', 'django.views.defaults.server_error'), (r'^test\.html$', TemplateView.as_view(template_name='boiler/test.html')),
(r'^grappelli/', include('grappelli.urls')), (r'^500', 'django.views.defaults.server_error'),
url(r'^accounts/', include('allauth.urls')), (r'^grappelli/', include('grappelli.urls')),
(r'^avatar/', include('avatar.urls')), url(r'^accounts/', include('allauth.urls')),
url(r'^', include('spa.urls')), (r'^avatar/', include('avatar.urls')),
url(r'^', include('spa.urls')),
) )
handler500 = 'spa.views.debug_500' handler500 = 'spa.views.debug_500'

View File

@@ -50,3 +50,4 @@ pyyaml
ua-parser ua-parser
user-agents user-agents
django-user-agents django-user-agents
nginx_signing

View File

@@ -16,6 +16,7 @@ from spa.api.v1.BackboneCompatibleResource import BackboneCompatibleResource
from spa.api.v1.CommentResource import CommentResource from spa.api.v1.CommentResource import CommentResource
from spa.api.v1.ActivityResource import ActivityResource from spa.api.v1.ActivityResource import ActivityResource
from spa.models.mix import Mix from spa.models.mix import Mix
from spa.models.show import Show
class MixResource(BackboneCompatibleResource): class MixResource(BackboneCompatibleResource):
@@ -158,6 +159,9 @@ class MixResource(BackboneCompatibleResource):
) )
semi_filtered = semi_filtered.filter( semi_filtered = semi_filtered.filter(
user__in=request.user.get_profile().following.all()) user__in=request.user.get_profile().following.all())
if request.GET.get('for_show'):
semi_filtered = semi_filtered.filter(show__isnull=True)
if f_user is not None: if f_user is not None:
semi_filtered = semi_filtered.filter(user__slug=f_user) semi_filtered = semi_filtered.filter(user__slug=f_user)

View File

@@ -1,3 +1,4 @@
from tastypie import fields
from tastypie.authorization import Authorization from tastypie.authorization import Authorization
from tastypie.exceptions import ImmediateHttpResponse from tastypie.exceptions import ImmediateHttpResponse
from tastypie.http import HttpBadRequest from tastypie.http import HttpBadRequest
@@ -11,10 +12,14 @@ DATE_FORMAT = '%d/%m/%Y %H:%M:%S'
class ShowResource(BackboneCompatibleResource): class ShowResource(BackboneCompatibleResource):
mix = fields.ToOneField('spa.api.v1.MixResource.MixResource',
'mix', null=False, full=False)
class Meta: class Meta:
queryset = Show.objects.all() queryset = Show.objects.all()
authorization = Authorization() authorization = Authorization()
resource_name = 'schedules' resource_name = 'show'
always_return_data = True
def obj_create(self, bundle, **kwargs): def obj_create(self, bundle, **kwargs):
try: try:
@@ -23,4 +28,8 @@ class ShowResource(BackboneCompatibleResource):
raise ImmediateHttpResponse( raise ImmediateHttpResponse(
HttpBadRequest("This event overlaps with an existing event") HttpBadRequest("This event overlaps with an existing event")
) )
except Exception, ex:
raise ImmediateHttpResponse(
HttpBadRequest(ex.message)
)

View File

@@ -0,0 +1,262 @@
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'Show.mix'
db.add_column(u'spa_show', 'mix',
self.gf('django.db.models.fields.related.ForeignKey')(default=3, related_name='show', to=orm['spa.Mix']),
keep_default=False)
def backwards(self, orm):
# Deleting field 'Show.mix'
db.delete_column(u'spa_show', 'mix_id')
models = {
u'auth.group': {
'Meta': {'object_name': 'Group'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
u'auth.permission': {
'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
u'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
u'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'schedule.calendar': {
'Meta': {'object_name': 'Calendar'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '200'})
},
'schedule.event': {
'Meta': {'object_name': 'Event'},
'calendar': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.Calendar']", 'null': 'True', 'blank': 'True'}),
'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'creator': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'creator'", 'null': 'True', 'to': u"orm['auth.User']"}),
'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'end': ('django.db.models.fields.DateTimeField', [], {}),
'end_recurring_period': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'rule': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.Rule']", 'null': 'True', 'blank': 'True'}),
'start': ('django.db.models.fields.DateTimeField', [], {}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'updated_on': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
},
'schedule.rule': {
'Meta': {'object_name': 'Rule'},
'description': ('django.db.models.fields.TextField', [], {}),
'frequency': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
'params': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'})
},
'spa._lookup': {
'Meta': {'object_name': '_Lookup'},
'description': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
},
'spa.activity': {
'Meta': {'object_name': 'Activity'},
'date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.UserProfile']", 'null': 'True', 'blank': 'True'})
},
'spa.activitycomment': {
'Meta': {'object_name': 'ActivityComment', '_ormbases': ['spa.Activity']},
u'activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa.Activity']", 'unique': 'True', 'primary_key': 'True'}),
'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'activity_comments'", 'to': "orm['spa.Mix']"})
},
'spa.activitydownload': {
'Meta': {'object_name': 'ActivityDownload', '_ormbases': ['spa.Activity']},
u'activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa.Activity']", 'unique': 'True', 'primary_key': 'True'}),
'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'activity_downloads'", 'to': "orm['spa.Mix']"})
},
'spa.activityfavourite': {
'Meta': {'object_name': 'ActivityFavourite', '_ormbases': ['spa.Activity']},
u'activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa.Activity']", 'unique': 'True', 'primary_key': 'True'}),
'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'activity_favourites'", 'to': "orm['spa.Mix']"})
},
'spa.activityfollow': {
'Meta': {'object_name': 'ActivityFollow', '_ormbases': ['spa.Activity']},
u'activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa.Activity']", 'unique': 'True', 'primary_key': 'True'}),
'to_user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'activity_follow'", 'to': "orm['spa.UserProfile']"})
},
'spa.activitylike': {
'Meta': {'object_name': 'ActivityLike', '_ormbases': ['spa.Activity']},
u'activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa.Activity']", 'unique': 'True', 'primary_key': 'True'}),
'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'activity_likes'", 'to': "orm['spa.Mix']"})
},
'spa.activityplay': {
'Meta': {'object_name': 'ActivityPlay', '_ormbases': ['spa.Activity']},
u'activity_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa.Activity']", 'unique': 'True', 'primary_key': 'True'}),
'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'activity_plays'", 'to': "orm['spa.Mix']"})
},
'spa.chatmessage': {
'Meta': {'object_name': 'ChatMessage'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'message': ('django.db.models.fields.TextField', [], {}),
'timestamp': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'chat_messages'", 'null': 'True', 'to': "orm['spa.UserProfile']"})
},
'spa.comment': {
'Meta': {'object_name': 'Comment'},
'comment': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
'date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'mix': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'comments'", 'null': 'True', 'to': "orm['spa.Mix']"}),
'time_index': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'})
},
'spa.genre': {
'Meta': {'object_name': 'Genre'},
'description': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'})
},
'spa.label': {
'Meta': {'object_name': 'Label'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'spa.mix': {
'Meta': {'object_name': 'Mix'},
'description': ('django.db.models.fields.TextField', [], {}),
'download_allowed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'duration': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'favourites': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'favourites'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['spa.UserProfile']"}),
'filetype': ('django.db.models.fields.CharField', [], {'default': "'mp3'", 'max_length': '10'}),
'genres': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['spa.Genre']", 'symmetrical': 'False'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_featured': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'likes': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'likes'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['spa.UserProfile']"}),
'mix_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '1024', 'blank': 'True'}),
'mp3tags_updated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
'uid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '38', 'blank': 'True'}),
'upload_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2014, 5, 9, 0, 0)'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'mixes'", 'to': "orm['spa.UserProfile']"}),
'waveform_generated': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
},
'spa.notification': {
'Meta': {'object_name': 'Notification'},
'accepted_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'from_user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'notifications'", 'null': 'True', 'to': "orm['spa.UserProfile']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'notification_html': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
'notification_text': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
'notification_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'}),
'target': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}),
'to_user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'to_notications'", 'to': "orm['spa.UserProfile']"}),
'verb': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'})
},
'spa.purchaselink': {
'Meta': {'object_name': 'PurchaseLink'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'provider': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'track': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'purchase_link'", 'to': "orm['spa.Tracklist']"}),
'url': ('django.db.models.fields.URLField', [], {'max_length': '200'})
},
'spa.recurrence': {
'Meta': {'object_name': 'Recurrence', '_ormbases': ['spa._Lookup']},
u'_lookup_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['spa._Lookup']", 'unique': 'True', 'primary_key': 'True'})
},
'spa.release': {
'Meta': {'object_name': 'Release'},
'embed_code': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'release_artist': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'release_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2014, 5, 9, 0, 0)'}),
'release_description': ('django.db.models.fields.TextField', [], {}),
'release_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}),
'release_label': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Label']"}),
'release_title': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.UserProfile']"})
},
'spa.releaseaudio': {
'Meta': {'object_name': 'ReleaseAudio'},
'description': ('django.db.models.fields.TextField', [], {}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'release': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'release_audio'", 'null': 'True', 'to': "orm['spa.Release']"})
},
'spa.show': {
'Meta': {'object_name': 'Show', '_ormbases': ['schedule.Event']},
u'event_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['schedule.Event']", 'unique': 'True', 'primary_key': 'True'}),
'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'show'", 'to': "orm['spa.Mix']"})
},
'spa.tracklist': {
'Meta': {'object_name': 'Tracklist'},
'artist': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'description': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'index': ('django.db.models.fields.SmallIntegerField', [], {}),
'label': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'mix': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tracklist'", 'to': "orm['spa.Mix']"}),
'remixer': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'timeindex': ('django.db.models.fields.TimeField', [], {'null': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
},
'spa.userprofile': {
'Meta': {'object_name': 'UserProfile'},
'activity_sharing': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'activity_sharing_networks': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'avatar_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '1024', 'blank': 'True'}),
'avatar_type': ('django.db.models.fields.CharField', [], {'default': "'social'", 'max_length': '15'}),
'city': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
'country': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'blank': 'True'}),
'display_name': ('django.db.models.fields.CharField', [], {'max_length': '35', 'blank': 'True'}),
'following': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'followers'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['spa.UserProfile']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'last_known_session': ('django.db.models.fields.CharField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'}),
'slug': ('django.db.models.fields.SlugField', [], {'default': 'None', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'userprofile'", 'unique': 'True', 'to': u"orm['auth.User']"})
},
'spa.venue': {
'Meta': {'object_name': 'Venue'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}),
'venue_address': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
'venue_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}),
'venue_name': ('django.db.models.fields.CharField', [], {'max_length': '250'})
}
}
complete_apps = ['spa']

View File

@@ -1,10 +1,15 @@
from django.db.models import Q from django.db.models import Q, ForeignKey
from schedule.models import Event from schedule.models import Event
from spa.models import Mix
class ShowOverlapException(Exception): class ShowOverlapException(Exception):
pass pass
class Show(Event): class Show(Event):
mix = ForeignKey(Mix, related_name='show')
class Meta: class Meta:
app_label = 'spa' app_label = 'spa'
@@ -13,7 +18,6 @@ class Show(Event):
""" """
throw an exception if event overlaps with another event throw an exception if event overlaps with another event
""" """
import ipdb; ipdb.set_trace()
overlaps = Show.objects.filter( overlaps = Show.objects.filter(
Q(start__gte=self.start, end__lte=self.start) | Q(start__gte=self.start, end__lte=self.start) |
Q(start__gte=self.end, end__lte=self.end) Q(start__gte=self.end, end__lte=self.end)

View File

@@ -7,7 +7,6 @@ from spa.api.v1.NotificationResource import NotificationResource
from spa.audio import AudioHandler from spa.audio import AudioHandler
from spa.api.v1.ChatResource import ChatResource from spa.api.v1.ChatResource import ChatResource
from spa.api.v1.CommentResource import CommentResource from spa.api.v1.CommentResource import CommentResource
#from spa.api.v1.EventResource import EventResource
from spa.api.v1.MixResource import MixResource from spa.api.v1.MixResource import MixResource
from spa.api.v1.ReleaseAudioResource import ReleaseAudioResource from spa.api.v1.ReleaseAudioResource import ReleaseAudioResource
from spa.api.v1.ReleaseResource import ReleaseResource from spa.api.v1.ReleaseResource import ReleaseResource
@@ -21,7 +20,6 @@ api.register(CommentResource())
api.register(MixResource()) api.register(MixResource())
api.register(ReleaseResource()) api.register(ReleaseResource())
api.register(ReleaseAudioResource()) api.register(ReleaseAudioResource())
#api.register(EventResource())
api.register(UserResource()) api.register(UserResource())
api.register(ActivityResource()) api.register(ActivityResource())
api.register(NotificationResource()) api.register(NotificationResource())
@@ -34,7 +32,7 @@ audio = AudioHandler()
urlpatterns = patterns( urlpatterns = patterns(
'', '',
url(r'^$', 'spa.views.app', name='home'), url(r'^$', 'spa.views.app', name='home'),
url(r'^tpl/(?P<template_name>\w+)/$', 'spa.templates.get_template'), url(r'^tpl/(?P<template_name>\w+)', 'spa.templates.get_template'),
url(r'^dlg/(?P<dialog_name>\w+)/$', 'spa.templates.get_dialog'), url(r'^dlg/(?P<dialog_name>\w+)/$', 'spa.templates.get_dialog'),
url(r'^dlg/embed/(?P<slug>[\w\d_.-]+)/$', 'spa.templates.get_embed_codes_dialog'), url(r'^dlg/embed/(?P<slug>[\w\d_.-]+)/$', 'spa.templates.get_embed_codes_dialog'),
url(r'^js/(?P<template_name>\w+)/$', 'spa.templates.get_javascript'), url(r'^js/(?P<template_name>\w+)/$', 'spa.templates.get_javascript'),

View File

@@ -25,6 +25,7 @@ define ['backbone', 'marionette', 'vent', 'utils', 'underscore',
App.addRegions App.addRegions
headerRegion: "#header" headerRegion: "#header"
fullContentRegion: "#full-content"
contentRegion: contentRegion:
selector: "#content" selector: "#content"
footerRegion: "#footer" footerRegion: "#footer"

View File

@@ -18,6 +18,7 @@
}); });
App.addRegions({ App.addRegions({
headerRegion: "#header", headerRegion: "#header",
fullContentRegion: "#full-content",
contentRegion: { contentRegion: {
selector: "#content" selector: "#content"
}, },

View File

@@ -1,11 +1,11 @@
define ['app', 'marionette', 'vent', 'utils', define ['app', 'marionette', 'vent', 'utils',
'views/mix/mixListLayout', 'views/mix/mixListView', 'views/mix/mixDetailView', 'views/mix/mixListLayout', 'views/mix/mixListView', 'views/mix/mixDetailView',
'views/schedule/scheduleView', 'views/show/scheduleShowLayout',
'views/mix/mixEditView', 'views/user/userProfileView', 'views/user/userListView', 'views/user/userEditView', 'views/mix/mixEditView', 'views/user/userProfileView', 'views/user/userListView', 'views/user/userEditView',
'models/mix/mixCollection', 'models/mix/mixItem', 'models/user/userItem'], 'models/mix/mixCollection', 'models/mix/mixItem', 'models/user/userItem'],
(App, Marionette, vent, utils, (App, Marionette, vent, utils,
MixListLayout, MixListView, MixDetailView, MixListLayout, MixListView, MixDetailView,
ScheduleView, ScheduleShowLayout,
MixEditView, UserProfileView, UserListView, UserEditView, MixEditView, UserProfileView, UserListView, UserEditView,
MixCollection, MixItem, UserItem)-> MixCollection, MixItem, UserItem)->
class DssController extends Marionette.Controller class DssController extends Marionette.Controller
@@ -22,8 +22,8 @@ define ['app', 'marionette', 'vent', 'utils',
showSchedule: -> showSchedule: ->
app = require('app') app = require('app')
app.contentRegion.show(new ScheduleView()) app.contentRegion.show(new ScheduleShowLayout())
vent.trigger('schedule:show') vent.trigger('show:schedule:show')
showMixList: (options, emptyTemplate) -> showMixList: (options, emptyTemplate) ->
app = require('app') app = require('app')

View File

@@ -3,7 +3,7 @@
var __hasProp = {}.hasOwnProperty, var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
define(['app', 'marionette', 'vent', 'utils', 'views/mix/mixListLayout', 'views/mix/mixListView', 'views/mix/mixDetailView', 'views/schedule/scheduleView', 'views/mix/mixEditView', 'views/user/userProfileView', 'views/user/userListView', 'views/user/userEditView', 'models/mix/mixCollection', 'models/mix/mixItem', 'models/user/userItem'], function(App, Marionette, vent, utils, MixListLayout, MixListView, MixDetailView, ScheduleView, MixEditView, UserProfileView, UserListView, UserEditView, MixCollection, MixItem, UserItem) { define(['app', 'marionette', 'vent', 'utils', 'views/mix/mixListLayout', 'views/mix/mixListView', 'views/mix/mixDetailView', 'views/show/scheduleShowLayout', 'views/mix/mixEditView', 'views/user/userProfileView', 'views/user/userListView', 'views/user/userEditView', 'models/mix/mixCollection', 'models/mix/mixItem', 'models/user/userItem'], function(App, Marionette, vent, utils, MixListLayout, MixListView, MixDetailView, ScheduleShowLayout, MixEditView, UserProfileView, UserListView, UserEditView, MixCollection, MixItem, UserItem) {
var DssController; var DssController;
DssController = (function(_super) { DssController = (function(_super) {
@@ -29,8 +29,8 @@
DssController.prototype.showSchedule = function() { DssController.prototype.showSchedule = function() {
var app; var app;
app = require('app'); app = require('app');
app.contentRegion.show(new ScheduleView()); app.contentRegion.show(new ScheduleShowLayout());
return vent.trigger('schedule:show'); return vent.trigger('show:schedule:show');
}; };
DssController.prototype.showMixList = function(options, emptyTemplate) { DssController.prototype.showMixList = function(options, emptyTemplate) {

View File

@@ -0,0 +1,15 @@
define ['backbone', 'models/show/showItem', 'app.lib/backbone.dss.model.collection'],
(Backbone, ShowItem, DssCollection) ->
class ScheduleCollection extends DssCollection
model: ShowItem
page: 0
limit: 20
url: ->
com.podnoms.settings.urlRoot + "show/?limit=" + @limit + "&offset=" + Math.max(@page-1, 0) * @limit
initialize: ->
if not ShowItem
@model = require('models/show/showItem')
ScheduleCollection

View File

@@ -0,0 +1,38 @@
// Generated by CoffeeScript 1.4.0
(function() {
var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
define(['backbone', 'models/show/showItem', 'app.lib/backbone.dss.model.collection'], function(Backbone, ShowItem, DssCollection) {
var ScheduleCollection;
ScheduleCollection = (function(_super) {
__extends(ScheduleCollection, _super);
function ScheduleCollection() {
return ScheduleCollection.__super__.constructor.apply(this, arguments);
}
ScheduleCollection.prototype.model = ShowItem;
ScheduleCollection.prototype.page = 0;
ScheduleCollection.prototype.limit = 20;
ScheduleCollection.prototype.url = function() {
return com.podnoms.settings.urlRoot + "show/?limit=" + this.limit + "&offset=" + Math.max(this.page - 1, 0) * this.limit;
};
ScheduleCollection.prototype.initialize = function() {
if (!ShowItem) {
return this.model = require('models/show/showItem');
}
};
return ScheduleCollection;
})(DssCollection);
return ScheduleCollection;
});
}).call(this);

View File

@@ -0,0 +1,5 @@
define ['app.lib/backbone.dss.model'],
(DssModel) ->
class ShowItem extends DssModel
urlRoot: com.podnoms.settings.urlRoot + "show/"
ShowItem

View File

@@ -0,0 +1,24 @@
// Generated by CoffeeScript 1.4.0
(function() {
var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
define(['app.lib/backbone.dss.model'], function(DssModel) {
var ShowItem;
ShowItem = (function(_super) {
__extends(ShowItem, _super);
function ShowItem() {
return ShowItem.__super__.constructor.apply(this, arguments);
}
ShowItem.prototype.urlRoot = com.podnoms.settings.urlRoot + "show/";
return ShowItem;
})(DssModel);
return ShowItem;
});
}).call(this);

View File

@@ -7,7 +7,6 @@ define ['backbone', 'models/user/userItem', 'app.lib/backbone.dss.model.collecti
url: -> url: ->
com.podnoms.settings.urlRoot + "user/?limit=" + @limit + "&offset=" + Math.max(@page-1, 0) * @limit com.podnoms.settings.urlRoot + "user/?limit=" + @limit + "&offset=" + Math.max(@page-1, 0) * @limit
initialize: -> initialize: ->
console.clear()
if not UserItem if not UserItem
@model = require('models/user/userItem') @model = require('models/user/userItem')

View File

@@ -24,7 +24,6 @@
}; };
UserCollection.prototype.initialize = function() { UserCollection.prototype.initialize = function() {
console.clear();
if (!UserItem) { if (!UserItem) {
return this.model = require('models/user/userItem'); return this.model = require('models/user/userItem');
} }

View File

@@ -1,130 +0,0 @@
define ['app', 'vent', 'marionette', 'fullcalendar', 'text!/tpl/ScheduleView'],
(App, vent, Marionette, fullcalendar, Template)->
class ScheduleView extends Marionette.ItemView
template: _.template(Template)
onShow: ->
$("#external-events div.external-event").each ->
# create an Event Object (http://arshaw.com/fullcalendar/docs/event_data/Event_Object/)
# it doesn't need to have a start or end
eventObject =
title: $.trim($(this).text()) # use the element's text as the event title
# store the Event Object in the DOM element so we can get to it later
$(this).data "eventObject", eventObject
# make the event draggable using jQuery UI
$(this).draggable
zIndex: 999
revert: true # will cause the event to go back to its
revertDuration: 0 # original position after the drag
return
date = new Date()
d = date.getDate()
m = date.getMonth()
y = date.getFullYear()
calendar = $("#calendar").fullCalendar(
#isRTL: true,
buttonText:
prev: "<i class=\"ace-icon fa fa-chevron-left\"></i>"
next: "<i class=\"ace-icon fa fa-chevron-right\"></i>"
header:
left: "prev,next today"
center: "title"
right: "month,agendaWeek,agendaDay"
events: [
{
title: "All Day Event"
start: new Date(y, m, 1)
className: "label-important"
}
{
title: "Long Event"
start: new Date(y, m, d - 5)
end: new Date(y, m, d - 2)
className: "label-success"
}
{
title: "Some Event"
start: new Date(y, m, d - 3, 16, 0)
allDay: false
}
]
editable: true
droppable: true # this allows things to be dropped onto the calendar !!!
drop: (date, allDay) -> # this function is called when something is dropped
# retrieve the dropped element's stored Event Object
originalEventObject = $(this).data("eventObject")
$extraEventClass = $(this).attr("data-class")
# we need to copy it, so that multiple events don't have a reference to the same object
copiedEventObject = $.extend({}, originalEventObject)
# assign it the date that was reported
copiedEventObject.start = date
copiedEventObject.allDay = allDay
copiedEventObject["className"] = [$extraEventClass] if $extraEventClass
# render the event on the calendar
# the last `true` argument determines if the event "sticks" (http://arshaw.com/fullcalendar/docs/event_rendering/renderEvent/)
$("#calendar").fullCalendar "renderEvent", copiedEventObject, true
# is the "remove after drop" checkbox checked?
# if so, remove the element from the "Draggable Events" list
$(this).remove() if $("#drop-remove").is(":checked")
return
selectable: true
selectHelper: true
select: (start, end, allDay) ->
bootbox.prompt "New Event Title:", (title) ->
if title isnt null
calendar.fullCalendar "renderEvent",
title: title
start: start
end: end
allDay: allDay
, true # make the event "stick"
return
calendar.fullCalendar "unselect"
return
eventClick: (calEvent, jsEvent, view) ->
#display a modal
modal = "<div class=\"modal fade\">\t\t\t <div class=\"modal-dialog\">\t\t\t <div class=\"modal-content\">\t\t\t\t <div class=\"modal-body\">\t\t\t\t <button type=\"button\" class=\"close\" data-dismiss=\"modal\" style=\"margin-top:-10px;\">&times;</button>\t\t\t\t <form class=\"no-margin\">\t\t\t\t\t <label>Change event name &nbsp;</label>\t\t\t\t\t <input class=\"middle\" autocomplete=\"off\" type=\"text\" value=\"" + calEvent.title + "\" />\t\t\t\t\t <button type=\"submit\" class=\"btn btn-sm btn-success\"><i class=\"ace-icon fa fa-check\"></i> Save</button>\t\t\t\t </form>\t\t\t\t </div>\t\t\t\t <div class=\"modal-footer\">\t\t\t\t\t<button type=\"button\" class=\"btn btn-sm btn-danger\" data-action=\"delete\"><i class=\"ace-icon fa fa-trash-o\"></i> Delete Event</button>\t\t\t\t\t<button type=\"button\" class=\"btn btn-sm\" data-dismiss=\"modal\"><i class=\"ace-icon fa fa-times\"></i> Cancel</button>\t\t\t\t </div>\t\t\t </div>\t\t\t </div>\t\t\t</div>"
modal = $(modal).appendTo("body")
modal.find("form").on "submit", (ev) ->
ev.preventDefault()
calEvent.title = $(this).find("input[type=text]").val()
calendar.fullCalendar "updateEvent", calEvent
modal.modal "hide"
return
modal.find("button[data-action=delete]").on "click", ->
calendar.fullCalendar "removeEvents", (ev) ->
ev._id is calEvent._id
modal.modal "hide"
return
modal.modal("show").on "hidden", ->
modal.remove()
return
return
)
true
ScheduleView

View File

@@ -1,125 +0,0 @@
// Generated by CoffeeScript 1.4.0
(function() {
var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
define(['app', 'vent', 'marionette', 'fullcalendar', 'text!/tpl/ScheduleView'], function(App, vent, Marionette, fullcalendar, Template) {
var ScheduleView;
ScheduleView = (function(_super) {
__extends(ScheduleView, _super);
function ScheduleView() {
return ScheduleView.__super__.constructor.apply(this, arguments);
}
ScheduleView.prototype.template = _.template(Template);
ScheduleView.prototype.onShow = function() {
var calendar, d, date, m, y;
$("#external-events div.external-event").each(function() {
var eventObject;
eventObject = {
title: $.trim($(this).text())
};
$(this).data("eventObject", eventObject);
$(this).draggable({
zIndex: 999,
revert: true,
revertDuration: 0
});
});
date = new Date();
d = date.getDate();
m = date.getMonth();
y = date.getFullYear();
return calendar = $("#calendar").fullCalendar({
buttonText: {
prev: "<i class=\"ace-icon fa fa-chevron-left\"></i>",
next: "<i class=\"ace-icon fa fa-chevron-right\"></i>"
},
header: {
left: "prev,next today",
center: "title",
right: "month,agendaWeek,agendaDay"
},
events: [
{
title: "All Day Event",
start: new Date(y, m, 1),
className: "label-important"
}, {
title: "Long Event",
start: new Date(y, m, d - 5),
end: new Date(y, m, d - 2),
className: "label-success"
}, {
title: "Some Event",
start: new Date(y, m, d - 3, 16, 0),
allDay: false
}
],
editable: true,
droppable: true,
drop: function(date, allDay) {
var $extraEventClass, copiedEventObject, originalEventObject;
originalEventObject = $(this).data("eventObject");
$extraEventClass = $(this).attr("data-class");
copiedEventObject = $.extend({}, originalEventObject);
copiedEventObject.start = date;
copiedEventObject.allDay = allDay;
if ($extraEventClass) {
copiedEventObject["className"] = [$extraEventClass];
}
$("#calendar").fullCalendar("renderEvent", copiedEventObject, true);
if ($("#drop-remove").is(":checked")) {
$(this).remove();
}
},
selectable: true,
selectHelper: true,
select: function(start, end, allDay) {
bootbox.prompt("New Event Title:", function(title) {
if (title !== null) {
calendar.fullCalendar("renderEvent", {
title: title,
start: start,
end: end,
allDay: allDay
}, true);
}
});
calendar.fullCalendar("unselect");
},
eventClick: function(calEvent, jsEvent, view) {
var modal;
modal = "<div class=\"modal fade\">\t\t\t <div class=\"modal-dialog\">\t\t\t <div class=\"modal-content\">\t\t\t\t <div class=\"modal-body\">\t\t\t\t <button type=\"button\" class=\"close\" data-dismiss=\"modal\" style=\"margin-top:-10px;\">&times;</button>\t\t\t\t <form class=\"no-margin\">\t\t\t\t\t <label>Change event name &nbsp;</label>\t\t\t\t\t <input class=\"middle\" autocomplete=\"off\" type=\"text\" value=\"" + calEvent.title + "\" />\t\t\t\t\t <button type=\"submit\" class=\"btn btn-sm btn-success\"><i class=\"ace-icon fa fa-check\"></i> Save</button>\t\t\t\t </form>\t\t\t\t </div>\t\t\t\t <div class=\"modal-footer\">\t\t\t\t\t<button type=\"button\" class=\"btn btn-sm btn-danger\" data-action=\"delete\"><i class=\"ace-icon fa fa-trash-o\"></i> Delete Event</button>\t\t\t\t\t<button type=\"button\" class=\"btn btn-sm\" data-dismiss=\"modal\"><i class=\"ace-icon fa fa-times\"></i> Cancel</button>\t\t\t\t </div>\t\t\t </div>\t\t\t </div>\t\t\t</div>";
modal = $(modal).appendTo("body");
modal.find("form").on("submit", function(ev) {
ev.preventDefault();
calEvent.title = $(this).find("input[type=text]").val();
calendar.fullCalendar("updateEvent", calEvent);
modal.modal("hide");
});
modal.find("button[data-action=delete]").on("click", function() {
calendar.fullCalendar("removeEvents", function(ev) {
return ev._id === calEvent._id;
});
modal.modal("hide");
});
modal.modal("show").on("hidden", function() {
modal.remove();
});
}
});
};
true;
return ScheduleView;
})(Marionette.ItemView);
return ScheduleView;
});
}).call(this);

View File

@@ -0,0 +1,108 @@
define ['app', 'vent', 'utils', 'marionette', 'fullcalendar',
'views/show/scheduleShowMixListView',
'models/show/showCollection', 'models/show/showItem',
'models/mix/mixCollection',
'text!/tpl/ShowScheduleLayout'],
(App, vent, utils, Marionette, fullcalendar,
ScheduleShowMixList,
ShowCollection, ShowItem,
MixCollection,
Template)->
class ScheduleShowLayout extends Marionette.Layout
template: _.template(Template)
regions:
availableMixes: "#external-events"
initialize: (options)->
@collection = new ShowCollection()
@options = options
@mixCollection = new MixCollection()
@mixCollection.fetch
data: {for_show: true, order_by: 'latest'}
success: (collection)=>
@availableMixes.show(new ScheduleShowMixList({collection: collection}))
return
onShow: =>
@calendar = $("#calendar").fullCalendar(
editable: true
droppable: true
selectable: true
selectHelper: true
defaultView: "agendaDay"
buttonText:
prev: "<i class=\"ace-icon fa fa-chevron-left\"></i>"
next: "<i class=\"ace-icon fa fa-chevron-right\"></i>"
header:
left: "prev,next today"
center: "title"
right: "month,agendaWeek,agendaDay"
drop: (date, allDay, jsEvent, ui) =>
s = new ShowItem(
mix: com.podnoms.settings.urlRoot + jsEvent.target.id
start: date
end: date
description: $(jsEvent.toElement).text().trim()
)
s.save null,
success: (model, response) =>
@collection.add(model)
@_renderEvent(model)
$(this).remove() # if $("#drop-remove").is(":checked")
error: (model, response) =>
utils.showError(response.responseText)
return
eventClick: (calEvent, jsEvent, view) ->
#display a modal
modal = "<div class=\"modal fade\">\t\t\t <div class=\"modal-dialog\">\t\t\t <div class=\"modal-content\">\t\t\t\t <div class=\"modal-body\">\t\t\t\t <button type=\"button\" class=\"close\" data-dismiss=\"modal\" style=\"margin-top:-10px;\">&times;</button>\t\t\t\t <form class=\"no-margin\">\t\t\t\t\t <label>Change event name &nbsp;</label>\t\t\t\t\t <input class=\"middle\" autocomplete=\"off\" type=\"text\" value=\"" + calEvent.title + "\" />\t\t\t\t\t <button type=\"submit\" class=\"btn btn-sm btn-success\"><i class=\"ace-icon fa fa-check\"></i> Save</button>\t\t\t\t </form>\t\t\t\t </div>\t\t\t\t <div class=\"modal-footer\">\t\t\t\t\t<button type=\"button\" class=\"btn btn-sm btn-danger\" data-action=\"delete\"><i class=\"ace-icon fa fa-trash-o\"></i> Delete Event</button>\t\t\t\t\t<button type=\"button\" class=\"btn btn-sm\" data-dismiss=\"modal\"><i class=\"ace-icon fa fa-times\"></i> Cancel</button>\t\t\t\t </div>\t\t\t </div>\t\t\t </div>\t\t\t</div>"
modal = $(modal).appendTo("body")
modal.find("form").on "submit", (ev) ->
ev.preventDefault()
calEvent.title = $(this).find("input[type=text]").val()
calendar.fullCalendar "updateEvent", calEvent
modal.modal "hide"
return
modal.find("button[data-action=delete]").on "click", ->
calendar.fullCalendar "removeEvents", (ev) ->
ev._id is calEvent._id
modal.modal "hide"
return
modal.modal("show").on "hidden", ->
modal.remove()
return
return
)
@_fetchEvents()
_fetchEvents: ->
@collection.fetch(
data: @options
success: =>
console.log("ScheduleView: Collection fetched")
@collection.each (model) =>
@_renderEvent(model)
return
)
_renderEvent: (model) ->
$("#calendar").fullCalendar("renderEvent", {
title: model.get("description").substring(0, 15),
start: model.get("start"),
end: model.get("end"),
allDay: false,
className: "label-important"
})
true
ScheduleShowLayout

View File

@@ -0,0 +1,133 @@
// Generated by CoffeeScript 1.4.0
(function() {
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
define(['app', 'vent', 'utils', 'marionette', 'fullcalendar', 'views/show/scheduleShowMixListView', 'models/show/showCollection', 'models/show/showItem', 'models/mix/mixCollection', 'text!/tpl/ShowScheduleLayout'], function(App, vent, utils, Marionette, fullcalendar, ScheduleShowMixList, ShowCollection, ShowItem, MixCollection, Template) {
var ScheduleShowLayout;
ScheduleShowLayout = (function(_super) {
__extends(ScheduleShowLayout, _super);
function ScheduleShowLayout() {
this.onShow = __bind(this.onShow, this);
return ScheduleShowLayout.__super__.constructor.apply(this, arguments);
}
ScheduleShowLayout.prototype.template = _.template(Template);
ScheduleShowLayout.prototype.regions = {
availableMixes: "#external-events"
};
ScheduleShowLayout.prototype.initialize = function(options) {
var _this = this;
this.collection = new ShowCollection();
this.options = options;
this.mixCollection = new MixCollection();
this.mixCollection.fetch({
data: {
for_show: true,
order_by: 'latest'
},
success: function(collection) {
return _this.availableMixes.show(new ScheduleShowMixList({
collection: collection
}));
}
});
};
ScheduleShowLayout.prototype.onShow = function() {
var _this = this;
this.calendar = $("#calendar").fullCalendar({
editable: true,
droppable: true,
selectable: true,
selectHelper: true,
defaultView: "agendaDay",
buttonText: {
prev: "<i class=\"ace-icon fa fa-chevron-left\"></i>",
next: "<i class=\"ace-icon fa fa-chevron-right\"></i>"
},
header: {
left: "prev,next today",
center: "title",
right: "month,agendaWeek,agendaDay"
},
drop: function(date, allDay, jsEvent, ui) {
var s;
s = new ShowItem({
mix: com.podnoms.settings.urlRoot + jsEvent.target.id,
start: date,
end: date,
description: $(jsEvent.toElement).text().trim()
});
s.save(null, {
success: function(model, response) {
_this.collection.add(model);
_this._renderEvent(model);
return $(_this).remove();
},
error: function(model, response) {
return utils.showError(response.responseText);
}
});
},
eventClick: function(calEvent, jsEvent, view) {
var modal;
modal = "<div class=\"modal fade\">\t\t\t <div class=\"modal-dialog\">\t\t\t <div class=\"modal-content\">\t\t\t\t <div class=\"modal-body\">\t\t\t\t <button type=\"button\" class=\"close\" data-dismiss=\"modal\" style=\"margin-top:-10px;\">&times;</button>\t\t\t\t <form class=\"no-margin\">\t\t\t\t\t <label>Change event name &nbsp;</label>\t\t\t\t\t <input class=\"middle\" autocomplete=\"off\" type=\"text\" value=\"" + calEvent.title + "\" />\t\t\t\t\t <button type=\"submit\" class=\"btn btn-sm btn-success\"><i class=\"ace-icon fa fa-check\"></i> Save</button>\t\t\t\t </form>\t\t\t\t </div>\t\t\t\t <div class=\"modal-footer\">\t\t\t\t\t<button type=\"button\" class=\"btn btn-sm btn-danger\" data-action=\"delete\"><i class=\"ace-icon fa fa-trash-o\"></i> Delete Event</button>\t\t\t\t\t<button type=\"button\" class=\"btn btn-sm\" data-dismiss=\"modal\"><i class=\"ace-icon fa fa-times\"></i> Cancel</button>\t\t\t\t </div>\t\t\t </div>\t\t\t </div>\t\t\t</div>";
modal = $(modal).appendTo("body");
modal.find("form").on("submit", function(ev) {
ev.preventDefault();
calEvent.title = $(this).find("input[type=text]").val();
calendar.fullCalendar("updateEvent", calEvent);
modal.modal("hide");
});
modal.find("button[data-action=delete]").on("click", function() {
calendar.fullCalendar("removeEvents", function(ev) {
return ev._id === calEvent._id;
});
modal.modal("hide");
});
modal.modal("show").on("hidden", function() {
modal.remove();
});
}
});
return this._fetchEvents();
};
ScheduleShowLayout.prototype._fetchEvents = function() {
var _this = this;
return this.collection.fetch({
data: this.options,
success: function() {
console.log("ScheduleView: Collection fetched");
_this.collection.each(function(model) {
return _this._renderEvent(model);
});
}
});
};
ScheduleShowLayout.prototype._renderEvent = function(model) {
return $("#calendar").fullCalendar("renderEvent", {
title: model.get("description").substring(0, 15),
start: model.get("start"),
end: model.get("end"),
allDay: false,
className: "label-important"
});
};
true;
return ScheduleShowLayout;
})(Marionette.Layout);
return ScheduleShowLayout;
});
}).call(this);

View File

@@ -0,0 +1,30 @@
define ['app', 'vent', 'marionette', 'fullcalendar',
'models/show/showCollection',
'models/mix/mixCollection',
'text!/tpl/ShowScheduleMixItem'],
(App, vent, Marionette, fullcalendar,
ScheduleCollection, MixCollection,
Template)->
class ScheduleShowMixItem extends Marionette.ItemView
template: _.template(Template)
class ScheduleShowMixList extends Marionette.CollectionView
itemView: ScheduleShowMixItem
initialize: (options)->
console.log("ScheduleShowMixList: initialize")
true
onShow: ->
$("#external-events div.external-event").each ->
$(this).draggable
zIndex: 999
revert: true # will cause the event to go back to its
revertDuration: 0 # original position after the drag
return
true
ScheduleShowMixList

View File

@@ -0,0 +1,54 @@
// Generated by CoffeeScript 1.4.0
(function() {
var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
define(['app', 'vent', 'marionette', 'fullcalendar', 'models/show/showCollection', 'models/mix/mixCollection', 'text!/tpl/ShowScheduleMixItem'], function(App, vent, Marionette, fullcalendar, ScheduleCollection, MixCollection, Template) {
var ScheduleShowMixItem, ScheduleShowMixList;
ScheduleShowMixItem = (function(_super) {
__extends(ScheduleShowMixItem, _super);
function ScheduleShowMixItem() {
return ScheduleShowMixItem.__super__.constructor.apply(this, arguments);
}
ScheduleShowMixItem.prototype.template = _.template(Template);
return ScheduleShowMixItem;
})(Marionette.ItemView);
ScheduleShowMixList = (function(_super) {
__extends(ScheduleShowMixList, _super);
function ScheduleShowMixList() {
return ScheduleShowMixList.__super__.constructor.apply(this, arguments);
}
ScheduleShowMixList.prototype.itemView = ScheduleShowMixItem;
ScheduleShowMixList.prototype.initialize = function(options) {
console.log("ScheduleShowMixList: initialize");
return true;
};
ScheduleShowMixList.prototype.onShow = function() {
return $("#external-events div.external-event").each(function() {
$(this).draggable({
zIndex: 999,
revert: true,
revertDuration: 0
});
});
};
true;
return ScheduleShowMixList;
})(Marionette.CollectionView);
return ScheduleShowMixList;
});
}).call(this);

View File

@@ -40,21 +40,23 @@
{% include 'inc/analytics.html' %} {% include 'inc/analytics.html' %}
<div id="header"></div> <div id="header"></div>
<div class="space-6"></div> <div class="space-6"></div>
<div class="body-content col-md-9"> <div class="col-md-12" id="full-content">
<div class="row"> <div class="body-content col-md-9">
<div class="ua-message">{{ ua_html|safe }}</div> <div class="row">
<div class="ua-message">{{ ua_html|safe }}</div>
</div>
<div class="row">
<div id="content"></div>
</div>
{% block content %}
{% endblock %}
</div> </div>
<div class="row"> <div id="side-content" class="col-md-3 hidden-phone">
<div id="content"></div> {% block sidecontent %}
{% endblock %}
<div id="sidebar"></div>
<div id="site-content-fill"></div>
</div> </div>
{% block content %}
{% endblock %}
</div>
<div id="side-content" class="col-md-3 hidden-phone">
{% block sidecontent %}
{% endblock %}
<div id="sidebar"></div>
<div id="site-content-fill"></div>
</div> </div>
<div id="footer"></div> <div id="footer"></div>
<script src="/js/settings/"></script> <script src="/js/settings/"></script>

View File

@@ -1,61 +0,0 @@
<div class="row">
<div class="col-sm-9">
<div class="space"></div>
<div id="calendar"></div>
</div>
<div class="col-sm-3">
<div class="widget-box transparent">
<div class="widget-header">
<h4>Draggable events</h4>
</div>
<div class="widget-body">
<div class="widget-main no-padding">
<div id="external-events">
<div class="external-event label-grey" data-class="label-grey">
<i class="ace-icon fa fa-arrows"></i>
My Event 1
</div>
<div class="external-event label-success" data-class="label-success">
<i class="ace-icon fa fa-arrows"></i>
My Event 2
</div>
<div class="external-event label-danger" data-class="label-danger">
<i class="ace-icon fa fa-arrows"></i>
My Event 3
</div>
<div class="external-event label-purple" data-class="label-purple">
<i class="ace-icon fa fa-arrows"></i>
My Event 4
</div>
<div class="external-event label-yellow" data-class="label-yellow">
<i class="ace-icon fa fa-arrows"></i>
My Event 5
</div>
<div class="external-event label-pink" data-class="label-pink">
<i class="ace-icon fa fa-arrows"></i>
My Event 6
</div>
<div class="external-event label-info" data-class="label-info">
<i class="ace-icon fa fa-arrows"></i>
My Event 7
</div>
<label>
<input type="checkbox" class="ace ace-checkbox" id="drop-remove"/>
<span class="lbl"> Remove after drop</span>
</label>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,20 @@
<div class="row">
<div class="col-sm-9">
<div class="space"></div>
<div id="calendar"></div>
</div>
<div class="col-sm-3">
<div class="widget-box transparent">
<div class="widget-header">
<h4>Schedule shows</h4>
</div>
<div class="widget-body">
<div class="widget-main no-padding">
<div id="external-events">
</div>
</div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,4 @@
<div class="external-event label-pink" data-class="label-pink" id="<%= item_url %>">
<i class="ace-icon fa fa-arrows"></i>
<%= title %>
</div>