Andrew Hwang & Kari Nasu
INFO 441 - WI19
To make the process of sharing and organizing photos more robust, our application will provide users with a platform to classify and share photos by tags. Our application could be used by various audiences (e.g. professional photographers, companies for social media purposes, etc.). However, we will focus on the general individual who prefers a flexible method of storing and sharing photos which surpasses the capabilities and use cases of typical, statically-structured file systems. Such a user would be able to better personalize their photo-viewing and photo-sharing experience by using our application.
This audience would want to use our application for a number of reasons, the initial one likely being the want or need to organize photos based on multiple factors. For example, a student may want to view groups of photos based on their year in college (i.e. freshman, sophomore, etc.), calendar year, and their birthday. By tagging photos appropriately, the user can accomplish multiple photo-viewing and photo-sharing experiences. In this case, he/she could recapitulate their senior year as they near graduation, the calendar year as New Year's Day approaches, and how they have spent their past birthdays.
As a developer, we can now take a direct approach to responding to ideas and people's needs. I have personally dealt with the limitations of current photo-viewing and sharing platforms, and have seen people around us experience the same issue. From forgetting which classification a certain photo is under in a file system to tediously and manually sharing select photos with various people, users have different pain points that can be addressed in this application. Overall, we see this application being able to address various pain points in diverse scenarios.
An intial challenge was deciding on the system architecture. This challenge dissipated as discussion progressed and as we gained a better grasp on the problem we hoped to solve. Other notable challenges include deciding on the technologies to accomplish the goals of our endpoints and troubleshooting communicating to the client. One thing we would do differently in the future while developing, would be to develop the server and client concurrently. This would allow us to thoroughly test and catch problems that may need to be addressed via change in the architecture.
Below are ideas to implement moving forward in the project:
- Adding websockets and message queues to notify users (e.g. Use cases: When a tag has been shared with them, when one of their photos have been liked, implementing other media type, implement photo download (small, med, large, original size)
- Filtering on multiple tags
- Save search queries for quick access
API: tag.karinasu.me Client: https://andrewhwang10.github.io/final-project
- API: tag.karinasu.me
- gatewaycontainer
- userscontainer
- sessionscontainer
- phototaggingcontainer
- mongocontainer
| Priority | User | Description |
| P0 | As a photo owner, I want to | Upload photos in various quantities |
| P0 | As a photo owner, I want to | Create tags |
| P0 | As a photo owner, I want to | Tag photos with numerous tags |
| P0 | As a user, I want to | View photos by tag |
| P1 | As a user, I want to | Create an account |
| P1 | As a user, I want to | View all photos at once that I am allowed to see |
| P1 | As a photo owner, I want to | Share photos to friends based on tags |
| P1 | As a photo owner, I want to | Remove friends from viewing tags |
| P2 | As a user, I want to | See all tags that I am able to view |
User has to be authenticated to reach all endpoints. Otherwise, will respond with 401: Status Unauthorized.
| Endpoint | Description | Implementation | Response Codes | ||
| Gets photos all photos the user is able to view | The user can view all the photos they are authorized to see. To do this, the browser would send a GET request to /photos. | 200: Successfully retrieved photos
400: Bad request 500: Internal server error |
|||
| Uploads at least one new photo to the database and user account | The Photos microservice will handle when a user uploads an image by saving the image in the graph database associated with the UserID and datetime . | 201: Created
415: Unsupported media type 500: Internal server error |
|||
| Gets photos that are tagged with the specified tag | The user can click a certain tag and see the photos it is used on. This will send a GET request to the Photos microservice, which will then return all photos with the specified tag that the client is allowed to see. | 200: Successfully retrieved photos
400: Bad request 500: Internal server error |
|||
| Likes OR unlikes a specific photo | If the user is not already a liker, a like will be added. If the user is a liker, the like will be removed. | 200: Successfully liked or unliked
403: The request user is not the photo owner or the user is not a permitted viewer 404: PhotoID does not exist 500: Internal server error |
|||
| Deletes a photo from the database and user account | Deletes an image from the database. Returns a plain text message that the delete was successful and returns the images the client is able to see based on the previous search queries. If client was not in the middle of a search, it will return all images the user is allowed to see. | 200: Successfully deleted photo
403: The request user is not the photo owner 404: PhotoID does not exist 500: Internal server error |
|||
| Adds one tag for a photo | A user can tag a photo with an existing tag or a new one. When a user tags a photo, the Photos microservice will handle the event and update the database. |
201: Created 403: The user is not the photo or tag owner 500: Internal server error |
|||
| Deletes one tag from a photo | A user can remove a tag from a photo. The Photos microservice will handle this event and update the database. |
200: Successfully removed tag 403: The user is not the photo or tag owner 404: PhotoID does not exist or TagID does not exist 500: Internal server error |
|||
| Creates a new user account | One can create a new account via a POST request to /user. User is saved in a MySQL database. | 201: Created
415: Unsupported media type 500: Internal server error |
|||
| Returns all tags the user is able to see | One can see all the tags they have created or shared to via a GET request to /tags. | 200: Successfully retrieved tags
400: Bad request 500: Internal server error |
|||
| Creates a new tag | A user can create a new tag. | 201: Successfully created tag
400: Bad request 500: Internal server error |
|||
| Gets metadata about specific tag | A user can request information about a specific tag, such as number of photos, friends shared with, etc. | 200: Successfully retrieved tag information
400: Bad request 404: TagID does not exist 500: Internal server error |
|||
| Deletes specific tag from all photos it is posted on | A user can delete a tag, resulting in the removal of that tag from all the photos it's attached to and removal of permissions for friends to see photos with this tag. | 200: Successfully deleted tag
403: The request user is not the tag creator 404: TagID does not exist 500: Internal server error |
|||
| Add a user to a tag | An owner of photos can add friends to a tag so they can view photos with the tag. | 200: Successfully added member to tag
404: UserID does not exist or TagID doesn't exist 500: Internal server error |
|||
| Delete a user from a tag | An owner of photos can remove friends from a tag, thus revoking their permission to view photos with the tag. | 200: Successfully deleted tag
403: The request user is not the tag creator 404: UserID or TagID does not exist 500: Internal server error |
|||
Users
create table if not exists users (
id int not null auto_increment primary key,
email varchar(320) not null,
firstname varchar(128) not null,
lastname varchar(128) not null,
username varchar(255) not null UNIQUE,
passhash binary(60) not null,
photourl varchar(2083) default null
);
create table if not exists tags (
id int not null auto_increment primary key,
name varchar(128) not null,
description varchar(320) not null
);
create table if not exists users_tags (
user_id int not null foreign key,
tag_id int not null foreign key
);
Photos
Sessions
Redis key-value store that associates sessionIDs with RedisStore objects, seen below:
type RedisStore struct{
Client *redis.Client \
SessionDuration time.Duration
}
