Beispiel #1
0
def handle_existing_account(request, users):
    if users.count() > 1:
        # There are only a few people in this situation, all of whom are
        # either editors themselves or definitely know how to easily get
        # in touch with an editor.
        return render_error(request,
          ('You already have multiple accounts with this email '
           'address.  Please contact an editor to get your '
           'personal and/or shared accounts sorted out before '
           'adding a new one.'))

    user = users[0]
    if user.is_active:
        return render_error(request, 
          'You already have an active account with this email address.  If '
          'you have forgotten your password, you may <a href="' +
           urlresolvers.reverse('forgot_password') + '">reset '
          'it</a>.  If you feel you need a second account with this email, '
          'please <a href="mailto:%s">contact us</a>.' %
          settings.EMAIL_CONTACT, is_safe=True)

    elif not user.indexer.is_banned:
        # TODO: automatic reactivation, but have to merge fields?  Complicated.
        return render_error(request, 
          ('An account with this email address already exists, '
           'but is deactivated.  Please '
           '<a href="mailto:%s">contact us</a> '
           'if you would like to reactivate it.') % settings.EMAIL_CONTACT,
           is_safe=True)
    else:
        return render_error(request,
          'A prior account with this email address has been '
          'shut down.  Please contact an Editor if you believe '
          'this was done in error.')
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.series.is_comics_publication:
            return render_error(request,
              'No covers for non-comics publications.', 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 cover_id and 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)

    # current request is an upload
    if request.method == 'POST':
        return handle_uploaded_cover(request, cover, issue)
    # 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)
Beispiel #3
0
def mentor_not_new(request, indexer_id):
    """
    Marks a user as no longer needing a mentor and adjusts their limits
    accordingly.
    POST only, although a GET will redirect to the basic mentoring view.
    """
    if not request.user.has_perm('gcd.can_mentor'):
        return render_error(request,
                            'You are not allowed to mentor new Indexers',
                            redirect=False)

    indexer = get_object_or_404(Indexer, id=indexer_id)
    if indexer.mentor != request.user:
        return render_error(
            request,
            'You are not allowed to change the state of this new Indexer',
            redirect=False)
    else:
        if request.method == 'POST':
            indexer.is_new = False
            indexer.max_reservations = max(settings.RESERVE_MAX_DEFAULT,
                                           indexer.max_reservations)
            indexer.max_ongoing = max(settings.RESERVE_MAX_ONGOING_DEFAULT,
                                      indexer.max_ongoing)
            indexer.save()

    return HttpResponseRedirect(urlresolvers.reverse('mentoring'))
Beispiel #4
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))
Beispiel #5
0
def mentor_not_new(request, indexer_id):
    """
    Marks a user as no longer needing a mentor and adjusts their limits
    accordingly.
    POST only, although a GET will redirect to the basic mentoring view.
    """
    if not request.user.has_perm('gcd.can_mentor'):
        return render_error(request,
          'You are not allowed to mentor new Indexers', redirect=False)

    indexer = get_object_or_404(Indexer, id=indexer_id)
    if indexer.mentor != request.user:
        return render_error(request,
          'You are not allowed to change the state of this new Indexer',
          redirect=False)
    else:
        if request.method == 'POST':
            indexer.is_new = False
            indexer.max_reservations = max(settings.RESERVE_MAX_DEFAULT,
                                           indexer.max_reservations)
            indexer.max_ongoing = max(settings.RESERVE_MAX_ONGOING_DEFAULT,
                                      indexer.max_ongoing)
            indexer.save()

    return HttpResponseRedirect(urlresolvers.reverse('mentoring'))
def confirm_account(request, key):
    try:
        indexer = Indexer.objects.get(registration_key=key)
        if date.today() > indexer.registration_expires:
            return render_error(request, 'Your confirmation key has expired. '
                     'You may <a href="' + urlresolvers.reverse('register') + \
                     '">re-register</a>.  ', is_safe=True )

        indexer.user.is_active = True
        indexer.user.save()
        indexer.registration_key = None
        indexer.registration_expires = None
        indexer.save()

        email_body = u"""
We have a new Indexer!

Name: %s
Email: %s
Country: %s
Languages: %s
Interests:
   %s

Mentor this indexer: %s
        """ % (indexer,
               indexer.user.email,
               indexer.country.name,
               ', '.join([lang.name for lang in indexer.languages.all()]),
               indexer.interests,
               'http://' + request.get_host() +
               urlresolvers.reverse('mentor',
                                    kwargs={ 'indexer_id': indexer.id }))

        if settings.BETA:
            emailSubject = 'New BETA Indexer: %s' % indexer
        else:
            emailSubject = 'New Indexer: %s' % indexer

        send_mail(from_email=settings.EMAIL_NEW_ACCOUNTS_FROM,
                  recipient_list=[settings.EMAIL_EDITORS],
                  subject=emailSubject,
                  message=email_body,
                  fail_silently=(not settings.BETA))

        return HttpResponseRedirect(urlresolvers.reverse('welcome'))

    except Indexer.DoesNotExist:
        return render_error(request,
          ('Invalid confirmation URL.  Please make certain that you copied '
           'the URL from the email correctly.  If it has been more than %d '
           'days, the confirmation code has expired and the account may have '
           'been deleted due to lack of confirmation.') %
          (settings.REGISTRATION_EXPIRATION_DELTA + 1))

    except Indexer.MultipleObjectsReturned:
        return render_error(request,
          ('There is a problem with your confirmation key.  Please email %s '
           'for assistance.') % settings.EMAIL_CONTACT)
