Exemple #1
0
def copy():
    """
    URLs:
    - /comic/copy?id=123

    Function:
    - Ask the user which box to file a copy of a comic into, and then perform
      the copy operation.
    """
    # Find out which comic is being copied.
    requested_comic = request.vars.get('id')

    # If a malformed ID (or no ID) is passed in, throw a 404 error.
    try:
        comic_id = int(requested_comic)
    except ValueError as error:
        raise HTTP(404)
    
    # Get the details of the comic.
    comic = db_access.get_comic(requested_comic)

    # If the requested comic doesn't exist, throw a 404.
    if comic is None:
        raise HTTP(404)

    # Get the id of the current user.
    current_user = auth.user_id

    # Get the details of the comic's owner.
    owner = db_access.get_user(comic.owner_id)

    # Set the title of the page.
    response.title = 'Copy Comic'

    # Remind the user what comic they are copying.
    response.subtitle = 'Copying {title} #{issue} from {name}'.format(title=comic.title,
                                                                      issue=comic.issue_number,
                                                                      name=owner.username)

    # Create a box selection form populated with a list of the user's boxes.
    form = box_selection_form(db, current_user, submit_button='Copy')

    # The form has no validation so it will always be accepted.
    if form.process().accepted:
        # Perform the copy operation, assigning the comic to the new user.
        new_comic_id = db_access.copy_comic(comic_id, current_user)

        # Create a filing between the new comic and the selected box.
        db_access.create_filing(new_comic_id, form.vars.box_id)

        # Take the user to their new comic.
        redirect(URL('comic', 'index', vars={'id': new_comic_id}))

    return dict(form=form)
Exemple #2
0
def delete():
    """
    URLs:
    - /comic/delete?id=123

    Function:
    - Perform the deletion of a comic after the user has confirmed they want it
      to be deleted.

    Notes:
    - This function should only be reached by redirection from comic/confirm_delete.
      Unfortunately there's no way to stop someone manually typing in the URL.
    """
    # Find out which comic is being deleted.
    requested_comic = request.vars.get('id')

    # If a malformed ID (or no ID) is passed in, throw a 404 error.
    try:
        comic_id = int(requested_comic)
    except ValueError as error:
        raise HTTP(404)
    
    # Get the details of the comic.
    comic = db_access.get_comic(requested_comic)

    # If the requested comic doesn't exist, throw a 404.
    if comic is None:
        raise HTTP(404)

    # Get the id of the current user.
    current_user = auth.user_id

    # If the comic doesn't belong to the current user, redirect to the private page.
    if comic.owner_id != current_user:
        redirect(URL('private', 'index', args='comic', vars={'edit': 'true'}))

    # Set the title of the page.
    response.title = 'Deleted'

    # Actually delete the comic.
    db_access.delete_comic(comic.id)

    return dict(comic=comic)
Exemple #3
0
def confirm_delete():
    """
    URLs:
    - /comic/confirm_delete?id=123

    Function:
    - Used to confirm that the user wants to delete a comic, providing a
      Delete button and a Cancel button. If the user chooses Delete, they
      will be redirected to /comic/delete which will actually delete the box.

    Notes:
    - If the comic does not belong to the logged in user, they will be redirected
      to /private/comic.
    """
    # Find out which comic is being deleted.
    requested_comic = request.vars.get('id')

    # If a malformed ID (or no ID) is passed in, throw a 404 error.
    try:
        comic_id = int(requested_comic)
    except ValueError as error:
        raise HTTP(404)
    
    # Get the details of the comic.
    comic = db_access.get_comic(requested_comic)

    # If the requested comic doesn't exist, throw a 404.
    if comic is None:
        raise HTTP(404)

    # Get the id of the current user.
    current_user = auth.user_id

    # If the comic doesn't belong to the current user, redirect to the private page.
    if comic.owner_id != current_user:
        redirect(URL('private', 'index', args='comic', vars={'edit': 'true'}))

    # Set the title of the page.
    response.title = 'Delete Comic'

    return dict(comic=comic)
Exemple #4
0
def file():
    """
    URLs:
    - /comic/file?id=123

    Function:
    - Allow the user to select which boxes to file a comic into.
    """
    # Find out which comic is being filed.
    requested_comic = request.vars.get('id')

    # If a malformed ID (or no ID) is passed in, throw a 404 error.
    try:
        comic_id = int(requested_comic)
    except ValueError as error:
        raise HTTP(404)
    
    # Get the details of the comic.
    comic = db_access.get_comic(requested_comic)

    # If the requested comic doesn't exist, throw a 404.
    if comic is None:
        raise HTTP(404)

    # Get the id of the current user.
    current_user = auth.user_id

    # If the comic doesn't belong to the current user, redirect to the private page.
    if comic.owner_id != current_user:
        redirect(URL('private', 'index', args='comic', vars={'edit': 'true'}))

    # Set the title of the page.
    response.title = 'File Comic'
    response.subtitle = 'Choose boxes to file {title} #{issue} into'.format(title=comic.title,
                                                                            issue=comic.issue_number)

    # Create a form for the user to choose boxes from.
    form = filing_form(db, current_user, comic_id, 'File Comic')

    # Process the form. A custom validation function is used to ensure that at
    # least one box is selected.
    if form.process(onvalidation=validate_filing).accepted:
        # The validation was successful. Unfile the comic from all boxes, then
        # file it into the chosen boxes.
        db_access.delete_filings_for_comic(comic_id)

        # If only one box is selected, form.vars.boxes will be a string instead
        # of a list, meaning it cannot be iterated over correctly. Put it in a
        # list so it can.
        if type(form.vars.boxes) == type(''):
            boxes = [form.vars.boxes]
        else:
            boxes = form.vars.boxes

        for box_id in boxes:
            db_access.create_filing(comic_id, box_id)

        # Take the user back to the comic page.
        redirect(URL('comic', 'index', vars={'id': comic_id}))

    # If the validation fails, add an error message above the submit button.
    elif form.errors.error is not None:
        error_message = DIV(
                            DIV(
                                DIV('Please choose at least one box to file the comic into.', _class='error'),
                                _class='col-md-12 text-center'
                            ),
                            _class='form-group'
                        )
        form.insert(-1, error_message)

    return dict(form=form)
