A web service designed to help language learners expand their Mandarin vocabulary through Taiwanese songs. LyricLab's goal is to make learning more convenient and enjoyable.
LyricLab involves the design and implementation of a database for managing songs, lyrics, vocabulary, and recommendations with related attributes. The database is created and managed using Sequel, a Ruby toolkit for interacting with SQL databases. LyricLab pulls song information (title, artist, popularity, etc.) as well as lyrics from the Spotify and LrcLib APIs. Users can select one of the language levels and search for a song, generating a vocabulary list based on the selected level and the lyrics of the specified song. Users can then select specific words to see more learning information such as translations, pinyin, and example sentences.
The primary domain entities for this project are:
- Lyrics: Represents individual song lyrics with associated metadata such as language and type (e.g., instrumental or not).
- Songs: Represents songs with attributes including title, popularity, and artist information. Each song links to
lyrics
andvocabulary
entries. - Vocabularies: Represents sets of language-level vocabulary associated with words.
- Words: Represents individual words with their characters, pinyin, translation, and additional metadata.
- Recommendations: Represents song recommendations with associated metadata like artist and Spotify ID.
- VocabulariesFilteredWords: A join table that associates
vocabularies
andwords
entities.
- id (Primary Key)
- text: The actual lyrics text.
- is_mandarin: Boolean indicating if the lyrics are in Mandarin.
- is_instrumental: Boolean indicating if the lyrics are instrumental.
- created_at: Timestamp of creation.
- updated_at: Timestamp of last update.
- id (Primary Key)
- lyrics_id (Foreign Key): References
id
in thelyrics
table. - vocabulary_id (Foreign Key): References
id
in thevocabularies
table. - title: Title of the song (required).
- origin_id: Unique Spotify identifier (required).
- popularity: Popularity score (required).
- album_name: Album name (required).
- artist_name_string: Name of the artist(s) (required).
- cover_image_url_big, cover_image_url_medium, cover_image_url_small: URLs for cover images.
- search_counter: Number of times searched (default 0).
- explicit: Boolean for explicit content (default
false
). - created_at, updated_at: Timestamps.
- id (Primary Key)
- language_level: Describes the proficiency level of the vocabulary set.
- created_at, updated_at: Timestamps.
- id (Primary Key)
- characters: The word characters (required).
- translation: Translation of the word (required).
- pinyin: Pronunciation guide (required).
- difficulty, definition, word_type, example_sentence: Additional attributes.
- created_at, updated_at: Timestamps.
- id (Primary Key)
- title: Title of the recommendation (required).
- artist_name_string: Name of the artist(s) (required).
- search_cnt: Number of times searched (required).
- origin_id: Unique Spotify identifier (required).
- created_at, updated_at: Timestamps.
- vocabulary_id: Foreign Key referencing
vocabularies
. - filtered_word_id: Foreign Key referencing
words
.
Below is a conceptual representation of the database structure:
+-------------+ +---------------+ +---------------+
| lyrics | | songs | | vocabularies |
+-------------+ +---------------+ +---------------+
| id |------>| lyrics_id |<----| id |
| text | | vocabulary_id | | |
| is_mandarin | | title |+--->| language_level|
| is_instr. | | origin_id || | created_at |
| created_at | | ... || | updated_at |
| updated_at | +---------------+| +---------------+
+-------------+ | ^
| |
+-------------+ +----------------------------+ |
| words |<------| vocabularies_filtered_words| |
+-------------+ +----------------------------+ |
| id | | vocabulary_id |-+
| characters | | filtered_word_id |
| translation | +----------------------------+
| pinyin |
| ... |
| created_at |
| updated_at |
+-------------+
+--------------------+
| recommendations |
+--------------------+
| id |
| title |
| artist_name_string |
| search_cnt |
| origin_id |
| created_at |
| updated_at |
+--------------------+
- lyrics table: Stores lyrics data and links to
songs
. - songs table: References
lyrics
andvocabularies
. - vocabularies table: Represents sets of words and is linked to
songs
andwords
. - words table: Contains individual word information.
- vocabularies_filtered_words: A join table for many-to-many relationships between
vocabularies
andwords
. - recommendations table: Contains song recommendation data.
- Create a personal Spotify API CLIENT_ID and CLIENT_SECRET.
- Copy
config/secrets_example.yml
toconfig/secrets.yml
and update the information. - Ensure the correct version of Ruby is installed (see
.ruby-version
for rbenv). - Run
bundle install
to install the required gems.
- Check API alive (API)
GET /
- List recommendations (recommendations)
GET /api/v1/recommendations
- Add song into recommendations
PUT /api/v1/songs/{origin_id}
- Show search results (songs)
POST /api/v1/search_results?search_query={search_query}
- Display vocabulary for selected song (song object with vocabularies)
GET/api/v1/vocabularies/{origin_id}
- Return song object (basic metadata)
GET /api/v1/songs/{origin_id}
# install curl
sudo apt install curl
# test API alive
curl localhost:9090
# get search results based on search query (5 max)
curl -X GET -d search_query='IuWRiuS6lOS6uiI=' http://localhost:9090/api/v1/search_results
# update recommendations db
curl localhost:9090/api/v1/songs/27FOde2nUw0pFuj7hlPbaS -X POST
# get song basic metadata
curl localhost:9090/api/v1/songs/27FOde2nUw0pFuj7hlPbaS -X GET
# get to searched songs (5 max)
curl localhost:9090/api/v1/recommendations
# get vocabulary for song
curl localhost:9090/api/v1/vocabularies/4KjPt8HrShkDOASRyMkTJ4
Base64.urlsafe_encode64(<your query>.to_json)