def login(request, template_name):
    """
    Do some pre-checking before handing off to the standard login view.
    If anything goes wrong just let the standard login handle it.
    """

    if request.user.is_authenticated():
        return HttpResponseRedirect(urlresolvers.reverse("default_profile"))

    try:
        if request.method == "POST":
            try:
                user = User.objects.get(email=request.POST["username"])
            except (User.DoesNotExist, User.MultipleObjectsReturned):
                user = User.objects.get(username=request.POST["username"])

            if user.indexer.registration_expires is not None:
                if date.today() > (user.indexer.registration_expires + timedelta(1)):
                    return render_error(
                        request,
                        (
                            'The account with the email "%s" was never confirmed '
                            'and has expired.  You may <a href="'
                            + urlresolvers.reverse("register")
                            + '">re-register</a>.  '
                        )
                        % esc(user.email),
                        is_safe=True,
                    )
                return render_error(
                    request,
                    (
                        'The account with email "%s" has not yet been confirmed. '
                        "You should receive an email that gives you a URL to visit "
                        "to confirm your account.  After you have visited that URL "
                        "you will be able to log in and use your account.  Please "
                        '<a href="mailto:%s">contact us</a> if you do not receive '
                        "the email within a few hours."
                    )
                    % (esc(user.email), settings.EMAIL_CONTACT),
                    is_safe=True,
                )

    except User.DoesNotExist:
        pass

    if "next" in request.POST:
        next = request.POST["next"]
        if re.match(r"/accounts/confirm/", next, flags=re.I):
            post = request.POST.copy()
            post["next"] = urlresolvers.reverse("welcome")
            request.POST = post
        if re.match(r"/gcd-error/", next, flags=re.I):
            post = request.POST.copy()
            post["next"] = urlresolvers.reverse("home")
            request.POST = post

    return standard_login(request, template_name=template_name, authentication_form=LongUsernameAuthenticationForm)
Beispiel #8
0
def confirm_account(request, key):
    try:
        indexer = Indexer.objects.get(registration_key=key)
        if date.today() > indexer.registration_expires:
            return render_error(request, 'Your confirmation key has expired. '
                     'You may <a href="' + urlresolvers.reverse('register') + \
                     '">re-register</a>.  ', is_safe=True )

        indexer.user.is_active = True
        indexer.user.save()
        indexer.registration_key = None
        indexer.registration_expires = None
        indexer.save()

        email_body = u"""
We have a new Indexer!

Name: %s
Email: %s
Country: %s
Languages: %s
Interests:
   %s

Mentor this indexer: %s
        """ % (indexer, indexer.user.email, indexer.country.name, ', '.join(
            [lang.name
             for lang in indexer.languages.all()]), indexer.interests,
               'http://' + request.get_host() + urlresolvers.reverse(
                   'mentor', kwargs={'indexer_id': indexer.id}))

        if settings.BETA:
            emailSubject = 'New BETA Indexer: %s' % indexer
        else:
            emailSubject = 'New Indexer: %s' % indexer

        send_mail(from_email=settings.EMAIL_NEW_ACCOUNTS_FROM,
                  recipient_list=[settings.EMAIL_EDITORS],
                  subject=emailSubject,
                  message=email_body,
                  fail_silently=(not settings.BETA))

        return HttpResponseRedirect(urlresolvers.reverse('welcome'))

    except Indexer.DoesNotExist:
        return render_error(request, (
            'Invalid confirmation URL.  Please make certain that you copied '
            'the URL from the email correctly.  If it has been more than %d '
            'days, the confirmation code has expired and the account may have '
            'been deleted due to lack of confirmation.') %
                            (settings.REGISTRATION_EXPIRATION_DELTA + 1))

    except Indexer.MultipleObjectsReturned:
        return render_error(
            request,
            ('There is a problem with your confirmation key.  Please email %s '
             'for assistance.') % settings.EMAIL_CONTACT)
Beispiel #9
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)
        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 cover_id and 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)

    # current request is an upload
    if request.method == 'POST':
        return handle_uploaded_cover(request, cover, issue)
    # 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)
Beispiel #10
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)
def unmentor(request, indexer_id):
    indexer = get_object_or_404(Indexer, id=indexer_id)
    if indexer.mentor is None:
        return render_error(request, "This indexer does not have a mentor.")
    if request.user != indexer.mentor:
        return render_error(request, "You are not this indexer's mentor, so you may not un-mentor them.")
    if request.method == "POST":
        indexer.mentor = None
        indexer.save()
        return HttpResponseRedirect(urlresolvers.reverse("mentoring"))

    return render_error(request, "Please access this page through the proper form.")
