From ec556a8e3b668af9d43fd8ae2815e1fa9989d5f6 Mon Sep 17 00:00:00 2001 From: Matt Mascarenhas Date: Thu, 10 Aug 2017 02:05:41 +0100 Subject: [PATCH] hmml_to_html.c: Cache the quotes Also link to insofaras' quote site --- hmml_to_html/cinera.js | 3 +- hmml_to_html/hmml_to_html.c | 204 ++++++++++++++++++++++++++---------- 2 files changed, 153 insertions(+), 54 deletions(-) diff --git a/hmml_to_html/cinera.js b/hmml_to_html/cinera.js index dae3863..792d0f5 100644 --- a/hmml_to_html/cinera.js +++ b/hmml_to_html/cinera.js @@ -465,7 +465,8 @@ function handleKey(key) { case "o": { if(focusedElement) { - if(focusedElement.parentNode.classList.contains("references_container")) + if(focusedElement.parentNode.classList.contains("references_container") || + focusedElement.parentNode.classList.contains("quotes_container")) { var url = focusedElement.getAttribute("href"); window.open(url, "_blank"); diff --git a/hmml_to_html/hmml_to_html.c b/hmml_to_html/hmml_to_html.c index 3243da1..9dffed6 100644 --- a/hmml_to_html/hmml_to_html.c +++ b/hmml_to_html/hmml_to_html.c @@ -19,6 +19,8 @@ typedef unsigned int bool; #include // NOTE(matt): getopts //#include "config.h" // TODO(matt): Implement config.h #include +#include +#include #define Kilobytes(Bytes) Bytes << 10 #define Megabytes(Bytes) Bytes << 20 @@ -823,40 +825,11 @@ CurlIntoBuffer(char *InPtr, size_t CharLength, size_t Chars, char **OutputPtr) return Length; }; -#include - int -BuildQuote(quote_info *Info, char *Speaker, int ID) +SearchQuotes(buffer QuoteStaging, int CacheSize, quote_info *Info, int ID) { - char QuotesURL[256]; - CopyString(QuotesURL, "https://dev.abaines.me.uk/quotes/%s.raw", Speaker); - - buffer QuoteStaging; - QuoteStaging.ID = "QuoteStaging"; - QuoteStaging.Size = Kilobytes(256); - if(!(QuoteStaging.Location = malloc(QuoteStaging.Size))) - { - perror("malloc"); - } QuoteStaging.Ptr = QuoteStaging.Location; - - 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); - } - - // TODO(matt): Search the quote store in reverse - QuoteStaging.Ptr = QuoteStaging.Location; - - while(*QuoteStaging.Ptr) + while(QuoteStaging.Ptr - QuoteStaging.Location < CacheSize) { char InID[4] = { 0 }; char InTime[16] = { 0 }; @@ -900,11 +873,87 @@ BuildQuote(quote_info *Info, char *Speaker, int ID) ++QuoteStaging.Ptr; } } - - FreeBuffer(&QuoteStaging); return 1; } +int +BuildQuote(quote_info *Info, char *Speaker, int ID, char *CacheDir) +{ + // TODO(matt): Rebuild cache option + + char QuoteCacheDir[255]; + CopyString(QuoteCacheDir, "%s/quotes", CacheDir); + char QuoteCachePath[255]; + CopyString(QuoteCachePath, "%s/%s", QuoteCacheDir, Speaker); + FILE *QuoteCache; + + while(!(QuoteCache = fopen(QuoteCachePath, "a+"))) + { + char StagingDirectory[255]; + CopyString(StagingDirectory, QuoteCacheDir); + while(mkdir(StagingDirectory, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == -1) + { + int i = StringLength(StagingDirectory); + while(StagingDirectory[i] != '/') + { + --i; + } + StagingDirectory[i] = '\0'; + } + } + + fseek(QuoteCache, 0, SEEK_END); + int FileSize = ftell(QuoteCache); + fseek(QuoteCache, 0, SEEK_SET); + + buffer QuoteStaging; + QuoteStaging.ID = "QuoteStaging"; + QuoteStaging.Size = Kilobytes(256); + if(!(QuoteStaging.Location = malloc(QuoteStaging.Size))) + { + perror("malloc"); + } + QuoteStaging.Ptr = QuoteStaging.Location; + + fread(QuoteStaging.Location, FileSize, 1, QuoteCache); + fclose(QuoteCache); + + if(SearchQuotes(QuoteStaging, FileSize, Info, ID) == 1) + { + char QuotesURL[256]; + CopyString(QuotesURL, "https://dev.abaines.me.uk/quotes/%s.raw", Speaker); + + 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); + fclose(QuoteCache); + + int CacheSize = QuoteStaging.Ptr - QuoteStaging.Location; + QuoteStaging.Ptr = QuoteStaging.Location; + if(SearchQuotes(QuoteStaging, CacheSize, Info, ID) == 1) + { + FreeBuffer(&QuoteStaging); + return 1; + } + } + return 0; +} + void GenerateTopicColours(buffer *Colour, char *Topic, char *TopicsDir) { @@ -1308,6 +1357,16 @@ main(int ArgC, char **Args) bool DefaultForceIntegration = FALSE; bool ForceIntegration = DefaultForceIntegration; + char CacheDir[255] = { 0 }; + if(getenv("XDG_CACHE_HOME")) + { + CopyString(CacheDir, "%s/cinera", getenv("XDG_CACHE_HOME")); + } + else + { + CopyString(CacheDir, "%s/.cache/cinera", getenv("HOME")); + } + if(ArgC < 2) { PrintUsage(Args[0], DefaultCSSDir, DefaultImagesDir, DefaultJSDir, DefaultDefaultMedium, DefaultOutLocation, DefaultTemplateLocation); @@ -2084,7 +2143,10 @@ main(int ArgC, char **Args) HasQuote = TRUE; - if(BuildQuote(&QuoteInfo, Anno->quote.author ? Anno->quote.author : HMML.metadata.stream_username ? HMML.metadata.stream_username : HMML.metadata.member, Anno->quote.id) == 1) + if(BuildQuote(&QuoteInfo, + Anno->quote.author ? Anno->quote.author : HMML.metadata.stream_username ? HMML.metadata.stream_username : HMML.metadata.member, + Anno->quote.id, + CacheDir) == 1) { fprintf(stderr, "%s:%d: Quote #%s %d not found. Unlucky!\n", Args[FileIndex], @@ -2098,22 +2160,26 @@ main(int ArgC, char **Args) } CopyStringToBuffer(&QuoteMenu, - " \n" - " \n" - "
Quote %d
\n" - "
", + " \n" + " \n" + " \n" + "
Quote %d
\n" + "
", + Anno->quote.author ? Anno->quote.author : HMML.metadata.stream_username ? HMML.metadata.stream_username : HMML.metadata.member, + Anno->quote.id, QuoteIdentifier, Anno->quote.id); CopyStringToBufferCSVSafe(&QuoteMenu, QuoteInfo.Text); CopyStringToBuffer(&QuoteMenu, "
\n" - " \n" + " \n" + "
\n" + "
\n" + " [&#%d;]%s\n" + "
\n" "
\n" - "
\n" - " [&#%d;]%s\n" - "
\n" - " \n", + "
\n", Anno->quote.author ? Anno->quote.author : HMML.metadata.stream_username ? HMML.metadata.stream_username : HMML.metadata.member, QuoteInfo.Date, TimecodeToSeconds(Anno->time), @@ -2531,34 +2597,66 @@ main(int ArgC, char **Args) " Enter Jump to timecode
\n"); } - if(HasReferenceMenu) + if(HasQuoteMenu) { CopyStringToBuffer(&Menus, - "

References "); - if(HasCreditsMenu) + "

Quotes"); + if(HasReferenceMenu) { - CopyStringToBuffer(&Menus, "and Credits Menus

\n"); + CopyStringToBuffer(&Menus, ", References "); + if(HasCreditsMenu) + { + CopyStringToBuffer(&Menus, "and Credits Menus"); + } + else + { + CopyStringToBuffer(&Menus, "and Credits Menus"); + } } else { - CopyStringToBuffer(&Menus, "and Credits Menus\n"); + CopyStringToBuffer(&Menus, ", References "); + if(HasCreditsMenu) + { + CopyStringToBuffer(&Menus, "and Credits Menus"); + } + else + { + CopyStringToBuffer(&Menus, "and Credits Menus"); + } } } else { CopyStringToBuffer(&Menus, - "

References"); - if(HasCreditsMenu) + "

Quotes"); + if(HasReferenceMenu) { - CopyStringToBuffer(&Menus, " and Credits Menus

\n"); + CopyStringToBuffer(&Menus, ",
References "); + if(HasCreditsMenu) + { + CopyStringToBuffer(&Menus, "and Credits Menus

"); + } + else + { + CopyStringToBuffer(&Menus, "and Credits Menus"); + } } else { - CopyStringToBuffer(&Menus, " and Credits Menus\n"); + CopyStringToBuffer(&Menus, ", References "); + if(HasCreditsMenu) + { + CopyStringToBuffer(&Menus, "and Credits Menus"); + } + else + { + CopyStringToBuffer(&Menus, "and Credits Menus"); + } } } - if(HasReferenceMenu || HasCreditsMenu) + if(HasQuoteMenu || HasReferenceMenu || HasCreditsMenu) { CopyStringToBuffer(&Menus, " o Open URL (in new tab)\n");