-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 2167b5d
Showing
83 changed files
with
328 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
root = true | ||
|
||
[*] | ||
indent_style = space | ||
indent_size = 4 | ||
end_of_line = lf | ||
charset = utf-8 | ||
trim_trailing_whitespace = true | ||
insert_final_newline = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
CLIENT_ID="YOUR_CLIENT_ID" | ||
CLIENT_SECRET="YOUR_CLIENT_SECRET" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
name: Optimize and Deploy | ||
|
||
on: | ||
push: | ||
branches: | ||
- main | ||
|
||
jobs: | ||
optimize: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Checkout repository | ||
uses: actions/checkout@v3 | ||
|
||
- name: Install dependencies | ||
run: | | ||
sudo apt-get update | ||
sudo apt-get install -y webp librsvg2-bin | ||
- name: Optimization | ||
run: | | ||
chmod +x optimize.sh | ||
./optimize.sh -i src/albums -h 600 -q 100 -o out | ||
./optimize.sh -i src/artists -h 300 -q 100 -o out | ||
- name: Deploy | ||
run: | | ||
sudo chown -R $(whoami):$(whoami) . | ||
git config --global user.email "[email protected]" | ||
git config --global user.name "$GITHUB_ACTOR" | ||
cp -r out/* /tmp | ||
cd /tmp | ||
git init | ||
git branch -M gh-pages | ||
git add . | ||
git commit -m "Optimize images" | ||
git remote add origin "https://$GITHUB_ACTOR:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY" | ||
git push -f origin gh-pages |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
.env | ||
venv |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
import os | ||
import re | ||
import requests | ||
from unidecode import unidecode | ||
|
||
from dotenv import load_dotenv | ||
load_dotenv() | ||
|
||
client_id = os.getenv('CLIENT_ID') | ||
client_secret = os.getenv('CLIENT_SECRET') | ||
|
||
auth_response = requests.post('https://accounts.spotify.com/api/token', { | ||
'grant_type': 'client_credentials', | ||
'client_id': client_id, | ||
'client_secret': client_secret, | ||
}) | ||
|
||
auth_response_data = auth_response.json() | ||
|
||
try: | ||
access_token = auth_response_data['access_token'] | ||
except KeyError: | ||
print('Authentication failed.') | ||
exit(1) | ||
|
||
headers = { | ||
'Authorization': f'Bearer {access_token}', | ||
} | ||
|
||
|
||
def main(): | ||
while True: | ||
print('1 - Track') | ||
print('2 - Artist') | ||
print('3 - Exit') | ||
|
||
try: | ||
option = int(input('Option: ')) | ||
except ValueError: | ||
print('Invalid option') | ||
continue | ||
|
||
match option: | ||
case 1: | ||
download_album_image(input('Track: '), 'albums') | ||
case 2: | ||
download_artist_image(input('Artist: '), 'artists') | ||
case 3: | ||
exit(0) | ||
case _: | ||
print('Invalid option') | ||
|
||
|
||
def download_album_image(track_name, output_dir): | ||
search_response = requests.get( | ||
'https://api.spotify.com/v1/search', | ||
headers=headers, | ||
params={ | ||
'q': track_name, | ||
'type': 'track', | ||
'limit': 1 | ||
} | ||
) | ||
|
||
search_data = search_response.json() | ||
|
||
try: | ||
album = search_data['tracks']['items'][0]['album'] | ||
image_url = album['images'][0]['url'] | ||
album_name = album['name'] | ||
except (KeyError, IndexError): | ||
print(f'No album image found for track: {track_name}') | ||
return | ||
|
||
filename = jpeg_filename(album_name) | ||
save_path = os.path.join(output_dir, filename) | ||
|
||
if not os.path.exists(save_path): | ||
response = requests.get(image_url) | ||
if response.status_code == 200: | ||
os.makedirs(output_dir, exist_ok=True) | ||
with open(save_path, 'wb') as file: | ||
file.write(response.content) | ||
print(f'{filename} download completed.') | ||
else: | ||
print(f'Failed to download image for track: {track_name}') | ||
else: | ||
print(f'{filename} already exists.') | ||
|
||
|
||
def download_artist_image(artist_name, output_dir): | ||
filename = jpeg_filename(artist_name) | ||
save_path = os.path.join(output_dir, filename) | ||
|
||
if not os.path.exists(save_path): | ||
search_response = requests.get( | ||
'https://api.spotify.com/v1/search', | ||
headers=headers, | ||
params={ | ||
'q': artist_name, | ||
'type': 'artist', | ||
'limit': 1 | ||
} | ||
) | ||
|
||
search_data = search_response.json() | ||
|
||
try: | ||
image_url = search_data['artists']['items'][0]['images'][0]['url'] | ||
artist_name = search_data['artists']['items'][0]['name'] | ||
except (KeyError, IndexError): | ||
print(f'No image found for artist: {artist_name}') | ||
return | ||
|
||
response = requests.get(image_url) | ||
if response.status_code == 200: | ||
os.makedirs(output_dir, exist_ok=True) | ||
with open(save_path, 'wb') as file: | ||
file.write(response.content) | ||
print(f'{filename} download completed.') | ||
else: | ||
print(f'Failed to download image for artist: {artist_name}') | ||
else: | ||
print(f'{filename} already exists.') | ||
|
||
|
||
def jpeg_filename(name): | ||
return f'{snake_case(name)}.jpeg' | ||
|
||
|
||
def snake_case(text): | ||
text = unidecode(text.strip().lower()) | ||
text = re.sub(r'\s+', '_', text) | ||
return re.sub(r'[^\w_]', '', text) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
#!/bin/bash | ||
|
||
TEMP_DIR=temp | ||
INPUT_DIR=src | ||
OUTPUT_DIR=out | ||
|
||
WIDTH=0 | ||
HEIGHT=300 | ||
IMAGE_QUALITY=100 | ||
|
||
while getopts "i:o:w:h:q:" opt; do | ||
case ${opt} in | ||
i ) | ||
INPUT_DIR=$OPTARG | ||
;; | ||
o ) | ||
OUTPUT_DIR=$OPTARG | ||
;; | ||
w ) | ||
WIDTH=$OPTARG | ||
;; | ||
h ) | ||
HEIGHT=$OPTARG | ||
;; | ||
q ) | ||
IMAGE_QUALITY=$OPTARG | ||
;; | ||
\? ) | ||
echo "Usage: ./optimize.sh [-i input_dir] [-o output_dir] [-w width] [-h height] [-q image_quality]" | ||
exit 1 | ||
;; | ||
esac | ||
done | ||
|
||
rm -rf "$TEMP_DIR" | ||
mkdir -p "$OUTPUT_DIR" | ||
|
||
mkdir "$TEMP_DIR" | ||
cp -r "$INPUT_DIR"/* "$TEMP_DIR" | ||
|
||
optimize_image() { | ||
local input_file="$1" | ||
local output_file="$2" | ||
cwebp -q "$IMAGE_QUALITY" -m 6 -sharpness 0 -noalpha -resize "$WIDTH" "$HEIGHT" -quiet "$input_file" -o "$output_file" | ||
} | ||
|
||
convert_svg_to_webp() { | ||
local input_file="$1" | ||
local output_file="$2" | ||
local temp_png="${output_file}.png" | ||
rsvg-convert -o "$temp_png" "$input_file" | ||
optimize_image "$temp_png" "$output_file" | ||
rm "$temp_png" | ||
} | ||
|
||
optimize_webp() { | ||
local input_file="$1" | ||
local output_file="$2" | ||
local temp_output="${output_file}.temp" | ||
|
||
if webpmux -info "$input_file" 2>&1 | grep -q "No. of frames: 1"; then | ||
optimize_image "$input_file" "$temp_output" | ||
else | ||
gif2webp -q "$IMAGE_QUALITY" "$input_file" -o "$temp_output" | ||
fi | ||
|
||
local original_size=$(stat -c %s "$input_file") | ||
local new_size=$(stat -c %s "$temp_output") | ||
|
||
if (( new_size < original_size )); then | ||
mv "$temp_output" "$output_file" | ||
echo "Optimized: $input_file -> $output_file (reduced size from $original_size to $new_size)" | ||
else | ||
rm "$temp_output" | ||
cp "$input_file" "$output_file" | ||
echo "Copied without change: $input_file -> $output_file" | ||
fi | ||
} | ||
|
||
file_exists_in_output() { | ||
local input_file="$1" | ||
local filename=$(basename "$input_file") | ||
[ -f "$OUTPUT_DIR/$filename" ] | ||
} | ||
|
||
process_images() { | ||
for img in "$TEMP_DIR"/*.{jpg,jpeg,png}; do | ||
[ -f "$img" ] || continue | ||
filename=$(basename "$img" .${img##*.}) | ||
output_file="$OUTPUT_DIR/$filename.webp" | ||
if ! file_exists_in_output "$output_file"; then | ||
optimize_image "$img" "$output_file" | ||
echo "Converted: $img -> $output_file" | ||
fi | ||
done | ||
} | ||
|
||
process_svgs() { | ||
for svg in "$TEMP_DIR"/*.svg; do | ||
[ -f "$svg" ] || continue | ||
filename=$(basename "$svg" .svg) | ||
output_file="$OUTPUT_DIR/$filename.webp" | ||
if ! file_exists_in_output "$output_file"; then | ||
convert_svg_to_webp "$svg" "$output_file" | ||
echo "Converted: $svg -> $output_file" | ||
fi | ||
done | ||
} | ||
|
||
process_webps() { | ||
for webp in "$TEMP_DIR"/*.webp; do | ||
[ -f "$webp" ] || continue | ||
filename=$(basename "$webp" .webp) | ||
output_file="$OUTPUT_DIR/$filename.webp" | ||
if ! file_exists_in_output "$output_file"; then | ||
optimize_webp "$webp" "$output_file" | ||
fi | ||
done | ||
} | ||
|
||
process_images | ||
process_svgs | ||
process_webps | ||
|
||
find "$TEMP_DIR" -type f ! -name '*.jpg' ! -name '*.jpeg' ! -name '*.png' ! -name '*.svg' -exec cp -v {} "$OUTPUT_DIR/" \; | ||
|
||
files_count=$(find "$INPUT_DIR" -type f | wc -l) | ||
echo "$files_count files in $INPUT_DIR" | ||
|
||
total=$(find "$OUTPUT_DIR" -type f | wc -l) | ||
echo "Total: $total files in $OUTPUT_DIR" | ||
|
||
rm -rf "$TEMP_DIR" | ||
|
||
echo "Optimization completed." |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
requests==2.32.3 | ||
unidecode==1.3.8 | ||
python-dotenv==1.0.1 |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+103 KB
src/albums/divinely_uninspired_to_a_hellish_extent_extended_edition.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.