Beispiel #12
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)
Beispiel #13
0
def login(request, template_name, landing_view='default_profile'):
    """
    Do some pre-checking before handing off to the standard login view.
    If anything goes wrong just let the standard login handle it.
    """

    if request.user.is_authenticated():
        return HttpResponseRedirect(urlresolvers.reverse(landing_view))

    try:
        if request.method == "POST":
            try:
                user = User.objects.get(email=request.POST['username'])
            except (User.DoesNotExist, User.MultipleObjectsReturned):
                user = User.objects.get(username=request.POST['username'])

            if user.indexer.registration_expires is not None:
                if date.today() > (user.indexer.registration_expires +
                                   timedelta(1)):
                    return render_error(request,
                      ('The account with the email "%s" was never confirmed '
                       'and has expired.  You may <a href="' + \
                       urlresolvers.reverse('register') + \
                       '">re-register</a>.  ') % esc(user.email), is_safe=True )
                return render_error(
                    request,
                    ('The account with email "%s" has not yet been confirmed. '
                     'You should receive an email that gives you a URL to visit '
                     'to confirm your account.  After you have visited that URL '
                     'you will be able to log in and use your account.  Please '
                     '<a href="mailto:%s">contact us</a> if you do not receive '
                     'the email within a few hours.') %
                    (esc(user.email), settings.EMAIL_CONTACT),
                    is_safe=True)

    except User.DoesNotExist:
        pass

    if 'next' in request.POST:
        next = request.POST['next']
        if re.match(r'/accounts/confirm/', next, flags=re.I):
            post = request.POST.copy()
            post['next'] = urlresolvers.reverse('welcome')
            request.POST = post
        if re.match(r'/gcd-error/', next, flags=re.I):
            post = request.POST.copy()
            post['next'] = urlresolvers.reverse('home')
            request.POST = post

    return standard_login(request,
                          template_name=template_name,
                          authentication_form=LongUsernameAuthenticationForm)
Beispiel #14
0
def unmentor(request, indexer_id):
    indexer = get_object_or_404(Indexer, id=indexer_id)
    if indexer.mentor is None:
        return render_error(request, "This indexer does not have a mentor.")
    if request.user != indexer.mentor:
        return render_error(request,
            "You are not this indexer's mentor, so you may not un-mentor them.")
    if request.method == 'POST':
        indexer.mentor = None
        indexer.save()
        return HttpResponseRedirect(urlresolvers.reverse('mentoring'))

    return render_error(request, 'Please access this page through the proper form.')
Beispiel #15
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:
        from apps.oi.views import _is_reservable
        is_reservable = _is_reservable('image', current_image.id)

        if is_reservable == 0:
            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()

    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.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 logout(request):
    """
    Handle logout.  Prevent GET requests from having side effects (such as
    logging the user out).  Don't leave the site on a user's error message
    after the user logs out.
    """
    if request.method == "POST":
        next_page = request.POST["next"]
        if re.match(urlresolvers.reverse("error"), next_page):
            next_page = "/"
        return standard_logout(request, next_page=next_page)

    elif request.user.is_authenticated():
        return render_error(request, "Please use the logout button to log out.")
    return render_error(request, "Cannot logout because you are not logged in.")
def mentor_not_new(request, indexer_id):
    if not request.user.has_perm("gcd.can_mentor"):
        return render_error(request, "You are not allowed to mentor new Indexers", redirect=False)

    indexer = get_object_or_404(Indexer, id=indexer_id)
    if indexer.mentor != request.user:
        return render_error(request, "You are not allowed to change the state of this new Indexer", redirect=False)
    else:
        if request.method == "POST":
            indexer.is_new = False
            indexer.max_reservations = max(settings.RESERVE_MAX_DEFAULT, indexer.max_reservations)
            indexer.max_ongoing = max(settings.RESERVE_MAX_ONGOING_DEFAULT, indexer.max_ongoing)
            indexer.save()

    return HttpResponseRedirect(urlresolvers.reverse("mentoring"))
Beispiel #18
0
def profile(request, user_id=None, edit=False):
    """
    View method to display (with this method) or edit (using the
    update_profile method) the user's profile data.
    """
    if request.method == 'POST':
        return update_profile(request, user_id)

    if not request.user.is_authenticated():
        return HttpResponseRedirect(urlresolvers.reverse('login'))

    if user_id is None:
        return HttpResponseRedirect(
            urlresolvers.reverse('view_profile',
                                 kwargs={'user_id': request.user.id}))
    else:
        profile_user = get_object_or_404(User, id=user_id)

    context = {'profile_user': profile_user, 'settings': settings}
    if edit is True:
        if profile_user == request.user:
            form = ProfileForm(
                auto_id=True,
                initial={
                    'email':
                    profile_user.email,
                    'first_name':
                    profile_user.first_name,
                    'last_name':
                    profile_user.last_name,
                    'country':
                    profile_user.indexer.country.id,
                    'languages':
                    [lang.id for lang in profile_user.indexer.languages.all()],
                    'interests':
                    profile_user.indexer.interests,
                    'from_where':
                    profile_user.indexer.from_where,
                    'opt_in_email':
                    profile_user.indexer.opt_in_email,
                    'issue_detail':
                    profile_user.indexer.issue_detail,
                    'notify_on_approve':
                    profile_user.indexer.notify_on_approve,
                    'collapse_compare_view':
                    profile_user.indexer.collapse_compare_view,
                    'show_wiki_links':
                    profile_user.indexer.show_wiki_links,
                })
            context['form'] = form
        else:
            return render_error(request,
                                "You may not edit other users' profiles")

    if profile_user == request.user:
        context['ranking'] = ranking(profile_user.indexer)

    return render_to_response('gcd/accounts/profile.html',
                              context,
                              context_instance=RequestContext(request))
