Code Monkey home page Code Monkey logo

alexkisielewicz / photo-adventures Goto Github PK

View Code? Open in Web Editor NEW
3.0 2.0 1.0 24.33 MB

Photo Adventures Website - Portfolio Project #4 (Full-Stack Toolkit) for Diploma in Full Stack Software Development at Code Institute.

Home Page: https://photo-adventures.herokuapp.com/

Dockerfile 2.97% Python 27.65% Procfile 0.02% HTML 49.34% CSS 10.98% JavaScript 9.04%
cloudinary css3 django-project full-stack-web-development html5 javascript python

photo-adventures's Introduction

Photo Adventures Website

Full-Stack Project (HTML5 CSS3, Bootstrap, Django, Python, JavaScript, jQuery, PostgreSQL, Cloudinary)


Developer: Aleksander Kisielewicz

View live website here ๐Ÿ’ป

Program mockup

Photo Adventures Website was created as Portfolio Project #4 (Full-Stack Toolkit) for Diploma in Full Stack Software Development at Code Institute.

Project purpose was to build a full-stack site using agile methodology to plan and design web application using MVC framework and related contemporary technologies. Appplication offers users full CRUD (create, read, update, delete) functionality.

Application offers such functionalities as:

  • Secure user registration - Users can register with captcha protection and e-mail verification
  • Password reset via email - Users can easily reset their forgotten password with just a few clicks
  • Sign in/out - Users can conveniently sign in and out of their account
  • Role-based access - Access to functionalities is granted based on the user's assigned role
  • User dashboard - Users can view their own personalized dashboard, complete with user content
  • Post management - Users can view, add, edit, and delete their posts with ease (CRUD)
  • Saving drafts and publishing - Users can save their edited posts as drafts or publish them (send to modaration)
  • Moderation - Admins can moderate posts and comments
  • Commenting - Users can leave comments on posts and have their Gravatar user picture displayed
  • Liking - Users can add likes to posts to show their appreciation
  • Messages/feedback - Users receive feedback and confirmation to their actions
  • Social media sharing: - Posts can be easily shared on Facebook and Twitter
  • Contact form: - Users can send messages to the admin through a contact form that includes captcha protection

Table of content

Project

Strategy/Scope

I chose to develop an web application that can be used in real life. My main focus was always on providing an excellent user experience, which is why I decided to create a web application that is both practical and engaging. Photo Adventures is a user-friendly blog-style website where users can share their photo adventures by creating visually appealing blog posts that include both images and text. Application should have clean and intuitive user interface and offer easy access and navigation to all functionalities. Application should also be responsive on devices of all screen sizes.

The website's target audience is anyone who is passionate about photography and enjoys sharing their experiences and stories through pictures. It is inclusive of both amateur and professional photographers who are looking for a platform to showcase their work and connect with like-minded individuals. Whether it's capturing stunning landscapes, wildlife images, or simply capturing moments of everyday life, Photo Adventures Website welcomes anyone who wants to share their love of photography with the world.

To achieve the strategy goals I implemented following features:

  • a clean and intuitive user interface for ease of navigation and readability,
  • a menu that provides easy access to all website sections, including personalized content via user dashboard,
  • cloud hosting of images for optimized website speed and user experience,
  • media queries to ensure responsiveness across all types of devices,
  • feedback messages to users for all important actions taken on the website.

Agile Methodology for project planning

I used agile methodology for the first time when planning full-stack django website with a focus on delivering the basic functionalities. I prioritized features by labeling them as "must-have" or "could-have" and moved some less critical ones to future development. To guide my development process, I created user stories for both the admin user and regular visitors. These stories helped to define the features and functionalities that were most important to project's target audience.

As a solo developer who was learning a lot during development, I faced challenges in estimating the time required for each task and only had a basic concept of what I would create. Therefore, I kept things simple and focused on achievable goals. As the project grew, I was able to add more advanced features and group user stories into milestones. However, I could not find the "epics" feature in GitHub Projects, only milestones (it provides only milestones and issues). Epics are supposed to be larger in scope than milestones, representing a significant amount of work. Milestones, on the other hand, are meant to mark significant points in time in terms of project completion. In this document, I added epics, but on the project board, I used only milestones to stay in order with GitHub's features.

To keep track of progress, I used a kanban board divided into following sections: "to do", "in progress" "done", "future enhancements" and "bugs" that allowed to visualize all tasks and prioritize next steps.

By using agile methodology, I was able to stay organized and focused on delivering the most important features, while also allowing flexibility for future development. This experience gave me valuable insight and lessons that I can apply to future projects.

agile

agile-boards

Epic Milestone User stories
Epic 1: Basic Site Functionality Milestone 1: Authentication #2, #4
Milestone 2: View and select posts #1, #5, #17
Milestone 3: Post CRUD operations #3, #10, #12, #15, #26
Milestone 4: Commenting and Liking #7, #8, #9, #11, #23, #30
Epic 2: User Management Milestone 1: User profile and dashboard #20, #21, #25
Milestone 2: Contact form and spam prevention #16, #33
Milestone 3: Validation #39, #40
Milestone 4: Error handling and feedback #31, #38
Epic 3: Content Management Milestone 1: Draft posts and featured posts #10, #41
Milestone 2: Categories and tags #13, #14, #28, #29, #34, #35
Epic 4: Social media Integration Milestone 1: Share posts on social media #37
Milestone 2: Popular posts and likes display #6, #19, #41

agile-milestones

