mirror of
https://github.com/cooperhammond/irs.git
synced 2024-12-22 17:35:28 +00:00
make the way mp3s are saved configurable
Signed-off-by: Luca Schlecker <luca.schlecker@hotmail.com>
This commit is contained in:
parent
2c364c38c2
commit
2e8bc6c8c5
57
README.md
57
README.md
|
@ -96,6 +96,8 @@ If you're one of those cool people who compiles from source
|
|||
```yaml
|
||||
binary_directory: ~/.irs/bin
|
||||
music_directory: ~/Music
|
||||
filename_pattern: "{track_number} - {title}"
|
||||
directory_pattern: "{artist}/{album}"
|
||||
client_key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
client_secret: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
single_folder_playlist:
|
||||
|
@ -122,6 +124,8 @@ Here's what they do:
|
|||
```yaml
|
||||
binary_directory: ~/.irs/bin
|
||||
music_directory: ~/Music
|
||||
filename_pattern: "{track_number} - {title}"
|
||||
directory_pattern: "{artist}/{album}"
|
||||
client_key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
client_secret: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
single_folder_playlist:
|
||||
|
@ -132,8 +136,8 @@ single_folder_playlist:
|
|||
- `binary_directory`: a path specifying where the downloaded binaries should
|
||||
be placed
|
||||
- `music_directory`: a path specifying where downloaded mp3s should be placed.
|
||||
Note that there will be more structure created inside that folder, usually
|
||||
in the format of `music-dir>artist-name>album-name>track`
|
||||
- `filename_pattern`: a pattern for the output filename of the mp3
|
||||
- `directory_pattern`: a pattern for the folder structure your mp3s are saved in
|
||||
- `client_key`: a client key from your spotify API application
|
||||
- `client_secret`: a client secret key from your spotify API application
|
||||
- `single_folder_playlist/enabled`: if set to true, all mp3s from a downloaded
|
||||
|
@ -145,6 +149,55 @@ single_folder_playlist:
|
|||
the album name and album image of the mp3 with the title of your playlist
|
||||
and the image for your playlist respectively
|
||||
|
||||
|
||||
In a pattern following keywords will be replaced:
|
||||
|
||||
| Keyword | Replacement | Example |
|
||||
| :----: | :----: | :----: |
|
||||
| `{artist}` | Artist Name | Queen |
|
||||
| `{title}` | Track Title | Bohemian Rhapsody |
|
||||
| `{album}` | Album Name | Stone Cold Classics |
|
||||
| `{track_number}` | Track Number | 9 |
|
||||
| `{total_tracks}` | Total Tracks in Album | 14 |
|
||||
| `{disc_number}` | Disc Number | 1 |
|
||||
| `{day}` | Release Day | 01 |
|
||||
| `{month}` | Release Month | 01 |
|
||||
| `{year}` | Release Year | 2006 |
|
||||
| `{id}` | Spotify ID | 6l8GvAyoUZwWDgF1e4822w |
|
||||
|
||||
Beware OS-restrictions when naming your mp3s.
|
||||
|
||||
Pattern Examples:
|
||||
```yaml
|
||||
music_directory: ~/Music
|
||||
filename_pattern: "{track_number} - {title}"
|
||||
directory_pattern: "{artist}/{album}"
|
||||
```
|
||||
Outputs: `~/Music/Queen/Stone Cold Classics/9 - Bohemian Rhapsody.mp3`
|
||||
<br><br>
|
||||
```yaml
|
||||
music_directory: ~/Music
|
||||
filename_pattern: "{artist} - {title}"
|
||||
directory_pattern: ""
|
||||
```
|
||||
Outputs: `~/Music/Queen - Bohemian Rhapsody.mp3`
|
||||
<br><br>
|
||||
```yaml
|
||||
music_directory: ~/Music
|
||||
filename_pattern: "{track_number} of {total_tracks} - {title}"
|
||||
directory_pattern: "{year}/{artist}/{album}"
|
||||
```
|
||||
Outputs: `~/Music/2006/Queen/Stone Cold Classics/9 of 14 - Bohemian Rhapsody.mp3`
|
||||
<br><br>
|
||||
```yaml
|
||||
music_directory: ~/Music
|
||||
filename_pattern: "{track_number}. {title}"
|
||||
directory_pattern: "irs/{artist} - {album}"
|
||||
```
|
||||
Outputs: `~/Music/irs/Queen - Stone Cold Classics/9. Bohemian Rhapsody.mp3`
|
||||
<br>
|
||||
|
||||
|
||||
## How it works
|
||||
|
||||
**At it's core** `irs` downloads individual songs. It does this by interfacing
|
||||
|
|
|
@ -83,7 +83,7 @@ class CLI
|
|||
s = Song.new(@args["song"], @args["artist"])
|
||||
s.provide_client_keys(Config.client_key, Config.client_secret)
|
||||
s.grab_it(@args["url"]?)
|
||||
s.organize_it(Config.music_directory)
|
||||
s.organize_it()
|
||||
elsif @args["album"]? && @args["artist"]?
|
||||
a = Album.new(@args["album"], @args["artist"])
|
||||
a.provide_client_keys(Config.client_key, Config.client_secret)
|
||||
|
|
|
@ -9,6 +9,8 @@ EXAMPLE_CONFIG = <<-EOP
|
|||
#{Style.dim "===="}
|
||||
#{Style.blue "binary_directory"}: #{Style.green "~/.irs/bin"}
|
||||
#{Style.blue "music_directory"}: #{Style.green "~/Music"}
|
||||
#{Style.blue "filename_pattern"}: #{Style.green "\"{track_number} - {title}\""}
|
||||
#{Style.blue "directory_pattern"}: #{Style.green "\"{artist}/{album}\""}
|
||||
#{Style.blue "client_key"}: #{Style.green "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"}
|
||||
#{Style.blue "client_secret"}: #{Style.green "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"}
|
||||
#{Style.blue "single_folder_playlist"}:
|
||||
|
@ -24,6 +26,8 @@ module Config
|
|||
@@arguments = [
|
||||
"binary_directory",
|
||||
"music_directory",
|
||||
"filename_pattern",
|
||||
"directory_pattern",
|
||||
"client_key",
|
||||
"client_secret",
|
||||
"single_folder_playlist: enabled",
|
||||
|
@ -51,6 +55,14 @@ module Config
|
|||
return Path[path].expand(home: true).to_s
|
||||
end
|
||||
|
||||
def filename_pattern : String
|
||||
return @@conf["filename_pattern"].to_s
|
||||
end
|
||||
|
||||
def directory_pattern : String
|
||||
return @@conf["directory_pattern"].to_s
|
||||
end
|
||||
|
||||
def client_key : String
|
||||
return @@conf["client_key"].to_s
|
||||
end
|
||||
|
|
28
src/bottle/pattern.cr
Normal file
28
src/bottle/pattern.cr
Normal file
|
@ -0,0 +1,28 @@
|
|||
module Pattern
|
||||
extend self
|
||||
|
||||
def parse(formatString : String, metadata : JSON::Any)
|
||||
formatted : String = formatString
|
||||
|
||||
date : Array(String) = (metadata["album"]? || JSON.parse("{}"))["release_date"]?.to_s.split('-')
|
||||
|
||||
keys : Hash(String, String) = {
|
||||
"artist" => ((metadata.dig?("artists") || JSON.parse("{}"))[0]? || JSON.parse("{}"))["name"]?.to_s,
|
||||
"title" => metadata["name"]?.to_s,
|
||||
"album" => (metadata["album"]? || JSON.parse("{}"))["name"]?.to_s,
|
||||
"track_number" => metadata["track_number"]?.to_s,
|
||||
"disc_number" => metadata["disc_number"]?.to_s,
|
||||
"total_tracks" => (metadata["album"]? || JSON.parse("{}"))["total_tracks"]?.to_s,
|
||||
"year" => date[0]?.to_s,
|
||||
"month" => date[1]?.to_s,
|
||||
"day" => date[2]?.to_s,
|
||||
"id" => metadata["id"]?.to_s
|
||||
}
|
||||
|
||||
keys.each do |pair|
|
||||
formatted = formatted.gsub("{#{pair[0]}}", pair[1] || "")
|
||||
end
|
||||
|
||||
return formatted
|
||||
end
|
||||
end
|
|
@ -42,6 +42,6 @@ class Album < SpotifyList
|
|||
end
|
||||
|
||||
private def organize(song : Song)
|
||||
song.organize_it(@home_music_directory)
|
||||
song.organize_it()
|
||||
end
|
||||
end
|
||||
|
|
|
@ -69,7 +69,7 @@ class Playlist < SpotifyList
|
|||
safe_filename = song.filename.gsub(/[\/]/, "").gsub(" ", " ")
|
||||
File.rename("./" + song.filename, (path / safe_filename).to_s)
|
||||
else
|
||||
song.organize_it(@home_music_directory)
|
||||
song.organize_it()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,6 +4,8 @@ require "../search/youtube"
|
|||
require "../interact/ripper"
|
||||
require "../interact/tagger"
|
||||
|
||||
require "../bottle/config"
|
||||
require "../bottle/pattern"
|
||||
require "../bottle/styles"
|
||||
|
||||
class Song
|
||||
|
@ -83,7 +85,7 @@ class Song
|
|||
end
|
||||
|
||||
data = @metadata.as(JSON::Any)
|
||||
@filename = data["track_number"].to_s + " - #{data["name"].to_s}.mp3"
|
||||
@filename = "#{Pattern.parse(Config.filename_pattern, data)}.mp3"
|
||||
|
||||
if ask_url
|
||||
outputter("url", 4)
|
||||
|
@ -154,20 +156,24 @@ class Song
|
|||
outputter("finished", 0)
|
||||
end
|
||||
|
||||
# Will organize the song into the user's provided music directory as
|
||||
# music_directory > artist_name > album_name > song
|
||||
# Will organize the song into the user's provided music directory
|
||||
# in the user's provided structure
|
||||
# Must be called AFTER the song has been downloaded.
|
||||
#
|
||||
# ```
|
||||
# s = Song.new("Bohemian Rhapsody", "Queen").grab_it
|
||||
# s.organize_it("/home/cooper/Music")
|
||||
# # Will move the mp3 file to
|
||||
# s.organize_it()
|
||||
# # With
|
||||
# # directory_pattern = "{artist}/{album}"
|
||||
# # filename_pattern = "{track_number} - {title}"
|
||||
# # Mp3 will be moved to
|
||||
# # /home/cooper/Music/Queen/A Night At The Opera/1 - Bohemian Rhapsody.mp3
|
||||
# ```
|
||||
def organize_it(music_directory : String)
|
||||
path = Path[music_directory].expand(home: true)
|
||||
path = path / @artist_name.gsub(/[\/]/, "").gsub(" ", " ")
|
||||
path = path / @album.gsub(/[\/]/, "").gsub(" ", " ")
|
||||
def organize_it()
|
||||
path = Path[Config.music_directory].expand(home: true)
|
||||
Pattern.parse(Config.directory_pattern, @metadata.as(JSON::Any)).split('/').each do |dir|
|
||||
path = path / dir.gsub(/[\/]/, "").gsub(" ", " ")
|
||||
end
|
||||
strpath = path.to_s
|
||||
if !File.directory?(strpath)
|
||||
FileUtils.mkdir_p(strpath)
|
||||
|
|
Loading…
Reference in a new issue