Merge branch 'master' of https://github.com/pyohio/symposion into pyohio-master

Conflicts:
	README.md
	symposion/boxes/urls.py
	symposion/cms/urls.py
	symposion/proposals/actions.py
	symposion/proposals/urls.py
	symposion/proposals/views.py
	symposion/reviews/tests.py
	symposion/reviews/urls.py
	symposion/reviews/views.py
	symposion/schedule/forms.py
	symposion/schedule/models.py
	symposion/schedule/views.py
	symposion/speakers/fixture_gen.py
	symposion/sponsorship/urls.py
	symposion/templates/cms/file_create.html
	symposion/templates/cms/file_index.html
	symposion/templates/conference/user_list.html
	symposion/templates/dashboard.html
	symposion/templates/emails/proposal_new_message/message.html
	symposion/templates/emails/proposal_updated/message.html
	symposion/templates/emails/speaker_addition/message.html
	symposion/templates/emails/speaker_invite/message.html
	symposion/templates/proposals/_pending_proposal_row.html
	symposion/templates/proposals/_proposal_fields.html
	symposion/templates/proposals/_proposal_row.html
	symposion/templates/proposals/proposal_cancel.html
	symposion/templates/proposals/proposal_detail.html
	symposion/templates/proposals/proposal_edit.html
	symposion/templates/proposals/proposal_speaker_manage.html
	symposion/templates/proposals/proposal_submit.html
	symposion/templates/reviews/_review_table.html
	symposion/templates/reviews/base.html
	symposion/templates/reviews/result_notification.html
	symposion/templates/reviews/result_notification_prepare.html
	symposion/templates/reviews/review_admin.html
	symposion/templates/reviews/review_assignment.html
	symposion/templates/reviews/review_detail.html
	symposion/templates/reviews/review_review.html
	symposion/templates/reviews/review_stats.html
	symposion/templates/schedule/_edit_grid.html
	symposion/templates/schedule/_grid.html
	symposion/templates/schedule/_slot_edit.html
	symposion/templates/schedule/presentation_detail.html
	symposion/templates/schedule/schedule_list.html
	symposion/templates/speakers/speaker_create.html
	symposion/templates/speakers/speaker_edit.html
	symposion/templates/speakers/speaker_profile.html
	symposion/templates/sponsorship/add.html
	symposion/templates/sponsorship/apply.html
	symposion/templates/sponsorship/detail.html
	symposion/templates/sponsorship/list.html
	symposion/templates/teams/team_detail.html
This commit is contained in:
Patrick Altman 2014-12-15 16:07:37 -06:00
commit f3614fcf52
39 changed files with 1533 additions and 248 deletions

View file

@ -27,7 +27,12 @@ See http://eldarion.com/symposion/ for commercial support, customization and hos
Quickstart Quickstart
========== ==========
If you're interested in running symposion locally, we have built a [basic To install Symposion, run:
pip install symposion
Symposion is a Django app. You will need to create a Django project to
customize and manage your Symposion installation. We have built a [basic
Django startproject template that includes Symposion][1]. Django startproject template that includes Symposion][1].
[1]: https://github.com/pinax/pinax-project-symposion [1]: https://github.com/pinax/pinax-project-symposion

13
requirements/base.txt Normal file
View file

@ -0,0 +1,13 @@
Django>=1.5,<=1.6
django-appconf==0.5
django-forms-bootstrap>=2.0.3.post2
django-markitup==2.1
django-model-utils==2.0.2
django-reversion==1.8
django-sitetree==1.0.0
django-taggit==0.11.2
django-timezones==0.2
django-user-accounts==1.0b13
easy-thumbnails==1.4
html5lib==0.95
markdown==2.3.1

View file

@ -1,10 +1,20 @@
#!/usr/bin/env python #!/usr/bin/env python
import os
from setuptools import setup, find_packages from setuptools import setup, find_packages
import symposion import symposion
def read_file(filename):
"""Read a file into a string."""
path = os.path.abspath(os.path.dirname(__file__))
filepath = os.path.join(path, filename)
try:
return open(filepath).read()
except IOError:
return ''
setup( setup(
name="symposion", name="symposion",
author="James Tauber", author="James Tauber",
@ -12,7 +22,7 @@ setup(
version=symposion.__version__, version=symposion.__version__,
description="A collection of Django apps for conference websites.", description="A collection of Django apps for conference websites.",
url="http://eldarion.com/symposion/", url="http://eldarion.com/symposion/",
packages=find_packages(exclude=["symposion_project"]), packages=find_packages(),
include_package_data=True, include_package_data=True,
classifiers=( classifiers=(
"Development Status :: 4 - Beta", "Development Status :: 4 - Beta",
@ -22,4 +32,5 @@ setup(
"Natural Language :: English", "Natural Language :: English",
"License :: OSI Approved :: MIT License", "License :: OSI Approved :: MIT License",
), ),
install_requires=read_file("requirements/base.txt").splitlines(),
) )

View file

@ -0,0 +1,76 @@
# -*- 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 model 'Box'
db.create_table('boxes_box', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('label', self.gf('django.db.models.fields.CharField')(max_length=100, db_index=True)),
('content', self.gf('markitup.fields.MarkupField')(no_rendered_field=True, blank=True)),
('created_by', self.gf('django.db.models.fields.related.ForeignKey')(related_name='boxes', to=orm['auth.User'])),
('last_updated_by', self.gf('django.db.models.fields.related.ForeignKey')(related_name='updated_boxes', to=orm['auth.User'])),
('_content_rendered', self.gf('django.db.models.fields.TextField')(blank=True)),
))
db.send_create_signal('boxes', ['Box'])
def backwards(self, orm):
# Deleting model 'Box'
db.delete_table('boxes_box')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'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': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'boxes.box': {
'Meta': {'object_name': 'Box'},
'_content_rendered': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'content': ('markitup.fields.MarkupField', [], {'no_rendered_field': 'True', 'blank': 'True'}),
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'boxes'", 'to': "orm['auth.User']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'label': ('django.db.models.fields.CharField', [], {'max_length': '100', 'db_index': 'True'}),
'last_updated_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'updated_boxes'", 'to': "orm['auth.User']"})
},
'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'}),
'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'})
}
}
complete_apps = ['boxes']

View file

View file

@ -1,5 +1,4 @@
from django.db import models from django.db import models
from django.contrib.auth.models import User from django.contrib.auth.models import User
import reversion import reversion

View file

@ -1,4 +1,4 @@
from django.conf.urls import url, patterns from django.conf.urls import patterns, url
urlpatterns = patterns( urlpatterns = patterns(

View file

@ -0,0 +1,83 @@
# -*- 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 model 'Page'
db.create_table('cms_page', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('title', self.gf('django.db.models.fields.CharField')(max_length=100)),
('path', self.gf('django.db.models.fields.CharField')(unique=True, max_length=100)),
('body', self.gf('markitup.fields.MarkupField')(no_rendered_field=True)),
('status', self.gf('django.db.models.fields.IntegerField')(default=2)),
('publish_date', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
('created', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
('updated', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
('_body_rendered', self.gf('django.db.models.fields.TextField')(blank=True)),
))
db.send_create_signal('cms', ['Page'])
# Adding model 'File'
db.create_table('cms_file', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('file', self.gf('django.db.models.fields.files.FileField')(max_length=100)),
('created', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
))
db.send_create_signal('cms', ['File'])
def backwards(self, orm):
# Deleting model 'Page'
db.delete_table('cms_page')
# Deleting model 'File'
db.delete_table('cms_file')
models = {
'cms.file': {
'Meta': {'object_name': 'File'},
'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
},
'cms.page': {
'Meta': {'object_name': 'Page'},
'_body_rendered': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'body': ('markitup.fields.MarkupField', [], {'no_rendered_field': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'path': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}),
'publish_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'status': ('django.db.models.fields.IntegerField', [], {'default': '2'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'updated': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'})
},
'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'}),
'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'})
},
'taggit.tag': {
'Meta': {'object_name': 'Tag'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'})
},
'taggit.taggeditem': {
'Meta': {'object_name': 'TaggedItem'},
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'taggit_taggeditem_tagged_items'", 'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'object_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'taggit_taggeditem_items'", 'to': "orm['taggit.Tag']"})
}
}
complete_apps = ['cms']

View file

View file

