IAP Assignment: Photo management web app

Deadline:

  • 30.05.2024 23:59 Deadline HARD!;

Changelog:

  • 20.04.2024: assignment published!

Introduction

In the early days of the web, personal websites and online communities started emerging. People began creating HTML pages to showcase their photo collections manually. Basic HTML and CSS were used to create rudimentary galleries.

With the rise of social media platforms like MySpace and Flickr, the popularity of online photo sharing platforms surged. They allowed users to upload, organize, and share their photos with others. Such platforms make it easier for non-technical users to build and customize their photo galleries.

For this assignment, you will implement a simple personal photo management web application (i.e., mini photo gallery) using Python and Flask technologies.

Specification

In the following subsections, we define the minimal (required) aspects to be followed (especially to make the grading process easy to automate), plus some recommendations for the easiest approaches.

Overall, the web application should have the following features:

  • a personalized HTML + CSS web template / design to base the rest of the application on; see the specification below for minimum requirements!
  • login functionality (HTML form, menu links, and associated Flask routes), for authenticating the administrator (to gain file upload permissions);
  • an unauthenticated front page displaying all uploaded images (low-resolution thumbnails) on a per-category basis (optionally, with category index);
  • an authenticated page with a image upload form + associated Flask functions;
  • optionally, when authenticated as administrator, add delete buttons for each photo gallery;
  • an additional “about me” page (fill it with a fake bio or whatever you want);
  • a method for persisting (storing) the uploaded photos on the server (either the server's filesystem, organized in directories (recommended), or a database – for bonus points);
  • a Docker container image with all dependencies to quickly start up the web application (quite important for the grading evaluation process, to make it error-proof – a container will work everywhere!);

We recommend starting this assignment with a HTML template for your design (plus various pages, e.g., specific forms), then porting it to Jinja2 templates and writing Flask routing functions.

Web Frontend: User Interface / Design

The web layout should present a (somewhat) friendly user interface with, at minimum:

  • a front page displaying the user's public photo gallery (unauthenticated);
  • an authentication (login) form for the administrator;
  • a file upload form to add images to the photo gallery (accessible by the authenticated user only!); it should also have an optional text field to rename the photo and a category name (i.e. subdirectory to upload the image to); you may use a predefined list of categories (e.g., <select> box).
  • an “about me” page (+ possibly others) – you have complete freedom for their content;
  • no needless code duplication: all common HTML code (i.e., the design / layout) should be kept inside a base Jinja2 template!

You can use whatever CSS framework you'd like, we recommend Bootstrap. If you wish, you could base it on the lab's template, though you should personalize it.

All pages must have a common menu bar directly linking to eachother. We recommend the use of a CSS framework (e.g., Bootstrap) for easily adding vertical / horizontal menus to a HTML page.

The gallery page (i.e. the frontpage) should display only low-resolution thumbnails of the uploaded photos in a grid, then open the full image on click (e.g., by linking it to the full-res image). Check out Bootstrap's Images page + Bootstrap Grid for the ingredients to do this easily.

The design (aspect) of the web pages does not matter as long as it meets the requirements above and one is able to determine which link to press for accessing the required functionality (login → upload → view gallery).

Web Backend: REST-ful API

A Web-based API (Application Programming Interface) is a contract between the provider of a service and the user wishing to make use of it. This usually consists of the format of the different URLs, specific parameters, HTTP methods they may be called with, and the request / response body formats. REpresentational State Transfer (REST) is a set of common principles / rules which makes such APIs consitent and easy to use.

Your Flask application must, too, adhere to such an API (obligatory for the grading process):

  • / (GET): serves the front HTML page;
  • /login (POST): the authentication form, must use username and password as POST field names (i.e.: <input name=”<this>”)!
  • /upload: the upload endpoint; should use the ''multipart/form-data'' encoding with the following input names: image (the uploaded file – binary data + reason for the FormData encoding), name (name to give to the photo) and category (text field with image category – used for grouping them on the gallery); should return 200 OK

Image formats: use any web-compatible image format (at least PNG + JPEGs should be supported!).

Server port: please configure Flask to bind on all interfaces, e.g.: app.run(host=“0.0.0.0”) (but leave its default port: 5000)!

As stated before, this is important for automating the grading process, so please respect this!

You may add any additional routes as required by your HTML+CSS-based UI (described below).

You may also add additional parameters (but they must be optional!) to the upload / login endpoints (if required by any bonus feature).

Web Backend: Image and Thumbnail Storage

All your uploaded images should be stored persistently.

We recommend saving them to a server filesystem directory + subdirectory for the upload category (e.g., ./upload/<category>/) with either their sanitized (with special symbols removed) original name, or the name entered by the admin inside its upload form (optional field). Make sure to keep the original image's extension when building the destination path!

For bonus points, you can also store images and/or their metadata inside a real database (e.g., SQLite, PostgreSQL, MySQL etc. – but no proprietary ones, please!).

We also require the creation of a small thumbnail (e.g., 200×200) for each uploaded image. You can use the Pillow library for image manipulation in Python to easily obtain this. If the images are stored on the server's filesystem, we recommend to create the thumbnail alongside each image, suffixed with a .thumb.<extension> (yep, don't forget to add the original image extension to this file, too!). Recall the reason for this: the thumbnails will be presented in the gallery, while the full image will be opened on click!

