diff --git a/hmml_to_html/hmml_to_html.c b/hmml_to_html/hmml_to_html.c index 9dffed6..9499289 100644 --- a/hmml_to_html/hmml_to_html.c +++ b/hmml_to_html/hmml_to_html.c @@ -859,7 +859,7 @@ SearchQuotes(buffer QuoteStaging, int CacheSize, quote_info *Info, int ID) { *OutPtr++ = *QuoteStaging.Ptr++; } - *--OutPtr = '\0'; + *OutPtr = '\0'; FreeBuffer(&QuoteStaging); return 0; @@ -876,6 +876,54 @@ SearchQuotes(buffer QuoteStaging, int CacheSize, quote_info *Info, int ID) return 1; } +int +MakeDir(char *Path) +{ + int i = StringLength(Path); + int Ancestors = 0; + while(mkdir(Path, 00755) == -1) + { + while(Path[i] != '/' && i > 0) + { + --i; + } + ++Ancestors; + Path[i] = '\0'; + if(i == 0) { return 1; } + } + while(Ancestors > 0) + { + while(Path[i] != '\0') + { + ++i; + } + Path[i] = '/'; + --Ancestors; + if((mkdir(Path, 00755)) == -1) + { + return 1; + } + } + return 0; +} + +void +CurlQuotes(buffer *QuoteStaging, char *QuotesURL) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &QuoteStaging->Ptr); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlIntoBuffer); + curl_easy_setopt(curl, CURLOPT_URL, QuotesURL); + if((res = curl_easy_perform(curl))) + { + fprintf(stderr, "%s", curl_easy_strerror(res)); + } + curl_easy_cleanup(curl); + } +} + int BuildQuote(quote_info *Info, char *Speaker, int ID, char *CacheDir) { @@ -886,25 +934,29 @@ BuildQuote(quote_info *Info, char *Speaker, int ID, char *CacheDir) char QuoteCachePath[255]; CopyString(QuoteCachePath, "%s/%s", QuoteCacheDir, Speaker); FILE *QuoteCache; + char QuotesURL[256]; + CopyString(QuotesURL, "https://dev.abaines.me.uk/quotes/%s.raw", Speaker); + bool CacheAvailable = FALSE; - while(!(QuoteCache = fopen(QuoteCachePath, "a+"))) + if(!(QuoteCache = fopen(QuoteCachePath, "a+"))) { - char StagingDirectory[255]; - CopyString(StagingDirectory, QuoteCacheDir); - while(mkdir(StagingDirectory, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == -1) + if(MakeDir(QuoteCacheDir) == 0) { - int i = StringLength(StagingDirectory); - while(StagingDirectory[i] != '/') - { - --i; - } - StagingDirectory[i] = '\0'; + CacheAvailable = TRUE; + }; + if(!(QuoteCache = fopen(QuoteCachePath, "a+"))) + { + perror(QuoteCachePath); + } + else + { + CacheAvailable = TRUE; } } - - fseek(QuoteCache, 0, SEEK_END); - int FileSize = ftell(QuoteCache); - fseek(QuoteCache, 0, SEEK_SET); + else + { + CacheAvailable = TRUE; + } buffer QuoteStaging; QuoteStaging.ID = "QuoteStaging"; @@ -915,34 +967,38 @@ BuildQuote(quote_info *Info, char *Speaker, int ID, char *CacheDir) } QuoteStaging.Ptr = QuoteStaging.Location; - fread(QuoteStaging.Location, FileSize, 1, QuoteCache); - fclose(QuoteCache); - - if(SearchQuotes(QuoteStaging, FileSize, Info, ID) == 1) + if(CacheAvailable) { - char QuotesURL[256]; - CopyString(QuotesURL, "https://dev.abaines.me.uk/quotes/%s.raw", Speaker); + fseek(QuoteCache, 0, SEEK_END); + int FileSize = ftell(QuoteCache); + fseek(QuoteCache, 0, SEEK_SET); - CURL *curl = curl_easy_init(); - if(curl) { - CURLcode res; - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &QuoteStaging.Ptr); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlIntoBuffer); - curl_easy_setopt(curl, CURLOPT_URL, QuotesURL); - if((res = curl_easy_perform(curl))) - { - fprintf(stderr, "%s", curl_easy_strerror(res)); - } - curl_easy_cleanup(curl); - } - - if(!(QuoteCache = fopen(QuoteCachePath, "w"))) - { - perror(QuoteCachePath); - } - fwrite(QuoteStaging.Location, QuoteStaging.Ptr - QuoteStaging.Location, 1, QuoteCache); + fread(QuoteStaging.Location, FileSize, 1, QuoteCache); fclose(QuoteCache); + if(SearchQuotes(QuoteStaging, FileSize, Info, ID) == 1) + { + CurlQuotes(&QuoteStaging, QuotesURL); + + if(!(QuoteCache = fopen(QuoteCachePath, "w"))) + { + perror(QuoteCachePath); + } + fwrite(QuoteStaging.Location, QuoteStaging.Ptr - QuoteStaging.Location, 1, QuoteCache); + fclose(QuoteCache); + + int CacheSize = QuoteStaging.Ptr - QuoteStaging.Location; + QuoteStaging.Ptr = QuoteStaging.Location; + if(SearchQuotes(QuoteStaging, CacheSize, Info, ID) == 1) + { + FreeBuffer(&QuoteStaging); + return 1; + } + } + } + else + { + CurlQuotes(&QuoteStaging, QuotesURL); int CacheSize = QuoteStaging.Ptr - QuoteStaging.Location; QuoteStaging.Ptr = QuoteStaging.Location; if(SearchQuotes(QuoteStaging, CacheSize, Info, ID) == 1) @@ -951,6 +1007,7 @@ BuildQuote(quote_info *Info, char *Speaker, int ID, char *CacheDir) return 1; } } + return 0; } @@ -2143,21 +2200,36 @@ main(int ArgC, char **Args) HasQuote = TRUE; + char *Speaker = Anno->quote.author ? Anno->quote.author : HMML.metadata.stream_username ? HMML.metadata.stream_username : HMML.metadata.member; if(BuildQuote(&QuoteInfo, - Anno->quote.author ? Anno->quote.author : HMML.metadata.stream_username ? HMML.metadata.stream_username : HMML.metadata.member, + Speaker, Anno->quote.id, CacheDir) == 1) { fprintf(stderr, "%s:%d: Quote #%s %d not found. Unlucky!\n", Args[FileIndex], Anno->line, - Anno->quote.author ? Anno->quote.author : HMML.metadata.stream_username ? HMML.metadata.stream_username : HMML.metadata.member, + Speaker, Anno->quote.id); hmml_free(&HMML); free(MemoryArena.Location); free(Template.Location); return 1; } + if(BuildQuote(&QuoteInfo, + Speaker, + Anno->quote.id, + CacheDir) == 2) + { + fprintf(stderr, "%s:%d: Failed to create quote cache at %s/quotes/%s for Quote #%s %d.\n" + "Proceeding anyway, without a cache!\n", + Args[FileIndex], + Anno->line, + CacheDir, + Speaker, + Speaker, + Anno->quote.id); + } CopyStringToBuffer(&QuoteMenu, " \n" @@ -2165,7 +2237,7 @@ main(int ArgC, char **Args) " \n" "
Quote %d
\n" "
", - Anno->quote.author ? Anno->quote.author : HMML.metadata.stream_username ? HMML.metadata.stream_username : HMML.metadata.member, + Speaker, Anno->quote.id, QuoteIdentifier, Anno->quote.id); @@ -2180,7 +2252,7 @@ main(int ArgC, char **Args) "
\n" "
\n" "
\n", - Anno->quote.author ? Anno->quote.author : HMML.metadata.stream_username ? HMML.metadata.stream_username : HMML.metadata.member, + Speaker, QuoteInfo.Date, TimecodeToSeconds(Anno->time), QuoteIdentifier,