@ -0,0 +1,61 @@
# -*- 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 model 'Conference'
db.create_table('conference_conference', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('title', self.gf('django.db.models.fields.CharField')(max_length=100)),
('start_date', self.gf('django.db.models.fields.DateField')(null=True, blank=True)),
('end_date', self.gf('django.db.models.fields.DateField')(null=True, blank=True)),
('timezone', self.gf('timezones.fields.TimeZoneField')(default='US/Eastern', max_length=100, blank=True)),
))
db.send_create_signal('conference', ['Conference'])
# Adding model 'Section'
db.create_table('conference_section', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('conference', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['conference.Conference'])),
('name', self.gf('django.db.models.fields.CharField')(max_length=100)),
('slug', self.gf('django.db.models.fields.SlugField')(max_length=50)),
('start_date', self.gf('django.db.models.fields.DateField')(null=True, blank=True)),
('end_date', self.gf('django.db.models.fields.DateField')(null=True, blank=True)),
))
db.send_create_signal('conference', ['Section'])
def backwards(self, orm):
# Deleting model 'Conference'
db.delete_table('conference_conference')
# Deleting model 'Section'
db.delete_table('conference_section')
models = {
'conference.conference': {
'Meta': {'object_name': 'Conference'},
'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'timezone': ('timezones.fields.TimeZoneField', [], {'default': "'US/Eastern'", 'max_length': '100', 'blank': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'conference.section': {
'Meta': {'ordering': "['start_date']", 'object_name': 'Section'},
'conference': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['conference.Conference']"}),
'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'})
}
}
complete_apps = ['conference']

View file

@ -3,6 +3,9 @@ from django.utils.translation import ugettext_lazy as _
from timezones.fields import TimeZoneField from timezones.fields import TimeZoneField
from south.modelsinspector import add_introspection_rules
add_introspection_rules([], [r"^timezones\.fields\.TimeZoneField"])
CONFERENCE_CACHE = {} CONFERENCE_CACHE = {}

View file

