GSOC 2022: Add Timezone support to ListenBrainz

Hello, I am Yichen. Here is my proposal for GSOC 2022: Add Timezone support to ListenBrainz. I will be very grateful if someone gives me a comment or a suggestion!

Project Name:

Add Timezone support to ListenBrainz

Project description:

This project aims to add Time zones of users to ListenBrainz. All listen of users are currently recorded in UTC. This project consists of three parts of work: creating a table to store timezones for users, creating React UI pages that allow the user to set/edit their timezone, and adding API endpoints to fetch/set the user timezone. Adding timezone support for users can help make more customized recommendations.

Technology stack:

Python, PostgreSQL, React

Project implementation:

The graph below shows the structure of the project. There are four major parts: React UI pages to present and set/edit time zones; views to achieve set/get time zone functions; the functions to operate data; the new table in PostgreSQL.


Step 1: making an appropriate table in Postgres to store timezones for users

Create a table in create_tables.sql:

In the file create_tables.sql of the ListenBrainz project, there is a table named “user” that has fields of basic user information. To record and use the user’s timezone, I will create a new table user_timezone.

CREATE TABLE user_timezone (
    id              SERIAL, -- PK
    user_id         INTEGER NOT NULL, --FK to "user".id
    timezone_name   text NOT NULL DEFAULT current_setting('TIMEZONE')
);

The id is serial and the primary key for the table. The user_id is a foreign key references user (id). The field timezone_name will store the name of the user’s timezone using datatype text. The default value of timezone_name is the time zone name of current user’s current setting.
There is a view in PostgreSQL that provides a list of timezones: pg_timezone_names. I will store time zone names from this view as timezone_name in table user_timezone.
image

Since the view also provides associated abbreviations, UTC offsets, and daylight-savings status for each time zone, we can get this information from time zone name for future use.
Add primary key in create_primary_keys.sql:

ALTER TABLE user_timezone ADD CONSTRAINT user_timezone_pkey PRIMARY KEY (id);

Add foreign key in create_foreign_keys.sql:

ALTER TABLE user_timezone
    ADD CONSTRAINT user_timezone_user_id_foreign_key
    FOREIGN KEY (user_id)
    REFERENCES "user" (id)
    ON DELETE CASCADE;

By using delete cascade, when a user is deleted, then the referencing row (time zone for the user) is deleted too.
Step 2:

Complete React UI pages that allow the user to set/edit their timezone

First, I decide to use a React component to let the user to choose her/his timezone. The user can search her/his city. After the user click the search button, it will recommend relative time zone names for the user to choose. This component can be used both for setting and editing time zones.

The first image shows the component before the user input. The second image shows the component after the user input the city name and click the search button.
image

image

Then I will finish UI pages for setting and editing time zones. I will write POST/GET requests to set/update/get the user’s time zone.

Step 3:
Add the API endpoints to allow the HTML pages to fetch/set the user timezone

  1. Add two functions set_user_timezone and fetch_time_zone in listenbrainz/db/user.py to operate the database. The function set_user_timezone(user_id, timezone_name) will insert a new row in the table user_timezone if the user doesn’t have a timezone; it will update the user’s timezone if the user has a timezone.
    The function fetch_time_zone(user_id) will select a row from table user_timezone where the user_id matches the id of current user.

  2. Develop two views: get_timezone and set_timezone. Decorate them with two routes @user_bp.route(“/<user_name>/get_timezone/”), @user_bp.route(“/<user_name>/set_timezone/”) respectively. In these two functions, call functions in step 1.

Development Process:

Community Bonding Period: May 20 - June 12

Bonding with the community; discussing project details with mentors; communicating with other developers in IRC; read codes and documentation; maybe fix some issues related to this project.

Phase 1: June 13- July 25

Goals in phase 1:

Create a table for timezones, add constraints for the table, write functions to set/fetch timezones information from database, generate fake data to test functions

June 13 - June 19

Create a table to store timezones for users; discuss with mentors about table details (for example, the column datatype); add constraints for the table; design UI