Site owner goals

  • #2 As Site Admin, I can log in to admin panel so that I can manage posts
  • #3 As Site Admin, I can perform CRUD operations on posts so that I can manage the content on the blog
  • #6 As Site Admin, I can view the number of likes on posts so that I can see which is the most popular
  • #7 As Site Admin, I can view comments on posts so that I can read the conversation
  • #11 As Site Admin, I can approve/delete users comments so that I can moderate inappropriate ones
  • #13 As Site Admin, I can add posts in categories so that I can group photos by this criteria
  • #14 As Site Admin, I can add tags to the posts so that others can easily find posts related to specific topics
  • #23 As Site Admin, I can prevent users from liking their own posts so that posts can be liked only by other users
  • #30 As Site Admin, I want to allow users to have a profile image displayed alongside their comments on the blog so it's easier for readers to identify who is commenting
  • #31 As Site Admin, I want to present the user with a custom 404 page if he navigates to a page that doesn't exist so that he can see a user-friendly message that offers some guidance or suggestions
  • #33 As Site Admin, I want to ensure that only human users can submit the contact form so that I can prevent spam or bot submissions
  • #38 As Site Admin, I want to display success, error, and warning messages to my users using Bootstrap toasts so that they always receive easy-to-understand feedback regarding their actions
  • #39 As Site Admin, I want to validate inputs in add/edit post forms so that I can have control on what input values are allowed
  • #40 As Site User, I can check image dimensions, format, and file size before user upload new image so that I have full control on what files are uploaded to the cloud
  • #41 As Site Admin, I can distinguish specific post as featured post so that I can direct user's attention to that post

External user's goal

  • #1 As Site User, I can view a list of all posts so that I can select one to read
  • #4 As Site User, I want to be able to create an account on the blog so that I can add posts, comments, and likes
  • #5 As Site User, I can select a post so that I can read it
  • #6 As Site User, I can view the number of likes on posts so that I can see which is the most popular
  • #7 As Site User, I can view comments on posts so that I can read the conversation
  • #8 As Site User, I can write comments on posts so that I can be the part of the conversation
  • #9 As Site User, I can like/unlike posts so that I can give feedback in form of likes
  • #10 As Site User, I can create draft posts so that I can finish publishing later
  • #12 As Site User, I can create blog posts with photos and text so that I can share my photography adventures
  • #13 As Site User, I can add posts in categories so that I can group photos by this criteria
  • #14 As Site User, I can add tags to the posts so that others can easily find posts related to specific topics
  • #15 As Site User, I can edit an delete my posts so that I can update them or remove if necessary
  • #16 As Site User, I can use the contact form so that I can contact the website owner if needed
  • #17 As Site User, I can view page content so that I can browse the website and interact with the content
  • #19 As Site User, I can see the posts with the highest number of likes so that I know which posts are the most popular
  • #20 As Site user, I can see my account page so that I can manage my posts
  • #21 As Site User, I can view all posts added by me so that I keep track of my blogging activity
  • #25 As Site User, I can view my drafts in my dashboard so that I can select them and continue editing
  • #26 As Site user, I can click on the edit button in full post view so that I can edit post quickly without the need of searching for the post in the dashboard
  • #29 As Site User, I can get recommendations to read similar posts on the blog so that I can read stories that are in my interest range
  • #35 As Site User, I can view a list of all posts written in specific category so that I can read the posts from categories that I am interested in
  • #37 As Site User, I can share interesting posts on popular social media platforms so that my friends can learn about posts that I enjoyed reading

Wireframes

Wireframes - PDF File

Index - main page

index-top index-down

Blog

blog

Single full post

full-post

About

about

Contact

contact

All accounts pages

accounts

User Experience (UX)

Colour Scheme

Colour palette was selected using coolors.co generator.

I created CSS classes and assigned them roles (examples):

  • #04100D "dark" - main text, headers, post titles
  • #003718 "green" - links inside paragraphs (text and hover outline), social icons, accordion buttonsm, buttons
  • #CDCECF "silver" - post tags bacground
  • #C9E365 "accent-green" - edit post icon (hover)
  • #FFBD59 "accent-orange" - links (hover), social icons (hover), navigation items (hover), user dashboard background

Colour Scheme

Typography

The Merriweather font is the main font used throughout the whole website with Sans Serif as the fallback. Merriweather is a clean, modern looking and well known font. It is sourced from Google fonts and it's linked to css document via @import method.

typography-merriweather

The Gloock is a contemporary high-contrast serif typeface intended for display use. It draws inspiration from newspaper's headlines but with a contemporary approach. I used this font to use for headings and post titles. Serif font is set as fallback.

typography-gloock

Lobster font is used as Photo Adventures text logo, cursive font is set as fallback.

typography-lobster

Logic and features

Data model ad database structure

Project uses cloud-based PostgreSQL database provided by ElephantSQL as a service. ElephantSQL is known for its ease of use, reliability, and is a popular choice for Django projects that requires PostgreSQL database. It offers web interface with console for SQL queries. Database URL including API key is stored as enviromental variable in heroku.

To generate model diagrams I used django-extensions with python library pygraphviz. They show relationship between models.

All django apps including generic/default apps:

all-model

Custom app "blog" with models Post, Comment and TaggedPost.

db-model

Model Description
Post This model represents a blog post and contains fields for the post's title, author, category, excerpt, featured image, location, content, creation and update times, status, and likes. It also has a slug field to generate unique URLs for each post and uses the TaggableManager (taggit library) to add tags.
TaggedPost This model is used to associate tags with posts and is created automatically by the TaggableManager (taggit library).
Comment This model represents a comment on a blog post and contains fields for the post it belongs to, the commenter's name and email, the comment's body, and creation time. It also has an approved field that can be used to moderate comments by admin.

Features

Navbar and main menu

Bootstrap navbar component was used to create navigation bar. It is always visible and stays fixed at the top of the screen. Navbar consists of image logo, text logo and links to main areas of the site (home, blog, about and contact pages). There is also place for Sign up and Sign in buttons which are displayed to unauthenticated user.