Beispiel #19
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}))
Beispiel #20
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 render_error(request,
            'Only the owner of a collection can add issues to it.',
            redirect=False)
    return collection
def profile(request, user_id=None, edit=False):
    if request.method == "POST":
        return update_profile(request, user_id)

    if not request.user.is_authenticated():
        return HttpResponseRedirect(urlresolvers.reverse("login"))

    if user_id is None:
        return HttpResponseRedirect(urlresolvers.reverse("view_profile", kwargs={"user_id": request.user.id}))
    else:
        profile_user = get_object_or_404(User, id=user_id)

    context = {"profile_user": profile_user, "settings": settings}
    if edit is True:
        if profile_user == request.user:
            form = ProfileForm(
                auto_id=True,
                initial={
                    "email": profile_user.email,
                    "first_name": profile_user.first_name,
                    "last_name": profile_user.last_name,
                    "country": profile_user.indexer.country.id,
                    "languages": [lang.id for lang in profile_user.indexer.languages.all()],
                    "interests": profile_user.indexer.interests,
                    "notify_on_approve": profile_user.indexer.notify_on_approve,
                    "collapse_compare_view": profile_user.indexer.collapse_compare_view,
                    "show_wiki_links": profile_user.indexer.show_wiki_links,
                },
            )
            context["form"] = form
        else:
            return render_error(request, "You may not edit other users' profiles")

    return render_to_response("gcd/accounts/profile.html", context, context_instance=RequestContext(request))
Beispiel #22
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
Beispiel #23
0
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)
Beispiel #24
0
def mark_cover(request, cover_id):
    """
    marks the cover of the issue for replacement
    """

    # TODO: once we have permissions 'can_mark' should be one
    if request.user.is_authenticated() and \
      request.user.groups.filter(name='editor'):
        # check for issue and cover
        cover = get_object_or_404(Cover, id=cover_id)

        cover.marked = True
        cover.save()

        # I kinda assume the HTTP_REFERER is always present, but just in case
        if request.META.has_key('HTTP_REFERER'):
            return HttpResponseRedirect(request.META['HTTP_REFERER'])
        else:
            cover_tag = get_image_tag(cover, "Cover Image", 2)
            return render_to_response('gcd/details/cover_marked.html', {
                'issue': cover.issue,
                'cover_tag': cover_tag,
                'error_subject': '%s cover' % cover.issue,
                'style': 'default',
            },
                                      context_instance=RequestContext(request))
    else:
        return render_error(
            request,
            'You are not allowed to mark covers for replacement.',
            redirect=False)
Beispiel #25
0
def mentor(request, indexer_id):
    if not request.user.has_perm('gcd.can_mentor'):
        return render_error(request,
                            'You are not allowed to mentor new Indexers',
                            redirect=False)

    indexer = get_object_or_404(Indexer, id=indexer_id)
    if request.method == 'POST' and indexer.mentor is None:
        indexer.mentor = request.user
        indexer.save()
        pending = indexer.user.changesets.filter(state=states.PENDING)
        for changeset in pending.all():
            try:
                changeset.assign(approver=request.user, notes='')
            except ValueError:
                # Someone is already reviewing this.  Unlikely, and just let it go.
                pass

        if pending.count():
            return HttpResponseRedirect(urlresolvers.reverse('reviewing'))

        # I kinda assume the HTTP_REFERER is always present, but just in case
        if 'HTTP_REFERER' in request.META:
            return HttpResponseRedirect(request.META['HTTP_REFERER'])

    return render_to_response('gcd/accounts/mentor.html', {'indexer': indexer},
                              context_instance=RequestContext(request))
def mentor(request, indexer_id):
    if not request.user.has_perm('gcd.can_mentor'):
        return render_error(request,
          'You are not allowed to mentor new Indexers', redirect=False)

    indexer = get_object_or_404(Indexer, id=indexer_id)
    if request.method == 'POST' and indexer.mentor is None:
        indexer.mentor = request.user
        indexer.save()
        pending = indexer.user.changesets.filter(state=states.PENDING)
        for changeset in pending.all():
            try:
              changeset.assign(approver=request.user, notes='')
            except ValueError:
                # Someone is already reviewing this.  Unlikely, and just let it go.
                pass

        if pending.count():
            return HttpResponseRedirect(urlresolvers.reverse('reviewing'))

        # I kinda assume the HTTP_REFERER is always present, but just in case
        if 'HTTP_REFERER' in request.META:
            return HttpResponseRedirect(request.META['HTTP_REFERER'])

    return render_to_response('gcd/accounts/mentor.html',
                              { 'indexer' : indexer },
                              context_instance=RequestContext(request))
