SyntheStory is a website that randomly generates story ideas for authors. The 'story idea' is a central concept in SyntheStory and represents a short and sweet premise for a story. The need for a website like SyntheStory would be that authors are sometimes lacking in inspiration and a site generating random ideas can help with filling that void.
After creating an account on SyntheStory, a user can filter by genre and SyntheStory will randomly generate a story idea for the user by pulling from a database containing only that particular genre's ideas. These ideas are created by the admin of the site and additional snippets of ideas and genres can be created by the admin in order to extend the usability of the site.
After a user has given a story idea a title, they can edit (editing can be done before saving), save and delete stories by accessing their own area of the website called 'My Stories'. This way a user can refer to their ideas, change randomly generated ones that don't quite fit and even create entirely original ones. SyntheStory is a website designed to get an author's writing off the ground and NOT a place to actually write stories so there is a character limit on the length of story idea.
You can find the deployed SyntheStory site by following the link here
The Homepage contains a brief introduction and instructions on how to use SyntheStory. It is the only 'main page' (meaning pages other than error pages or pages to do with login) which does not require login access.
The Genre page contains a list of genres from which the user can choose to narrow down a generated story idea. They can click on the links in the cards to take them to a Genre Type page which will display a Story Idea with their chosen genre.
The Genre Type page contains a randomly generated Story Idea taken from a 'bank' of Story pieces in the database related to a specific genre. The user can save a story idea using the Save Story Idea! button or refresh the page with a new randomly generated Story Idea by clicking the Generate Another Idea! button. The user can also edit the Story Idea field text and both fields must be filled in before a submission can be made.
The My Stories Page represents the user's saved stories and as such is unique to each user (see MANUAL_TESTS.md for information on how users are prevented from interfering with other users' data). The My Stories page contains links to each of the users saved Story Ideas.
The Story Idea Page is unique to each Story Idea and can only be accessed by the user who's profile corresponds to that particular Story Idea. In the Story Idea page Story Ideas can be edited by pressing the Edit Story Idea button, editing and clicking the Save Edited idea button or deleted by pressing the Delete Story button.
The Login, Logout and Signup pages act as you would imagine, giving people the opportunity to make accounts and work the site. Many parts of the site will be blocked off and will redirect to the Login page unless a user is logged in.
The 403, 404 and 500 error pages are there to indicate errors to a user. The 404 page will occur if the user tries to access something which does not exist. The 403 page will occur if the user tries to interact with another user's Story Ideas and the 500 page will occur if there is an internal server error. The user will be redirected to the homepage from there.
A feature that is far beyond the scope of this project but might be an idea for the future would be to somehow link each generated Story Idea up to an API to do with a text-to-image diffusion model which would display an AI generated image displaying the Story Idea in picture form. I am not entirely sure on the achievability of this at the current moment and am ignorant of any potential copyright issues that would occur but believe it might help inspire an author with imagery.
A feature that was not included was a mandatory email signup feature as this was deemed to be outside the scope of the project and unnecessary.
A feature that would auto-generate a title based on the story text of a story idea was considered as an idea but was not included due to the work necessary to make it 'fit' with the story idea organically. I estimated this feature would take more time than it was worth as most users would probably change the title anyway.
Five data models were created for SyntheStory: Genre, StoryStart, StoryMiddle, StoryEnd and StoryIdea. The User model was also imported from django.contrib.auth.models.
The Genre Model represents a single genre by which the user can filter which ideas are generated from. Each Genre instance contains a title, an image and a description to display to the frontend and also contains a creation date which is used to order the Genre data. The Genre Model relates to the StoryStart, StoryMiddle and StoryEnd models by acting as a foreign key for them. New Genres can be created by an admin of the site, allowing extensibility to SyntheStory's random generation in the future.
The StoryStart, StoryMiddle and StoryEnd Models are very similar and could have been derived from a base class but were decided not to due to there only three of them and the story text fields changed size on each of them. They represent corresponding parts of a randomly generated idea and contain story text, creation date and genre(which is a foreign key for Genre) fields. The genre foreign key interacts with the view to make sure that once the user has filtered their ideas by genre only that idea is pulled from when SyntheStory generates random ideas. New StoryStarts, StoryMiddles and StoryEnds can be created by the admin of the site, allowing extensibility to SyntheStory's random generation in the future.
The StoryIdea Model represents a saved story idea that is connected to a user. This is used to present the user with their story ideas and allow them to edit and delete them as needs be. Each StoryIdea instance contains a user(foreign key connected to User), title, story text and a creation date and updated on date. The title and story text fields are used to display information on the frontend and the creation date is used to refer to when it was created and the updated on date is used to control te order that the story ideas are presented to the user in their My Stories page.
SyntheStory was created using an agile planning method and utilised the GitHub Projects Kanban Board. Link to Kanban Board for SyntheStory
The SyntheStory project was developed in a series of sprints. Each sprint ran for 7 days and was tracked using GitHub's Project Milestones and were attached to user stories when completed to signify which sprint they were completed in. The sprints started at Sprint 0 and ran till Sprint 4. Each user story was broken down in to tasks and assigned to an epic, and these epics were also written as user stories. Each user story was designated a number of 'story points' using GitHub's labels (for example, a label of 'SP:1' would signify the user story was estimated to take 1 story point to complete). The epic user stories were not given story points as they were composed of the generic user stories.
User stories were also assigned labels of 'Must Have', 'Should Have', 'Could Have' and 'Won't Have'. These were assigned when a user story was placed in the 'In Progress' section of the Kanban board. These labels could change between sprints. For example, if a user story had a 'Should Have' in Sprint 1 it would likely have a 'Must Have' in Sprint 2. The 'Won't Have' label was only applied to a single user story. This story was making email signup mandatory and this was because I decided that it was outside the scope of this project.
The SyntheStory project was planned in a series of epics which were broken down into user stories. Here are links to see the user stories of each epic.
Visual/ Introductory User Stories
Here are the wireframes created before the SyntheStory project was developed. The homepage screen is the only one that shows a non-logged in navigation bar due to all others only being accessible when logged in and the navigation bar after being logged in staying the same.
Used the HTML validator at (https://validator.w3.org/). Had to copy and paste from 'View Page Source' in browser in live project because of Django's templating laguage messing up the code otherwise. All HTML was valid.
Used the CSS validator at (https://jigsaw.w3.org/css-validator/#validate_by_input). There were errors raised regarding some colors and background colors not being valid however these are not valid errors because they are to do with the validator not recognising gradient coloring correctly. Code was created at (https://cssgradient.io/) and this code works and removing it removes the intended effect. The validator also found an error with the imported fonts from Google Fonts however this is not an error but is due to the validator not checking the imported files.
JS Hint was used to check the validity of the scripts running in the templates. No errors were found.
PEP8 was the style guide used for the Python code of this project and pylint was used in the Gitpod environment to check against it. Unfortunately whilst most the of the PEP8 errors were valid and easily fixable, there are numerous 'errors' left in that either cannot be fixed properly or are not actually errors. I will explain each individually:
'env' imported but unused
. This is untrue and in the development environment this was used and removing it breaks SyntheStory's functionality.line too long
. This is due to the length of some password strings and cannot be adequately fixed as it require breaking the string on a new line.Class 'x' has not 'objects' member
. This is untrue and without the code it references SyntheStory does not work.local variable 'x' is assigned but never used
. This is due to it being used in a TestCase setUp function and pylint not recognised it is used in other functions of the test suite after this.Unnecessarily calls dunder method __str__. Use str built in function.
This is due to str built in function being used in str functions of the models to remove another error saying the str method did not return a string. Either way a PEP8 error is thrown so it has been left as is.
SyntheStory was tested in Brave's Lightouse feature and was found to be fast-loading and accessible for the visually impaired.
Lighthouse check on desktop:
Lighthouse check on mobile:
SyntheStory was tested in both Brave and Firefox browsers. There is a small issue of messages being unaligned with their cross in Firefox but this does not affect functionality and works in Brave.
Manual testing was carried out to ensure that SyntheStory worked correctly from a user's point of view. Details of this can be found here
Automated testing was carried out using TestCase. This was used to ensure there were no 'behind the scenes' problems occurring. One problem that was highlighted was that the 403 error page was being given as a 200 response so the HttpForbidden method was used to make sure a 403 response was given when this appeared.
Here is an image of the tests being carried out:
A coverage report of automated testing was carried out. This shows the amount of coverage the automated testing dealt with. The automated tests were carried out to 93% coverage. The only part of the application that didn't get complete automated coverage was the views and was to do with post requests and deletion of story ideas which are more easily handled and verified through manually checking that they work.
I tried to use an internal script in the HTML to pre-populate a form by changing it's 'value' attribute in the HTML with data passed in from the view. This caused Django to represent any unusual characters (such as apostrophes) with strange characters as a safety precaution. I then tried to use an external JavaScript file to do the same but this resulted in it not reading the Django template properly and showing no data. To rectify the problem I passed in an a dictionary of values to the form in the view as an initial value which populated the fields without bugs.
ACCOUNT_EMAIL_VERIFICATION was set to 'optional' in settings. When making fake accounts to test the signup feature using fake email addresses would cause a 500 internal server error due to the email not being sent to a valid email address but the account would still be created. As SyntheStory does not require an email address to verify account I decided to change ACCOUNT_EMAIL_VERIFICATION to 'none' to prevent internal server errors.
In automated testing, a test to return a 403 response was triggering a 200 instead. After looking into it, it appeared I was using a 200 response in my views but redirecting to a 403 template. Used the HttpResponseForbidden class from Django to get around this.
Firefox messages: The messages that display on firefox browser do not have the text and cross line up correctly. As they work on brave I have left this as it may just be a discrepancy between how the browsers display the messages and it is still prefectly readable and understandable on Firefox.
SyntheStory was deployed on Heroku. Here are the steps to achieve this: