mirror of
https://github.com/fergalmoran/dss.git
synced 2026-02-05 15:44:20 +00:00
Various changes to user profile editing
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -4,6 +4,7 @@ tags
|
||||
.tags_sorted_by_file
|
||||
.idea
|
||||
*.pyc
|
||||
*.swp
|
||||
media/*
|
||||
build/*
|
||||
_working/*
|
||||
@@ -13,4 +14,3 @@ dss.conf
|
||||
dss/debugsettings.py
|
||||
mysql
|
||||
test.py
|
||||
|
||||
|
||||
@@ -209,7 +209,7 @@ def upload_release_image(request, release_id):
|
||||
release.save()
|
||||
return HttpResponse(_get_json("Success"))
|
||||
except Exception, ex:
|
||||
logger.exception("Error uploading avatar")
|
||||
logger.exception("Error uploading release image")
|
||||
return HttpResponse(_get_json("Failed"))
|
||||
|
||||
|
||||
@@ -223,17 +223,17 @@ def upload_image(request, mix_id):
|
||||
mix.save()
|
||||
return HttpResponse(_get_json("Success"))
|
||||
except Exception, ex:
|
||||
logger.exception("Error uploading avatar")
|
||||
logger.exception("Error uploading image")
|
||||
return HttpResponse(_get_json("Failed"))
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
def upload_avatar_image(request):
|
||||
try:
|
||||
if 'Filedata' in request.FILES:
|
||||
if 'avatar_image' in request.FILES:
|
||||
profile = request.user.get_profile()
|
||||
if profile:
|
||||
profile.avatar_image = request.FILES['Filedata']
|
||||
profile.avatar_image = request.FILES['avatar_image']
|
||||
profile.save()
|
||||
return HttpResponse(_get_json("Success"))
|
||||
except Exception, ex:
|
||||
|
||||
@@ -49,5 +49,7 @@ class ActivityResource(BackboneCompatibleResource):
|
||||
return [i for i in data['objects'] if i is not None and i.obj.user is not None and i.obj.get_object_name is not None and i.obj.get_object_url is not None]
|
||||
"""
|
||||
|
||||
"""
|
||||
def dehydrate_date(self, bundle):
|
||||
return self.humanize_date(bundle.obj.date)
|
||||
"""
|
||||
@@ -22,8 +22,10 @@ class CommentResource(BackboneCompatibleResource):
|
||||
bundle.data['user'] = {'pk': request.user.pk}
|
||||
return super(CommentResource, self).obj_create(bundle, request, user=request.user)
|
||||
|
||||
"""
|
||||
def dehydrate_date_created(self, bundle):
|
||||
return self.humanize_date(bundle.obj.date_created)
|
||||
"""
|
||||
|
||||
def dehydrate(self, bundle):
|
||||
bundle.data['avatar_image'] = bundle.obj.user.get_profile().get_small_profile_image()
|
||||
|
||||
@@ -1,71 +1,88 @@
|
||||
from django.conf.urls import url
|
||||
from django.contrib.auth.models import User
|
||||
from tastypie import fields
|
||||
from tastypie.authentication import Authentication
|
||||
from tastypie.authorization import Authorization
|
||||
from tastypie.constants import ALL, ALL_WITH_RELATIONS
|
||||
from tastypie.authorization import DjangoAuthorization
|
||||
from spa.api.v1.BackboneCompatibleResource import BackboneCompatibleResource
|
||||
from spa.models import UserProfile
|
||||
|
||||
|
||||
class UserResource(BackboneCompatibleResource):
|
||||
class UserProfileResource(BackboneCompatibleResource):
|
||||
class Meta:
|
||||
queryset = UserProfile.objects.all()
|
||||
excludes = []
|
||||
authorization = Authorization()
|
||||
authentication = Authentication()
|
||||
resource_name = 'profile'
|
||||
include_resource_uri = False
|
||||
include_absolute_url = False
|
||||
always_return_data = True
|
||||
filtering = {
|
||||
'user': ALL_WITH_RELATIONS,
|
||||
'username': ALL,
|
||||
'id': ALL,
|
||||
}
|
||||
authorization = DjangoAuthorization()
|
||||
authentication = Authentication()
|
||||
|
||||
def prepend_urls(self):
|
||||
return [
|
||||
url(r"^(?P<resource_name>%s)/(?P<slug>[\w\d_.-]+)/$" % self._meta.resource_name, self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),
|
||||
]
|
||||
def _hydrateBitmapOption(self, source, comparator):
|
||||
return "checked" if (source & comparator) != 0 else ""
|
||||
|
||||
def authorized_read_list(self, object_list, bundle):
|
||||
return object_list.filter(user_id=bundle.request.user.id)
|
||||
|
||||
def authorized_read_detail(self, object_list, bundle):
|
||||
return object_list.only('description')
|
||||
def hydrate(self, bundle):
|
||||
if 'activity_sharing_likes' in bundle.data:
|
||||
likes = UserProfile.ACTIVITY_SHARE_LIKES if bundle.data['activity_sharing_likes'] else 0
|
||||
favourites = UserProfile.ACTIVITY_SHARE_FAVOURITES if bundle.data['activity_sharing_favourites'] else 0
|
||||
comments = UserProfile.ACTIVITY_SHARE_COMMENTS if bundle.data['activity_sharing_comments'] else 0
|
||||
bundle.data['activity_sharing'] = (likes | favourites | comments)
|
||||
del bundle.data['activity_sharing_likes']
|
||||
del bundle.data['activity_sharing_favourites']
|
||||
del bundle.data['activity_sharing_comments']
|
||||
|
||||
if 'activity_sharing_networks_facebook' in bundle.data:
|
||||
facebook = UserProfile.ACTIVITY_SHARE_NETWORK_FACEBOOK if bundle.data['activity_sharing_networks_facebook'] else 0
|
||||
twitter = UserProfile.ACTIVITY_SHARE_NETWORK_TWITTER if bundle.data['activity_sharing_networks_twitter'] else 0
|
||||
bundle.data['activity_sharing_networks'] = (facebook | twitter)
|
||||
del bundle.data['activity_sharing_networks_facebook']
|
||||
del bundle.data['activity_sharing_networks_twitter']
|
||||
|
||||
return bundle
|
||||
|
||||
def obj_update(self, bundle, skip_errors=False, **kwargs):
|
||||
"""
|
||||
This feels extremely hacky - but for some reason, deleting from the bundle
|
||||
in hydrate is not preventing the fields from being serialized at the ORM
|
||||
"""
|
||||
if 'activity_sharing_networks_facebook' in kwargs: del kwargs['activity_sharing_networks_facebook']
|
||||
if 'activity_sharing_networks_twitter' in kwargs: del kwargs['activity_sharing_networks_twitter']
|
||||
if 'activity_sharing_likes' in kwargs: del kwargs['activity_sharing_likes']
|
||||
if 'activity_sharing_favourites' in kwargs: del kwargs['activity_sharing_favourites']
|
||||
if 'activity_sharing_comments' in kwargs: del kwargs['activity_sharing_comments']
|
||||
|
||||
return super(UserProfileResource, self).obj_update(bundle, skip_errors, **kwargs)
|
||||
|
||||
def dehydrate(self, bundle):
|
||||
|
||||
#set the "me" user only properties
|
||||
del bundle.data['activity_sharing']
|
||||
del bundle.data['activity_sharing_networks']
|
||||
if bundle.obj.user.id == bundle.request.user.id:
|
||||
bundle.data['email'] = bundle.obj.email
|
||||
if bundle.obj.activity_sharing is not None:
|
||||
bundle.data['activity_share_likes'] = \
|
||||
(bundle.obj.activity_sharing & UserProfile.ACTIVITY_SHARE_LIKES) != 0
|
||||
bundle.data['activity_share_favourites'] = \
|
||||
(bundle.obj.activity_sharing & UserProfile.ACTIVITY_SHARE_FAVOURITES) != 0
|
||||
bundle.data['activity_share_comments'] = \
|
||||
(bundle.obj.activity_sharing & UserProfile.ACTIVITY_SHARE_COMMENTS) != 0
|
||||
else:
|
||||
bundle.data['activity_share_likes'] = 0
|
||||
bundle.data['activity_share_favourites'] = 0
|
||||
bundle.data['activity_share_comments'] = 0
|
||||
bundle.data['activity_sharing_likes'] = \
|
||||
self._hydrateBitmapOption(bundle.obj.activity_sharing, UserProfile.ACTIVITY_SHARE_LIKES)
|
||||
bundle.data['activity_sharing_favourites'] = \
|
||||
self._hydrateBitmapOption(bundle.obj.activity_sharing, UserProfile.ACTIVITY_SHARE_FAVOURITES)
|
||||
bundle.data['activity_sharing_comments'] = \
|
||||
self._hydrateBitmapOption(bundle.obj.activity_sharing, UserProfile.ACTIVITY_SHARE_COMMENTS)
|
||||
|
||||
if bundle.obj.activity_sharing_networks is not None:
|
||||
bundle.data['activity_share_networks_facebook'] = \
|
||||
(bundle.obj.activity_sharing_networks & UserProfile.ACTIVITY_SHARE_NETWORK_FACEBOOK) != 0
|
||||
bundle.data['activity_share_networks_twitter'] = \
|
||||
(bundle.obj.activity_sharing_networks & UserProfile.ACTIVITY_SHARE_NETWORK_TWITTER) != 0
|
||||
else:
|
||||
bundle.data['activity_share_networks_facebook'] = 0
|
||||
bundle.data['activity_share_networks_facebook'] = 0
|
||||
else:
|
||||
del bundle.data['activity_sharing']
|
||||
del bundle.data['activity_sharing_networks']
|
||||
|
||||
bundle.data['first_name'] = bundle.obj.first_name
|
||||
bundle.data['last_name'] = bundle.obj.last_name
|
||||
bundle.data['activity_sharing_networks_facebook'] = \
|
||||
self._hydrateBitmapOption(bundle.obj.activity_sharing_networks, UserProfile.ACTIVITY_SHARE_NETWORK_FACEBOOK)
|
||||
bundle.data['activity_sharing_networks_twitter'] = \
|
||||
self._hydrateBitmapOption(bundle.obj.activity_sharing_networks, UserProfile.ACTIVITY_SHARE_NETWORK_TWITTER)
|
||||
|
||||
return bundle
|
||||
|
||||
def hydrate_slug(self, bundle):
|
||||
if bundle.data['slug'] == '':
|
||||
bundle.data['slug'] = None
|
||||
return bundle
|
||||
class UserResource(BackboneCompatibleResource):
|
||||
profile = fields.ToOneField(UserProfileResource, attribute='userprofile', related_name='user', full=True)
|
||||
|
||||
class Meta:
|
||||
queryset = User.objects.all()
|
||||
resource_name = 'user'
|
||||
excludes = ['is_active', 'is_staff', 'is_superuser', 'password']
|
||||
authorization = DjangoAuthorization()
|
||||
authentication = Authentication()
|
||||
|
||||
def dehydrate(self, bundle):
|
||||
if bundle.obj.id != bundle.request.user.id:
|
||||
del bundle.data['email']
|
||||
del bundle.data['username']
|
||||
|
||||
return bundle
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
from django.core.management.base import NoArgsCommand
|
||||
from spa.models import Mix
|
||||
|
||||
|
||||
class Command(NoArgsCommand):
|
||||
def handle(self, *args, **options):
|
||||
candidates = Mix.objects.filter(waveform_generated=False)
|
||||
for mix in candidates:
|
||||
print "Deleting: %s" % mix.title
|
||||
mix.delete()
|
||||
from django.core.management.base import NoArgsCommand
|
||||
from spa.models import Mix
|
||||
|
||||
|
||||
class Command(NoArgsCommand):
|
||||
def handle(self, *args, **options):
|
||||
candidates = Mix.objects.filter(waveform_generated=False)
|
||||
for mix in candidates:
|
||||
print "Deleting: %s" % mix.title
|
||||
mix.delete()
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import os
|
||||
import shutil
|
||||
from django.core.management.base import NoArgsCommand
|
||||
from spa.models import Mix
|
||||
|
||||
|
||||
class Command(NoArgsCommand):
|
||||
def handle(self, *args, **options):
|
||||
candidates = Mix.objects.all()
|
||||
for mix in candidates:
|
||||
file = mix.get_absolute_path(prefix="expired/")
|
||||
if os.path.exists(file):
|
||||
new = mix.get_absolute_path()
|
||||
shutil.move(file, new)
|
||||
import os
|
||||
import shutil
|
||||
from django.core.management.base import NoArgsCommand
|
||||
from spa.models import Mix
|
||||
|
||||
|
||||
class Command(NoArgsCommand):
|
||||
def handle(self, *args, **options):
|
||||
candidates = Mix.objects.all()
|
||||
for mix in candidates:
|
||||
file = mix.get_absolute_path(prefix="expired/")
|
||||
if os.path.exists(file):
|
||||
new = mix.get_absolute_path()
|
||||
shutil.move(file, new)
|
||||
|
||||
@@ -1,39 +1,39 @@
|
||||
"""
|
||||
Tightens up response content by removed superflous line breaks and whitespace.
|
||||
By Doug Van Horn
|
||||
|
||||
---- CHANGES ----
|
||||
v1.1 - 31st May 2011
|
||||
Cal Leeming [Simplicity Media Ltd]
|
||||
Modified regex to strip leading/trailing white space from every line, not just those with blank \n.
|
||||
|
||||
---- TODO ----
|
||||
* Ensure whitespace isn't stripped from within <pre> or <code> or <textarea> tags.
|
||||
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
class StripWhitespaceMiddleware(object):
|
||||
"""
|
||||
Strips leading and trailing whitespace from response content.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.whitespace = re.compile('^\s*\n', re.MULTILINE)
|
||||
# self.whitespace_lead = re.compile('^\s+', re.MULTILINE)
|
||||
# self.whitespace_trail = re.compile('\s+$', re.MULTILINE)
|
||||
|
||||
|
||||
def process_response(self, request, response):
|
||||
if "text" in response['Content-Type']:
|
||||
if hasattr(self, 'whitespace_lead'):
|
||||
response.content = self.whitespace_lead.sub('', response.content)
|
||||
if hasattr(self, 'whitespace_trail'):
|
||||
response.content = self.whitespace_trail.sub('\n', response.content)
|
||||
# Uncomment the next line to remove empty lines
|
||||
if hasattr(self, 'whitespace'):
|
||||
response.content = self.whitespace.sub('', response.content)
|
||||
return response
|
||||
else:
|
||||
return response
|
||||
"""
|
||||
Tightens up response content by removed superflous line breaks and whitespace.
|
||||
By Doug Van Horn
|
||||
|
||||
---- CHANGES ----
|
||||
v1.1 - 31st May 2011
|
||||
Cal Leeming [Simplicity Media Ltd]
|
||||
Modified regex to strip leading/trailing white space from every line, not just those with blank \n.
|
||||
|
||||
---- TODO ----
|
||||
* Ensure whitespace isn't stripped from within <pre> or <code> or <textarea> tags.
|
||||
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
class StripWhitespaceMiddleware(object):
|
||||
"""
|
||||
Strips leading and trailing whitespace from response content.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.whitespace = re.compile('^\s*\n', re.MULTILINE)
|
||||
# self.whitespace_lead = re.compile('^\s+', re.MULTILINE)
|
||||
# self.whitespace_trail = re.compile('\s+$', re.MULTILINE)
|
||||
|
||||
|
||||
def process_response(self, request, response):
|
||||
if "text" in response['Content-Type']:
|
||||
if hasattr(self, 'whitespace_lead'):
|
||||
response.content = self.whitespace_lead.sub('', response.content)
|
||||
if hasattr(self, 'whitespace_trail'):
|
||||
response.content = self.whitespace_trail.sub('\n', response.content)
|
||||
# Uncomment the next line to remove empty lines
|
||||
if hasattr(self, 'whitespace'):
|
||||
response.content = self.whitespace.sub('', response.content)
|
||||
return response
|
||||
else:
|
||||
return response
|
||||
|
||||
219
spa/migrations/0006_auto__chg_field_userprofile_user.py
Executable file
219
spa/migrations/0006_auto__chg_field_userprofile_user.py
Executable file
@@ -0,0 +1,219 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
# Changing field 'UserProfile.user'
|
||||
db.alter_column(u'spa_userprofile', 'user_id', self.gf('django.db.models.fields.related.OneToOneField')(unique=True, to=orm['auth.User']))
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Changing field 'UserProfile.user'
|
||||
db.alter_column(u'spa_userprofile', 'user_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], unique=True))
|
||||
|
||||
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', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
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', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'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'})
|
||||
},
|
||||
'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'}),
|
||||
'uid': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'null': '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.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', [], {}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"})
|
||||
},
|
||||
'spa.event': {
|
||||
'Meta': {'object_name': 'Event'},
|
||||
'attendees': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'attendees'", 'symmetrical': 'False', 'to': u"orm['auth.User']"}),
|
||||
'date_created': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2013, 4, 24, 0, 0)'}),
|
||||
'event_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2013, 4, 24, 0, 0)'}),
|
||||
'event_description': ('tinymce.models.HTMLField', [], {}),
|
||||
'event_recurrence': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Recurrence']"}),
|
||||
'event_time': ('django.db.models.fields.TimeField', [], {'default': 'datetime.datetime(2013, 4, 24, 0, 0)'}),
|
||||
'event_title': ('django.db.models.fields.CharField', [], {'max_length': '250'}),
|
||||
'event_venue': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.Venue']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': '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'}),
|
||||
'download_url': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'duration': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'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'}),
|
||||
'local_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}),
|
||||
'mix_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}),
|
||||
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
|
||||
'stream_url': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'title': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
|
||||
'uid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '38', 'blank': 'True'}),
|
||||
'upload_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2013, 4, 24, 0, 0)'}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['spa.UserProfile']"}),
|
||||
'waveform_generated': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
|
||||
},
|
||||
'spa.mixdownload': {
|
||||
'Meta': {'object_name': 'MixDownload', '_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': "'downloads'", 'to': "orm['spa.Mix']"})
|
||||
},
|
||||
'spa.mixfavourite': {
|
||||
'Meta': {'object_name': 'MixFavourite', '_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': "'favourites'", 'to': "orm['spa.Mix']"})
|
||||
},
|
||||
'spa.mixlike': {
|
||||
'Meta': {'object_name': 'MixLike', '_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': "'likes'", 'to': "orm['spa.Mix']"})
|
||||
},
|
||||
'spa.mixplay': {
|
||||
'Meta': {'object_name': 'MixPlay', '_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': "'plays'", 'to': "orm['spa.Mix']"})
|
||||
},
|
||||
'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(2013, 4, 24, 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'}),
|
||||
'local_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
|
||||
'release': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'release_audio'", 'null': 'True', 'to': "orm['spa.Release']"})
|
||||
},
|
||||
'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.userfollows': {
|
||||
'Meta': {'object_name': 'UserFollows'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'user_from': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'followers'", 'unique': 'True', 'to': "orm['spa.UserProfile']"}),
|
||||
'user_to': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'following'", 'unique': 'True', 'to': "orm['spa.UserProfile']"})
|
||||
},
|
||||
'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': '100', 'blank': 'True'}),
|
||||
'avatar_type': ('django.db.models.fields.CharField', [], {'default': "'social'", 'max_length': '15'}),
|
||||
'description': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'blank': 'True'}),
|
||||
'display_name': ('django.db.models.fields.CharField', [], {'max_length': '35', 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': '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']
|
||||
@@ -30,7 +30,7 @@ class UserProfile(_BaseModel):
|
||||
ACTIVITY_SHARE_NETWORK_TWITTER = 2
|
||||
|
||||
# This field is required.
|
||||
user = models.ForeignKey(User, unique=True)
|
||||
user = models.OneToOneField(User, unique=True, related_name='userprofile')
|
||||
avatar_type = models.CharField(max_length=15, default='social')
|
||||
avatar_image = models.ImageField(blank=True, upload_to=avatar_name)
|
||||
display_name = models.CharField(blank=True, max_length=35)
|
||||
@@ -43,19 +43,15 @@ class UserProfile(_BaseModel):
|
||||
def __unicode__(self):
|
||||
return "%s - %s" % (self.user.get_full_name(), self.slug)
|
||||
|
||||
def save(self, force_insert=False, force_update=False, using=None):
|
||||
def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
|
||||
"""
|
||||
Save Photo after ensuring it is not blank. Resize as needed.
|
||||
"""
|
||||
|
||||
if not force_insert and not self.id:
|
||||
return
|
||||
|
||||
if self.slug is None or self.slug == '':
|
||||
self.slug = unique_slugify(self, self.get_username())
|
||||
print "Slugified: %s" % self.slug
|
||||
|
||||
return super(UserProfile, self).save(force_insert, force_update, using)
|
||||
return super(UserProfile, self).save(force_insert, force_update, using, update_fields)
|
||||
|
||||
def get_username(self):
|
||||
return self.user.username
|
||||
|
||||
@@ -1 +1 @@
|
||||
__author__ = 'fergalm'
|
||||
__author__ = 'fergalm'
|
||||
|
||||
@@ -7,6 +7,7 @@ from spa.models import UserProfile
|
||||
|
||||
__author__ = 'fergalm'
|
||||
|
||||
|
||||
@not_minified_response
|
||||
def get_template(request, template_name):
|
||||
#Temporary hack here to create user profiles for zombie users
|
||||
@@ -29,6 +30,9 @@ def get_template_ex(request, template_name):
|
||||
|
||||
|
||||
def get_javascript(request, template_name):
|
||||
localsettings.JS_SETTINGS.update({
|
||||
'CURRENT_USER_ID': request.user.id or -1
|
||||
})
|
||||
return render_to_response(
|
||||
'javascript/%s.js' % template_name,
|
||||
localsettings.JS_SETTINGS,
|
||||
|
||||
182
static/css/bootstrap-timepicker.css
vendored
182
static/css/bootstrap-timepicker.css
vendored
@@ -1,91 +1,91 @@
|
||||
|
||||
.bootstrap-timepicker.dropdown-menu {
|
||||
border-radius: 4px 4px 4px 4px;
|
||||
display: none;
|
||||
left: 0;
|
||||
margin-top: 1px;
|
||||
padding: 4px;
|
||||
top: 0;
|
||||
}
|
||||
.bootstrap-timepicker.dropdown-menu.open {
|
||||
display: inline-block;
|
||||
}
|
||||
.bootstrap-timepicker.dropdown-menu:before {
|
||||
border-bottom: 7px solid rgba(0, 0, 0, 0.2);
|
||||
border-left: 7px solid transparent;
|
||||
border-right: 7px solid transparent;
|
||||
content: "";
|
||||
left: 6px;
|
||||
position: absolute;
|
||||
top: -7px;
|
||||
}
|
||||
.bootstrap-timepicker.dropdown-menu:after {
|
||||
border-bottom: 6px solid #FFFFFF;
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
content: "";
|
||||
left: 7px;
|
||||
position: absolute;
|
||||
top: -6px;
|
||||
}
|
||||
.bootstrap-timepicker.modal {
|
||||
margin-left: -100px;
|
||||
margin-top: 0;
|
||||
top: 30%;
|
||||
width: 200px;
|
||||
}
|
||||
.bootstrap-timepicker.modal .modal-content {
|
||||
padding: 0;
|
||||
}
|
||||
.bootstrap-timepicker table {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.bootstrap-timepicker table td {
|
||||
height: 30px;
|
||||
margin: 0;
|
||||
padding: 2px;
|
||||
text-align: center;
|
||||
width: 49%;
|
||||
}
|
||||
.bootstrap-timepicker table.show-meridian td, .bootstrap-timepicker table.show-seconds td {
|
||||
width: 32%;
|
||||
}
|
||||
.bootstrap-timepicker table.show-seconds.show-meridian td {
|
||||
width: 23.5%;
|
||||
}
|
||||
.bootstrap-timepicker table td.separator {
|
||||
width: 2% !important;
|
||||
}
|
||||
.bootstrap-timepicker table td span {
|
||||
width: 100%;
|
||||
}
|
||||
.bootstrap-timepicker table td a {
|
||||
border: 1px solid transparent;
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
outline: 0 none;
|
||||
padding: 8px 0;
|
||||
width: 90%;
|
||||
}
|
||||
.bootstrap-timepicker table td a:hover {
|
||||
background-color: #EEEEEE;
|
||||
border-color: #DDDDDD;
|
||||
border-radius: 4px 4px 4px 4px;
|
||||
}
|
||||
.bootstrap-timepicker table td a i {
|
||||
margin-top: 2px;
|
||||
}
|
||||
.bootstrap-timepicker table td input {
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
width: 25px;
|
||||
}
|
||||
.bootstrap-timepicker-component .add-on {
|
||||
cursor: pointer;
|
||||
}
|
||||
.bootstrap-timepicker-component .add-on i {
|
||||
display: block;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
.bootstrap-timepicker.dropdown-menu {
|
||||
border-radius: 4px 4px 4px 4px;
|
||||
display: none;
|
||||
left: 0;
|
||||
margin-top: 1px;
|
||||
padding: 4px;
|
||||
top: 0;
|
||||
}
|
||||
.bootstrap-timepicker.dropdown-menu.open {
|
||||
display: inline-block;
|
||||
}
|
||||
.bootstrap-timepicker.dropdown-menu:before {
|
||||
border-bottom: 7px solid rgba(0, 0, 0, 0.2);
|
||||
border-left: 7px solid transparent;
|
||||
border-right: 7px solid transparent;
|
||||
content: "";
|
||||
left: 6px;
|
||||
position: absolute;
|
||||
top: -7px;
|
||||
}
|
||||
.bootstrap-timepicker.dropdown-menu:after {
|
||||
border-bottom: 6px solid #FFFFFF;
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
content: "";
|
||||
left: 7px;
|
||||
position: absolute;
|
||||
top: -6px;
|
||||
}
|
||||
.bootstrap-timepicker.modal {
|
||||
margin-left: -100px;
|
||||
margin-top: 0;
|
||||
top: 30%;
|
||||
width: 200px;
|
||||
}
|
||||
.bootstrap-timepicker.modal .modal-content {
|
||||
padding: 0;
|
||||
}
|
||||
.bootstrap-timepicker table {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.bootstrap-timepicker table td {
|
||||
height: 30px;
|
||||
margin: 0;
|
||||
padding: 2px;
|
||||
text-align: center;
|
||||
width: 49%;
|
||||
}
|
||||
.bootstrap-timepicker table.show-meridian td, .bootstrap-timepicker table.show-seconds td {
|
||||
width: 32%;
|
||||
}
|
||||
.bootstrap-timepicker table.show-seconds.show-meridian td {
|
||||
width: 23.5%;
|
||||
}
|
||||
.bootstrap-timepicker table td.separator {
|
||||
width: 2% !important;
|
||||
}
|
||||
.bootstrap-timepicker table td span {
|
||||
width: 100%;
|
||||
}
|
||||
.bootstrap-timepicker table td a {
|
||||
border: 1px solid transparent;
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
outline: 0 none;
|
||||
padding: 8px 0;
|
||||
width: 90%;
|
||||
}
|
||||
.bootstrap-timepicker table td a:hover {
|
||||
background-color: #EEEEEE;
|
||||
border-color: #DDDDDD;
|
||||
border-radius: 4px 4px 4px 4px;
|
||||
}
|
||||
.bootstrap-timepicker table td a i {
|
||||
margin-top: 2px;
|
||||
}
|
||||
.bootstrap-timepicker table td input {
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
width: 25px;
|
||||
}
|
||||
.bootstrap-timepicker-component .add-on {
|
||||
cursor: pointer;
|
||||
}
|
||||
.bootstrap-timepicker-component .add-on i {
|
||||
display: block;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
@@ -391,3 +391,14 @@ div.event-content td {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
.dss-option-table td{
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
#div_avatar_image_upload{
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
#div_avatar_image{
|
||||
display: inline-block;
|
||||
}
|
||||
@@ -221,14 +221,16 @@ var AppRouter = Backbone.Router.extend({
|
||||
alert("Connecting accounts");
|
||||
},
|
||||
userDetails: function () {
|
||||
var user = new User();
|
||||
var user = new User({
|
||||
id: com.podnoms.settings.currentUser
|
||||
});
|
||||
$('#site-content-fill').html('');
|
||||
user.fetch({
|
||||
success: function () {
|
||||
var content = new UserView({
|
||||
model: user
|
||||
}).el;
|
||||
$('#content').html(content);
|
||||
});
|
||||
$('#content').html(content.render().el);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
/** @license
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
Copyright (c) 2012, Fergal Moran. All rights reserved.
|
||||
Code provided under the BSD License:
|
||||
|
||||
*/
|
||||
var Activity = DSSModel.extend({
|
||||
urlRoot:com.podnoms.settings.urlRoot + "activity/"
|
||||
});
|
||||
|
||||
var ActivityCollection = TastypieCollection.extend({
|
||||
model: Activity,
|
||||
url:com.podnoms.settings.urlRoot + "activity/",
|
||||
comparator: function (activity) {
|
||||
return -activity.get("id");
|
||||
}
|
||||
/** @license
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
Copyright (c) 2012, Fergal Moran. All rights reserved.
|
||||
Code provided under the BSD License:
|
||||
|
||||
*/
|
||||
var Activity = DSSModel.extend({
|
||||
urlRoot:com.podnoms.settings.urlRoot + "activity/"
|
||||
});
|
||||
|
||||
var ActivityCollection = TastypieCollection.extend({
|
||||
model: Activity,
|
||||
url:com.podnoms.settings.urlRoot + "activity/",
|
||||
comparator: function (activity) {
|
||||
return -activity.get("id");
|
||||
}
|
||||
});
|
||||
@@ -8,8 +8,17 @@
|
||||
*/
|
||||
var User = DSSModel.extend({
|
||||
urlRoot:com.podnoms.settings.urlRoot + "user/",
|
||||
isValid:function () {
|
||||
isValid: function () {
|
||||
this.errors = {};
|
||||
return "";
|
||||
},
|
||||
avatarGravatar: function(){
|
||||
return this.get('profile').avatar_type == 'gravatar';
|
||||
},
|
||||
avatarSocial: function(){
|
||||
return this.get('profile').avatar_type == 'social';
|
||||
},
|
||||
avatarCustom: function(){
|
||||
return this.get('profile').avatar_type == 'custom';
|
||||
}
|
||||
});
|
||||
|
||||
@@ -235,7 +235,7 @@ window.MixCreateView = DSSEditableView.extend({
|
||||
},
|
||||
checkRedirect: function () {
|
||||
if (this.state == 2) {
|
||||
Backbone.history.navigate('/mix/' + this.model.get('id'), {trigger: true});
|
||||
Backbone.history.navigate('/mix/' + this.model.get('slug'), {trigger: true});
|
||||
}
|
||||
},
|
||||
initialize: function () {
|
||||
|
||||
@@ -6,77 +6,81 @@
|
||||
Code provided under the BSD License:
|
||||
|
||||
*/
|
||||
window.UserView = DSSEditableView.extend({
|
||||
events:{
|
||||
"click #save-changes":"saveChanges",
|
||||
"click input[type=radio]":"selectAvatar",
|
||||
"change input":"changed",
|
||||
"change textarea":"changed",
|
||||
"change select":"changed",
|
||||
"change .switch":"changeSwitch"
|
||||
},
|
||||
initialize:function () {
|
||||
this.render();
|
||||
},
|
||||
render:function () {
|
||||
var model = this.model;
|
||||
$(this.el).html(this.template({"item":this.model.toJSON()}));
|
||||
$('.switch', this.el).each(function (item) {
|
||||
var val = model.get(this.id) ? "on" : "off";
|
||||
$(this).attr('checked', val == "on");
|
||||
$(this).iphoneSwitch(
|
||||
val,
|
||||
function (obj) {
|
||||
},
|
||||
function (obj) {
|
||||
},
|
||||
{
|
||||
speed:250,
|
||||
use_images:true,
|
||||
track_bg_color:'#333',
|
||||
sync_checkbox:true
|
||||
}
|
||||
);
|
||||
});
|
||||
$("#div_avatar_image", this.el).hide();
|
||||
var avatarType = this.model.get('avatar_type');
|
||||
if (!com.podnoms.utils.isEmpty(avatarType))
|
||||
$('#' + this.model.get('avatar_type'), this.el).attr('checked', 'checked');
|
||||
|
||||
//console.clear();
|
||||
UserView = DSSEditableView.extend({
|
||||
events: {
|
||||
"click #save-changes": "saveChanges",
|
||||
"change input[type=radio]": "selectAvatar"
|
||||
},
|
||||
initialize: function () {
|
||||
},
|
||||
render: function () {
|
||||
ich.addTemplate('user', this.template());
|
||||
var renderedTemplate = ich.user(this.model.toJSON());
|
||||
$(this.el).html(renderedTemplate);
|
||||
|
||||
$("#div_avatar_image_upload", this.el).hide();
|
||||
var avatarType = this.model.get('profile').avatar_type;
|
||||
if (!com.podnoms.utils.isEmpty(avatarType)){
|
||||
$('#avatar_' + avatarType, this.el).attr('checked', true);
|
||||
if (avatarType == 'custom') {
|
||||
$("#div_avatar_image_upload", this.el).show();
|
||||
$('#file_upload').uploadifive({
|
||||
'uploadScript': 'ajax/upload_avatar_image/'
|
||||
});
|
||||
}
|
||||
}
|
||||
return this;
|
||||
},
|
||||
saveChanges:function () {
|
||||
var model = this.model;
|
||||
saveChanges: function () {
|
||||
var data = Backbone.Syphon.serialize(this);
|
||||
this.model.set(data);
|
||||
var ref = this;
|
||||
this._saveChanges({
|
||||
success:function () {
|
||||
com.podnoms.utils.showAlert("Success", "Successfully updated yourself");
|
||||
Backbone.history.navigate('/', {trigger:true});
|
||||
success: function () {
|
||||
if (ref.model.get('profile').avatar_type == 'custom'){
|
||||
$.ajaxFileUpload({
|
||||
url: '/ajax/upload_avatar_image/',
|
||||
secureuri: false,
|
||||
fileElementId: 'avatar_image',
|
||||
success: function (data, status) {
|
||||
if (typeof(data.error) != 'undefined') {
|
||||
if (data.error != '') {
|
||||
alert(data.error);
|
||||
} else {
|
||||
alert(data.msg);
|
||||
}
|
||||
} else {
|
||||
com.podnoms.utils.showAlert("Success", "Successfully updated yourself");
|
||||
Backbone.history.navigate('/', {trigger:true});
|
||||
}
|
||||
},
|
||||
error: function (data, status, e) {
|
||||
alert(e);
|
||||
}
|
||||
});
|
||||
}else{
|
||||
com.podnoms.utils.showAlert("Success", "Successfully updated yourself");
|
||||
Backbone.history.navigate('/', {trigger:true});
|
||||
}
|
||||
},
|
||||
error:function () {
|
||||
error: function () {
|
||||
com.podnoms.utils.showError("Error", "There was an error updating your info. Please try again later.");
|
||||
}
|
||||
});
|
||||
return false;
|
||||
},
|
||||
changeSwitch:function (evt) {
|
||||
var bit = $(evt.currentTarget).data('bitflag');
|
||||
var coalesce = $(evt.currentTarget).data('coalesce');
|
||||
if ($(evt.currentTarget).attr('checked')) {
|
||||
this.model.set(coalesce, this.model.get(coalesce) | bit);
|
||||
} else {
|
||||
this.model.set(coalesce, this.model.get(coalesce) & ~bit);
|
||||
}
|
||||
this.model.save();
|
||||
},
|
||||
selectAvatar:function (evt) {
|
||||
|
||||
selectAvatar: function (evt) {
|
||||
var type = $(evt.currentTarget).val();
|
||||
this.model.set('avatar_type', type);
|
||||
if (type == 'custom') {
|
||||
$("#div_avatar_image", this.el).show();
|
||||
$("#div_avatar_image_upload", this.el).show();
|
||||
$('#file_upload').uploadifive({
|
||||
'uploadScript':'ajax/upload_avatar_image/'
|
||||
'uploadScript': 'ajax/upload_avatar_image/'
|
||||
});
|
||||
}else{
|
||||
$("#div_avatar_image_upload", this.el).hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
2388
static/js/libs/backbone/backbone.marionette.js
Executable file
2388
static/js/libs/backbone/backbone.marionette.js
Executable file
File diff suppressed because it is too large
Load Diff
@@ -56,7 +56,7 @@ window.DSSModel = window.TastypieModel.extend({
|
||||
}
|
||||
});
|
||||
|
||||
window.DSSEditableView = Backbone.View.extend({
|
||||
window.DSSEditableView = Backbone.Marionette.ItemView.extend({
|
||||
events: {
|
||||
"change input": "changed",
|
||||
"change textarea": "changed"
|
||||
@@ -71,6 +71,9 @@ window.DSSEditableView = Backbone.View.extend({
|
||||
}
|
||||
},
|
||||
changed: function (evt) {
|
||||
//change handler for the form to update the model
|
||||
//with the new values
|
||||
return;
|
||||
var changed = evt.currentTarget;
|
||||
//$("#" + changed.id)
|
||||
if (!com.podnoms.utils.isEmpty(changed.id)) {
|
||||
|
||||
471
static/js/libs/backbone/backbone.syphon.js
Executable file
471
static/js/libs/backbone/backbone.syphon.js
Executable file
@@ -0,0 +1,471 @@
|
||||
// Backbone.Syphon, v0.4.1
|
||||
// Copyright (c)2012 Derick Bailey, Muted Solutions, LLC.
|
||||
// Distributed under MIT license
|
||||
// http://github.com/derickbailey/backbone.syphon
|
||||
Backbone.Syphon = (function (Backbone, $, _) {
|
||||
var Syphon = {};
|
||||
|
||||
// Ignore Element Types
|
||||
// --------------------
|
||||
|
||||
// Tell Syphon to ignore all elements of these types. You can
|
||||
// push new types to ignore directly in to this array.
|
||||
Syphon.ignoredTypes = ["button", "submit", "reset", "fieldset"];
|
||||
|
||||
// Syphon
|
||||
// ------
|
||||
|
||||
// Get a JSON object that represents
|
||||
// all of the form inputs, in this view.
|
||||
// Alternately, pass a form element directly
|
||||
// in place of the view.
|
||||
Syphon.serialize = function (view, options) {
|
||||
var data = {};
|
||||
|
||||
// Build the configuration
|
||||
var config = buildConfig(options);
|
||||
|
||||
// Get all of the elements to process
|
||||
var elements = getInputElements(view, config);
|
||||
|
||||
// Process all of the elements
|
||||
_.each(elements, function (el) {
|
||||
var $el = $(el);
|
||||
var type = getElementType($el);
|
||||
|
||||
// Get the key for the input
|
||||
var keyExtractor = config.keyExtractors.get(type);
|
||||
var key = keyExtractor($el);
|
||||
|
||||
// Get the value for the input
|
||||
var inputReader = config.inputReaders.get(type);
|
||||
var value = inputReader($el);
|
||||
|
||||
// Get the key assignment validator and make sure
|
||||
// it's valid before assigning the value to the key
|
||||
var validKeyAssignment = config.keyAssignmentValidators.get(type);
|
||||
if (validKeyAssignment($el, key, value)) {
|
||||
var keychain = config.keySplitter(key);
|
||||
data = assignKeyValue(data, keychain, value);
|
||||
}
|
||||
});
|
||||
|
||||
// Done; send back the results.
|
||||
return data;
|
||||
};
|
||||
|
||||
// Use the given JSON object to populate
|
||||
// all of the form inputs, in this view.
|
||||
// Alternately, pass a form element directly
|
||||
// in place of the view.
|
||||
Syphon.deserialize = function (view, data, options) {
|
||||
// Build the configuration
|
||||
var config = buildConfig(options);
|
||||
|
||||
// Get all of the elements to process
|
||||
var elements = getInputElements(view, config);
|
||||
|
||||
// Flatten the data structure that we are deserializing
|
||||
var flattenedData = flattenData(config, data);
|
||||
|
||||
// Process all of the elements
|
||||
_.each(elements, function (el) {
|
||||
var $el = $(el);
|
||||
var type = getElementType($el);
|
||||
|
||||
// Get the key for the input
|
||||
var keyExtractor = config.keyExtractors.get(type);
|
||||
var key = keyExtractor($el);
|
||||
|
||||
// Get the input writer and the value to write
|
||||
var inputWriter = config.inputWriters.get(type);
|
||||
var value = flattenedData[key];
|
||||
|
||||
// Write the value to the input
|
||||
inputWriter($el, value);
|
||||
});
|
||||
};
|
||||
|
||||
// Helpers
|
||||
// -------
|
||||
|
||||
// Retrieve all of the form inputs
|
||||
// from the form
|
||||
var getInputElements = function (view, config) {
|
||||
var form = getForm(view);
|
||||
var elements = form.elements;
|
||||
|
||||
elements = _.reject(elements, function (el) {
|
||||
var reject;
|
||||
var type = getElementType(el);
|
||||
var extractor = config.keyExtractors.get(type);
|
||||
var identifier = extractor($(el));
|
||||
|
||||
var foundInIgnored = _.include(config.ignoredTypes, type);
|
||||
var foundInInclude = _.include(config.include, identifier);
|
||||
var foundInExclude = _.include(config.exclude, identifier);
|
||||
|
||||
if (foundInInclude) {
|
||||
reject = false;
|
||||
} else {
|
||||
if (config.include) {
|
||||
reject = true;
|
||||
} else {
|
||||
reject = (foundInExclude || foundInIgnored);
|
||||
}
|
||||
}
|
||||
|
||||
return reject;
|
||||
});
|
||||
|
||||
return elements;
|
||||
};
|
||||
|
||||
// Determine what type of element this is. It
|
||||
// will either return the `type` attribute of
|
||||
// an `<input>` element, or the `tagName` of
|
||||
// the element when the element is not an `<input>`.
|
||||
var getElementType = function (el) {
|
||||
var typeAttr;
|
||||
var $el = $(el);
|
||||
var tagName = $el[0].tagName;
|
||||
var type = tagName;
|
||||
|
||||
if (tagName.toLowerCase() === "input") {
|
||||
typeAttr = $el.attr("type");
|
||||
if (typeAttr) {
|
||||
type = typeAttr;
|
||||
} else {
|
||||
type = "text";
|
||||
}
|
||||
}
|
||||
|
||||
// Always return the type as lowercase
|
||||
// so it can be matched to lowercase
|
||||
// type registrations.
|
||||
return type.toLowerCase();
|
||||
};
|
||||
|
||||
// If a form element is given, just return it.
|
||||
// Otherwise, get the form element from the view.
|
||||
var getForm = function (viewOrForm) {
|
||||
if (_.isUndefined(viewOrForm.$el) && viewOrForm.tagName.toLowerCase() === 'form') {
|
||||
return viewOrForm;
|
||||
} else {
|
||||
return viewOrForm.$el.is("form") ? viewOrForm.el : viewOrForm.$("form")[0];
|
||||
}
|
||||
};
|
||||
|
||||
// Build a configuration object and initialize
|
||||
// default values.
|
||||
var buildConfig = function (options) {
|
||||
var config = _.clone(options) || {};
|
||||
|
||||
config.ignoredTypes = _.clone(Syphon.ignoredTypes);
|
||||
config.inputReaders = config.inputReaders || Syphon.InputReaders;
|
||||
config.inputWriters = config.inputWriters || Syphon.InputWriters;
|
||||
config.keyExtractors = config.keyExtractors || Syphon.KeyExtractors;
|
||||
config.keySplitter = config.keySplitter || Syphon.KeySplitter;
|
||||
config.keyJoiner = config.keyJoiner || Syphon.KeyJoiner;
|
||||
config.keyAssignmentValidators = config.keyAssignmentValidators || Syphon.KeyAssignmentValidators;
|
||||
|
||||
return config;
|
||||
};
|
||||
|
||||
// Assigns `value` to a parsed JSON key.
|
||||
//
|
||||
// The first parameter is the object which will be
|
||||
// modified to store the key/value pair.
|
||||
//
|
||||
// The second parameter accepts an array of keys as a
|
||||
// string with an option array containing a
|
||||
// single string as the last option.
|
||||
//
|
||||
// The third parameter is the value to be assigned.
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// `["foo", "bar", "baz"] => {foo: {bar: {baz: "value"}}}`
|
||||
//
|
||||
// `["foo", "bar", ["baz"]] => {foo: {bar: {baz: ["value"]}}}`
|
||||
//
|
||||
// When the final value is an array with a string, the key
|
||||
// becomes an array, and values are pushed in to the array,
|
||||
// allowing multiple fields with the same name to be
|
||||
// assigned to the array.
|
||||
var assignKeyValue = function (obj, keychain, value) {
|
||||
if (!keychain) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
var key = keychain.shift();
|
||||
|
||||
// build the current object we need to store data
|
||||
if (!obj[key]) {
|
||||
obj[key] = _.isArray(key) ? [] : {};
|
||||
}
|
||||
|
||||
// if it's the last key in the chain, assign the value directly
|
||||
if (keychain.length === 0) {
|
||||
if (_.isArray(obj[key])) {
|
||||
obj[key].push(value);
|
||||
} else {
|
||||
obj[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
// recursive parsing of the array, depth-first
|
||||
if (keychain.length > 0) {
|
||||
assignKeyValue(obj[key], keychain, value);
|
||||
}
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
// Flatten the data structure in to nested strings, using the
|
||||
// provided `KeyJoiner` function.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// This input:
|
||||
//
|
||||
// ```js
|
||||
// {
|
||||
// widget: "wombat",
|
||||
// foo: {
|
||||
// bar: "baz",
|
||||
// baz: {
|
||||
// quux: "qux"
|
||||
// },
|
||||
// quux: ["foo", "bar"]
|
||||
// }
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// With a KeyJoiner that uses [ ] square brackets,
|
||||
// should produce this output:
|
||||
//
|
||||
// ```js
|
||||
// {
|
||||
// "widget": "wombat",
|
||||
// "foo[bar]": "baz",
|
||||
// "foo[baz][quux]": "qux",
|
||||
// "foo[quux]": ["foo", "bar"]
|
||||
// }
|
||||
// ```
|
||||
var flattenData = function (config, data, parentKey) {
|
||||
var flatData = {};
|
||||
|
||||
_.each(data, function (value, keyName) {
|
||||
var hash = {};
|
||||
|
||||
// If there is a parent key, join it with
|
||||
// the current, child key.
|
||||
if (parentKey) {
|
||||
keyName = config.keyJoiner(parentKey, keyName);
|
||||
}
|
||||
|
||||
if (_.isArray(value)) {
|
||||
keyName += "[]";
|
||||
hash[keyName] = value;
|
||||
} else if (_.isObject(value)) {
|
||||
hash = flattenData(config, value, keyName);
|
||||
} else {
|
||||
hash[keyName] = value;
|
||||
}
|
||||
|
||||
// Store the resulting key/value pairs in the
|
||||
// final flattened data object
|
||||
_.extend(flatData, hash);
|
||||
});
|
||||
|
||||
return flatData;
|
||||
};
|
||||
|
||||
return Syphon;
|
||||
})(Backbone, jQuery, _);
|
||||
|
||||
// Type Registry
|
||||
// -------------
|
||||
|
||||
// Type Registries allow you to register something to
|
||||
// an input type, and retrieve either the item registered
|
||||
// for a specific type or the default registration
|
||||
Backbone.Syphon.TypeRegistry = function () {
|
||||
this.registeredTypes = {};
|
||||
};
|
||||
|
||||
// Borrow Backbone's `extend` keyword for our TypeRegistry
|
||||
Backbone.Syphon.TypeRegistry.extend = Backbone.Model.extend;
|
||||
|
||||
_.extend(Backbone.Syphon.TypeRegistry.prototype, {
|
||||
|
||||
// Get the registered item by type. If nothing is
|
||||
// found for the specified type, the default is
|
||||
// returned.
|
||||
get: function (type) {
|
||||
var item = this.registeredTypes[type];
|
||||
|
||||
if (!item) {
|
||||
item = this.registeredTypes["default"];
|
||||
}
|
||||
|
||||
return item;
|
||||
},
|
||||
|
||||
// Register a new item for a specified type
|
||||
register: function (type, item) {
|
||||
this.registeredTypes[type] = item;
|
||||
},
|
||||
|
||||
// Register a default item to be used when no
|
||||
// item for a specified type is found
|
||||
registerDefault: function (item) {
|
||||
this.registeredTypes["default"] = item;
|
||||
},
|
||||
|
||||
// Remove an item from a given type registration
|
||||
unregister: function (type) {
|
||||
if (this.registeredTypes[type]) {
|
||||
delete this.registeredTypes[type];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Key Extractors
|
||||
// --------------
|
||||
|
||||
// Key extractors produce the "key" in `{key: "value"}`
|
||||
// pairs, when serializing.
|
||||
Backbone.Syphon.KeyExtractorSet = Backbone.Syphon.TypeRegistry.extend();
|
||||
|
||||
// Built-in Key Extractors
|
||||
Backbone.Syphon.KeyExtractors = new Backbone.Syphon.KeyExtractorSet();
|
||||
|
||||
// The default key extractor, which uses the
|
||||
// input element's "id" attribute
|
||||
Backbone.Syphon.KeyExtractors.registerDefault(function ($el) {
|
||||
return $el.prop("name");
|
||||
});
|
||||
|
||||
|
||||
// Input Readers
|
||||
// -------------
|
||||
|
||||
// Input Readers are used to extract the value from
|
||||
// an input element, for the serialized object result
|
||||
Backbone.Syphon.InputReaderSet = Backbone.Syphon.TypeRegistry.extend();
|
||||
|
||||
// Built-in Input Readers
|
||||
Backbone.Syphon.InputReaders = new Backbone.Syphon.InputReaderSet();
|
||||
|
||||
// The default input reader, which uses an input
|
||||
// element's "value"
|
||||
Backbone.Syphon.InputReaders.registerDefault(function ($el) {
|
||||
return $el.val();
|
||||
});
|
||||
|
||||
// Checkbox reader, returning a boolean value for
|
||||
// whether or not the checkbox is checked.
|
||||
Backbone.Syphon.InputReaders.register("checkbox", function ($el) {
|
||||
var checked = $el.prop("checked");
|
||||
return checked;
|
||||
});
|
||||
|
||||
|
||||
// Input Writers
|
||||
// -------------
|
||||
|
||||
// Input Writers are used to insert a value from an
|
||||
// object into an input element.
|
||||
Backbone.Syphon.InputWriterSet = Backbone.Syphon.TypeRegistry.extend();
|
||||
|
||||
// Built-in Input Writers
|
||||
Backbone.Syphon.InputWriters = new Backbone.Syphon.InputWriterSet();
|
||||
|
||||
// The default input writer, which sets an input
|
||||
// element's "value"
|
||||
Backbone.Syphon.InputWriters.registerDefault(function ($el, value) {
|
||||
$el.val(value);
|
||||
});
|
||||
|
||||
// Checkbox writer, set whether or not the checkbox is checked
|
||||
// depending on the boolean value.
|
||||
Backbone.Syphon.InputWriters.register("checkbox", function ($el, value) {
|
||||
$el.prop("checked", value);
|
||||
});
|
||||
|
||||
// Radio button writer, set whether or not the radio button is
|
||||
// checked. The button should only be checked if it's value
|
||||
// equals the given value.
|
||||
Backbone.Syphon.InputWriters.register("radio", function ($el, value) {
|
||||
$el.prop("checked", $el.val() === value);
|
||||
});
|
||||
|
||||
// Key Assignment Validators
|
||||
// -------------------------
|
||||
|
||||
// Key Assignment Validators are used to determine whether or not a
|
||||
// key should be assigned to a value, after the key and value have been
|
||||
// extracted from the element. This is the last opportunity to prevent
|
||||
// bad data from getting serialized to your object.
|
||||
|
||||
Backbone.Syphon.KeyAssignmentValidatorSet = Backbone.Syphon.TypeRegistry.extend();
|
||||
|
||||
// Build-in Key Assignment Validators
|
||||
Backbone.Syphon.KeyAssignmentValidators = new Backbone.Syphon.KeyAssignmentValidatorSet();
|
||||
|
||||
// Everything is valid by default
|
||||
Backbone.Syphon.KeyAssignmentValidators.registerDefault(function () {
|
||||
return true;
|
||||
});
|
||||
|
||||
// But only the "checked" radio button for a given
|
||||
// radio button group is valid
|
||||
Backbone.Syphon.KeyAssignmentValidators.register("radio", function ($el, key, value) {
|
||||
return $el.prop("checked");
|
||||
});
|
||||
|
||||
|
||||
// Backbone.Syphon.KeySplitter
|
||||
// ---------------------------
|
||||
|
||||
// This function is used to split DOM element keys in to an array
|
||||
// of parts, which are then used to create a nested result structure.
|
||||
// returning `["foo", "bar"]` results in `{foo: { bar: "value" }}`.
|
||||
//
|
||||
// Override this method to use a custom key splitter, such as:
|
||||
// `<input name="foo.bar.baz">`, `return key.split(".")`
|
||||
Backbone.Syphon.KeySplitter = function (key) {
|
||||
var matches = key.match(/[^\[\]]+/g);
|
||||
|
||||
if (key.indexOf("[]") === key.length - 2) {
|
||||
lastKey = matches.pop();
|
||||
matches.push([lastKey]);
|
||||
}
|
||||
|
||||
return matches;
|
||||
}
|
||||
|
||||
|
||||
// Backbone.Syphon.KeyJoiner
|
||||
// -------------------------
|
||||
|
||||
// Take two segments of a key and join them together, to create the
|
||||
// de-normalized key name, when deserializing a data structure back
|
||||
// in to a form.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// With this data strucutre `{foo: { bar: {baz: "value", quux: "another"} } }`,
|
||||
// the key joiner will be called with these parameters, and assuming the
|
||||
// join happens with "[ ]" square brackets, the specified output:
|
||||
//
|
||||
// `KeyJoiner("foo", "bar")` //=> "foo[bar]"
|
||||
// `KeyJoiner("foo[bar]", "baz")` //=> "foo[bar][baz]"
|
||||
// `KeyJoiner("foo[bar]", "quux")` //=> "foo[bar][quux]"
|
||||
|
||||
Backbone.Syphon.KeyJoiner = function (parentKey, childKey) {
|
||||
return parentKey + "[" + childKey + "]";
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -26,7 +26,6 @@
|
||||
</head>
|
||||
<body>
|
||||
{% include 'inc/analytics.html' %}
|
||||
{% include 'inc/facebook_init.html' %}
|
||||
{% include 'inc/ancient_browser.html' %}
|
||||
<div id="header"></div>
|
||||
<div class="container-fluid">
|
||||
@@ -71,6 +70,8 @@
|
||||
<script src="{{ STATIC_URL }}js/libs/ICanHaz.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/libs/select2.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/libs/backbone/backbone.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/libs/backbone/backbone.marionette.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/libs/backbone/backbone.syphon.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/libs/backbone/backbone-tastypie.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/libs/backbone/backbone.mine.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/libs/backbone/backbone.infiniscroll.js"></script>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
User-agent: *
|
||||
Disallow:
|
||||
Disallow: /media/
|
||||
Disallow: /ajax/
|
||||
User-agent: *
|
||||
Disallow:
|
||||
Disallow: /media/
|
||||
Disallow: /ajax/
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head prefix="og: http://ogp.me/ns#">
|
||||
<meta charset="utf-8">
|
||||
<title>Two structured audio properties</title>
|
||||
<meta property="og:title" content='Brawther "back to basics"'>
|
||||
<meta property="og:site_name" content="Deep South Sounds">
|
||||
<meta property="og:type" content="audio.song">
|
||||
<meta property="og:url" content="http://examples.opengraphprotocol.us/audio-array.html">
|
||||
<meta property="og:image"
|
||||
content="http://ext-test.deepsouthsounds.com:8000/media/mix-images/Deepsouthsounds/brawther.jpg">
|
||||
<meta property="og:image:width" content="50">
|
||||
<meta property="og:image:height" content="50">
|
||||
<meta property="og:image:type" content="image/png">
|
||||
<meta property="og:audio"
|
||||
content="http://ext-test.deepsouthsounds.com:8000/media/mixes/Deepsouthsounds/Brawther - BackToBasics Podcast 01.mp3">
|
||||
<meta property="og:audio:type" content="audio/mpeg">
|
||||
</head>
|
||||
<body>
|
||||
<p>Audio property with type declaration as structured property.</p>
|
||||
</body>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head prefix="og: http://ogp.me/ns#">
|
||||
<meta charset="utf-8">
|
||||
<title>Two structured audio properties</title>
|
||||
<meta property="og:title" content='Brawther "back to basics"'>
|
||||
<meta property="og:site_name" content="Deep South Sounds">
|
||||
<meta property="og:type" content="audio.song">
|
||||
<meta property="og:url" content="http://examples.opengraphprotocol.us/audio-array.html">
|
||||
<meta property="og:image"
|
||||
content="http://ext-test.deepsouthsounds.com:8000/media/mix-images/Deepsouthsounds/brawther.jpg">
|
||||
<meta property="og:image:width" content="50">
|
||||
<meta property="og:image:height" content="50">
|
||||
<meta property="og:image:type" content="image/png">
|
||||
<meta property="og:audio"
|
||||
content="http://ext-test.deepsouthsounds.com:8000/media/mixes/Deepsouthsounds/Brawther - BackToBasics Podcast 01.mp3">
|
||||
<meta property="og:audio:type" content="audio/mpeg">
|
||||
</head>
|
||||
<body>
|
||||
<p>Audio property with type declaration as structured property.</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,22 +1,22 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head prefix="og: http://ogp.me/ns#">
|
||||
<meta charset="utf-8">
|
||||
<title>Two structured audio properties</title>
|
||||
<meta property="og:title" content='Brawther "back to basics"'>
|
||||
<meta property="og:site_name" content="Deep South Sounds">
|
||||
<meta property="og:type" content="audio.song">
|
||||
<meta property="og:url" content="http://ext-test.deepsouthsounds.com:8000/static/html/test1.html">
|
||||
<meta property="og:image"
|
||||
content="http://ext-test.deepsouthsounds.com:8000/media/mix-images/Deepsouthsounds/brawther.jpg">
|
||||
<meta property="og:image:width" content="50">
|
||||
<meta property="og:image:height" content="50">
|
||||
<meta property="og:image:type" content="image/png">
|
||||
<meta property="og:audio"
|
||||
content="http://ext-test.deepsouthsounds.com:8000/media/mixes/Deepsouthsounds/Brawther - BackToBasics Podcast 01.mp3">
|
||||
<meta property="og:audio:type" content="audio/mpeg">
|
||||
</head>
|
||||
<body>
|
||||
<p>Audio property with type declaration as structured property.</p>
|
||||
</body>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head prefix="og: http://ogp.me/ns#">
|
||||
<meta charset="utf-8">
|
||||
<title>Two structured audio properties</title>
|
||||
<meta property="og:title" content='Brawther "back to basics"'>
|
||||
<meta property="og:site_name" content="Deep South Sounds">
|
||||
<meta property="og:type" content="audio.song">
|
||||
<meta property="og:url" content="http://ext-test.deepsouthsounds.com:8000/static/html/test1.html">
|
||||
<meta property="og:image"
|
||||
content="http://ext-test.deepsouthsounds.com:8000/media/mix-images/Deepsouthsounds/brawther.jpg">
|
||||
<meta property="og:image:width" content="50">
|
||||
<meta property="og:image:height" content="50">
|
||||
<meta property="og:image:type" content="image/png">
|
||||
<meta property="og:audio"
|
||||
content="http://ext-test.deepsouthsounds.com:8000/media/mixes/Deepsouthsounds/Brawther - BackToBasics Podcast 01.mp3">
|
||||
<meta property="og:audio:type" content="audio/mpeg">
|
||||
</head>
|
||||
<body>
|
||||
<p>Audio property with type declaration as structured property.</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,15 +1,15 @@
|
||||
<div class="activity-block">
|
||||
<a href="">
|
||||
<img class="image-avatar-small" src="<%= item.avatar_image %>" alt="">
|
||||
</a>
|
||||
|
||||
<div class="activity-details">
|
||||
<a class="activity-user" href="<%= item.user_url %>">
|
||||
<%= item.user_name %>
|
||||
</a>
|
||||
<blockquote class="pull-right">
|
||||
<p><%= item.activity %></p>
|
||||
<small><%= item.date_created %></small>
|
||||
</blockquote>
|
||||
</div>
|
||||
</div>
|
||||
<div class="activity-block">
|
||||
<a href="">
|
||||
<img class="image-avatar-small" src="<%= item.avatar_image %>" alt="">
|
||||
</a>
|
||||
|
||||
<div class="activity-details">
|
||||
<a class="activity-user" href="<%= item.user_url %>">
|
||||
<%= item.user_name %>
|
||||
</a>
|
||||
<blockquote class="pull-right">
|
||||
<p><%= item.activity %></p>
|
||||
<small><%= item.date_created %></small>
|
||||
</blockquote>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -11,6 +11,7 @@ com.podnoms.settings = {
|
||||
volume: '{{ DEFAULT_AUDIO_VOLUME }}',
|
||||
smDebugMode: '{{ SM_DEBUG_MODE }}',
|
||||
drawTimelineOnMix: false,
|
||||
currentUser: {{ CURRENT_USER_ID }},
|
||||
/** simple helper to take an api JSON object and initialise a player item */
|
||||
setupPlayer: function (data, id) {
|
||||
com.podnoms.player.setupPlayer({
|
||||
|
||||
@@ -1,33 +1,34 @@
|
||||
{% verbatim %}
|
||||
<div id="title-area">
|
||||
<p class="page-header">User details</p>
|
||||
</div>
|
||||
<div id="layout-area" class="hero-well">
|
||||
<div class="row">
|
||||
<form enctype="multipart/form-data" method="post" class="form-horizontal" id="id-new-user-form">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="profile[id]" value="{{ profile.id }}"/>
|
||||
<fieldset>
|
||||
<div class="span6">
|
||||
<div class="clearfix control-group" id="div_display_name">
|
||||
<label class="control-label" for="display_name">Display name</label>
|
||||
<div class="controls">
|
||||
<input type="text" maxlength="75" name="email" class="textinput textInput" id="display_name"
|
||||
value="<%= item.display_name %>">
|
||||
<input type="text" maxlength="75" name="profile[display_name]" class="textinput textInput"
|
||||
id="profile[display_name]"
|
||||
value="{{ profile.display_name }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix control-group" id="div_slug">
|
||||
<label class="control-label" for="slug">Profile Slug</label>
|
||||
|
||||
<div class="controls">
|
||||
<input type="text" maxlength="75" name="email" class="textinput textInput" id="slug"
|
||||
value="<%= item.slug %>">
|
||||
<input type="text" maxlength="75" name="profile[slug]" class="textinput textInput"
|
||||
id="profile[slug]"
|
||||
value="{{ profile.slug }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix control-group" id="div_email">
|
||||
<label class="control-label" for="email">E-mail address</label>
|
||||
|
||||
<div class="controls">
|
||||
<input type="text" maxlength="75" name="email" class="textinput textInput" id="email"
|
||||
value="{{ user.email }}">
|
||||
value="{{ email }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix control-group" id="div_first_name">
|
||||
@@ -35,85 +36,108 @@
|
||||
<div class="controls">
|
||||
<input type="text" maxlength="30" name="first_name" class="textinput textInput"
|
||||
id="first_name"
|
||||
value="{{ user.first_name }}">
|
||||
value="{{ first_name }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix control-group" id="div_last_name">
|
||||
<label class="control-label " for="last_name">Last name</label>
|
||||
|
||||
<div class="controls">
|
||||
<input type="text" maxlength="30" name="last_name" class="textinput textInput"
|
||||
id="last_name"
|
||||
value="{{ user.last_name }}">
|
||||
value="{{ last_name }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix control-group" id="div_avatar_image_select">
|
||||
<label class="control-label requiredField" for="avatar_image_select_0">Avatar Image<span
|
||||
class="asteriskField">*</span></label>
|
||||
|
||||
<div class="controls">
|
||||
<label class="radio">
|
||||
Use gravatar image.
|
||||
<input type="radio" value="gravatar" id="gravatar" name="avatar_type">
|
||||
</label>
|
||||
<label class="radio">
|
||||
Use Twitter/Facebook image.
|
||||
<input type="radio" value="social" id="social" name="avatar_type">
|
||||
</label>
|
||||
<label class="radio">
|
||||
Use custom image (upload below).
|
||||
<input type="radio" value="custom" id="custom" name="avatar_type">
|
||||
</label>
|
||||
<label class="radio">Use gravatar image.<input type="radio" id='avatar_gravatar' value='gravatar' name="profile[avatar_type]" /></label>
|
||||
<label class="radio">Use Twitter/Facebook image.<input type="radio" id='avatar_social' value='social' name="profile[avatar_type]" /></label>
|
||||
<label class="radio">Use custom image.<input type="radio" id='avatar_custom' value='custom' name="profile[avatar_type]" /></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix control-group" id="div_avatar_image">
|
||||
<div class="controls">
|
||||
<form action="/ajax/file-upload">
|
||||
{% csrf_token %}
|
||||
<input id="file_upload" type="file" name="file_upload"/>
|
||||
</form>
|
||||
<div class="clearfix control-group" id="div_avatar_image_upload">
|
||||
<label class="control-label requiredField" for="fileupload-new">Upload image<span
|
||||
class="asteriskField">*</span></label>
|
||||
<div class="fileupload fileupload-new pull-left" data-provides="fileupload"
|
||||
id="div_avatar_image">
|
||||
<div class="fileupload-new thumbnail" style="width: 200px; height: 150px;">
|
||||
<img src="{{ profile[avatar_image] }}"/>
|
||||
</div>
|
||||
<div class="fileupload-preview fileupload-exists thumbnail"
|
||||
style="max-width: 200px; max-height: 150px; line-height: 20px;">
|
||||
</div>
|
||||
<div>
|
||||
<span class="btn btn-file">
|
||||
<span class="fileupload-new">
|
||||
Select image
|
||||
</span>
|
||||
<span class="fileupload-exists">
|
||||
Change
|
||||
</span>
|
||||
<input id="avatar_image" type="file" size="45" name="avatar_image" class="input">
|
||||
</span>
|
||||
<a href="#" class="btn fileupload-exists" data-dismiss="fileupload">Remove</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="span6">
|
||||
<div class="row">
|
||||
<textarea style="width: 92%" id="description" rows="5">{{ user.description }}</textarea>
|
||||
<span class="help-block">Tell us a bit about yourself.</span>
|
||||
<p>
|
||||
<h5>Tell us a bit about yourself.</h5>
|
||||
</p>
|
||||
<textarea style="width: 100%" name="profile[description]" id="profile[description]" rows="5">{{profile.description}}</textarea>
|
||||
</div>
|
||||
<div class="row">
|
||||
<h5>Share this activity</h5>
|
||||
<ul class="list-horiz">
|
||||
<li>
|
||||
<h5>Likes</h5>
|
||||
<input type="checkbox" name="switch" value="" id="activity_share_likes"
|
||||
class="switch" data-coalesce="activity_sharing" data-bitflag="1">
|
||||
</li>
|
||||
<li>
|
||||
<h5>Favourites</h5>
|
||||
<input type="checkbox" name="switch" value="" id="activity_share_favourites"
|
||||
class="switch" data-coalesce="activity_sharing" data-bitflag="2">
|
||||
</li>
|
||||
<li>
|
||||
<h5>Comments</h5>
|
||||
<input type="checkbox" name="switch" value="" id="activity_share_comments"
|
||||
class="switch" data-coalesce="activity_sharing" data-bitflag="4">
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="row">
|
||||
<h5>On these networks</h5>
|
||||
<ul class="list-horiz">
|
||||
<li>
|
||||
<h5>Facebook</h5>
|
||||
<input type="checkbox" name="switch" value="" id="activity_share_networks_facebook"
|
||||
class="switch" data-coalesce="activity_sharing_networks" data-bitflag="1">
|
||||
</li>
|
||||
<li>
|
||||
<h5>Twitter</h5>
|
||||
<input type="checkbox" name="switch" value="" id="activity_share_networks_twitter"
|
||||
class="switch" data-coalesce="activity_sharing_networks" data-bitflag="2">
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
<h5>What can we share about you?</h5>
|
||||
</p>
|
||||
<div class="span5 pull-left">
|
||||
<h5>Share this activity</h5>
|
||||
<table class="table dss-option-table table-condensed table-bordered">
|
||||
<tbody>
|
||||
<tr class="info">
|
||||
<td>Likes</td>
|
||||
<td>Favourites</td>
|
||||
<td>Comments</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<input type="checkbox" name="profile[activity_sharing_likes]"
|
||||
id="activity_sharing_likes" {{ profile.activity_sharing_likes }}>
|
||||
</td>
|
||||
<td>
|
||||
<input type="checkbox" name="profile[activity_sharing_favourites]"
|
||||
id="activity_sharing_favourites" {{ profile.activity_sharing_favourites }}>
|
||||
</td>
|
||||
<td>
|
||||
<input type="checkbox" name="profile[activity_sharing_comments]"
|
||||
id="activity_sharing_comments" {{ profile.activity_sharing_comments }}>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="span5 pull-right">
|
||||
<h5>On these networks</h5>
|
||||
<table class="table dss-option-table table-condensed table-bordered">
|
||||
<tbody>
|
||||
<tr class="info">
|
||||
<td>Facebook</td>
|
||||
<td>Twitter</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center; vertical-align: middle">
|
||||
<input type="checkbox" name="profile[activity_sharing_networks_facebook]" {{ profile.activity_sharing_networks_facebook }}>
|
||||
</td>
|
||||
<td>
|
||||
<input type="checkbox" name="profile[activity_sharing_networks_twitter]" {{ profile.activity_sharing_networks_twitter }}>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
@@ -124,4 +148,5 @@
|
||||
<button id="save-changes" class="btn">Save changes</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endverbatim %}
|
||||
|
||||
Reference in New Issue
Block a user