commit f909b8cbc4f0ca007918065bbaddfd8adbcc95c9
parent 44fd2dfbe476a8f13b067f8fbd583a39d777863a
Author: Alex Balgavy <alex@balgavy.eu>
Date: Sat, 4 Jun 2022 22:36:15 +0200
Add ruby files that I still need to rewrite
Diffstat:
6 files changed, 148 insertions(+), 20 deletions(-)
diff --git a/src/config.rs b/src/config.rs
@@ -19,7 +19,7 @@ pub struct Item {
pub website: String,
pub url: Option<String>,
pub mpc_load_option: Option<MpcLoadOptions>,
- pub radios: Option<Vec<Item>>
+ pub radios: Option<Vec<Item>>,
}
pub fn read_config() -> ConfigData {
diff --git a/src/main.rs b/src/main.rs
@@ -2,10 +2,10 @@ mod config;
mod radio;
mod screen;
mod tunein;
+use config::*;
use radio::*;
use std::process::exit;
use tunein::*;
-use config::*;
fn choose_radio(radios: &Vec<Item>) -> &Item {
loop {
let choices: Vec<String> = radios
@@ -15,18 +15,21 @@ fn choose_radio(radios: &Vec<Item>) -> &Item {
let (choice_i, _) = match screen::list_menu(&*choices) {
Some((i, s)) => (i, s),
- None => continue
+ None => continue,
};
let chosen_radio = match radios[choice_i].url {
Some(_) => &radios[choice_i],
None => {
- let choices: Vec<String> = radios[choice_i].radios.as_ref().unwrap()
+ let choices: Vec<String> = radios[choice_i]
+ .radios
+ .as_ref()
+ .unwrap()
.iter()
.map(|x| format!("{} ({})", x.name, x.website))
.collect();
let (choice_i, _) = match screen::list_menu(&*choices) {
Some((i, s)) => (i, s),
- None => continue
+ None => continue,
};
&radios[choice_i]
}
@@ -37,10 +40,10 @@ fn choose_radio(radios: &Vec<Item>) -> &Item {
fn main() {
let data = config::read_config();
assert!(data
- .config
- .radios
- .iter()
- .all(|x| (x.url.is_some() && x.mpc_load_option.is_some()) || (x.radios.is_some())));
+ .config
+ .radios
+ .iter()
+ .all(|x| (x.url.is_some() && x.mpc_load_option.is_some()) || (x.radios.is_some())));
let top_radios = &data.config.radios;
let chosen_radio = choose_radio(top_radios);
diff --git a/src/radio/radiogarden.rb b/src/radio/radiogarden.rb
@@ -0,0 +1,53 @@
+# TODO: convert to rust
+class RadioGarden < Radio
+ require 'json'
+ require 'open-uri'
+ require 'cgi'
+
+ def initialize(_)
+ @base_url = 'https://radio.garden/api'
+ puts 'No radio found, please try again.' while (retrieved_channels = search_channels).empty?
+ channels = parse_channels(retrieved_channels)
+ selected_channel = choose_from_list(channels, channels.map { |c| c[:name] }) while selected_channel.nil?
+ @channel = get_channel_link(selected_channel)
+ super()
+ rescue Interrupt
+ @channel = nil
+ end
+
+ def play
+ if @player == 'mpc'
+ system 'mpc', 'clear', 1 => '/dev/null'
+ system 'mpc', 'add', @channel
+ end
+ super @channel
+ end
+
+ private
+
+ def search_channels
+ print 'Enter radio search: '
+ query = gets.chomp
+ URI.parse("#{@base_url}/search?q=#{CGI.escape query}").open do |response|
+ JSON.parse(response.read)['hits']['hits']
+ end
+ rescue OpenURI::HTTPError
+ []
+ end
+
+ def get_channel_link(selected_channel)
+ # Will redirect
+ @channel = URI.parse("#{@base_url}/ara/content/listen/#{selected_channel[:id]}/channel.mp3").open(redirect: false)
+ rescue OpenURI::HTTPRedirect => e
+ @channel = e.uri.to_s.gsub(/\?listening-from.*/, '')
+ rescue OpenURI::HTTPError
+ @channel = None
+ end
+
+ def parse_channels(retrieved_channels)
+ retrieved_channels.inject([]) do |channels, c|
+ channels << { name: "#{c['_source']['title']} (#{c['_source']['subtitle']})",
+ id: c['_source']['channelId'] }
+ end
+ end
+end
diff --git a/src/radio/sounds_of_earth.rb b/src/radio/sounds_of_earth.rb
@@ -0,0 +1,32 @@
+# TODO: convert to rust
+class SoundsOfEarth < Radio
+ require 'json'
+ require 'open-uri'
+
+ def initialize(_)
+ channels = retrieve_channels
+ @channel = choose_from_list(channels.map { |c| c[:link] }, channels.map { |c| c[:name] }) while @channel.nil?
+ super()
+ rescue Interrupt
+ @channel = nil
+ end
+
+ def play
+ if @player == 'mpc'
+ system 'mpc', 'clear', 1 => '/dev/null'
+ system 'mpc', 'add', @channel
+ end
+ super @channel
+ end
+
+ private
+
+ def retrieve_channels
+ URI('https://soundsofearth.eco/regions.json').open do |response|
+ streams = JSON.parse(response.read)['results']
+ streams.map { |stream| { name: "#{stream['name']} (#{stream['description']})", link: stream['sound'] } }
+ end
+ rescue OpenURI::HTTPError
+ []
+ end
+end
diff --git a/src/radio/subreddit.rb b/src/radio/subreddit.rb
@@ -0,0 +1,43 @@
+# TODO: convert to rust
+class Subreddit < Radio
+ require 'json'
+ require 'open-uri'
+ require 'shellwords'
+
+ def initialize(_)
+ puts 'Subreddit has no music posts or does not exist.' while (posts = retrieve_subreddit_posts).empty?
+ @links = extract_post_links(posts)
+ super()
+ rescue Interrupt
+ @channel = nil
+ end
+
+ def play
+ puts "Number of tracks: #{@links.length}"
+ # TODO: support mpd
+ system("mpv --vid=no --volume=50 -- #{@links.map { |l| l[:url] }.shelljoin}")
+ end
+
+ private
+
+ def retrieve_subreddit_posts
+ print 'Enter subreddit name: '
+ sub = gets.chomp
+ url = "https://www.reddit.com/r/#{sub}/top.json?t=month&limit=100&show=all"
+ URI.parse(url).open('User-Agent' => 'ruby/2.7', 'Accept' => 'application/json') do |response|
+ @channel = sub
+ JSON.parse(response.read)['data']['children']
+ end
+ rescue OpenURI::HTTPError
+ []
+ end
+
+ def extract_post_links(posts)
+ posts.each_with_object([]) do |post, links|
+ p = post['data']
+ if !p['is_self'] && p['post_hint'] != 'image'
+ links.append(title: p['title'], url: p['url'], reddit: "https://reddit.com#{p['permalink']}")
+ end
+ end
+ end
+end
diff --git a/src/screen.rs b/src/screen.rs
@@ -22,7 +22,6 @@ fn prompt(prompt: &str) -> String {
}
}
-
pub fn list_menu(list: &[String]) -> Option<(usize, String)> {
let mut message = None;
loop {
@@ -44,17 +43,15 @@ pub fn list_menu(list: &[String]) -> Option<(usize, String)> {
let n = match trimmed.parse::<usize>() {
Ok(n) => n,
- _ => {
- match trimmed {
- "q" | "quit" => {
- return None;
- }
- _ => {
- message = Some("Not a number!");
- continue;
- }
+ _ => match trimmed {
+ "q" | "quit" => {
+ return None;
+ }
+ _ => {
+ message = Some("Not a number!");
+ continue;
}
- }
+ },
};
if n == 0 || n > list.len() {
message = Some("choice out of range");