June 20 - June 26

Dive into format conversion of timezones(for example, the conversion of timezone name and utc_offset)

June 27 - July 3

Write functions to set and fetch timezones information from database

July 4 – July 10

Write functions to set and fetch timezones information from database

July 11 - July 17

Generate fake data to test finished functions

Milestone: finish functions related to database operations

July 18 – July 24

Design UI pages for set/edit timezones; design React components

Phase 2: July 25 - September 4

Goals in phase 2:

Realize React UI pages; write API endpoints to set/fetch timezone information; write unit tests to test functions; test the whole feature; finish the project and write a documentation

July 25 – July 31

Realize webpages using React

Milestone: finish frontend pages

August 1 – August 7

write API endpoints to set and fetch timezone information

August 8 – August 14

write API endpoints to set and fetch timezone information; write unit tests to test functions.

August 15 – August 21

test the whole feature (from the frontend pages to the database); fix bugs.

Milestone: finish the whole feature

August 22 – August 28

Fix bugs; write documentation for the project; discuss with mentors about merging features into the production code

August 29 – September 4

Buffer for unexpected delay; try to implement other features if I have extra time

September 5 - September 12

Submit results(code and documentation)

About me:

Basic Information

Name: Yichen Qian

Email: yq82@duke.edu

Github: https://github.com/halfmoontonight

Time Zone: UTC-04:00 (United States Eastern time)

Location: North Carolina, the United States

Education Information:

I am a first-year master student in computer science at Duke University (expected graduation May 2023).

Experiences:

The project is a researcher club application based on databases containing published scholarly papers (paper title, author, abstract, year, etc). On our application, users can “shop” papers they are interested in. The goal of our application is to help researchers efficiently access useful papers. The project uses Python, Flask framework, PostgreSQL.

Functions I completed: user’s login and registration, user’s profile and information update, user’s collections, browse history, etc. I also participated in designing and creating tables in Postgres.

The project is a mobile application that helps students to better manage their time. Users can schedule and record their daily tasks. The application also provides plan recommendation and user behavior analysis to help them improve their time management skills.

Functions I completed: built modules such as task timing, scheduling, excellent allocation plan recommendation, user behavior pattern analysis using Java; designed Client-Server interfaces; completed network requests of the APP based on OkHttp library; drew dynamic charts to help users obtain intuitive and clear reports and analysis.

The project is a club website. Users can see the introduction and development of our club, they can also apply for our club online and communicate with club members online.

Functions I completed: developed modules including club introduction, members display, message board using HTML, CSS, JavaScript, and jQuery library; completed the mobile terminal adaptation of the corresponding modules; dynamically displayed the information of club members by years; implemented the waterfall flow layout using AJAX.

Working time:

The estimated project length is 175 hours. I can spend more than 15 hours every week during all the coding phases for the project. I can spend extra time discussing with mentors and contribute more to the community if needed.

Before the student projects are announced, I am willing to start contributing to the community and make some early preparation for the project.

Hi! Thanks for the proposal.

Suggestions:

  1. We want to store other types of user preferences in future so it would be better to rename the user_timezones table to something generic so that we can just add columns as necessary when needed instead of creating a new table for each preference.

  2. Also, I suggest you to setup the ListenBrainz webserver locally and try to work a good-first-issue to become familiar with the development process.

Thanks for your suggestions! Your suggestions are very helpful. Could I ask about the details?

  1. May I just rename the user_timezones table to user_info without changing the table structure?
  2. I have set up the ListenBrainz webserver locally. Now I am looking at a good-first-bug ticket. When I am trying to work on an issue, do I need to say it in IRC, or do I just need to create a pull request when I finish?

Thank you very much!

  1. I was thinking something on the lines of user_preferences or user_settings. The exact name can be finalized later anyway though. Yes, the table structure looks fine.

  2. Assigning the ticket in JIRA to yourself is enough. Its not necessary to mention in IRC but feel free to ask there if you are in doubt or need some clarification about the ticket or approach to fix the bug/add a feature etc.

Thanks very much for your patient help!