navbar-default

Nabar displayed to authenticated user includes user name, gravatar and button link leading to user dashboard.

navbar-loggedin-user

Navbar displayed to staff/admin user includes button with link leading to admin panel (accounts).

navbar-admin

Mobile navbar for medium screen devices with hamburger menu button and collapsible menu.

navbar-mobile1

Mobile navbar for small screen devices, without image logo to save screen space.

navbar-mobile2

Footer

The footer consists of 3 columns. The first column contains copyright info and address. The second one has quick navigation links for easy navigation. The third one includes site logo and social media links with icons, allowing visitors to connect with the brand on popular social media platforms.

On small devices all elements are centered in one column that takes all width of the screen.

footer

Home page - carousel

User is welcomed with image slideshow with pictures related to such categories as Landscape, Nature, Architecture and Travel. Bootstrap carousel component was used to showcase different types of pictures and provide users with a visually engaging and dynamic experience. Slideshow has automatic transition but users can take control of the slides using "previous" and "next" buttons. Each slide picture has header and short slogan description located in overlay. Carousel takes all viewport width and height on big screens and is reduced on small devices that are usually used in portrait mode.

index-carousel

Hero section is designed to catch visitor's attention and provide them basic introduction to site content and purpose. Hero section consists of two columns, one with text and second with image. Unauthorised users can see "Sign up" and "Visit blog" call-to-action buttons. Authenticated user can see "Add post" and "Visit blog" buttons instead.

Home page - hero

index-hero

Below hero section there are animated counters that present "page in numbers" statistics. They show total number of posts, comments, reactions and registered users.

Home page - counters

index-counters

Most liked posts is a section that presents three posts with highest numer of "likes". Posts are displayed as bootstrap cards, they include links to full articles.

Home page - most liked posts

index-most-liked

Blog

Blog page is a list of all posts. Each post is presented as bootstrap card that includes featured image (or default placeholder if picture is not provided by user), post title, brief excerpt. In addition to this elements user can also find post details such as its location, author, creation date and number of likes and comments. The posts are paginated by 5 articles per page.

blog

It is possible to browse posts by tags.

blog

Full Post

When viewing a post in full, users will see either a featured image or a placeholder if the author hasn't provided one. As on the blog page, the post title and other details are displayed beneath the image. On the left side of the picture, an overlay shows the location information. In the top right corner, users will find a like button. Only authenticated users can like posts, and if the user is also the author of the post, they will see an edit button below the like button. In the bottom right corner of the picture, there are social media sharing buttons, allowing users to easily share the post on Facebook or Twitter.

In the full post view, users can also see post tags, which can be clicked to bring the user to a list of related posts. This feature helps readers discover other content on the same topic and explore related ideas.

Beneath the main content of the article, you'll find a comment section. On the left-hand side of the page, all comments are displayed, along with the author's Gravatar, username, and date of the comment. For users who do not have a Gravatar account, a placeholder image will be displayed instead. This ensures that all comments are visually consistent. To post a comment, users must be authenticated and can use the form provided in the right-hand column. A link to guidelines and posting rules is also included to ensure that all comments are respectful and related to topic.

full_post1

full_post2

full_post3

full_post3

About Page

The About page is divided into three paragraphs. The first paragraph introduces who we are as a group, while the second highlights passion for photography. The third paragraph outlines the mission and what we hope to achieve. Images are included within the text to visually enhance the content.

about1

At the bottom of the page, a bootstrap accordion houses a FAQ section. The answers to common questions are provided in a concise format, making it easy for users to quickly find the information they need.

about2

Contact Page

The Contact page is designed with a two-column layout, featuring the contact form on the left and the location, address, and Google Maps on the right. Users can use the contact form to get in touch with the site admin directly. To facilitate sending emails through client-side technologies, the Email.js library has been integrated. The form allows users to fill in their name, email address, and message, and authenticated users can have their name and email fields pre-filled for convenience.

To prevent spam, a Google reCAPTCHA v2 widget has been implemented.

On the right-hand side, the location, address, and Google Maps provide users with a visual representation of where we are located and make it easy for them to find us.

contact

Admin Panel

The admin panel provides access to various details related to blog posts, including the post title, slug, author, category, tags, status, and creation date. These details make it easy for the admin to manage and organize posts effectively. There is also existing "featured" field in the model, this functionality was left as potential future enhancement and has been described in project's user stories.

In addition, actions have been registered that allow the admin to select multiple posts and change their status in one click. This feature saves time and helps to manage larger number of posts.

admin1

Also a list of filters have been registered in the admin view, admin can sort and display posts by author, status, etc.

admi2

User Dashboard

The page displays a dashboard for the user with basic statistics about their blog posts and gives user the ability to manage them (full CRUD functionality). The user's gravatar is displayed in the top left of the page, along with a welcome message that greets the user by name. In this section user can also find "Add post" button to click and start writing new post. The form of keypoints inform users that they can manage their content from the dashboard and can view their post history and monitor engagement such as likes and comments.

Three sections below show all posts written by user in a form of bootstrap cards. They are divideded into tabs: drafts, awaiting moderation and published posts. The sections stay hidden until there is related content to be presented. Each card can be clicked and overlay contains relevant control buttons allowing viewing, editing or deleteing posts.

dashboard1

dashboard2

dashboard3

dashboard4

Form of defensive development, post deletion confirmation screen.

dashboard5

Accounts Templates

All accounts subpages are based on one template designed for this purpose. It's a narrow container with header image and form or other relevant information.

User can sign up using registration form. Google reCaptcha v2 widget was implemented to ensure that only human users can register and to protect site against spam and bots. Users who have already registered can click a link at the bottom of the page to sign in.

accounts1

accounts2