@ -22,9 +22,8 @@ def export_as_csv_action(description="Export selected objects as CSV file",
elif exclude: elif exclude:
excludeset = set(exclude) excludeset = set(exclude)
field_names = field_names - excludeset field_names = field_names - excludeset
response = HttpResponse(mimetype="text/csv") response = HttpResponse(content_type="text/csv")
response["Content-Disposition"] = \ response["Content-Disposition"] = "attachment; filename=%s.csv" % unicode(opts).replace(".", "_")
"attachment; filename=%s.csv" % unicode(opts).replace(".", "_")
writer = csv.writer(response) writer = csv.writer(response)
if header: if header:
writer.writerow(list(field_names)) writer.writerow(list(field_names))

View file

@ -0,0 +1,210 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
depends_on = (
("speakers", "0001_initial"),
)
def forwards(self, orm):
# Adding model 'ProposalSection'
db.create_table('proposals_proposalsection', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('section', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['conference.Section'], unique=True)),
('start', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)),
('end', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)),
('closed', self.gf('django.db.models.fields.NullBooleanField')(null=True, blank=True)),
('published', self.gf('django.db.models.fields.NullBooleanField')(null=True, blank=True)),
))
db.send_create_signal('proposals', ['ProposalSection'])
# Adding model 'ProposalKind'
db.create_table('proposals_proposalkind', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('section', self.gf('django.db.models.fields.related.ForeignKey')(related_name='proposal_kinds', to=orm['conference.Section'])),
('name', self.gf('django.db.models.fields.CharField')(max_length=100)),
('slug', self.gf('django.db.models.fields.SlugField')(max_length=50)),
))
db.send_create_signal('proposals', ['ProposalKind'])
# Adding model 'ProposalBase'
db.create_table('proposals_proposalbase', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('kind', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['proposals.ProposalKind'])),
('title', self.gf('django.db.models.fields.CharField')(max_length=100)),
('description', self.gf('django.db.models.fields.TextField')(max_length=400)),
('abstract', self.gf('markitup.fields.MarkupField')(no_rendered_field=True)),
('additional_notes', self.gf('markitup.fields.MarkupField')(no_rendered_field=True, blank=True)),
('submitted', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
('speaker', self.gf('django.db.models.fields.related.ForeignKey')(related_name='proposals', to=orm['speakers.Speaker'])),
('cancelled', self.gf('django.db.models.fields.BooleanField')(default=False)),
('_abstract_rendered', self.gf('django.db.models.fields.TextField')(blank=True)),
('_additional_notes_rendered', self.gf('django.db.models.fields.TextField')(blank=True)),
))
db.send_create_signal('proposals', ['ProposalBase'])
# Adding model 'AdditionalSpeaker'
db.create_table('proposals_proposalbase_additional_speakers', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('speaker', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['speakers.Speaker'])),
('proposalbase', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['proposals.ProposalBase'])),
('status', self.gf('django.db.models.fields.IntegerField')(default=1)),
))
db.send_create_signal('proposals', ['AdditionalSpeaker'])
# Adding unique constraint on 'AdditionalSpeaker', fields ['speaker', 'proposalbase']
db.create_unique('proposals_proposalbase_additional_speakers', ['speaker_id', 'proposalbase_id'])
# Adding model 'SupportingDocument'
db.create_table('proposals_supportingdocument', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('proposal', self.gf('django.db.models.fields.related.ForeignKey')(related_name='supporting_documents', to=orm['proposals.ProposalBase'])),
('uploaded_by', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
('created_at', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
('file', self.gf('django.db.models.fields.files.FileField')(max_length=100)),
('description', self.gf('django.db.models.fields.CharField')(max_length=140)),
))
db.send_create_signal('proposals', ['SupportingDocument'])
def backwards(self, orm):
# Removing unique constraint on 'AdditionalSpeaker', fields ['speaker', 'proposalbase']
db.delete_unique('proposals_proposalbase_additional_speakers', ['speaker_id', 'proposalbase_id'])
# Deleting model 'ProposalSection'
db.delete_table('proposals_proposalsection')
# Deleting model 'ProposalKind'
db.delete_table('proposals_proposalkind')
# Deleting model 'ProposalBase'
db.delete_table('proposals_proposalbase')
# Deleting model 'AdditionalSpeaker'
db.delete_table('proposals_proposalbase_additional_speakers')
# Deleting model 'SupportingDocument'
db.delete_table('proposals_supportingdocument')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'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': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'conference.conference': {
'Meta': {'object_name': 'Conference'},
'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'timezone': ('timezones.fields.TimeZoneField', [], {'default': "'US/Eastern'", 'max_length': '100', 'blank': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'conference.section': {
'Meta': {'ordering': "['start_date']", 'object_name': 'Section'},
'conference': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['conference.Conference']"}),
'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'})
},
'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'}),
'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'})
},
'proposals.additionalspeaker': {
'Meta': {'unique_together': "(('speaker', 'proposalbase'),)", 'object_name': 'AdditionalSpeaker', 'db_table': "'proposals_proposalbase_additional_speakers'"},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'proposalbase': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['proposals.ProposalBase']"}),
'speaker': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['speakers.Speaker']"}),
'status': ('django.db.models.fields.IntegerField', [], {'default': '1'})
},
'proposals.proposalbase': {
'Meta': {'object_name': 'ProposalBase'},
'_abstract_rendered': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'_additional_notes_rendered': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'abstract': ('markitup.fields.MarkupField', [], {'no_rendered_field': 'True'}),
'additional_notes': ('markitup.fields.MarkupField', [], {'no_rendered_field': 'True', 'blank': 'True'}),
'additional_speakers': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['speakers.Speaker']", 'symmetrical': 'False', 'through': "orm['proposals.AdditionalSpeaker']", 'blank': 'True'}),
'cancelled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'description': ('django.db.models.fields.TextField', [], {'max_length': '400'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'kind': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['proposals.ProposalKind']"}),
'speaker': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'proposals'", 'to': "orm['speakers.Speaker']"}),
'submitted': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'proposals.proposalkind': {
'Meta': {'object_name': 'ProposalKind'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'section': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'proposal_kinds'", 'to': "orm['conference.Section']"}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
},
'proposals.proposalsection': {
'Meta': {'object_name': 'ProposalSection'},
'closed': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
'end': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'published': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
'section': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['conference.Section']", 'unique': 'True'}),
'start': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
},
'proposals.supportingdocument': {
'Meta': {'object_name': 'SupportingDocument'},
'created_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'description': ('django.db.models.fields.CharField', [], {'max_length': '140'}),
'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'proposal': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'supporting_documents'", 'to': "orm['proposals.ProposalBase']"}),
'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
},
'speakers.speaker': {
'Meta': {'ordering': "['name']", 'object_name': 'Speaker'},
'_biography_rendered': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'annotation': ('django.db.models.fields.TextField', [], {}),
'biography': ('markitup.fields.MarkupField', [], {'no_rendered_field': 'True', 'blank': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'invite_email': ('django.db.models.fields.CharField', [], {'max_length': '200', 'unique': 'True', 'null': 'True', 'db_index': 'True'}),
'invite_token': ('django.db.models.fields.CharField', [], {'max_length': '40', 'db_index': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'photo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'speaker_profile'", 'unique': 'True', 'null': 'True', 'to': "orm['auth.User']"})
}
}
complete_apps = ['proposals']

View file

@ -12,15 +12,10 @@ urlpatterns = patterns(
name="proposal_speaker_manage"), name="proposal_speaker_manage"),
url(r"^(\d+)/cancel/$", "proposal_cancel", name="proposal_cancel"), url(r"^(\d+)/cancel/$", "proposal_cancel", name="proposal_cancel"),
url(r"^(\d+)/leave/$", "proposal_leave", name="proposal_leave"), url(r"^(\d+)/leave/$", "proposal_leave", name="proposal_leave"),
url(r"^(\d+)/join/$", "proposal_pending_join", url(r"^(\d+)/join/$", "proposal_pending_join", name="proposal_pending_join"),
name="proposal_pending_join"), url(r"^(\d+)/decline/$", "proposal_pending_decline", name="proposal_pending_decline"),
url(r"^(\d+)/decline/$", "proposal_pending_decline",
name="proposal_pending_decline"),
url(r"^(\d+)/document/create/$", "document_create", url(r"^(\d+)/document/create/$", "document_create", name="proposal_document_create"),
name="proposal_document_create"), url(r"^document/(\d+)/delete/$", "document_delete", name="proposal_document_delete"),
url(r"^document/(\d+)/delete/$", "document_delete", url(r"^document/(\d+)/([^/]+)$", "document_download", name="proposal_document_download"),
name="proposal_document_delete"),
url(r"^document/(\d+)/([^/]+)$", "document_download",
name="proposal_document_download"),
) )

View file

@ -1,3 +1,4 @@
import hashlib
import random import random
import sys import sys
@ -9,8 +10,6 @@ from django.http import Http404, HttpResponse, HttpResponseForbidden
from django.shortcuts import render, redirect, get_object_or_404 from django.shortcuts import render, redirect, get_object_or_404
from django.views import static from django.views import static
from hashlib import sha1
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
@ -123,8 +122,8 @@ def proposal_speaker_manage(request, pk):
Q(user=None, invite_email=email_address) Q(user=None, invite_email=email_address)
) )
except Speaker.DoesNotExist: except Speaker.DoesNotExist:
salt = sha1(str(random.random())).hexdigest()[:5] salt = hashlib.sha1(str(random.random())).hexdigest()[:5]
token = sha1(salt + email_address).hexdigest() token = hashlib.sha1(salt + email_address).hexdigest()
pending = Speaker.objects.create( pending = Speaker.objects.create(
invite_email=email_address, invite_email=email_address,
invite_token=token, invite_token=token,

View file

@ -1,9 +0,0 @@
from django.contrib.auth.models import Group
from fixture_generator import fixture_generator
@fixture_generator(Group)
def initial_data():
Group.objects.create(name="reviewers")
Group.objects.create(name="reviewers-admins")

View file

@ -0,0 +1,316 @@
# -*- 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 model 'ReviewAssignment'
db.create_table('reviews_reviewassignment', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('proposal', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['proposals.ProposalBase'])),
('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
('origin', self.gf('django.db.models.fields.IntegerField')()),
('assigned_at', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
('opted_out', self.gf('django.db.models.fields.BooleanField')(default=False)),
))
db.send_create_signal('reviews', ['ReviewAssignment'])
# Adding model 'ProposalMessage'
db.create_table('reviews_proposalmessage', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('proposal', self.gf('django.db.models.fields.related.ForeignKey')(related_name='messages', to=orm['proposals.ProposalBase'])),
('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
('message', self.gf('markitup.fields.MarkupField')(no_rendered_field=True)),
('submitted_at', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
('_message_rendered', self.gf('django.db.models.fields.TextField')(blank=True)),
))
db.send_create_signal('reviews', ['ProposalMessage'])
# Adding model 'Review'
db.create_table('reviews_review', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('proposal', self.gf('django.db.models.fields.related.ForeignKey')(related_name='reviews', to=orm['proposals.ProposalBase'])),
('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
('vote', self.gf('django.db.models.fields.CharField')(max_length=2, blank=True)),
('comment', self.gf('markitup.fields.MarkupField')(no_rendered_field=True)),
('submitted_at', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
('_comment_rendered', self.gf('django.db.models.fields.TextField')(blank=True)),
))
db.send_create_signal('reviews', ['Review'])
# Adding model 'LatestVote'
db.create_table('reviews_latestvote', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('proposal', self.gf('django.db.models.fields.related.ForeignKey')(related_name='votes', to=orm['proposals.ProposalBase'])),
('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
('vote', self.gf('django.db.models.fields.CharField')(max_length=2)),
('submitted_at', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
))
db.send_create_signal('reviews', ['LatestVote'])
# Adding unique constraint on 'LatestVote', fields ['proposal', 'user']
db.create_unique('reviews_latestvote', ['proposal_id', 'user_id'])
# Adding model 'ProposalResult'
db.create_table('reviews_proposalresult', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('proposal', self.gf('django.db.models.fields.related.OneToOneField')(related_name='result', unique=True, to=orm['proposals.ProposalBase'])),
('score', self.gf('django.db.models.fields.DecimalField')(default='0.00', max_digits=5, decimal_places=2)),
('comment_count', self.gf('django.db.models.fields.PositiveIntegerField')(default=0)),
('vote_count', self.gf('django.db.models.fields.PositiveIntegerField')(default=0)),
('plus_one', self.gf('django.db.models.fields.PositiveIntegerField')(default=0)),
('plus_zero', self.gf('django.db.models.fields.PositiveIntegerField')(default=0)),
('minus_zero', self.gf('django.db.models.fields.PositiveIntegerField')(default=0)),
('minus_one', self.gf('django.db.models.fields.PositiveIntegerField')(default=0)),
('accepted', self.gf('django.db.models.fields.NullBooleanField')(default=None, null=True, blank=True)),
('status', self.gf('django.db.models.fields.CharField')(default='undecided', max_length=20)),
))
db.send_create_signal('reviews', ['ProposalResult'])
# Adding model 'Comment'
db.create_table('reviews_comment', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('proposal', self.gf('django.db.models.fields.related.ForeignKey')(related_name='comments', to=orm['proposals.ProposalBase'])),
('commenter', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
('text', self.gf('markitup.fields.MarkupField')(no_rendered_field=True)),
('public', self.gf('django.db.models.fields.BooleanField')(default=False)),
('commented_at', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
('_text_rendered', self.gf('django.db.models.fields.TextField')(blank=True)),
))
db.send_create_signal('reviews', ['Comment'])
# Adding model 'NotificationTemplate'
db.create_table('reviews_notificationtemplate', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('label', self.gf('django.db.models.fields.CharField')(max_length=100)),
('from_address', self.gf('django.db.models.fields.EmailField')(max_length=75)),
('subject', self.gf('django.db.models.fields.CharField')(max_length=100)),
('body', self.gf('django.db.models.fields.TextField')()),
))
db.send_create_signal('reviews', ['NotificationTemplate'])
# Adding model 'ResultNotification'
db.create_table('reviews_resultnotification', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('proposal', self.gf('django.db.models.fields.related.ForeignKey')(related_name='notifications', to=orm['proposals.ProposalBase'])),
('template', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['reviews.NotificationTemplate'], null=True, on_delete=models.SET_NULL, blank=True)),
('timestamp', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
('to_address', self.gf('django.db.models.fields.EmailField')(max_length=75)),
('from_address', self.gf('django.db.models.fields.EmailField')(max_length=75)),
('subject', self.gf('django.db.models.fields.CharField')(max_length=100)),
('body', self.gf('django.db.models.fields.TextField')()),
))
db.send_create_signal('reviews', ['ResultNotification'])
def backwards(self, orm):
# Removing unique constraint on 'LatestVote', fields ['proposal', 'user']
db.delete_unique('reviews_latestvote', ['proposal_id', 'user_id'])
# Deleting model 'ReviewAssignment'
db.delete_table('reviews_reviewassignment')
# Deleting model 'ProposalMessage'
db.delete_table('reviews_proposalmessage')
# Deleting model 'Review'
db.delete_table('reviews_review')
# Deleting model 'LatestVote'
db.delete_table('reviews_latestvote')
# Deleting model 'ProposalResult'
db.delete_table('reviews_proposalresult')
# Deleting model 'Comment'
db.delete_table('reviews_comment')
# Deleting model 'NotificationTemplate'
db.delete_table('reviews_notificationtemplate')
# Deleting model 'ResultNotification'
db.delete_table('reviews_resultnotification')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'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': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'conference.conference': {
'Meta': {'object_name': 'Conference'},
'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'timezone': ('timezones.fields.TimeZoneField', [], {'default': "'US/Eastern'", 'max_length': '100', 'blank': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'conference.section': {
'Meta': {'ordering': "['start_date']", 'object_name': 'Section'},
'conference': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['conference.Conference']"}),
'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'})
},
'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'}),
'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'})
},
'proposals.additionalspeaker': {
'Meta': {'unique_together': "(('speaker', 'proposalbase'),)", 'object_name': 'AdditionalSpeaker', 'db_table': "'proposals_proposalbase_additional_speakers'"},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'proposalbase': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['proposals.ProposalBase']"}),
'speaker': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['speakers.Speaker']"}),
'status': ('django.db.models.fields.IntegerField', [], {'default': '1'})
},
'proposals.proposalbase': {
'Meta': {'object_name': 'ProposalBase'},
'_abstract_rendered': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'_additional_notes_rendered': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'abstract': ('markitup.fields.MarkupField', [], {'no_rendered_field': 'True'}),
'additional_notes': ('markitup.fields.MarkupField', [], {'no_rendered_field': 'True', 'blank': 'True'}),
'additional_speakers': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['speakers.Speaker']", 'symmetrical': 'False', 'through': "orm['proposals.AdditionalSpeaker']", 'blank': 'True'}),
'cancelled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'description': ('django.db.models.fields.TextField', [], {'max_length': '400'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'kind': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['proposals.ProposalKind']"}),
'speaker': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'proposals'", 'to': "orm['speakers.Speaker']"}),
'submitted': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'proposals.proposalkind': {
'Meta': {'object_name': 'ProposalKind'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'section': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'proposal_kinds'", 'to': "orm['conference.Section']"}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
},
'reviews.comment': {
'Meta': {'object_name': 'Comment'},
'_text_rendered': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'commented_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'commenter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'proposal': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'comments'", 'to': "orm['proposals.ProposalBase']"}),
'public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'text': ('markitup.fields.MarkupField', [], {'no_rendered_field': 'True'})
},
'reviews.latestvote': {
'Meta': {'unique_together': "[('proposal', 'user')]", 'object_name': 'LatestVote'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'proposal': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'votes'", 'to': "orm['proposals.ProposalBase']"}),
'submitted_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
'vote': ('django.db.models.fields.CharField', [], {'max_length': '2'})
},
'reviews.notificationtemplate': {
'Meta': {'object_name': 'NotificationTemplate'},
'body': ('django.db.models.fields.TextField', [], {}),
'from_address': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'subject': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'reviews.proposalmessage': {
'Meta': {'ordering': "['submitted_at']", 'object_name': 'ProposalMessage'},
'_message_rendered': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'message': ('markitup.fields.MarkupField', [], {'no_rendered_field': 'True'}),
'proposal': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'messages'", 'to': "orm['proposals.ProposalBase']"}),
'submitted_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
},
'reviews.proposalresult': {
'Meta': {'object_name': 'ProposalResult'},
'accepted': ('django.db.models.fields.NullBooleanField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
'comment_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'minus_one': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
'minus_zero': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
'plus_one': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
'plus_zero': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
'proposal': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'result'", 'unique': 'True', 'to': "orm['proposals.ProposalBase']"}),
'score': ('django.db.models.fields.DecimalField', [], {'default': "'0.00'", 'max_digits': '5', 'decimal_places': '2'}),
'status': ('django.db.models.fields.CharField', [], {'default': "'undecided'", 'max_length': '20'}),
'vote_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'})
},
'reviews.resultnotification': {
'Meta': {'object_name': 'ResultNotification'},
'body': ('django.db.models.fields.TextField', [], {}),
'from_address': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'proposal': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'notifications'", 'to': "orm['proposals.ProposalBase']"}),
'subject': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'template': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['reviews.NotificationTemplate']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
'timestamp': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'to_address': ('django.db.models.fields.EmailField', [], {'max_length': '75'})
},
'reviews.review': {
'Meta': {'object_name': 'Review'},
'_comment_rendered': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'comment': ('markitup.fields.MarkupField', [], {'no_rendered_field': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'proposal': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'reviews'", 'to': "orm['proposals.ProposalBase']"}),
'submitted_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
'vote': ('django.db.models.fields.CharField', [], {'max_length': '2', 'blank': 'True'})
},
'reviews.reviewassignment': {
'Meta': {'object_name': 'ReviewAssignment'},
'assigned_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'opted_out': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'origin': ('django.db.models.fields.IntegerField', [], {}),
'proposal': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['proposals.ProposalBase']"}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
},
'speakers.speaker': {
'Meta': {'ordering': "['name']", 'object_name': 'Speaker'},
'_biography_rendered': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'annotation': ('django.db.models.fields.TextField', [], {}),
'biography': ('markitup.fields.MarkupField', [], {'no_rendered_field': 'True', 'blank': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'invite_email': ('django.db.models.fields.CharField', [], {'max_length': '200', 'unique': 'True', 'null': 'True', 'db_index': 'True'}),
'invite_token': ('django.db.models.fields.CharField', [], {'max_length': '40', 'db_index': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'photo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'speaker_profile'", 'unique': 'True', 'null': 'True', 'to': "orm['auth.User']"})
}
}
complete_apps = ['reviews']

View file

View file

@ -1,143 +0,0 @@
from django.core.urlresolvers import reverse
from django.test import TestCase
from django.contrib.auth.models import User, Group
from symposion.proposals.models import Proposal
from symposion.reviews.models import Review, ReviewAssignment
class login(object):
def __init__(self, testcase, user, password):
self.testcase = testcase
success = testcase.client.login(username=user, password=password)
self.testcase.assertTrue(
success,
"login with username=%r, password=%r failed" % (user, password)
)
def __enter__(self):
pass
def __exit__(self, *args):
self.testcase.client.logout()
class ReviewTests(TestCase):
fixtures = ["proposals"]
def get(self, url_name, *args, **kwargs):
return self.client.get(reverse(url_name, args=args, kwargs=kwargs))
def post(self, url_name, *args, **kwargs):
data = kwargs.pop("data")
return self.client.post(reverse(url_name, args=args, kwargs=kwargs), data)
def login(self, user, password):
return login(self, user, password)
def test_detail_perms(self):
guidos_proposal = Proposal.objects.all()[0]
response = self.get("review_detail", pk=guidos_proposal.pk)
# Not logged in
self.assertEqual(response.status_code, 302)
with self.login("guido", "pythonisawesome"):
response = self.get("review_detail", pk=guidos_proposal.pk)
# Guido can see his own proposal.
self.assertEqual(response.status_code, 200)
with self.login("matz", "pythonsucks"):
response = self.get("review_detail", pk=guidos_proposal.pk)
# Matz can't see guido's proposal
self.assertEqual(response.status_code, 302)
larry = User.objects.get(username="larryw")
# Larry is a trustworthy guy, he's a reviewer.
larry.groups.add(Group.objects.get(name="reviewers"))
with self.login("larryw", "linenoisehere"):
response = self.get("review_detail", pk=guidos_proposal.pk)
# Reviewers can see a review detail page.
self.assertEqual(response.status_code, 200)
def test_reviewing(self):
guidos_proposal = Proposal.objects.all()[0]
with self.login("guido", "pythonisawesome"):
response = self.post("review_review", pk=guidos_proposal.pk, data={
"vote": "+1",
})
# It redirects, but...
self.assertEqual(response.status_code, 302)
# ... no vote recorded
self.assertEqual(guidos_proposal.reviews.count(), 0)
larry = User.objects.get(username="larryw")
# Larry is a trustworthy guy, he's a reviewer.
larry.groups.add(Group.objects.get(name="reviewers"))
with self.login("larryw", "linenoisehere"):
response = self.post("review_review", pk=guidos_proposal.pk, data={
"vote": "+0",
"text": "Looks like a decent proposal, and Guido is a smart guy",
})
self.assertEqual(response.status_code, 302)
self.assertEqual(guidos_proposal.reviews.count(), 1)
self.assertEqual(ReviewAssignment.objects.count(), 1)
assignment = ReviewAssignment.objects.get()
self.assertEqual(assignment.proposal, guidos_proposal)
self.assertEqual(assignment.origin, ReviewAssignment.OPT_IN)
self.assertEqual(guidos_proposal.comments.count(), 1)
comment = guidos_proposal.comments.get()
self.assertFalse(comment.public)
response = self.post("review_review", pk=guidos_proposal.pk, data={
"vote": "+1",
"text": "Actually Perl is dead, we really need a talk on the future",
})
self.assertEqual(guidos_proposal.reviews.count(), 2)
self.assertEqual(ReviewAssignment.objects.count(), 1)
assignment = ReviewAssignment.objects.get()
self.assertEqual(assignment.review, Review.objects.order_by("-id")[0])
self.assertEqual(guidos_proposal.comments.count(), 2)
# Larry's a big fan...
response = self.post("review_review", pk=guidos_proposal.pk, data={
"vote": "+20",
})
self.assertEqual(guidos_proposal.reviews.count(), 2)
def test_speaker_commenting(self):
guidos_proposal = Proposal.objects.all()[0]
with self.login("guido", "pythonisawesome"):
response = self.get("review_comment", pk=guidos_proposal.pk)
# Guido can comment on his proposal.
self.assertEqual(response.status_code, 200)
response = self.post("review_comment", pk=guidos_proposal.pk, data={
"text": "FYI I can do this as a 30-minute or 45-minute talk.",
})
self.assertEqual(response.status_code, 302)
self.assertEqual(guidos_proposal.comments.count(), 1)
comment = guidos_proposal.comments.get()
self.assertTrue(comment.public)
larry = User.objects.get(username="larryw")
# Larry is a trustworthy guy, he's a reviewer.
larry.groups.add(Group.objects.get(name="reviewers"))
with self.login("larryw", "linenoisehere"):
response = self.get("review_comment", pk=guidos_proposal.pk)
# Larry can comment, since he's a reviewer
self.assertEqual(response.status_code, 200)
response = self.post("review_comment", pk=guidos_proposal.pk, data={
"text": "Thanks for the heads-up Guido."
})
self.assertEqual(response.status_code, 302)
self.assertEqual(guidos_proposal.comments.count(), 2)
with self.login("matz", "pythonsucks"):
response = self.get("review_comment", pk=guidos_proposal.pk)
# Matz can't comment.
self.assertEqual(response.status_code, 302)

View file

@ -3,30 +3,18 @@ from django.conf.urls import patterns, url
urlpatterns = patterns( urlpatterns = patterns(
"symposion.reviews.views", "symposion.reviews.views",
url(r"^section/(?P<section_slug>[\w\-]+)/all/$", "review_section", url(r"^section/(?P<section_slug>[\w\-]+)/all/$", "review_section", {"reviewed": "all"}, name="review_section"),
{"reviewed": "all"}, name="review_section"), url(r"^section/(?P<section_slug>[\w\-]+)/reviewed/$", "review_section", {"reviewed": "reviewed"}, name="user_reviewed"),
url(r"^section/(?P<section_slug>[\w\-]+)/reviewed/$", "review_section", url(r"^section/(?P<section_slug>[\w\-]+)/not_reviewed/$", "review_section", {"reviewed": "not_reviewed"}, name="user_not_reviewed"),
{"reviewed": "reviewed"}, name="user_reviewed"), url(r"^section/(?P<section_slug>[\w\-]+)/assignments/$", "review_section", {"assigned": True}, name="review_section_assignments"),
url(r"^section/(?P<section_slug>[\w\-]+)/not_reviewed/$", "review_section", url(r"^section/(?P<section_slug>[\w\-]+)/status/$", "review_status", name="review_status"),
{"reviewed": "not_reviewed"}, name="user_not_reviewed"), url(r"^section/(?P<section_slug>[\w\-]+)/status/(?P<key>\w+)/$", "review_status", name="review_status"),
url(r"^section/(?P<section_slug>[\w\-]+)/assignments/$", "review_section", url(r"^section/(?P<section_slug>[\w\-]+)/list/(?P<user_pk>\d+)/$", "review_list", name="review_list_user"),
{"assigned": True}, name="review_section_assignments"), url(r"^section/(?P<section_slug>[\w\-]+)/admin/$", "review_admin", name="review_admin"),
url(r"^section/(?P<section_slug>[\w\-]+)/status/$", "review_status", url(r"^section/(?P<section_slug>[\w\-]+)/admin/accept/$", "review_bulk_accept", name="review_bulk_accept"),
name="review_status"), url(r"^section/(?P<section_slug>[\w\-]+)/notification/(?P<status>\w+)/$", "result_notification", name="result_notification"),
url(r"^section/(?P<section_slug>[\w\-]+)/status/(?P<key>\w+)/$", url(r"^section/(?P<section_slug>[\w\-]+)/notification/(?P<status>\w+)/prepare/$", "result_notification_prepare", name="result_notification_prepare"),
"review_status", name="review_status"), url(r"^section/(?P<section_slug>[\w\-]+)/notification/(?P<status>\w+)/send/$", "result_notification_send", name="result_notification_send"),
url(r"^section/(?P<section_slug>[\w\-]+)/list/(?P<user_pk>\d+)/$",
"review_list", name="review_list_user"),
url(r"^section/(?P<section_slug>[\w\-]+)/admin/$", "review_admin",
name="review_admin"),
url(r"^section/(?P<section_slug>[\w\-]+)/admin/accept/$",
"review_bulk_accept", name="review_bulk_accept"),
url(r"^section/(?P<section_slug>[\w\-]+)/notification/(?P<status>\w+)/$",
"result_notification", name="result_notification"),
url(r"^section/(?P<section_slug>[\w\-]+)/notification/(?P<status>\w+)/prepare/$",
"result_notification_prepare", name="result_notification_prepare"),
url(r"^section/(?P<section_slug>[\w\-]+)/notification/(?P<status>\w+)/send/$",
"result_notification_send", name="result_notification_send"),
url(r"^review/(?P<pk>\d+)/$", "review_detail", name="review_detail"), url(r"^review/(?P<pk>\d+)/$", "review_detail", name="review_detail"),

View file

@ -69,7 +69,7 @@ def review_section(request, section_slug, assigned=False, reviewed="all"):
return access_not_permitted(request) return access_not_permitted(request)
section = get_object_or_404(ProposalSection, section__slug=section_slug) section = get_object_or_404(ProposalSection, section__slug=section_slug)
queryset = ProposalBase.objects.filter(kind__section=section) queryset = ProposalBase.objects.filter(kind__section=section.section)
if assigned: if assigned:
assignments = ReviewAssignment.objects.filter(user=request.user)\ assignments = ReviewAssignment.objects.filter(user=request.user)\
@ -343,8 +343,7 @@ def review_status(request, section_slug=None, key=None):
for status in proposals: for status in proposals:
if key and key != status: if key and key != status:
continue continue
proposals[status] = list(proposals_generator(request, proposals[status], proposals[status] = list(proposals_generator(request, proposals[status], check_speaker=not admin))
check_speaker=not admin))
if key: if key:
ctx.update({ ctx.update({
@ -409,9 +408,7 @@ def result_notification(request, section_slug, status):
if not request.user.has_perm("reviews.can_manage_%s" % section_slug): if not request.user.has_perm("reviews.can_manage_%s" % section_slug):
return access_not_permitted(request) return access_not_permitted(request)
proposals = ProposalBase.objects.filter(kind__section__slug=section_slug, proposals = ProposalBase.objects.filter(kind__section__slug=section_slug, result__status=status).select_related("speaker__user", "result").select_subclasses()
result__status=status)\
.select_related("speaker__user", "result").select_subclasses()
notification_templates = NotificationTemplate.objects.all() notification_templates = NotificationTemplate.objects.all()
ctx = { ctx = {

View file

@ -1,15 +1,17 @@
import csv import csv
import time import time
from datetime import datetime from datetime import datetime
from django import forms from django import forms
from django.contrib import messages from django.contrib import messages
from django.db import IntegrityError from django.db import IntegrityError, transaction
from django.db.models import Q from django.db.models import Q
from markitup.widgets import MarkItUpWidget from markitup.widgets import MarkItUpWidget
from symposion.schedule.models import (Day, Presentation, Room, SlotKind, Slot, SlotRoom) from symposion.schedule.models import (Day, Presentation, Room, SlotKind, Slot,
SlotRoom)
class SlotEditForm(forms.Form): class SlotEditForm(forms.Form):
@ -145,9 +147,7 @@ class ScheduleSectionForm(forms.Form):
) )
created_items.append(slot) created_items.append(slot)
try: try:
# @@@ TODO - upgrade Django, use atomic transactions with transaction.atomic():
# with transaction.atomic():
# SlotRoom.objects.create(slot=slot, room=room)
SlotRoom.objects.create(slot=slot, room=room) SlotRoom.objects.create(slot=slot, room=room)
except IntegrityError: except IntegrityError:
# delete all created objects and report error # delete all created objects and report error

View file

@ -0,0 +1,284 @@
# -*- 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 model 'Schedule'
db.create_table('schedule_schedule', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('section', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['conference.Section'], unique=True)),
('published', self.gf('django.db.models.fields.BooleanField')(default=True)),
('hidden', self.gf('django.db.models.fields.BooleanField')(default=False)),
))
db.send_create_signal('schedule', ['Schedule'])
# Adding model 'Day'
db.create_table('schedule_day', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('schedule', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['schedule.Schedule'])),
('date', self.gf('django.db.models.fields.DateField')()),
))
db.send_create_signal('schedule', ['Day'])
# Adding unique constraint on 'Day', fields ['schedule', 'date']
db.create_unique('schedule_day', ['schedule_id', 'date'])
# Adding model 'Room'
db.create_table('schedule_room', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('schedule', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['schedule.Schedule'])),
('name', self.gf('django.db.models.fields.CharField')(max_length=65)),
('order', self.gf('django.db.models.fields.PositiveIntegerField')()),
))
db.send_create_signal('schedule', ['Room'])
# Adding model 'SlotKind'
db.create_table('schedule_slotkind', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('schedule', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['schedule.Schedule'])),
('label', self.gf('django.db.models.fields.CharField')(max_length=50)),
))
db.send_create_signal('schedule', ['SlotKind'])
# Adding model 'Slot'
db.create_table('schedule_slot', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('day', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['schedule.Day'])),
('kind', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['schedule.SlotKind'])),
('start', self.gf('django.db.models.fields.TimeField')()),
('end', self.gf('django.db.models.fields.TimeField')()),
('content_override', self.gf('markitup.fields.MarkupField')(no_rendered_field=True, blank=True)),
('_content_override_rendered', self.gf('django.db.models.fields.TextField')(blank=True)),
))
db.send_create_signal('schedule', ['Slot'])
# Adding model 'SlotRoom'
db.create_table('schedule_slotroom', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('slot', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['schedule.Slot'])),
('room', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['schedule.Room'])),
))
db.send_create_signal('schedule', ['SlotRoom'])
# Adding unique constraint on 'SlotRoom', fields ['slot', 'room']
db.create_unique('schedule_slotroom', ['slot_id', 'room_id'])
# Adding model 'Presentation'
db.create_table('schedule_presentation', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('slot', self.gf('django.db.models.fields.related.OneToOneField')(blank=True, related_name='content_ptr', unique=True, null=True, to=orm['schedule.Slot'])),
('title', self.gf('django.db.models.fields.CharField')(max_length=100)),
('description', self.gf('markitup.fields.MarkupField')(no_rendered_field=True)),
('abstract', self.gf('markitup.fields.MarkupField')(no_rendered_field=True)),
('speaker', self.gf('django.db.models.fields.related.ForeignKey')(related_name='presentations', to=orm['speakers.Speaker'])),
('cancelled', self.gf('django.db.models.fields.BooleanField')(default=False)),
('proposal_base', self.gf('django.db.models.fields.related.OneToOneField')(related_name='presentation', unique=True, to=orm['proposals.ProposalBase'])),
('section', self.gf('django.db.models.fields.related.ForeignKey')(related_name='presentations', to=orm['conference.Section'])),
('_description_rendered', self.gf('django.db.models.fields.TextField')(blank=True)),
('_abstract_rendered', self.gf('django.db.models.fields.TextField')(blank=True)),
))
db.send_create_signal('schedule', ['Presentation'])
# Adding M2M table for field additional_speakers on 'Presentation'
m2m_table_name = db.shorten_name('schedule_presentation_additional_speakers')
db.create_table(m2m_table_name, (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('presentation', models.ForeignKey(orm['schedule.presentation'], null=False)),
('speaker', models.ForeignKey(orm['speakers.speaker'], null=False))
))
db.create_unique(m2m_table_name, ['presentation_id', 'speaker_id'])
def backwards(self, orm):
# Removing unique constraint on 'SlotRoom', fields ['slot', 'room']
db.delete_unique('schedule_slotroom', ['slot_id', 'room_id'])
# Removing unique constraint on 'Day', fields ['schedule', 'date']
db.delete_unique('schedule_day', ['schedule_id', 'date'])
# Deleting model 'Schedule'
db.delete_table('schedule_schedule')
# Deleting model 'Day'
db.delete_table('schedule_day')
# Deleting model 'Room'
db.delete_table('schedule_room')
# Deleting model 'SlotKind'
db.delete_table('schedule_slotkind')
# Deleting model 'Slot'
db.delete_table('schedule_slot')
# Deleting model 'SlotRoom'
db.delete_table('schedule_slotroom')
# Deleting model 'Presentation'
db.delete_table('schedule_presentation')
# Removing M2M table for field additional_speakers on 'Presentation'
db.delete_table(db.shorten_name('schedule_presentation_additional_speakers'))
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'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': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'conference.conference': {
'Meta': {'object_name': 'Conference'},
'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'timezone': ('timezones.fields.TimeZoneField', [], {'default': "'US/Eastern'", 'max_length': '100', 'blank': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'conference.section': {
'Meta': {'ordering': "['start_date']", 'object_name': 'Section'},
'conference': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['conference.Conference']"}),
'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'})
},
'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'}),
'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'})
},
'proposals.additionalspeaker': {
'Meta': {'unique_together': "(('speaker', 'proposalbase'),)", 'object_name': 'AdditionalSpeaker', 'db_table': "'proposals_proposalbase_additional_speakers'"},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'proposalbase': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['proposals.ProposalBase']"}),
'speaker': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['speakers.Speaker']"}),
'status': ('django.db.models.fields.IntegerField', [], {'default': '1'})
},
'proposals.proposalbase': {
'Meta': {'object_name': 'ProposalBase'},
'_abstract_rendered': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'_additional_notes_rendered': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'abstract': ('markitup.fields.MarkupField', [], {'no_rendered_field': 'True'}),
'additional_notes': ('markitup.fields.MarkupField', [], {'no_rendered_field': 'True', 'blank': 'True'}),
'additional_speakers': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['speakers.Speaker']", 'symmetrical': 'False', 'through': "orm['proposals.AdditionalSpeaker']", 'blank': 'True'}),
'cancelled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'description': ('django.db.models.fields.TextField', [], {'max_length': '400'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'kind': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['proposals.ProposalKind']"}),
'speaker': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'proposals'", 'to': "orm['speakers.Speaker']"}),
'submitted': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'proposals.proposalkind': {
'Meta': {'object_name': 'ProposalKind'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'section': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'proposal_kinds'", 'to': "orm['conference.Section']"}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
},
'schedule.day': {
'Meta': {'ordering': "['date']", 'unique_together': "[('schedule', 'date')]", 'object_name': 'Day'},
'date': ('django.db.models.fields.DateField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'schedule': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.Schedule']"})
},
'schedule.presentation': {
'Meta': {'ordering': "['slot']", 'object_name': 'Presentation'},
'_abstract_rendered': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'_description_rendered': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'abstract': ('markitup.fields.MarkupField', [], {'no_rendered_field': 'True'}),
'additional_speakers': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'copresentations'", 'blank': 'True', 'to': "orm['speakers.Speaker']"}),
'cancelled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'description': ('markitup.fields.MarkupField', [], {'no_rendered_field': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'proposal_base': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'presentation'", 'unique': 'True', 'to': "orm['proposals.ProposalBase']"}),
'section': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'presentations'", 'to': "orm['conference.Section']"}),
'slot': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'related_name': "'content_ptr'", 'unique': 'True', 'null': 'True', 'to': "orm['schedule.Slot']"}),
'speaker': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'presentations'", 'to': "orm['speakers.Speaker']"}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'schedule.room': {
'Meta': {'object_name': 'Room'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '65'}),
'order': ('django.db.models.fields.PositiveIntegerField', [], {}),
'schedule': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.Schedule']"})
},
'schedule.schedule': {
'Meta': {'ordering': "['section']", 'object_name': 'Schedule'},
'hidden': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'published': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'section': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['conference.Section']", 'unique': 'True'})
},
'schedule.slot': {
'Meta': {'ordering': "['day', 'start', 'end']", 'object_name': 'Slot'},
'_content_override_rendered': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'content_override': ('markitup.fields.MarkupField', [], {'no_rendered_field': 'True', 'blank': 'True'}),
'day': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.Day']"}),
'end': ('django.db.models.fields.TimeField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'kind': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.SlotKind']"}),
'start': ('django.db.models.fields.TimeField', [], {})
},
'schedule.slotkind': {
'Meta': {'object_name': 'SlotKind'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'label': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'schedule': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.Schedule']"})
},
'schedule.slotroom': {
'Meta': {'ordering': "['slot', 'room__order']", 'unique_together': "[('slot', 'room')]", 'object_name': 'SlotRoom'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'room': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.Room']"}),
'slot': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.Slot']"})
},
'speakers.speaker': {
'Meta': {'ordering': "['name']", 'object_name': 'Speaker'},
'_biography_rendered': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'annotation': ('django.db.models.fields.TextField', [], {}),
'biography': ('markitup.fields.MarkupField', [], {'no_rendered_field': 'True', 'blank': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'invite_email': ('django.db.models.fields.CharField', [], {'max_length': '200', 'unique': 'True', 'null': 'True', 'db_index': 'True'}),
'invite_token': ('django.db.models.fields.CharField', [], {'max_length': '40', 'db_index': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'photo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'speaker_profile'", 'unique': 'True', 'null': 'True', 'to': "orm['auth.User']"})
}
}
complete_apps = ['schedule']

View file

@ -79,10 +79,10 @@ class Slot(models.Model):
""" """
Unassign the associated content with this slot. Unassign the associated content with this slot.
""" """
if self.content and self.content.slot_id: content = self.content
presentation = self.content if content and content.slot_id:
presentation.slot = None content.slot = None
presentation.save() content.save()
@property @property
def content(self): def content(self):

View file

@ -6,9 +6,10 @@ from django.shortcuts import render, get_object_or_404, redirect
from django.template import loader, Context from django.template import loader, Context
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.contrib.sites.models import Site from django.contrib.sites.models import Site
from symposion.schedule.forms import SlotEditForm from symposion.schedule.forms import SlotEditForm, ScheduleSectionForm
from symposion.schedule.models import Schedule, Day, Slot, Presentation from symposion.schedule.models import Schedule, Day, Slot, Presentation
from symposion.schedule.timetable import TimeTable from symposion.schedule.timetable import TimeTable
@ -81,8 +82,8 @@ def schedule_list_csv(request, slug=None):
presentations = Presentation.objects.filter(section=schedule.section) presentations = Presentation.objects.filter(section=schedule.section)
presentations = presentations.exclude(cancelled=True).order_by("id") presentations = presentations.exclude(cancelled=True).order_by("id")
response = HttpResponse(content_type="text/csv")
response = HttpResponse(mimetype="text/csv")
if slug: if slug:
file_slug = slug file_slug = slug
else: else:
@ -104,11 +105,24 @@ def schedule_edit(request, slug=None):
schedule = fetch_schedule(slug) schedule = fetch_schedule(slug)
if request.method == "POST":
form = ScheduleSectionForm(
request.POST, request.FILES, schedule=schedule
)
if form.is_valid():
if 'submit' in form.data:
msg = form.build_schedule()
elif 'delete' in form.data:
msg = form.delete_schedule()
messages.add_message(request, msg[0], msg[1])
else:
form = ScheduleSectionForm(schedule=schedule)
days_qs = Day.objects.filter(schedule=schedule) days_qs = Day.objects.filter(schedule=schedule)
days = [TimeTable(day) for day in days_qs] days = [TimeTable(day) for day in days_qs]
ctx = { ctx = {
"schedule": schedule, "schedule": schedule,
"days": days, "days": days,
"form": form
} }
return render(request, "schedule/schedule_edit.html", ctx) return render(request, "schedule/schedule_edit.html", ctx)

View file

@ -1,29 +0,0 @@
from django.contrib.auth.models import User
from fixture_generator import fixture_generator
from symposion.speakers.models import Speaker
@fixture_generator(Speaker, User)
def speakers():
guido = User.objects.create_user("guido", "guido@python.org", "pythonisawesome")
matz = User.objects.create_user("matz", "matz@ruby.org", "pythonsucks")
larry = User.objects.create_user("larryw", "larry@perl.org", "linenoisehere")
Speaker.objects.create(
user=guido,
name="Guido van Rossum",
biography="I wrote Python, and named it after Monty Python",
)
Speaker.objects.create(
user=matz,
name="Yukihiro Matsumoto",
biography=("I wrote Ruby, and named it after the rare gem Ruby, a pun "
"on Perl/pearl."),
)
Speaker.objects.create(
user=larry,
name="Larry Wall",
biography="I wrote Perl, and named it after the Parable of the Pearl",
)

View file

@ -0,0 +1,84 @@
# -*- 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 model 'Speaker'
db.create_table('speakers_speaker', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('user', self.gf('django.db.models.fields.related.OneToOneField')(related_name='speaker_profile', unique=True, null=True, to=orm['auth.User'])),
('name', self.gf('django.db.models.fields.CharField')(max_length=100)),
('biography', self.gf('markitup.fields.MarkupField')(no_rendered_field=True, blank=True)),
('photo', self.gf('django.db.models.fields.files.ImageField')(max_length=100, blank=True)),
('annotation', self.gf('django.db.models.fields.TextField')()),
('invite_email', self.gf('django.db.models.fields.CharField')(max_length=200, unique=True, null=True, db_index=True)),
('invite_token', self.gf('django.db.models.fields.CharField')(max_length=40, db_index=True)),
('created', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
('_biography_rendered', self.gf('django.db.models.fields.TextField')(blank=True)),
))
db.send_create_signal('speakers', ['Speaker'])
def backwards(self, orm):
# Deleting model 'Speaker'
db.delete_table('speakers_speaker')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'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': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'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'}),
'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'})
},
'speakers.speaker': {
'Meta': {'ordering': "['name']", 'object_name': 'Speaker'},
'_biography_rendered': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'annotation': ('django.db.models.fields.TextField', [], {}),
'biography': ('markitup.fields.MarkupField', [], {'no_rendered_field': 'True', 'blank': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'invite_email': ('django.db.models.fields.CharField', [], {'max_length': '200', 'unique': 'True', 'null': 'True', 'db_index': 'True'}),
'invite_token': ('django.db.models.fields.CharField', [], {'max_length': '40', 'db_index': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'photo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'speaker_profile'", 'unique': 'True', 'null': 'True', 'to': "orm['auth.User']"})
}
}
complete_apps = ['speakers']

View file

@ -0,0 +1,188 @@
# -*- 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):
depends_on = (
("conference", "0001_initial"),
)
def forwards(self, orm):
# Adding model 'SponsorLevel'
db.create_table('sponsorship_sponsorlevel', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('conference', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['conference.Conference'])),
('name', self.gf('django.db.models.fields.CharField')(max_length=100)),
('order', self.gf('django.db.models.fields.IntegerField')(default=0)),
('cost', self.gf('django.db.models.fields.PositiveIntegerField')()),
('description', self.gf('django.db.models.fields.TextField')(blank=True)),
))
db.send_create_signal('sponsorship', ['SponsorLevel'])
# Adding model 'Sponsor'
db.create_table('sponsorship_sponsor', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('applicant', self.gf('django.db.models.fields.related.ForeignKey')(related_name='sponsorships', null=True, to=orm['auth.User'])),
('name', self.gf('django.db.models.fields.CharField')(max_length=100)),
('external_url', self.gf('django.db.models.fields.URLField')(max_length=200)),
('annotation', self.gf('django.db.models.fields.TextField')(blank=True)),
('contact_name', self.gf('django.db.models.fields.CharField')(max_length=100)),
('contact_email', self.gf('django.db.models.fields.EmailField')(max_length=75)),
('level', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['sponsorship.SponsorLevel'])),
('added', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
('active', self.gf('django.db.models.fields.BooleanField')(default=False)),
('sponsor_logo', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='+', null=True, to=orm['sponsorship.SponsorBenefit'])),
))
db.send_create_signal('sponsorship', ['Sponsor'])
# Adding model 'Benefit'
db.create_table('sponsorship_benefit', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('name', self.gf('django.db.models.fields.CharField')(max_length=100)),
('description', self.gf('django.db.models.fields.TextField')(blank=True)),
('type', self.gf('django.db.models.fields.CharField')(default='simple', max_length=10)),
))
db.send_create_signal('sponsorship', ['Benefit'])
# Adding model 'BenefitLevel'
db.create_table('sponsorship_benefitlevel', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('benefit', self.gf('django.db.models.fields.related.ForeignKey')(related_name='benefit_levels', to=orm['sponsorship.Benefit'])),
('level', self.gf('django.db.models.fields.related.ForeignKey')(related_name='benefit_levels', to=orm['sponsorship.SponsorLevel'])),
('max_words', self.gf('django.db.models.fields.PositiveIntegerField')(null=True, blank=True)),
('other_limits', self.gf('django.db.models.fields.CharField')(max_length=200, blank=True)),
))
db.send_create_signal('sponsorship', ['BenefitLevel'])
# Adding model 'SponsorBenefit'
db.create_table('sponsorship_sponsorbenefit', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('sponsor', self.gf('django.db.models.fields.related.ForeignKey')(related_name='sponsor_benefits', to=orm['sponsorship.Sponsor'])),
('benefit', self.gf('django.db.models.fields.related.ForeignKey')(related_name='sponsor_benefits', to=orm['sponsorship.Benefit'])),
('active', self.gf('django.db.models.fields.BooleanField')(default=True)),
('max_words', self.gf('django.db.models.fields.PositiveIntegerField')(null=True, blank=True)),
('other_limits', self.gf('django.db.models.fields.CharField')(max_length=200, blank=True)),
('text', self.gf('django.db.models.fields.TextField')(blank=True)),
('upload', self.gf('django.db.models.fields.files.FileField')(max_length=100, blank=True)),
))
db.send_create_signal('sponsorship', ['SponsorBenefit'])
def backwards(self, orm):
# Deleting model 'SponsorLevel'
db.delete_table('sponsorship_sponsorlevel')
# Deleting model 'Sponsor'
db.delete_table('sponsorship_sponsor')
# Deleting model 'Benefit'
db.delete_table('sponsorship_benefit')
# Deleting model 'BenefitLevel'
db.delete_table('sponsorship_benefitlevel')
# Deleting model 'SponsorBenefit'
db.delete_table('sponsorship_sponsorbenefit')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'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': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'conference.conference': {
'Meta': {'object_name': 'Conference'},
'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'timezone': ('timezones.fields.TimeZoneField', [], {'default': "'US/Eastern'", 'max_length': '100', 'blank': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'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'}),
'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'})
},
'sponsorship.benefit': {
'Meta': {'object_name': 'Benefit'},
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'type': ('django.db.models.fields.CharField', [], {'default': "'simple'", 'max_length': '10'})
},
'sponsorship.benefitlevel': {
'Meta': {'ordering': "['level']", 'object_name': 'BenefitLevel'},
'benefit': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'benefit_levels'", 'to': "orm['sponsorship.Benefit']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'level': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'benefit_levels'", 'to': "orm['sponsorship.SponsorLevel']"}),
'max_words': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
'other_limits': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'})
},
'sponsorship.sponsor': {
'Meta': {'object_name': 'Sponsor'},
'active': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'added': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'annotation': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'applicant': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'sponsorships'", 'null': 'True', 'to': "orm['auth.User']"}),
'contact_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
'contact_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'external_url': ('django.db.models.fields.URLField', [], {'max_length': '200'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['sponsorship.SponsorLevel']"}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'sponsor_logo': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'to': "orm['sponsorship.SponsorBenefit']"})
},
'sponsorship.sponsorbenefit': {
'Meta': {'ordering': "['-active']", 'object_name': 'SponsorBenefit'},
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'benefit': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'sponsor_benefits'", 'to': "orm['sponsorship.Benefit']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'max_words': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
'other_limits': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
'sponsor': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'sponsor_benefits'", 'to': "orm['sponsorship.Sponsor']"}),
'text': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'upload': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'})
},
'sponsorship.sponsorlevel': {
'Meta': {'ordering': "['conference', 'order']", 'object_name': 'SponsorLevel'},
'conference': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['conference.Conference']"}),
'cost': ('django.db.models.fields.PositiveIntegerField', [], {}),
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'})
}
}
complete_apps = ['sponsorship']

