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,14 +227,15 @@ 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(parse_qs(urlparse(ebook_epub.url).query).get("id"), ['U3FXAAAAYAAJ'])
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]
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(parse_qs(urlparse(ebook_pdf.url).query).get("id"), ['U3FXAAAAYAAJ'])
self.assertEqual(parse_qs(urlparse(ebook_pdf.url).query).get("output"), ['pdf'])
self.assertEqual(ebook_pdf.provider, 'google')
self.assertEqual(edition.public_domain, True)
self.assertEqual(ebook_pdf.provider, 'Google Books')
self.assertEqual(edition.public_domain, True)
w = edition.work
self.assertEqual(w.first_epub().url, ebook_epub.url)
@ -242,6 +243,9 @@ class BookLoaderTests(TestCase):
self.assertEqual(w.first_epub_url(), ebook_epub.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):
# this edition lacks an ebook, but we should still be able to load it
e = bookloader.add_by_isbn('0465019358')

View File

@ -11,14 +11,29 @@ from decimal import Decimal as D
from selectable.forms import AutoCompleteSelectMultipleWidget,AutoCompleteSelectMultipleField
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
import logging
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 ):
class ClaimForm(forms.ModelForm):
i_agree=forms.BooleanField()
@ -194,30 +209,30 @@ class CampaignAdminForm(forms.Form):
pass
class EmailShareForm(forms.Form):
recipient = forms.EmailField()
sender = forms.EmailField(widget=forms.HiddenInput())
subject = forms.CharField(max_length=100)
message = forms.CharField(widget=forms.Textarea())
# 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
# and may iterate several times as it catches user errors, losing URL info
next = forms.CharField(widget=forms.HiddenInput())
recipient = forms.EmailField()
sender = forms.EmailField(widget=forms.HiddenInput())
subject = forms.CharField(max_length=100)
message = forms.CharField(widget=forms.Textarea())
# 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
# and may iterate several times as it catches user errors, losing URL info
next = forms.CharField(widget=forms.HiddenInput())
class FeedbackForm(forms.Form):
sender = forms.EmailField(widget=forms.TextInput(attrs={'size':50}), label="Your email")
subject = forms.CharField(max_length=500, widget=forms.TextInput(attrs={'size':50}))
message = forms.CharField(widget=forms.Textarea())
page = forms.CharField(widget=forms.HiddenInput())
notarobot = forms.IntegerField(label="Please prove you're not a robot")
answer = forms.IntegerField(widget=forms.HiddenInput())
num1 = forms.IntegerField(widget=forms.HiddenInput())
num2 = forms.IntegerField(widget=forms.HiddenInput())
def clean(self):
cleaned_data = self.cleaned_data
notarobot = str(cleaned_data.get("notarobot"))
answer = str(cleaned_data.get("answer"))
if notarobot!=answer:
raise forms.ValidationError(_("Whoops, try that sum again."))
return cleaned_data
sender = forms.EmailField(widget=forms.TextInput(attrs={'size':50}), label="Your email")
subject = forms.CharField(max_length=500, widget=forms.TextInput(attrs={'size':50}))
message = forms.CharField(widget=forms.Textarea())
page = forms.CharField(widget=forms.HiddenInput())
notarobot = forms.IntegerField(label="Please prove you're not a robot")
answer = forms.IntegerField(widget=forms.HiddenInput())
num1 = forms.IntegerField(widget=forms.HiddenInput())
num2 = forms.IntegerField(widget=forms.HiddenInput())
def clean(self):
cleaned_data = self.cleaned_data
notarobot = str(cleaned_data.get("notarobot"))
answer = str(cleaned_data.get("answer"))
if notarobot!=answer:
raise forms.ValidationError(_("Whoops, try that sum again."))
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 panelback side2">
<div class="greenpanel2">
@ -6,17 +6,17 @@
<div class="unglued_white">
{% 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>
</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' %}
<b>UNGLUED!</b>
<p><b>On:</b> {{ deadline|date:"M d, Y" }}</p>
<p><b>Raised:</b> {{ work.last_campaign.current_total }}</p>
</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' %}
<b>UNGLUE IT!</b>
@ -123,14 +123,11 @@
<div class="listview panelfront side1 icons">
{% 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>
{% else %}{% if work.first_pdf_url or work.first_epub_url %}
{% else %}{% if work.first_ebook %}
<span class="listview boolist-ebook">
{% if work.first_epub_url %}
<a href="{{ work.first_epub_url }}">EPUB</a>
{% endif %}
{% if work.first_pdf_url %}
<a href="{{ work.first_pdf_url }}">PDF</a>
{% endif %}
{% for ebook in work.ebooks|slice:":3" %}
<a href="ebook.url">{{ ebook.format }}</a>
{% endfor %}
</span>
{% else %}

View File

@ -19,7 +19,14 @@ jQuery(document).ready(function(){
jQuery('#embed').click(function(){
jQuery('div#widgetcode').toggle();
});
jQuery('.show_more_edition').click(function(){
jQuery(this).html('less...');
jQuery(this).next().toggle();
});
});
</script>
{% endblock %}
@ -31,7 +38,7 @@ jQuery(document).ready(function(){
<div class="jsmodule rounded">
<div class="jsmod-content{% if status == 'ACTIVE' %} active{{ work.percent_unglued}}{% endif %}">
<span>
{% if work.first_epub_url or work.first_pdf_url %}
{% if work.first_ebook %}
AVAILABLE!
{% else %}{% if work.last_campaign %}
{% if status == 'ACTIVE' %}
@ -106,7 +113,7 @@ jQuery(document).ready(function(){
</div>
</div>
<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 %}
1 Ungluer is
{% else %}
@ -127,17 +134,14 @@ jQuery(document).ready(function(){
{% endif %} wished for this Work
{% endif %}{% endif %}
</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 class="btn_wishlist" id="wishlist_actions">
{% if work.first_epub_url or work.first_pdf_url %}
{% if work.first_ebook %}
<span class="boolist-ebook">
{% if work.first_epub_url %}
<a href="{{ work.first_epub_url }}">EPUB</a>
{% endif %}
{% if work.first_pdf_url %}
<a href="{{ work.first_pdf_url }}">PDF</a>
{% endif %}
{% for ebook in work.ebooks %}
<a href="ebook.url">{{ ebook.format }}</a> {{ebook.rights}} at {{ebook.provider}}<br />
{% endfor %}
</span>
{% endif %}
{% if request.user.is_anonymous %}
@ -154,7 +158,7 @@ jQuery(document).ready(function(){
</div>
{% else %}
<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>
{% endif %}{% endif %}{% endif %}
</div>
@ -224,7 +228,7 @@ jQuery(document).ready(function(){
<h4>Last campaign details</h4>
{{ work.last_campaign.details|safe }}
{% endif %}
<h4> Rights Information </h4>
{% if work.claim.count %}
<p> This work has been claimed by:</p>
@ -271,10 +275,11 @@ jQuery(document).ready(function(){
{% endif %}
<h4>Editions</h4>
{% if alert %}<div class="alert"><b>Ebook Contribution:</b><br />{{ alert }}</div>{% endif %}
{% 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="metadata">{{edition.publisher}}<br />
{{edition.publication_date}}<br />
<div class="metadata" id="edition_{{edition.id}}">Publisher: {{edition.publisher}}<br />
Published: {{edition.publication_date}}<br />
{% with edition.isbn_13 as isbn %}
{% if isbn %}
ISBN: {{ isbn }}<br />
@ -284,6 +289,26 @@ jQuery(document).ready(function(){
{% 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>
</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 %}
</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 RightsHolderForm, UserClaimForm, LibraryThingForm, OpenCampaignForm
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.models import Transaction
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'):
try:
work = models.Work.objects.get(id = work_id)
work = models.Work.objects.get(id = work_id)
except models.Work.DoesNotExist:
try:
work = models.WasWork.objects.get(was = work_id).work
except models.WasWork.DoesNotExist:
raise Http404
try:
work = models.WasWork.objects.get(was = work_id).work
except models.WasWork.DoesNotExist:
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')
campaign = work.last_campaign()
try:
@ -109,6 +126,9 @@ def work(request, work_id, action='display'):
pubdate = 'unknown'
if not request.user.is_anonymous():
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:
claimform = None
if campaign:
@ -120,12 +140,6 @@ def work(request, work_id, action='display'):
wishers = work.num_wishes
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
if action == 'setup_campaign':
@ -142,6 +156,7 @@ def work(request, work_id, action='display'):
'pubdate': pubdate,
'pledged':pledged,
'activetab': activetab,
'alert':alert
})
def manage_campaign(request, id):
@ -729,8 +744,8 @@ def supporter(request, supporter_username, template_name):
wishlist = supporter.wishlist
fromsupport = 1
# querysets for tabs
# unglued tab is anything for which there has been a successful campaign OR anything with an existing ebook
# querysets for tabs
# 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')
# 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;
}
.panelborders {
border-width: 1px 0px;
border-style: solid none;
border-color: #FFFFFF;
}
.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;
}
.roundedspan > span:hover .hovertext {
display: inline;
}
.mediaborder {
padding: 5px;
border: solid 5px #EDF3F4;
}
.google_signup_div {
padding: 14px 0;
}
.google_signup_div div {
height: 24px;
line-height: 24px;
float: left;
padding-left: 5px;
}
.google_signup_div img {
float: left;
height: 24px;
width: 24px;
}
.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;
}
#js-page-wrap {
overflow: hidden;
}
#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;
}
.header-text{height:36px;line-height:36px;display:block;text-decoration:none;font-weight:bold;font-size:13px;letter-spacing:-0.05em;}
.panelborders{border-width:1px 0px;border-style:solid none;border-color:#FFFFFF;}
.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;}
.roundedspan>span:hover .hovertext{display:inline;}
.mediaborder{padding:5px;border:solid 5px #EDF3F4;}
.google_signup_div{padding:14px 0;}.google_signup_div div{height:24px;line-height:24px;float:left;padding-left:5px;}
.google_signup_div img{float:left;height:24px;width:24px;}
.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;}
#js-page-wrap{overflow:hidden;}
#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;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;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;}
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;}
.more_edition{display:none;clear:both;padding-bottom:10px;padding-left:60px;}
.show_more_edition:hover{text-decoration:underline;}
.show_more_edition{text-align:right;}