def profile(request, user_id=None, edit=False):
    if request.method == 'POST':
        return update_profile(request, user_id)

    if not request.user.is_authenticated():
        return HttpResponseRedirect(urlresolvers.reverse('login'))

    if user_id is None:
        return HttpResponseRedirect(
          urlresolvers.reverse('view_profile',
                               kwargs={'user_id': request.user.id}))
    else:
        profile_user = get_object_or_404(User, id=user_id)

    context = { 'profile_user': profile_user }
    if edit is True:
        if profile_user == request.user:
            form = ProfileForm(auto_id=True, initial={
              'email': profile_user.email,
              'first_name': profile_user.first_name,
              'last_name': profile_user.last_name,
              'country': profile_user.indexer.country.id,
              'languages':
                [ lang.id for lang in profile_user.indexer.languages.all() ],
              'interests': profile_user.indexer.interests,
            })
            context['form'] = form
        else:
            return render_error(request,
              "You may not edit other users' profiles")

    return render_to_response('gcd/accounts/profile.html',
                              context,
                              context_instance=RequestContext(request))
Beispiel #28
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} ))
def mark_cover(request, cover_id):
    """
    marks the cover of the issue for replacement
    """

    # TODO: once we have permissions 'can_mark' should be one
    if request.user.is_authenticated() and \
      request.user.groups.filter(name='editor'):
        # check for issue and cover
        cover = get_object_or_404(Cover, id=cover_id)
        
        cover.marked = True
        cover.save()

        # I kinda assume the HTTP_REFERER is always present, but just in case
        if request.META.has_key('HTTP_REFERER'):
            return HttpResponseRedirect(request.META['HTTP_REFERER'])
        else:
            cover_tag = get_image_tag(cover, "Cover Image", 2)
            return render_to_response(
              'gcd/details/cover_marked.html',
              {
                'issue': cover.issue,
                'cover_tag': cover_tag,
                'error_subject': '%s cover' % cover.issue,
                'style': 'default',
              },
              context_instance=RequestContext(request)
            )        
    else:
        return render_error(request,
          'You are not allowed to mark covers for replacement.', 
          redirect=False)
def delete_cover(request, id):
    cover = get_object_or_404(Cover, id=id)

    # check if there is a pending change for the cover
    try:
        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)
    except:
        revision = None

    changeset = Changeset(indexer=request.user, state=states.PENDING,
                          change_type=CTYPES['cover'])
    changeset.save()
    revision = CoverRevision(changeset=changeset, issue=cover.issue,
                             cover=cover, deleted=True)
    revision.save()

    comments = request.POST['comments']
    changeset.comments.create(commenter=request.user,
                              text=comments,
                              old_state=states.UNRESERVED,
                              new_state=changeset.state)

    return HttpResponseRedirect(urlresolvers.reverse('edit_covers',
                                kwargs={'issue_id': cover.issue.id}))
Beispiel #31
0
def update_profile(request, user_id=None):
    """
    Helper method to perform the update if the main profile view
    detects a POST request.
    """
    if request.user.id != int(user_id):
        return render_error(request, 'You may only edit your own profile.')

    errors = []
    form = ProfileForm(request.POST)
    if not form.is_valid():
        return render_to_response('gcd/accounts/profile.html', {'form': form},
                                  context_instance=RequestContext(request))

    set_password = False
    old = form.cleaned_data['old_password']
    new = form.cleaned_data['new_password']
    confirm = form.cleaned_data['confirm_new_password']
    if (new or confirm) and not old:
        errors.append(
            u'You must supply your old password in order to change it.')
    elif old and (new or confirm):
        if not request.user.check_password(old):
            errors.append(u'Old password incorrect, please try again.')
        elif new != confirm:
            errors.append(
                u'New password and confirm new password do not match.')
        else:
            set_password = True

    if errors:
        return render_to_response('gcd/accounts/profile.html', {
            'form': form,
            'error_list': errors
        },
                                  context_instance=RequestContext(request))

    request.user.first_name = form.cleaned_data['first_name']
    request.user.last_name = form.cleaned_data['last_name']
    request.user.email = form.cleaned_data['email']
    if set_password is True:
        request.user.set_password(new)
    request.user.save()

    indexer = request.user.indexer
    indexer.notify_on_approve = form.cleaned_data['notify_on_approve']
    indexer.collapse_compare_view = form.cleaned_data['collapse_compare_view']
    indexer.show_wiki_links = form.cleaned_data['show_wiki_links']
    indexer.country = form.cleaned_data['country']
    indexer.languages = form.cleaned_data['languages']
    indexer.interests = form.cleaned_data['interests']
    indexer.from_where = form.cleaned_data['from_where']
    indexer.opt_in_email = form.cleaned_data['opt_in_email']
    indexer.issue_detail = form.cleaned_data['issue_detail']
    indexer.save()

    return HttpResponseRedirect(
        urlresolvers.reverse('view_profile',
                             kwargs={'user_id': request.user.id}))
 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
