From fec7f33d9ea61c5a596e00a16542e5d7d97bf620 Mon Sep 17 00:00:00 2001 From: eric Date: Wed, 12 Dec 2012 22:35:35 -0500 Subject: [PATCH 1/6] staff only UI for merging works [finish #39297681] staff-only link in rights tab of every work! --- core/lookups.py | 20 +++++++++++++-- frontend/forms.py | 34 ++++++++++++++++++++++++-- frontend/templates/merge.html | 35 +++++++++++++++++++++++++++ frontend/templates/work.html | 3 +++ frontend/templates/workbox.html | 16 ++++++++++++ frontend/urls.py | 3 ++- frontend/views.py | 43 ++++++++++++++++++++++++++++++++- 7 files changed, 148 insertions(+), 6 deletions(-) create mode 100644 frontend/templates/merge.html create mode 100644 frontend/templates/workbox.html diff --git a/core/lookups.py b/core/lookups.py index 0a4c5203..0eb2dbea 100644 --- a/core/lookups.py +++ b/core/lookups.py @@ -2,9 +2,25 @@ from selectable.base import ModelLookup from selectable.registry import registry from django.contrib.auth.models import User +from regluit.core.models import Work class OwnerLookup(ModelLookup): model = User search_fields = ('username__icontains',) - -registry.register(OwnerLookup) \ No newline at end of file + +class WorkLookup(ModelLookup): + model = Work + search_fields = ('title__istartswith',) + filters = {'language': 'en', } + def get_item_label(self,item): + return "%s (%s)"%(item.title,item.id) + + def get_query(self, request, term): + results = super(WorkLookup, self).get_query(request, term) + language = request.GET.get('language', 'en') + results = results.filter(language=language) + return results + + +registry.register(OwnerLookup) +registry.register(WorkLookup) \ No newline at end of file diff --git a/frontend/forms.py b/frontend/forms.py index eba95246..be98311a 100644 --- a/frontend/forms.py +++ b/frontend/forms.py @@ -13,8 +13,8 @@ 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, Ebook, Edition, PledgeExtra -from regluit.core.lookups import OwnerLookup +from regluit.core.models import UserProfile, RightsHolder, Claim, Campaign, Premium, Ebook, Edition, PledgeExtra, Work +from regluit.core.lookups import OwnerLookup, WorkLookup from regluit.utils.localdatetime import now @@ -208,6 +208,36 @@ def getTransferCreditForm(maximum, data=None, *args, **kwargs ): ) return TransferCreditForm( data=data ) + +class WorkForm(forms.Form): + other_work = forms.ModelChoiceField(queryset=Work.objects.all(), + widget=forms.HiddenInput(), + required=True, + error_messages={'required': 'Missing work to merge with.'}, + ) + work=None + + def clean_other_work(self): + if self.cleaned_data["other_work"].id== self.work.id: + raise forms.ValidationError(_("You can't merge a work into itself")) + return self.cleaned_data["other_work"] + + def __init__(self, work=None, *args, **kwargs): + super(WorkForm, self).__init__(*args, **kwargs) + self.work=work + +class OtherWorkForm(WorkForm): + other_work = AutoCompleteSelectField( + WorkLookup, + label='Other Work', + widget=AutoCompleteSelectWidget(WorkLookup), + required=True, + error_messages={'required': 'Missing work to merge with.'}, + ) + + def __init__(self, *args, **kwargs): + super(OtherWorkForm, self).__init__(*args, **kwargs) + self.fields['other_work'].widget.update_query_parameters({'language':self.work.language}) class EditManagersForm(forms.ModelForm): managers = AutoCompleteSelectMultipleField( diff --git a/frontend/templates/merge.html b/frontend/templates/merge.html new file mode 100644 index 00000000..e1ea1e0c --- /dev/null +++ b/frontend/templates/merge.html @@ -0,0 +1,35 @@ +{% extends "basedocumentation.html" %} + +{% block extra_extra_head %} + +{{ form.media.css }} + + +{{ form.media.js }} +{% endblock %} + +{% block doccontent %} +{% if merge_complete %} +

Merge {{ old_work_id }} into {{ work.id }} Complete

+ {% include 'workbox.html' %} +{% else %} +

Merge Works

+
+ {% csrf_token %} + {{ form.as_p }} +

Merge this work...

+ {% if other_work %} + {% with other_work as work%} + {% include 'workbox.html' %} + {% endwith %} + {% endif %} +

... into the current work

+ {% include 'workbox.html' %} + {% if other_work %} + + {% else %} + + {% endif %} +
+{% endif %} +{% endblock %} \ No newline at end of file diff --git a/frontend/templates/work.html b/frontend/templates/work.html index bd83254d..7ef54423 100644 --- a/frontend/templates/work.html +++ b/frontend/templates/work.html @@ -321,6 +321,9 @@ $j(document).ready(function(){ {% endif %}

If you'd like to contact us regarding rights for this work, please email rights@gluejar.com.

+ {% if user.is_staff %}

Related Works

+ Merge other works into this one
+ {% endif %} {% if work.subjects.all.count > 0 %}

Subjects

diff --git a/frontend/templates/workbox.html b/frontend/templates/workbox.html new file mode 100644 index 00000000..67b849a2 --- /dev/null +++ b/frontend/templates/workbox.html @@ -0,0 +1,16 @@ +
+ {{ work.title }} # {{work.id }}
+ Language: {{ work.language }}
+ Editions:
    + {% for edition in work.editions.all %} +
  1. +
    {{ edition.title }}, published by {{edition.publisher}} in {{ edition.publication_date }} with authors + {% for author in edition.authors.all %} + {{author}}, + {% endfor %} + +
    +
  2. + {% endfor %} +
+
diff --git a/frontend/urls.py b/frontend/urls.py index 0dd49d24..c3a6c56d 100644 --- a/frontend/urls.py +++ b/frontend/urls.py @@ -10,7 +10,7 @@ from regluit.core.feeds import SupporterWishlistFeed from regluit.core.models import Campaign from regluit.frontend.views import GoodreadsDisplayView, LibraryThingView, PledgeView, PledgeCompleteView, PledgeCancelView, PledgeRechargeView, FAQView from regluit.frontend.views import CampaignListView, WorkListView, UngluedListView, InfoPageView, InfoLangView, DonationView, FundPledgeView -from regluit.frontend.views import NonprofitCampaign, DonationCredit, PledgeModifiedView, ManageAccount +from regluit.frontend.views import NonprofitCampaign, DonationCredit, PledgeModifiedView, ManageAccount, MergeView urlpatterns = patterns( "regluit.frontend.views", @@ -49,6 +49,7 @@ urlpatterns = patterns( url(r"^work/(?P\d+)/lockss/$", "lockss", name="lockss"), url(r"^lockss/(?P\d+)/$", "lockss_manifest", name="lockss_manifest"), url(r"^work/(?P\d+)/download/$", "download", name="download"), + url(r"^work/(?P\d+)/merge/$", login_required(MergeView.as_view()), name="merge"), url(r"^work/\d+/acks/images/(?P[\w\.]*)$", "static_redirect_view",{'dir': 'images'}), url(r"^work/(?P\d+)/librarything/$", "work_librarything", name="work_librarything"), url(r"^work/(?P\d+)/goodreads/$", "work_goodreads", name="work_goodreads"), diff --git a/frontend/views.py b/frontend/views.py index 28b256e7..8b919f74 100755 --- a/frontend/views.py +++ b/frontend/views.py @@ -44,11 +44,12 @@ from regluit.core import models, bookloader, librarything from regluit.core import userlists from regluit.core.search import gluejar_search from regluit.core.goodreads import GoodreadsClient +from regluit.core.bookloader import merge_works from regluit.frontend.forms import UserData, UserEmail, ProfileForm, CampaignPledgeForm, GoodreadsShelfLoadingForm from regluit.frontend.forms import RightsHolderForm, UserClaimForm, LibraryThingForm, OpenCampaignForm from regluit.frontend.forms import getManageCampaignForm, DonateForm, CampaignAdminForm, EmailShareForm, FeedbackForm from regluit.frontend.forms import EbookForm, CustomPremiumForm, EditManagersForm, EditionForm, PledgeCancelForm -from regluit.frontend.forms import getTransferCreditForm, CCForm, CloneCampaignForm, PlainCCForm +from regluit.frontend.forms import getTransferCreditForm, CCForm, CloneCampaignForm, PlainCCForm, WorkForm, OtherWorkForm from regluit.payment.manager import PaymentManager from regluit.payment.models import Transaction, Account from regluit.payment import baseprocessor @@ -568,6 +569,46 @@ class CampaignListView(FilterableListView): context['facet'] =self.kwargs['facet'] return context +class MergeView(FormView): + template_name="merge.html" + work=None + + def dispatch(self, request, *args, **kwargs): + if not request.user.is_staff: + return render(request, "admins_only.html") + else: + return super(MergeView, self).dispatch(request, *args, **kwargs) + + def get_context_data(self, **kwargs): + context = super(MergeView, self).get_context_data(**kwargs) + context['work']=self.work + return context + + def get_form_class(self): + if self.request.method == 'POST' and self.request.POST.has_key('confirm_merge_works'): + return WorkForm + else: + return OtherWorkForm + + def get_form_kwargs(self): + self.work = get_object_or_404(models.Work, id=self.kwargs["work_id"]) + form_kwargs= {'work':self.work} + if self.request.method == 'POST': + form_kwargs.update({'data':self.request.POST}) + return form_kwargs + + def form_valid(self, form): + other_work=form.cleaned_data['other_work'] + context=self.get_context_data() + if self.request.POST.has_key('confirm_merge_works'): + context['old_work_id']=other_work.id + merge_works(self.work,other_work,self.request.user) + context['merge_complete']=True + else: + context['form']=WorkForm(initial={'other_work':other_work}) + context['other_work']=other_work + return render(self.request, self.template_name, context) + class DonationView(TemplateView): template_name = "donation.html" From 575d34d968061163b84e717b9eb7ed598b40c0e8 Mon Sep 17 00:00:00 2001 From: thatandromeda Date: Thu, 13 Dec 2012 09:51:36 -0500 Subject: [PATCH 2/6] Update frontend/templates/base.html --- frontend/templates/base.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/templates/base.html b/frontend/templates/base.html index 6f9b4b4d..9aa99427 100644 --- a/frontend/templates/base.html +++ b/frontend/templates/base.html @@ -139,7 +139,7 @@ {% block news %}
- We unglued one book. Amazon shut us down. Now we're back. Help us unglue five more books!
+ We've unglued two books. Help us unglue four more!
{% endblock %} From 83d3e5ba824684ae88981d896e03fa44773b9598 Mon Sep 17 00:00:00 2001 From: Andromeda Yelton Date: Mon, 31 Dec 2012 09:49:09 -0500 Subject: [PATCH 3/6] position lightbox relative to top of viewport, allow for scrolling --- static/js/hijax.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/static/js/hijax.js b/static/js/hijax.js index 3dc27112..6c614f56 100644 --- a/static/js/hijax.js +++ b/static/js/hijax.js @@ -12,6 +12,11 @@ $j(document).ready(function() { var windowWidth = $j(document).width(); var marginWidth = (windowWidth - hijaxWidth)/2; $j('#about_expandable').css({'margin-left': marginWidth}); + + // position div vertically relative to top of viewport, to ensure visibility + // regardless of where on the page the user clicked to activate it + var marginTop = window.pageYOffset; + $j('#about_expandable').css({'margin-top': marginTop}); }); if ($j(this).attr("href").substr(-9,8) == "download") { @@ -22,7 +27,7 @@ $j(document).ready(function() { $j('#feedback').css({"opacity": "0.07"}); $j('#js-page-wrap').css({"opacity": "0.07"}); $j('#footer').css({"opacity": "0.07"}); - $j('#about_expandable').css({'position': 'fixed'}); + $j('#about_expandable').css({'position': 'absolute'}); $j('#about_expandable').fadeTo("slow", 1); // if we're on a supporter page, personalize our about box From a726a1115457bc16634d0893f34feb278168d517 Mon Sep 17 00:00:00 2001 From: Raymond Yee Date: Mon, 31 Dec 2012 10:10:24 -0500 Subject: [PATCH 4/6] [fix #41788889] google id for book changed --- core/tests.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/tests.py b/core/tests.py index 16058183..1ef50c46 100755 --- a/core/tests.py +++ b/core/tests.py @@ -249,15 +249,15 @@ class BookLoaderTests(TestCase): #ebook_epub = edition.ebooks.all()[0] ebook_epub = edition.ebooks.filter(format='epub')[0] self.assertEqual(ebook_epub.format, 'epub') - #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(ebook_epub.url, 'http://books.google.com/books/download/The_Latin_language.epub?id=N1RfAAAAMAAJ&ie=ISO-8859-1&output=epub&source=gbs_api') + self.assertEqual(parse_qs(urlparse(ebook_epub.url).query).get("id"), ['N1RfAAAAMAAJ']) self.assertEqual(parse_qs(urlparse(ebook_epub.url).query).get("output"), ['epub']) 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(ebook_pdf.url, 'http://books.google.com/books/download/The_Latin_language.pdf?id=N1RfAAAAMAAJ&ie=ISO-8859-1&output=pdf&sig=ACfU3U2yLt3nmTncB8ozxOWUc4iHKUznCA&source=gbs_api') + self.assertEqual(parse_qs(urlparse(ebook_pdf.url).query).get("id"), ['N1RfAAAAMAAJ']) self.assertEqual(parse_qs(urlparse(ebook_pdf.url).query).get("output"), ['pdf']) self.assertEqual(ebook_pdf.provider, 'Google Books') self.assertEqual(edition.public_domain, True) From 609c09c74d42b335e005e4b27ddb5107d1e8fef0 Mon Sep 17 00:00:00 2001 From: Andromeda Yelton Date: Mon, 31 Dec 2012 11:12:55 -0500 Subject: [PATCH 5/6] it was missing a parenthesis --- frontend/templates/notification/wishlist_successful/full.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/templates/notification/wishlist_successful/full.txt b/frontend/templates/notification/wishlist_successful/full.txt index f1349b5a..0df3c953 100644 --- a/frontend/templates/notification/wishlist_successful/full.txt +++ b/frontend/templates/notification/wishlist_successful/full.txt @@ -9,4 +9,4 @@ If necessary to provide you with any premiums you requested, {{ campaign.rightsh Thank you for your support. -{{ campaign.rightsholder }} (rights holder for {{ campaign.work.title }} and the Unglue.it team \ No newline at end of file +{{ campaign.rightsholder }} (rights holder for {{ campaign.work.title }}) and the Unglue.it team \ No newline at end of file From 7fd78d93493b1224c5d81fad12fa7519d9d9c6bc Mon Sep 17 00:00:00 2001 From: thatandromeda Date: Mon, 31 Dec 2012 13:07:18 -0500 Subject: [PATCH 6/6] Update frontend/templates/base.html --- frontend/templates/base.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/templates/base.html b/frontend/templates/base.html index 9aa99427..12886287 100644 --- a/frontend/templates/base.html +++ b/frontend/templates/base.html @@ -139,7 +139,7 @@ {% block news %}
- We've unglued two books. Help us unglue four more!
+ We've unglued our second and third books. Help us unglue even more!
{% endblock %}