Exemple #5
0
def edit():
    """
    URLs:
    - /comic/edit?id=123

    Function:
    - Display a form so the user can edit an existing comic.

    Notes:
    - If the comic does not belong to the logged in user, they will be redirected
      to /private/comic.
    """
    # Find out which comic is being edited.
    requested_comic = request.vars.get('id')

    # For some reason, when the form is submitted, request.vars.id is a list
    # containing the same value twice.
    if type(requested_comic) == type([]):
        requested_comic = requested_comic[0]

    # If a malformed ID (or no ID) is passed in, throw a 404 error.
    try:
        comic_id = int(requested_comic)
    except ValueError as error:
        raise HTTP(404)
    
    # Get the details of the comic.
    comic = db_access.get_comic(requested_comic)

    # If the requested comic doesn't exist, throw a 404.
    if comic is None:
        raise HTTP(404)

    # Get the id of the current user.
    current_user = auth.user_id

    # If the comic doesn't belong to the current user, redirect to the private page.
    if comic.owner_id != current_user:
        redirect(URL('private', 'index', args='comic', vars={'edit': 'true'}))

    # Set the title of the page.
    response.title = 'Edit Comic'

    # Create a comic editing form, passing in the ID of the comic to set the
    # values of the form, and to put the SQLFORM into update mode.
    form = comic_edit_form(db, user_id=auth.user_id, submit_button='Save Changes', edit_comic_id=comic_id)

    # Validate and process the form.
    if form.process().accepted:
        # Return to the comic's page.
        redirect(URL('comic', 'index', vars={'id': comic.id}))

    # If there are errors in the form, highlight the appropriate sections in red.
    if form.errors is not None:
        if len(form.errors) > 0:
            # Highlight the title field if it wasn't entered.
            if form.errors.title is not None:
                form[0][0]['_class'] += ' has-error'

            # Highlight the issue number field if that wasn't entered.
            if form.errors.issue_number is not None:
                form[0][1]['_class'] += ' has-error'

            # Highlight the image upload field if the image was too large.
            if form.errors.cover_image is not None:
                form[0][2]['_class'] += ' has-error'

    return dict(form=form)
Exemple #6
0
def index():
    """
    URLs:
    - /comic?id=123

    Function:
    - Display the details of the comic with the given ID.
    """
    # Get the ID of the comic to display.
    requested_comic = request.vars.get('id')

    # If a malformed ID (or no ID) is passed in, throw a 404 error.
    try:
        comic_id = int(requested_comic)
    except ValueError as error:
        raise HTTP(404)

    # Get the details of the comic and its owner.
    comic = db_access.get_comic(requested_comic)

    # If the requested comic doesn't exist, throw a 404 error.
    if comic is None:
        raise HTTP(404)

    # Get the details of the comic's owner.
    user = db_access.get_user(comic.owner_id)

    # Get a list of the boxes the comic is stored in. If the comic's owner is
    # the currently logged in user, this can include private boxes.
    include_private = (comic.owner_id == user.id)
    boxes = db_access.get_boxes_for_comic(requested_comic, include_private=include_private)

    # If the comic is only filed in private boxes and the current user doesn't
    # own the comic, it shouldn't be visible. In this case, since the query
    # above would have excluded private boxes, then no boxes will have been
    # returned.
    has_permission = len(boxes) > 0

    # If the user doesn't have permission, redirect to the private page.
    if not has_permission:
        redirect(URL('private', 'index', args='comic'))

    # Set the title of the page to show the user where they are.
    response.title = "{title} #{issue}".format(title=comic.title, issue=comic.issue_number)

    # Create a link to the comic's owner.
    user_link = A(user.username, _href=URL('user', 'index', vars={'id': user.id}))

    # Display the owner of the comic below the title.
    response.subtitle = 'Owned by {user}'.format(user=user_link)

    # The action buttons depend on whether the comic belongs to the logged-in
    # user. They shouldn't be able to delete or edit someone else's comic, or
    # copy their own comic to their collection.
    if comic.owner_id == auth.user_id:
        # Add buttons to the top of the page to edit, delete, and file the comic.
        page_actions = [
            ('File in Boxes', URL('comic', 'file',           vars={'id': comic.id}), 'credit-card'),
            ('Edit',          URL('comic', 'edit',           vars={'id': comic.id}), 'pencil'),
            ('Delete',        URL('comic', 'confirm_delete', vars={'id': comic.id}), 'trash')
        ]
    elif auth.user_id is not None:
        # Add a button to copy the comic to the current user's collection, if a
        # user is actually logged in.
        page_actions = [
            ('Copy to My Collection', URL('comic', 'copy', vars={'id': comic.id}), 'duplicate')
        ]
    else:
        page_actions = []

    return dict(comic=comic, user=user, boxes=boxes, has_permission=has_permission, page_actions=page_actions)