Beispiel #33
0
def logout(request):
    """
    Handle logout.  Prevent GET requests from having side effects (such as
    logging the user out).  Don't leave the site on a user's error message
    after the user logs out.
    """
    if request.method == 'POST':
        next_page = request.POST['next']
        if re.match(urlresolvers.reverse('error'), next_page):
            next_page = '/'
        return standard_logout(request, next_page=next_page)

    elif request.user.is_authenticated():
        return render_error(request,
                            'Please use the logout button to log out.')
    return render_error(request,
                        'Cannot logout because you are not logged in.')
Beispiel #34
0
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)
Beispiel #35
0
def update_profile(request, user_id=None):
    """
    Helper method to perform the update if the main profile view
    detects a POST request.
    """
    if request.user.id != int(user_id):
        return render_error(request, 'You may only edit your own profile.')

    errors = []
    form = ProfileForm(request.POST)
    if not form.is_valid():
        return render_to_response('gcd/accounts/profile.html',
                                  { 'form': form },
                                  context_instance=RequestContext(request))

    set_password = False
    old = form.cleaned_data['old_password']
    new = form.cleaned_data['new_password']
    confirm = form.cleaned_data['confirm_new_password']
    if (new or confirm) and not old:
        errors.append(
          u'You must supply your old password in order to change it.')
    elif old and (new or confirm):
        if not request.user.check_password(old):
            errors.append(u'Old password incorrect, please try again.')
        elif new != confirm:
            errors.append(
              u'New password and confirm new password do not match.')
        else:
            set_password = True

    if errors:
        return render_to_response('gcd/accounts/profile.html',
                                  { 'form': form, 'error_list': errors },
                                  context_instance=RequestContext(request))

    request.user.first_name = form.cleaned_data['first_name']
    request.user.last_name = form.cleaned_data['last_name']
    request.user.email = form.cleaned_data['email']
    if set_password is True:
        request.user.set_password(new)
    request.user.save()

    indexer = request.user.indexer
    indexer.notify_on_approve = form.cleaned_data['notify_on_approve']
    indexer.collapse_compare_view = form.cleaned_data['collapse_compare_view']
    indexer.show_wiki_links = form.cleaned_data['show_wiki_links']
    indexer.country = form.cleaned_data['country']
    indexer.languages = form.cleaned_data['languages']
    indexer.interests = form.cleaned_data['interests']
    indexer.from_where = form.cleaned_data['from_where']
    indexer.opt_in_email = form.cleaned_data['opt_in_email']
    indexer.issue_detail = form.cleaned_data['issue_detail']
    indexer.save()

    return HttpResponseRedirect(
      urlresolvers.reverse('view_profile',
                           kwargs={'user_id': request.user.id}))
Beispiel #36
0
def unmentor(request, indexer_id):
    """
    Releases a user from being mentored.  POST only.
    This is NOT for "graduating" a user into not needing a mentor.
    It is for releasing the new user to find another mentor.
    """
    indexer = get_object_or_404(Indexer, id=indexer_id)
    if indexer.mentor is None:
        return render_error(request, "This indexer does not have a mentor.")
    if request.user != indexer.mentor:
        return render_error(request,
            "You are not this indexer's mentor, so you may not un-mentor them.")
    if request.method == 'POST':
        indexer.mentor = None
        indexer.save()
        return HttpResponseRedirect(urlresolvers.reverse('mentoring'))

    return render_error(request, 'Please access this page through the proper form.')
Beispiel #37
0
def mentor_not_new(request, indexer_id):
    if not request.user.has_perm('gcd.can_mentor'):
        return render_error(request,
          'You are not allowed to mentor new Indexers', redirect=False)

    indexer = get_object_or_404(Indexer, id=indexer_id)
    if indexer.mentor != request.user:
        return render_error(request,
          'You are not allowed to change the state of this new Indexer', 
          redirect=False)
    else:
        if request.method == 'POST':
            indexer.is_new = False
            indexer.max_reservations = settings.RESERVE_MAX_DEFAULT
            indexer.max_ongoing = settings.RESERVE_MAX_ONGOING_DEFAULT
            indexer.save()
    
    return HttpResponseRedirect(urlresolvers.reverse('mentoring'))
