mirror of
https://github.com/cooperhammond/irs.git
synced 2024-12-22 17:35:28 +00:00
need to add 'next' feature for spotify searches
This commit is contained in:
parent
8cfb59a368
commit
f849e61045
25
src/glue/album.cr
Normal file
25
src/glue/album.cr
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
require "./song"
|
||||||
|
require "./list"
|
||||||
|
|
||||||
|
|
||||||
|
class Album < SpotifyList
|
||||||
|
|
||||||
|
def find_it
|
||||||
|
album = @spotify_searcher.find_item("album", {
|
||||||
|
"name" => @list_name.as(String),
|
||||||
|
"artist" => @list_author.as(String)
|
||||||
|
})
|
||||||
|
if album
|
||||||
|
return album.as(JSON::Any)
|
||||||
|
else
|
||||||
|
puts "No album was found by that name and artist."
|
||||||
|
exit 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private def set_organization(index : Int32, song : Song)
|
||||||
|
# pass
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
puts Album.new("A Night At The Opera", "Queen").find_it()
|
45
src/glue/list.cr
Normal file
45
src/glue/list.cr
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
require "../search/spotify"
|
||||||
|
require "../search/youtube"
|
||||||
|
|
||||||
|
require "../interact/ripper"
|
||||||
|
require "../interact/tagger"
|
||||||
|
|
||||||
|
require "./song"
|
||||||
|
|
||||||
|
|
||||||
|
# A parent class for downloading albums and playlists from spotify
|
||||||
|
abstract class SpotifyList
|
||||||
|
@spotify_searcher = SpotifySearcher.new()
|
||||||
|
@file_names = [] of String
|
||||||
|
|
||||||
|
def initialize(@list_name : String, @list_author : String?)
|
||||||
|
@spotify_searcher.authorize(
|
||||||
|
"e4198f6a3f7b48029366f22528b5dc66",
|
||||||
|
"ba057d0621a5496bbb64edccf758bde5")
|
||||||
|
end
|
||||||
|
|
||||||
|
# Finds the list, and downloads all of the songs using the `Song` class
|
||||||
|
def grab_it
|
||||||
|
list = find_it()
|
||||||
|
contents = list["tracks"][0]["items"]
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
contents.each do |data|
|
||||||
|
if song["track"]?
|
||||||
|
data = data["track"]
|
||||||
|
end
|
||||||
|
|
||||||
|
song = Song.new(data["name"].to_s, data["artists"][0]["name"].to_s)
|
||||||
|
song.provide_spotify(@spotify_searcher)
|
||||||
|
set_organization(i , song)
|
||||||
|
song.grab_it()
|
||||||
|
|
||||||
|
i += 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
abstract def find_it : JSON::Any
|
||||||
|
|
||||||
|
private abstract def set_organization(song_index : Int32, song : Song)
|
||||||
|
|
||||||
|
end
|
|
@ -4,6 +4,10 @@ class Logger
|
||||||
|
|
||||||
@command : String
|
@command : String
|
||||||
|
|
||||||
|
# *command* is the bash command that you want to run and capture the output
|
||||||
|
# of. *@log_name* is the name of the log file you want to temporarily create.
|
||||||
|
# *@sleept* is the time you want to wait before rechecking if the command has
|
||||||
|
# started yet, probably something you don't want to worry about
|
||||||
def initialize(command : String, @log_name : String, @sleept = 0.01)
|
def initialize(command : String, @log_name : String, @sleept = 0.01)
|
||||||
# Have the command output its information to a log and after the command is
|
# Have the command output its information to a log and after the command is
|
||||||
# finished, append an end signal to the document
|
# finished, append an end signal to the document
|
||||||
|
|
|
@ -19,8 +19,6 @@ module Ripper
|
||||||
# remove the extension that will be added on by ydl
|
# remove the extension that will be added on by ydl
|
||||||
output_filename = output_filename.split(".")[..-2].join(".")
|
output_filename = output_filename.split(".")[..-2].join(".")
|
||||||
|
|
||||||
# TODO: update the logger for this. Explore overwriting stdout and
|
|
||||||
# injecting/removing text
|
|
||||||
options = {
|
options = {
|
||||||
"--output" => %("#{output_filename}.%(ext)s"), # auto-add correct ext
|
"--output" => %("#{output_filename}.%(ext)s"), # auto-add correct ext
|
||||||
# "--quiet" => "",
|
# "--quiet" => "",
|
||||||
|
|
|
@ -1,11 +1,17 @@
|
||||||
# TODO: write comments/documentation
|
# Uses FFMPEG binary to add metadata to mp3 files
|
||||||
|
# ```
|
||||||
|
# t = Tags.new("bohem rap.mp3")
|
||||||
|
# t.add_album_art("a night at the opera album cover.jpg")
|
||||||
|
# t.add_text_tag("title", "Bohemian Rhapsody")
|
||||||
|
# t.save()
|
||||||
|
# ```
|
||||||
class Tags
|
class Tags
|
||||||
|
|
||||||
|
# TODO: export this path to a config file
|
||||||
@BIN_LOC = Path["~/.irs/bin".sub("~", Path.home)]
|
@BIN_LOC = Path["~/.irs/bin".sub("~", Path.home)]
|
||||||
@query_args = [] of String
|
@query_args = [] of String
|
||||||
|
|
||||||
|
# initialize the class with an already created MP3
|
||||||
def initialize(@filename : String)
|
def initialize(@filename : String)
|
||||||
if !File.exists?(@filename)
|
if !File.exists?(@filename)
|
||||||
raise "MP3 not found at location: #{@filename}"
|
raise "MP3 not found at location: #{@filename}"
|
||||||
|
@ -15,10 +21,8 @@ class Tags
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_text_tag(key : String, value : String) : Nil
|
# Add album art to the mp3. Album art must be added BEFORE text tags are.
|
||||||
@query_args.push(%(-metadata #{key}="#{value}"))
|
# Check the usage above to see a working example.
|
||||||
end
|
|
||||||
|
|
||||||
def add_album_art(image_location : String) : Nil
|
def add_album_art(image_location : String) : Nil
|
||||||
if !File.exists?(image_location)
|
if !File.exists?(image_location)
|
||||||
raise "Image file not found at location: #{image_location}"
|
raise "Image file not found at location: #{image_location}"
|
||||||
|
@ -33,6 +37,13 @@ class Tags
|
||||||
@query_args.push(%(-metadata:s:v title="Album cover"))
|
@query_args.push(%(-metadata:s:v title="Album cover"))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Add a text tag to the mp3. If you want to see what text tags are supported,
|
||||||
|
# check out: https://wiki.multimedia.cx/index.php?title=FFmpeg_Metadata
|
||||||
|
def add_text_tag(key : String, value : String) : Nil
|
||||||
|
@query_args.push(%(-metadata #{key}="#{value}"))
|
||||||
|
end
|
||||||
|
|
||||||
|
# Run the necessary commands to attach album art to the mp3
|
||||||
def save : Nil
|
def save : Nil
|
||||||
@query_args.push(%("_#{@filename}"))
|
@query_args.push(%("_#{@filename}"))
|
||||||
command = @BIN_LOC.to_s + "/ffmpeg " + @query_args.join(" ")
|
command = @BIN_LOC.to_s + "/ffmpeg " + @query_args.join(" ")
|
||||||
|
|
|
@ -69,24 +69,34 @@ class SpotifySearcher
|
||||||
points = rank_items(items, item_parameters)
|
points = rank_items(items, item_parameters)
|
||||||
|
|
||||||
begin
|
begin
|
||||||
return items[points[0][1]]
|
return get_item(item_type, items[points[0][1]]["id"].to_s)
|
||||||
rescue IndexError
|
rescue IndexError
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Get the complete metadata of an item based off of its id
|
||||||
|
#
|
||||||
|
# ```
|
||||||
|
# SpotifySearcher.new().authorize(...).get_item("artist", "1dfeR4HaWDbWqFHLkxsg1d")
|
||||||
|
# ```
|
||||||
|
def get_item(item_type : String, id : String) : JSON::Any?
|
||||||
|
url = @root_url.join("#{item_type}s/#{id}").to_s()
|
||||||
|
|
||||||
|
response = HTTP::Client.get(url, headers: @access_header)
|
||||||
|
error_check(response)
|
||||||
|
|
||||||
|
return JSON.parse(response.body)
|
||||||
|
end
|
||||||
|
|
||||||
# Find the genre of an artist based off of their id
|
# Find the genre of an artist based off of their id
|
||||||
#
|
#
|
||||||
# ```
|
# ```
|
||||||
# SpotifySearcher.new().authorize(...).find_genre("1dfeR4HaWDbWqFHLkxsg1d")
|
# SpotifySearcher.new().authorize(...).find_genre("1dfeR4HaWDbWqFHLkxsg1d")
|
||||||
# ```
|
# ```
|
||||||
def find_genre(id : String) : String
|
def find_genre(id : String) : String
|
||||||
url = @root_url.join("artists/#{id}").to_s()
|
|
||||||
|
|
||||||
response = HTTP::Client.get(url, headers: @access_header)
|
genre = get_item("artist", id)["genres"][0].to_s
|
||||||
error_check(response)
|
|
||||||
|
|
||||||
genre = JSON.parse(response.body)["genres"][0].to_s
|
|
||||||
genre = genre.split(" ").map { |x| x.capitalize }.join(" ")
|
genre = genre.split(" ").map { |x| x.capitalize }.join(" ")
|
||||||
|
|
||||||
return genre
|
return genre
|
||||||
|
@ -117,8 +127,9 @@ class SpotifySearcher
|
||||||
query += param_encode(item_type, item_parameters[k])
|
query += param_encode(item_type, item_parameters[k])
|
||||||
|
|
||||||
# check if the key is to be excluded
|
# check if the key is to be excluded
|
||||||
elsif !query_exclude.includes?(k)
|
elsif query_exclude.includes?(k)
|
||||||
query += item_parameters[k].gsub(" ", "+") + "+"
|
next
|
||||||
|
# query += item_parameters[k].gsub(" ", "+") + "+"
|
||||||
|
|
||||||
# if it's none of the above, treat it normally
|
# if it's none of the above, treat it normally
|
||||||
else
|
else
|
||||||
|
@ -206,10 +217,14 @@ class SpotifySearcher
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# puts SpotifySearcher.new()
|
puts SpotifySearcher.new()
|
||||||
# .authorize("e4198f6a3f7b48029366f22528b5dc66",
|
.authorize("e4198f6a3f7b48029366f22528b5dc66",
|
||||||
# "ba057d0621a5496bbb64edccf758bde5")
|
"ba057d0621a5496bbb64edccf758bde5")
|
||||||
# .find_item("album", {
|
.find_item("playlist", {
|
||||||
|
"name" => "Brain Food",
|
||||||
|
"username" => "spotify"
|
||||||
# "name " => "A Night At The Opera",
|
# "name " => "A Night At The Opera",
|
||||||
# "artist" => "Queen"
|
# "artist" => "Queen"
|
||||||
# })
|
# "track" => "Bohemian Rhapsody",
|
||||||
|
# "artist" => "Queen"
|
||||||
|
})
|
Loading…
Reference in a new issue