dvd files
wget https://git.christianimmanuel.de/games/dvd/archive/dvd.tar.gzmain.c raw
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "imdb_search.h"
#include "upcitemdb.h"
// ANSI color codes
#define RESET "\033[0m"
#define RED "\033[31m"
#define GREEN "\033[32m"
#define YELLOW "\033[33m"
#define BLUE "\033[34m"
#define MAGENTA "\033[35m"
#define CYAN "\033[36m"
#define WHITE "\033[37m"
#define PRINT_HEADER(title) \
printf(MAGENTA "\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n" RESET); \
printf(CYAN " %s\n" RESET, title); \
printf(MAGENTA "┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅\n" RESET);
#define PRINT_HEADER_SMALL(title) \
printf(MAGENTA "\n–––––––––––––––––––––––––––––––––––––––––\n" RESET); \
printf(CYAN " %s\n" RESET, title); \
#define DATABASE_FILE "selected_results.db"
typedef struct {
SearchResult result;
Websearch_st web_data;
char file_path[256];
char search_query[256];
char barcode[14];
} DataStruct;
void clearInputBuffer() {
fseek(stdin,0,SEEK_END);
fflush(stdout);
}
void append_to_database(const char *entry) {
FILE *db_file = fopen(DATABASE_FILE, "a");
if (db_file == NULL) {
fprintf(stderr, "Failed to open database file for writing.\n");
return;
}
fprintf(db_file, "%s\n", entry);
fclose(db_file);
}
// Helper function to check if a string consists of only digits
int is_numeric(const char *str) {
if (str == NULL) {
return 0;
}
for (int i = 0; str[i] != '\0'; i++) {
if (!isdigit((unsigned char)str[i])) {
return 0; // Return false if a non-digit character is found
}
}
return 1; // Return true if all characters are digits
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
// Ensure directory exists
void ensure_directory_exists(const char *dir) {
struct stat st = {0};
if (stat(dir, &st) == -1) {
mkdir(dir, 0700);
}
}
// Function implementations
DataStruct createDataStruct(SearchResult *result, Websearch_st *web_data, char search_query[256], char barcode[14]) {
barcode[13] = '\0';
DataStruct data;
snprintf(data.file_path, sizeof(data.file_path), "local/%s.txt", result->tconst);
data.result = *result;
data.web_data = *web_data;
strncpy(data.search_query, search_query, sizeof(data.search_query) - 1);
strncpy(data.barcode, barcode, 13);
data.barcode[13] = '\0';
return data;
}
void writeStructToFile(DataStruct *data) {
char file_path[512];
snprintf(file_path, sizeof(file_path), "local/%s.txt", data->result.tconst);
ensure_directory_exists("local");
FILE *file = fopen(file_path, "w");
if (!file) {
perror("Failed to open file for writing");
return;
}
// Write SearchResult data
fprintf(file, "tconst=%s\n", data->result.tconst);
fprintf(file, "primaryTitle=%s\n", data->result.primaryTitle);
fprintf(file, "selected=%s\n", data->result.selected);
fprintf(file, "selected_id=%d\n", data->result.selected_id);
fprintf(file, "score=%.2f\n", data->result.score);
fprintf(file, "barcode=%s\n", data->barcode);
fprintf(file, "searchQuery=%s\n", data->search_query);
// Write associated TitleEntry data
if (data->result.title) {
TitleEntry *title = data->result.title;
fprintf(file, "\n[TitleEntry]\n");
fprintf(file, "tconst=%s\n", title->tconst);
fprintf(file, "primaryTitle=%s\n", title->primaryTitle);
fprintf(file, "originalTitle=%s\n", title->originalTitle);
fprintf(file, "titleType=%s\n", title->titleType);
fprintf(file, "startYear=%d\n", title->startYear);
fprintf(file, "endYear=%d\n", title->endYear);
fprintf(file, "isAdult=%d\n", title->isAdult);
fprintf(file, "runtimeMinutesgenres=%s\n", title->runtimeMinutesgenres);
if (title->ratingInfo) {
fprintf(file, "\n[RatingInfo]\n");
fprintf(file, "averageRating=%.1f\n", title->ratingInfo->averageRating);
fprintf(file, "numVotes=%d\n", title->ratingInfo->numVotes);
}
}
// Write Websearch_st data
fprintf(file, "\n[WebSearch]\n");
fprintf(file, "title=%s\n", data->web_data.title);
fprintf(file, "lowestRecordedPrice=%.2f\n", data->web_data.lowest_recorded_price);
fprintf(file, "highestRecordedPrice=%.2f\n", data->web_data.highest_recorded_price);
fprintf(file, "category=%s\n", data->web_data.category);
fclose(file);
printf("\nSaved result to " WHITE "%s\n" RESET, file_path);
}
// Function to read data from a file and populate DataStruct
int readStructFromFile(const char *file_path, DataStruct *data) {
FILE *file = fopen(file_path, "r");
if (!file) {
perror("Failed to open file for reading");
return -1; // Return -1 to indicate error
}
char line[512];
TitleEntry *title = NULL;
Websearch_st *web_data = NULL;
while (fgets(line, sizeof(line), file)) {
// Remove newline at the end of the line
line[strcspn(line, "\n")] = '\0';
// Read the SearchResult fields
if (strncmp(line, "tconst=", 7) == 0) {
strncpy(data->result.tconst, line + 7, sizeof(data->result.tconst) - 1);
} else if (strncmp(line, "primaryTitle=", 13) == 0) {
strncpy(data->result.primaryTitle, line + 13, sizeof(data->result.primaryTitle) - 1);
} else if (strncmp(line, "selected=", 9) == 0) {
strncpy(data->result.selected, line + 9, sizeof(data->result.selected) - 1);
} else if (strncmp(line, "selected_id=", 12) == 0) {
data->result.selected_id = atoi(line + 12);
} else if (strncmp(line, "score=", 6) == 0) {
data->result.score = atof(line + 6);
} else if (strncmp(line, "barcode=", 8) == 0) {
strncpy(data->barcode, line + 8, sizeof(data->barcode) - 1);
} else if (strncmp(line, "searchQuery=", 12) == 0) {
strncpy(data->search_query, line + 12, sizeof(data->search_query) - 1);
}
// Read the TitleEntry fields (if they exist)
if (strncmp(line, "[TitleEntry]", 12) == 0) {
title = malloc(sizeof(TitleEntry)); // Allocate memory for TitleEntry
memset(title, 0, sizeof(TitleEntry)); // Initialize the TitleEntry struct
} else if (title) {
if (strncmp(line, "tconst=", 7) == 0) {
strncpy(title->tconst, line + 7, sizeof(title->tconst) - 1);
} else if (strncmp(line, "primaryTitle=", 13) == 0) {
strncpy(title->primaryTitle, line + 13, sizeof(title->primaryTitle) - 1);
} else if (strncmp(line, "originalTitle=", 14) == 0) {
strncpy(title->originalTitle, line + 14, sizeof(title->originalTitle) - 1);
} else if (strncmp(line, "titleType=", 10) == 0) {
strncpy(title->titleType, line + 10, sizeof(title->titleType) - 1);
} else if (strncmp(line, "startYear=", 10) == 0) {
title->startYear = atoi(line + 10);
} else if (strncmp(line, "endYear=", 8) == 0) {
title->endYear = atoi(line + 8);
} else if (strncmp(line, "isAdult=", 8) == 0) {
title->isAdult = atoi(line + 8);
} else if (strncmp(line, "runtimeMinutesgenres=", 21) == 0) {
strncpy(title->runtimeMinutesgenres, line + 21, sizeof(title->runtimeMinutesgenres) - 1);
} else if (strncmp(line, "[RatingInfo]", 12) == 0) {
// Allocate memory for RatingInfo
title->ratingInfo = malloc(sizeof(RatingInfo));
memset(title->ratingInfo, 0, sizeof(RatingInfo));
} else if (title->ratingInfo) {
if (strncmp(line, "averageRating=", 14) == 0) {
title->ratingInfo->averageRating = atof(line + 14);
} else if (strncmp(line, "numVotes=", 9) == 0) {
title->ratingInfo->numVotes = atoi(line + 9);
}
}
}
// Read the Websearch_st fields
if (strncmp(line, "[WebSearch]", 11) == 0) {
web_data = malloc(sizeof(Websearch_st)); // Allocate memory for Websearch_st
memset(web_data, 0, sizeof(Websearch_st)); // Initialize the Websearch_st struct
} else if (web_data) {
if (strncmp(line, "title=", 6) == 0) {
strncpy(web_data->title, line + 6, sizeof(web_data->title) - 1);
} else if (strncmp(line, "lowestRecordedPrice=", 20) == 0) {
web_data->lowest_recorded_price = atof(line + 20);
} else if (strncmp(line, "highestRecordedPrice=", 21) == 0) {
web_data->highest_recorded_price = atof(line + 21);
} else if (strncmp(line, "category=", 9) == 0) {
strncpy(web_data->category, line + 9, sizeof(web_data->category) - 1);
}
}
}
// Close the file
fclose(file);
// Assign the read values to the DataStruct object
if (title) {
data->result.title = title; // Link the title data
}
if (web_data) {
data->web_data = *web_data; // Copy the web data into the struct
}
return 0; // Return 0 to indicate success
}
void printDataStruct(DataStruct *data) {
if (!data || !data->result.title || strlen(data->result.tconst) == 0 || strlen(data->result.primaryTitle) == 0){
printf("No valid dvd found!\n");
return;
}
printf(MAGENTA "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n");
printf(MAGENTA "┃ " WHITE "%s\n" RESET, data->result.primaryTitle);
if (strlen(data->result.selected) > 0 && data->result.title->languageCount > 0 && data->result.selected_id < data->result.title->languageCount)
printf(MAGENTA "┃ " WHITE "%s: " WHITE "%s\n" RESET, data->result.selected, data->result.title->languages[data->result.selected_id].title);
printf(MAGENTA "┠────────────────────────────────────────────\n" RESET);
// Year, ID, Genres
if (data->result.title) {
printf(MAGENTA "┃ " YELLOW "Primary title: " WHITE "%s\n",
data->result.title->primaryTitle);
printf(MAGENTA "┃ " YELLOW "Type: " WHITE "%s" YELLOW ", Genre: " WHITE "%s\n",
data->result.title->titleType,
data->result.title->runtimeMinutesgenres);
printf(MAGENTA "┃ " YELLOW "Year: " WHITE "%d-%d" YELLOW ", Adult: " WHITE "%d" YELLOW " Languages: %d\n",
data->result.title->startYear, data->result.title->endYear,
data->result.title->isAdult,
data->result.title->languageCount);
}
// Type, Rank, Selected
printf(MAGENTA "┃ " YELLOW "tconst: " WHITE "%s" CYAN ", Score: " WHITE "%.2f" YELLOW
", Selected: " WHITE "%s" YELLOW " –> " WHITE "%d\n" RESET,
data->result.tconst,
data->result.score,
data->result.selected,
data->result.selected_id);
// Rating and Votes
if (data->result.title && data->result.title->ratingInfo != NULL) {
printf(MAGENTA "┃ " YELLOW "Rating: " CYAN "%.1f" YELLOW ", Votes: " WHITE "%d\n" RESET,
data->result.title->ratingInfo->averageRating,
data->result.title->ratingInfo->numVotes);
}
printf(MAGENTA "┠────────────────────────────────────────────\n" RESET);
// Web Data
printf(MAGENTA "┃ " CYAN "Web Search:\n" RESET);
printf(MAGENTA "┃ " YELLOW "Title: " RESET "%s\n", data->web_data.title);
printf(MAGENTA "┃ " YELLOW "Price: " RESET "%.2f-%.2f\n",
data->web_data.lowest_recorded_price,
data->web_data.highest_recorded_price);
printf(MAGENTA "┃ " YELLOW "Category: " RESET "%s\n", data->web_data.category);
printf(MAGENTA "┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n" RESET);
}
#include <sys/stat.h> // For stat
#include <dirent.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int loadLocalMovies(DataStruct **movies, const char *directory) {
struct dirent *entry;
DIR *dp = opendir(directory);
if (!dp) {
perror("Failed to open directory");
return -1;
}
int count = 0;
size_t capacity = 10; // Initial capacity for dynamic allocation
*movies = malloc(capacity * sizeof(DataStruct));
if (!*movies) {
perror("Failed to allocate memory for movies array");
closedir(dp);
return -1;
}
while ((entry = readdir(dp)) != NULL) {
// Skip "." and ".." entries
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
continue;
}
char file_path[512];
snprintf(file_path, sizeof(file_path), "%s/%s", directory, entry->d_name);
// Use stat to determine if it is a regular file
struct stat file_stat;
if (stat(file_path, &file_stat) != 0) {
perror("Failed to stat file");
continue;
}
if (S_ISREG(file_stat.st_mode)) { // Regular file
FILE *file = fopen(file_path, "r");
if (!file) {
perror("Failed to open file for reading");
continue;
}
DataStruct data;
memset(&data, 0, sizeof(DataStruct));
// Parse the file contents into a DataStruct
char line[512];
TitleEntry *title = NULL;
Websearch_st *web_data = NULL;
while (fgets(line, sizeof(line), file)) {
// Remove newline at the end of the line
line[strcspn(line, "\n")] = '\0';
// Read the SearchResult fields
if (strncmp(line, "tconst=", 7) == 0) {
strncpy(data.result.tconst, line + 7, sizeof(data.result.tconst) - 1);
} else if (strncmp(line, "primaryTitle=", 13) == 0) {
strncpy(data.result.primaryTitle, line + 13, sizeof(data.result.primaryTitle) - 1);
} else if (strncmp(line, "selected=", 9) == 0) {
strncpy(data.result.selected, line + 9, sizeof(data.result.selected) - 1);
} else if (strncmp(line, "selected_id=", 12) == 0) {
data.result.selected_id = atoi(line + 12);
} else if (strncmp(line, "score=", 6) == 0) {
data.result.score = atof(line + 6);
} else if (strncmp(line, "barcode=", 8) == 0) {
strncpy(data.barcode, line + 8, sizeof(data.barcode) - 1);
} else if (strncmp(line, "searchQuery=", 12) == 0) {
strncpy(data.search_query, line + 12, sizeof(data.search_query) - 1);
}
// Handle TitleEntry section
if (strncmp(line, "[TitleEntry]", 12) == 0) {
title = malloc(sizeof(TitleEntry));
memset(title, 0, sizeof(TitleEntry));
} else if (title) {
if (strncmp(line, "tconst=", 7) == 0) {
strncpy(title->tconst, line + 7, sizeof(title->tconst) - 1);
} else if (strncmp(line, "primaryTitle=", 13) == 0) {
strncpy(title->primaryTitle, line + 13, sizeof(title->primaryTitle) - 1);
} else if (strncmp(line, "originalTitle=", 14) == 0) {
strncpy(title->originalTitle, line + 14, sizeof(title->originalTitle) - 1);
} else if (strncmp(line, "titleType=", 10) == 0) {
strncpy(title->titleType, line + 10, sizeof(title->titleType) - 1);
} else if (strncmp(line, "startYear=", 10) == 0) {
title->startYear = atoi(line + 10);
} else if (strncmp(line, "endYear=", 8) == 0) {
title->endYear = atoi(line + 8);
} else if (strncmp(line, "isAdult=", 8) == 0) {
title->isAdult = atoi(line + 8);
} else if (strncmp(line, "runtimeMinutesgenres=", 21) == 0) {
strncpy(title->runtimeMinutesgenres, line + 21, sizeof(title->runtimeMinutesgenres) - 1);
} else if (strncmp(line, "[RatingInfo]", 12) == 0) {
title->ratingInfo = malloc(sizeof(RatingInfo));
memset(title->ratingInfo, 0, sizeof(RatingInfo));
} else if (title->ratingInfo) {
if (strncmp(line, "averageRating=", 14) == 0) {
title->ratingInfo->averageRating = atof(line + 14);
} else if (strncmp(line, "numVotes=", 9) == 0) {
title->ratingInfo->numVotes = atoi(line + 9);
}
}
}
// Handle Websearch_st section
if (strncmp(line, "[WebSearch]", 11) == 0) {
web_data = malloc(sizeof(Websearch_st));
memset(web_data, 0, sizeof(Websearch_st));
} else if (web_data) {
if (strncmp(line, "title=", 6) == 0) {
strncpy(web_data->title, line + 6, sizeof(web_data->title) - 1);
} else if (strncmp(line, "lowestRecordedPrice=", 20) == 0) {
web_data->lowest_recorded_price = atof(line + 20);
} else if (strncmp(line, "highestRecordedPrice=", 21) == 0) {
web_data->highest_recorded_price = atof(line + 21);
} else if (strncmp(line, "category=", 9) == 0) {
strncpy(web_data->category, line + 9, sizeof(web_data->category) - 1);
}
}
}
// Close the file
fclose(file);
// Link TitleEntry and Websearch_st to the main DataStruct
if (title) {
data.result.title = title;
}
if (web_data) {
data.web_data = *web_data;
}
// Add DataStruct to the array
if (count >= capacity) {
capacity *= 2;
DataStruct *new_movies = realloc(*movies, capacity * sizeof(DataStruct));
if (!new_movies) {
perror("Failed to reallocate memory for movies array");
free(*movies);
closedir(dp);
return -1;
}
*movies = new_movies;
}
(*movies)[count++] = data;
}
}
closedir(dp);
return count;
}
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FILENAME "playlists.txt"
#define MAX_ID_LENGTH 14
#define MAX_NAME_LENGTH 256
#define MAX_LINE 512
// Function to check if playlist ID exists
int isValidPlaylistID(const char *playlist_id) {
FILE *file = fopen(FILENAME, "r");
if (!file) {
perror(RED "Error opening playlist file" RESET);
return 0; // File not found or cannot be opened
}
char line[MAX_LINE];
while (fgets(line, sizeof(line), file)) {
char id[14], name[257]; // Buffers for ID and name
sscanf(line, "%13[^|]|%256[^\n]", id, name); // Parse ID and name
if (strcmp(id, playlist_id) == 0) {
fclose(file);
return 1; // ID found in file
}
}
fclose(file);
return 0; // ID not found in file
}
// Function to display all playlists
void list_playlists() {
FILE *file = fopen(FILENAME, "r");
if (!file) {
perror(RED "Error opening file" RESET);
return;
}
printf(GREEN "Playlists:\n" RESET);
printf(BLUE "----------------------------------------\n" RESET);
char line[MAX_LINE];
int count = 0;
while (fgets(line, sizeof(line), file)) {
char id[MAX_ID_LENGTH], name[257]; // Increase ID buffer size
if (sscanf(line, "%13[^|]|%256[^\n]", id, name) == 2) { // Parse ID and name
printf(CYAN "[%d] " RESET, ++count);
printf(YELLOW "ID: " RESET "%s\n", id);
printf(MAGENTA " Name: " WHITE "%s\n" RESET, name);
printf(BLUE "----------------------------------------\n" RESET);
}
}
if (count == 0) {
printf(RED "No playlists found.\n" RESET);
}
fclose(file);
}
// Function to add a playlist
void add_playlist(char id[14]) {
printf("[q] quit\n");
char name[MAX_NAME_LENGTH] = "\0";
// Display existing playlists (placeholder)
printf("Existing Playlists:\n");
// list_playlists(); // Uncomment this if you have a function to list playlists
list_playlists();
// Input Playlist ID
while (1) {
printf("Enter new Playlist ID (up to 13 characters): ");
fgets(id, 14, stdin); // Read ID (13 + null terminator)
id[strcspn(id, "\n")] = 0; // Remove trailing newline
if (strlen(id) == 0) {
printf("Error: Playlist ID cannot be empty.\n");
continue;
}
if (id[0] == 'q') return; // User requested to quit
if (!isValidPlaylistID(id)) {
break; // Valid ID, exit loop
} else {
printf("Error: Playlist ID '%s' already exists. Please enter a different ID.\n", id);
}
}
// Input Playlist Name
while (1) {
printf("Enter Playlist Name (up to 256 characters): ");
fgets(name, MAX_NAME_LENGTH, stdin); // Read name
name[strcspn(name, "\n")] = 0; // Remove trailing newline
if (strlen(name) == 0) {
printf("Error: Playlist Name cannot be empty.\n");
continue;
}
if (name[0] == 'q') return; // User requested to quit
break; // Valid name, exit loop
}
// Write to File
FILE *file = fopen(FILENAME, "a"); // Open file in append mode
if (!file) {
perror("Error opening file");
return;
}
fprintf(file, "%s|%s\n", id, name); // Write ID and name separated by '|'
fclose(file);
printf("Playlist '%s' added with ID '%s'.\n", name, id);
list_playlists();
}
// Function to remove a playlist by ID
void remove_playlist() {
char id[64];
list_playlists();
printf("Remove Playlist ID (up to 10 characters): ");
fgets(id, sizeof(id), stdin);
id[strcspn(id, "\n")] = 0; // Remove trailing newline
if (id[0] == 'q') return;
FILE *file = fopen(FILENAME, "r");
if (!file) {
perror("Error opening file");
return;
}
FILE *temp = fopen("temp.txt", "w"); // Temporary file for updated data
if (!temp) {
perror("Error creating temporary file");
fclose(file);
return;
}
char line[MAX_LINE];
int found = 0;
while (fgets(line, sizeof(line), file)) {
char line_id[11]; // ID buffer (10 + null terminator)
sscanf(line, "%10[^|]", line_id); // Extract the ID before the '|'
if (line_id[0] == 'q') return;
if (strcmp(line_id, id) != 0) {
fputs(line, temp); // Copy line to temp if ID doesn't match
} else {
found = 1;
}
}
fclose(file);
fclose(temp);
if (found) {
remove(FILENAME); // Delete the original file
rename("temp.txt", FILENAME); // Rename temp to original
printf("Playlist with ID '%s' removed.\n", id);
} else {
remove("temp.txt"); // Cleanup temp if no match found
printf("Playlist with ID '%s' not found.\n", id);
}
}
void listMovies(DataStruct* movies, int count) {
if (count > 0) {
printf(GREEN "Loaded %d movies from the local directory:\n" RESET, count);
for (int i = 0; i < count; i++) {
printf(CYAN "[%d] " RESET, i + 1);
printf(YELLOW "Title: " WHITE "%s\n" RESET, movies[i].result.primaryTitle);
printf(MAGENTA " ID: " RESET "%s\n", movies[i].result.tconst);
printf(RED "----------------------------------------\n" RESET);
}
} else {
printf(RED "No movies found in the local directory.\n" RESET);
}
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h> // For unlink()
int removeMovie(DataStruct *movies, int *movie_count) {
listMovies(movies, *movie_count);
if (*movie_count <= 0) {
printf("No movies available to remove.\n");
return -1;
}
char tconst[256];
printf("Enter the tconst of the movie to remove: ");
if (!fgets(tconst, sizeof(tconst), stdin)) {
perror("Failed to read input");
return -1;
}
// Remove trailing newline
tconst[strcspn(tconst, "\n")] = '\0';
int index = -1;
for (int i = 0; i < *movie_count; i++) {
if (strcmp(movies[i].result.tconst, tconst) == 0) {
index = i;
break;
}
}
if (index == -1) {
printf("No movie found with tconst '%s'.\n", tconst);
return -1;
}
// Delete the associated file
if (unlink(movies[index].file_path) == 0) {
printf("File '%s' deleted successfully.\n", movies[index].file_path);
} else {
perror("Failed to delete file");
// Continue removing from memory even if file deletion fails
}
// Shift elements in the array to remove the movie
for (int i = index; i < *movie_count - 1; i++) {
movies[i] = movies[i + 1];
}
(*movie_count)--;
printf("Movie with tconst '%s' removed from memory and file system.\n", tconst);
return 0;
}
// Function to get the playlist name from the file based on playlist ID
int getPlaylistName(const char* playlist_id, char playlist_name_p[256]) {
FILE *file = fopen("playlists.txt", "r");
if (!file) {
perror("Failed to open playlists file");
return 1; // Return NULL if file can't be opened
}
static char playlist_name[256]; // Static variable to hold playlist name
char line[512];
while (fgets(line, sizeof(line), file)) {
char id[128], name[256];
// Split the line into ID and name using the delimiter '|'
if (sscanf(line, "%127[^|]|%255[^\n]", id, name) == 2) {
printf("-- %s %s --\n", id, name);;
if (strcmp(id, playlist_id) == 0) {
// Found the matching ID, return the playlist name
strncpy(playlist_name, name, sizeof(playlist_name) - 1);
playlist_name[sizeof(playlist_name) - 1] = '\0'; // Null-terminate
fclose(file);
strcpy(playlist_name_p, playlist_name);
return 0;
}
}
}
fclose(file);
return 1; // Return NULL if ID not found
}
void displayPlaylistContent(DataStruct* movies, int movie_count, char playlist_id[11]) {
// Prompt user for playlist ID
if(strlen(playlist_id) == 0) {
list_playlists();
printf("Enter the " YELLOW "playlist ID" RESET ": ");
scanf("%s", playlist_id);
getchar(); // fix..
playlist_id[strcspn(playlist_id, "\n")] = '\0'; // Remove newline
}
// Construct playlist file path
char playlist_path[512];
snprintf(playlist_path, sizeof(playlist_path), "playlists/%s.txt", playlist_id);
// Open playlist file
FILE *file = fopen(playlist_path, "r");
if (!file) {
printf(RED "Error: Playlist with ID '%s' does not exist or could not be opened.\n" RESET, playlist_id);
return;
}
char playlist_name[256] = "\0";
getPlaylistName(playlist_id, playlist_name);
printf(CYAN "\n┌──────────────────────────────────────────────\n" RESET); \
printf(CYAN "│" RESET WHITE "%-24s " RESET "(%s)\n", playlist_name, playlist_id);
printf(CYAN "│" GREEN "------------------------------" RESET "\n");
char tconst[256];
int movie_found = 0;
// Read tconst entries from playlist file
while (fgets(tconst, sizeof(tconst), file)) {
tconst[strcspn(tconst, "\n")] = '\0'; // Remove newline
// Search for the movie in the provided movies array
int found = 0;
for (int i = 0; i < movie_count; i++) {
if (strcmp(movies[i].result.tconst, tconst) == 0) {
printf(CYAN "│" RESET "%3d. " WHITE "%20s" RESET " (" CYAN "%s" RESET ")\n",
i + 1,
movies[i].result.primaryTitle,
movies[i].result.tconst);
found = 1;
break;
}
}
// If the tconst isn't found in the movies array
if (!found) {
printf(CYAN "│" YELLOW "Warning: Movie with tconst '%s' not found in the movies list.\n" RESET, tconst);
}
movie_found = 1;
}
fclose(file);
if (!movie_found) {
printf(CYAN "│" RED "This playlist is empty or contains invalid entries.\n" RESET);
} else {
printf(CYAN "│" GREEN "------------------------------" RESET "\n");
}
printf(CYAN "└──────────────────────────────────────────────\n" RESET); \
}
void displayRelevantInfo(DataStruct *data) {
// Display Title Entry info with colors
printf(MAGENTA "\n┌──────────────────────────────────────────────\n" RESET);
if (data->result.title) {
TitleEntry *title = data->result.title;
printf(MAGENTA "│ " WHITE "%-28s" MAGENTA "%s %s" "\n" RESET,
title->primaryTitle,
title->languageCount > 0 && strlen(data->result.selected) > 0 ? " ||" : "",
title->languageCount > 0 && strlen(data->result.selected) > 0 ? title->languages[data->result.selected_id].title : "");
printf(MAGENTA "├──────────────────────────────────────────────\n" RESET);
printf(MAGENTA "│" RESET " Type: " WHITE "%s, " RESET "Rank: " WHITE "%.2f, " RESET "Rank_c: " WHITE "%d, " RESET "Selected: " WHITE "%s\n",
title->titleType, data->result.score, data->result.selected_id, data->result.selected);
// Display Year, ID, and Genres
printf(MAGENTA "│" RESET " Year: " WHITE "%d-%d, " RESET "ID: " WHITE "%s, " RESET "Genres: " WHITE "%s\n",
title->startYear, title->endYear, data->result.tconst, title->runtimeMinutesgenres);
// Optionally display RatingInfo if it exists
if (title->ratingInfo) {
printf(MAGENTA "│" RESET " Rating: " WHITE "%.1f, " RESET "Votes: " WHITE "%d\n",
title->ratingInfo->averageRating, title->ratingInfo->numVotes);
}
} else {
// Display Search Query and Barcode
printf(MAGENTA "│" RESET " Search Query: " WHITE "%s, " RESET "Barcode: " WHITE "%s\n", data->search_query, data->barcode);
}
printf(MAGENTA "└──────────────────────────────────────────────\n" RESET);
}
// Function to check if a tconst exists in a playlist
int is_movie_in_playlist(const char *playlist_id, const char *tconst) {
char filepath[256]; // Path to the playlist file
char line[14];
// Construct the filepath for the playlist
snprintf(filepath, sizeof(filepath), "playlists/%s.txt", playlist_id);
// Open the playlist file for reading
FILE *file = fopen(filepath, "r");
if (!file) {
perror("Error opening playlist file");
return 0; // Return 0 if the file doesn't exist
}
// Read the file line by line and check for the tconst
while (fgets(line, sizeof(line), file)) {
trim_whitespace(line);
if (strcmp(line, tconst) == 0) {
fclose(file);
return 1; // tconst found in the playlist
}
}
// Close the file and return 0 if tconst not found
fclose(file);
return 0;
}
DataStruct* findMovieByBarcode(DataStruct* movies, int movie_count, char barcode[14]) {
// Validate input and find the corresponding movie
for (int i = 0; i < movie_count; i++) {
if (strcmp(movies[i].barcode, barcode) == 0) {
return &movies[i];
}
}
return NULL;
}
DataStruct* findMovieByTconst(DataStruct* movies, int movie_count, char tconst[13]) {
// Validate input and find the corresponding movie
for (int i = 0; i < movie_count; i++) {
if (strcmp(movies[i].result.tconst, tconst) == 0) {
return &movies[i];
break;
}
}
return NULL;
}
void addMovieToPlaylist(DataStruct* movies, int movie_count, char tconst[13]) {
// List all movies
listMovies(movies, movie_count);
if (movie_count == 0) {
printf(RED "No movies available to add to a playlist.\n" RESET);
return;
}
char input[256] = "\0";
DataStruct *selected_movie = NULL;
while (!selected_movie) {
// Get barcode or tconst
if (strlen(tconst) == 0) {
while(strlen(input) == 0) {
printf("Enter the " YELLOW "barcode or tconst" RESET " of the movie: ");
fgets(input, sizeof(input), stdin);
trim_whitespace(input);
if (input[0] == 'q')
return;
}
} else {
strcpy(input, tconst);
}
// Validate input and find the corresponding movie
printf("TCON#%s#\n", input);
selected_movie = findMovieByTconst(movies, movie_count, input);
if (!selected_movie) {
printf(RED "Error: No movie found with barcode or tconst '%s'.\n" RESET, input);
input[0] = '\0';
}
}
displayRelevantInfo(selected_movie);
// List playlists
list_playlists();
// Ask for playlist ID or create a new one
static char playlist_id[14] = "\0";
char playlist_id_new[14] = "\0";
while (!isValidPlaylistID(playlist_id_new)) {
printf(YELLOW "[playlist id|new|q]\n" RESET);
printf(WHITE "(%s): " RESET, playlist_id);
fgets(playlist_id_new, sizeof(playlist_id_new), stdin);
trim_whitespace(playlist_id_new);
if (playlist_id_new[0] == 'q')
return;
if (is_movie_in_playlist(playlist_id_new, selected_movie->result.tconst)) {
playlist_id_new[0] = '\0';
printf(RED "Movie already in the playlist.\n" RESET);
int c;
while ((c = getchar()) != '\n' && c != EOF) { }
continue;
}
if (strlen(playlist_id_new) == 0 && isValidPlaylistID(playlist_id))
break;
strcpy(playlist_id, playlist_id_new);
if (isValidPlaylistID(playlist_id))
break;
if (strcmp(playlist_id, "new") == 0) {
add_playlist(playlist_id);
}
}
if (!isValidPlaylistID(playlist_id)) {
printf("Invalid Playlist: %s\n", playlist_id);
addMovieToPlaylist(movies, movie_count, tconst);
return;
}
char playlist_name[257];
if (strcmp(playlist_id, "new") == 0) {
printf("Enter the " YELLOW "name of the new playlist" RESET ": ");
fgets(playlist_name, sizeof(playlist_name), stdin);
playlist_name[strcspn(playlist_name, "\n")] = '\0'; // Remove newline
// Create a new playlist
FILE *file = fopen(FILENAME, "a");
if (!file) {
perror(RED "Error opening playlist file" RESET);
return;
}
// Generate new ID
int new_id = rand() % 10000; // Generate a random ID (for simplicity)
snprintf(playlist_id, sizeof(playlist_id), "%04d", new_id);
fprintf(file, "%s|%s\n", playlist_id, playlist_name);
fclose(file);
printf(GREEN "New playlist created with ID: %s\n" RESET, playlist_id);
}
// Write the tconst to the playlist file
char playlist_path[512];
snprintf(playlist_path, sizeof(playlist_path), "playlists/%s.txt", playlist_id);
ensure_directory_exists("playlists");
FILE *playlist_file = fopen(playlist_path, "a");
if (!playlist_file) {
perror(RED "Error opening playlist file" RESET);
return;
}
fprintf(playlist_file, "%s\n", selected_movie->result.tconst);
fclose(playlist_file);
printf(GREEN "Movie " WHITE "%s" RESET " (tconst: %s) " GREEN "added to playlist %s\n" RESET,
selected_movie->result.primaryTitle,
selected_movie->result.tconst,
playlist_id);
displayPlaylistContent(movies, movie_count, playlist_id);
getchar(); // fix..
}
// Function to remove a movie from a playlist
void removeMovieFromPlaylist(DataStruct* movies, int movie_count) {
list_playlists();
char playlist_id[14], tconst[256];
// Ask for the playlist ID to remove movie from
printf("Enter the " YELLOW "playlist ID" RESET " to remove from: ");
fgets(playlist_id, sizeof(playlist_id), stdin);
trim_whitespace(playlist_id);
int c;
while ((c = getchar()) != '\n' && c != EOF) { }
// Validate the playlist ID
if (!isValidPlaylistID(playlist_id)) {
printf(RED "Error: Playlist ID '%s' does not exist.\n" RESET, playlist_id);
clearInputBuffer();
return;
}
displayPlaylistContent(movies, movie_count, playlist_id);
// Ask for the tconst of the movie to be removed
printf("Enter the " YELLOW "tconst" RESET " of the movie to remove: ");
fgets(tconst, sizeof(tconst), stdin);
tconst[strcspn(tconst, "\n")] = '\0'; // Remove newline
// File path for the playlist (e.g., "playlists/1234.txt")
char playlist_file_path[256];
snprintf(playlist_file_path, sizeof(playlist_file_path), "playlists/%s.txt", playlist_id);
// Read the existing playlist file
FILE *file = fopen(playlist_file_path, "r");
if (!file) {
perror(RED "Error opening playlist file" RESET);
return;
}
// Create a temporary file to store the updated playlist
FILE *temp_file = fopen("temp_playlist.txt", "w");
if (!temp_file) {
perror(RED "Error creating temporary file" RESET);
fclose(file);
return;
}
char line[MAX_LINE];
int found = 0;
while (fgets(line, sizeof(line), file)) {
// If the line doesn't match the tconst to be removed, write it to the temporary file
if (strncmp(line, tconst, strlen(tconst)) != 0) {
fputs(line, temp_file);
} else {
found = 1;
}
}
fclose(file);
fclose(temp_file);
// If the movie was found and removed, replace the old playlist file with the updated one
if (found) {
remove(playlist_file_path); // Delete the old playlist file
rename("temp_playlist.txt", playlist_file_path); // Rename temp file to original playlist file
displayPlaylistContent(movies, movie_count, playlist_id);
printf(GREEN "Movie with tconst '%s' removed from playlist '%s'.\n" RESET, tconst, playlist_id);
} else {
printf(RED "Error: Movie with tconst '%s' not found in playlist '%s'.\n" RESET, tconst, playlist_id);
remove("temp_playlist.txt"); // Clean up temp file if no movie was removed
}
}
int main() {
DataStruct* movies = NULL;
int movie_count = loadLocalMovies(&movies, "local");
listMovies(movies, movie_count);
DataStruct* dvd;
Websearch_st data_web;
TitleEntry *titles;
int title_count;
RatingInfo *ratings = NULL;
// Load the ratings from the file
int ratings_count = 0;
int is_imbd_data_loadad = 0;
/*
for (int i = 0; i < 3; i++) {
if (titles[i].languages == NULL) continue;
for (int j = 0; j < titles[i].languageCount; j++) {
if (titles[i].languages[j].isOriginalTitle)
printf("ORIGINAL: %s\n", titles[i].tconst);
if (titles[i].languages[j].region == NULL) continue;
if (strcmp(titles[i].languages[j].region, "DE") == 0) {
printf("%d %d\n", i, titles[i].languageCount); break; } }
}
*/
char barcode[14] = "\0";
char file_path[512] = "\0";
SearchResult* res = NULL;
SearchResult* res_last = NULL;
int search_locally = 0;
while (1) {
char search_query[256] = "\0";
// If empty, read the search query from stdin
while (1) {
clearInputBuffer();
printf(BLUE "\n─────────────────────────────────────────\n" RESET);
printf(" %s%s" CYAN " DB Action on " YELLOW "%s %s\n" RESET, search_locally ? GREEN : YELLOW ,search_locally ? "Local" : "Global" ,barcode, res_last ? res_last->tconst : "");
// Prompt for input
printf(" [list|add|rm|rm last|print|clear|local]\n");
printf(" [list|add|remove] [from] playlist[s]\n");
printf(" [search barcode]\n\n");
printf(" [\"search query\"|\"barcode\"]\n\n");
printf(WHITE "Enter search query: " RESET);
fgets(search_query, sizeof(search_query), stdin);
printf("\n");
// Remove the trailing newline character if it exists
trim_whitespace(search_query);
// Check if input is empty
int sl = strlen(search_query);
if (sl == 0) {
printf("Input is empty, please enter a valid query.\n");
continue;
}
// Check if input is a barcode (14 digits)
if (strcmp(search_query, "list playlists") == 0 ||
strcmp(search_query, "playlists") == 0) {
PRINT_HEADER("List Playlists");
list_playlists();
} else if (strcmp(search_query, "remove from playlist") == 0) {
PRINT_HEADER("Remove Movie from Playlist");
removeMovieFromPlaylist(movies, movie_count);
} else if (strcmp(search_query, "list playlist") == 0 ||
strcmp(search_query, "playlist") == 0) {
PRINT_HEADER("Display Playlist Content");
char empty_playlist_id[14] = "";
displayPlaylistContent(movies, movie_count, empty_playlist_id);
} else if (strcmp(search_query, "add playlist") == 0) {
PRINT_HEADER("Add Playlist");
char empty_playlist_id[14] = "";
add_playlist(empty_playlist_id);
} else if (strcmp(search_query, "rm playlist") == 0) {
PRINT_HEADER("Remove Playlist");
remove_playlist();
} else if (strcmp(search_query, "rm") == 0) {
PRINT_HEADER("Remove Movie");
removeMovie(movies, &movie_count);
} else if (strcmp(search_query, "local") == 0) {
search_locally = !search_locally ;
} else if (strcmp(search_query, "add") == 0) {
PRINT_HEADER("Add Movie to Playlist");
char lt[13];
strcpy(lt,res_last != NULL ? res_last->tconst : "\0");
addMovieToPlaylist(movies, movie_count, lt);
} else if (strcmp(search_query, "list") == 0) {
PRINT_HEADER("List Movies");
listMovies(movies, movie_count);
} else if (strcmp(search_query, "rm last") == 0) {
PRINT_HEADER("Remove last added");
if (strlen(file_path) == 0) continue;
if (remove(file_path) == 0) {
printf("File deleted successfully.\n");
} else {
perror("Error deleting file");
}
} else if (strcmp(search_query, "print") == 0) {
printDataStruct(dvd);
} else if (strcmp(search_query, "clear") == 0) {
Websearch_st data_web_new = {};
data_web = data_web_new;
data_web.title[0] = '\0';
barcode[0] = '\0';
file_path[0] = '\0';
res = NULL;
res_last = NULL;
} else if (search_locally) {
search_query[12] = '\0';
dvd = findMovieByTconst(movies, movie_count, search_query);
printDataStruct(dvd);
} else if ((sl == 13 && strspn(search_query, "0123456789") == 13) ||
(sl == 12 && strspn(search_query, "0123456789") == 12) ||
strcmp(search_query, "search barcode") == 0) {
Websearch_st data_web_new = { "", 0.0, 0.0, "" };
if (strcmp(search_query, "search barcode") == 0) {
if (!(strlen(dvd->barcode) ==12 || strlen(dvd->barcode) ==13)) {
perror("Not a valid barcode\n");
search_query[0] = '\0';
continue;
}
printf("Make use of barcode: %s\n", dvd->barcode);
strcpy(search_query, dvd->barcode);
} else {
data_web = data_web_new;
data_web.title[0] = '\0';
barcode[0] = '\0';
file_path[0] = '\0';
res = NULL;
res_last = NULL;
strcpy(barcode, search_query);
barcode[13] = '\0';
DataStruct* res_d = findMovieByBarcode(movies, movie_count, barcode);
if (res_d) {
res = &res_d->result;
res_last = &res_d->result;
data_web = res_d->web_data;
dvd = res_d;
printDataStruct(dvd);
continue;
}
}
printf("Recognized barcode %s...\n", barcode);
PRINT_HEADER("Search Barcode in web..");
data_web_new = readUpcitemdb(barcode);
print_json_response(&data_web_new);
PRINT_HEADER_SMALL("Search web done: ");
printf("%s\n", data_web_new.title);
if (strlen(data_web_new.title) > 0) {
data_web = data_web_new;
strcpy(search_query, data_web.title);
break;
}
} else if (sl > 0) {
break;
}
}
//continue; // !!! <---
if (!is_imbd_data_loadad) {
PRINT_HEADER("Source imbd files");
fflush(stdout);
PRINT_HEADER_SMALL("source ratings");
ratings_count = load_ratings(&ratings);
if (ratings_count < 0) {
fprintf(stderr, "Failed to load ratings.\n");
return 1;
}
//for (int i = 0; i < 22; i++) printf("%d %s %lf\n", i, ratings[i].tconst, ratings[i].averageRating); exit(1);
PRINT_HEADER_SMALL("source titles");
if (load_titles(&titles, &title_count, ratings, ratings_count) != 0) {
fprintf(stderr, "Failed to load titles.\n");
return 1;
}
PRINT_HEADER_SMALL("source languages");
for (int i = 0; i < title_count; i++) {
pthread_mutex_init(&titles[i].lock, NULL);
}
if (load_languages_and_regions(titles, title_count) != 0) {
fprintf(stderr, "Failed to load titles.\n");
return 1;
}
for (int i = 0; i < title_count; i++) {
pthread_mutex_destroy(&titles[i].lock);
}
/*
for (int i = 0; i < 12; i++) {
if (titles[i].ratingInfo == NULL) continue;
if (titles[i].languageCount == 0) continue;
printf("%d %s %s %lf\n", i, titles[i].tconst, titles[i].languages[0].title, titles[i].ratingInfo->averageRating);
}
*/
is_imbd_data_loadad = 1;
PRINT_HEADER_SMALL("Donne sourcing imbd files");
}
PRINT_HEADER("Search query: ");
printf("Searching for: %s\n\n", search_query);
fflush(stdout);
// Call search_and_select function
res = search_and_select(search_query, titles, title_count);
if (res != NULL) {
//saveToFile(res, &data_web, search_query, barcode, file_path);
DataStruct dvd_ = createDataStruct(res, &data_web, search_query, barcode);
dvd = &dvd_;
printDataStruct(dvd);
writeStructToFile(dvd);
} else {
snprintf(file_path, sizeof(file_path), "");
}
// If search_and_select produced results, append to database
PRINT_HEADER_SMALL("Add to DB");
if (strlen(search_query) > 0) {
printf("Appending result to database: %s\n", search_query);
append_to_database(search_query);
movie_count = loadLocalMovies(&movies, "local");
res_last = res;
} else {
res_last = NULL;
printf("No results to append.\n");
}
printf(RESET);
}
printf(RESET);
free(titles);
// Free allocated memory
free(movies);
return 0;
}