def login(request, template_name):
    """
    Do some pre-checking before handing off to the standard login view.
    If anything goes wrong just let the standard login handle it.
    """

    if request.user.is_authenticated():
        return HttpResponseRedirect(urlresolvers.reverse('default_profile'))

    try:
        if request.method == "POST":
            user = User.objects.get(username=request.POST['username'])
            if user.indexer.registration_key is not None:
                if date.today() > (user.indexer.registration_expires +
                                   timedelta(1)):
                    return render_error(request,
                      ('The account with the email "%s" was never confirmed '
                       'and has expired.  You may <a href="' + \
                       urlresolvers.reverse('register') + \
                       '">re-register</a>.  ') % esc(user.email), is_safe=True )
                return render_error(request,
                  ('The account with email "%s" has not yet been confirmed. '
                   'You should receive an email that gives you a URL to visit '
                   'to confirm your account.  After you have visited that URL '
                   'you will be able to log in and use your account.  Please '
                   '<a href="mailto:%s">contact us</a> if you do not receive '
                   'the email within a few hours.') %
                  (esc(user.email), settings.EMAIL_CONTACT), is_safe=True)

    except Exception:
        pass

    if 'next' in request.POST:
        next = request.POST['next']
        if re.match(r'/accounts/confirm/', next, flags=re.I):
            post = request.POST.copy()
            post['next'] = urlresolvers.reverse('welcome')
            request.POST = post
        if re.match(r'/gcd-error/', next, flags=re.I):
            post = request.POST.copy()
            post['next'] = urlresolvers.reverse('home')
            request.POST = post

    return standard_login(request, template_name=template_name)
Beispiel #39
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
Beispiel #40
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)
Beispiel #41
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:
        from apps.oi.views import _is_reservable
        is_reservable = _is_reservable('image', current_image.id)

        if is_reservable == 0:
            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()

    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.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 _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
Beispiel #43
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
Beispiel #44
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)
Beispiel #45
0
def unmentor(request, indexer_id):
    """
    Releases a user from being mentored.  POST only.
    This is NOT for "graduating" a user into not needing a mentor.
    It is for releasing the new user to find another mentor.
    """
    indexer = get_object_or_404(Indexer, id=indexer_id)
    if indexer.mentor is None:
        return render_error(request, "This indexer does not have a mentor.")
    if request.user != indexer.mentor:
        return render_error(
            request,
            "You are not this indexer's mentor, so you may not un-mentor them."
        )
    if request.method == 'POST':
        indexer.mentor = None
        indexer.save()
        return HttpResponseRedirect(urlresolvers.reverse('mentoring'))

    return render_error(request,
                        'Please access this page through the proper form.')
def mentor(request, indexer_id):
    if not request.user.has_perm("gcd.can_mentor"):
        return render_error(request, "You are not allowed to mentor new Indexers", redirect=False)

    indexer = get_object_or_404(Indexer, id=indexer_id)
    if request.method == "POST":
        indexer.mentor = request.user
        indexer.save()

    return render_to_response(
        "gcd/accounts/mentor.html", {"indexer": indexer}, context_instance=RequestContext(request)
    )
def character_by_name(request, character_name, sort=ORDER_ALPHA):
    """Find stories based on characters.  Since characters for whom a feature
    is named are often not also listed under character appearances, this
    search looks at both the feature and characters fields."""

    if len(character_name) < 4:
        return render_error(request,
          'A search for characters must use more than 3 letters.', redirect=False)

    q_obj = Q(characters__icontains=character_name) | \
            Q(feature__icontains=character_name)
    return generic_by_name(request, character_name, q_obj, sort,
                           credit="characters:" + character_name)
Beispiel #48
0
def mentor(request, indexer_id):
    if not request.user.has_perm('gcd.can_mentor'):
        return render_error(request,
                            'You are not allowed to mentor new Indexers',
                            redirect=False)

    indexer = get_object_or_404(Indexer, id=indexer_id)
    if request.method == 'POST':
        indexer.mentor = request.user
        indexer.save()

    return render_to_response('gcd/accounts/mentor.html', {'indexer': indexer},
                              context_instance=RequestContext(request))
Beispiel #49
0
def vote(request):
    option = get_object_or_404(Option, id=request.POST['option'])
    if 'rank' in request.POST:
        rank = request.POST['rank'].strip()
    else:
        rank = None
    if option.topic.token is not None and \
       request.POST['token'].strip() != option.topic.token:
        return render_error(request,
          'You must supply an authorization token in order to vote on this topic.')
    vote = Vote(option=option, voter=request.user, rank=rank)
    vote.save()
    return HttpResponseRedirect(urlresolvers.reverse('ballot',
      kwargs={ 'id': option.topic.id }))
Beispiel #50
0
def mentor(request, indexer_id):
    if not request.user.has_perm('gcd.can_mentor'):
        return render_error(request,
                            'You are not allowed to mentor new Indexers',
                            redirect=False)

    indexer = get_object_or_404(Indexer, id=indexer_id)
    if request.method == 'POST' and indexer.mentor is None:
        indexer.mentor = request.user
        indexer.save()
        # I kinda assume the HTTP_REFERER is always present, but just in case
        if request.META.has_key('HTTP_REFERER'):
            return HttpResponseRedirect(request.META['HTTP_REFERER'])

    return render_to_response('gcd/accounts/mentor.html', {'indexer': indexer},
                              context_instance=RequestContext(request))
def mentor(request, indexer_id):
    if not request.user.has_perm('gcd.can_mentor'):
        return render_error(request,
          'You are not allowed to mentor new Indexers', redirect=False)

    indexer = get_object_or_404(Indexer, id=indexer_id)
    if request.method == 'POST' and indexer.mentor is None:
        indexer.mentor = request.user
        indexer.save()
        # I kinda assume the HTTP_REFERER is always present, but just in case
        if request.META.has_key('HTTP_REFERER'):
            return HttpResponseRedirect(request.META['HTTP_REFERER'])

    return render_to_response('gcd/accounts/mentor.html',
                              { 'indexer' : indexer },
                              context_instance=RequestContext(request))
