From aec0eb4c7f20cb6d99ccb0c6bcf407d16e1f14cd Mon Sep 17 00:00:00 2001 From: riwiwa Date: Sat, 19 Jul 2025 23:42:33 -0700 Subject: [PATCH] added unzip functionality, kinda buggy tho --- README.md | 1 + muzi.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 76 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 5c0f905..530a523 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ Self hosted music listening statistics ### Dependencies: - cJSON (https://github.com/DaveGamble/cJSON) +- libzip (https://libzip.org/) ### plans: - Ability to import all listening statistics and scrobbles from lastfm, spotify, apple music diff --git a/muzi.c b/muzi.c index 1a78aa6..4913030 100644 --- a/muzi.c +++ b/muzi.c @@ -2,16 +2,27 @@ #include #include #include +#include #include +#include +#include // TODO: -// - unzip given .zip archives of spotify data +// - unzip a given .zip archive of spotify data to a directory +// - for each json file in the directory { +// - for each json entry { +// - add entry to postgresql db +// } +// } +// // - web ui -// - enter all json data into postgresql db automatically // - sql tables: "full history", "artists", "songs", "albums" (see ipad) -int main(void) { - FILE *fp = fopen("test.json", "r"); +int extract(const char *path); +int get_artist_plays(void); + +int get_artist_plays(void) { + FILE *fp = fopen("/home/r/dl/spotify-data/rm35@gm - Spotify Extended Streaming History/Streaming_History_Audio_2020-2021_4.json", "r"); if(fp == NULL) { printf("Error while opening file\n"); return 1; @@ -39,7 +50,7 @@ int main(void) { cJSON *track = NULL; int i = 0; - char artist[] = "Test"; + char artist[] = ""; cJSON_ArrayForEach(track, json) { cJSON *trackName = cJSON_GetObjectItemCaseSensitive(track, "master_metadata_album_artist_name"); if(cJSON_IsString(trackName)) { @@ -55,3 +66,62 @@ int main(void) { free(buffer); return 0; } + +int extract(const char *path) { + zip_t *za; + int err; + if((za = zip_open(path, 0, &err)) == NULL) { + zip_error_t error; + zip_error_init_with_code(&error, err); + fprintf(stderr, "Error opening zip archive: %s\n", zip_error_strerror(&error)); + zip_error_fini(&error); + return 1; + } + + int archived_files = zip_get_num_entries(za, ZIP_FL_UNCHANGED); + + for (int i = 0; i < archived_files; i++) { + struct zip_stat st; + if (zip_stat_index(za, i, 0, &st) < 0) { + fprintf(stderr, "Error getting file info for index %d\n", i); + continue; + } + + // Handle directories + if (st.name[strlen(st.name) - 1] == '/') { + mkdir(st.name, 0755); // Create directory if it doesn't exist + continue; + } + + // Open file in archive + zip_file_t *zf = zip_fopen_index(za, i, 0); + if (!zf) { + fprintf(stderr, "Error opening file in zip: %s\n", st.name); + continue; + } + + // Create output file + FILE *outfile = fopen(st.name, "w+"); + if (!outfile) { + fprintf(stderr, "Error creating output file: %s\n", st.name); + zip_fclose(zf); + continue; + } + + // Read and write data + char buffer[4096]; + zip_int64_t bytes_read; + while ((bytes_read = zip_fread(zf, buffer, sizeof(buffer))) > 0) { + fwrite(buffer, 1, bytes_read, outfile); + } + + // Close files + fclose(outfile); + zip_fclose(zf); + } + return 0; +} + +int main(void) { + extract("archive.zip"); +}