Account verification setting has been set to "mandatory". Gmail SMTP service has been configured to provide email backend service for this functionality. Upon successful registration, user receives e-mail verification message.

accounts3

User is asked to click the link to activate the account.

accounts4

The link (if valid) brings user to confirmation page. On successful confirmation user is automatically signed in and redirected to home page.

accounts5

If the link is invalid or the token has expired, the user will be prompted to log in with their email and password to receive a new confirmation email.

accounts6

If a user who already has an account attempts to sign up again using the same email, they will receive a notification email.

accounts7

Returning registered user can sign in.

accounts8

Forgotten password can be reset.

accounts9

accounts10

Message that user receives if requested password reset. Again, if link/token is valid user can proceed with password change, if not, will see "bad token" error page and can repeat the process.

accounts11

accounts12

On successful password change user is asked to go to sign in page to continue.

accounts13

Add/Edit Post - form validation

Users can access the "Add Post" page from the user dashboard. The form on the page is used for submitting a new post. Basic validation has been implemented into the form using JavaScript.

The form fields reflect the model post fields: Title, Slug, Category, Tags, Excerpt, Image, Location, Content, and Status. All fields are required; however if users don't upload an image, a placeholder will be present in the template.

Slug field is being filled automatically (and converted to dash-separated lowercase words) when user type in title field, user still needs to interact with this field in order to make it valid. Event listener "input" is attached.

add-post1

Fields that are not validated with JavaScript:

  • Image field: I left this feature as possible future enhancement and described here.
  • Content field: Summernote WYSIWYG widget is used for this field. Django only checks if field is not empty, this is sufficient as any character would be allowed in post body.
Field Allowed input Matching charset, regular expression Length (min, max)
Title Alphanumeric, space, coma /^[a-zA-Z0-9 ,]+$/ 5 - 50
Slug Lowercase alphanumeric, dash /^[a-z0-9]+(?:-[a-z0-9]+)*$/ 5 - 50
Category (select) One option from dropdown menu Any option (no default is selected) N/A
Tags Comma-separated words with alpha char, space /^([a-zA-Z]{3,}\s*,\s*)*[a-zA-Z]{3,}$/ 3 - 60, the shortest tag - 3
Excerpt Alphanumeric, space, special any 10 - 200
Location Alpha, space, coma /^[a-zA-Z ,]+$/ 4 - 40
Status (radio checkbox) Any option from two available Valid if any is checked N/A

The validation functions have been connected to the field inputs using "input" event listeners. The script checks if the form is valid and then uses the Bootstrap classes "is-valid" or "is-invalid" to highlight the field in green or red. This gives the user feedback about whether the input is correct or incorrect. When all fields become valid and highlighted with green, the "submit" button becomes active and form can be send. Submit button is disabled by default when page is loaded. The same script and mechanism works on "Edit page", user need to interact with the fields, make them valid in order to be able to save changes.

add-post2 add-post3

Messages

Django messages are implemented in the website's app. These messages are displayed using the Bootstrap toast component on several occasions when feedback is needed, such as signing in/out, commenting, saving drafts, and editing changes to posts.

messages

Technology

Languages used

  • HTML5 - markup language used for structuring webpage content
  • CSS3 - stylesheet language
  • JavaScript - high-level, imperative, programming language.
  • Python - high-level, imperative, general-purpose programming language.
  • Markdown - markup language used to write README and TESTING documents.

Software used

  • Animate On Scroll AOS - library used to animate containers on the website
  • Bootstrap 5 - CSS framework developed by Twitter
  • Balsamiq - used to create project wireframes
  • Cloudinary - cloude-based image and video API
  • Canva - used to design logo picture
  • Convertio.io - used to convert images to webp format
  • Coolors.co - was used to create colour palette for terminal display page
  • Django - python-based web framework with MTV architectural pattern
  • ElephantSQL - PostgreSQL database as a service
  • EmailJS - JavaScript library used to send emails usung only client-side technologies
  • Favicon.io - tool used to create favicon
  • Font Awesome: - Font Awesome icons were used for social links in terminal display page
  • Git - Git was used for version control by utilizing the Gitpod terminal to commit to Git and Push to GitHub
  • GitHub - GitHub is used to store the project's code after being pushed from Git
  • Google DevTools - used for developing HTML/CSS/DOM navigating/JavaScript console
  • Google Lighthouse - used for testing website performance
  • Google Maps - google map used in contact page
  • Google reCaptcha v2 - captcha widget used to prevent spam
  • Gmail - SMTP service used for sending emails
  • Gravatar - global avatar, allows to display user profile picture related to email
  • Heroku - online app used to deploy project
  • Jinja - web template engine for python/django apps
  • jQuery - JavaScript library
  • Pexels - was used to source bacground picture for terminal display page
  • Techsini.com - website mockup generator
  • WAVE - web accessibility online tool
  • WebAIM - online tool to check colour contrast/accesibility

Python libraries/modules

  • os - built-in Pythod module - used to save and import env variables
  • cloudinary - cloud hosting used to store pictures
  • dj3-cloudinary-storage - provides django integration with Cloudinary service
  • django-crispy-forms - renders elegant div based forms
  • CrispyBootstrap5 - template pack for django-crispy-forms
  • dj-database-url - utility that allows configure environment variable to a connection string that includes the database engine
  • django-allauth - integrated django accounts management
  • django-social-share - used for facebook and twitter share buttons
  • django-summernote - WYSIWYG editor widget used for writing/editing post content
  • django-taggit - used for post categorizing by tag name
  • gunicorn - Python WSGI HTTP Server for UNIX
  • oauthlib - framework for implementing open standard for authorization
  • psycopg2 - PostgresSQL database adapter for Python language
  • PyJWT - Python library for encoding, decoding and veryfying JSON Web Tokens
  • pytz - library that provides support for working with time zones, converts the dates between zones
  • requests-oauthlib - OAuth library suppor for python requests
  • sqlparse - non-validating SQL parser for Python. It provides support for parsing, splitting and formatting SQL statements.
  • pygraphviz - used to generate visualization of database model

