def load_doab_edition(title, doab_id, url, format, rights, language, isbns, provider, **kwargs): """ load a record from doabooks.org represented by input parameters and return an ebook """ if language and isinstance(language, list): language = language[0] # check to see whether the Edition hasn't already been loaded first # search by url ebooks = models.Ebook.objects.filter(url=url) # 1 match # > 1 matches # 0 match # simplest case -- if match (1 or more), we could check whether any # ebook.edition.work has a doab id matching given doab_id # put a migration to force Ebook.url to be unique id # if yes, then return one of the Edition(s) whose work is doab_id # if no, then ebook = None if len(ebooks) > 1: raise Exception( "There is more than one Ebook matching url {0}".format(url)) elif len(ebooks) == 1: ebook = ebooks[0] doab_identifer = models.Identifier.get_or_add(type='doab', value=doab_id, work=ebook.edition.work) # update the cover id cover_url = update_cover_doab(doab_id, ebook.edition) # attach more metadata attach_more_doab_metadata( ebook.edition, description=kwargs.get('description'), subjects=kwargs.get('subject'), publication_date=kwargs.get('date'), publisher_name=kwargs.get('publisher'), language=language, authors=kwargs.get('authors'), ) # make sure all isbns are added add_all_isbns(isbns, None, language=language, title=title) return ebook # remaining case --> no ebook, load record, create ebook if there is one. assert len(ebooks) == 0 # we need to find the right Edition/Work to tie Ebook to... # look for the Edition with which to associate ebook. # loop through the isbns to see whether we get one that is not None work = None edition = add_all_isbns(isbns, None, language=language, title=title) if edition: edition.refresh_from_db() work = edition.work if doab_id and not work: # make sure there's not already a doab_id idents = models.Identifier.objects.filter(type='doab', value=doab_id) for ident in idents: edition = ident.work.preferred_edition work = edition.work break if edition is not None: # if this is a new edition, then add related editions asynchronously if getattr(edition, 'new', False): tasks.populate_edition.delay(edition.isbn_13) doab_identifer = models.Identifier.get_or_add(type='doab', value=doab_id, work=edition.work) # we need to create Edition(s) de novo else: # if there is a Work with doab_id already, attach any new Edition(s) try: work = models.Identifier.objects.get(type='doab', value=doab_id).work except models.Identifier.DoesNotExist: if language: work = models.Work(language=language, title=title, age_level='18-') else: work = models.Work(language='xx', title=title, age_level='18-') work.save() doab_identifer = models.Identifier.get_or_add(type='doab', value=doab_id, work=work) # if work has any ebooks already, attach the ebook to the corresponding edition # otherwise pick the first one # pick the first edition as the one to tie ebook to editions_with_ebooks = models.Edition.objects.filter(Q(work__id=work.id) & \ Q(ebooks__isnull=False)).distinct() if editions_with_ebooks: edition = editions_with_ebooks[0] elif work.editions.all(): edition = work.editions.all()[0] else: edition = models.Edition(work=work, title=title) edition.save() # make the edition the selected_edition of the work work.selected_edition = edition work.save() if format in ('pdf', 'epub', 'mobi'): ebook = models.Ebook() ebook.format = format ebook.provider = provider ebook.url = url ebook.rights = rights # tie the edition to ebook ebook.edition = edition ebook.save() # update the cover id (could be done separately) cover_url = update_cover_doab(doab_id, edition) # attach more metadata attach_more_doab_metadata( edition, description=kwargs.get('description'), subjects=kwargs.get('subject'), publication_date=kwargs.get('date'), publisher_name=kwargs.get('publisher'), authors=kwargs.get('authors'), ) return ebook
def edit_edition(request, work_id, edition_id, by=None): ''' view for editing editions ''' if not work_id and not edition_id: return new_edition(request, by=by) # if the work and edition are set, we save the edition and set the work language = 'en' age_level = '' description = '' title = '' if work_id: work = safe_get_work(work_id) language = work.language age_level = work.age_level description = work.description title = work.title else: work = None alert = '' admin = user_can_edit_work(request.user, work) if edition_id: edition = get_edition(edition_id) if work: edition.work = work language = edition.work.language age_level = edition.work.age_level description = edition.work.description else: edition = models.Edition() if work: edition.work = work edition.publication_date = work.earliest_publication_date edition.new_authors = [] for relator in work.relators(): edition.new_authors.append( (relator.author.name, relator.relation.code)) initial = { 'language': language, 'age_level': age_level, 'publisher_name': edition.publisher_name, 'description': description, 'title': title, } if request.method == 'POST': form = None edition.new_authors = zip(request.POST.getlist('new_author'), request.POST.getlist('new_author_relation')) edition.new_subjects = request.POST.getlist('new_subject') if edition.id and admin: for author in edition.authors.all(): if request.POST.has_key('delete_author_%s' % author.id): edition.remove_author(author) form = EditionForm(instance=edition, data=request.POST, files=request.FILES) break work_rels = models.WorkRelation.objects.filter( Q(to_work=work) | Q(from_work=work)) for work_rel in work_rels: if request.POST.has_key('delete_work_rel_%s' % work_rel.id): work_rel.delete() form = EditionForm(instance=edition, data=request.POST, files=request.FILES) break activate_all = request.POST.has_key('activate_all_ebooks') deactivate_all = request.POST.has_key('deactivate_all_ebooks') ebookchange = False for ebook in work.ebooks_all(): if request.POST.has_key( 'activate_ebook_%s' % ebook.id) or activate_all: ebook.activate() ebookchange = True elif request.POST.has_key( 'deactivate_ebook_%s' % ebook.id) or deactivate_all: ebook.deactivate() ebookchange = True if ebookchange: form = EditionForm(instance=edition, data=request.POST, files=request.FILES) if request.POST.has_key('add_author_submit') and admin: new_author_name = request.POST['add_author'].strip() new_author_relation = request.POST['add_author_relation'] try: author = models.Author.objects.get(name=new_author_name) except models.Author.DoesNotExist: author = models.Author.objects.create(name=new_author_name) edition.new_authors.append((new_author_name, new_author_relation)) form = EditionForm(instance=edition, data=request.POST, files=request.FILES) elif not form and admin: form = EditionForm(instance=edition, data=request.POST, files=request.FILES) if form.is_valid(): form.save() if not work: work = models.Work( title=form.cleaned_data['title'], language=form.cleaned_data['language'], age_level=form.cleaned_data['age_level'], description=form.cleaned_data['description'], ) work.save() edition.work = work edition.save() else: work.description = form.cleaned_data['description'] work.title = form.cleaned_data['title'] work.publication_range = None # will reset on next access work.language = form.cleaned_data['language'] work.age_level = form.cleaned_data['age_level'] work.save() id_type = form.cleaned_data['id_type'] id_val = form.cleaned_data['id_value'] if id_val == 'delete': if edition.identifiers.exclude(type=id_type): edition.identifiers.filter(type=id_type).delete() else: alert = ( 'Can\'t delete identifier - must have at least one left.' ) elif id_val: models.Identifier.set(type=id_type, value=id_val, edition=edition, work=work) for relator in edition.relators.all(): if request.POST.has_key('change_relator_%s' % relator.id): new_relation = request.POST['change_relator_%s' % relator.id] relator.set(new_relation) related_work = form.cleaned_data['add_related_work'] if related_work: models.WorkRelation.objects.get_or_create( to_work=work, from_work=related_work, relation=form.cleaned_data['add_work_relation'], ) for (author_name, author_relation) in edition.new_authors: edition.add_author(author_name, author_relation) if form.cleaned_data.has_key('bisac'): bisacsh = form.cleaned_data['bisac'] while bisacsh: add_subject(bisacsh.full_label, work, authority="bisacsh") bisacsh = bisacsh.parent for subject_name in edition.new_subjects: add_subject(subject_name, work) work_url = reverse('work', kwargs={'work_id': edition.work.id}) cover_file = form.cleaned_data.get("coverfile", None) if cover_file: # save it cover_file_name = '/Users/%s/covers/%s/%s' % ( request.user.username, edition.pk, cover_file.name) new_file = default_storage.open(cover_file_name, 'w') new_file.write(cover_file.read()) new_file.close() #and put its url into cover_image edition.cover_image = default_storage.url(cover_file_name) edition.save() if not alert: return HttpResponseRedirect(work_url) else: form = EditionForm(instance=edition, initial=initial) return render( request, 'edit_edition.html', { 'form': form, 'identform': IdentifierForm(), 'edition': edition, 'admin': admin, 'alert': alert, })