From ce6f77d68ddfc29eb7f45884900e0d7533afa5a7 Mon Sep 17 00:00:00 2001 From: Cooper Hammond Date: Fri, 15 May 2020 09:16:50 -0700 Subject: [PATCH] nothing affecting functionality, all meta changes - changed license to MIT - wrote out actual README - spotify client keys are checked for on run in config.cr - spotify-searcher class doesn't crash now when there's a problem with the keys or authentication, rather it just sets @authenticated to false --- LICENSE | 2 +- README.md | 67 +++++++++++++++++++++++++++++++++---------- src/bottle/config.cr | 28 ++++++++++++------ src/search/spotify.cr | 5 +++- 4 files changed, 77 insertions(+), 25 deletions(-) diff --git a/LICENSE b/LICENSE index 191c7f4..cd00ded 100755 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2019 Cooper Hammond +Copyright (c) 2020 Cooper Hammond Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index f2fd4e9..f292c96 100755 --- a/README.md +++ b/README.md @@ -1,33 +1,70 @@ -# irs +# `irs` +###### AKA `Ironic Repositioning System` -TODO: Write a description here +[![made-with-crystal](https://img.shields.io/badge/Made%20with-Crystal-1f425f.svg?style=flat-square)](https://crystal-lang.org/) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow?style=flat-square)](https://github.com/cooperhammond/irs/blob/master/LICENSE) +[![Say Thanks](https://img.shields.io/badge/say-thanks-ff69b4.svg?style=flat-square)](https://saythanks.io/to/kepoorhampond) + +> A music scraper that understands your metadata needs. + +## Installation + +1. Download the latest release for your platform [here](https://github.com/cooperhammond/irs/releases) +1. Create a `.yaml` config file somewhere on your system +1. Copy the following into it + ```yaml + binary_directory: ~/.irs/bin + music_directory: ~/Music + client_key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + client_secret: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + single_folder_playlist: + enabled: true + retain_playlist_order: true + overwrite_album: false + ``` +1. Set the environment variable `IRS_CONFIG_LOCATION` pointing to that file +1. Go to [`https://developer.spotify.com/dashboard/`](https://developer.spotify.com/dashboard/) +1. Log in or create an account +1. Click `CREATE A CLIENT ID` +1. Enter all necessary info, true or false, continue +1. Find your client key and client secret +2. Copy them into where all the X's are in your config file from above + +You should be good to go! Run the file from your command line to get help on usage or keep reading! + +##### Optionally From Source + +Or if you're one of those cool people who compiles from source + +1. Install crystal-lang ([`https://crystal-lang.org/install/`](https://crystal-lang.org/install/)) +1. Clone it (`git clone https://github.com/cooperhammond/irs`) +1. CD it (`cd irs`) +1. Build it (`shards build`) ## Usage

- +

-TODO: Write usage instructions here +## How it works -## Installation +**At it's core** `irs` downloads individual songs. It does this by interfacing with the Spotify API, grabbing metadata, and then searching Youtube for a video containing the song's audio. It will download the video using [`youtube-dl`](https://github.com/ytdl-org/youtube-dl), extract the audio using [`ffmpeg`](https://ffmpeg.org/), and then pack the audio and metadata together into an MP3. -TODO: Write installation instructions here +From the core, it has been extended to download the index of albums and playlists through the spotify API, and then iteratively use the method above for downloading each song. +It used to be in `python`, but +1. I wasn't a fan of python's limited ability to distribute standalone binaries +1. It was a clusterfuck of code that I made when I was little and I wanted to refine it +2. `crystal-lang` made some promises and I was interested in seeing how well it did (verdict: if you're building high-level tools you want to run quickly and distribute, it's a joy to work in) -## Development - -TODO: Write development instructions here - ## Contributing +Any and all contributions are welcome. If you think of a cool feature, send a PR or shoot me an [email](mailto:kepoorh@gmail.com). If you think something could be implemented better, _please_ shoot me an email. If you like what I'm doing here, _pretty please_ shoot me an email. + 1. Fork it () 2. Create your feature branch (`git checkout -b my-new-feature`) 3. Commit your changes (`git commit -am 'Add some feature'`) 4. Push to the branch (`git push origin my-new-feature`) -5. Create a new Pull Request - -## Contributors - -- [Cooper Hammond](https://github.com/your-github-user) - creator and maintainer +5. Create a new Pull Request \ No newline at end of file diff --git a/src/bottle/config.cr b/src/bottle/config.cr index ddf3a07..ab1c81f 100755 --- a/src/bottle/config.cr +++ b/src/bottle/config.cr @@ -2,17 +2,19 @@ require "yaml" require "./styles" +require "../search/spotify" + EXAMPLE_CONFIG = <<-EOP #{Style.dim "exampleconfig.yml"} #{Style.dim "===="} -binary_directory: ~/.irs/bin -music_directory: ~/Music -client_key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -client_secret: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -single_folder_playlist: - enabled: true - retain_playlist_order: true - overwrite_album: false +#{Style.blue "binary_directory"}: #{Style.green "~/.irs/bin"} +#{Style.blue "music_directory"}: #{Style.green "~/Music"} +#{Style.blue "client_key"}: #{Style.green "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"} +#{Style.blue "client_secret"}: #{Style.green "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"} +#{Style.blue "single_folder_playlist"}: + #{Style.blue "enabled"}: #{Style.green "true"} + #{Style.blue "retain_playlist_order"}: #{Style.green "true"} + #{Style.blue "overwrite_album"}: #{Style.green "false"} #{Style.dim "===="} EOP @@ -86,6 +88,16 @@ module Config puts Style.bold "See https://github.com/cooperhammond/irs for more information on the config file" exit 1 end + spotify = SpotifySearcher.new + spotify.authorize(self.client_key, self.client_secret) + if !spotify.authorized? + puts Style.red("There's something wrong with your client key and/or client secret") + puts "Get your keys from https://developer.spotify.com/dashboard, and enter them in your config file" + puts "Your config file is at #{ENV["IRS_CONFIG_LOCATION"]}" + puts EXAMPLE_CONFIG + puts Style.bold "See https://github.com/cooperhammond/irs for more information on the config file" + exit 1 + end end private def check_conf(key : String) : YAML::Any? diff --git a/src/search/spotify.cr b/src/search/spotify.cr index c1ea10e..33501e1 100755 --- a/src/search/spotify.cr +++ b/src/search/spotify.cr @@ -28,7 +28,10 @@ class SpotifySearcher payload = "grant_type=client_credentials" response = HTTP::Client.post(auth_url, headers: headers, form: payload) - error_check(response) + if response.status_code != 200 + @authorized = false + return self + end access_token = JSON.parse(response.body)["access_token"]