Compare commits
7 Commits
master
...
mb_request
Author | SHA1 | Date | |
---|---|---|---|
63f86aa8e4 | |||
c7faeb6bc8 | |||
6189a8b17f | |||
9530bb9190 | |||
39c6a1bcc1 | |||
5e88e7c2c3 | |||
cfd80b839b |
117
.gitignore
vendored
117
.gitignore
vendored
@ -435,120 +435,3 @@ Temporary Items
|
||||
# Built Visual Studio Code Extensions
|
||||
*.vsix
|
||||
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/pycharm
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=pycharm
|
||||
|
||||
### PyCharm ###
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# AWS User-specific
|
||||
.idea/**/aws.xml
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/artifacts
|
||||
# .idea/compiler.xml
|
||||
# .idea/jarRepositories.xml
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
# *.iml
|
||||
# *.ipr
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# SonarLint plugin
|
||||
.idea/sonarlint/
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
### PyCharm Patch ###
|
||||
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
|
||||
|
||||
# *.iml
|
||||
# modules.xml
|
||||
# .idea/misc.xml
|
||||
# *.ipr
|
||||
|
||||
# Sonarlint plugin
|
||||
# https://plugins.jetbrains.com/plugin/7973-sonarlint
|
||||
.idea/**/sonarlint/
|
||||
|
||||
# SonarQube Plugin
|
||||
# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
|
||||
.idea/**/sonarIssues.xml
|
||||
|
||||
# Markdown Navigator plugin
|
||||
# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
|
||||
.idea/**/markdown-navigator.xml
|
||||
.idea/**/markdown-navigator-enh.xml
|
||||
.idea/**/markdown-navigator/
|
||||
|
||||
# Cache file creation bug
|
||||
# See https://youtrack.jetbrains.com/issue/JBR-2257
|
||||
.idea/$CACHE_FILE$
|
||||
|
||||
# CodeStream plugin
|
||||
# https://plugins.jetbrains.com/plugin/12206-codestream
|
||||
.idea/codestream.xml
|
||||
|
||||
# Azure Toolkit for IntelliJ plugin
|
||||
# https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij
|
||||
.idea/**/azureSettings.xml
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/pycharm
|
||||
|
@ -1,3 +1,3 @@
|
||||
# get_artist_art
|
||||
|
||||
Pulls artist art from https://fanart.tv/ using identifiers from https://musicbrainz.org.
|
||||
Pulls artist art from https://www.theaudiodb.com/
|
71
api_calls.py
71
api_calls.py
@ -1,71 +0,0 @@
|
||||
import requests
|
||||
import os
|
||||
from time import sleep
|
||||
|
||||
def get_mb_id(artist_name, mb_confidence):
|
||||
artist_name = artist_name.strip('_')
|
||||
mb_url = f'https://musicbrainz.org/ws/2/artist?query=artist:"{artist_name}"&fmt=json'
|
||||
header = {'User-Agent': 'get_artist_art.py/1.0'}
|
||||
response = requests.get(mb_url, headers=header)
|
||||
if response.status_code == 200:
|
||||
mb_data = response.json()
|
||||
if mb_data['count'] > 0:
|
||||
if mb_data['artists'][0]['score'] > mb_confidence:
|
||||
return True, mb_data['artists'][0]['id'], True
|
||||
else:
|
||||
print("No artist found of hight enough confidance.")
|
||||
return False, "", True
|
||||
else:
|
||||
print("No artist found.")
|
||||
return False, "", True
|
||||
elif response.status_code == 503:
|
||||
sleep(1)
|
||||
return False, "", False
|
||||
else:
|
||||
print(f"MB Error: {response.status_code}")
|
||||
return False, "", True
|
||||
|
||||
def get_image(mb_id, ftv_api_key, artist_path):
|
||||
ftv_api_url = f'https://webservice.fanart.tv/v3/music/{mb_id}?api_key={ftv_api_key}'
|
||||
response = requests.get(ftv_api_url)
|
||||
ftv_data =response.json()
|
||||
if not ('status' in ftv_data):
|
||||
if 'artistthumb' in ftv_data:
|
||||
art_url = ftv_data['artistthumb'][0]['url']
|
||||
print(art_url)
|
||||
response = requests.get(art_url)
|
||||
if response.status_code == 200:
|
||||
with open(os.path.join(artist_path, 'artist.jpg'), 'wb') as f:
|
||||
f.write(response.content)
|
||||
return True
|
||||
elif 'artistbackground' in ftv_data:
|
||||
art_url = ftv_data['artistbackground'][0]['url']
|
||||
response = requests.get(art_url)
|
||||
if response.status_code == 200:
|
||||
with open(os.path.join(artist_path, 'artist.jpg'),'wb') as f:
|
||||
f.write(response.content)
|
||||
return True
|
||||
elif 'hdmusiclogo' in ftv_data:
|
||||
art_url = ftv_data['hdmusiclogo'][0]['url']
|
||||
response = requests.get(art_url)
|
||||
if response.status_code == 200:
|
||||
with open(os.path.join(artist_path, 'artist.png'), 'wb') as f:
|
||||
f.write(response.content)
|
||||
return True
|
||||
else:
|
||||
print("Error downloading: ", response.status_code)
|
||||
return True
|
||||
else:
|
||||
print("Thumb not found.")
|
||||
return True
|
||||
elif response.status_code == 503:
|
||||
sleep(1)
|
||||
return False
|
||||
else:
|
||||
error_msg = ftv_data['error message']
|
||||
if error_msg == "503":
|
||||
sleep(1)
|
||||
return False
|
||||
else:
|
||||
print(f"FTV Error: {error_msg}")
|
||||
return True
|
@ -1,10 +0,0 @@
|
||||
import os
|
||||
|
||||
def get_all(path):
|
||||
return [name for name in os.listdir(path) if os.path.isdir(os.path.join(path, name))]
|
||||
|
||||
def has_artist_art(path):
|
||||
if(os.path.exists(os.path.join(path, "artist.jpg")))or (os.path.exists(os.path.join(path, "artist.png"))):
|
||||
return True
|
||||
else:
|
||||
return False
|
147
get_artist_art.c
Normal file
147
get_artist_art.c
Normal file
@ -0,0 +1,147 @@
|
||||
#include <curl/curl.h>
|
||||
#include <libconfig.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define version_str "1.0"
|
||||
#define conf_file "config.ini"
|
||||
#define mb_url \
|
||||
"https://musicbrainz.org/ws/2/artist?query=artist:\"%s\"&fmt=json"
|
||||
|
||||
const char *get_conf_str(char set_key[]) {
|
||||
const char *prog_conf = malloc(10 * sizeof(char));
|
||||
config_t cfg;
|
||||
config_setting_t *setting;
|
||||
|
||||
config_init(&cfg);
|
||||
|
||||
if (!config_read_file(&cfg, conf_file)) {
|
||||
fprintf(stderr, "%s:%d - %s\n", config_error_file(&cfg),
|
||||
config_error_line(&cfg), config_error_text(&cfg));
|
||||
config_destroy(&cfg);
|
||||
return "";
|
||||
}
|
||||
|
||||
setting = config_lookup(&cfg, set_key);
|
||||
|
||||
prog_conf = config_setting_get_string(setting);
|
||||
|
||||
config_destroy(&cfg);
|
||||
return prog_conf;
|
||||
}
|
||||
|
||||
int get_conf_int(char set_key[]) {
|
||||
int set_int;
|
||||
config_t cfg;
|
||||
config_setting_t *setting;
|
||||
|
||||
config_init(&cfg);
|
||||
|
||||
if (!config_read_file(&cfg, conf_file)) {
|
||||
fprintf(stderr, "%s:%d - %s\n", config_error_file(&cfg),
|
||||
config_error_line(&cfg), config_error_text(&cfg));
|
||||
config_destroy(&cfg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
setting = config_lookup(&cfg, set_key);
|
||||
set_int = config_setting_get_int(setting);
|
||||
|
||||
config_destroy(&cfg);
|
||||
|
||||
return set_int;
|
||||
}
|
||||
|
||||
void print_conf(const char m_dir[], const int mb_conf,
|
||||
const char ftv_api_key[32]) {
|
||||
if (m_dir != NULL) {
|
||||
printf("The music directory is: %s\n", m_dir);
|
||||
}
|
||||
if (mb_conf != 1) {
|
||||
printf("The lower limit for MB confidence is: %d\n", mb_conf);
|
||||
}
|
||||
if (ftv_api_key != NULL) {
|
||||
printf("Your API key is: %s\n", ftv_api_key);
|
||||
}
|
||||
}
|
||||
|
||||
const char *get_mb_id(char *artist_name) {
|
||||
int response_code;
|
||||
const char *mb_id;
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
char *buffer;
|
||||
long res_len;
|
||||
char mb_url_full[100];
|
||||
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
|
||||
curl = curl_easy_init();
|
||||
|
||||
if (curl) {
|
||||
/*Make the artist name URL safe.*/
|
||||
char *artist_name_esc = curl_easy_escape(curl, artist_name, 0);
|
||||
printf("%s", artist_name_esc);
|
||||
/*Format the MB URL to insert the Artist name for the query.*/
|
||||
snprintf(mb_url_full, sizeof(mb_url_full), mb_url, artist_name_esc);
|
||||
printf("%s\n", mb_url_full);
|
||||
curl_easy_setopt(curl, CURLOPT_URL, mb_url_full);
|
||||
curl_easy_setopt(curl, CURLOPT_USERAGENT, "get_artist_art.py/1.0");
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
if (res != CURLE_OK) {
|
||||
fprintf(stderr, "curl_easy_perform() failed with error: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
return "1";
|
||||
}
|
||||
|
||||
curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &res_len);
|
||||
|
||||
buffer = malloc(res_len);
|
||||
|
||||
res = curl_easy_recv(curl, buffer, res_len, 0);
|
||||
|
||||
if (res != CURLE_OK) {
|
||||
fprintf(stderr, "curl_easy_recv() failed with error: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
return "1";
|
||||
}
|
||||
|
||||
printf("Response body: %s\n", buffer);
|
||||
|
||||
free(buffer);
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
return mb_id;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int mb_conf, opt;
|
||||
const char *m_dir, *ftv_api_key;
|
||||
|
||||
m_dir = get_conf_str("dir");
|
||||
mb_conf = get_conf_int("confidence");
|
||||
ftv_api_key = get_conf_str("api_key");
|
||||
|
||||
while ((opt = getopt(argc, argv, "ps:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'p':
|
||||
print_conf(m_dir, mb_conf, ftv_api_key);
|
||||
break;
|
||||
case 's':
|
||||
printf("This doesn't do anything yet but you searched for %s\n", optarg);
|
||||
break;
|
||||
default:
|
||||
printf("So long and thanks for all the fish.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
get_mb_id("The Beatles");
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import configparser
|
||||
import os
|
||||
from time import sleep
|
||||
import dir_activities
|
||||
import api_calls
|
||||
|
||||
config = configparser.ConfigParser()
|
||||
if os.path.exists('config.ini'):
|
||||
conf_path = 'config.ini'
|
||||
else:
|
||||
conf_path = os.path.join(os.path.expanduser("~"), ".local/share/get_artist_art/config.ini")
|
||||
|
||||
config.read(conf_path)
|
||||
|
||||
music_path = config['music']['dir']
|
||||
ftv_api_key = config['fanart_tv']['api_key']
|
||||
mb_confidence = int(config['musicbrainz']['confidence'])
|
||||
|
||||
count = 1
|
||||
dir_list = dir_activities.get_all(music_path)
|
||||
dir_list.sort()
|
||||
for artist in dir_list:
|
||||
artist_path = os.path.join(music_path, artist)
|
||||
if not(dir_activities.has_artist_art(artist_path)):
|
||||
# print(dir_activities.has_artist_art(artist_path))
|
||||
print(str(count) + ": " + artist.strip('_'))
|
||||
try:
|
||||
ftv_response = False
|
||||
mb_exit = False
|
||||
while not mb_exit:
|
||||
found_status, mb_id, mb_exit = api_calls.get_mb_id(artist, mb_confidence)
|
||||
# print("Getting ", artist_image)
|
||||
if found_status:
|
||||
while not ftv_response:
|
||||
ftv_response = api_calls.get_image(mb_id, ftv_api_key, artist_path)
|
||||
# print(ftv_response)
|
||||
else:
|
||||
print(f"{artist} returned no results.")
|
||||
# api_requests.get_art(artist_image, artist, music_path)
|
||||
except Exception as e:
|
||||
print("Artist or art not found.")
|
||||
print(e)
|
||||
print("---------")
|
||||
count += 1
|
||||
#sleep(1)
|
Loading…
x
Reference in New Issue
Block a user