niittymaa

LyricGenius Script - Download and Convert to Text Files (With Language Detection)

Feb 18th, 2023 (edited)
49
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.67 KB | Music | 0 0
  1. '''
  2. LyricGenius Script: Download and Convert to Text Files
  3. -------------------------------------------------------
  4. This script downloads song lyrics using the 'LyricsGenius' python library and converts them into text files
  5. by removing unnecessary special characters. The purpose of the script is to prepare the lyrics as better data
  6. to be used for AI training.
  7.  
  8. https://lyricsgenius.readthedocs.io/en/master/usage.html
  9.  
  10. INSTALL LIBRARIES:
  11. ------------------
  12. LyricGenius:
  13. pip install lyricsgenius
  14.  
  15. Language detection tool:
  16. pip install langdetect
  17. '''
  18.  
  19. import os
  20. import json
  21. from lyricsgenius import Genius
  22. from langdetect import detect
  23. from langdetect import DetectorFactory
  24. from difflib import SequenceMatcher
  25. DetectorFactory.seed = 0
  26.  
  27. class Lyrics():
  28.     def __init__(self):
  29.        
  30.         # Artist Name And ID --------------------------------------------------------------------- #
  31.         self.artist_name = 'Nirvana'
  32.         # Use also artist ID if result is wrong artist
  33.         # Get artist ID from genius artist page source
  34.         # Use None by default
  35.         self.artist_id = None
  36.        
  37.         # Settings ------------------------------------------------------------------------------- #
  38.         self.save_only_language = 'en'
  39.         # Prevent shortest lyrics to be saved
  40.         self.min_lyric_length = 200
  41.         # Prevent duplicates with similarity check
  42.         # If name is more than 0.3 (30%) similar, skip
  43.         self.similarity_ratio = 0.7
  44.        
  45.         # Initialize Filename For JSON ----------------------------------------------------------- #
  46.         self.json_filename = self.clean_name('Lyrics_' + self.clean_artist_name(self.artist_name) + '.json')
  47.         self.json_filename = self.json_filename.replace(' ', '')
  48.        
  49.         # DISABLE DOWNLOADING AND ONLY CLEAN TEXT FILES ------------------------------------------ #
  50.         self.download_lyrics()
  51.        
  52.         # Remove These Characters From Lyrics ---------------------------------------------------- #
  53.         self.remove_symbols = {
  54.             'д': 'ä', 'Д': 'Ä',
  55.             'ц': 'ö', 'Ц': 'Ö',
  56.             '/': '', '_': '', '--': '', '?': '',
  57.             'I:': '', 'II:': '', 'III:': '',
  58.             'San.': '', 'san.': '', 'Säv.': '', 'säv.': '',
  59.             'Kertosäe2:': '', 'Kertosäe:': '' ,
  60.             'Embed': '', 'You might also like': '',
  61.             'CHORUS': '', 'Chorus': '', '(chorus:)': '',
  62.             'VERSE': '', 'Verse': '',
  63.             'Intro': '', 'INTRO': '',
  64.             'SOLOS:': '', 'SOLO:': '', '(solo)': '', '(Guitar solo)': '',
  65.             '(Missing Stanzas)': '',
  66.             'PRE-:': '', 'PRE-': '',
  67.             'C-PART': '', 'Spoken:': '',              
  68.             '(x2)': '', '( x2)': '', '(2x)': '', '(x3)': '', '(3x)': '', '( x3)': '',
  69.             '()': '', '(?)': '', '(???)': '',
  70.             '(original)': '',
  71.             "Refren':": '', "Refrain:": '', "Refren'": '',
  72.             '(NARRATION:)': '',
  73.             'These lyrics have yet to be transcribed': '',
  74.         }
  75.        
  76.         # Conver downloaded data to text files        
  77.         self.convert_to_txt()
  78.    
  79.     # Download Lyrics ---------------------------------------------------------------------------- #    
  80.     def download_lyrics(self, artist_id = None):
  81.         if not os.path.exists(self.json_filename):
  82.             genius = Genius('M5SQpNcF83ussWh7u18fBzGQOHuN8IzoTw2GZEGNbsy77FWCmKTU2m0d2E3iF5Ll')
  83.             genius.remove_section_headers = True
  84.             genius.response_format = 'plain'
  85.             artist = genius.search_artist(artist_name=self.artist_name ,artist_id=self.artist_id, sort="title")
  86.             if artist:
  87.                 artist.save_lyrics()
  88.  
  89.     # Extract Lyrics From JSON And Save To Separated Files --------------------------------------- #
  90.     def convert_to_txt(self):
  91.  
  92.         # Check if json file exist
  93.         if os.path.exists(self.json_filename):
  94.  
  95.             json_data = {}
  96.             artist_data = []
  97.  
  98.             with open(self.json_filename) as json_file:
  99.                 json_data = json.load(json_file)
  100.                 print('### File Found:', self.json_filename)                
  101.            
  102.             # Get data from json for organizing
  103.             for song in json_data['songs']:
  104.                 data = {
  105.                     'artist': song['artist'],
  106.                     'song': song['title'],
  107.                     'lyrics': song['lyrics'],
  108.                 }
  109.                 artist_data.append(data)
  110.                
  111.             # Sort data list by song title
  112.             artist_data = sorted(artist_data, key=lambda d: d['song'])
  113.            
  114.             # Remove similar/duplicate files from list
  115.             artist_data_cleaned = []
  116.             for artist in artist_data:
  117.                 duplicate_found = False                
  118.                 for item in artist_data_cleaned:
  119.                     name_1 = self.remove_words_within_brackets(item['song'].lower())
  120.                     name_2 = self.remove_words_within_brackets(artist['song'].lower())
  121.                     if self.similar(name_1, name_2) > self.similarity_ratio:
  122.                         print('### Duplicate song found:', name_1, 'is almost same as', name_2)
  123.                         duplicate_found = True
  124.                 if duplicate_found == False:
  125.                     artist_data_cleaned.append(artist)
  126.            
  127.             for song in artist_data_cleaned:
  128.                 self.save_text_file(song)
  129.  
  130.  
  131.     # Save Text Files ---------------------------------------------------------------------------- #
  132.     def save_text_file(self, data):
  133.                                        
  134.         filename = self.clean_name(data['song']) + ' - ' + self.clean_name(data['artist']) + '.txt'
  135.         file_path = os.path.join(os.getcwd(), 'Lyrics', data['artist'])
  136.        
  137.         if not os.path.exists(file_path):
  138.             os.makedirs(file_path)                
  139.         file_path = os.path.join(file_path, filename)
  140.        
  141.         # Check if there is enough long lyrics and correct language
  142.         if len(data['lyrics']) > self.min_lyric_length and detect(data['lyrics']) == self.save_only_language:
  143.             with open(file_path, 'w', encoding='utf-8') as f:
  144.                 reformatted_data = ''
  145.                 for lyric in data['lyrics']:
  146.                     reformatted_data += lyric
  147.                 # Try to split string from target word like "Lyrics"
  148.                 if len(reformatted_data.split('Lyrics', 1)) > 1:
  149.                     reformatted_data = reformatted_data.split('Lyrics', 1)[1]
  150.                 # If needed replace character with another
  151.                 for k, v in self.remove_symbols.items():
  152.                     reformatted_data = reformatted_data.replace(k, v)
  153.                 # Save file
  154.                 f.write(str(reformatted_data))
  155.         else:
  156.             print('### No proper lyrics for song:', data['song'])
  157.        
  158.     # Clean Names To Avoid Path Errors ----------------------------------------------------------- #
  159.     def clean_name(self, name):        
  160.         return_name = name
  161.         remove_symbols = [*'<>:"/\|?*']
  162.         for i in remove_symbols:
  163.             return_name = return_name.replace(i, '')
  164.         return return_name
  165.    
  166.     # Clean Artist Names To Make Path Work ------------------------------------------------------- #
  167.     def clean_artist_name(self, name):        
  168.         return_name = name
  169.         remove_symbols = [*'<>:"/\|?*() ']
  170.         for i in remove_symbols:
  171.             return_name = return_name.replace(i, '')
  172.         return return_name
  173.    
  174.     # Remove Words Within Brackets --------------------------------------------------------------- #
  175.     def remove_words_within_brackets(self, text):
  176.         words = text.split()
  177.         result = ''
  178.         in_brackets = False
  179.         for word in words:
  180.             if '(' in word:
  181.                 in_brackets = True
  182.                 word = ''
  183.             if ')' in word:
  184.                 in_brackets = False
  185.                 word = ''
  186.             if not in_brackets:
  187.                 result += word + ' '        
  188.         return result.strip()
  189.    
  190.     # Compare Two Filenames And Return Similarity Value ------------------------------------------ #
  191.     def similar(self, a, b):
  192.         return SequenceMatcher(None, a, b).ratio()
  193.    
  194.    
  195. # ================================================================================================ #
  196. # MAIN                                                                                             #
  197. # ================================================================================================ #
  198.    
  199. def main():
  200.     Lyrics()
  201.    
  202. if __name__ == '__main__':
  203.     main()
Advertisement
Add Comment
Please, Sign In to add comment