commit
babeb9e4aa
|
@ -487,6 +487,20 @@ def merge_works(w1, w2, user=None):
|
|||
ww.save()
|
||||
|
||||
w2.delete()
|
||||
|
||||
def detach_edition(e):
|
||||
"""will detach edition from its work, creating a new stub work. if remerge=true, will see if there's another work to attach to
|
||||
"""
|
||||
logger.info("splitting edition %s from %s", e, e.work)
|
||||
w = models.Work(title=e.title, language = e.work.language)
|
||||
w.save()
|
||||
|
||||
for identifier in e.identifiers.all():
|
||||
identifier.work = w
|
||||
identifier.save()
|
||||
|
||||
e.work = w
|
||||
e.save()
|
||||
|
||||
def despam_description(description):
|
||||
""" a lot of descriptions from openlibrary have free-book promotion text; this removes some of it."""
|
||||
|
|
|
@ -16,7 +16,7 @@ from selectable.forms import AutoCompleteSelectWidget,AutoCompleteSelectField
|
|||
|
||||
from regluit.core.models import UserProfile, RightsHolder, Claim, Campaign, Premium, Ebook, Edition, PledgeExtra, Work, Press
|
||||
from regluit.core.models import TWITTER, FACEBOOK, GRAVATAR
|
||||
from regluit.core.lookups import OwnerLookup, WorkLookup
|
||||
from regluit.core.lookups import OwnerLookup, WorkLookup, PublisherNameLookup
|
||||
|
||||
from regluit.utils.localdatetime import now
|
||||
|
||||
|
@ -27,10 +27,17 @@ logger = logging.getLogger(__name__)
|
|||
class EditionForm(forms.ModelForm):
|
||||
add_author = forms.CharField(max_length=500, required=False)
|
||||
add_subject = forms.CharField(max_length=200, required=False)
|
||||
isbn_13 = forms.RegexField(
|
||||
publisher_name = AutoCompleteSelectField(
|
||||
PublisherNameLookup,
|
||||
label='Publisher Name',
|
||||
widget=AutoCompleteSelectWidget(PublisherNameLookup),
|
||||
required=False,
|
||||
)
|
||||
|
||||
isbn = forms.RegexField(
|
||||
label=_("ISBN"),
|
||||
max_length=13,
|
||||
regex=r'^97[89]\d\d\d\d\d\d\d\d\d\d$',
|
||||
regex=r'^(97[89]\d\d\d\d\d\d\d\d\d\d|delete)$',
|
||||
required = True,
|
||||
help_text = _("13 digits, no dash."),
|
||||
error_messages = {
|
||||
|
@ -38,9 +45,39 @@ class EditionForm(forms.ModelForm):
|
|||
'required': _("Yes, we need an ISBN."),
|
||||
}
|
||||
)
|
||||
oclcnum = forms.RegexField(
|
||||
goog = forms.RegexField(
|
||||
label=_("Google Books ID"),
|
||||
max_length=12,
|
||||
regex=r'^([a-zA-Z0-9\-_]{12}|delete)$',
|
||||
required = False,
|
||||
help_text = _("12 alphanumeric characters, dash or underscore, case sensitive."),
|
||||
error_messages = {
|
||||
'invalid': _("This value must be 12 alphanumeric characters, dash or underscore."),
|
||||
}
|
||||
)
|
||||
gdrd = forms.RegexField(
|
||||
label=_("GoodReads ID"),
|
||||
max_length=8,
|
||||
regex=r'^(\d+|delete)$',
|
||||
required = False,
|
||||
help_text = _("1-8 digits."),
|
||||
error_messages = {
|
||||
'invalid': _("This value must be 1-8 digits."),
|
||||
}
|
||||
)
|
||||
thng = forms.RegexField(
|
||||
label=_("LibraryThing ID"),
|
||||
max_length=8,
|
||||
regex=r'(^\d+|delete)$',
|
||||
required = False,
|
||||
help_text = _("1-8 digits."),
|
||||
error_messages = {
|
||||
'invalid': _("This value must be 1-8 digits."),
|
||||
}
|
||||
)
|
||||
oclc = forms.RegexField(
|
||||
label=_("OCLCnum"),
|
||||
regex=r'^\d\d\d\d\d\d\d\d\d*$',
|
||||
regex=r'^(\d\d\d\d\d\d\d\d\d*|delete)$',
|
||||
required = False,
|
||||
help_text = _("8 or more digits."),
|
||||
error_messages = {
|
||||
|
@ -237,7 +274,7 @@ class WorkForm(forms.Form):
|
|||
class OtherWorkForm(WorkForm):
|
||||
other_work = AutoCompleteSelectField(
|
||||
WorkLookup,
|
||||
label='Other Work',
|
||||
label='Other Work (title)',
|
||||
widget=AutoCompleteSelectWidget(WorkLookup),
|
||||
required=True,
|
||||
error_messages={'required': 'Missing work to merge with.'},
|
||||
|
|
|
@ -8,9 +8,12 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block doccontent %}
|
||||
<h2>{{ work.title }}</h2>
|
||||
|
||||
{% if merge_complete %}
|
||||
<h2>Merge {{ old_work_id }} into {{ work.id }} Complete</h2>
|
||||
<h2>Merge {{ old_work_id }} into <a href="{% url work work.id %}">{{ work.id }}</a> Complete</h2>
|
||||
{% include 'workbox.html' %}
|
||||
<div><a href="?again">Merge more</a><br /><br /></div>
|
||||
{% else %}
|
||||
<h2>Merge Works</h2>
|
||||
<form method="POST" action="#">
|
||||
|
@ -31,4 +34,9 @@
|
|||
{% endif %}
|
||||
</form>
|
||||
{% endif %}
|
||||
|
||||
<h2>More Edition Management</h2>
|
||||
<div><a href="{% url split work.id %}">Remove editions from this work</a><br /><br /></div>
|
||||
<div><a href="{% url new_edition work.id '' %}">Create a new edition for this work</a><br /><br /></div>
|
||||
|
||||
{% endblock %}
|
|
@ -4,6 +4,7 @@
|
|||
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/themes/ui-lightness/jquery-ui.css" type="text/css" media="screen">
|
||||
{{ form.media.css }}
|
||||
<script type="text/javascript" src="{{ jquery_ui_home }}" ></script>
|
||||
|
||||
{{ form.media.js }}
|
||||
{% endblock %}
|
||||
|
||||
|
@ -20,6 +21,7 @@
|
|||
{{ form.work }}
|
||||
<div>
|
||||
<p><b>Title</b>: {{ form.title.errors }}{{ form.title }}</p>
|
||||
<p><b>Publisher</b>: {{ form.publisher_name.errors }}{{ form.publisher_name }}</p>
|
||||
|
||||
<p>
|
||||
<b>Authors</b>:
|
||||
|
@ -43,9 +45,14 @@
|
|||
<input type="submit" name="add_author_submit" value="Add Author" id="submit_author"></p>
|
||||
|
||||
<p><b>Language</b>: {{ form.language.errors }}{{ form.language }}</p>
|
||||
|
||||
<p><b>ISBN-13</b>: {{ form.isbn_13.errors }}{{ form.isbn_13 }}</p>
|
||||
<p><b>OCLC Number</b>: {{ form.oclcnum.errors }}{{ form.oclcnum }}</p>
|
||||
<h4> Identifiers </h4>
|
||||
{% if id_msg %} <span class="errorlist">{{ id_msg }} </span>{% endif %}
|
||||
<p> Enter 'delete' to remove the identifier. </p>
|
||||
<p><b>ISBN-13</b>: {{ form.isbn.errors }}{{ form.isbn }}</p>
|
||||
<p><b>OCLC Number</b>: {{ form.oclc.errors }}{{ form.oclc }}</p>
|
||||
<p><b>Google Books ID</b>: {{ form.goog.errors }}{{ form.goog }}</p>
|
||||
<p><b>GoodReads ID</b>: {{ form.gdrd.errors }}{{ form.gdrd }}</p>
|
||||
<p><b>LibraryThing ID</b>: {{ form.thng.errors }}{{ form.thng }}</p>
|
||||
|
||||
<p><b>Description</b>: <br />
|
||||
{{ form.description.errors }}{{ form.description }}<br />
|
||||
|
@ -81,6 +88,11 @@
|
|||
</div>
|
||||
<input type="submit" name="create_new_edition" value="{% if edition.pk %}Save Edits{% else %}Create Edition{% endif %}" id="submit">
|
||||
</form>
|
||||
{% if edition.work %}
|
||||
<h2>More Edition Management</h2>
|
||||
|
||||
<div><a href="{% url merge edition.work.id %}">Merge other works into this one</a></div>
|
||||
<div><a href="{% url split edition.work.id %}">Remove editions from this work</a><br /><br /></div>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
|
@ -0,0 +1,33 @@
|
|||
{% extends "basedocumentation.html" %}
|
||||
|
||||
{% block doccontent %}
|
||||
<h2 class="book-name"><a href="{% url work work.id %}">{{ work.title }}</a></h2>
|
||||
|
||||
|
||||
<h2>Split Editions</h2>
|
||||
<form method="POST" action="#">
|
||||
{% csrf_token %}
|
||||
{{ formset.management_form }}
|
||||
<dl>
|
||||
{% for form in formset %}
|
||||
<dt class="editionbox">
|
||||
{{ form.instance.title }}, published by {{form.instance.publisher}} in {{ form.instance.publication_date }}
|
||||
</dt>
|
||||
<dd>with authors
|
||||
{% for author in form.instance.authors.all %}
|
||||
{{author}},
|
||||
{% endfor %}
|
||||
<br />
|
||||
ISBN: {{ form.instance.isbn_13 }}
|
||||
<br />
|
||||
{{ form.id }}Split this Edition: {{form.DELETE.0}}
|
||||
</dd>
|
||||
{% endfor %}
|
||||
</dl>
|
||||
<input type="submit" value="Split Editions" name="submit" />
|
||||
</form>
|
||||
<h2>More Edition Management</h2>
|
||||
<div><a href="{% url merge work.id %}">Merge other works into this one</a></div>
|
||||
<div><a href="{% url new_edition work.id '' %}">Create a new edition for this work</a><br /><br /></div>
|
||||
|
||||
{% endblock %}
|
|
@ -320,7 +320,8 @@
|
|||
{% endif %}
|
||||
{% if user.is_staff %}
|
||||
<h4>Related Works</h4>
|
||||
<a href="{% url merge work_id %}">Merge other works into this one</a><br />
|
||||
<div><a href="{% url merge work_id %}">Merge other works into this one</a></div>
|
||||
<div><a href="{% url split work_id %}">Remove editions from this work</a><br /><br /></div>
|
||||
{% endif %}
|
||||
{% if work.subjects.all.count > 0 %}
|
||||
<h4>Subjects</h4>
|
||||
|
|
|
@ -57,6 +57,7 @@ urlpatterns = patterns(
|
|||
url(r"^lockss/(?P<year>\d+)/$", "lockss_manifest", name="lockss_manifest"),
|
||||
url(r"^work/(?P<work_id>\d+)/download/$", "download", name="download"),
|
||||
url(r"^work/(?P<work_id>\d+)/merge/$", login_required(MergeView.as_view()), name="merge"),
|
||||
url(r"^work/(?P<work_id>\d+)/split/$", "split_work", name="split"),
|
||||
url(r"^work/\d+/acks/images/(?P<file_name>[\w\.]*)$", "static_redirect_view",{'dir': 'images'}),
|
||||
url(r"^work/(?P<work_id>\d+)/librarything/$", "work_librarything", name="work_librarything"),
|
||||
url(r"^work/(?P<work_id>\d+)/goodreads/$", "work_goodreads", name="work_goodreads"),
|
||||
|
|
|
@ -35,6 +35,7 @@ from django.core.urlresolvers import reverse
|
|||
from django.db.models import Q, Count, Sum
|
||||
from django.forms import Select
|
||||
from django.forms.models import modelformset_factory
|
||||
from django.forms.models import inlineformset_factory
|
||||
from django.http import HttpResponseRedirect, Http404
|
||||
from django.http import HttpResponse, HttpResponseNotFound
|
||||
from django.shortcuts import render, render_to_response, get_object_or_404
|
||||
|
@ -54,7 +55,7 @@ from regluit.core import tasks
|
|||
from regluit.core import models, bookloader, librarything
|
||||
from regluit.core import userlists
|
||||
from regluit.core import goodreads
|
||||
from regluit.core.bookloader import merge_works
|
||||
from regluit.core.bookloader import merge_works, detach_edition
|
||||
from regluit.core.goodreads import GoodreadsClient
|
||||
from regluit.core.search import gluejar_search
|
||||
from regluit.core.signals import supporter_message
|
||||
|
@ -407,12 +408,20 @@ def new_edition(request, work_id, edition_id, by=None):
|
|||
work.title=form.cleaned_data['title']
|
||||
work.save()
|
||||
|
||||
# note: this is very powerful. it can steal an isbn from another edition/work, and it will wipe the changed isbn from the db
|
||||
models.Identifier.set(type='isbn', value=form.cleaned_data['isbn_13'], edition=edition, work=work)
|
||||
|
||||
if form.cleaned_data['oclcnum']:
|
||||
# note: this is very powerful.(same comment as for isbn) use with care!
|
||||
models.Identifier.set(type='oclc', value=form.cleaned_data['oclcnum'], edition=edition, work=work)
|
||||
id_msg=""
|
||||
for id_type in ('isbn', 'oclc', 'goog', 'thng', 'gdrd'):
|
||||
id_val = form.cleaned_data[id_type]
|
||||
if id_val=='delete':
|
||||
edition.identifiers.filter(type=id_type).delete()
|
||||
elif id_val:
|
||||
existing= models.Identifier.objects.filter(type=id_type, value=form.cleaned_data[id_type])
|
||||
if existing.count() and existing[0].edition != edition:
|
||||
return render(request, 'new_edition.html', {
|
||||
'form': form, 'edition': edition,
|
||||
'id_msg': "%s = %s already exists"%( id_type, id_val ),
|
||||
})
|
||||
else:
|
||||
models.Identifier.set(type=id_type, value=id_val, edition=edition, work=work)
|
||||
for author_name in edition.new_author_names:
|
||||
try:
|
||||
author= models.Author.objects.get(name=author_name)
|
||||
|
@ -430,14 +439,18 @@ def new_edition(request, work_id, edition_id, by=None):
|
|||
else:
|
||||
form = EditionForm(instance=edition, initial={
|
||||
'language':language,
|
||||
'isbn_13':edition.isbn_13,
|
||||
'oclcnum':edition.oclc,
|
||||
'publisher_name':edition.publisher_name,
|
||||
'isbn':edition.isbn_13,
|
||||
'oclc':edition.oclc,
|
||||
'description':description,
|
||||
'title': title
|
||||
'title': title,
|
||||
'goog': edition.googlebooks_id,
|
||||
'gdrd': edition.goodreads_id,
|
||||
'thng': edition.librarything_id,
|
||||
})
|
||||
|
||||
return render(request, 'new_edition.html', {
|
||||
'form': form, 'edition': edition
|
||||
'form': form, 'edition': edition,
|
||||
})
|
||||
|
||||
|
||||
|
@ -719,6 +732,22 @@ class CampaignListView(FilterableListView):
|
|||
context['facet'] =self.kwargs['facet']
|
||||
return context
|
||||
|
||||
@login_required
|
||||
def split_work(request,work_id):
|
||||
if not request.user.is_staff:
|
||||
return render(request, "admins_only.html")
|
||||
work = get_object_or_404(models.Work, id=work_id)
|
||||
EditionFormSet = inlineformset_factory(models.Work, models.Edition, fields=(), extra=0 )
|
||||
|
||||
if request.method == "POST":
|
||||
formset = EditionFormSet(data=request.POST, instance=work)
|
||||
if formset.is_valid():
|
||||
for form in formset.deleted_forms:
|
||||
detach_edition(form.instance)
|
||||
|
||||
formset = EditionFormSet(instance=work)
|
||||
return render(request, "split.html", { "work":work, "formset": formset,})
|
||||
|
||||
class MergeView(FormView):
|
||||
template_name="merge.html"
|
||||
work=None
|
||||
|
|
|
@ -26,7 +26,7 @@ django-nose-selenium==0.7.3
|
|||
#django-notification==0.2
|
||||
git+git://github.com/aladagemre/django-notification.git@2927346f4c513a217ac8ad076e494dd1adbf70e1
|
||||
django-registration==0.8
|
||||
django-selectable==0.5.2
|
||||
django-selectable==0.7.0
|
||||
django-smtp-ssl==1.0
|
||||
django-social-auth==0.7.20
|
||||
django-storages==1.1.6
|
||||
|
|
Loading…
Reference in New Issue