def _display_cover_upload_form(request, form, cover, issue, info_text='', variant=False, kwargs=None): if kwargs == None: kwargs = {} upload_template = 'oi/edit/upload_cover.html' kwargs['upload_type'] = '' if cover: kwargs['upload_type'] = 'replacement' kwargs['replace_cover'] = get_image_tag(cover, "cover to replace", ZOOM_MEDIUM) else: if issue.has_covers(): kwargs['current_covers'] = get_image_tags_per_issue(issue, "current covers", ZOOM_MEDIUM, as_list=True, variants=True) kwargs['upload_type'] = 'additional' if variant: kwargs['upload_type'] = 'variant' # generate tags for cover uploads for this issue currently in the queue active_covers_tags = [] if issue.variant_of: active_covers = CoverRevision.objects\ .filter(issue=issue.variant_of, changeset__state__in=states.ACTIVE, deleted=False).order_by('created') active_covers = active_covers | CoverRevision.objects\ .filter(issue__variant_of=issue.variant_of, changeset__state__in=states.ACTIVE, deleted=False).order_by('created') if issue.variant_of.has_covers(): covers_list = get_image_tags_per_issue(issue.variant_of, "current covers", ZOOM_MEDIUM, as_list=True, variants=True) if 'current_covers' in kwargs: kwargs['current_covers'].extend(covers_list) else: kwargs['current_covers'] = covers_list else: active_covers = CoverRevision.objects.filter(issue=issue, changeset__state__in=states.ACTIVE, deleted=False).order_by('created') active_covers = active_covers | CoverRevision.objects\ .filter(issue__variant_of=issue, changeset__state__in=states.ACTIVE, deleted=False).order_by('created') active_covers = active_covers.exclude(changeset__change_type=CTYPES['variant_add']) for active_cover in active_covers: active_covers_tags.append([active_cover, get_preview_image_tag(active_cover, "pending cover", ZOOM_MEDIUM)]) kwargs['form'] = form kwargs['info'] = info_text kwargs['cover'] = cover kwargs['issue'] = issue kwargs['active_covers'] = active_covers_tags kwargs['table_width'] = UPLOAD_WIDTH return render_to_response(upload_template, kwargs, context_instance=RequestContext(request))
def cover(request, issue_id, size): """ Display the cover for a single issue on its own page. """ size = int(size) if size not in [ZOOM_SMALL, ZOOM_MEDIUM, ZOOM_LARGE]: raise Http404 issue = get_object_or_404(Issue, id = issue_id) [prev_issue, next_issue] = issue.get_prev_next_issue() cover_tag = get_image_tags_per_issue(issue, "Cover Image", size) style = get_style(request) extra = 'cover/%d/' % size # TODO: remove abstraction-breaking hack. return render_to_response( 'gcd/details/cover.html', { 'issue': issue, 'prev_issue': prev_issue, 'next_issue': next_issue, 'cover_tag': cover_tag, 'extra': extra, 'error_subject': '%s cover' % issue, 'style': style }, context_instance=RequestContext(request) )
def cover(request, issue_id, size): """ Display the cover for a single issue on its own page. """ issue = get_object_or_404(Issue, id = issue_id) cover = issue.cover_set.all()[0] [prev_issue, next_issue] = issue.get_prev_next_issue() cover_tag = get_image_tags_per_issue(issue, "Cover Image", int(size)) style = get_style(request) extra = 'cover/' + size + '/' # TODO: remove abstraction-breaking hack. return render_to_response( 'gcd/details/cover.html', { 'issue': issue, 'prev_issue': prev_issue, 'next_issue': next_issue, 'cover_tag': cover_tag, 'extra': extra, 'error_subject': '%s cover' % issue, 'style': style }, context_instance=RequestContext(request) )
def show_cover_tag(issue, zoom_level=ZOOM_SMALL): if issue: return get_image_tags_per_issue(issue, alt_text='', zoom_level=zoom_level) else: return ""
def cover(request, issue_id, size): """ Display the cover for a single issue on its own page. """ issue = get_object_or_404(Issue, id=issue_id) cover = issue.cover_set.all()[0] [prev_issue, next_issue] = get_prev_next_issue(issue.series, cover) cover_tag = get_image_tags_per_issue(issue, "Cover Image", int(size)) style = get_style(request) extra = "cover/" + size + "/" # TODO: remove abstraction-breaking hack. return render_to_response( "gcd/details/cover.html", { "issue": issue, "prev_issue": prev_issue, "next_issue": next_issue, "cover_tag": cover_tag, "extra": extra, "error_subject": "%s cover" % issue, "style": style, }, context_instance=RequestContext(request), )
def cover(request, issue_id, size): """ Display the cover for a single issue on its own page. """ size = int(size) if size not in [ZOOM_SMALL, ZOOM_MEDIUM, ZOOM_LARGE]: raise Http404 issue = get_object_or_404(Issue, id=issue_id) if issue.deleted: return HttpResponseRedirect( urlresolvers.reverse("change_history", kwargs={"model_name": "issue", "id": issue_id}) ) [prev_issue, next_issue] = issue.get_prev_next_issue() cover_tag = get_image_tags_per_issue(issue, "Cover for %s" % unicode(issue), size, variants=True) extra = "cover/%d/" % size # TODO: remove abstraction-breaking hack. return render_to_response( "gcd/details/cover.html", { "issue": issue, "prev_issue": prev_issue, "next_issue": next_issue, "cover_tag": cover_tag, "extra": extra, "error_subject": "%s cover" % issue, }, context_instance=RequestContext(request), )
def cover(request, issue_id, size): """ Display the cover for a single issue on its own page. """ size = int(size) if size not in [ZOOM_SMALL, ZOOM_MEDIUM, ZOOM_LARGE]: raise Http404 issue = get_object_or_404(Issue, id = issue_id) if issue.deleted: return HttpResponseRedirect(urlresolvers.reverse('change_history', kwargs={'model_name': 'issue', 'id': issue_id})) [prev_issue, next_issue] = issue.get_prev_next_issue() cover_tag = get_image_tags_per_issue(issue, "Cover Image", size) extra = 'cover/%d/' % size # TODO: remove abstraction-breaking hack. return render_to_response( 'gcd/details/cover.html', { 'issue': issue, 'prev_issue': prev_issue, 'next_issue': next_issue, 'cover_tag': cover_tag, 'extra': extra, 'error_subject': '%s cover' % issue, }, context_instance=RequestContext(request) )
def show_issue(request, issue, preview=False): """ Handle the main work of displaying an issue. Also used by OI previews. """ if preview and issue.issue: cover_issue = issue.issue else: cover_issue = issue image_tag = get_image_tags_per_issue(issue=cover_issue, zoom_level=ZOOM_SMALL, alt_text='Cover Thumbnail') series = issue.series [prev_issue, next_issue] = issue.get_prev_next_issue() # TODO: Since the number of stories per issue is typically fairly small, # it seems more efficient to grab the whole list and only do one database # query rather than separately select the cover story and the interior # stories. But we should measure this. Note that we definitely want # to send the cover and interior stories to the UI separately, as the # UI should not be concerned with the designation of story 0 as the cover. stories = list(issue.active_stories().order_by('sequence_number')\ .select_related('type')) cover_story = None if (len(stories) > 0): cover_story = stories.pop(0) # get reservations which got approved and make unique for indexers res = issue.reservation_set.filter(status=3) oi_indexers = [] for i in res: oi_indexers.append(i.indexer) if preview: res = IssueRevision.objects.filter(issue=issue.issue) else: res = IssueRevision.objects.filter(issue=issue) res = res.filter(changeset__state=states.APPROVED)\ .exclude(changeset__indexer__username=settings.ANON_USER_NAME) for i in res: oi_indexers.append(i.changeset.indexer.indexer) oi_indexers = list(set(oi_indexers)) return render_to_response( 'gcd/details/issue.html', { 'issue': issue, 'prev_issue': prev_issue, 'next_issue': next_issue, 'cover_story': cover_story, 'stories': stories, 'oi_indexers' : oi_indexers, 'image_tag': image_tag, 'error_subject': '%s' % issue, 'preview': preview, }, context_instance=RequestContext(request))
def edit_covers(request, issue_id): """ Overview of covers for an issue and possible actions """ issue = get_object_or_404(Issue, id=issue_id) covers = get_image_tags_per_issue(issue, "current covers", ZOOM_MEDIUM, as_list=True) return render_to_response('oi/edit/edit_covers.html', { 'issue': issue, 'covers': covers, 'table_width': UPLOAD_WIDTH }, context_instance=RequestContext(request))
def issue(request, issue_id): """ Display the issue details page, including story details. """ issue = get_object_or_404(Issue, id=issue_id) image_tag = get_image_tags_per_issue(issue=issue, zoom_level=ZOOM_SMALL, alt_text="Cover Thumbnail") cover = issue.cover_set.all()[0] style = get_style(request) series = issue.series [prev_issue, next_issue] = get_prev_next_issue(series, cover) # TODO: Since the number of stories per issue is typically fairly small, # it seems more efficient to grab the whole list and only do one database # query rather than separately select the cover story and the interior # stories. But we should measure this. Note that we definitely want # to send the cover and interior stories to the UI separately, as the # UI should not be concerned with the designation of story 0 as the cover. stories = list(issue.story_set.order_by("sequence_number")) cover_story = None if len(stories) > 0: cover_story = stories.pop(0) # get reservations which got approved and make unique for indexers res = issue.reservation_set.filter(status=3) oi_indexers = [] for i in res: oi_indexers.append(i.indexer) oi_indexers = list(set(oi_indexers)) return render_to_response( "gcd/details/issue.html", { "issue": issue, "prev_issue": prev_issue, "next_issue": next_issue, "cover_story": cover_story, "stories": stories, "oi_indexers": oi_indexers, "image_tag": image_tag, "error_subject": "%s" % issue, "style": style, }, context_instance=RequestContext(request), )
def edit_covers(request, issue_id): """ Overview of covers for an issue and possible actions """ issue = get_object_or_404(Issue, id=issue_id) covers = get_image_tags_per_issue(issue, "current covers", ZOOM_MEDIUM, as_list=True) return render_to_response( 'oi/edit/edit_covers.html', { 'issue': issue, 'covers': covers, 'table_width': UPLOAD_WIDTH }, context_instance=RequestContext(request) )
def issue(request, issue_id): """ Display the issue details page, including story details. """ issue = get_object_or_404(Issue, id=issue_id) image_tag = get_image_tags_per_issue(issue=issue, zoom_level=ZOOM_SMALL, alt_text='Cover Thumbnail') cover = issue.cover_set.all()[0] style = get_style(request) series = issue.series [prev_issue, next_issue] = get_prev_next_issue(series, cover) # TODO: Since the number of stories per issue is typically fairly small, # it seems more efficient to grab the whole list and only do one database # query rather than separately select the cover story and the interior # stories. But we should measure this. Note that we definitely want # to send the cover and interior stories to the UI separately, as the # UI should not be concerned with the designation of story 0 as the cover. stories = list(issue.story_set.order_by('sequence_number')) cover_story = None if (len(stories) > 0): cover_story = stories.pop(0) # get reservations which got approved and make unique for indexers res = issue.reservation_set.filter(status=3) oi_indexers = [] for i in res: oi_indexers.append(i.indexer) oi_indexers = list(set(oi_indexers)) return render_to_response('gcd/details/issue.html', { 'issue': issue, 'prev_issue': prev_issue, 'next_issue': next_issue, 'cover_story': cover_story, 'stories': stories, 'oi_indexers': oi_indexers, 'image_tag': image_tag, 'error_subject': '%s' % issue, 'style': style, }, context_instance=RequestContext(request))
def edit_covers(request, issue_id): """ Overview of covers for an issue and possible actions """ issue = get_object_or_404(Issue, id=issue_id) if issue.has_covers(): covers = get_image_tags_per_issue(issue, "current covers", ZOOM_MEDIUM, as_list=True, variants=True) return render( request, 'oi/edit/edit_covers.html', {'issue': issue, 'covers': covers, 'table_width': UPLOAD_WIDTH }) else: return upload_cover(request, issue_id=issue_id)
def edit_covers(request, issue_id): """ Overview of covers for an issue and possible actions """ issue = get_object_or_404(Issue, id=issue_id) if issue.has_covers(): covers = get_image_tags_per_issue(issue, "current covers", ZOOM_MEDIUM, as_list=True, variants=True) return render(request, 'oi/edit/edit_covers.html', { 'issue': issue, 'covers': covers, 'table_width': UPLOAD_WIDTH }) else: return upload_cover(request, issue_id=issue_id)
def _display_cover_upload_form(request, form, cover, issue, info_text=''): upload_template = 'oi/edit/upload_cover.html' # set covers, replace_cover, upload_type covers = [] replace_cover = None if cover: upload_type = 'replacement' replace_cover = get_image_tag(cover, "cover to replace", ZOOM_MEDIUM) else: if issue.has_covers(): covers = get_image_tags_per_issue(issue, "current covers", ZOOM_MEDIUM, as_list=True) upload_type = 'variant' else: upload_type = '' # generate tags for cover uploads for this issue currently in the queue active_covers_tags = [] active_covers = CoverRevision.objects.filter( issue=issue, changeset__state__in=states.ACTIVE, deleted=False).order_by('created') for active_cover in active_covers: active_covers_tags.append([ active_cover, get_preview_image_tag(active_cover, "pending cover", ZOOM_MEDIUM) ]) return render_to_response(upload_template, { 'form': form, 'info': info_text, 'cover': cover, 'issue': issue, 'current_covers': covers, 'replace_cover': replace_cover, 'active_covers': active_covers_tags, 'upload_type': upload_type, 'table_width': UPLOAD_WIDTH }, context_instance=RequestContext(request))
def _display_cover_upload_form(request, form, cover, issue, info_text=''): upload_template = 'oi/edit/upload_cover.html' # set covers, replace_cover, upload_type covers = [] replace_cover = None if cover: upload_type = 'replacement' replace_cover = get_image_tag(cover, "cover to replace", ZOOM_MEDIUM) else: if issue.has_covers(): covers = get_image_tags_per_issue(issue, "current covers", ZOOM_MEDIUM, as_list=True) upload_type = 'variant' else: upload_type = '' # generate tags for cover uploads for this issue currently in the queue active_covers_tags = [] active_covers = CoverRevision.objects.filter(issue=issue, changeset__state__in=states.ACTIVE, deleted=False).order_by('created') for active_cover in active_covers: active_covers_tags.append([active_cover, get_preview_image_tag(active_cover, "pending cover", ZOOM_MEDIUM)]) return render_to_response(upload_template, { 'form': form, 'info' : info_text, 'cover' : cover, 'issue' : issue, 'current_covers' : covers, 'replace_cover' : replace_cover, 'active_covers' : active_covers_tags, 'upload_type' : upload_type, 'table_width': UPLOAD_WIDTH}, context_instance=RequestContext(request))
def cover(request, issue_id, size): """ Display the cover for a single issue on its own page. """ issue = get_object_or_404(Issue, id=issue_id) cover = issue.cover_set.all()[0] [prev_issue, next_issue] = issue.get_prev_next_issue() cover_tag = get_image_tags_per_issue(issue, "Cover Image", int(size)) style = get_style(request) extra = 'cover/' + size + '/' # TODO: remove abstraction-breaking hack. return render_to_response('gcd/details/cover.html', { 'issue': issue, 'prev_issue': prev_issue, 'next_issue': next_issue, 'cover_tag': cover_tag, 'extra': extra, 'error_subject': '%s cover' % issue, 'style': style }, context_instance=RequestContext(request))
def upload_cover(request, cover_id=None, issue_id=None): """ Handles uploading of covers be it - first upload - replacement upload - variant upload """ # this cannot actually happen if cover_id and issue_id: raise ValueError upload_template = 'oi/edit/upload_cover.html' style = 'default' # set cover, issue, covers, replace_cover, upload_type covers = [] replace_cover = None # if cover_id is present it is a replacement upload if cover_id: cover = get_object_or_404(Cover, id=cover_id) issue = cover.issue # check if there is a pending change for the cover if CoverRevision.objects.filter(cover=cover, changeset__state__in=states.ACTIVE): revision = CoverRevision.objects.get( cover=cover, changeset__state__in=states.ACTIVE) return render_error( request, ('There currently is a <a href="%s">pending replacement</a> ' 'for this cover of %s.') % (urlresolvers.reverse( 'compare', kwargs={'id': revision.changeset.id }), esc(cover.issue)), redirect=False, is_safe=True) upload_type = 'replacement' replace_cover = get_image_tag(cover, "cover to replace", ZOOM_MEDIUM) # no cover_id, therefore upload a cover to an issue (first or variant) else: issue = get_object_or_404(Issue, id=issue_id) cover = None if issue.has_covers(): covers = get_image_tags_per_issue(issue, "current covers", ZOOM_MEDIUM, as_list=True) upload_type = 'variant' else: upload_type = '' # generate tags for cover uploads for this issue currently in the queue active_covers_tags = [] active_covers = CoverRevision.objects.filter( issue=issue, changeset__state__in=states.ACTIVE, deleted=False).order_by('created') for active_cover in active_covers: active_covers_tags.append([ active_cover, get_preview_image_tag(active_cover, "pending cover", ZOOM_MEDIUM) ]) # current request is an upload if request.method == 'POST': try: form = UploadScanForm(request.POST, request.FILES) except IOError: # sometimes uploads misbehave. connection dropped ? error_text = 'Something went wrong with the upload. ' + \ 'Please <a href="' + request.path + '">try again</a>.' return render_error(request, error_text, redirect=False, is_safe=True) if not form.is_valid(): return render_to_response(upload_template, { 'form': form, 'cover': cover, 'issue': issue, 'style': style, 'replace_cover': replace_cover, 'current_covers': covers, 'upload_type': upload_type, 'table_width': UPLOAD_WIDTH }, context_instance=RequestContext(request)) # if scan is actually in the form handle it if 'scan' in request.FILES: # process form scan = request.FILES['scan'] file_source = request.POST['source'] marked = 'marked' in request.POST # create OI records changeset = Changeset(indexer=request.user, state=states.PENDING, change_type=CTYPES['cover']) changeset.save() if upload_type == 'replacement': revision = CoverRevision(changeset=changeset, issue=issue, cover=cover, file_source=file_source, marked=marked, is_replacement=True) else: revision = CoverRevision(changeset=changeset, issue=issue, file_source=file_source, marked=marked) revision.save() # put new uploaded covers into # media/<LOCAL_NEW_SCANS>/<monthname>_<year>/ # with name # <revision_id>_<date>_<time>.<ext> scan_name = str(revision.id) + os.path.splitext(scan.name)[1] upload_dir = settings.MEDIA_ROOT + LOCAL_NEW_SCANS + \ changeset.created.strftime('%B_%Y/').lower() destination_name = upload_dir + scan_name try: # essentially only needed at beginning of the month check_cover_dir(upload_dir) except IOError: changeset.delete() error_text = "Problem with file storage for uploaded " + \ "cover, please report an error." return render_error(request, error_text, redirect=False) # write uploaded file destination = open(destination_name, 'wb') for chunk in scan.chunks(): destination.write(chunk) destination.close() try: # generate different sizes we are using im = Image.open(destination.name) if im.size[0] >= 400: generate_sizes(revision, im) else: changeset.delete() os.remove(destination.name) info_text = "Image is too small, only " + str(im.size) + \ " in size." return render_to_response( upload_template, { 'form': form, 'info': info_text, 'cover': cover, 'current_covers': covers, 'replace_cover': replace_cover, 'upload_type': upload_type, 'table_width': UPLOAD_WIDTH, 'issue': issue }, context_instance=RequestContext(request)) except IOError: # just in case, django *should* have taken care of file type changeset.delete() os.remove(destination.name) return render_to_response(upload_template, { 'form': form, 'info' : 'Error: File \"' + scan.name + \ '" is not a valid picture.', 'cover' : cover, 'issue' : issue, 'current_covers' : covers, 'replace_cover' : replace_cover, 'upload_type' : upload_type, 'table_width': UPLOAD_WIDTH }, context_instance=RequestContext(request)) # all done, we can save the state changeset.comments.create(commenter=request.user, text=form.cleaned_data['comments'], old_state=states.UNRESERVED, new_state=changeset.state) if 'remember_source' in request.POST: request.session['oi_file_source'] = request.POST['source'] else: request.session.pop('oi_file_source', '') return HttpResponseRedirect( urlresolvers.reverse('upload_cover_complete', kwargs={'revision_id': revision.id})) # request is a GET for the form else: if 'oi_file_source' in request.session: vars = { 'source': request.session['oi_file_source'], 'remember_source': True } else: vars = None form = UploadScanForm(initial=vars) # display the form return render_to_response(upload_template, { 'form': form, 'cover': cover, 'issue': issue, 'current_covers': covers, 'replace_cover': replace_cover, 'active_covers': active_covers_tags, 'upload_type': upload_type, 'table_width': UPLOAD_WIDTH }, context_instance=RequestContext(request))
def show_cover_tag_medium(issue): return get_image_tags_per_issue(issue, alt_text=u'', zoom_level=ZOOM_MEDIUM)
def show_issue(request, issue, preview=False): """ Helper function to handle the main work of displaying an issue. Also used by OI previews. """ alt_text = u'Cover Thumbnail for %s' % issue.full_name() zoom_level = ZOOM_MEDIUM if preview: images_count = 0 # excludes are currently only relevant for variant_add, maybe later # other cover moves will be possible if issue.changeset.change_type in [CTYPES['variant_add'], CTYPES['two_issues']] and \ issue.changeset.coverrevisions.count(): # need to exclude the moved one image_tag = mark_safe('') if issue.issue and issue.issue.active_covers().count(): exclude_ids = issue.changeset.coverrevisions\ .filter(issue=issue.issue).values_list('cover__id', flat=True) if len(exclude_ids) < issue.issue.active_covers().count(): image_tag = get_image_tags_per_issue( issue=issue.issue, zoom_level=zoom_level, alt_text=alt_text, exclude_ids=exclude_ids) # add moved cover(s) for cover in issue.changeset.coverrevisions\ .exclude(issue=issue.issue): image_tag += get_image_tag(cover.cover, alt_text=alt_text, zoom_level=zoom_level) if image_tag == '': image_tag = mark_safe( get_image_tag(cover=None, zoom_level=zoom_level, alt_text=alt_text)) elif issue.issue: image_tag = get_image_tags_per_issue(issue=issue.issue, zoom_level=zoom_level, alt_text=alt_text) images_count = Image.objects.filter(object_id=issue.issue.id, deleted=False, content_type = ContentType.objects.get_for_model(issue.issue))\ .count() else: image_tag = mark_safe( get_image_tag(cover=None, zoom_level=zoom_level, alt_text=alt_text)) else: image_tag = get_image_tags_per_issue(issue=issue, zoom_level=zoom_level, alt_text=alt_text) images_count = Image.objects.filter( object_id=issue.id, deleted=False, content_type=ContentType.objects.get_for_model(issue)).count() variant_image_tags = [] for variant_cover in issue.variant_covers(): variant_image_tags.append([ variant_cover.issue, get_image_tag(variant_cover, zoom_level=ZOOM_SMALL, alt_text=u'Cover Thumbnail for %s' % unicode(variant_cover.issue)) ]) series = issue.series [prev_issue, next_issue] = issue.get_prev_next_issue() # TODO: Since the number of stories per issue is typically fairly small, # it seems more efficient to grab the whole list and only do one database # query rather than separately select the cover story and the interior # stories. But we should measure this. Note that we definitely want # to send the cover and interior stories to the UI separately, as the # UI should not be concerned with the designation of story 0 as the cover. cover_story, stories = issue.shown_stories() # get reservations which got approved and make unique for indexers res = issue.reservation_set.filter(status=3) oi_indexers = [] for i in res: oi_indexers.append(i.indexer) if preview: if issue.issue: res = IssueRevision.objects.filter(issue=issue.issue) else: res = IssueRevision.objects.none() else: res = IssueRevision.objects.filter(issue=issue) res = res.filter(changeset__state=states.APPROVED)\ .exclude(changeset__indexer__username=settings.ANON_USER_NAME) for i in res: oi_indexers.append(i.changeset.indexer.indexer) oi_indexers = list(set(oi_indexers)) show_original = False if (request.GET.has_key('original_reprint_notes')): if request.GET['original_reprint_notes'] == 'True': show_original = True return render_to_response('gcd/details/issue.html', { 'issue': issue, 'prev_issue': prev_issue, 'next_issue': next_issue, 'cover_story': cover_story, 'stories': stories, 'oi_indexers': oi_indexers, 'image_tag': image_tag, 'variant_image_tags': variant_image_tags, 'images_count': images_count, 'show_original': show_original, 'error_subject': '%s' % issue, 'preview': preview, }, context_instance=RequestContext(request))
def show_cover_tag(issue, zoom_level=ZOOM_SMALL): if issue: return get_image_tags_per_issue(issue, alt_text=u'', zoom_level=zoom_level) else: return ""
def show_issue(request, issue, preview=False): """ Handle the main work of displaying an issue. Also used by OI previews. """ alt_text = 'Cover Thumbnail' zoom_level = ZOOM_MEDIUM if preview: # excludes are currently only relevant for variant_add, maybe later # other cover moves will be possible if issue.changeset.change_type in [CTYPES['variant_add'], CTYPES['two_issues']] and \ issue.changeset.coverrevisions.count(): # need to exclude the moved one image_tag = mark_safe('') if issue.issue and issue.issue.active_covers().count(): exclude_ids = issue.changeset.coverrevisions\ .filter(issue=issue.issue).values_list('cover__id', flat=True) if len(exclude_ids) < issue.issue.active_covers().count(): image_tag = get_image_tags_per_issue(issue=issue.issue, zoom_level=zoom_level, alt_text=alt_text, exclude_ids=exclude_ids) # add moved cover(s) for cover in issue.changeset.coverrevisions\ .exclude(issue=issue.issue): image_tag += get_image_tag(cover.cover, alt_text=alt_text, zoom_level=zoom_level) if image_tag == '': image_tag = mark_safe(get_image_tag(cover=None, zoom_level=zoom_level, alt_text=alt_text)) elif issue.issue: image_tag = get_image_tags_per_issue(issue=issue.issue, zoom_level=zoom_level, alt_text=alt_text) else: image_tag = mark_safe(get_image_tag(cover=None, zoom_level=zoom_level, alt_text=alt_text)) else: image_tag = get_image_tags_per_issue(issue=issue, zoom_level=zoom_level, alt_text=alt_text) variant_image_tags = [] for variant_cover in issue.variant_covers(): variant_image_tags.append([variant_cover.issue, get_image_tag(variant_cover, zoom_level=ZOOM_SMALL, alt_text='Cover Thumbnail')]) series = issue.series [prev_issue, next_issue] = issue.get_prev_next_issue() # TODO: Since the number of stories per issue is typically fairly small, # it seems more efficient to grab the whole list and only do one database # query rather than separately select the cover story and the interior # stories. But we should measure this. Note that we definitely want # to send the cover and interior stories to the UI separately, as the # UI should not be concerned with the designation of story 0 as the cover. cover_story, stories = issue.shown_stories() # get reservations which got approved and make unique for indexers res = issue.reservation_set.filter(status=3) oi_indexers = [] for i in res: oi_indexers.append(i.indexer) if preview: if issue.issue: res = IssueRevision.objects.filter(issue=issue.issue) else: res = IssueRevision.objects.none() else: res = IssueRevision.objects.filter(issue=issue) res = res.filter(changeset__state=states.APPROVED)\ .exclude(changeset__indexer__username=settings.ANON_USER_NAME) for i in res: oi_indexers.append(i.changeset.indexer.indexer) oi_indexers = list(set(oi_indexers)) return render_to_response( 'gcd/details/issue.html', { 'issue': issue, 'prev_issue': prev_issue, 'next_issue': next_issue, 'cover_story': cover_story, 'stories': stories, 'oi_indexers' : oi_indexers, 'image_tag': image_tag, 'variant_image_tags': variant_image_tags, 'error_subject': '%s' % issue, 'preview': preview, }, context_instance=RequestContext(request))
def show_cover_tag(issue): return get_image_tags_per_issue(issue, alt_text=u'', zoom_level=ZOOM_SMALL)
def show_issue(request, issue, preview=False): """ Helper function to handle the main work of displaying an issue. Also used by OI previews. """ alt_text = u'Cover Thumbnail for %s' % issue.full_name() zoom_level = ZOOM_MEDIUM if preview: images_count = 0 not_shown_types = [] # excludes are currently only relevant for variant_add, maybe later # other cover moves will be possible if issue.changeset.change_type in [CTYPES['variant_add'], CTYPES['two_issues']] and \ issue.changeset.coverrevisions.count(): # need to exclude the moved one image_tag = mark_safe('') if issue.issue and issue.issue.active_covers().count(): exclude_ids = issue.changeset.coverrevisions\ .filter(issue=issue.issue).values_list('cover__id', flat=True) if len(exclude_ids) < issue.issue.active_covers().count(): image_tag = get_image_tags_per_issue(issue=issue.issue, zoom_level=zoom_level, alt_text=alt_text, exclude_ids=exclude_ids) # add moved cover(s) for cover in issue.changeset.coverrevisions\ .exclude(issue=issue.issue): image_tag += get_image_tag(cover.cover, alt_text=alt_text, zoom_level=zoom_level) if image_tag == '': image_tag = mark_safe(get_image_tag(cover=None, zoom_level=zoom_level, alt_text=alt_text)) elif issue.issue: image_tag = get_image_tags_per_issue(issue=issue.issue, zoom_level=zoom_level, alt_text=alt_text) images_count = Image.objects.filter(object_id=issue.issue.id, deleted=False, content_type = ContentType.objects.get_for_model(issue.issue))\ .count() else: image_tag = mark_safe(get_image_tag(cover=None, zoom_level=zoom_level, alt_text=alt_text)) else: if 'issue_detail' in request.GET: try: issue_detail = int(request.GET['issue_detail']) except ValueError: issue_detail = 1 elif request.user.is_authenticated(): issue_detail = request.user.indexer.issue_detail else: issue_detail = 1 if issue_detail == 0: not_shown_types = StoryType.objects.exclude(id__in=CORE_TYPES)\ .values_list('id', flat=True) elif issue_detail == 1: not_shown_types = AD_TYPES else: not_shown_types = [] image_tag = get_image_tags_per_issue(issue=issue, zoom_level=zoom_level, alt_text=alt_text) images_count = Image.objects.filter(object_id=issue.id, deleted=False, content_type = ContentType.objects.get_for_model(issue)).count() variant_image_tags = [] for variant_cover in issue.variant_covers(): variant_image_tags.append([variant_cover.issue, get_image_tag(variant_cover, zoom_level=ZOOM_SMALL, alt_text=u'Cover Thumbnail for %s' % unicode(variant_cover.issue))]) series = issue.series [prev_issue, next_issue] = issue.get_prev_next_issue() # TODO: Since the number of stories per issue is typically fairly small, # it seems more efficient to grab the whole list and only do one database # query rather than separately select the cover story and the interior # stories. But we should measure this. Note that we definitely want # to send the cover and interior stories to the UI separately, as the # UI should not be concerned with the designation of story 0 as the cover. cover_story, stories = issue.shown_stories() # get reservations which got approved and make unique for indexers res = issue.reservation_set.filter(status=3) oi_indexers = [] for i in res: oi_indexers.append(i.indexer) if preview: if issue.issue: res = IssueRevision.objects.filter(issue=issue.issue) else: res = IssueRevision.objects.none() else: res = IssueRevision.objects.filter(issue=issue) res = res.filter(changeset__state=states.APPROVED)\ .exclude(changeset__indexer__username=settings.ANON_USER_NAME) for i in res: oi_indexers.append(i.changeset.indexer.indexer) oi_indexers = list(set(oi_indexers)) show_original = False if (request.GET.has_key('original_reprint_notes')): if request.GET['original_reprint_notes'] == 'True': show_original = True if series.is_singleton: country = series.country language = series.language else: country = None language = None return render_to_response( 'gcd/details/issue.html', { 'issue': issue, 'prev_issue': prev_issue, 'next_issue': next_issue, 'cover_story': cover_story, 'stories': stories, 'oi_indexers' : oi_indexers, 'image_tag': image_tag, 'variant_image_tags': variant_image_tags, 'images_count': images_count, 'show_original': show_original, 'country': country, 'language': language, 'error_subject': '%s' % issue, 'preview': preview, 'not_shown_types': not_shown_types, 'NO_ADS': True }, context_instance=RequestContext(request))
def show_issue(request, issue, preview=False): """ Helper function to handle the main work of displaying an issue. Also used by OI previews. """ alt_text = u"Cover Thumbnail for %s" % issue.full_name() zoom_level = ZOOM_MEDIUM if preview: images_count = 0 # excludes are currently only relevant for variant_add, maybe later # other cover moves will be possible if ( issue.changeset.change_type in [CTYPES["variant_add"], CTYPES["two_issues"]] and issue.changeset.coverrevisions.count() ): # need to exclude the moved one image_tag = mark_safe("") if issue.issue and issue.issue.active_covers().count(): exclude_ids = issue.changeset.coverrevisions.filter(issue=issue.issue).values_list( "cover__id", flat=True ) if len(exclude_ids) < issue.issue.active_covers().count(): image_tag = get_image_tags_per_issue( issue=issue.issue, zoom_level=zoom_level, alt_text=alt_text, exclude_ids=exclude_ids ) # add moved cover(s) for cover in issue.changeset.coverrevisions.exclude(issue=issue.issue): image_tag += get_image_tag(cover.cover, alt_text=alt_text, zoom_level=zoom_level) if image_tag == "": image_tag = mark_safe(get_image_tag(cover=None, zoom_level=zoom_level, alt_text=alt_text)) elif issue.issue: image_tag = get_image_tags_per_issue(issue=issue.issue, zoom_level=zoom_level, alt_text=alt_text) images_count = Image.objects.filter( object_id=issue.issue.id, deleted=False, content_type=ContentType.objects.get_for_model(issue.issue) ).count() else: image_tag = mark_safe(get_image_tag(cover=None, zoom_level=zoom_level, alt_text=alt_text)) else: image_tag = get_image_tags_per_issue(issue=issue, zoom_level=zoom_level, alt_text=alt_text) images_count = Image.objects.filter( object_id=issue.id, deleted=False, content_type=ContentType.objects.get_for_model(issue) ).count() variant_image_tags = [] for variant_cover in issue.variant_covers(): variant_image_tags.append( [ variant_cover.issue, get_image_tag( variant_cover, zoom_level=ZOOM_SMALL, alt_text=u"Cover Thumbnail for %s" % unicode(variant_cover.issue), ), ] ) series = issue.series [prev_issue, next_issue] = issue.get_prev_next_issue() # TODO: Since the number of stories per issue is typically fairly small, # it seems more efficient to grab the whole list and only do one database # query rather than separately select the cover story and the interior # stories. But we should measure this. Note that we definitely want # to send the cover and interior stories to the UI separately, as the # UI should not be concerned with the designation of story 0 as the cover. cover_story, stories = issue.shown_stories() # get reservations which got approved and make unique for indexers res = issue.reservation_set.filter(status=3) oi_indexers = [] for i in res: oi_indexers.append(i.indexer) if preview: if issue.issue: res = IssueRevision.objects.filter(issue=issue.issue) else: res = IssueRevision.objects.none() else: res = IssueRevision.objects.filter(issue=issue) res = res.filter(changeset__state=states.APPROVED).exclude(changeset__indexer__username=settings.ANON_USER_NAME) for i in res: oi_indexers.append(i.changeset.indexer.indexer) oi_indexers = list(set(oi_indexers)) show_original = False if request.GET.has_key("original_reprint_notes"): if request.GET["original_reprint_notes"] == "True": show_original = True return render_to_response( "gcd/details/issue.html", { "issue": issue, "prev_issue": prev_issue, "next_issue": next_issue, "cover_story": cover_story, "stories": stories, "oi_indexers": oi_indexers, "image_tag": image_tag, "variant_image_tags": variant_image_tags, "images_count": images_count, "show_original": show_original, "error_subject": "%s" % issue, "preview": preview, }, context_instance=RequestContext(request), )
def upload_cover(request, cover_id=None, issue_id=None): """ Handles uploading of covers be it - first upload - replacement upload - variant upload """ # this cannot actually happen if cover_id and issue_id: raise ValueError upload_template = 'oi/edit/upload_cover.html' style = 'default' # set cover, issue, covers, replace_cover, upload_type covers = [] replace_cover = None # if cover_id is present it is a replacement upload if cover_id: cover = get_object_or_404(Cover, id=cover_id) issue = cover.issue if not cover.has_image: # nothing to replace, empty cover slot, redirect to issue upload return HttpResponseRedirect(urlresolvers.reverse('upload_cover', kwargs={'issue_id': issue.id} )) # check if there is a pending change for the cover if CoverRevision.objects.filter(cover=cover, changeset__state__in=states.ACTIVE): revision = CoverRevision.objects.get(cover=cover, changeset__state__in=states.ACTIVE) return render_error(request, ('There currently is a <a href="%s">pending replacement</a> ' 'for this cover of %s.') % (urlresolvers.reverse('compare', kwargs={'id': revision.changeset.id}), esc(cover.issue)), redirect=False, is_safe=True) upload_type = 'replacement' replace_cover = get_image_tag(cover, "cover to replace", ZOOM_MEDIUM) # no cover_id, therefore upload a cover to an issue (first or variant) else: issue = get_object_or_404(Issue, id=issue_id) cover = issue.cover_set.latest() # latest can be the empty first one if cover.has_image: covers = get_image_tags_per_issue(issue, "current covers", ZOOM_MEDIUM, as_list=True) upload_type = 'variant' else: upload_type = '' # generate tags for cover uploads for this issue currently in the queue active_covers_tags = [] active_covers = CoverRevision.objects.filter(issue=issue, changeset__state__in=states.ACTIVE).order_by('created') for active_cover in active_covers: active_covers_tags.append([active_cover, get_preview_image_tag(active_cover, "pending cover", ZOOM_MEDIUM)]) # current request is an upload if request.method == 'POST': try: form = UploadScanForm(request.POST,request.FILES) except IOError: # sometimes uploads misbehave. connection dropped ? error_text = 'Something went wrong with the upload. ' + \ 'Please <a href="' + request.path + '">try again</a>.' return render_error(request, error_text, redirect=False, is_safe=True) if not form.is_valid(): return render_to_response(upload_template, { 'form': form, 'cover' : cover, 'issue' : issue, 'style' : style, 'replace_cover' : replace_cover, 'current_covers' : covers, 'upload_type' : upload_type, 'table_width': UPLOAD_WIDTH }, context_instance=RequestContext(request)) # if scan is actually in the form handle it if 'scan' in request.FILES: # process form scan = request.FILES['scan'] file_source = request.POST['source'] marked = 'marked' in request.POST # create OI records changeset = Changeset(indexer=request.user, state=states.PENDING) changeset.save() if upload_type == 'replacement': revision = CoverRevision(changeset=changeset, issue=issue, cover=cover, file_source=file_source, marked=marked, is_replacement = True) else: revision = CoverRevision(changeset=changeset, issue=issue, file_source=file_source, marked=marked) revision.save() # put new uploaded covers into # media/<LOCAL_NEW_SCANS>/<monthname>_<year>/ # with name # <revision_id>_<date>_<time>.<ext> scan_name = str(revision.id) + os.path.splitext(scan.name)[1] upload_dir = settings.MEDIA_ROOT + LOCAL_NEW_SCANS + \ changeset.created.strftime('%B_%Y/').lower() destination_name = upload_dir + scan_name try: # essentially only needed at beginning of the month check_cover_dir(upload_dir) except IOError: changeset.delete() error_text = "Problem with file storage for uploaded " + \ "cover, please report an error." return render_error(request, error_text, redirect=False) # write uploaded file destination = open(destination_name, 'wb') for chunk in scan.chunks(): destination.write(chunk) destination.close() try: # generate different sizes we are using im = Image.open(destination.name) if im.size[0] >= 400: generate_sizes(revision, im) else: changeset.delete() os.remove(destination.name) info_text = "Image is too small, only " + str(im.size) + \ " in size." return render_to_response(upload_template, { 'form': form, 'info' : info_text, 'cover' : cover, 'current_covers' : covers, 'replace_cover' : replace_cover, 'upload_type' : upload_type, 'table_width': UPLOAD_WIDTH, 'issue' : issue }, context_instance=RequestContext(request)) except IOError: # just in case, django *should* have taken care of file type changeset.delete() os.remove(destination.name) return render_to_response(upload_template, { 'form': form, 'info' : 'Error: File \"' + scan.name + \ '" is not a valid picture.', 'cover' : cover, 'issue' : issue, 'current_covers' : covers, 'replace_cover' : replace_cover, 'upload_type' : upload_type, 'table_width': UPLOAD_WIDTH }, context_instance=RequestContext(request)) # all done, we can save the state changeset.comments.create(commenter=request.user, text=form.cleaned_data['comments'], old_state=states.UNRESERVED, new_state=changeset.state) if 'remember_source' in request.POST: request.session['oi_file_source'] = request.POST['source'] else: request.session.pop('oi_file_source','') return HttpResponseRedirect(urlresolvers.reverse('upload_cover_complete', kwargs={'revision_id': revision.id} )) # request is a GET for the form else: if 'oi_file_source' in request.session: vars = {'source' : request.session['oi_file_source'], 'remember_source' : True} else: vars = None form = UploadScanForm(initial=vars) # display the form return render_to_response(upload_template, { 'form': form, 'cover' : cover, 'issue' : issue, 'current_covers' : covers, 'replace_cover' : replace_cover, 'active_covers' : active_covers_tags, 'upload_type' : upload_type, 'table_width': UPLOAD_WIDTH}, context_instance=RequestContext(request))