finish committing all changes

pull/1/head
eric 2012-02-28 17:28:33 -05:00
parent 039f617f17
commit eebeb2476f
7 changed files with 440 additions and 597 deletions

View File

@ -0,0 +1,238 @@
# encoding: utf-8
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
no_dry_run = True
def forwards(self, orm):
# Adding field 'Ebook.user'
db.add_column('core_ebook', 'user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True), keep_default=False)
# Adding field 'WasWork.moved'
db.add_column('core_waswork', 'moved', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, default=datetime.date(2012, 2, 25), blank=True), keep_default=False)
# Adding field 'WasWork.user'
db.add_column('core_waswork', 'user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True), keep_default=False)
# change value of ebook.provider
for ebook in orm.Ebook.objects.filter(provider = 'google'):
ebook.provider ='Google Books'
ebook.rights = 'PD-US'
ebook.save()
for ebook in orm.Ebook.objects.filter(provider = 'gutenberg'):
ebook.provider ='Project Gutenberg'
ebook.rights = 'PD-US'
ebook.save()
def backwards(self, orm):
# Deleting field 'Ebook.user'
db.delete_column('core_ebook', 'user_id')
# Deleting field 'WasWork.moved'
db.delete_column('core_waswork', 'moved')
# Deleting field 'WasWork.user'
db.delete_column('core_waswork', 'user_id')
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'})
},
'core.author': {
'Meta': {'object_name': 'Author'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'editions': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'authors'", 'symmetrical': 'False', 'to': "orm['core.Edition']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '500'})
},
'core.campaign': {
'Meta': {'object_name': 'Campaign'},
'activated': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'amazon_receiver': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'deadline': ('django.db.models.fields.DateTimeField', [], {}),
'description': ('django.db.models.fields.TextField', [], {'null': 'True'}),
'details': ('django.db.models.fields.TextField', [], {'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'left': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '14', 'decimal_places': '2'}),
'managers': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'campaigns'", 'symmetrical': 'False', 'to': "orm['auth.User']"}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '500', 'null': 'True'}),
'paypal_receiver': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'status': ('django.db.models.fields.CharField', [], {'default': "'INITIALIZED'", 'max_length': '15', 'null': 'True'}),
'target': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '14', 'decimal_places': '2'}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'campaigns'", 'to': "orm['core.Work']"})
},
'core.campaignaction': {
'Meta': {'object_name': 'CampaignAction'},
'campaign': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'actions'", 'to': "orm['core.Campaign']"}),
'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'timestamp': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '15'})
},
'core.celerytask': {
'Meta': {'object_name': 'CeleryTask'},
'active': ('django.db.models.fields.NullBooleanField', [], {'default': 'True', 'null': 'True', 'blank': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 2, 25, 11, 41, 50, 264275)', 'auto_now_add': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'null': 'True'}),
'function_args': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
'function_name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'task_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tasks'", 'null': 'True', 'to': "orm['auth.User']"})
},
'core.claim': {
'Meta': {'object_name': 'Claim'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'rights_holder': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'claim'", 'to': "orm['core.RightsHolder']"}),
'status': ('django.db.models.fields.CharField', [], {'default': "'pending'", 'max_length': '7'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'claim'", 'to': "orm['auth.User']"}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'claim'", 'to': "orm['core.Work']"})
},
'core.ebook': {
'Meta': {'object_name': 'Ebook'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ebooks'", 'to': "orm['core.Edition']"}),
'format': ('django.db.models.fields.CharField', [], {'max_length': '25'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'provider': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'rights': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
'url': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'})
},
'core.edition': {
'Meta': {'object_name': 'Edition'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'public_domain': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
'publication_date': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True'}),
'publisher': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'editions'", 'null': 'True', 'to': "orm['core.Work']"})
},
'core.identifier': {
'Meta': {'unique_together': "(('type', 'value'),)", 'object_name': 'Identifier'},
'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'identifiers'", 'null': 'True', 'to': "orm['core.Edition']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '4'}),
'value': ('django.db.models.fields.CharField', [], {'max_length': '31'}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'identifiers'", 'to': "orm['core.Work']"})
},
'core.premium': {
'Meta': {'object_name': 'Premium'},
'amount': ('django.db.models.fields.DecimalField', [], {'max_digits': '10', 'decimal_places': '0'}),
'campaign': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'premiums'", 'null': 'True', 'to': "orm['core.Campaign']"}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.TextField', [], {'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '2'})
},
'core.rightsholder': {
'Meta': {'object_name': 'RightsHolder'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'email': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'rights_holder'", 'to': "orm['auth.User']"}),
'rights_holder_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'})
},
'core.subject': {
'Meta': {'ordering': "['name']", 'object_name': 'Subject'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '200'}),
'works': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'subjects'", 'symmetrical': 'False', 'to': "orm['core.Work']"})
},
'core.userprofile': {
'Meta': {'object_name': 'UserProfile'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'facebook_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}),
'goodreads_auth_secret': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'goodreads_auth_token': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'goodreads_user_id': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}),
'goodreads_user_link': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
'goodreads_user_name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
'home_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'librarything_id': ('django.db.models.fields.CharField', [], {'max_length': '31', 'blank': 'True'}),
'pic_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
'tagline': ('django.db.models.fields.CharField', [], {'max_length': '140', 'blank': 'True'}),
'twitter_id': ('django.db.models.fields.CharField', [], {'max_length': '15', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'profile'", 'unique': 'True', 'to': "orm['auth.User']"})
},
'core.waswork': {
'Meta': {'object_name': 'WasWork'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'moved': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}),
'was': ('django.db.models.fields.IntegerField', [], {'unique': 'True'}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['core.Work']"})
},
'core.wishes': {
'Meta': {'object_name': 'Wishes', 'db_table': "'core_wishlist_works'"},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'source': ('django.db.models.fields.CharField', [], {'max_length': '15', 'blank': 'True'}),
'wishlist': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['core.Wishlist']"}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'wishes'", 'to': "orm['core.Work']"})
},
'core.wishlist': {
'Meta': {'object_name': 'Wishlist'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'wishlist'", 'unique': 'True', 'to': "orm['auth.User']"}),
'works': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'wishlists'", 'symmetrical': 'False', 'through': "orm['core.Wishes']", 'to': "orm['core.Work']"})
},
'core.work': {
'Meta': {'ordering': "['title']", 'object_name': 'Work'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'language': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '2'}),
'num_wishes': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'openlibrary_lookup': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'})
}
}
complete_apps = ['core']

View File

@ -227,13 +227,14 @@ class BookLoaderTests(TestCase):
#self.assertEqual(ebook_epub.url, 'http://books.google.com/books/download/The_Latin_language.epub?id=U3FXAAAAYAAJ&ie=ISO-8859-1&output=epub&source=gbs_api') #self.assertEqual(ebook_epub.url, 'http://books.google.com/books/download/The_Latin_language.epub?id=U3FXAAAAYAAJ&ie=ISO-8859-1&output=epub&source=gbs_api')
self.assertEqual(parse_qs(urlparse(ebook_epub.url).query).get("id"), ['U3FXAAAAYAAJ']) self.assertEqual(parse_qs(urlparse(ebook_epub.url).query).get("id"), ['U3FXAAAAYAAJ'])
self.assertEqual(parse_qs(urlparse(ebook_epub.url).query).get("output"), ['epub']) self.assertEqual(parse_qs(urlparse(ebook_epub.url).query).get("output"), ['epub'])
self.assertEqual(ebook_epub.provider, 'google') self.assertEqual(ebook_epub.provider, 'Google Books')
self.assertEqual(ebook_epub.set_provider(), 'Google Books')
ebook_pdf = edition.ebooks.filter(format='pdf')[0] ebook_pdf = edition.ebooks.filter(format='pdf')[0]
self.assertEqual(ebook_pdf.format, 'pdf') self.assertEqual(ebook_pdf.format, 'pdf')
#self.assertEqual(ebook_pdf.url, 'http://books.google.com/books/download/The_Latin_language.pdf?id=U3FXAAAAYAAJ&ie=ISO-8859-1&output=pdf&sig=ACfU3U2yLt3nmTncB8ozxOWUc4iHKUznCA&source=gbs_api') #self.assertEqual(ebook_pdf.url, 'http://books.google.com/books/download/The_Latin_language.pdf?id=U3FXAAAAYAAJ&ie=ISO-8859-1&output=pdf&sig=ACfU3U2yLt3nmTncB8ozxOWUc4iHKUznCA&source=gbs_api')
self.assertEqual(parse_qs(urlparse(ebook_pdf.url).query).get("id"), ['U3FXAAAAYAAJ']) self.assertEqual(parse_qs(urlparse(ebook_pdf.url).query).get("id"), ['U3FXAAAAYAAJ'])
self.assertEqual(parse_qs(urlparse(ebook_pdf.url).query).get("output"), ['pdf']) self.assertEqual(parse_qs(urlparse(ebook_pdf.url).query).get("output"), ['pdf'])
self.assertEqual(ebook_pdf.provider, 'google') self.assertEqual(ebook_pdf.provider, 'Google Books')
self.assertEqual(edition.public_domain, True) self.assertEqual(edition.public_domain, True)
w = edition.work w = edition.work
@ -242,6 +243,9 @@ class BookLoaderTests(TestCase):
self.assertEqual(w.first_epub_url(), ebook_epub.url) self.assertEqual(w.first_epub_url(), ebook_epub.url)
self.assertEqual(w.first_pdf_url(), ebook_pdf.url) self.assertEqual(w.first_pdf_url(), ebook_pdf.url)
ebook_pdf.url='http://en.wikisource.org/wiki/Frankenstein'
self.assertEqual(ebook_pdf.set_provider(), 'Wikisource')
def test_add_no_ebook(self): def test_add_no_ebook(self):
# this edition lacks an ebook, but we should still be able to load it # this edition lacks an ebook, but we should still be able to load it
e = bookloader.add_by_isbn('0465019358') e = bookloader.add_by_isbn('0465019358')

View File

@ -11,13 +11,28 @@ from decimal import Decimal as D
from selectable.forms import AutoCompleteSelectMultipleWidget,AutoCompleteSelectMultipleField from selectable.forms import AutoCompleteSelectMultipleWidget,AutoCompleteSelectMultipleField
from selectable.forms import AutoCompleteSelectWidget,AutoCompleteSelectField from selectable.forms import AutoCompleteSelectWidget,AutoCompleteSelectField
from regluit.core.models import UserProfile, RightsHolder, Claim, Campaign, Premium from regluit.core.models import UserProfile, RightsHolder, Claim, Campaign, Premium, Ebook
from regluit.core.lookups import OwnerLookup from regluit.core.lookups import OwnerLookup
import logging import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class EbookForm(forms.ModelForm):
class Meta:
model = Ebook
exclude = 'created'
widgets = {
'edition': forms.HiddenInput,
'user': forms.HiddenInput,
'provider': forms.HiddenInput,
'url': forms.TextInput(attrs={'size' : 60}),
}
def clean_provider(self):
new_provider= Ebook.infer_provider(self.data['url'])
if not new_provider:
raise forms.ValidationError(_("At this time, ebook URLs must point at Internet Archive, Wikisources, Hathitrust, Project Gutenberg, or Google Books."))
return new_provider
def UserClaimForm ( user_instance, *args, **kwargs ): def UserClaimForm ( user_instance, *args, **kwargs ):
class ClaimForm(forms.ModelForm): class ClaimForm(forms.ModelForm):
@ -194,30 +209,30 @@ class CampaignAdminForm(forms.Form):
pass pass
class EmailShareForm(forms.Form): class EmailShareForm(forms.Form):
recipient = forms.EmailField() recipient = forms.EmailField()
sender = forms.EmailField(widget=forms.HiddenInput()) sender = forms.EmailField(widget=forms.HiddenInput())
subject = forms.CharField(max_length=100) subject = forms.CharField(max_length=100)
message = forms.CharField(widget=forms.Textarea()) message = forms.CharField(widget=forms.Textarea())
# allows us to return user to original page by passing it as hidden form input # allows us to return user to original page by passing it as hidden form input
# we can't rely on POST or GET since the emailshare view handles both # we can't rely on POST or GET since the emailshare view handles both
# and may iterate several times as it catches user errors, losing URL info # and may iterate several times as it catches user errors, losing URL info
next = forms.CharField(widget=forms.HiddenInput()) next = forms.CharField(widget=forms.HiddenInput())
class FeedbackForm(forms.Form): class FeedbackForm(forms.Form):
sender = forms.EmailField(widget=forms.TextInput(attrs={'size':50}), label="Your email") sender = forms.EmailField(widget=forms.TextInput(attrs={'size':50}), label="Your email")
subject = forms.CharField(max_length=500, widget=forms.TextInput(attrs={'size':50})) subject = forms.CharField(max_length=500, widget=forms.TextInput(attrs={'size':50}))
message = forms.CharField(widget=forms.Textarea()) message = forms.CharField(widget=forms.Textarea())
page = forms.CharField(widget=forms.HiddenInput()) page = forms.CharField(widget=forms.HiddenInput())
notarobot = forms.IntegerField(label="Please prove you're not a robot") notarobot = forms.IntegerField(label="Please prove you're not a robot")
answer = forms.IntegerField(widget=forms.HiddenInput()) answer = forms.IntegerField(widget=forms.HiddenInput())
num1 = forms.IntegerField(widget=forms.HiddenInput()) num1 = forms.IntegerField(widget=forms.HiddenInput())
num2 = forms.IntegerField(widget=forms.HiddenInput()) num2 = forms.IntegerField(widget=forms.HiddenInput())
def clean(self): def clean(self):
cleaned_data = self.cleaned_data cleaned_data = self.cleaned_data
notarobot = str(cleaned_data.get("notarobot")) notarobot = str(cleaned_data.get("notarobot"))
answer = str(cleaned_data.get("answer")) answer = str(cleaned_data.get("answer"))
if notarobot!=answer: if notarobot!=answer:
raise forms.ValidationError(_("Whoops, try that sum again.")) raise forms.ValidationError(_("Whoops, try that sum again."))
return cleaned_data return cleaned_data

View File

@ -1,4 +1,4 @@
<div class="thewholebook listview tabs {% if status == 'SUCCESSFUL' or work.first_pdf_url or work.first_epub_url %}tabs-1{% else %}{% if status == 'ACTIVE' %}tabs-2{% else %}tabs-3{% endif %}{% endif %}"> <div class="thewholebook listview tabs {% if status == 'SUCCESSFUL' or work.first_ebook %}tabs-1{% else %}{% if status == 'ACTIVE' %}tabs-2{% else %}tabs-3{% endif %}{% endif %}">
<div class="listview book-list"> <div class="listview book-list">
<div class="listview panelback side2"> <div class="listview panelback side2">
<div class="greenpanel2"> <div class="greenpanel2">
@ -6,17 +6,17 @@
<div class="unglued_white"> <div class="unglued_white">
{% comment %}top section: campaign info + optional action button. Varies by campaign status.{% endcomment %} {% comment %}top section: campaign info + optional action button. Varies by campaign status.{% endcomment %}
{% if work.first_pdf_url or work.first_epub_url %} {% if work.first_ebook %}
<b>AVAILABLE!</b> <b>AVAILABLE!</b>
</div> </div>
<div class="read_itbutton">{% if work.first_epub_url %}<a href="{{ work.first_epub_url }}">{% else %}<a href="{{ work.first_pdf_url }}">{% endif %}Read it Now</a></div> <div class="read_itbutton">{% if work.first_ebook %}<a href="{{ work.ebooks.0.url }}">{% endif %}Read it Now</a></div>
{% else %}{% if status == 'SUCCESSFUL' %} {% else %}{% if status == 'SUCCESSFUL' %}
<b>UNGLUED!</b> <b>UNGLUED!</b>
<p><b>On:</b> {{ deadline|date:"M d, Y" }}</p> <p><b>On:</b> {{ deadline|date:"M d, Y" }}</p>
<p><b>Raised:</b> {{ work.last_campaign.current_total }}</p> <p><b>Raised:</b> {{ work.last_campaign.current_total }}</p>
</div> </div>
<div class="read_itbutton">{% if work.first_epub_url %}<a href="{{ work.first_epub_url }}">{% else %}<a href="{{ work.first_pdf_url }}">{% endif %}Read it Now</a></div> <div class="read_itbutton">{% if work.first_ebook %}<a href="{{ work.ebooks.0.url }}">{% endif %}Read it Now</a></div>
{% else %}{% if status == 'ACTIVE' %} {% else %}{% if status == 'ACTIVE' %}
<b>UNGLUE IT!</b> <b>UNGLUE IT!</b>
@ -123,14 +123,11 @@
<div class="listview panelfront side1 icons"> <div class="listview panelfront side1 icons">
{% if status == 'No campaign yet' or status == 'INITIALIZED' %} {% if status == 'No campaign yet' or status == 'INITIALIZED' %}
<a href="{% url work work.id %}?tab=3" class="nobold"><span class="rounded"><span class="grey"><span class="panelnope">Wished by&nbsp;</span>{{ work.num_wishes }}</span></span></a> <a href="{% url work work.id %}?tab=3" class="nobold"><span class="rounded"><span class="grey"><span class="panelnope">Wished by&nbsp;</span>{{ work.num_wishes }}</span></span></a>
{% else %}{% if work.first_pdf_url or work.first_epub_url %} {% else %}{% if work.first_ebook %}
<span class="listview boolist-ebook"> <span class="listview boolist-ebook">
{% if work.first_epub_url %} {% for ebook in work.ebooks|slice:":3" %}
<a href="{{ work.first_epub_url }}">EPUB</a> <a href="ebook.url">{{ ebook.format }}</a>
{% endif %} {% endfor %}
{% if work.first_pdf_url %}
<a href="{{ work.first_pdf_url }}">PDF</a>
{% endif %}
</span> </span>
{% else %} {% else %}

View File

@ -19,7 +19,14 @@ jQuery(document).ready(function(){
jQuery('#embed').click(function(){ jQuery('#embed').click(function(){
jQuery('div#widgetcode').toggle(); jQuery('div#widgetcode').toggle();
}); });
jQuery('.show_more_edition').click(function(){
jQuery(this).html('less...');
jQuery(this).next().toggle();
});
}); });
</script> </script>
{% endblock %} {% endblock %}
@ -31,7 +38,7 @@ jQuery(document).ready(function(){
<div class="jsmodule rounded"> <div class="jsmodule rounded">
<div class="jsmod-content{% if status == 'ACTIVE' %} active{{ work.percent_unglued}}{% endif %}"> <div class="jsmod-content{% if status == 'ACTIVE' %} active{{ work.percent_unglued}}{% endif %}">
<span> <span>
{% if work.first_epub_url or work.first_pdf_url %} {% if work.first_ebook %}
AVAILABLE! AVAILABLE!
{% else %}{% if work.last_campaign %} {% else %}{% if work.last_campaign %}
{% if status == 'ACTIVE' %} {% if status == 'ACTIVE' %}
@ -106,7 +113,7 @@ jQuery(document).ready(function(){
</div> </div>
</div> </div>
<div class="pledged-info"><div class="pledged-group"> <div class="pledged-info"><div class="pledged-group">
{% if work.first_epub_url or work.first_pdf_url %} {% if work.first_ebook %}
{% if wishers == 1 %} {% if wishers == 1 %}
1 Ungluer is 1 Ungluer is
{% else %} {% else %}
@ -127,17 +134,14 @@ jQuery(document).ready(function(){
{% endif %} wished for this Work {% endif %} wished for this Work
{% endif %}{% endif %} {% endif %}{% endif %}
</div> </div>
<div class="status"><img src="/static/images/images/icon-book-37by25-{% if work.first_epub_url or work.first_pdf_url %}6{%else%}{{ work.percent_unglued }}{%endif%}.png" /></div> <div class="status"><img src="/static/images/images/icon-book-37by25-{% if work.first_ebook %}6{%else%}{{ work.percent_unglued }}{%endif%}.png" /></div>
</div> </div>
<div class="btn_wishlist" id="wishlist_actions"> <div class="btn_wishlist" id="wishlist_actions">
{% if work.first_epub_url or work.first_pdf_url %} {% if work.first_ebook %}
<span class="boolist-ebook"> <span class="boolist-ebook">
{% if work.first_epub_url %} {% for ebook in work.ebooks %}
<a href="{{ work.first_epub_url }}">EPUB</a> <a href="ebook.url">{{ ebook.format }}</a> {{ebook.rights}} at {{ebook.provider}}<br />
{% endif %} {% endfor %}
{% if work.first_pdf_url %}
<a href="{{ work.first_pdf_url }}">PDF</a>
{% endif %}
</span> </span>
{% endif %} {% endif %}
{% if request.user.is_anonymous %} {% if request.user.is_anonymous %}
@ -154,7 +158,7 @@ jQuery(document).ready(function(){
</div> </div>
{% else %} {% else %}
<div class="add-wishlist"> <div class="add-wishlist">
<span id="{{ work.googlebooks_id }}">Add to {% if work.first_epub_url or work.first_pdf_url %}Enjoying{% else %}Wishlist{% endif %}</span> <span id="{{ work.googlebooks_id }}">Add to {% if work.first_ebook %}Enjoying{% else %}Wishlist{% endif %}</span>
</div> </div>
{% endif %}{% endif %}{% endif %} {% endif %}{% endif %}{% endif %}
</div> </div>
@ -271,10 +275,11 @@ jQuery(document).ready(function(){
{% endif %} {% endif %}
<h4>Editions</h4> <h4>Editions</h4>
{% if alert %}<div class="alert"><b>Ebook Contribution:</b><br />{{ alert }}</div>{% endif %}
{% for edition in editions %} {% for edition in editions %}
<div class="editions"><div class="image"><img src="http://bks{% cycle '1' '2' '3' '4' '5' '6' '7' '8' '9' %}.books.google.com/books?id={{ edition.googlebooks_id }}&printsec=frontcover&img=1&zoom=5" /></div> <div class="editions"><div class="image"><img src="http://bks{% cycle '1' '2' '3' '4' '5' '6' '7' '8' '9' %}.books.google.com/books?id={{ edition.googlebooks_id }}&printsec=frontcover&img=1&zoom=5" /></div>
<div class="metadata">{{edition.publisher}}<br /> <div class="metadata" id="edition_{{edition.id}}">Publisher: {{edition.publisher}}<br />
{{edition.publication_date}}<br /> Published: {{edition.publication_date}}<br />
{% with edition.isbn_13 as isbn %} {% with edition.isbn_13 as isbn %}
{% if isbn %} {% if isbn %}
ISBN: {{ isbn }}<br /> ISBN: {{ isbn }}<br />
@ -284,6 +289,26 @@ jQuery(document).ready(function(){
{% endwith %} {% endwith %}
See <a href="http://bks{% cycle '1' '2' '3' '4' '5' '6' '7' '8' '9' %}.books.google.com/books?id={{ edition.googlebooks_id }}">this edition on Google Books</a></div> See <a href="http://bks{% cycle '1' '2' '3' '4' '5' '6' '7' '8' '9' %}.books.google.com/books?id={{ edition.googlebooks_id }}">this edition on Google Books</a></div>
</div> </div>
{% if edition.ebook_form %}
<div class="show_more_edition" >more...</div>
<div class="more_edition">
{% if edition.ebooks %}
<h5>eBooks for this Edition</h5>
{% for ebook in edition.ebooks.all %}
<a href="ebook.url">{{ ebook.format }}</a> {{ebook.rights}} at {{ebook.provider}}<br />
{% endfor %}
{% endif %}
<h5>Add an eBook for this Edition</h5>
<span>If you know that this edition is available as a public domain or Creative Commons ebook, you can enter the link here and "unglue" it. Right now, we're only accepting URLs that point to Internet Archive, Wikisources, Hathitrust, Project Gutenberg, or Google Books.</span>
<form method="POST" action="#edition_{{edition.id}}">
{% csrf_token %}{{ edition.ebook_form.edition }}{{ edition.ebook_form.user }}{{ edition.ebook_form.provider }}
URL: {{ edition.ebook_form.url }}<br />
File Format: {{ edition.ebook_form.format }}&nbsp;&nbsp;&nbsp;
License: {{ edition.ebook_form.rights }}<br />
<input type="submit" name="add_ebook" value="add ebook" id="submit" />
</form>
</div>
{% endif %}
{% endfor %} {% endfor %}
</div> </div>
</div> </div>

View File

@ -42,6 +42,7 @@ from regluit.core.goodreads import GoodreadsClient
from regluit.frontend.forms import UserData, ProfileForm, CampaignPledgeForm, GoodreadsShelfLoadingForm from regluit.frontend.forms import UserData, ProfileForm, CampaignPledgeForm, GoodreadsShelfLoadingForm
from regluit.frontend.forms import RightsHolderForm, UserClaimForm, LibraryThingForm, OpenCampaignForm from regluit.frontend.forms import RightsHolderForm, UserClaimForm, LibraryThingForm, OpenCampaignForm
from regluit.frontend.forms import ManageCampaignForm, DonateForm, CampaignAdminForm, EmailShareForm, FeedbackForm from regluit.frontend.forms import ManageCampaignForm, DonateForm, CampaignAdminForm, EmailShareForm, FeedbackForm
from regluit.frontend.forms import EbookForm
from regluit.payment.manager import PaymentManager from regluit.payment.manager import PaymentManager
from regluit.payment.models import Transaction from regluit.payment.models import Transaction
from regluit.payment.parameters import TARGET_TYPE_CAMPAIGN, TARGET_TYPE_DONATION, PAYMENT_TYPE_AUTHORIZATION from regluit.payment.parameters import TARGET_TYPE_CAMPAIGN, TARGET_TYPE_DONATION, PAYMENT_TYPE_AUTHORIZATION
@ -90,13 +91,29 @@ def stub(request):
def work(request, work_id, action='display'): def work(request, work_id, action='display'):
try: try:
work = models.Work.objects.get(id = work_id) work = models.Work.objects.get(id = work_id)
except models.Work.DoesNotExist: except models.Work.DoesNotExist:
try: try:
work = models.WasWork.objects.get(was = work_id).work work = models.WasWork.objects.get(was = work_id).work
except models.WasWork.DoesNotExist: except models.WasWork.DoesNotExist:
raise Http404 raise Http404
if request.method == 'POST' and not request.user.is_anonymous():
activetab = '4'
ebook_form= EbookForm( data = request.POST)
if ebook_form.is_valid():
ebook_form.save()
alert = 'Thanks for adding an ebook to unglue.it!'
else:
alert = ebook_form.errors
else:
alert=''
try:
activetab = request.GET['tab']
if activetab not in ['1', '2', '3', '4']:
activetab = '1';
except:
activetab = '1';
editions = work.editions.all().order_by('-publication_date') editions = work.editions.all().order_by('-publication_date')
campaign = work.last_campaign() campaign = work.last_campaign()
try: try:
@ -109,6 +126,9 @@ def work(request, work_id, action='display'):
pubdate = 'unknown' pubdate = 'unknown'
if not request.user.is_anonymous(): if not request.user.is_anonymous():
claimform = UserClaimForm( request.user, data={'work':work.pk, 'user': request.user.id}) claimform = UserClaimForm( request.user, data={'work':work.pk, 'user': request.user.id})
for edition in editions:
#edition.ebook_form = EbookForm( data = {'user':request.user.id, 'edition':edition.pk })
edition.ebook_form = EbookForm( instance= models.Ebook(user = request.user, edition = edition, provider = 'x' ) )
else: else:
claimform = None claimform = None
if campaign: if campaign:
@ -120,12 +140,6 @@ def work(request, work_id, action='display'):
wishers = work.num_wishes wishers = work.num_wishes
base_url = request.build_absolute_uri("/")[:-1] base_url = request.build_absolute_uri("/")[:-1]
try:
activetab = request.GET['tab']
if activetab not in ['1', '2', '3', '4']:
activetab = '1';
except:
activetab = '1';
#may want to deprecate the following #may want to deprecate the following
if action == 'setup_campaign': if action == 'setup_campaign':
@ -142,6 +156,7 @@ def work(request, work_id, action='display'):
'pubdate': pubdate, 'pubdate': pubdate,
'pledged':pledged, 'pledged':pledged,
'activetab': activetab, 'activetab': activetab,
'alert':alert
}) })
def manage_campaign(request, id): def manage_campaign(request, id):
@ -729,8 +744,8 @@ def supporter(request, supporter_username, template_name):
wishlist = supporter.wishlist wishlist = supporter.wishlist
fromsupport = 1 fromsupport = 1
# querysets for tabs # querysets for tabs
# unglued tab is anything for which there has been a successful campaign OR anything with an existing ebook # unglued tab is anything for which there has been a successful campaign OR anything with an existing ebook
works_unglued = wishlist.works.all().filter(Q(campaigns__status='SUCCESSFUL') | Q(editions__ebooks__isnull=False)).order_by('-num_wishes') works_unglued = wishlist.works.all().filter(Q(campaigns__status='SUCCESSFUL') | Q(editions__ebooks__isnull=False)).order_by('-num_wishes')
# take the set complement of the unglued tab and filter it for active works to get middle tab # take the set complement of the unglued tab and filter it for active works to get middle tab

View File

@ -1,528 +1,77 @@
/* variables and mixins used in multiple less files go here */ .header-text{height:36px;line-height:36px;display:block;text-decoration:none;font-weight:bold;font-size:13px;letter-spacing:-0.05em;}
.header-text { .panelborders{border-width:1px 0px;border-style:solid none;border-color:#FFFFFF;}
height: 36px; .roundedspan{border:1px solid #d4d4d4;-moz-border-radius:7px;-webkit-border-radius:7px;border-radius:7px;padding:1px;color:#fff;margin:0 8px 0 0;display:inline-block;}.roundedspan>span{padding:7px 7px;min-width:15px;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;text-align:center;display:inline-block;}.roundedspan>span .hovertext{display:none;}
line-height: 36px; .roundedspan>span:hover .hovertext{display:inline;}
display: block; .mediaborder{padding:5px;border:solid 5px #EDF3F4;}
text-decoration: none; .google_signup_div{padding:14px 0;}.google_signup_div div{height:24px;line-height:24px;float:left;padding-left:5px;}
font-weight: bold; .google_signup_div img{float:left;height:24px;width:24px;}
font-size: 13px; .actionbuttons{width:auto;height:36px;line-height:36px;background:#8dc63f;-moz-border-radius:32px;-webkit-border-radius:32px;border-radius:32px;color:white;cursor:pointer;font-size:13px;font-weight:bold;padding:0 15px;border:none;margin:5px 0;}
letter-spacing: -0.05em; #js-page-wrap{overflow:hidden;}
} #main-container{margin-top:20px;}
.panelborders { #js-leftcol .jsmodule,.pledge.jsmodule{margin-bottom:10px;}#js-leftcol .jsmodule.rounded .jsmod-content,.pledge.jsmodule.rounded .jsmod-content{-moz-border-radius:20px;-webkit-border-radius:20px;border-radius:20px;background:#edf3f4;color:#3d4e53;padding:10px 20px;font-weight:bold;border:none;margin:0;}#js-leftcol .jsmodule.rounded .jsmod-content.active0,.pledge.jsmodule.rounded .jsmod-content.active0,#js-leftcol .jsmodule.rounded .jsmod-content.active1,.pledge.jsmodule.rounded .jsmod-content.active1{background:#e35351;}
border-width: 1px 0px; #js-leftcol .jsmodule.rounded .jsmod-content.active2,.pledge.jsmodule.rounded .jsmod-content.active2{background:#e18551;}
border-style: solid none; #js-leftcol .jsmodule.rounded .jsmod-content.active3,.pledge.jsmodule.rounded .jsmod-content.active3{background:#e5a956;}
border-color: #FFFFFF; #js-leftcol .jsmodule.rounded .jsmod-content.active4,.pledge.jsmodule.rounded .jsmod-content.active4{background:#efd45e;}
} #js-leftcol .jsmodule.rounded .jsmod-content.active5,.pledge.jsmodule.rounded .jsmod-content.active5{background:#bbcf67;}
.roundedspan { #js-leftcol .jsmodule.rounded .jsmod-content.active6,.pledge.jsmodule.rounded .jsmod-content.active6{background:#8dc63f;}
border: 1px solid #d4d4d4; #js-leftcol .jsmodule.rounded .jsmod-content span,.pledge.jsmodule.rounded .jsmod-content span{display:inline-block;vertical-align:middle;}#js-leftcol .jsmodule.rounded .jsmod-content span.spacer,.pledge.jsmodule.rounded .jsmod-content span.spacer{visibility:none;}
-moz-border-radius: 7px; #js-leftcol .jsmodule.rounded .jsmod-content span.findtheungluers,.pledge.jsmodule.rounded .jsmod-content span.findtheungluers{cursor:pointer;}
-webkit-border-radius: 7px; .jsmodule.pledge{float:left;margin-left:10px;}
border-radius: 7px; .book-detail{float:left;width:100%;clear:both;display:block;}
padding: 1px; .book-detail-img{float:left;margin-right:10px;width:151px;}.book-detail-img img{padding:5px;border:solid 5px #EDF3F4;}
color: #fff; .book-detail-info{float:left;width:309px;}.book-detail-info h2.book-name,.book-detail-info h3.book-author,.book-detail-info h3.book-year{padding:0;margin:0;line-height:normal;}
margin: 0 8px 0 0; .book-detail-info h2.book-name{font-size:18px;text-transform:capitalize;font-weight:bold;color:#3d4e53;}
display: inline-block; .book-detail-info h3.book-author,.book-detail-info h3.book-year{font-size:12px;font-weight:normal;color:#6994a3;}
} .book-detail-info>div{width:100%;clear:both;display:block;overflow:hidden;border-top:1px solid #edf3f4;padding:10px 0;}
.roundedspan > span { .book-detail-info>div.layout{border:none;padding:0;}.book-detail-info>div.layout div.pubinfo{float:left;width:auto;}
padding: 7px 7px; .book-detail-info>div.layout div.btn_support{float:right;}.book-detail-info>div.layout div.btn_support input{background:url("/static/images/btn_bg.png") 0 0 no-repeat;width:104px;height:41px;display:block;color:#fff;font-weight:bold;text-align:center;border:none;padding:0;cursor:pointer;}
min-width: 15px; .book-detail-info>div.layout div.btn_support.modify input{background:url("/static/images/btn_bg_grey.png") 0 0 no-repeat;}
-moz-border-radius: 5px; .book-detail-info .btn_wishlist span{text-align:right;}
-webkit-border-radius: 5px; .book-detail-info .find-book{margin-top:15px;}.book-detail-info .find-book label{float:left;line-height:31px;}
border-radius: 5px; .book-detail-info .find-link{float:right;}.book-detail-info .find-link a{padding:0 0 0 4px;}
text-align: center; .book-detail-info .pledged-info{padding:0;position:relative;}
display: inline-block; .book-detail-info .pledged-group{padding:10px 40px 10px 0;float:left;}
} .book-detail-info .status{position:absolute;top:50%;right:0%;height:25px;margin-top:-12px;}
.roundedspan > span .hovertext { #tabs{border-bottom:4px solid #6994a3;clear:both;float:left;margin-top:10px;width:100%;}#tabs ul.book-list-view{margin-bottom:4px !important;}
display: none; #tabs-1,#tabs-2,#tabs-3,#tabs-4{display:none;}
} #tabs-1.active,#tabs-2.active,#tabs-3.active,#tabs-4.active{display:inherit;}
.roundedspan > span:hover .hovertext { #tabs-2 textarea{width:95%;}
display: inline; ul.tabs{float:left;padding:0;margin:0;list-style:none;width:100%;}ul.tabs li{float:left;height:46px;line-height:46px;padding-right:2px;width:116px;}ul.tabs li.tabs4{padding-right:0px;}
} ul.tabs li a{height:46px;line-height:46px;display:block;text-align:center;padding:0 10px;min-width:80px;-moz-border-radius:7px 7px 0 0;-webkit-border-radius:7px 7px 0 0;border-radius:7px 7px 0 0;background:#d6dde0;color:#3d4e53;}ul.tabs li a:hover{text-decoration:none;}
.mediaborder { ul.tabs li a:hover,ul.tabs li.active a{background:#6994a3;color:#fff;}
padding: 5px; #js-rightcol{float:right;width:235px;margin-bottom:20px;}#js-rightcol h3.jsmod-title{background:#a7c1ca;-moz-border-radius:10px;-webkit-border-radius:10px;border-radius:10px;padding:10px;height:auto;font-style:normal;font-size:14px;margin:0 0 10px 0;color:white;}#js-rightcol h3.jsmod-title span{padding:0;color:#fff;font-style:normal;}
border: solid 5px #EDF3F4; #js-rightcol .jsmodule{margin-bottom:10px;}
} .js-rightcol-pad{border:1px solid #d6dde0;-moz-border-radius:10px;-webkit-border-radius:10px;border-radius:10px;padding:10px;}
.google_signup_div { #js-maincol{float:left;width:470px;margin:0 10px;}#js-maincol div#content-block{background:none;padding:0;}
padding: 14px 0; div#content-block-content{padding-left:5px;}
} .tabs-content{padding-right:5px;}.tabs-content iframe{padding:5px;border:solid 5px #EDF3F4;}
.google_signup_div div { .tabs-content form{margin-left:-5px;}
height: 24px; ul.social a:hover{text-decoration:none;}
line-height: 24px; ul.social li{padding:5px 0 5px 30px;height:28px;line-height:28px;}ul.social li.facebook{background:url("/static/images/icons/facebook.png") 10px center no-repeat;cursor:pointer;}ul.social li.facebook span{padding-left:10px;}
float: left; ul.social li.facebook:hover{background:#8dc63f url("/static/images/icons/facebook-hover.png") 10px center no-repeat;}ul.social li.facebook:hover span{color:#fff;}
padding-left: 5px; ul.social li.twitter{background:url("/static/images/icons/twitter.png") 10px center no-repeat;cursor:pointer;}ul.social li.twitter span{padding-left:10px;}
} ul.social li.twitter:hover{background:#8dc63f url("/static/images/icons/twitter-hover.png") 10px center no-repeat;}ul.social li.twitter:hover span{color:#fff;}
.google_signup_div img { ul.social li.email{background:url("/static/images/icons/email.png") 10px center no-repeat;cursor:pointer;}ul.social li.email span{padding-left:10px;}
float: left; ul.social li.email:hover{background:#8dc63f url("/static/images/icons/email-hover.png") 10px center no-repeat;}ul.social li.email:hover span{color:#fff;}
height: 24px; ul.social li.embed{background:url("/static/images/icons/embed.png") 10px center no-repeat;cursor:pointer;}ul.social li.embed span{padding-left:10px;}
width: 24px; ul.social li.embed:hover{background:#8dc63f url("/static/images/icons/embed-hover.png") 10px center no-repeat;}ul.social li.embed:hover span{color:#fff;}
} #widgetcode{display:none;border:1px solid #d6dde0;-moz-border-radius:10px;-webkit-border-radius:10px;border-radius:10px;padding:10px;}
.actionbuttons { ul.support li{border-bottom:1px solid #d6dde0;padding:10px 5px 10px 10px;background:url("/static/images/icons/pledgearrow.png") 98% center no-repeat;}ul.support li span{display:block;padding-right:10px;}ul.support li span.menu-item-price{font-size:18px;}
width: auto; ul.support li:hover{color:#fff;background:#8dc63f url("/static/images/icons/pledgearrow-hover.png") 98% center no-repeat;}ul.support li:hover a{color:#fff;text-decoration:none;}
height: 36px; .work_supporter_nocomment{height:50px;margin-top:5px;vertical-align:middle;margin-left:-5px;}
line-height: 36px; .work_supporter_avatar{float:left;}
background: #8dc63f; .work_supporter_name{height:50px;line-height:50px;float:left;}
-moz-border-radius: 32px; a{color:#3d4e53;font-size:12px;}
-webkit-border-radius: 32px; .add-wishlist,.add-wishlist-workpage,.remove-wishlist-workpage,.remove-wishlist,.on-wishlist,.create-account{float:right;cursor:pointer;}.add-wishlist span,.add-wishlist-workpage span,.remove-wishlist-workpage span,.remove-wishlist span,.on-wishlist span,.create-account span{font-weight:normal;color:#3d4e53;text-transform:none;padding-left:20px;}.add-wishlist span.on-wishlist,.add-wishlist-workpage span.on-wishlist,.remove-wishlist-workpage span.on-wishlist,.remove-wishlist span.on-wishlist,.on-wishlist span.on-wishlist,.create-account span.on-wishlist{background:url("/static/images/checkmark_small.png") left center no-repeat;cursor:default;}
border-radius: 32px; .add-wishlist span,.add-wishlist-workpage span,.create-account span{background:url("/static/images/booklist/add-wishlist.png") left center no-repeat;}
color: white; .remove-wishlist-workpage span,.remove-wishlist span{background:url("/static/images/booklist/remove-wishlist-blue.png") left center no-repeat;}
cursor: pointer; .editions{clear:both;}.editions div{float:left;padding-bottom:5px;}
font-size: 13px; .editions .image{width:60px;overflow:hidden;}
font-weight: bold; .editions .metadata{display:block;overflow:hidden;margin-left:5px;}
padding: 0 15px; .editions a:hover{text-decoration:underline;}
border: none; .thank-you{font-size:20px;}
margin: 5px 0; .work_supporter{height:auto;min-height:50px;margin-top:5px;vertical-align:middle;margin-left:-5px;}
} .work_supporter_avatar{margin-right:5px;}.work_supporter_avatar img{-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;}
#js-page-wrap { .more_edition{display:none;clear:both;padding-bottom:10px;padding-left:60px;}
overflow: hidden; .show_more_edition:hover{text-decoration:underline;}
} .show_more_edition{text-align:right;}
#main-container {
margin-top: 20px;
}
#js-leftcol .jsmodule, .pledge.jsmodule {
margin-bottom: 10px;
}
#js-leftcol .jsmodule.rounded .jsmod-content, .pledge.jsmodule.rounded .jsmod-content {
-moz-border-radius: 20px;
-webkit-border-radius: 20px;
border-radius: 20px;
background: #edf3f4;
color: #3d4e53;
padding: 10px 20px;
font-weight: bold;
border: none;
margin: 0;
}
#js-leftcol .jsmodule.rounded .jsmod-content.active0,
.pledge.jsmodule.rounded .jsmod-content.active0,
#js-leftcol .jsmodule.rounded .jsmod-content.active1,
.pledge.jsmodule.rounded .jsmod-content.active1 {
background: #e35351;
}
#js-leftcol .jsmodule.rounded .jsmod-content.active2, .pledge.jsmodule.rounded .jsmod-content.active2 {
background: #e18551;
}
#js-leftcol .jsmodule.rounded .jsmod-content.active3, .pledge.jsmodule.rounded .jsmod-content.active3 {
background: #e5a956;
}
#js-leftcol .jsmodule.rounded .jsmod-content.active4, .pledge.jsmodule.rounded .jsmod-content.active4 {
background: #efd45e;
}
#js-leftcol .jsmodule.rounded .jsmod-content.active5, .pledge.jsmodule.rounded .jsmod-content.active5 {
background: #bbcf67;
}
#js-leftcol .jsmodule.rounded .jsmod-content.active6, .pledge.jsmodule.rounded .jsmod-content.active6 {
background: #8dc63f;
}
#js-leftcol .jsmodule.rounded .jsmod-content span, .pledge.jsmodule.rounded .jsmod-content span {
display: inline-block;
vertical-align: middle;
}
#js-leftcol .jsmodule.rounded .jsmod-content span.spacer, .pledge.jsmodule.rounded .jsmod-content span.spacer {
visibility: none;
}
#js-leftcol .jsmodule.rounded .jsmod-content span.findtheungluers, .pledge.jsmodule.rounded .jsmod-content span.findtheungluers {
cursor: pointer;
}
.jsmodule.pledge {
float: left;
margin-left: 10px;
}
.book-detail {
float: left;
width: 100%;
clear: both;
display: block;
}
.book-detail-img {
float: left;
margin-right: 10px;
width: 151px;
}
.book-detail-img img {
padding: 5px;
border: solid 5px #EDF3F4;
}
.book-detail-info {
float: left;
/* if we want to nix the explore bar, width should be 544ish */
width: 309px;
}
.book-detail-info h2.book-name, .book-detail-info h3.book-author, .book-detail-info h3.book-year {
padding: 0;
margin: 0;
line-height: normal;
}
.book-detail-info h2.book-name {
font-size: 18px;
text-transform: capitalize;
font-weight: bold;
color: #3d4e53;
}
.book-detail-info h3.book-author, .book-detail-info h3.book-year {
font-size: 12px;
font-weight: normal;
color: #6994a3;
}
.book-detail-info > div {
width: 100%;
clear: both;
display: block;
overflow: hidden;
border-top: 1px solid #edf3f4;
padding: 10px 0;
}
.book-detail-info > div.layout {
border: none;
padding: 0;
}
.book-detail-info > div.layout div.pubinfo {
float: left;
width: auto;
}
.book-detail-info > div.layout div.btn_support {
float: right;
}
.book-detail-info > div.layout div.btn_support input {
background: url("/static/images/btn_bg.png") 0 0 no-repeat;
width: 104px;
height: 41px;
display: block;
color: #fff;
font-weight: bold;
text-align: center;
border: none;
padding: 0;
cursor: pointer;
}
.book-detail-info > div.layout div.btn_support.modify input {
background: url("/static/images/btn_bg_grey.png") 0 0 no-repeat;
}
.book-detail-info .btn_wishlist span {
text-align: right;
}
.book-detail-info .find-book {
margin-top: 15px;
}
.book-detail-info .find-book label {
float: left;
line-height: 31px;
}
.book-detail-info .find-link {
float: right;
}
.book-detail-info .find-link a {
padding: 0 0 0 4px;
}
.book-detail-info .pledged-info {
padding: 0;
position: relative;
}
.book-detail-info .pledged-group {
padding: 10px 40px 10px 0;
float: left;
}
.book-detail-info .status {
position: absolute;
top: 50%;
right: 0%;
height: 25px;
margin-top: -12px;
}
#tabs {
border-bottom: 4px solid #6994a3;
clear: both;
float: left;
margin-top: 10px;
width: 100%;
}
#tabs ul.book-list-view {
margin-bottom: 4px !important;
}
#tabs-1,
#tabs-2,
#tabs-3,
#tabs-4 {
display: none;
}
#tabs-1.active,
#tabs-2.active,
#tabs-3.active,
#tabs-4.active {
display: inherit;
}
#tabs-2 textarea {
width: 95%;
}
ul.tabs {
float: left;
padding: 0;
margin: 0;
list-style: none;
width: 100%;
}
ul.tabs li {
float: left;
height: 46px;
line-height: 46px;
padding-right: 2px;
width: 116px;
}
ul.tabs li.tabs4 {
padding-right: 0px;
}
ul.tabs li a {
height: 46px;
line-height: 46px;
display: block;
text-align: center;
padding: 0 10px;
min-width: 80px;
-moz-border-radius: 7px 7px 0 0;
-webkit-border-radius: 7px 7px 0 0;
border-radius: 7px 7px 0 0;
background: #d6dde0;
color: #3d4e53;
}
ul.tabs li a:hover {
text-decoration: none;
}
ul.tabs li a:hover, ul.tabs li.active a {
background: #6994a3;
color: #fff;
}
#js-rightcol {
float: right;
width: 235px;
margin-bottom: 20px;
}
#js-rightcol h3.jsmod-title {
background: #a7c1ca;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
padding: 10px;
height: auto;
font-style: normal;
font-size: 14px;
margin: 0 0 10px 0;
color: white;
}
#js-rightcol h3.jsmod-title span {
padding: 0;
color: #fff;
font-style: normal;
}
#js-rightcol .jsmodule {
margin-bottom: 10px;
}
.js-rightcol-pad {
border: 1px solid #d6dde0;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
padding: 10px;
}
#js-maincol {
float: left;
/* If we want to nuke the explore column, width should be 705ish */
width: 470px;
margin: 0 10px;
}
#js-maincol div#content-block {
background: none;
padding: 0;
}
div#content-block-content {
padding-left: 5px;
}
.tabs-content {
padding-right: 5px;
}
.tabs-content iframe {
padding: 5px;
border: solid 5px #EDF3F4;
}
.tabs-content form {
margin-left: -5px;
}
ul.social a:hover {
text-decoration: none;
}
ul.social li {
padding: 5px 0 5px 30px;
height: 28px;
line-height: 28px;
}
ul.social li.facebook {
background: url("/static/images/icons/facebook.png") 10px center no-repeat;
cursor: pointer;
}
ul.social li.facebook span {
padding-left: 10px;
}
ul.social li.facebook:hover {
background: #8dc63f url("/static/images/icons/facebook-hover.png") 10px center no-repeat;
}
ul.social li.facebook:hover span {
color: #fff;
}
ul.social li.twitter {
background: url("/static/images/icons/twitter.png") 10px center no-repeat;
cursor: pointer;
}
ul.social li.twitter span {
padding-left: 10px;
}
ul.social li.twitter:hover {
background: #8dc63f url("/static/images/icons/twitter-hover.png") 10px center no-repeat;
}
ul.social li.twitter:hover span {
color: #fff;
}
ul.social li.email {
background: url("/static/images/icons/email.png") 10px center no-repeat;
cursor: pointer;
}
ul.social li.email span {
padding-left: 10px;
}
ul.social li.email:hover {
background: #8dc63f url("/static/images/icons/email-hover.png") 10px center no-repeat;
}
ul.social li.email:hover span {
color: #fff;
}
ul.social li.embed {
background: url("/static/images/icons/embed.png") 10px center no-repeat;
cursor: pointer;
}
ul.social li.embed span {
padding-left: 10px;
}
ul.social li.embed:hover {
background: #8dc63f url("/static/images/icons/embed-hover.png") 10px center no-repeat;
}
ul.social li.embed:hover span {
color: #fff;
}
#widgetcode {
display: none;
border: 1px solid #d6dde0;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
padding: 10px;
}
ul.support li {
border-bottom: 1px solid #d6dde0;
padding: 10px 5px 10px 10px;
background: url("/static/images/icons/pledgearrow.png") 98% center no-repeat;
}
ul.support li span {
display: block;
padding-right: 10px;
}
ul.support li span.menu-item-price {
font-size: 18px;
}
ul.support li:hover {
color: #fff;
background: #8dc63f url("/static/images/icons/pledgearrow-hover.png") 98% center no-repeat;
}
ul.support li:hover a {
color: #fff;
text-decoration: none;
}
.work_supporter_nocomment {
height: 50px;
margin-top: 5px;
vertical-align: middle;
margin-left: -5px;
}
.work_supporter_avatar {
float: left;
}
.work_supporter_name {
height: 50px;
line-height: 50px;
float: left;
}
/* this line differs from sitewide.css. should it? */
a {
color: #3d4e53;
font-size: 12px;
}
.add-wishlist,
.add-wishlist-workpage,
.remove-wishlist-workpage,
.remove-wishlist,
.on-wishlist,
.create-account {
float: right;
cursor: pointer;
}
.add-wishlist span,
.add-wishlist-workpage span,
.remove-wishlist-workpage span,
.remove-wishlist span,
.on-wishlist span,
.create-account span {
font-weight: normal;
color: #3d4e53;
text-transform: none;
padding-left: 20px;
}
.add-wishlist span.on-wishlist,
.add-wishlist-workpage span.on-wishlist,
.remove-wishlist-workpage span.on-wishlist,
.remove-wishlist span.on-wishlist,
.on-wishlist span.on-wishlist,
.create-account span.on-wishlist {
background: url("/static/images/checkmark_small.png") left center no-repeat;
cursor: default;
}
.add-wishlist span, .add-wishlist-workpage span, .create-account span {
background: url("/static/images/booklist/add-wishlist.png") left center no-repeat;
}
.remove-wishlist-workpage span, .remove-wishlist span {
background: url("/static/images/booklist/remove-wishlist-blue.png") left center no-repeat;
}
.editions {
clear: both;
}
.editions div {
float: left;
padding-bottom: 5px;
}
.editions .image {
width: 60px;
overflow: hidden;
}
.editions .metadata {
display: block;
overflow: hidden;
margin-left: 5px;
}
.editions a:hover {
text-decoration: underline;
}
.thank-you {
font-size: 20px;
}
.work_supporter {
height: auto;
min-height: 50px;
margin-top: 5px;
vertical-align: middle;
margin-left: -5px;
}
.work_supporter_avatar {
margin-right: 5px;
}
.work_supporter_avatar img {
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
}