View file

@ -0,0 +1,123 @@
# -*- 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 model 'Team'
db.create_table('teams_team', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('slug', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=50)),
('name', self.gf('django.db.models.fields.CharField')(max_length=100)),
('description', self.gf('django.db.models.fields.TextField')(blank=True)),
('access', self.gf('django.db.models.fields.CharField')(max_length=20)),
('created', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
))
db.send_create_signal('teams', ['Team'])
# Adding M2M table for field permissions on 'Team'
m2m_table_name = db.shorten_name('teams_team_permissions')
db.create_table(m2m_table_name, (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('team', models.ForeignKey(orm['teams.team'], null=False)),
('permission', models.ForeignKey(orm['auth.permission'], null=False))
))
db.create_unique(m2m_table_name, ['team_id', 'permission_id'])
# Adding M2M table for field manager_permissions on 'Team'
m2m_table_name = db.shorten_name('teams_team_manager_permissions')
db.create_table(m2m_table_name, (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('team', models.ForeignKey(orm['teams.team'], null=False)),
('permission', models.ForeignKey(orm['auth.permission'], null=False))
))
db.create_unique(m2m_table_name, ['team_id', 'permission_id'])
# Adding model 'Membership'
db.create_table('teams_membership', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('user', self.gf('django.db.models.fields.related.ForeignKey')(related_name='memberships', to=orm['auth.User'])),
('team', self.gf('django.db.models.fields.related.ForeignKey')(related_name='memberships', to=orm['teams.Team'])),
('state', self.gf('django.db.models.fields.CharField')(max_length=20)),
('message', self.gf('django.db.models.fields.TextField')(blank=True)),
))
db.send_create_signal('teams', ['Membership'])
def backwards(self, orm):
# Deleting model 'Team'
db.delete_table('teams_team')
# Removing M2M table for field permissions on 'Team'
db.delete_table(db.shorten_name('teams_team_permissions'))
# Removing M2M table for field manager_permissions on 'Team'
db.delete_table(db.shorten_name('teams_team_manager_permissions'))
# Deleting model 'Membership'
db.delete_table('teams_membership')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'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': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'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'}),
'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'})
},
'teams.membership': {
'Meta': {'object_name': 'Membership'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'message': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'state': ('django.db.models.fields.CharField', [], {'max_length': '20'}),
'team': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'memberships'", 'to': "orm['teams.Team']"}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'memberships'", 'to': "orm['auth.User']"})
},
'teams.team': {
'Meta': {'object_name': 'Team'},
'access': ('django.db.models.fields.CharField', [], {'max_length': '20'}),
'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'manager_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'manager_teams'", 'blank': 'True', 'to': "orm['auth.Permission']"}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'member_teams'", 'blank': 'True', 'to': "orm['auth.Permission']"}),
'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'})
}
}
complete_apps = ['teams']

