mirror of
https://github.com/farfalleflickan/cmyflix.git
synced 2025-05-09 12:12:07 +00:00
Compare commits
15 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
f827776594 | ||
|
28ea811f95 | ||
|
dcb1de38c9 | ||
|
01777bbf11 | ||
|
8ba5e3a48c | ||
|
b080ff6f03 | ||
|
d4b22ce191 | ||
|
6e5a709e22 | ||
|
b8902589b2 | ||
|
f4e1cb4dcb | ||
|
47a0685230 | ||
|
4699ede21d | ||
|
87445fd8a4 | ||
|
a3b57f7033 | ||
|
8ed17ed69b |
65
.github/workflows/main.yml
vendored
Normal file
65
.github/workflows/main.yml
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
name: Build and Release DEB
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build-deb:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libbsd-dev libcjson-dev libcurl4-openssl-dev
|
||||
|
||||
- name: Build DEB
|
||||
run: |
|
||||
make deb
|
||||
|
||||
- name: Upload DEB artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: deb-package
|
||||
path: deb/*.deb
|
||||
|
||||
create-release:
|
||||
needs: build-deb
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Download DEB artifact
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: deb-package
|
||||
path: .
|
||||
|
||||
- name: Find the DEB filename and extract version
|
||||
id: find_deb
|
||||
run: |
|
||||
DEB_FILE=$(ls *.deb)
|
||||
echo "deb_file=$DEB_FILE" >> $GITHUB_OUTPUT
|
||||
VERSION=$(echo "$DEB_FILE" | sed -E 's/^.*_([0-9.]+)_.*/\1/')
|
||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Create or Update GitHub Release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ steps.find_deb.outputs.version }}
|
||||
release_name: "cmyflix v${{ steps.find_deb.outputs.version }}"
|
||||
draft: true
|
||||
prerelease: false
|
||||
|
||||
- name: Upload DEB to Release
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: ${{ steps.find_deb.outputs.deb_file }}
|
||||
asset_name: ${{ steps.find_deb.outputs.deb_file }}
|
||||
asset_content_type: "application/vnd.debian.binary-package"
|
@ -37,7 +37,7 @@ Either install from source with make install OR use a pre-compiled package from
|
||||
Beware, the pre-compiled `deb` file is built using the default `libcurl4-openssl-dev` backend.
|
||||
|
||||
# Requirements to run:
|
||||
cmyflix uses libcjson(>=1.7.15), libcurl(>=7.68), imagemagick, ffmpeg and a TMDB api key. Please do also note that cmyflix searches for `mp4` files due to the usage of HTML5 and its supported formats.
|
||||
cmyflix uses libcjson(>=1.7.15), libcurl(>=7.68), imagemagick, ffmpeg and a TMDB api key. Please do also note that cmyflix searches for `mp4`,`mkv`,`ogv` and `webm` files due to the usage of HTML5 and its supported formats.
|
||||
|
||||
# Configuration & usage:
|
||||
For starters, cmyflix looks for `cmyflix.cfg` first in the same folder as the binary, then in `$HOME/.config/cmyflix/` and lastly in `/etc/cmyflix/`. Same thing applies for folder `html` and its contents.
|
||||
|
@ -287,7 +287,7 @@ progConfig *getConfig(char *srcPath) {
|
||||
|
||||
if (setrlimit(RLIMIT_NOFILE, &(options->newLim))==-1){
|
||||
confCleanup(options);
|
||||
fatalError_abort("getConfig error", "could not set new fileLimit, error: %s\n", errno, strerror(errno));
|
||||
fatalError_abort("getConfig error", "could not set new fileLimit, error: %s\n", strerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -116,12 +116,21 @@ fileList *sortedJoinLists(fileList *part1, fileList *part2, size_t cmpPos, bool
|
||||
name2=part2->data[cmpPos];
|
||||
}
|
||||
|
||||
if (name1!=NULL && name2!=NULL && strcmp(name1, name2)<0 && isAscending==true) { // name2 is later in the alphabet
|
||||
list=part1;
|
||||
list->next=sortedJoinLists(part1->next, part2, cmpPos, isAscending, mode);
|
||||
} else {
|
||||
list=part2;
|
||||
list->next=sortedJoinLists(part1, part2->next, cmpPos, isAscending, mode);
|
||||
if (name1 != NULL && name2 != NULL) {
|
||||
int cmp = strcasecmp(name1, name2);
|
||||
if ((cmp < 0 && isAscending) || (cmp > 0 && !isAscending)) {
|
||||
list = part1;
|
||||
list->next = sortedJoinLists(part1->next, part2, cmpPos, isAscending, mode);
|
||||
} else {
|
||||
list = part2;
|
||||
list->next = sortedJoinLists(part1, part2->next, cmpPos, isAscending, mode);
|
||||
}
|
||||
} else if (name1 == NULL) {
|
||||
list = part2;
|
||||
list->next = sortedJoinLists(part1, part2->next, cmpPos, isAscending, mode);
|
||||
} else if (name2 == NULL) {
|
||||
list = part1;
|
||||
list->next = sortedJoinLists(part1->next, part2, cmpPos, isAscending, mode);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
@ -296,3 +305,20 @@ char *fileListToJSONStr(fileList *list) {
|
||||
strlcat(listStr, "]", sizeStr);
|
||||
return listStr;
|
||||
}
|
||||
|
||||
fileList *reverseList(fileList *head) {
|
||||
fileList *prev = NULL;
|
||||
fileList *current = head;
|
||||
fileList *next = NULL;
|
||||
size_t listSize = 0;
|
||||
|
||||
while (current != NULL) {
|
||||
next = current->next;
|
||||
current->next = prev;
|
||||
prev = current;
|
||||
current->listSize = ++listSize;
|
||||
current = next;
|
||||
}
|
||||
|
||||
return prev; // The new head of the reversed list
|
||||
}
|
@ -23,6 +23,7 @@ fileList *JSONtofileList(cJSON *json, ioMode mode);
|
||||
void splitList(fileList *list, fileList **part1, fileList **part2);
|
||||
// mergeSort a list
|
||||
void msortList(fileList **list, size_t cmpPos, bool isAscending, sortMode mode);
|
||||
fileList *reverseList(fileList *head);
|
||||
void freeList(struct fileList *list);
|
||||
void printList(fileList *list);
|
||||
// save fileList to a file, header is a string to be put at the top of the file
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "iofiles.h"
|
||||
|
||||
// Own implementation with opendir/readdir. nftw might be faster? Dunno, nftw seemed slower in tests
|
||||
struct fileList *find(progConfig *conf, char *dirPath, char *searchStr, ioMode mode, bool recursive) {
|
||||
struct fileList *find(progConfig *conf, char *dirPath, char **searchStrs, ioMode mode, bool recursive) {
|
||||
DIR *directory = opendir(dirPath);
|
||||
if (directory == NULL) {
|
||||
printError("find warning", false, HYEL, "failed while opening directory \"%s\";\nError: %s;\n", dirPath, strerror(errno));
|
||||
@ -46,7 +46,7 @@ struct fileList *find(progConfig *conf, char *dirPath, char *searchStr, ioMode m
|
||||
list = initList(list, NULL, 0);
|
||||
addData(list, path);
|
||||
}
|
||||
fileList *temp = find(conf, path, searchStr, mode, recursive);
|
||||
fileList *temp = find(conf, path, searchStrs, mode, recursive);
|
||||
if (temp != NULL) {
|
||||
list = joinLists(list, temp);
|
||||
}
|
||||
@ -56,36 +56,41 @@ struct fileList *find(progConfig *conf, char *dirPath, char *searchStr, ioMode m
|
||||
addData(newFile, fileP->d_name);
|
||||
list=joinLists(newFile, list);
|
||||
}
|
||||
} else if (strstr(fileP->d_name, searchStr) && (mode & FI_MODE)!=0) { // if filename matches the string we looking for AND in file mode
|
||||
char **fileMatch = NULL;
|
||||
if ((mode & TV_MODE)!=0) { // if TV mode bit set
|
||||
// if ( conf->tvDB_exists==true && (mode & CK_MODE)!=0 && strstr(conf->tvDB_str, path)!=NULL) { // if filename already in database & in 'check mode'
|
||||
for (int i=0; i<conf->regexTVnum && fileMatch == NULL; i++) {
|
||||
fileMatch=matchReg(path, conf->regexTVstr[i], conf->regexTVgroups);
|
||||
if (fileMatch!=NULL) {
|
||||
fileList *newFile=newList();
|
||||
for (int j=1; j<=parseStrToInt(fileMatch[0]); j++) {
|
||||
addData(newFile, fileMatch[j]);
|
||||
if (j==1) {
|
||||
addData(newFile, dirPath);
|
||||
addData(newFile, fileP->d_name);
|
||||
} else if ((mode & FI_MODE)!=0) { // if filename matches the string we looking for AND in file mode
|
||||
for (char **currentStr = searchStrs; *currentStr != NULL; currentStr++) {
|
||||
if (strstr(fileP->d_name, *currentStr) != NULL) {
|
||||
char **fileMatch = NULL;
|
||||
if ((mode & TV_MODE)!=0) { // if TV mode bit set
|
||||
// if ( conf->tvDB_exists==true && (mode & CK_MODE)!=0 && strstr(conf->tvDB_str, path)!=NULL) { // if filename already in database & in 'check mode'
|
||||
for (int i=0; i<conf->regexTVnum && fileMatch == NULL; i++) {
|
||||
fileMatch=matchReg(path, conf->regexTVstr[i], conf->regexTVgroups);
|
||||
if (fileMatch!=NULL) {
|
||||
fileList *newFile=newList();
|
||||
for (int j=1; j<=parseStrToInt(fileMatch[0]); j++) {
|
||||
addData(newFile, fileMatch[j]);
|
||||
if (j==1) {
|
||||
addData(newFile, dirPath);
|
||||
addData(newFile, fileP->d_name);
|
||||
}
|
||||
}
|
||||
list = joinLists(newFile, list);
|
||||
}
|
||||
}
|
||||
list = joinLists(newFile, list);
|
||||
} else if ((mode & MO_MODE)!=0) { // if movie mode bit set...
|
||||
/*
|
||||
* Nothing, else works just as well
|
||||
*/
|
||||
} else { // if in file mode but NOT in movie/tv mode...
|
||||
fileList *newFile=newList();
|
||||
addData(newFile, path);
|
||||
addData(newFile, dirPath);
|
||||
addData(newFile, fileP->d_name);
|
||||
list=joinLists(newFile, list);
|
||||
}
|
||||
freeStrArr(fileMatch);
|
||||
break;
|
||||
}
|
||||
} else if ((mode & MO_MODE)!=0) { // if movie mode bit set...
|
||||
/*
|
||||
* Nothing, else works just as well
|
||||
*/
|
||||
} else { // if in file mode but NOT in movie/tv mode...
|
||||
fileList *newFile=newList();
|
||||
addData(newFile, path);
|
||||
addData(newFile, dirPath);
|
||||
addData(newFile, fileP->d_name);
|
||||
list=joinLists(newFile, list);
|
||||
}
|
||||
freeStrArr(fileMatch);
|
||||
}
|
||||
tryFree(path);
|
||||
}
|
||||
|
@ -9,4 +9,4 @@ typedef enum {
|
||||
TV_MODE=1 << 3 // TV show mode
|
||||
} ioMode;
|
||||
|
||||
struct fileList *find(progConfig *conf, char *dirPath, char *searchStr, ioMode mode, bool recursive);
|
||||
struct fileList *find(progConfig *conf, char *dirPath, char **searchStrs, ioMode mode, bool recursive);
|
||||
|
40
src/main.c
40
src/main.c
@ -17,7 +17,7 @@
|
||||
#include "main.h"
|
||||
|
||||
#define REPO_URL "https://github.com/farfalleflickan/cmyflix"
|
||||
#define VERSION_STRING "0.2"
|
||||
#define VERSION_STRING "0.25"
|
||||
|
||||
// GLOBAL VARIABLES
|
||||
FILE *LOGFILE=NULL;
|
||||
@ -43,7 +43,8 @@ void printHelp() {
|
||||
printf(" \t\t--id \t 12345\t\tspecifies new id for fix mode\n");
|
||||
printf(" \t\t--name \t \"new name\"\tspecifies new name for fix mode\n");
|
||||
printf(" \t\t--poster path/to/file\tspecifies new poster for fix mode\n");
|
||||
printf(" \t\t--refresh\t\trefresh info of \"name\", so refreshes episode names in TV shows (also re-downloads poster if --poster \"\" is passed)\n");
|
||||
printf(" \t\t--titles\t\trefreshes the episode titles\n");
|
||||
printf(" \t\t--refresh\t\trefresh info of \"name\", re-downloads poster if --poster \"\" is passed & refreshes episode names in TV shows if --titles is also passed\n");
|
||||
printf(" --version\t\t\t\tprint version\n");
|
||||
printf(" --gen-config\t\t\t\tprint default configuration to shell\n");
|
||||
printf(" --check-update\t\t\tcheck if program update is available\n");
|
||||
@ -78,9 +79,6 @@ void checkUpdate() {
|
||||
resetSTDColors();
|
||||
FILE *cmdRet=popen(cmdStr, "r");
|
||||
if (cmdRet==NULL) {
|
||||
if (pclose(cmdRet)!=0) {
|
||||
printError("cmyflix", false, HRED, "%s\n", strerror(errno));
|
||||
}
|
||||
tryFree(cmdStr);
|
||||
fatalError_exit("checkUpdate", "something went wrong while trying to check for an update, errno is: %s\n", strerror(errno));
|
||||
} else {
|
||||
@ -119,6 +117,7 @@ void *tvCode(void *args) {
|
||||
if (runFlags & HTML_MODE) {
|
||||
if (tv==NULL && (runFlags & DB_MODE)==0) {
|
||||
tv=JSONtofileList(conf->JSON_tvDB, TV_MODE);
|
||||
tv=reverseList(tv);
|
||||
if (tv==NULL) {
|
||||
printError("cmyflix warning", false, HYEL, "Running in HTML mode but no database could be found!\nBuilding new database...\n");
|
||||
tv=createTVShowDB(conf); // find files and create/edit database
|
||||
@ -159,6 +158,7 @@ void *movieCode(void *args) {
|
||||
if (runFlags & HTML_MODE) {
|
||||
if (movies==NULL && (runFlags & DB_MODE)==0) {
|
||||
movies=JSONtofileList(conf->JSON_moDB, MO_MODE);
|
||||
movies=reverseList(movies);
|
||||
if (movies==NULL) {
|
||||
movies=createMoviesDB(conf);
|
||||
if (movies!=NULL) {
|
||||
@ -215,9 +215,6 @@ void copyExtras(progConfig *conf, progFlags runFlags, char *htmlFolder, char *de
|
||||
resetSTDColors();
|
||||
FILE *cmdRet=popen(cmdStr, "r");
|
||||
if (cmdRet==NULL) {
|
||||
if (pclose(cmdRet)!=0) {
|
||||
printError("cmyflix", false, HRED, "%s\n", strerror(errno));
|
||||
}
|
||||
tryFree(cmdStr);
|
||||
fatalError_exit("cmyflix error", "something went wrong while trying to copy HTML resources from '%s' to '%s';\n", extPath, tempStr2);
|
||||
} else {
|
||||
@ -268,8 +265,13 @@ void cleanMode(progConfig *conf, progFlags flags) {
|
||||
if (threadArgTV.oldJSON!=NULL) {
|
||||
char *newDB=cJSON_Print(threadArgTV.oldJSON);
|
||||
cJSON_Delete(threadArgTV.oldJSON);
|
||||
freeFileMem(conf->dbNameTV, conf->tvDB_str);
|
||||
writeCharToFile(newDB, conf->dbNameTV);
|
||||
tryFree(newDB);
|
||||
cJSON_Delete(conf->JSON_tvDB);
|
||||
conf->JSON_tvDB=NULL;
|
||||
conf->tvDB_str=fileToMem(conf->dbNameTV);
|
||||
conf->JSON_tvDB=cJSON_Parse(conf->tvDB_str);
|
||||
} else {
|
||||
printInfo("cleanMode warning", true, "oldJSON was NULL!\n");
|
||||
}
|
||||
@ -279,8 +281,13 @@ void cleanMode(progConfig *conf, progFlags flags) {
|
||||
if (threadArgMovies.oldJSON!=NULL) {
|
||||
char *newDB=cJSON_Print(threadArgMovies.oldJSON);
|
||||
cJSON_Delete(threadArgMovies.oldJSON);
|
||||
freeFileMem(conf->dbNameMovie, conf->moDB_str);
|
||||
writeCharToFile(newDB, conf->dbNameMovie);
|
||||
tryFree(newDB);
|
||||
cJSON_Delete(conf->JSON_moDB);
|
||||
conf->JSON_moDB=NULL;
|
||||
conf->moDB_str=fileToMem(conf->dbNameMovie);
|
||||
conf->JSON_moDB=cJSON_Parse(conf->moDB_str);
|
||||
} else {
|
||||
printInfo("cleanMode warning", true, "oldJSON was NULL!\n");
|
||||
}
|
||||
@ -339,11 +346,12 @@ int main(int argc, char * argv[]) {
|
||||
{"id", required_argument, 0, '4'},
|
||||
{"poster", required_argument, 0, '5'},
|
||||
{"name", required_argument, 0, '6'},
|
||||
{"refresh", no_argument, 0, '7'},
|
||||
{"version", no_argument, 0, '8'},
|
||||
{"gen-config", no_argument, 0, '9'},
|
||||
{"titles", no_argument, 0, '7'},
|
||||
{"refresh", no_argument, 0, '8'},
|
||||
{"version", no_argument, 0, '9'},
|
||||
{"check-update", no_argument, 0, 'u'},
|
||||
{"clean", no_argument, 0, 'c'},
|
||||
{"gen-config", no_argument, 0, 'g'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"movies", no_argument, 0, 'm'},
|
||||
{"quiet", no_argument, 0, 'q'},
|
||||
@ -403,12 +411,14 @@ int main(int argc, char * argv[]) {
|
||||
} else if (currOption=='6') { // --name
|
||||
fixName=optarg;
|
||||
runFlags |= FIX_NAME_MODE;
|
||||
} else if (currOption=='7') { // --refresh
|
||||
} else if (currOption=='7') { // --titles
|
||||
runFlags |= FIX_TITLES_MODE;
|
||||
} else if (currOption=='8') { // --refresh
|
||||
runFlags |= FIX_REFR_MODE;
|
||||
} else if (currOption=='8') { // --version
|
||||
} else if (currOption=='9') { // --version
|
||||
printVersion();
|
||||
exit(EXIT_SUCCESS);
|
||||
} else if (currOption=='9') { // --gen-config
|
||||
} else if (currOption=='g') { // --gen-config
|
||||
printf("%s\n", DEF_CONF);
|
||||
exit(EXIT_SUCCESS);
|
||||
} else if (currOption=='c') { // --clean
|
||||
@ -490,7 +500,7 @@ int main(int argc, char * argv[]) {
|
||||
|
||||
if (runFlags & FIX_MODE) { // if in fix mode
|
||||
// if in either TV show mode or movie mode *AND* ( --id or --poster or --name)
|
||||
if (((runFlags & SHOWS_MODE) || (runFlags & MOVIES_MODE)) && ((runFlags & FIX_ID_MODE) || (runFlags & FIX_POSTER_MODE) || (runFlags & FIX_NAME_MODE) || (runFlags & FIX_REFR_MODE))) {
|
||||
if (((runFlags & SHOWS_MODE) || (runFlags & MOVIES_MODE)) && ((runFlags & FIX_ID_MODE) || (runFlags & FIX_POSTER_MODE) || (runFlags & FIX_NAME_MODE) || (runFlags & FIX_TITLES_MODE) || (runFlags & FIX_REFR_MODE))) {
|
||||
bool refreshMode=false;
|
||||
if (runFlags & FIX_REFR_MODE) {
|
||||
refreshMode=true;
|
||||
|
@ -11,7 +11,8 @@ typedef enum {
|
||||
FIX_ID_MODE = 1 << 6, // FIX MODE ID
|
||||
FIX_POSTER_MODE = 1 << 7, // FIX MODE POSTER
|
||||
FIX_NAME_MODE = 1 << 8, // FIX MODE NAME
|
||||
FIX_REFR_MODE = 1 << 9 // FIX MODE REFRESH
|
||||
FIX_TITLES_MODE = 1 << 9, // FIX MODE NAME
|
||||
FIX_REFR_MODE = 1 << 10 // FIX MODE REFRESH
|
||||
} progFlags;
|
||||
|
||||
void printHelp();
|
||||
|
39
src/movies.c
39
src/movies.c
@ -15,7 +15,7 @@ struct fileList *createMoviesDB(progConfig *conf) {
|
||||
char *infoStr="building home movies' database...";
|
||||
if (conf->homeMovies==false) {
|
||||
infoStr="building movies' database...";
|
||||
folders=find(conf, conf->MoviesPath, "", DI_MODE, false);
|
||||
folders=find(conf, conf->MoviesPath, (char *[]){"", NULL}, DI_MODE, false);
|
||||
}
|
||||
printInfo("createMoviesDB info", true, "%s\n", infoStr);
|
||||
|
||||
@ -61,6 +61,7 @@ struct fileList *createMoviesDB(progConfig *conf) {
|
||||
temp->dataSize--;
|
||||
}
|
||||
}
|
||||
movieJSON=reverseList(movieJSON);
|
||||
char *jsonStr=fileListToJSONStr(movieJSON);
|
||||
if (jsonStr!=NULL) {
|
||||
cJSON_Delete(conf->JSON_moDB);
|
||||
@ -128,6 +129,7 @@ struct fileList *createMoviesDB(progConfig *conf) {
|
||||
temp->dataSize--;
|
||||
}
|
||||
}
|
||||
hmovieJSON=reverseList(hmovieJSON);
|
||||
char *jsonStr=fileListToJSONStr(hmovieJSON);
|
||||
if (jsonStr!=NULL) {
|
||||
cJSON_Delete(conf->JSON_moDB);
|
||||
@ -300,6 +302,12 @@ char *getMoviePoster(progConfig *conf, int tmdb_id) {
|
||||
snprintf(posterURL, posterURLSize, "%s%s%d%s%s%s,%s", tmdbSite, tmdbM, tmdb_id, tmdbP, conf->TMDBapi, tmdbP_Opts, conf->prefImgLangM);
|
||||
if (posterURL!=NULL) {
|
||||
imgURL=getPoster(posterURL, conf, conf->prefImgWidthM, conf->prefImgRatioM, conf->prefImgLangM);
|
||||
if (imgURL==NULL) {
|
||||
printError("getMoviePoster error", true, HRED, "failed while using URL '%s';\nRetrying without language option...\n", posterURL);
|
||||
posterURL[0]='\0';
|
||||
snprintf(posterURL, posterURLSize, "%s%s%d%s%s", tmdbSite, tmdbM, tmdb_id, tmdbP, conf->TMDBapi);
|
||||
imgURL=getPoster(posterURL, conf, conf->prefImgWidthM, conf->prefImgRatioM, NULL);
|
||||
}
|
||||
if (imgURL==NULL) {
|
||||
printError("getMoviePoster error", true, HRED, "failed while using URL '%s';\n", posterURL);
|
||||
} else {
|
||||
@ -327,7 +335,7 @@ char *getMoviePoster(progConfig *conf, int tmdb_id) {
|
||||
}
|
||||
}
|
||||
}
|
||||
tryFree(posterURL);
|
||||
tryFree(posterURL);
|
||||
} else {
|
||||
printError("getMoviePoster error", false, HRED, "could not build URL request string, something went wrong...\n");
|
||||
}
|
||||
@ -356,11 +364,10 @@ void createMoviesHTML(progConfig *conf, fileList *list) {
|
||||
pthread_create(&threads[i], NULL, movieHTML, (void *) &threadObj[i]);
|
||||
}
|
||||
|
||||
i=0;
|
||||
fileList *htmlList=newList();
|
||||
addData(htmlList, MOVIE_HTML_TOP);
|
||||
|
||||
for (fileList *temp=list; temp!=NULL; temp=temp->next, i++) {
|
||||
for (i--; i>=0; i--) {
|
||||
pthread_join(threads[i], NULL);
|
||||
for (size_t j=0; j<threadObj[i].list->dataSize; j++) {
|
||||
addData(htmlList, threadObj[i].list->data[j]);
|
||||
@ -425,11 +432,25 @@ void *movieHTML(void *threadArg) {
|
||||
}
|
||||
printInfo("movieHTML info", true, "building HTML for \"%s\";\n", movieName);
|
||||
|
||||
size_t tempStrSize=strlen(MOVIE_HTML_VIDEO)+intSize(thisThread->id)*3+strlen(moviePoster)+strlen(movieFile)+strlen(movieName)*2+1;
|
||||
char *tempStr=NULL;
|
||||
mallocMacro(tempStr, tempStrSize, "movieHTML error");
|
||||
|
||||
snprintf(tempStr, tempStrSize, MOVIE_HTML_VIDEO, thisThread->id, movieName, moviePoster, movieName, thisThread->id, thisThread->id, movieFile);
|
||||
size_t tempStrSize = 0;
|
||||
if (strstr(movieFile, ".webm") != NULL) {
|
||||
tempStrSize=strlen(MOVIE_HTML_VIDEO_WEBM)+intSize(thisThread->id)*3+strlen(moviePoster)+strlen(movieFile)+strlen(movieName)*2+1;
|
||||
mallocMacro(tempStr, tempStrSize, "movieHTML error");
|
||||
snprintf(tempStr, tempStrSize, MOVIE_HTML_VIDEO_WEBM, thisThread->id, movieName, moviePoster, movieName, thisThread->id, thisThread->id, movieFile);
|
||||
} else if (strstr(movieFile, ".ogv") != NULL) {
|
||||
tempStrSize=strlen(MOVIE_HTML_VIDEO_OGG)+intSize(thisThread->id)*3+strlen(moviePoster)+strlen(movieFile)+strlen(movieName)*2+1;
|
||||
mallocMacro(tempStr, tempStrSize, "movieHTML error");
|
||||
snprintf(tempStr, tempStrSize, MOVIE_HTML_VIDEO_OGG, thisThread->id, movieName, moviePoster, movieName, thisThread->id, thisThread->id, movieFile);
|
||||
} else if (strstr(movieFile, ".mp4") != NULL) {
|
||||
tempStrSize=strlen(MOVIE_HTML_VIDEO_MP4)+intSize(thisThread->id)*3+strlen(moviePoster)+strlen(movieFile)+strlen(movieName)*2+1;
|
||||
mallocMacro(tempStr, tempStrSize, "movieHTML error");
|
||||
snprintf(tempStr, tempStrSize, MOVIE_HTML_VIDEO_MP4, thisThread->id, movieName, moviePoster, movieName, thisThread->id, thisThread->id, movieFile);
|
||||
} else {
|
||||
tempStrSize=strlen(MOVIE_HTML_VIDEO)+intSize(thisThread->id)*3+strlen(moviePoster)+strlen(movieFile)+strlen(movieName)*2+1;
|
||||
mallocMacro(tempStr, tempStrSize, "movieHTML error");
|
||||
snprintf(tempStr, tempStrSize, MOVIE_HTML_VIDEO, thisThread->id, movieName, moviePoster, movieName, thisThread->id, thisThread->id, movieFile);
|
||||
}
|
||||
addData(thisThread->list, tempStr);
|
||||
|
||||
cJSON *currSub=NULL;
|
||||
@ -447,7 +468,7 @@ void *movieHTML(void *threadArg) {
|
||||
}
|
||||
tryFree(subPath);
|
||||
}
|
||||
addData(thisThread->list, MOVIE_HTML_VIDEO_BOT);
|
||||
addData(thisThread->list, MOVIE_HTML_VIDEO_BOTTOM);
|
||||
tryFree(moviePoster);
|
||||
tryFree(movieFile);
|
||||
tryFree(tempStr);
|
||||
|
@ -4,11 +4,14 @@
|
||||
|
||||
#define MOVIE_HTML_TOP "<!DOCTYPE html>\n<html>\n<head>\n<title>cmyflix</title>\n<meta http-equiv=\"Content-type\" content=\"text/html;charset=UTF-8\">\n<meta name=\"description\" content=\"Daria Rostirolla\">\n<meta name=\"keywords\" content=\"HTML, CSS\">\n<meta name=\"author\" content=\"Daria Rostirolla\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<link href=\"css/movie.css\" rel=\"stylesheet\" type=\"text/css\">\n<link rel=\"icon\" type=\"image/png\" href=\"img/favicon.png\">\n</head>\n<body>\n<script type=\"text/javascript\" src=\"js/Mscript.js\"></script><div id=\"wrapper\">"
|
||||
|
||||
#define MOVIE_HTML_VIDEO "<div class=\"movieDiv\">\n<input id=\"A%d\" class=\"myBtn\" alt=\"%s\" onclick=\"javascript:showModal(this)\" type=\"image\" src=\"%s\" onload=\"javascript:setAlt(this, '%s')\">\n<div id=\"B%d\" class=\"modal\">\n<div class=\"modal-content\">\n<video id=\"C%d\" class=\"video_player\" controls preload=\"none\">\n<source src=\"%s\" type=\"video/mp4\">"
|
||||
#define MOVIE_HTML_VIDEO "<div class=\"movieDiv\">\n<input id=\"A%d\" class=\"myBtn\" alt=\"%s\" onclick=\"javascript:showModal(this)\" type=\"image\" src=\"%s\" onload=\"javascript:setAlt(this, '%s')\">\n<div id=\"B%d\" class=\"modal\">\n<div class=\"modal-content\">\n<video id=\"C%d\" class=\"video_player\" controls preload=\"none\">\n<source src=\"%s\">"
|
||||
#define MOVIE_HTML_VIDEO_WEBM "<div class=\"movieDiv\">\n<input id=\"A%d\" class=\"myBtn\" alt=\"%s\" onclick=\"javascript:showModal(this)\" type=\"image\" src=\"%s\" onload=\"javascript:setAlt(this, '%s')\">\n<div id=\"B%d\" class=\"modal\">\n<div class=\"modal-content\">\n<video id=\"C%d\" class=\"video_player\" controls preload=\"none\">\n<source src=\"%s\" type=\"video/webm\">"
|
||||
#define MOVIE_HTML_VIDEO_MP4 "<div class=\"movieDiv\">\n<input id=\"A%d\" class=\"myBtn\" alt=\"%s\" onclick=\"javascript:showModal(this)\" type=\"image\" src=\"%s\" onload=\"javascript:setAlt(this, '%s')\">\n<div id=\"B%d\" class=\"modal\">\n<div class=\"modal-content\">\n<video id=\"C%d\" class=\"video_player\" controls preload=\"none\">\n<source src=\"%s\" type=\"video/mp4\">"
|
||||
#define MOVIE_HTML_VIDEO_OGG "<div class=\"movieDiv\">\n<input id=\"A%d\" class=\"myBtn\" alt=\"%s\" onclick=\"javascript:showModal(this)\" type=\"image\" src=\"%s\" onload=\"javascript:setAlt(this, '%s')\">\n<div id=\"B%d\" class=\"modal\">\n<div class=\"modal-content\">\n<video id=\"C%d\" class=\"video_player\" controls preload=\"none\">\n<source src=\"%s\" type=\"video/ogg\">"
|
||||
|
||||
#define MOVIE_HTML_SUBS "\n<track src=\"%s\" kind=\"subtitles\" label=\"%s\">"
|
||||
|
||||
#define MOVIE_HTML_VIDEO_BOT "\n</video>\n<span onclick=\"javascript:hideModal()\" class=\"close\">×</span>\n</div>\n</div>\n</div>"
|
||||
#define MOVIE_HTML_VIDEO_BOTTOM "\n</video>\n<span onclick=\"javascript:hideModal()\" class=\"close\">×</span>\n</div>\n</div>\n</div>"
|
||||
|
||||
#define MOVIE_HTML_BOT "\n<div id=\"paddingDiv\">\n</div>\n</div>\n</body>\n</html>"
|
||||
|
||||
|
274
src/tvshow.c
274
src/tvshow.c
@ -15,7 +15,7 @@
|
||||
// JSON maker
|
||||
struct fileList *createTVShowDB(progConfig *conf) {
|
||||
printInfo("createTVShowDB info", true, "building TV shows' database...\n");
|
||||
fileList *showFolders=find(conf, conf->TVpath, "", DI_MODE, false);
|
||||
fileList *showFolders=find(conf, conf->TVpath, (char *[]){"", NULL}, DI_MODE, false);
|
||||
|
||||
if (showFolders != NULL ) {
|
||||
int foldersListSize=showFolders->listSize, i=0;
|
||||
@ -49,7 +49,7 @@ struct fileList *createTVShowDB(progConfig *conf) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
printError("createTVShowDB warning", false, "some errors occured while reading \"%s\", parts of the database will be rebuilt from scratch...\n", conf->dbNameTV);
|
||||
printError("createTVShowDB warning", false, HYEL, "some errors occured while reading \"%s\", parts of the database will be rebuilt from scratch...\n", conf->dbNameTV);
|
||||
threadObj[i].oldJSON=NULL;
|
||||
conf->tvDB_exists=false;
|
||||
cJSON_Delete(tempJSON);
|
||||
@ -119,7 +119,7 @@ void *findSeasons(void *threadArg) { // runs in Show.Name folder and spawns thre
|
||||
}
|
||||
// Find all the seasons of the current tv show
|
||||
printInfo("findSeasons info", true, "looking for seasons' folders in: \"%s\";\n", showPath);
|
||||
fileList *seasonsList = find(conf, showPath, "", DI_MODE, false); // get all seasons folders
|
||||
fileList *seasonsList = find(conf, showPath, (char *[]){"", NULL}, DI_MODE, false); // get all seasons folders
|
||||
|
||||
if (seasonsList!=NULL && seasonsList->data!=NULL) {
|
||||
bool showHasExtras=false;
|
||||
@ -276,7 +276,7 @@ void *findSeasons(void *threadArg) { // runs in Show.Name folder and spawns thre
|
||||
tryFree(extrasJSONStr);
|
||||
tryFree(tempShowJSONStr);
|
||||
} else {
|
||||
printError("findSeasons warning", false, HYEL, "please note, could not find any \".%s\" in path \"%s\"\n", videoExt, showPath);
|
||||
printError("findSeasons warning", false, HYEL, "please note, could not find any in path \"%s\"\n", showPath);
|
||||
}
|
||||
} else {
|
||||
printError("findSeasons warning", false, HYEL, "please note, path \"%s\" is empty!\n", showPath);
|
||||
@ -432,9 +432,13 @@ void *findEpisodes(void *threadArg) { // find files of 'this' season
|
||||
|
||||
if (epName==NULL) {
|
||||
if (temp->dataSize>5 && seasonExtra==false) {
|
||||
if (strcmp(temp->data[6], videoExt)==0) {
|
||||
epName=removeExtension(temp->data[2]);
|
||||
} else {
|
||||
for (char **currentStr = videoExt; *currentStr != NULL; currentStr++) {
|
||||
if (strcmp(temp->data[6], *currentStr)==0) {
|
||||
epName=removeExtension(temp->data[2]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (epName==NULL) {
|
||||
epName=removeExtension(temp->data[6]);
|
||||
}
|
||||
} else {
|
||||
@ -495,31 +499,46 @@ char *getShowPoster(progConfig *conf, unsigned int tmdb_id) {
|
||||
mallocMacro(posterURL, posterURLSize, "getShowPoster error");
|
||||
posterURL[0]='\0';
|
||||
snprintf(posterURL, posterURLSize, "%s%s%u%s%s%s,%s", tmdbSite, tmdbTV, tmdb_id, tmdbP, conf->TMDBapi, tmdbP_Opts, conf->prefImgLangTV);
|
||||
imgURL=getPoster(posterURL, conf, conf->prefImgWidthTV, conf->prefImgRatioTV, conf->prefImgLangTV);
|
||||
|
||||
printInfo("getShowPoster info", true, "got poster for \"%d\", URL: \"%s\";\n", tmdb_id, imgURL);
|
||||
if (imgURL!=NULL && conf->dTVImg) { // if image should actually be downloaded, otherwise will just link to imgURL
|
||||
if (checkFolder(conf->dTVFolder, true)==0) {
|
||||
size_t dlFileStrLen=strlen(imgURL)+strlen(conf->dTVFolder);
|
||||
char *dlFileName=NULL;
|
||||
mallocMacro(dlFileName, dlFileStrLen, "getShowPoster error");
|
||||
dlFileName[0]='\0';
|
||||
snprintf(dlFileName, dlFileStrLen, "%s%s", conf->dTVFolder, strrchr(imgURL, '/')+1);
|
||||
|
||||
if (dlFile(conf, imgURL, dlFileName)==CURLE_OK) { // downloaded poster!
|
||||
imgURL=realloc(imgURL, dlFileStrLen+1);
|
||||
if (imgURL==NULL)
|
||||
fatalError_abort("getShowPoster error", "could not realloc;\nError: %s;\n", strerror(errno));
|
||||
|
||||
strlcpy(imgURL, dlFileName, dlFileStrLen);
|
||||
if (conf->compressImgTV) {
|
||||
imgURL=compressImg(conf->compressImgTVCmd, imgURL, true);
|
||||
}
|
||||
}
|
||||
tryFree(dlFileName);
|
||||
if (posterURL!=NULL) {
|
||||
imgURL=getPoster(posterURL, conf, conf->prefImgWidthTV, conf->prefImgRatioTV, conf->prefImgLangTV);
|
||||
|
||||
if (imgURL==NULL) {
|
||||
printError("getShowPoster error", true, HRED, "failed while using URL '%s';\nRetrying without language option...\n", posterURL);
|
||||
posterURL[0]='\0';
|
||||
snprintf(posterURL, posterURLSize, "%s%s%u%s%s", tmdbSite, tmdbTV, tmdb_id, tmdbP, conf->TMDBapi);
|
||||
imgURL=getPoster(posterURL, conf, conf->prefImgWidthTV, conf->prefImgRatioTV, NULL);
|
||||
}
|
||||
|
||||
if (imgURL==NULL) {
|
||||
printError("getShowPoster error", true, HRED, "failed while using URL '%s';\n", posterURL);
|
||||
} else {
|
||||
printInfo("getShowPoster info", true, "got poster for \"%d\", URL: \"%s\";\n", tmdb_id, imgURL);
|
||||
if (imgURL!=NULL && conf->dTVImg) { // if image should actually be downloaded, otherwise will just link to imgURL
|
||||
if (checkFolder(conf->dTVFolder, true)==0) {
|
||||
size_t dlFileStrLen=strlen(imgURL)+strlen(conf->dTVFolder);
|
||||
char *dlFileName=NULL;
|
||||
mallocMacro(dlFileName, dlFileStrLen, "getShowPoster error");
|
||||
dlFileName[0]='\0';
|
||||
snprintf(dlFileName, dlFileStrLen, "%s%s", conf->dTVFolder, strrchr(imgURL, '/')+1);
|
||||
|
||||
if (dlFile(conf, imgURL, dlFileName)==CURLE_OK) { // downloaded poster!
|
||||
imgURL=realloc(imgURL, dlFileStrLen+1);
|
||||
if (imgURL==NULL)
|
||||
fatalError_abort("getShowPoster error", "could not realloc;\nError: %s;\n", strerror(errno));
|
||||
|
||||
strlcpy(imgURL, dlFileName, dlFileStrLen);
|
||||
if (conf->compressImgTV) {
|
||||
imgURL=compressImg(conf->compressImgTVCmd, imgURL, true);
|
||||
}
|
||||
}
|
||||
tryFree(dlFileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tryFree(posterURL);
|
||||
} else {
|
||||
printError("getShowPoster error", false, HRED, "could not build URL request string, something went wrong...\n");
|
||||
}
|
||||
return imgURL;
|
||||
}
|
||||
|
||||
@ -584,7 +603,7 @@ void createShowsHTML(progConfig *conf, fileList *list) {
|
||||
mallocMacro(threads, sizeof(pthread_t)*list->listSize, "createShowsHTML error");
|
||||
threadStruct *threadObj=NULL;
|
||||
mallocMacro(threadObj, sizeof(threadStruct)*list->listSize, "createShowsHTML error");
|
||||
size_t i=0;
|
||||
int i=0;
|
||||
for (fileList *temp=list; temp!=NULL; temp=temp->next) {
|
||||
threadObj[i].conf=conf;
|
||||
threadObj[i].data=temp->data;
|
||||
@ -596,25 +615,24 @@ void createShowsHTML(progConfig *conf, fileList *list) {
|
||||
i++;
|
||||
}
|
||||
|
||||
i=0;
|
||||
fileList *htmlList=newList();
|
||||
addData(htmlList, TV_HTML_TOP);
|
||||
|
||||
char *htmlStr=NULL;
|
||||
for (fileList *temp=list; temp!=NULL; temp=temp->next) {
|
||||
pthread_join(threads[i], NULL);
|
||||
for (int j=0; j<i; j++) {
|
||||
pthread_join(threads[j], NULL);
|
||||
char *showFile=NULL;
|
||||
char *showPoster=NULL;
|
||||
if (checkFolder(threadObj[i].list->data[0], false)==0) {
|
||||
showFile=getRelativePath(conf->TVhtml, threadObj[i].list->data[0]);
|
||||
if (checkFolder(threadObj[j].list->data[0], false)==0) {
|
||||
showFile=getRelativePath(conf->TVhtml, threadObj[j].list->data[0]);
|
||||
} else {
|
||||
fatalError_exit("createShowsHTML", "could not find \"%s\";\nExiting...\n", threadObj[i].list->data[0]);
|
||||
fatalError_exit("createShowsHTML", "could not find \"%s\";\nExiting...\n", threadObj[j].list->data[0]);
|
||||
}
|
||||
|
||||
if (checkFolder(threadObj[i].list->data[1], false)==0) {
|
||||
showPoster=getRelativePath(conf->TVhtml, threadObj[i].list->data[1]);
|
||||
if (checkFolder(threadObj[j].list->data[1], false)==0) {
|
||||
showPoster=getRelativePath(conf->TVhtml, threadObj[j].list->data[1]);
|
||||
} else {
|
||||
fatalError_exit("createShowsHTML", "could not find \"%s\";\nExiting...\n", threadObj[i].list->data[1]);
|
||||
fatalError_exit("createShowsHTML", "could not find \"%s\";\nExiting...\n", threadObj[j].list->data[1]);
|
||||
}
|
||||
|
||||
if (showPoster==NULL) {
|
||||
@ -622,20 +640,19 @@ void createShowsHTML(progConfig *conf, fileList *list) {
|
||||
mallocMacro(showPoster, 1, "createShowsHTML error");
|
||||
showPoster[0]='\0';
|
||||
}
|
||||
char *showName=threadObj[i].list->data[2];
|
||||
char *showName=threadObj[j].list->data[2];
|
||||
|
||||
size_t htmlStrSize=strlen(TV_HTML_FRAME)+strlen(showFile)+strlen(showPoster)+strlen(showName)*2+intSize(i)+1;
|
||||
size_t htmlStrSize=strlen(TV_HTML_FRAME)+strlen(showFile)+strlen(showPoster)+strlen(showName)*2+intSize(j)+1;
|
||||
htmlStr=realloc(htmlStr, htmlStrSize);
|
||||
if (htmlStr==NULL) {
|
||||
fatalError_abort("createShowsHTML error", "could not realloc;\nError: %s;\n", strerror(errno));
|
||||
}
|
||||
snprintf(htmlStr, htmlStrSize, TV_HTML_FRAME, i, showName, showFile, showPoster, showName, i, i, i);
|
||||
snprintf(htmlStr, htmlStrSize, TV_HTML_FRAME, j, showName, showFile, showPoster, showName, j, j, j);
|
||||
|
||||
addData(htmlList, htmlStr);
|
||||
freeList(threadObj[i].list);
|
||||
freeList(threadObj[j].list);
|
||||
tryFree(showFile);
|
||||
tryFree(showPoster);
|
||||
i++;
|
||||
}
|
||||
addData(htmlList, TV_HTML_BOT);
|
||||
fileListToFile(htmlList, conf->TVhtml, "", "");
|
||||
@ -677,11 +694,6 @@ void *showHTML(void *threadArg) {
|
||||
fatalError_abort("showHTML error", "showName==NULL; JSON was:\n%s\n--- END ---\n", cJSON_Print(myJSON));
|
||||
}
|
||||
|
||||
char *numOfSeasonsStr=cJSON_GetStringValue(cJSON_GetObjectItem(myJSON, "Seasons"));
|
||||
int myNumSeasons=0;
|
||||
if (numOfSeasonsStr!=NULL) {
|
||||
myNumSeasons=parseStrToInt(numOfSeasonsStr);
|
||||
}
|
||||
int uuid=thisThread->id;
|
||||
cJSON *episodesArray=cJSON_GetObjectItem(myJSON, "Episodes");
|
||||
cJSON *extrasArray=cJSON_GetObjectItem(myJSON, "Extras");
|
||||
@ -689,7 +701,6 @@ void *showHTML(void *threadArg) {
|
||||
fatalError_abort("showHTML error", " episodesArray or extrasArray were equal to NULL; JSON was:\n%s\n--- END ---\n ", cJSON_Print(myJSON));
|
||||
}
|
||||
printInfo("showHTML info", true, "building HTML for \"%s\";\n", showName);
|
||||
|
||||
cJSON *episode=NULL;
|
||||
|
||||
addData(this_show, SHOW_HTML_TOP);
|
||||
@ -702,15 +713,22 @@ void *showHTML(void *threadArg) {
|
||||
snprintf(tempStr, tempStrSize, SHOW_HTML_SEL, uuid);
|
||||
addData(this_show, tempStr);
|
||||
|
||||
while (currSeason<myNumSeasons) {
|
||||
currSeason++;
|
||||
tempStrSize=strlen(SHOW_HTML_OPT_SEASON)+intSize(currSeason)+intSize(currSeason)+1;
|
||||
tempStr=realloc(tempStr, tempStrSize);
|
||||
if (tempStr==NULL) {
|
||||
fatalError_abort("showHTML error", "could not realloc;\nError: %s;\n", strerror(errno));
|
||||
cJSON_ArrayForEach(episode, episodesArray) {
|
||||
int this_seasonNum=0;
|
||||
cJSON *jsonSeason=cJSON_GetObjectItem(episode, "Season");
|
||||
if (jsonSeason!=NULL) {
|
||||
this_seasonNum=parseStrToInt(cJSON_GetStringValue(jsonSeason));
|
||||
}
|
||||
if (this_seasonNum>currSeason) {
|
||||
currSeason=this_seasonNum;
|
||||
tempStrSize=strlen(SHOW_HTML_OPT_SEASON)+intSize(currSeason)+intSize(currSeason)+1;
|
||||
tempStr=realloc(tempStr, tempStrSize);
|
||||
if (tempStr==NULL) {
|
||||
fatalError_abort("showHTML error", "could not realloc;\nError: %s;\n", strerror(errno));
|
||||
}
|
||||
snprintf(tempStr, tempStrSize, SHOW_HTML_OPT_SEASON, currSeason, currSeason);
|
||||
addData(this_show, tempStr);
|
||||
}
|
||||
snprintf(tempStr, tempStrSize, SHOW_HTML_OPT_SEASON, currSeason, currSeason);
|
||||
addData(this_show, tempStr);
|
||||
}
|
||||
if (extrasArray!=NULL && cJSON_GetArraySize(extrasArray)>0) {
|
||||
currSeason++;
|
||||
@ -801,7 +819,7 @@ void episodeHTML(fileList *this_show, progConfig *conf, cJSON *episode, int *cur
|
||||
if (*currSeason>0) { // new season, so close prev season list
|
||||
addData(this_show, "\n</ul>\n");
|
||||
}
|
||||
(*currSeason)++;
|
||||
(*currSeason)=this_seasonNum;
|
||||
tempStrSize=intSize(*uuid)+intSize(*currSeason)+strlen(SHOW_HTML_UL)+1;
|
||||
tempStr=realloc(tempStr, tempStrSize);
|
||||
if (tempStr==NULL) {
|
||||
@ -835,12 +853,35 @@ void episodeHTML(fileList *this_show, progConfig *conf, cJSON *episode, int *cur
|
||||
snprintf(tempStr, tempStrSize, SHOW_HTML_SPAN, this_episodeName);
|
||||
addData(this_show, tempStr);
|
||||
|
||||
tempStrSize=intSize(*uuid)+intSize(*uuidEpisode)+strlen(this_file)+strlen(SHOW_HTML_VIDEO)+1;
|
||||
tempStr=realloc(tempStr, tempStrSize);
|
||||
if (tempStr==NULL) {
|
||||
fatalError_abort("episodeHTML error", "could not realloc;\nError: %s;\n", strerror(errno));
|
||||
if (strstr(this_file, ".webm") != NULL) {
|
||||
tempStrSize=intSize(*uuid)+intSize(*uuidEpisode)+strlen(this_file)+strlen(SHOW_HTML_VIDEO_WEBM)+1;
|
||||
tempStr=realloc(tempStr, tempStrSize);
|
||||
if (tempStr==NULL) {
|
||||
fatalError_abort("episodeHTML error", "could not realloc;\nError: %s;\n", strerror(errno));
|
||||
}
|
||||
snprintf(tempStr, tempStrSize, SHOW_HTML_VIDEO_WEBM, *uuid, *uuidEpisode, this_file);
|
||||
} else if (strstr(this_file, ".ogv") != NULL) {
|
||||
tempStrSize=intSize(*uuid)+intSize(*uuidEpisode)+strlen(this_file)+strlen(SHOW_HTML_VIDEO_OGG)+1;
|
||||
tempStr=realloc(tempStr, tempStrSize);
|
||||
if (tempStr==NULL) {
|
||||
fatalError_abort("episodeHTML error", "could not realloc;\nError: %s;\n", strerror(errno));
|
||||
}
|
||||
snprintf(tempStr, tempStrSize, SHOW_HTML_VIDEO_OGG, *uuid, *uuidEpisode, this_file);
|
||||
} else if (strstr(this_file, ".mp4") != NULL) {
|
||||
tempStrSize=intSize(*uuid)+intSize(*uuidEpisode)+strlen(this_file)+strlen(SHOW_HTML_VIDEO_MP4)+1;
|
||||
tempStr=realloc(tempStr, tempStrSize);
|
||||
if (tempStr==NULL) {
|
||||
fatalError_abort("episodeHTML error", "could not realloc;\nError: %s;\n", strerror(errno));
|
||||
}
|
||||
snprintf(tempStr, tempStrSize, SHOW_HTML_VIDEO_MP4, *uuid, *uuidEpisode, this_file);
|
||||
} else {
|
||||
tempStrSize=intSize(*uuid)+intSize(*uuidEpisode)+strlen(this_file)+strlen(SHOW_HTML_VIDEO)+1;
|
||||
tempStr=realloc(tempStr, tempStrSize);
|
||||
if (tempStr==NULL) {
|
||||
fatalError_abort("episodeHTML error", "could not realloc;\nError: %s;\n", strerror(errno));
|
||||
}
|
||||
snprintf(tempStr, tempStrSize, SHOW_HTML_VIDEO, *uuid, *uuidEpisode, this_file);
|
||||
}
|
||||
snprintf(tempStr, tempStrSize, SHOW_HTML_VIDEO, *uuid, *uuidEpisode, this_file);
|
||||
addData(this_show, tempStr);
|
||||
|
||||
cJSON *currSub=NULL;
|
||||
@ -893,7 +934,9 @@ void *cleanTV(void *threadArg) {
|
||||
cJSON *newJSON=cJSON_CreateArray();
|
||||
for (i=0; i<numThreads; i++) {
|
||||
pthread_join(threads[i], NULL);
|
||||
cJSON_AddItemToArray(newJSON, threadObj[i].oldJSON);
|
||||
if (threadObj[i].oldJSON != NULL) {
|
||||
cJSON_AddItemToArray(newJSON, threadObj[i].oldJSON);
|
||||
}
|
||||
}
|
||||
thisThread->oldJSON=cJSON_Duplicate(newJSON, true);
|
||||
cJSON_Delete(newJSON);
|
||||
@ -908,40 +951,87 @@ void *cleanTV(void *threadArg) {
|
||||
void *cleanShow(void *threadArg) {
|
||||
threadStruct *thisThread=threadArg;
|
||||
cJSON *show=thisThread->oldJSON;
|
||||
cJSON *episodesArray;
|
||||
cJSON *extrasArray;
|
||||
int episodesArraySize=0;
|
||||
int extrasArraySize=0;
|
||||
|
||||
if (show!=NULL && cJSON_GetObjectItem(show, "Episodes")!=NULL) {
|
||||
cJSON *episodesArray=cJSON_Duplicate(cJSON_GetObjectItem(show, "Episodes"), true);
|
||||
cJSON *episode=NULL;
|
||||
int i=0, numDeleted=0;
|
||||
cJSON_ArrayForEach(episode, episodesArray) {
|
||||
if (episode!=NULL && cJSON_GetObjectItem(episode, "File")!=NULL) {
|
||||
char *tempStr=cJSON_GetStringValue(cJSON_GetObjectItem(episode, "File"));
|
||||
if (tempStr!=NULL) {
|
||||
if (access(tempStr, F_OK)==0) {
|
||||
cJSON *subsArray=cJSON_Duplicate(cJSON_GetObjectItem(episode, "Subs"), true);
|
||||
int j=0, subsDeleted=0;
|
||||
cJSON *sub=NULL;
|
||||
cJSON_ArrayForEach(sub, subsArray) {
|
||||
char *tempSubStr=cJSON_GetStringValue(cJSON_GetObjectItem(sub, "subFile"));
|
||||
if (tempSubStr!=NULL) {
|
||||
if (access(tempSubStr, F_OK)!=0) {
|
||||
cJSON *tempSubs=cJSON_GetObjectItem(cJSON_GetArrayItem(cJSON_GetObjectItem(show, "Episodes"), i-numDeleted), "Subs");
|
||||
cJSON_DeleteItemFromArray(tempSubs, j-subsDeleted);
|
||||
subsDeleted++;
|
||||
if (show!=NULL) {
|
||||
if (cJSON_GetObjectItem(show, "Episodes")!=NULL) {
|
||||
episodesArray=cJSON_Duplicate(cJSON_GetObjectItem(show, "Episodes"), true);
|
||||
cJSON *episode=NULL;
|
||||
int i=0, numDeleted=0;
|
||||
cJSON_ArrayForEach(episode, episodesArray) {
|
||||
if (episode!=NULL && cJSON_GetObjectItem(episode, "File")!=NULL) {
|
||||
char *tempStr=cJSON_GetStringValue(cJSON_GetObjectItem(episode, "File"));
|
||||
if (tempStr!=NULL) {
|
||||
if (access(tempStr, F_OK)==0) {
|
||||
cJSON *subsArray=cJSON_Duplicate(cJSON_GetObjectItem(episode, "Subs"), true);
|
||||
int j=0, subsDeleted=0;
|
||||
cJSON *sub=NULL;
|
||||
cJSON_ArrayForEach(sub, subsArray) {
|
||||
char *tempSubStr=cJSON_GetStringValue(cJSON_GetObjectItem(sub, "subFile"));
|
||||
if (tempSubStr!=NULL) {
|
||||
if (access(tempSubStr, F_OK)!=0) {
|
||||
cJSON *tempSubs=cJSON_GetObjectItem(cJSON_GetArrayItem(cJSON_GetObjectItem(show, "Episodes"), i-numDeleted), "Subs");
|
||||
cJSON_DeleteItemFromArray(tempSubs, j-subsDeleted);
|
||||
subsDeleted++;
|
||||
}
|
||||
}
|
||||
j++;
|
||||
}
|
||||
j++;
|
||||
cJSON_Delete(subsArray);
|
||||
} else {
|
||||
cJSON_DeleteItemFromArray(cJSON_GetObjectItem(show, "Episodes"), i-numDeleted);
|
||||
numDeleted++;
|
||||
}
|
||||
cJSON_Delete(subsArray);
|
||||
} else {
|
||||
cJSON_DeleteItemFromArray(cJSON_GetObjectItem(show, "Episodes"), i-numDeleted);
|
||||
numDeleted++;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
episodesArraySize=cJSON_GetArraySize(episodesArray);
|
||||
cJSON_Delete(episodesArray);
|
||||
}
|
||||
if (cJSON_GetObjectItem(show, "Extras")!=NULL) {
|
||||
extrasArray=cJSON_Duplicate(cJSON_GetObjectItem(show, "Extras"), true);
|
||||
cJSON *extra=NULL;
|
||||
int i=0, numDeleted=0;
|
||||
cJSON_ArrayForEach(extra, extrasArray) {
|
||||
if (extra!=NULL && cJSON_GetObjectItem(extra, "File")!=NULL) {
|
||||
char *tempStr=cJSON_GetStringValue(cJSON_GetObjectItem(extra, "File"));
|
||||
if (tempStr!=NULL) {
|
||||
if (access(tempStr, F_OK)==0) {
|
||||
cJSON *subsArray=cJSON_Duplicate(cJSON_GetObjectItem(extra, "Subs"), true);
|
||||
int j=0, subsDeleted=0;
|
||||
cJSON *sub=NULL;
|
||||
cJSON_ArrayForEach(sub, subsArray) {
|
||||
char *tempSubStr=cJSON_GetStringValue(cJSON_GetObjectItem(sub, "subFile"));
|
||||
if (tempSubStr!=NULL) {
|
||||
if (access(tempSubStr, F_OK)!=0) {
|
||||
cJSON *tempSubs=cJSON_GetObjectItem(cJSON_GetArrayItem(cJSON_GetObjectItem(show, "Extras"), i-numDeleted), "Subs");
|
||||
cJSON_DeleteItemFromArray(tempSubs, j-subsDeleted);
|
||||
subsDeleted++;
|
||||
}
|
||||
}
|
||||
j++;
|
||||
}
|
||||
cJSON_Delete(subsArray);
|
||||
} else {
|
||||
cJSON_DeleteItemFromArray(cJSON_GetObjectItem(show, "Extras"), i-numDeleted);
|
||||
numDeleted++;
|
||||
}
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
extrasArraySize=cJSON_GetArraySize(extrasArray);
|
||||
cJSON_Delete(extrasArray);
|
||||
}
|
||||
if ((episodesArraySize+extrasArraySize) == 0) {
|
||||
//TODO: parse "Show" tag for filename then delete HTML show file?
|
||||
cJSON_Delete(thisThread->oldJSON);
|
||||
thisThread->oldJSON = NULL;
|
||||
}
|
||||
cJSON_Delete(episodesArray);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
#define TV_HTML_TOP "<!DOCTYPE html>\n<html>\n<head>\n<title>cmyflix</title>\n<meta http-equiv=\"Content-type\" content=\"text/html;charset=UTF-8\">\n<meta name=\"description\" content=\"Daria Rostirolla\">\n<meta name=\"keywords\" content=\"HTML, CSS\">\n<meta name=\"author\" content=\"Daria Rostirolla\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<link href=\"css/tv.css\" rel=\"stylesheet\" type=\"text/css\">\n<link rel=\"icon\" type=\"image/png\" href=\"img/favicon.png\">\n</head>\n<body>\n<script type=\"text/javascript\" src=\"js/mainTVScript.js\"></script>\n<div id=\"wrapper\">\n"
|
||||
|
||||
#define TV_HTML_FRAME "<div class=\"showDiv\">\n<input id=\"A%zu\" class=\"myBtn\" alt=\"%s\" onclick=\"javascript:setFrame(this, \'%s\' )\" type=\"image\" src=\"%s\" onload=\"javascript:setAlt(this, \'%s\')\">\n<div id=\"B%zu\" class=\"modal\">\n<div id=\"frameDiv%zu\" class=\"modal-content\">\n<iframe id=\"IN%zu\" src=\"\" frameborder=\"0\" onload=\"javascript:resizeFrame(this)\" allowfullscreen></iframe>\n</div>\n</div>\n</div>\n"
|
||||
#define TV_HTML_FRAME "<div class=\"showDiv\">\n<input id=\"A%d\" class=\"myBtn\" alt=\"%s\" onclick=\"javascript:setFrame(this, \'%s\' )\" type=\"image\" src=\"%s\" onload=\"javascript:setAlt(this, \'%s\')\">\n<div id=\"B%d\" class=\"modal\">\n<div id=\"frameDiv%d\" class=\"modal-content\">\n<iframe id=\"IN%d\" src=\"\" frameborder=\"0\" onload=\"javascript:resizeFrame(this)\" allowfullscreen></iframe>\n</div>\n</div>\n</div>\n"
|
||||
|
||||
#define TV_HTML_BOT "\n<div id=\"paddingDiv\">\n</div>\n</div>\n</body>\n</html>"
|
||||
|
||||
@ -26,7 +26,10 @@
|
||||
|
||||
#define SHOW_HTML_SPAN "<span onclick=\"javascript:hideVideoModal()\" class=\"close\">×</span>\n<p id=\"epTitle\">%s</p>"
|
||||
|
||||
#define SHOW_HTML_VIDEO "\n<video id=\"F%d_%d\" class=\"video_player\" controls preload=\"none\" onplaying=\"javascript:rezHandler()\">\n<source src=\"../%s\" type=\"video/mp4\">"
|
||||
#define SHOW_HTML_VIDEO "\n<video id=\"F%d_%d\" class=\"video_player\" controls preload=\"none\" onplaying=\"javascript:rezHandler()\">\n<source src=\"../%s\">"
|
||||
#define SHOW_HTML_VIDEO_WEBM "\n<video id=\"F%d_%d\" class=\"video_player\" controls preload=\"none\" onplaying=\"javascript:rezHandler()\">\n<source src=\"../%s\" type=\"video/webm\">"
|
||||
#define SHOW_HTML_VIDEO_MP4 "\n<video id=\"F%d_%d\" class=\"video_player\" controls preload=\"none\" onplaying=\"javascript:rezHandler()\">\n<source src=\"../%s\" type=\"video/mp4\">"
|
||||
#define SHOW_HTML_VIDEO_OGG "\n<video id=\"F%d_%d\" class=\"video_player\" controls preload=\"none\" onplaying=\"javascript:rezHandler()\">\n<source src=\"../%s\" type=\"video/ogg\">"
|
||||
|
||||
#define SHOW_HTML_SUBS "\n<track src=\"../%s\" kind=\"subtitles\" label=\"%s\">"
|
||||
|
||||
|
18
src/utils.c
18
src/utils.c
@ -603,7 +603,7 @@ char *randStr(size_t size) {
|
||||
char *getSubs(progConfig *conf, char *fileStr, char *filePath) {
|
||||
char *epSubs=NULL;
|
||||
char *fileName=removeExtension(fileStr);
|
||||
fileList *subs=find(conf, filePath, fileName, FI_MODE, false);
|
||||
fileList *subs=find(conf, filePath, (char *[]){fileName, NULL}, FI_MODE, false);
|
||||
|
||||
for (fileList *tempSub=subs; tempSub!=NULL; tempSub=tempSub->next) {
|
||||
if (tempSub->dataSize>2) {
|
||||
@ -780,7 +780,7 @@ char *getPoster(const char *posterURL, progConfig *conf, int prefImgWidth, doubl
|
||||
cJSON *lang=cJSON_DetachItemFromObject(item, "iso_639_1");
|
||||
|
||||
if ((width!=NULL && cJSON_GetNumberValue(width)==prefImgWidth) || (ratio!=NULL && cJSON_GetNumberValue(ratio)==prefImgRatio)) {
|
||||
if (lang!=NULL && cJSON_GetStringValue(lang)!=NULL && strcmp(cJSON_GetStringValue(lang), prefImgLang)==0) {
|
||||
if ((prefImgLang!=NULL && lang!=NULL && cJSON_GetStringValue(lang)!=NULL && strcmp(cJSON_GetStringValue(lang), prefImgLang)==0) || prefImgLang==NULL) {
|
||||
cJSON *imgStr=cJSON_DetachItemFromObject(item, "file_path");
|
||||
if (imgStr!=NULL && cJSON_GetStringValue(imgStr)!=NULL) {
|
||||
size_t urlLen=strlen(tmdbImg)+strlen(cJSON_GetStringValue(imgStr))+1;
|
||||
@ -791,10 +791,10 @@ char *getPoster(const char *posterURL, progConfig *conf, int prefImgWidth, doubl
|
||||
}
|
||||
cJSON_Delete(imgStr);
|
||||
}
|
||||
cJSON_Delete(width);
|
||||
cJSON_Delete(ratio);
|
||||
cJSON_Delete(lang);
|
||||
}
|
||||
cJSON_Delete(width);
|
||||
cJSON_Delete(ratio);
|
||||
cJSON_Delete(lang);
|
||||
} else {
|
||||
printError("getPoster warning", true, HYEL, "request error, URL: '%s';\nitem==NULL - json_posters was:\n", posterURL);
|
||||
char *tempStr=cJSON_Print(json_posters);
|
||||
@ -805,13 +805,12 @@ char *getPoster(const char *posterURL, progConfig *conf, int prefImgWidth, doubl
|
||||
cJSON_Delete(item);
|
||||
}
|
||||
if (imgURL==NULL) {
|
||||
printError("getPoster warning", true, HYEL, "request error, URL: '%s';\nitem==NULL - json_posters was:\n", posterURL);
|
||||
printError("getPoster warning", true, HYEL, "request error, URL: '%s';\nCould not find a poster - json_posters was:\n", posterURL);
|
||||
char *tempStr=cJSON_Print(json_posters);
|
||||
printError("", true, COLOR_RESET, tempStr);
|
||||
printError("", true, HYEL, "\nEND;\n");
|
||||
tryFree(tempStr);
|
||||
}
|
||||
cJSON_Delete(json_posters);
|
||||
} else {
|
||||
printError("getPoster warning", true, HYEL, "request error, URL: '%s';\njson_posters==NULL - json_root was:\n", posterURL);
|
||||
char *tempStr=cJSON_Print(json_root);
|
||||
@ -819,10 +818,11 @@ char *getPoster(const char *posterURL, progConfig *conf, int prefImgWidth, doubl
|
||||
printError("", true, HYEL, "\nEND;\n");
|
||||
tryFree(tempStr);
|
||||
}
|
||||
cJSON_Delete(json_root);
|
||||
cJSON_Delete(json_posters);
|
||||
} else {
|
||||
printError("getPoster warning", true, HYEL, "request error, URL: '%s';\njson_root==NULL\n", posterURL);
|
||||
}
|
||||
cJSON_Delete(json_root);
|
||||
freeBlock(mem);
|
||||
return imgURL;
|
||||
}
|
||||
@ -936,7 +936,7 @@ int fixMode(progConfig *conf, progFlags flags, const char *toFix, const char *id
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags & SHOWS_MODE) && conf->getEpisodeName && refreshMode) {
|
||||
if ((flags & SHOWS_MODE) && (flags & FIX_TITLES_MODE) && refreshMode) {
|
||||
int tempID=parseStrToInt(id);
|
||||
cJSON *this_episodes=cJSON_GetObjectItem(element, "Episodes");
|
||||
cJSON *episode=NULL;
|
||||
|
@ -14,7 +14,7 @@
|
||||
#define tmdbTV_ID "https://api.themoviedb.org/3/search/tv?page=1&query=" // name&api_key=blah +opts
|
||||
#define tmdbTV_Opts "&language=en" //to find the ID based on name
|
||||
#define tmdbImg "https://image.tmdb.org/t/p/original"
|
||||
#define videoExt "mp4"
|
||||
#define videoExt (char *[]){"mp4", "mkv", "ogv", "webm", NULL}
|
||||
#define subExt1 "srt"
|
||||
#define subExt2 "vtt"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user