Testing

Manual testing

Details of manual testing can be found in TESTING.md file.

Bugs/known issues

Minor syntax and spelling errors were eliminated during development, below is a list of registered issues.

Issue Problem Solution
#22 Bootstrap cards for posts without uploaded images are not displayed correctly If/else statement added in the template to diplay placeholder image if featured image is not available
#27 When the user sends the form with a new post or edits an existing post draft, the tag field stays empty after saving. The database is not being updated as expected. Save many to many method was added within if statement
#36 Error 404 - not found occurs when sending a comment on full_post.html. Queryset was changed to filted only published posts
#43 2 template syntax errors found using django-extensions validate_templates. One in account/email.html and one in account/verified_email_required.html Misspelled "load" in templates/accounts/email.html was corrected, head_title block was removed from accounts/verified_email_required.html (screenshot added to issue)
#44 During the tests, I found out that Google Maps iframe element (third party code) on contact.html page generates a console errors (screenshot added to issue) It appears that the errors are linked to the use of ad blockers in the browser. After testing with filters turned off and in private mode, I was able to browse without encountering any errors.

Deployment

App was deployed to heroku for the first time when django installation was completed to make sure that everything is working correctly.

Database (ElephangSQL)

  1. Navitate to ElephantSQL website, log in to your account
  2. In top-right corner click on green button "Create New Instance".
  3. Enter database name, leave plan field as is, optionaly enter tags.
  4. Select region, click on "Review" and then on "Create instance".
  5. Go to your dashboard, find newly created database instance, click on it.
  6. Copy URL starting with "postgress://"
  7. Paste this URL into env.py file as DATABASE_URL value and save the file.
os.environ["DATABASE_URL"] = "postgres://yourLinkFromDatabaseDashboard"

Cloudinary

  1. Navigate to https://cloudinary.com/ and log in to your account.
  2. Navigate to dashboard/console https://console.cloudinary.com/console/ and copy API Enviroment variable starting with "cloudinary://".
  3. Paste copied url into env.py file as CLOUDINARY_URL value and save the file.
os.environ["CLOUDINARY_URL"] = "cloudinary://yourLinkFromCloudinaryDashboard"

Django secret key

In order to protect django app secret key it was set as anviroment variable and stored in env.py. Please change your password accordingly.

os.environ["SECRET_KEY"] = "yourSecretKey"

Gmail SMTP

Warning: Gitpod doesn't allow to use smtp service, emails won't be send if you run http server on Gitpod. If debug mode is switched to True, emails will be visible in the console. Emails will be sent correctly on deployed project assuming all enviromental variables are configured correctly.

In order to have google smtp service running in local env, make sure you add following variables to env.py:

import os

os.environ["EMAIL_HOST_USER"] = "[email protected]"
os.environ["EMAIL_HOST_PASSWORD"] = "yourpassword"
os.environ["DEFAULT_FROM_EMAIL"] = "Photo Adventures"

Email password needs to be generated in order to use gmail with third party apps. Go to https://myaccount.google.com/ navigate to security section to generate password. If you need more help on that, please follow this tutorial.

envvars

GitHub and Gitpod