View file

View file

@ -1,5 +1,8 @@
{% extends "site_base.html" %} {% extends "site_base.html" %}
{% load url from future %}
{% load sitetree %} {% load sitetree %}
{% load i18n %} {% load i18n %}
@ -12,7 +15,7 @@
{% block body %} {% block body %}
{% if editable %} {% if editable %}
<div class="pull-right"> <div class="pull-right">
<a href="{% url cms_page_edit page.path %}" class="btn"><i class="icon-pencil icon-large"></i> Edit this page</a> <a href="{% url 'cms_page_edit' page.path %}" class="btn"><i class="icon-pencil icon-large"></i> Edit this page</a>
</div> </div>
{% endif %} {% endif %}
<h2>{{ page.title }}</h2> <h2>{{ page.title }}</h2>

View file

@ -1,8 +1,9 @@
{% load url from future %}
<p>{{ proposal.speaker.name }} attached you as an additional speaker to a <p>{{ proposal.speaker.name }} attached you as an additional speaker to a
talk proposal for {{ current_site.name }} entitled "{{ proposal.title }}".</p> talk proposal for {{ current_site.name }} entitled "{{ proposal.title }}".</p>
<p>Go to</p> <p>Go to</p>
<p><a href="http://{{ current_site }}{% url speaker_create_token token %}">http://{{ current_site }}{% url speaker_create_token token %}</a></p> <p><a href="http://{{ current_site }}{% url 'speaker_create_token' token %}">http://{{ current_site }}{% url 'speaker_create_token' token %}</a></p>
<p>to confirm and fill out your speaker profile.</p> <p>to confirm and fill out your speaker profile.</p>

View file

@ -45,5 +45,19 @@
e.preventDefault(); e.preventDefault();
}); });
}); });
$(function() {
//submit event handler
$("form#schedule-builder :submit").click(function(e) {
var name = this.name;
if(name == 'delete') {
if (!confirm("Are you sure you want to delete the schedule?"))
{
e.preventDefault();
return;
}
}
});
});
</script> </script>
{% endblock %} {% endblock %}