Containerization

In order for your web application to be easily deployable / shared (with us :P), you must add a Dockerfile installing all of its dependencies (also use pip and a requirements.txt file with the libraries you used!). You may start from any base image, although we recommend ''python:<version>-alpine'' due to its low disk footprint.

Thus, a containerized solution must work using the following steps:

  • the docker build -t iap1-tema . command should run successfully;
  • docker run -p 5000:5000 -it iap1-tema should start the Flask server and make it accessible on http://localhost:5000.

Please follow the archiving conventions and have everything (especially the Dockerfile) inside its root directory!

Grading

The base assignment constitutes 4p out of your final grade (100p homework = 4p final grade). The 100p are split between the following tasks:

  • [40p] Frontend Pages, including Flask + Jinja2 templates, gallery and forms; if you don't intend to implement the image upload & storage/resize functionality, make sure to present some stock / sample thumbnail images in your frontpage to get the full points for this!
  • [40p] Backend: functioning image upload form + Flask code to upload, store/resize full photos + thumbnails;
  • [20p] Docker container: must be a working Dockerfile for easily building & running the server during the grading process;
  • [up to 20% of the assignment's points] Bonus ideas:
    • A nice UX ;)
    • Database storage;
    • Extra image processing functionality using the Pillow library (e.g., form to apply various filters etc.);
    • Anything else that adds features to the web application!

You must also write a README (.txt / .md) containing a description of your implementation, design choices, any third party libraries (and the whys), challenges you encountered, etc.

The project's source code (i.e., no binary / generated files need to be included) must be archived (.zip, please) and make sure the scripts (incl. Dockerfile) are placed directly in the root folder (i.e. depth 0) of the archive! Otherwise, the grading process will be slower ⇒ lower score :(

NOTE: Assistants are free do deduct points for bad / illegible code!

Also, please double-check if you followed all naming conventions!

Resources

  • pillow is a image processing module that has support for many image formats and grants the developer access to the pixel data. You can install it using pip (see the Labs for info regarding pip and virtual environments).
  • Flask web framework for Python.
  • Jinja2 template engine (integrated with Flask).
  • Docker container engine (Getting started tutorial).

FAQ

Q: Can I write the tool in something other than Python?
A: No, please use Python. You can have some JavaScript for enhancing your frontend, but the sever-side must use Python.

Q: What platform will this assignment be tested on?
A: Linux (though, you don't need to use any platform-specific APIs + containers/Docker is the pinnacle of portability!).

TODO: Collect questions from Teams / lab and add them here.

ii/assignments/s2/photo-gallery.txt · Last modified: 2024/05/21 10:49 by florin.stancu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0