Beispiel #52
0
def profile(request, user_id=None, edit=False):
    """
    View method to display (with this method) or edit (using the
    update_profile method) the user's profile data.
    """
    if request.method == 'POST':
        return update_profile(request, user_id)

    if not request.user.is_authenticated():
        return HttpResponseRedirect(urlresolvers.reverse('login'))

    if user_id is None:
        return HttpResponseRedirect(
          urlresolvers.reverse('view_profile',
                               kwargs={'user_id': request.user.id}))
    else:
        profile_user = get_object_or_404(User, id=user_id)

    context = { 'profile_user': profile_user, 'settings': settings }
    if edit is True:
        if profile_user == request.user:
            form = ProfileForm(auto_id=True, initial={
              'email': profile_user.email,
              'first_name': profile_user.first_name,
              'last_name': profile_user.last_name,
              'country': profile_user.indexer.country.id,
              'languages':
                [ lang.id for lang in profile_user.indexer.languages.all() ],
              'interests': profile_user.indexer.interests,
              'from_where': profile_user.indexer.from_where,
              'opt_in_email': profile_user.indexer.opt_in_email,
              'issue_detail': profile_user.indexer.issue_detail,
              'notify_on_approve': profile_user.indexer.notify_on_approve,
              'collapse_compare_view': profile_user.indexer.collapse_compare_view,
              'show_wiki_links': profile_user.indexer.show_wiki_links,
            })
            context['form'] = form
        else:
            return render_error(request,
              "You may not edit other users' profiles")

    if profile_user == request.user:
        context['ranking'] = ranking(profile_user.indexer)

    return render_to_response('gcd/accounts/profile.html',
                              context,
                              context_instance=RequestContext(request))
Beispiel #53
0
def topic(request, id):
    topic = get_object_or_404(Topic, id=id)

    if not request.user.has_perm('gcd.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_to_response('voting/topic.html', {
        'topic': topic,
        'voted': topic.has_vote_from(request.user),
        'votes': votes,
        'closed': topic.deadline < datetime.now(),
        'settings': settings,
    },
                              context_instance=RequestContext(request))
Beispiel #54
0
def profile(request, user_id=None, edit=False):
    if request.method == 'POST':
        return update_profile(request, user_id)

    if user_id is None:
        if request.user.is_authenticated():
            return HttpResponseRedirect(
                urlresolvers.reverse('view_profile',
                                     kwargs={'user_id': request.user.id}))
        else:
            return HttpResponseRedirect(urlresolvers.reverse('login'))
        profile_user = request.user
    else:
        profile_user = get_object_or_404(User, id=user_id)

    context = {'profile_user': profile_user}
    if edit is True:
        if profile_user == request.user:
            form = ProfileForm(
                auto_id=True,
                initial={
                    'email':
                    profile_user.email,
                    'first_name':
                    profile_user.first_name,
                    'last_name':
                    profile_user.last_name,
                    'country':
                    profile_user.indexer.country.id,
                    'languages':
                    [lang.id for lang in profile_user.indexer.languages.all()],
                    'interests':
                    profile_user.indexer.interests,
                })
            context['form'] = form
        else:
            return render_error(request,
                                "You may not edit other users' profiles")

    return render_to_response('gcd/accounts/profile.html',
                              context,
                              context_instance=RequestContext(request))
Beispiel #55
0
def topic(request, id):
    topic = get_object_or_404(Topic, id=id)

    voted = False
    votes = []
    if not request.user.has_perm('gcd.can_vote'):
        return render_error(
            request, 'You do not have permission to vote on this topic.')

    votes = topic.options.filter(votes__voter=request.user)
    receipts = topic.receipts.filter(voter=request.user)
    voted = votes.count() > 0 or receipts.count() > 0

    return render_to_response('voting/topic.html', {
        'topic': topic,
        'voted': voted,
        'votes': votes,
        'closed': topic.deadline < datetime.now(),
        'settings': settings,
    },
                              context_instance=RequestContext(request))
Beispiel #56
0
def delete_cover(request, id):
    cover = get_object_or_404(Cover, id=id)

    # check if there is a pending change for the cover
    try:
        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)
    except:
        revision = None

    changeset = Changeset(indexer=request.user,
                          state=states.PENDING,
                          change_type=CTYPES['cover'])
    changeset.save()
    revision = CoverRevision(changeset=changeset,
                             issue=cover.issue,
                             cover=cover,
                             deleted=True)
    revision.save()

    comments = request.POST['comments']
    changeset.comments.create(commenter=request.user,
                              text=comments,
                              old_state=states.UNRESERVED,
                              new_state=changeset.state)

    return HttpResponseRedirect(
        urlresolvers.reverse('edit_covers',
                             kwargs={'issue_id': cover.issue.id}))
Beispiel #57
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

    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))