Note: Repository was created using Code Institute template: https://github.com/Code-Institute-Org/gitpod-full-template

  1. Login to Github and navigate to repository: https://github.com/alexkisielewicz/photo-adventures

  2. Click on "Fork button" in upper-right corner and create a new form in your own account.

  3. Open your repository in local IDE or using Gitpod. Preferred way is to used Chrome Gitpod Extension. When you install extension, green "Gitpod" button appears in your repository. Click on it to cread new workspace.

  4. Go to workspace terminal and install all requirements using command: "pip install -r requirements.txt". All te packages will be installed. requirements.txt content:

    asgiref==3.6.0
    cloudinary==1.32.0
    crispy-bootstrap5==0.7
    dj-database-url==0.5.0
    dj3-cloudinary-storage==0.0.6
    Django==3.2.18
    django-allauth==0.52.0
    django-crispy-forms==2.0
    django-social-share==2.3.0
    django-summernote==0.8.20.0
    django-taggit==3.1.0
    gunicorn==20.1.0
    oauthlib==3.2.2
    psycopg2==2.9.5
    PyJWT==2.6.0
    python3-openid==3.2.0
    pytz==2022.7.1
    requests-oauthlib==1.3.1
    sqlparse==0.4.3
  5. Local env.py file should be configured as on example below:

    import os
    
    # Env vars
    os.environ["DATABASE_URL"] = "postgres://yourLinkCopiedFromElephantSQLDashboard"
    os.environ["SECRET_KEY"] = "YourSecretKey"
    os.environ["CLOUDINARY_URL"] = "cloudinary://yourLinkCopiedFromCloudinaryDashboard"
    
    # Gmail vars
    os.environ["EMAIL_HOST_USER"] = "[email protected]"
    os.environ["EMAIL_HOST_PASSWORD"] = "passwordObtainedFromGoogleAccount"
    os.environ["DEFAULT_FROM_EMAIL"] = "Photo Adventures"
  6. In order to save django changes in database migration needs to be made.

  7. Use terminal commands:

    python3 manage.py makemigrations
    python3 manage.py migrate
    
  8. Create superuser to access admin area using terminal command (email is optional, password won't be visible when typing, confirm password twice):

    python3 manage.py createsuperuser
    
  9. App can be run in gitpod enviroment using terminal command:

    python3 manage.py runserver
    
  10. Go to Heroku and follow further instructions below.

Heroku

  1. Navigate to https://heroku.com/ login to your account and open dashboard. Click button "New" and select "Create new app" button.

  2. Enter app name, I used "photo-adventures", chose your region and click on "Create app" button.

  3. Click on newly created app and go to "Deploy" tab and then to "Deployment method" section. Authorize and connect your GitHub account, then find and select your repository.

  4. Go to the "Settings" tab, click on "Reveal Config Vars" and add the following keys and values (all values should be strings without any quotation marks):

    NOTE: DISABLE_COLLECTSTATIC variable should be set to "1" for initial deployment. Before final deployment it should be removed.

    Key Value
    CLOUDINARY_URL cloudinary url beginning with cloudinary://
    DATABASE_URL postgress url beginning with postgress://
    DEFAULT_FROM_EMAIL Photo Adventures
    DISABLE_COLLECTSTATIC 1
    EMAIL_HOST_PASSWORD YourPassword obtained from Google account
    EMAIL_HOST_USER [email protected]
    PORT 8000
    SECRET_KEY YourSecretKey, the same as in env.py

    envvars

  5. Return to your Gitpod workspace and navigate to the file photoadventures/settings.py. Change allowed hosts including the name of the app that you created in previous steps. In my case, it was 'photo-adventures.herokuapp.com'. Save the file.

    hosts

  6. Procfile required to run project on Heroku was already created but if you change your app's name please make sure that this change is reflected in Procfile. It can be found in your project's main directory. In my case Procfile looks as below:

    web: gunicorn photoadventures.wsgi
  7. After adding enviromental variables and editing Procfile project is ready for deployment. In Heroku app's dashboard navigate to "Deploy" tab, scroll down to "Manual deploy" section. Select main branch from dropdown menu and click on "Deploy Branch".

  8. Step required for final deployment: Navigate again to app's settings, reveal config vars and delete DISABLE_COLLECTSTATIC entry if it was set before.

  9. After built is done, you should be able to see the button with the link leading to deployed app. In my case http://photo-adventures.herokuapp.com.

Possible future development

If I had more time or decide to develop app further I would add/improve following functionalities that I moved to Future enhancements column on project board:

  • #29 Similar posts recommendation to suggest user next read
  • #34 Post list by category
  • #35 Post list by author
  • #40 File size/format/dimension validation of uploaded images
  • #41 Featured post - functionality that allows admin to mark selected post as featured and highlight it on main page.

Credits

Code

  • send_email.js - basic configuration was done as in Code Institute walkthrough and then further developed,
  • in order to implement gravatar I used method suggested in gravatar docs, that required to create and register custom template tag as described in django docs,
  • idea for counters animation on the main page found in this snippet,
  • patterns for regular expressions used for input validaiton found here.

Media

Learning resources

Acknowledgements

  • My Mentor Reuben Ferrante for helpful feedback and guidance at all stages of the project.
  • Code Institute Slack Community for being invaluable knowledge base.

Disclaimer

  • Photo Adventures Website was created for educational purpose only.

photo-adventures's People

Contributors

alexkisielewicz avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar

photo-adventures's Issues

[User Story] 404 Error page

User story:

As Site Admin, I want to present the user with a custom 404 page if he navigates to a page that doesn't exist so that he can see a user-friendly message that offers some guidance or suggestions

Acceptance Criteria:

  • page 404 is displayed when not found error occurs
  • page 404 contains a link to the home page, so the user does not have to use the browser "go back" button

[User Story] Save draft posts

User story:

As Site User, I can create draft posts so that I can finish publishing later

Acceptance criteria:

  • When writing a new post user can select form option to change the post status to "draft"
  • When editing an existing post user can select form option to change the post status to "draft
  • In both situations, the post can be successfully saved in the database with selected status

[User Story] User can comment

User story:

As Site User, I can write comments on posts so that I can be part of the conversation

Acceptance criteria:

  • Authorised users can add comments to posts using the comment form.
  • Comments are not visible to the public before being approved by admin.
  • The user receives a confirmation message upon successful submission of the comment form.
  • Comments approved by the admin should be visible to all users in the comments section of the relevant post.

[User Story] User profile page

User story:

As Site user, I can see my account page so that I can manage my posts

Acceptance criteria:

  • Link to the dashboard is present in the navbar for an authorized user
  • Authorized users can access their own user dashboard
  • Anonymous users can not access any user's dashboard
  • Posts belonging to the user (if exist) are visible in the user dashboard

[BUG] Tags are not saved in the add_post and edit_post forms

Describe the bug
When the user sends the form with a new post or edits an existing post draft, the tag field stays empty after saving. The database is not being updated as expected.

To Reproduce
Steps to reproduce the behavior:

  1. As a logged-in user go to the dashboard and click 'Add new post'
  2. Complete the form and click 'send'.
  3. As an admin, check post details in the admin panel to see that field 'tags' is empty

Expected behavior
Tags should be saved in the database upon form submission on the add_post and edit_post pages

[User Story] Categorize blog posts

User story:

As Site User/Admin, I can add posts in categories so that I can group photos by this criteria

Acceptance criteria:

  • There are various categories existing in the backend
  • When creating or editing a post, user can select a category from the list of existing categories
  • Created or edited post can be successfully saved with chosen category

[User Story] Post list by category

User story:

As Site User, I can view a list of all posts written in specific category so that I can read the posts from categories that I am interested in

Acceptance Criteria:

  • category is a link in full post view, the user can click it to display all posts from this category
  • list of posts is paginated the same way as in blog template

[User Story] Basic page template

User story:

As Site User, I can view page content so that I can browse the website and interact with the content

Acceptance criteria:

  • The Site User should be able to access the website and view its rendered templates without issues.
  • The website should not have any broken links or missing content that would prevent Site Users from accessing or interacting with the website's content.

Tasks

  • Create basic html sceleton and add semantic tags
  • Add headers including links to style, bootstrap
  • Add basic navigation
  • Add script links to bootstrap js and jquery

[User Story] Share posts on social media

User story:

As Site User, I can share interesting posts on popular social media platforms so that my friends can learn about posts that I enjoyed reading

Acceptance criteria:

  • Social share buttons are present in full post template
  • Buttons can be clicked to share current post on chosen platform

Tasks

  • In the full_post template - add a button that the user can click to share a post on social media
  • Provide Facebook and Twitter sharing buttons as they are the most popular platforms.
  • Add to the template open graph meta tags that are widely used by social platforms to read meta tags of sharing content.

[User Story] Tag name in header when browsing posts by tags

User story:

As Site User, I want to be able to see the name of the tag associated with blog posts that I am currently browsing so that I can understand the context and navigate between posts with similar themes

Acceptance criteria:

  • In full post view tags are displayed within post details
  • Each tag is a link that the user can click to browse the page with all posts tagged with this specific tag

[User Story] Edit button on full post view

User story:

As Site user, I can click on the edit button in full post view so that I can edit post quickly without the need of searching for the post in the dashboard

Acceptance criteria:

  • There is an edit button present in the full_post template
  • User can click the button that leads to the edit_post template that renders the post edit form

Tasks

  • Add edit button in full_post template and link it with edit_post URL
  • Adjust the button position to stay over the picture near like icon

[User Story] Approve/delete comments

User story:

As Site Admin, I can approve/delete users comments so that I can moderate inappropriate ones

Acceptance criteria:

  • Admin should be able to view a list of all comments made on the website.
  • Admin should be able to select a comment to approve it or delete it.
  • Deleted comments should not be visible to anyone.
  • Approved comments should be visible for all visitors on the full_post page for the relevant post.

[User Story] Django messages in bootstrap toasts

User story:

As Site Admin, I want to display success, error, and warning messages to my users using Bootstrap toasts so that they always receive easy-to-understand feedback regarding their actions

Acceptance criteria:

  • bootstrap toast is added to the base.html template
  • toast is initialized using JS
  • appropriate messages are added in the backend eg. when commented when added like when signed in
  • messages are triggered correctly and displayed in the toast

[User Story] Add tags to posts

User story:

As Site User/Admin, I can add tags to the posts so that others can easily find posts related to specific topics

Acceptance criteria:

  • A user/admin should be able to add tags to a post while creating or editing the post.
  • The tags should be keywords or short phrases that describe the content of the post.
  • A post can have multiple tags.
  • The tags should be visible to all users who view the post.
  • A user should be able to click on a tag to see a list of all posts with that tag.

[User Story]: View all posts

User story:

As Site User, I can view a list of all posts so that I can select one to read

Acceptance criteria:

  • Posts retrieved from the database are visibly rendered in the blog template
  • There are at least two posts visible
  • User can click post to go to full post view

Tasks

  • Create post model
  • Create a database
  • Make migration

[README] Write readme documentation

Topics to be included in the README:

  • Project/Strategy/Scope
  • User Stories for Users and Site Owner
  • UX/UI
  • Logic and data model
  • Technology used
  • Testing
  • Deployment
  • Possible future development
  • Credits

[User Story] View number of likes on post

User story:

As Site User/Admin, I can view the number of likes on posts so that I can see which is the most popular

Acceptance criteria:

  • Total number of likes for post is visible in post details on blog page
  • Total number of likes for post is visible in post details on full_post page

[User Story] Post list by author

User story:

As Site User, I can view a list of all posts written by specific authors so that I can select only this author's posts to read

Acceptance Criteria:

  • User can click on the author's name in full post view to display all posts written by this author
  • The list is paginated the same way as the blog template

[User Story] Open blog post

User story:

As Site User, I can select a post so that I can read it

Acceptance criteria:

  • Post is displayed on the website
  • User can click a link leading to the post
  • User can read full post

Tasks

  • Add a link to the post in the blog template
  • Add post to the views
  • Add url path to single post view

[User Story] List of posts added by user in the profile

User story:

As Site User, I can view all posts added by me so that I keep track of my blogging activity

Acceptance criteria:

  • A user should be able to view a list of all posts that they have added to the blog.
  • The list should be accessible from the user's dashboard.
  • The list should display at least the post featured image, post title, and a link to the post.
  • The newest post should be displayed at the top.
  • The user should be able to click on a post thumbnail to go to the full post view.

[User Story] User creates post

User story:

As Site User, I can create blog posts with photos and text so that I can share my photography adventures

Acceptance criteria:

  • User can successfully create a new post that includes text and images.
  • Full post can be rendered and displayed as full post view.

[User Story] Top 3 liked posts

User story:

As Site User, I can see the posts with the highest number of likes so that I know which posts are the most popular

Acceptance Criteria:

  • the main page contains a section with "most liked posts"
  • 3 posts with the highest number of likes are displayed in the bootstrap card component
  • number of likes is displayed on each card

Tasks

  • Add to views: query database for all posts, display order by most liked, slice array to show last 3
  • Display view in html template

[User Story] Featured post

User story:

As Site Admin, I can distinguish specific post as featured post so that I can direct user's attention to that post

Acceptance criteria:

  • featured post field is added to the post model
  • selected featured image is displayed in the template
  • admin can edit posts and and mark it as featured post

[User Story] Implement google reCaptcha

User story:

As Site Admin, I want to ensure that only human users can submit the contact form so that I can prevent spam or bot submissions

Acceptance Criteria:

  • google captcha widget is present in the contact form
  • contact form can not be sent without solving the captcha
  • the appropriate message is shown if the captcha is not solved and the user tries to send a form

[User Story] User can like/unlike posts

User story:

As Site User, I can like/unlike posts so that I can give feedback in form of likes

Acceptance criteria:

  • Like button as a heart icon should be present in the full_view template for each post.
  • A user should only be able to like a post once and unlike it afterward.
  • The like count for a post should be displayed within post details.
  • A user should not be able to like their own posts.
  • If a user unlikes a post, their like should be removed from the like count for that post.
  • Anonymous users should not be able to like the posts.

[User Story] Prevent user from liking own posts

User story:

As Site Admin, I can prevent users from liking their own posts so that posts can be liked only by other users

Acceptance criteria:

  • User can not add like to own posts
  • Feedback is displayed if the user tries to like their own post

Tasks

  • Add if else statement to check if the active user is the author of the post
  • Disable likes form if the statement above is true/allow to like if not true
  • Add user feedback in html template

[User Story] Create user account

User story:

As Site User, I want to be able to create an account on the blog so that I can add posts, comments, and likes

Acceptance criteria:

  • A user should be able to create an account on the website by providing their email, name and password.
  • The user should be required to provide a unique email when creating an account.
  • The user should be able to log in to their account using their email address and password (if the account has been verified).

Tasks

  • Add 3 buttons in the template: for registration, login, and logout
  • Install allauth
  • Add accounts links/ to urls

[User Story] File size/format/dimension validation

User story:

As Site Admin, I can check image dimensions, format, and file size before user upload new image so that I have full control on what files are uploaded to the cloud

Acceptance criteria:

  • Validation checks filesize
  • Validation checks file extension
  • Validation checks image width and height

[User Story] Add/edit post validation

User story:

As Site Admin, I want to validate inputs in add/edit post forms so that I can have control on what input values are allowed

Acceptance Criteria:

  • Script is linked to add_post template
  • Script is linked to edit_post template
  • All text fields (except summernote widget field) are validated using individual set of allowed characters
  • Form can not be sent until are text fields are valid

[User Story] Manage posts

User story:

As Site Admin, I can perform CRUD operations on posts so that I can manage the content on the blog

Acceptance criteria:

  • admin should be able to create posts
  • admin should be able to view all posts
  • admin should be able to edit posts
  • admin should be able to delete existing posts

[User Story] Draft post on the dashboard

User story:

As Site User, I can view my drafts in my dashboard so that I can select them and continue editing

Acceptance criteria:

  • posts with status "draft" are displayed in the user dashboard in "drafts" tab
  • edit link is provided for selected draft post that allows the user to go to the edit_post page and continue editing

Tasks

  • Add draft field to post model
  • Modify view
  • Modify add post and edit post forms

[User Story] View comments on posts

User story:

As Site User/Admin, I can view comments on posts so that I can read the conversation

Acceptance criteria:

  • Approved comments are visible to all visitors on the full_post page for the relevant post.
  • Each comment should include the author's name, date and time of submission, and comment body.

Implementation of gravatars

User story:

As Site Admin, I want to allow users to have a profile image displayed alongside their comments on the blog so it's easier for readers to identify who's commenting**

Acceptance criteria:

  • The user's avatar is displayed in full post view next to the body of the user's comment
  • The user's avatar should be displayed to anyone who views the comment section
  • The user's avatar should be displayed as round pictures

Tasks

  • Add support for gravatar images by using the gravatar API to retrieve the image associated with a user's email address, if available.
  • Provide placeholder image if gravatar is not associated with user email
  • Modify the comment section in the full post template

[User Story] Contact form/submit message

User story:

As Site User, I can use the contact form so that I can contact the website owner if needed

Acceptance Criteria:

  • contact page contains the contact form
  • user can fill in the form with name, password, and message
  • filled form can be successfully sent
  • sent message is successfully delivered to admin

Modify UI/UX for django default templates

Adjust UI to match the style of the website, also adjust default forms:

  • sign_in.html
  • sign_up.html
  • logout.html
  • password_reset.html
  • edit_post.html
  • add_post.html
  • delete_post.html

[BUG] Google Maps console errors

Describe the bug
During the tests, I found out that Google Maps iframe element (third party code) on contact.html page generates a console error as in the enclosed screenshot.

Screenshots
bug

Desktop (please complete the following information):

[User Story] Total number of comments

User story:

As Site User, I can see total number of comments for individual post so that know which post is most discussed

Acceptance criteria:

  • Number of comments made is displayed on blog page
  • Number of comments made is displayed on individual post

[User Story] Similar posts recommendations

User story:

As Site User, I can get recommendations to read similar posts on the blog so that I can read stories that are in my interest range

Acceptance criteria:

  • Link to the post is presented to the user
  • Link leads to the post from the same category as the reading post

[User Story] Admin panel

User story:

As Site Admin, I can log in to admin panel so that I can manage posts

Acceptance criteria:

  • The Site Admin should be able to access the admin panel by providing valid login credentials.
  • After logging in, the Site Admin should be directed to the admin panel where posts can be managed.
  • The admin panel should only be accessible to authenticated Site Admins and should redirect any unauthorized access attempts to the login page.

Tasks

  • create django superuser
  • create admin view, add url path
  • navigate to /admin page and logit to the admin panel

[User Story] Edit and delete posts

User story:

As Site User, I can edit and delete my posts so that I can update them or remove them if necessary

Acceptance criteria:

  • The user is able to edit their own posts using the edit link in the dashboard.
  • Changes made by the user can be successfully saved.
  • The user receives a confirmation message upon saving changes.
  • The user is able to delete their own posts using the delete link in the dashboard.
  • An appropriate message is displayed before post deletion, giving the user a choice to delete the post or cancel.
  • Deletion of the post is not possible until confirmed by the user.
  • Once a post is deleted, it should no longer be accessible or visible to any user.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.