Ejemplo n.º 1
0
def import_sequences_from_file(request, issue_id, changeset_id, use_csv = False):
    changeset = get_object_or_404(Changeset, id=changeset_id)
    if request.user != changeset.indexer:
        return render_error(request,
          'Only the reservation holder may import stories.')
    try:
        # Process add form if this is a POST.
        if request.method == 'POST' and 'flatfile' in request.FILES:
            issue_revision = changeset.issuerevisions.get(issue=issue_id)
            if 'csv' in request.POST:
                use_csv = True
            else:
                use_csv = False
            lines, failure = _process_file(request, changeset,
                                           is_issue=False, use_csv=use_csv)
            if failure:
                return lines
            running_number = issue_revision.next_sequence_number()
            return _import_sequences(request, issue_id, changeset,
                                     lines, running_number)
        else:
            return HttpResponseRedirect(urlresolvers.reverse('edit',
              kwargs={ 'id': changeset.id }))

    except (Issue.DoesNotExist, Issue.MultipleObjectsReturned,
            IssueRevision.DoesNotExist):
        return render_error(request,
          'Could not find issue for id %s and changeset %s' \
            % (issue_id, changeset_id))
def upload_image(request, model_name, id, image_type, image=None):
    from apps.oi.views import DISPLAY_CLASSES, REVISION_CLASSES
    """
    Handles uploading of supporting images
    """

    display_obj = get_object_or_404(DISPLAY_CLASSES[model_name], id=id,
                                    deleted=False)

    kwargs = None
    # replacement
    if image:
        if image.object != display_obj:
            return render_error(request,
              'Image and object id do not match.',
              redirect=False, is_safe=True)
        kwargs = {'upload_type': 'replacement', 'current_image': image,
          'current_image_tag': get_generic_image_tag(image, 'current image')}
    # check if there is an image if image_type.unique is set
    else:
        img_type = get_object_or_404(ImageType, name=image_type)
        if img_type.unique:
            if Image.objects.filter(content_type=\
              ContentType.objects.get_for_model(display_obj),
              object_id=display_obj.id, type=img_type, deleted=False).count():
                return render_error(request,
                  ('%s has an image. Further images cannot be added, '
                  'only replaced.') % (esc(display_obj)),
                  redirect=False, is_safe=True)

    # check if there is a pending object deletion
    filter_dict = {model_name : display_obj, 'deleted' : True,
                   'changeset__state__in' : states.ACTIVE}
    revision = REVISION_CLASSES[model_name].objects.filter(**filter_dict)
    if revision:
        revision = revision.get()
        return render_error(request,
          ('%s is <a href="%s">pending deletion</a>. Images '
          'cannot be added or modified.') % (esc(display_obj),
          urlresolvers.reverse('compare', kwargs={'id': revision.changeset.id})),
          redirect=False, is_safe=True)

    # current request is an upload
    if request.method == 'POST':
        if image:
            return handle_uploaded_image(request, display_obj, model_name,
                                         image_type, current_image=image)
        else:
            return handle_uploaded_image(request, display_obj, model_name,
                                         image_type)
    # request is a GET for the form
    else:
        form = UploadImageForm()
        # display the form
        return _display_image_upload_form(request, form, display_obj,
                                          model_name, image_type, kwargs=kwargs)
Ejemplo n.º 3
0
def upload_variant(request, issue_id):
    """
    Handles uploading of variant covers
    """
    issue = get_object_or_404(Issue, id=issue_id)

    if issue.variant_of:
        return render_error(
            request, 'Variants can only be uploaded to the base issue.')

    # check if there is a pending issue deletion
    if IssueRevision.objects.filter(issue=issue,
                                    deleted=True,
                                    changeset__state__in=states.ACTIVE):
        revision = IssueRevision.objects.get(
            issue=issue, changeset__state__in=states.ACTIVE)
        return render_error(
            request,
            ('%s is <a href="%s">pending deletion</a>. Covers '
             'cannot be added or modified.') %
            (esc(issue),
             urlresolvers.reverse('compare',
                                  kwargs={'id': revision.changeset.id})),
            redirect=False,
            is_safe=True)

    # current request is an upload
    if request.method == 'POST':
        return handle_uploaded_cover(request, None, issue, variant=True)
    # 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 = UploadVariantScanForm(initial=vars)
        kwargs={'pending_variant_adds': Changeset.objects\
          .filter(issuerevisions__variant_of=issue,
                  #state__in=states.ACTIVE,
                  state__in=[states.PENDING,states.REVIEWING],
                  change_type__in=[CTYPES['issue_add'],
                                   CTYPES['variant_add']])}
        # display the form
        return _display_cover_upload_form(request,
                                          form,
                                          None,
                                          issue,
                                          variant=True,
                                          kwargs=kwargs)
Ejemplo n.º 4
0
def handle_uploaded_image(request, display_obj, model_name, image_type,
                          current_image=None):
    ''' process the uploaded file and generate ImageRevision '''

    try:
        form = UploadImageForm(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 _display_image_upload_form(request, form, display_obj,
                                          model_name, image_type)

    # process form
    image = form.cleaned_data['image']

    if current_image:
        revision_lock = _get_revision_lock(current_image)
        if not revision_lock:
            return render_error(
              request,
              u'Cannot replace %s as it is already reserved.' %
              current_image.description())

    # create OI records
    changeset = Changeset(indexer=request.user, state=states.OPEN,
                          change_type=CTYPES['image'])
    changeset.save()
    if current_image:
        revision_lock.changeset = changeset
        revision_lock.save()

    revision = ImageRevision(
      changeset=changeset,
      content_type=ContentType.objects.get_for_model(display_obj),
      object_id=display_obj.id, type=ImageType.objects.get(name=image_type),
      marked=form.cleaned_data['marked'])
    if current_image:
        revision.image = current_image
        revision.is_replacement = True
        revision.previous_revision = current_image.revisions.get(
                                     next_revision=None,
                                     changeset__state=states.APPROVED,
                                     committed=True)
    revision.save()
    revision.image_file.save(str(revision.id) + '.jpg', content=File(image))
    revision.changeset.submit(form.cleaned_data['comments'])
    return HttpResponseRedirect(urlresolvers.reverse('editing'))
def replace_image(request, model_name, id, image_id):
    image = get_object_or_404(Image, id=image_id, deleted=False)
    if image.reserved:
        return render_error(request,
            ('%s is reserved.') % (image.description()),
            redirect=False, is_safe=True)
    return upload_image(request, model_name, id, image.type.name, image=image)
Ejemplo n.º 6
0
def flip_artwork_flag(request, revision_id=None):
    """
    flips the status in regard to variants with different cover artwork
    """

    cover = get_object_or_404(CoverRevision, id=revision_id)
    changeset = cover.changeset
    if request.user != changeset.approver:
        return render_error(request,
          'The variant artwork status may only be changed by the approver.')
    story = list(changeset.storyrevisions.all())
    if len(story) == 1:
        for s in story:
            s.delete()
    elif len(story) == 0:
        story_revision = StoryRevision(
          changeset=changeset,
          type=StoryType.objects.get(name='cover'),
          pencils='?',
          inks='?',
          colors='?',
          sequence_number=0,
          page_count=2 if cover.is_wraparound else 1,
          )
        story_revision.save()
    else:
        # this should never happen
        raise ValueError("More than one story sequence in a cover revision.")

    return HttpResponseRedirect(urlresolvers.reverse('compare',
                                kwargs={'id': cover.changeset.id}))
Ejemplo n.º 7
0
def get_collection_for_owner(request, collection_id):
    collection = get_object_or_404(Collection, id=collection_id)
    if collection.collector.user != request.user:
        return None, render_error(request,
            'Only the owner of a collection can add issues to it.',
            redirect=False)
    return collection, None
Ejemplo n.º 8
0
def get_collection_for_owner(request, collection_id):
    collection = get_object_or_404(Collection, id=collection_id)
    if collection.collector.user != request.user:
        return None, render_error(request,
            'Only the owner of a collection can add issues to it.',
            redirect=False)
    return collection, None
Ejemplo n.º 9
0
def replace_image(request, model_name, id, image_id):
    image = get_object_or_404(Image, id=image_id, deleted=False)
    if is_locked(image):
        return render_error(
          request,
          ('%s is reserved.') % (image.description()),
          redirect=False, is_safe=True)
    return upload_image(request, model_name, id, image.type.name, image=image)
Ejemplo n.º 10
0
 def process_response(self, request, response): 
     if request.user.is_authenticated():
         logout(request)
         return render_error(request, "Online editing is currently turned "
             "off, no user can login. We are working on the site. "
             "More information on the <a href='/'>main page</a>.", 
           redirect=False, is_safe=True)
     return response
Ejemplo n.º 11
0
def unsubscribe_series(request, subscription_id):
    subscription = get_object_or_404(Subscription, id=subscription_id)
    if subscription.collection.collector.user != request.user:
        return render_error(request,
            'Only the owner of a collection can unsubscribe series.',
            redirect=False)
    subscription.delete()
    return HttpResponseRedirect(
             urlresolvers.reverse('subscriptions_collection',
               kwargs={'collection_id': subscription.collection.id}))
Ejemplo n.º 12
0
def dummy(request,
          id=None,
          issue_id=None,
          model_name=None,
          image_type=None,
          image_id=None):
    return render_error(request, \
      "Online editing and change history are currently turned off. "
      "We are working on the site. More information on the "
      "<a href='/'>main page</a>.", redirect=False, is_safe=True)
Ejemplo n.º 13
0
 def process_response(self, request, response):
     if request.user.is_authenticated:
         logout(request)
         return render_error(
             request, "Online editing is currently turned "
             "off, no user can login. We are working on the site. "
             "More information on the <a href='/'>main page</a>.",
             redirect=False,
             is_safe=True)
     return response
Ejemplo n.º 14
0
def _handle_import_error(request, changeset, error_text):
    response = render_error(request,
      '%s Back to the <a href="%s">editing page</a>.' % \
        (error_text, urlresolvers.reverse('edit',
                                          kwargs={'id': changeset.id})),
      is_safe=True)
    # there might be a temporary file attached
    if hasattr(request, "tmpfile"):
        request.tmpfile.close()
        os.remove(request.tmpfile_name)
    return response, True
Ejemplo n.º 15
0
def unsubscribe_series(request, subscription_id):
    subscription = get_object_or_404(Subscription, id=subscription_id)
    if subscription.collection.collector.user != request.user:
        return render_error(
          request, 'Only the owner of a collection can unsubscribe series.',
          redirect=False)
    subscription.delete()
    return HttpResponseRedirect(
             urlresolvers.reverse('subscriptions_collection',
                                  kwargs={'collection_id':
                                          subscription.collection.id}))
def _handle_import_error(request, changeset, error_text):
    response = render_error(request,
      '%s Back to the <a href="%s">editing page</a>.' % \
        (error_text, urlresolvers.reverse('edit',
                                          kwargs={'id': changeset.id})),
      is_safe=True)
    # there might be a temporary file attached
    if hasattr(request, "tmpfile"):
        request.tmpfile.close()
        os.remove(request.tmpfile_name)
    return response, True
Ejemplo n.º 17
0
def upload_variant(request, issue_id):
    """
    Handles uploading of variant covers
    """
    issue = get_object_or_404(Issue, id=issue_id)

    if issue.variant_of:
        return render_error(request,
          'Variants can only be uploaded to the base issue.')

    # check if there is a pending issue deletion
    if IssueRevision.objects.filter(issue=issue, deleted=True,
                                    changeset__state__in=states.ACTIVE):
        revision = IssueRevision.objects.get(issue=issue,
          changeset__state__in=states.ACTIVE)
        return render_error(request,
          ('%s is <a href="%s">pending deletion</a>. Covers '
          'cannot be added or modified.') % (esc(issue),
          urlresolvers.reverse('compare', kwargs={'id': revision.changeset.id})),
          redirect=False, is_safe=True)

    # current request is an upload
    if request.method == 'POST':
        return handle_uploaded_cover(request, None, issue, variant=True)
    # 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 = UploadVariantScanForm(initial=vars)
        kwargs={'pending_variant_adds': Changeset.objects\
          .filter(issuerevisions__variant_of=issue,
                  #state__in=states.ACTIVE,
                  state__in=[states.PENDING,states.REVIEWING],
                  change_type__in=[CTYPES['issue_add'],
                                   CTYPES['variant_add']])}
        # display the form
        return _display_cover_upload_form(request, form, None, issue,
                                          variant=True, kwargs=kwargs)
Ejemplo n.º 18
0
def topic(request, id):
    topic = get_object_or_404(Topic, id=id)

    if not request.user.has_perm('indexer.can_vote'):
        return render_error(request,
                            'You do not have permission to vote on this topic.')
    # Note that if this was a secret ballot, this will be an empty
    # queryset.  That is OK, the UI won't look at it in that case.
    # But this is why "voted" is not just a check for at least one vote here.
    votes = topic.options.filter(votes__voter=request.user)

    return render(request, 'voting/topic.html',
                  {'topic': topic,
                   'voted': topic.has_vote_from(request.user),
                   'votes': votes,
                   'closed': topic.deadline < datetime.now() \
                             or topic.result_calculated,
                   'settings': settings})
Ejemplo n.º 19
0
def _cant_get_key(request):
    return render_error(
        request,
        'Internal data for selecting objects is corrupted. If this message '
        'persists try logging out and logging in.',
        redirect=False)
Ejemplo n.º 20
0
def select_object(request, select_key):
    try:
        data = get_select_data(request, select_key)
    except KeyError:
        return _cant_get_key(request)
    if request.method == 'GET':
        if 'refine_search' in request.GET or 'search_issue' in request.GET:
            request_data = request.GET
        else:
            request_data = None
        initial = data.get('initial', {})
        initial['select_key'] = select_key
        publisher = data.get('publisher', False)
        series = data.get('series', False)
        issue = data.get('issue', False)
        story = data.get('story', False)
        search_form, cache_form = get_select_forms(request,
                                                   initial,
                                                   request_data,
                                                   publisher=publisher,
                                                   series=series,
                                                   issue=issue,
                                                   story=story)
        haystack_form = FacetedSearchForm()
        return render(
            request, 'oi/edit/select_object.html', {
                'heading': data['heading'],
                'select_key': select_key,
                'cache_form': cache_form,
                'search_form': search_form,
                'haystack_form': haystack_form,
                'publisher': publisher,
                'series': series,
                'issue': issue,
                'story': story,
                'target': data['target']
            })

    if 'cancel' in request.POST:
        return data['cancel']
    elif 'select_object' in request.POST:
        try:
            choice = request.POST['object_choice']
            object_type, selected_id = choice.split('_')
            if object_type == 'cover':
                object_type = 'story'
        except MultiValueDictKeyError:
            return render_error(request, 'You did not select a cached object. '
                                'Please use the back button to return.',
                                redirect=False)
    elif 'search_select' in request.POST:
        choice = request.POST['object_choice']
        object_type, selected_id = choice.split('_')
    elif 'entered_issue_id' in request.POST:
        object_type = 'issue'
        try:
            selected_id = int(request.POST['entered_issue_id'])
        except ValueError:
            return render_error(request,
                                'Entered Id must be an integer number. '
                                'Please use the back button to return.',
                                redirect=False)
    elif 'entered_story_id' in request.POST:
        object_type = 'story'
        try:
            selected_id = int(request.POST['entered_story_id'])
        except ValueError:
            return render_error(request,
                                'Entered Id must be an integer number. '
                                'Please use the back button to return.',
                                redirect=False)
    else:
        raise ValueError
    return data['return'](request, data, object_type, selected_id)
Ejemplo n.º 21
0
def upload_image(request, model_name, id, image_type, image=None):
    from apps.oi.views import DISPLAY_CLASSES, REVISION_CLASSES
    """
    Handles uploading of supporting images
    """

    display_obj = get_object_or_404(DISPLAY_CLASSES[model_name], id=id,
                                    deleted=False)

    kwargs = None
    # replacement
    if image:
        if image.object != display_obj:
            return render_error(
              request, 'Image and object id do not match.',
              redirect=False, is_safe=True)
        kwargs = {
          'upload_type': 'replacement', 'current_image': image,
          'current_image_tag': get_generic_image_tag(image, 'current image')}
    # check if there is an image if image_type.unique is set
    else:
        img_type = get_object_or_404(ImageType, name=image_type)
        if img_type.unique:
            if Image.objects.filter(
              content_type=ContentType.objects.get_for_model(display_obj),
              object_id=display_obj.id, type=img_type, deleted=False).count():
                return render_error(
                  request,
                  ('%s has an image. Further images cannot be added, '
                   'only replaced.') % (esc(display_obj)),
                  redirect=False, is_safe=True)

    # check if there is a pending object deletion
    filter_dict = {model_name: display_obj, 'deleted': True,
                   'changeset__state__in': states.ACTIVE}
    revision = REVISION_CLASSES[model_name].objects.filter(**filter_dict)
    if revision:
        revision = revision.get()
        return render_error(
          request,
          ('%s is <a href="%s">pending deletion</a>. Images '
           'cannot be added or modified.') % (
            esc(display_obj), urlresolvers.reverse(
              'compare', kwargs={'id': revision.changeset.id})),
          redirect=False, is_safe=True)

    # current request is an upload
    if request.method == 'POST':
        if image:
            return handle_uploaded_image(request, display_obj, model_name,
                                         image_type, current_image=image)
        else:
            return handle_uploaded_image(request, display_obj, model_name,
                                         image_type)
    # request is a GET for the form
    else:
        form = UploadImageForm()
        # display the form
        return _display_image_upload_form(request, form, display_obj,
                                          model_name, image_type,
                                          kwargs=kwargs)
Ejemplo n.º 22
0
def import_issue_from_file(request, issue_id, changeset_id, use_csv = False):
    changeset = get_object_or_404(Changeset, id=changeset_id)
    if request.user != changeset.indexer:
        return render_error(request,
          'Only the reservation holder may import issue data.')
    try:
        # Process add form if this is a POST.
        if request.method == 'POST' and 'flatfile' in request.FILES:
            issue_revision = changeset.issuerevisions.get(issue=issue_id)
            if StoryRevision.objects.filter(changeset=changeset).count():
                return render_error(request,
                  'There are already sequences present for %s in this'
                  ' changeset. Back to the <a href="%s">editing page</a>.'\
                   % (esc(issue_revision), urlresolvers.reverse('edit',
                      kwargs={'id': changeset.id})), is_safe=True)
            if 'csv' in request.POST:
                use_csv = True
            else:
                use_csv = False
            lines, failure = _process_file(request, changeset,
                                           is_issue=True, use_csv=use_csv)
            if failure:
                return lines

            # parse the issue line
            issue_fields = lines.pop(0)
            issue_revision.number = issue_fields[NUMBER].strip()
            issue_revision.volume, issue_revision.no_volume = \
              _parse_volume(issue_fields[VOLUME].strip())

            indicia_publisher_name, issue_revision.indicia_pub_not_printed = \
              _check_for_none(issue_fields[INDICIA_PUBLISHER])
            indicia_publisher, failure = _find_publisher_object(request,
              changeset, indicia_publisher_name,
              IndiciaPublisher.objects.all(), "Indicia publisher",
              issue_revision.issue.series.publisher)
            if failure:
                return indicia_publisher
            else:
                issue_revision.indicia_publisher = indicia_publisher

            brand_name, issue_revision.no_brand = \
              _check_for_none(issue_fields[BRAND])
            brand, failure = _find_publisher_object(request, changeset,
              brand_name, Brand.objects.all(), "Brand",
              issue_revision.issue.series.publisher)
            if failure:
                return brand
            else:
                issue_revision.brand = brand

            issue_revision.publication_date = issue_fields[PUBLICATION_DATE]\
              .strip()
            issue_revision.key_date = issue_fields[KEY_DATE].strip()\
                                                            .replace('.', '-')
            if issue_revision.key_date and \
              not re.search(KEY_DATE_REGEXP, issue_revision.key_date):
                return render_error(request,
                  "key_date '%s' is invalid." % issue_revision.key_date)

            issue_revision.indicia_frequency, \
              issue_revision.no_indicia_frequency = \
              _check_for_none(issue_fields[INDICIA_FREQUENCY])
            issue_revision.price = issue_fields[PRICE].strip()
            issue_revision.page_count, issue_revision.page_count_uncertain =\
              _check_page_count(issue_fields[ISSUE_PAGE_COUNT])
            issue_revision.editing, issue_revision.no_editing = \
              _check_for_none(issue_fields[ISSUE_EDITING])
            issue_revision.isbn, issue_revision.no_isbn = \
              _check_for_none(issue_fields[ISBN])
            issue_revision.barcode, issue_revision.no_barcode = \
              _check_for_none(issue_fields[BARCODE])
            on_sale_date = issue_fields[ON_SALE_DATE].strip()
            if on_sale_date:
                if on_sale_date[-1] == '?':
                    issue_revision.on_sale_date_uncertain = True
                    on_sale_date = on_sale_date[:-1].strip()
                else:
                    issue_revision.on_sale_date_uncertain = False
                try:
                    # only full dates can be imported
                    sale_date = datetime.strptime(on_sale_date, '%Y-%m-%d')
                    issue_revision.year_on_sale = sale_date.year
                    issue_revision.month_on_sale = sale_date.month
                    issue_revision.day_on_sale = sale_date.day
                except ValueError:
                    return render_error(request,
                      "on-sale_date '%s' is invalid." % \
                      on_sale_date)
            issue_revision.notes = issue_fields[ISSUE_NOTES].strip()
            if issue_revision.series.has_issue_title:
                issue_revision.title, issue_revision.no_title = \
                _check_for_none(issue_fields[ISSUE_TITLE])
            issue_revision.keywords = issue_fields[ISSUE_KEYWORDS].strip()
            issue_revision.save()
            running_number = 0
            return _import_sequences(request, issue_id, changeset,
                                     lines, running_number)
        else:
            return HttpResponseRedirect(urlresolvers.reverse('edit',
              kwargs={ 'id': changeset.id }))

    except (Issue.DoesNotExist, Issue.MultipleObjectsReturned,
            IssueRevision.DoesNotExist):
        return render_error(request,
          'Could not find issue for id %s and changeset %s' \
            % (issue_id, changeset_id))
Ejemplo n.º 23
0
def download(request):

    if request.method == 'POST':
        form = DownloadForm(request.POST)
        if form.is_valid():
            cd = form.cleaned_data

            # Note that the submit input is never present in the cleaned data.
            file = settings.MYSQL_DUMP
            if ('postgres' in request.POST):
                file = settings.POSTGRES_DUMP
            path = os.path.join(settings.MEDIA_ROOT, settings.DUMP_DIR, file)

            delta = settings.DOWNLOAD_DELTA
            recently = datetime.now() - timedelta(minutes=delta)
            if Download.objects.filter(user=request.user,
                                       description__contains=file,
                                       timestamp__gt=recently).count():
                return render_error(
                    request,
                    ("You have started a download of this file within the "
                     "last %d minutes.  Please check your download window.  "
                     "If you need to start a new download, please wait at "
                     "least %d minutes in order to avoid consuming excess "
                     "bandwidth.") % (delta, delta))

            desc = {'file': file, 'accepted license': True}
            if 'purpose' in cd and cd['purpose']:
                desc['purpose'] = cd['purpose']
            if 'usage' in cd and cd['usage']:
                desc['usage'] = cd['usage']

            record = Download(user=request.user, description=repr(desc))
            record.save()

            response = FileResponse(open(path, 'rb'),
                                    content_type='application/zip')
            response['Content-Disposition'] = \
                'attachment; filename=current.zip'
            return response
    else:
        form = DownloadForm()

    m_path = os.path.join(settings.MEDIA_ROOT, settings.DUMP_DIR,
                          settings.MYSQL_DUMP)
    p_path = os.path.join(settings.MEDIA_ROOT, settings.DUMP_DIR,
                          settings.POSTGRES_DUMP)

    # Use a list of tuples because we want the MySQL dump (our primary format)
    # to be first.
    timestamps = []
    for dump_info in (('MySQL', m_path), ('PostgreSQL-compatible', p_path)):
        try:
            timestamps.append(
                (dump_info[0],
                 datetime.utcfromtimestamp(
                    os.stat(dump_info[1])[stat.ST_MTIME])))
        except OSError, ose:
            if ose.errno == errno.ENOENT:
                timestamps.append((dump_info[0], 'never'))
            else:
                raise
Ejemplo n.º 24
0
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

    # 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
    # no cover_id, therefore upload a cover to an issue (first or variant)
    else:
        issue = get_object_or_404(Issue, id=issue_id)
        if not issue.can_have_cover():
            return render_error(request,
              'No covers for non-comics publications if the issue has less'
              ' than 10% indexed comics content.', redirect=False)
        cover = None

    # check if there is a pending issue deletion
    if IssueRevision.objects.filter(issue=issue, deleted=True,
                                    changeset__state__in=states.ACTIVE):
        revision = IssueRevision.objects.get(issue=issue,
          changeset__state__in=states.ACTIVE)
        return render_error(request,
          ('%s is <a href="%s">pending deletion</a>. Covers '
          'cannot be added or modified.') % (esc(issue),
          urlresolvers.reverse('compare', kwargs={'id': revision.changeset.id})),
          redirect=False, is_safe=True)

    # check if there is a pending change for the cover
    # if POST, get a lock
    if cover_id and request.method == 'POST':
        revision_lock = _get_revision_lock(cover)
        if not revision_lock:
            return render_error(
              request,
              u'Cannot replace %s as it is already reserved.' %
              cover.issue)
    # if GET, check for a lock
    elif cover_id and is_locked(cover):
        return render_error(
          request,
          ('There currently is a pending replacement for this cover of %s.')
          % (cover.issue), redirect=False, is_safe=True)
    else:
        revision_lock = None

    # current request is an upload
    if request.method == 'POST':
        return handle_uploaded_cover(request, cover, issue,
                                     revision_lock=revision_lock)
    # 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 _display_cover_upload_form(request, form, cover, issue)
Ejemplo n.º 25
0
def handle_uploaded_cover(request, cover, issue, variant=False,
                          revision_lock=None):
    ''' process the uploaded file and generate CoverRevision '''

    try:
        if variant:
            form = UploadVariantScanForm(request.POST, request.FILES)
        else:
            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 _display_cover_upload_form(request, form, cover, issue,
                                          variant=variant)

    # process form
    if form.cleaned_data['is_gatefold']:
        return handle_gatefold_cover(request, cover, issue, form)
    scan = form.cleaned_data['scan']
    file_source = form.cleaned_data['source']
    marked = form.cleaned_data['marked']

    # create OI records
    changeset = Changeset(indexer=request.user, state=states.OPEN,
                            change_type=CTYPES['cover'])
    changeset.save()

    if cover: # upload_type is 'replacement':
        revision = CoverRevision(changeset=changeset, issue=issue,
            cover=cover, file_source=file_source, marked=marked,
            is_replacement = True)
        revision_lock.changeset = changeset
        revision_lock.save()
        revision.previous_revision = cover.revisions.get(
                                           next_revision=None,
                                           changeset__state=states.APPROVED,
                                           committed=True)
    else:
        revision = CoverRevision(changeset=changeset, issue=issue,
            file_source=file_source, marked=marked)
    revision.save()

    # if uploading a variant, generate an issue_revision for
    # the variant issue and copy the values which would not change
    # TODO are these reasonable assumptions below ?
    if variant:
        current_variants = issue.variant_set.all().order_by('-sort_code')
        if current_variants:
            add_after = current_variants[0]
        else:
            add_after = issue
        issue_revision = IssueRevision(changeset=changeset,
          after=add_after,
          number=issue.number,
          title=issue.title,
          no_title=issue.no_title,
          volume=issue.volume,
          no_volume=issue.no_volume,
          display_volume_with_number=issue.display_volume_with_number,
          variant_of=issue,
          variant_name=form.cleaned_data['variant_name'],
          page_count=issue.page_count,
          page_count_uncertain=issue.page_count_uncertain,
          series=issue.series,
          editing=issue.editing,
          no_editing=issue.no_editing,
          reservation_requested=form.cleaned_data['reservation_requested']
          )
        issue_revision.save()
        if form.cleaned_data['variant_artwork']:
            story_revision = StoryRevision(changeset=changeset,
              type=StoryType.objects.get(name='cover'),
              no_script=True,
              pencils='?',
              inks='?',
              colors='?',
              no_letters=True,
              no_editing=True,
              sequence_number=0,
              page_count=2 if form.cleaned_data['is_wraparound'] else 1,
              )
            story_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 = os.path.join(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 = pyImage.open(destination.name)
        large_enough = False
        if form.cleaned_data['is_wraparound']:
            # wraparounds need to have twice the width
            if im.size[0] >= 800 and im.size[1] >= 400:
                large_enough = True
        elif min(im.size) >= 400:
            large_enough = True
        if large_enough:
            if form.cleaned_data['is_wraparound']:
                revision.is_wraparound = True
                revision.front_left = im.size[0]/2
                revision.front_right = im.size[0]
                revision.front_bottom = im.size[1]
                revision.front_top = 0
                revision.save()
            generate_sizes(revision, im)
        else:
            changeset.delete()
            os.remove(destination.name)
            info_text = "Image is too small, only " + str(im.size) + \
                        " in size."
            return _display_cover_upload_form(request, form, cover, issue,
                info_text=info_text, variant=variant)
    except IOError as e:
        # just in case, django *should* have taken care of file type
        changeset.delete()
        os.remove(destination.name)
        info_text = 'Error: File \"' + scan.name + \
                    '" is not a valid picture.'
        return _display_cover_upload_form(request, form, cover, issue,
            info_text=info_text, variant=variant)

    # all done, we can save the state
    return finish_cover_revision(request, revision, form.cleaned_data)
Ejemplo n.º 26
0
def process_edited_gatefold_cover(request):
    ''' process the edited gatefold cover and generate CoverRevision '''

    if request.method != 'POST':
        return render_error(request,
            'This page may only be accessed through the proper form',
            redirect=False)

    form = GatefoldScanForm(request.POST)
    if not form.is_valid():
        error_text = 'Error: Something went wrong in the file upload.'
        return render_error(request, error_text, redirect=False)
    cd = form.cleaned_data

    tmpdir = settings.MEDIA_ROOT + LOCAL_NEW_SCANS + 'tmp'
    scan_name = cd['scan_name']
    tmp_name = os.path.join(tmpdir, scan_name)

    if 'discard' in request.POST:
        os.remove(tmp_name)
        return HttpResponseRedirect(urlresolvers.reverse('edit_covers',
                kwargs={'issue_id': cd['issue_id']} ))

    # create OI records
    changeset = Changeset(indexer=request.user, state=states.OPEN,
                            change_type=CTYPES['cover'])

    if cd['cover_id']:
        cover = get_object_or_404(Cover, id=cd['cover_id'])
        issue = cover.issue
        # check if there is a pending change for the cover
        revision_lock = _get_revision_lock(cover)
        if not revision_lock:
            return render_error(
              request,
              u'Cannot replace %s as it is already reserved.' %
              cover.issue)
        changeset.save()
        revision_lock.changeset = changeset
        revision_lock.save()

        revision = CoverRevision(changeset=changeset, issue=issue,
            cover=cover, file_source=cd['source'], marked=cd['marked'],
            is_replacement = True)
    # no cover_id, therefore upload a cover to an issue (first or variant)
    else:
        changeset.save()
        issue = get_object_or_404(Issue, id=cd['issue_id'])
        cover = None
        revision = CoverRevision(changeset=changeset, issue=issue,
            file_source=cd['source'], marked=cd['marked'])
    revision.save()

    scan_name = str(revision.id) + os.path.splitext(tmp_name)[1]
    upload_dir = settings.MEDIA_ROOT + LOCAL_NEW_SCANS + \
                   changeset.created.strftime('%B_%Y').lower()
    destination_name = os.path.join(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)

    shutil.move(tmp_name, destination_name)

    im = pyImage.open(destination_name)
    revision.is_wraparound = True
    # convert from scaled to real values
    width = cd['width']
    height = cd['height']
    left = cd['left']
    top = cd['top']
    revision.front_left = left
    revision.front_right = left + width
    revision.front_top = top
    revision.front_bottom = top + height
    revision.save()
    generate_sizes(revision, im)

    return finish_cover_revision(request, revision, cd)
Ejemplo n.º 27
0
def _cant_get_key(request):
    return render_error(
      request,
      'Internal data for selecting objects is corrupted. If this message '
      'persists try logging out and logging in.', redirect=False)
Ejemplo n.º 28
0
def process_edited_gatefold_cover(request):
    ''' process the edited gatefold cover and generate CoverRevision '''

    if request.method != 'POST':
        return render_error(
            request,
            'This page may only be accessed through the proper form',
            redirect=False)

    form = GatefoldScanForm(request.POST)
    if not form.is_valid():
        error_text = 'Error: Something went wrong in the file upload.'
        return render_error(request, error_text, redirect=False)
    cd = form.cleaned_data

    tmpdir = settings.MEDIA_ROOT + LOCAL_NEW_SCANS + 'tmp'
    scan_name = cd['scan_name']
    tmp_name = os.path.join(tmpdir, scan_name)

    if 'discard' in request.POST:
        os.remove(tmp_name)
        return HttpResponseRedirect(
            urlresolvers.reverse('edit_covers',
                                 kwargs={'issue_id': cd['issue_id']}))

    # create OI records
    changeset = Changeset(indexer=request.user,
                          state=states.OPEN,
                          change_type=CTYPES['cover'])

    if cd['cover_id']:
        cover = get_object_or_404(Cover, id=cd['cover_id'])
        issue = cover.issue
        # check if there is a pending change for the cover
        revision_lock = _get_revision_lock(cover)
        if not revision_lock:
            return render_error(
                request,
                'Cannot replace %s as it is already reserved.' % cover.issue)
        changeset.save()
        revision_lock.changeset = changeset
        revision_lock.save()

        revision = CoverRevision(changeset=changeset,
                                 issue=issue,
                                 cover=cover,
                                 file_source=cd['source'],
                                 marked=cd['marked'],
                                 is_replacement=True)
    # no cover_id, therefore upload a cover to an issue (first or variant)
    else:
        changeset.save()
        issue = get_object_or_404(Issue, id=cd['issue_id'])
        cover = None
        revision = CoverRevision(changeset=changeset,
                                 issue=issue,
                                 file_source=cd['source'],
                                 marked=cd['marked'])
    revision.save()

    scan_name = str(revision.id) + os.path.splitext(tmp_name)[1]
    upload_dir = settings.MEDIA_ROOT + LOCAL_NEW_SCANS + \
                   changeset.created.strftime('%B_%Y').lower()
    destination_name = os.path.join(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)

    shutil.move(tmp_name, destination_name)

    im = pyImage.open(destination_name)
    revision.is_wraparound = True
    # convert from scaled to real values
    width = cd['width']
    height = cd['height']
    left = cd['left']
    top = cd['top']
    revision.front_left = left
    revision.front_right = left + width
    revision.front_top = top
    revision.front_bottom = top + height
    revision.save()
    generate_sizes(revision, im)

    return finish_cover_revision(request, revision, cd)
Ejemplo n.º 29
0
def handle_uploaded_cover(request,
                          cover,
                          issue,
                          variant=False,
                          revision_lock=None):
    ''' process the uploaded file and generate CoverRevision '''

    try:
        if variant:
            form = UploadVariantScanForm(request.POST, request.FILES)
        else:
            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 _display_cover_upload_form(request,
                                          form,
                                          cover,
                                          issue,
                                          variant=variant)

    # process form
    if form.cleaned_data['is_gatefold']:
        return handle_gatefold_cover(request, cover, issue, form)
    scan = form.cleaned_data['scan']
    file_source = form.cleaned_data['source']
    marked = form.cleaned_data['marked']

    # create OI records
    changeset = Changeset(indexer=request.user,
                          state=states.OPEN,
                          change_type=CTYPES['cover'])
    changeset.save()

    if cover:  # upload_type is 'replacement':
        revision = CoverRevision(changeset=changeset,
                                 issue=issue,
                                 cover=cover,
                                 file_source=file_source,
                                 marked=marked,
                                 is_replacement=True)
        revision_lock.changeset = changeset
        revision_lock.save()
        revision.previous_revision = cover.revisions.get(
            next_revision=None,
            changeset__state=states.APPROVED,
            committed=True)
    else:
        revision = CoverRevision(changeset=changeset,
                                 issue=issue,
                                 file_source=file_source,
                                 marked=marked)
    revision.save()

    # if uploading a variant, generate an issue_revision for
    # the variant issue and copy the values which would not change
    # TODO are these reasonable assumptions below ?
    if variant:
        current_variants = issue.variant_set.all().order_by('-sort_code')
        if current_variants:
            add_after = current_variants[0]
        else:
            add_after = issue
        issue_revision = IssueRevision(
            changeset=changeset,
            after=add_after,
            number=issue.number,
            title=issue.title,
            no_title=issue.no_title,
            volume=issue.volume,
            no_volume=issue.no_volume,
            display_volume_with_number=issue.display_volume_with_number,
            variant_of=issue,
            variant_name=form.cleaned_data['variant_name'],
            page_count=issue.page_count,
            page_count_uncertain=issue.page_count_uncertain,
            series=issue.series,
            editing=issue.editing,
            no_editing=issue.no_editing,
            reservation_requested=form.cleaned_data['reservation_requested'])
        issue_revision.save()
        if form.cleaned_data['variant_artwork']:
            story_revision = StoryRevision(
                changeset=changeset,
                type=StoryType.objects.get(name='cover'),
                no_script=True,
                pencils='?',
                inks='?',
                colors='?',
                no_letters=True,
                no_editing=True,
                sequence_number=0,
                page_count=2 if form.cleaned_data['is_wraparound'] else 1,
            )
            story_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 = os.path.join(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 = pyImage.open(destination.name)
        large_enough = False
        if form.cleaned_data['is_wraparound']:
            # wraparounds need to have twice the width
            if im.size[0] >= 800 and im.size[1] >= 400:
                large_enough = True
        elif min(im.size) >= 400:
            large_enough = True
        if large_enough:
            if form.cleaned_data['is_wraparound']:
                revision.is_wraparound = True
                revision.front_left = im.size[0] / 2
                revision.front_right = im.size[0]
                revision.front_bottom = im.size[1]
                revision.front_top = 0
                revision.save()
            generate_sizes(revision, im)
        else:
            changeset.delete()
            os.remove(destination.name)
            info_text = "Image is too small, only " + str(im.size) + \
                        " in size."
            return _display_cover_upload_form(request,
                                              form,
                                              cover,
                                              issue,
                                              info_text=info_text,
                                              variant=variant)
    except IOError as e:
        # just in case, django *should* have taken care of file type
        changeset.delete()
        os.remove(destination.name)
        info_text = 'Error: File \"' + scan.name + \
                    '" is not a valid picture.'
        return _display_cover_upload_form(request,
                                          form,
                                          cover,
                                          issue,
                                          info_text=info_text,
                                          variant=variant)

    # all done, we can save the state
    return finish_cover_revision(request, revision, form.cleaned_data)
Ejemplo n.º 30
0
def vote(request):
    if request.method != 'POST':
        return render_error(request,
                            'Please access this page through the correct form.')

    first = True
    topic = None
    voter = None
    option_params = request.POST.getlist('option')
    ranks = {}
    if not option_params:
        # ranked_choice, collect all ranks
        values = request.POST.keys()
        for value in values:
            if value.startswith('option'):
                if request.POST[value]:
                    try:
                        ranks[int(value[7:])] = int(request.POST[value])
                    except ValueError:
                        return render_error(request,
                        'You must enter a full number for the ranking.')
                else:
                    ranks[int(value[7:])] = None
        options = Option.objects.filter(id__in=ranks.keys())
    else:
        options = Option.objects.filter(id__in=option_params)
        # Get all of these now because we may need to iterate twice.
        options = options.select_related('topic__agenda', 'topic__vote_type').all()
    if not options:
        return render_error(request,
                            'You must choose at least one option to vote.')
    for option in options:
        if first is True:
            first = False
            topic = option.topic

            if not request.user.has_perm('%s.%s' %
                (topic.agenda.permission.content_type.app_label,
                 topic.agenda.permission.codename)):
                return render_error(request,
                  'We are sorry, but you do not have permission to vote '
                  'on this ballot.  You must have the "%s" permission.' %
                   topic.agenda.permission.name)

            if topic.token is not None and \
               request.POST['token'].strip() != topic.token:
                return render_error(request,
                  'You must supply an authorization token in order '
                  'to vote on this topic.')

            if topic.vote_type.max_votes is not None and \
               len(option_params) > topic.vote_type.max_votes:
                plural = 's' if len(option_params) > 1 else ''
                return render_error(request,
                  'You may not vote for more than %d option%s' %
                  (topic.vote_type.max_votes, plural))

            if topic.agenda.secret_ballot:
                receipts = Receipt.objects.filter(topic=topic, voter=request.user)
                already_voted = receipts.count() > 0
            else:
                voter = request.user
                already_voted = Vote.objects.filter(option__topic=topic,
                                                    voter=request.user).count() > 0

            if already_voted:
                return render_error(request,
                  'You have already voted on this ballot.  If you wish to change '
                  'your vote, please contact the voting administrator at ' +
                  settings.EMAIL_VOTING_ADMIN)

        if not option_params:
            # for ranked choice options can be empty, set these last in ranking
            if option.id in ranks:
                rank = ranks[option.id]
            if not rank:
                rank = max(ranks.values()) + 1
        else:
            rank = None
        vote = Vote(option=option, voter=voter, rank=rank)
        vote.save()

    if topic.agenda.secret_ballot:
        # We email the salt and the vote string to the voter, and store
        # the receipt key in the database.  This way they can prove that
        # they voted a particular way by sending us back those two values,
        # and repair or change a vote.
        vote_ids = ', '.join(option_params)
        salt = hashlib.sha1(str(random())).hexdigest()[:5]
        key = hashlib.sha1(salt + vote_ids).hexdigest()

        receipt = Receipt(voter=request.user,
                          topic=option.topic,
                          vote_key=key)
        receipt.save()

        # Log the data as a backup in case of mail sending/receiving problems.
        # Technically, this makes it not a secret ballot, but it takes some
        # work to interpret the log, and there's always been a human counting
        # the ballots before, so this allows for at least as much secrecy
        # as before.
        # Use unbuffered appends because we don't want concurrent writes to get
        # spliced due to buffering.
        path = os.path.join(settings.VOTING_DIR, 'vote_record_%d' % topic.id)
        voting_record = open(path, 'a', 0)
        voting_record.write('%d | %s | %s | %s\n' %
                            (request.user.id, salt, vote_ids, key))
        voting_record.close()

        vote_values = "\n".join([unicode(o) for o in options])
        send_mail(from_email=settings.EMAIL_VOTING_FROM,
                  recipient_list=[request.user.email],
                  subject="GCD secret ballot receipt",
                  message=EMAIL_RECEIPT % (topic, vote_values,
                                           settings.EMAIL_VOTING_ADMIN,
                                           salt, vote_ids),
                  fail_silently=(not settings.BETA))

    return HttpResponseRedirect(urlresolvers.reverse('ballot',
      kwargs={ 'id': option.topic.id }))
Ejemplo n.º 31
0
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

    # 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
    # no cover_id, therefore upload a cover to an issue (first or variant)
    else:
        issue = get_object_or_404(Issue, id=issue_id)
        if not issue.can_have_cover():
            return render_error(
                request,
                'No covers for non-comics publications if the issue has less'
                ' than 10% indexed comics content.',
                redirect=False)
        cover = None

    # check if there is a pending issue deletion
    if IssueRevision.objects.filter(issue=issue,
                                    deleted=True,
                                    changeset__state__in=states.ACTIVE):
        revision = IssueRevision.objects.get(
            issue=issue, changeset__state__in=states.ACTIVE)
        return render_error(
            request,
            ('%s is <a href="%s">pending deletion</a>. Covers '
             'cannot be added or modified.') %
            (esc(issue),
             urlresolvers.reverse('compare',
                                  kwargs={'id': revision.changeset.id})),
            redirect=False,
            is_safe=True)

    # check if there is a pending change for the cover
    # if POST, get a lock
    if cover_id and request.method == 'POST':
        revision_lock = _get_revision_lock(cover)
        if not revision_lock:
            return render_error(
                request,
                'Cannot replace %s as it is already reserved.' % cover.issue)
    # if GET, check for a lock
    elif cover_id and is_locked(cover):
        return render_error(
            request,
            ('There currently is a pending replacement for this cover of %s.')
            % (cover.issue),
            redirect=False,
            is_safe=True)
    else:
        revision_lock = None

    # current request is an upload
    if request.method == 'POST':
        return handle_uploaded_cover(request,
                                     cover,
                                     issue,
                                     revision_lock=revision_lock)
    # 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 _display_cover_upload_form(request, form, cover, issue)
Ejemplo n.º 32
0
def select_object(request, select_key):
    try:
        data = get_select_data(request, select_key)
    except KeyError:
        return _cant_get_key(request)
    if request.method == 'GET':
        if 'refine_search' in request.GET or 'search_issue' in request.GET:
            request_data = request.GET
        else:
            request_data = None
        initial = data.get('initial', {})
        initial['select_key'] = select_key
        publisher = data.get('publisher', False)
        series = data.get('series', False)
        issue = data.get('issue', False)
        story = data.get('story', False)
        search_form, cache_form = get_select_forms(request,
                                                   initial,
                                                   request_data,
                                                   publisher=publisher,
                                                   series=series,
                                                   issue=issue,
                                                   story=story)
        haystack_form = FacetedSearchForm()
        return render(request, 'oi/edit/select_object.html',
                      {'heading': data['heading'],
                       'select_key': select_key,
                       'cache_form': cache_form,
                       'search_form': search_form,
                       'haystack_form': haystack_form,
                       'publisher': publisher,
                       'series': series,
                       'issue': issue,
                       'story': story,
                       'target': data['target']
                       })

    if 'cancel' in request.POST:
        return data['cancel']
    elif 'select_object' in request.POST:
        try:
            choice = request.POST['object_choice']
            object_type, selected_id = choice.split('_')
            if object_type == 'cover':
                object_type = 'story'
        except MultiValueDictKeyError:
            return render_error(request,
                                'You did not select a cached object. '
                                'Please use the back button to return.',
                                redirect=False)
    elif 'search_select' in request.POST:
        choice = request.POST['object_choice']
        object_type, selected_id = choice.split('_')
    elif 'entered_issue_id' in request.POST:
        object_type = 'issue'
        try:
            selected_id = int(request.POST['entered_issue_id'])
        except ValueError:
            return render_error(request,
                                'Entered Id must be an integer number. '
                                'Please use the back button to return.',
                                redirect=False)
    elif 'entered_story_id' in request.POST:
        object_type = 'story'
        try:
            selected_id = int(request.POST['entered_story_id'])
        except ValueError:
            return render_error(request,
                                'Entered Id must be an integer number. '
                                'Please use the back button to return.',
                                redirect=False)
    else:
        raise ValueError
    return data['return'](request, data, object_type, selected_id)