hmml_to_html.c: Cache the quotes

Also link to insofaras' quote site
This commit is contained in:
Matt Mascarenhas 2017-08-10 02:05:41 +01:00
parent 5f21a9544d
commit ec556a8e3b
2 changed files with 153 additions and 54 deletions

View File

@ -465,7 +465,8 @@ function handleKey(key) {
case "o": { case "o": {
if(focusedElement) 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"); var url = focusedElement.getAttribute("href");
window.open(url, "_blank"); window.open(url, "_blank");

View File

@ -19,6 +19,8 @@ typedef unsigned int bool;
#include <getopt.h> // NOTE(matt): getopts #include <getopt.h> // NOTE(matt): getopts
//#include "config.h" // TODO(matt): Implement config.h //#include "config.h" // TODO(matt): Implement config.h
#include <curl/curl.h> #include <curl/curl.h>
#include <time.h>
#include <sys/stat.h>
#define Kilobytes(Bytes) Bytes << 10 #define Kilobytes(Bytes) Bytes << 10
#define Megabytes(Bytes) Bytes << 20 #define Megabytes(Bytes) Bytes << 20
@ -823,40 +825,11 @@ CurlIntoBuffer(char *InPtr, size_t CharLength, size_t Chars, char **OutputPtr)
return Length; return Length;
}; };
#include <time.h>
int 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; QuoteStaging.Ptr = QuoteStaging.Location;
while(QuoteStaging.Ptr - QuoteStaging.Location < CacheSize)
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)
{ {
char InID[4] = { 0 }; char InID[4] = { 0 };
char InTime[16] = { 0 }; char InTime[16] = { 0 };
@ -900,9 +873,85 @@ BuildQuote(quote_info *Info, char *Speaker, int ID)
++QuoteStaging.Ptr; ++QuoteStaging.Ptr;
} }
} }
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); FreeBuffer(&QuoteStaging);
return 1; return 1;
}
}
return 0;
} }
void void
@ -1308,6 +1357,16 @@ main(int ArgC, char **Args)
bool DefaultForceIntegration = FALSE; bool DefaultForceIntegration = FALSE;
bool ForceIntegration = DefaultForceIntegration; 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) if(ArgC < 2)
{ {
PrintUsage(Args[0], DefaultCSSDir, DefaultImagesDir, DefaultJSDir, DefaultDefaultMedium, DefaultOutLocation, DefaultTemplateLocation); PrintUsage(Args[0], DefaultCSSDir, DefaultImagesDir, DefaultJSDir, DefaultDefaultMedium, DefaultOutLocation, DefaultTemplateLocation);
@ -2084,7 +2143,10 @@ main(int ArgC, char **Args)
HasQuote = TRUE; 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", fprintf(stderr, "%s:%d: Quote #%s %d not found. Unlucky!\n",
Args[FileIndex], Args[FileIndex],
@ -2098,10 +2160,13 @@ main(int ArgC, char **Args)
} }
CopyStringToBuffer(&QuoteMenu, CopyStringToBuffer(&QuoteMenu,
" <span data-id=\"&#%d;\" class=\"ref\">\n" " <a target=\"_blank\" class=\"ref\" href=\"https://dev.abaines.me.uk/quotes/%s/%d\">\n"
" <span data-id=\"&#%d;\">\n"
" <span class=\"ref_content\">\n" " <span class=\"ref_content\">\n"
" <div class=\"source\">Quote %d</div>\n" " <div class=\"source\">Quote %d</div>\n"
" <div class=\"ref_title\">", " <div class=\"ref_title\">",
Anno->quote.author ? Anno->quote.author : HMML.metadata.stream_username ? HMML.metadata.stream_username : HMML.metadata.member,
Anno->quote.id,
QuoteIdentifier, QuoteIdentifier,
Anno->quote.id); Anno->quote.id);
@ -2113,7 +2178,8 @@ main(int ArgC, char **Args)
" <div class=\"ref_indices\">\n" " <div class=\"ref_indices\">\n"
" <span data-timestamp=\"%d\" class=\"timecode\"><span class=\"ref_index\">[&#%d;]</span><span class=\"time\">%s</span></span>\n" " <span data-timestamp=\"%d\" class=\"timecode\"><span class=\"ref_index\">[&#%d;]</span><span class=\"time\">%s</span></span>\n"
" </div>\n" " </div>\n"
" </span>\n", " </span>\n"
" </a>\n",
Anno->quote.author ? Anno->quote.author : HMML.metadata.stream_username ? HMML.metadata.stream_username : HMML.metadata.member, Anno->quote.author ? Anno->quote.author : HMML.metadata.stream_username ? HMML.metadata.stream_username : HMML.metadata.member,
QuoteInfo.Date, QuoteInfo.Date,
TimecodeToSeconds(Anno->time), TimecodeToSeconds(Anno->time),
@ -2531,34 +2597,66 @@ main(int ArgC, char **Args)
" <span style=\"width: auto\" class=\"help_key unavailable\">Enter</span> <span class=\"help_text unavailable\">Jump to timecode</span><br>\n"); " <span style=\"width: auto\" class=\"help_key unavailable\">Enter</span> <span class=\"help_text unavailable\">Jump to timecode</span><br>\n");
} }
if(HasQuoteMenu)
{
CopyStringToBuffer(&Menus,
" <h2>Quotes");
if(HasReferenceMenu) if(HasReferenceMenu)
{ {
CopyStringToBuffer(&Menus, CopyStringToBuffer(&Menus, ", References ");
" <h2>References ");
if(HasCreditsMenu) if(HasCreditsMenu)
{ {
CopyStringToBuffer(&Menus, "and Credits Menus</h2>\n"); CopyStringToBuffer(&Menus, "and Credits Menus</h2>");
} }
else else
{ {
CopyStringToBuffer(&Menus, "<span class=\"unavailable\">and Credits</span> Menus</h2>\n"); CopyStringToBuffer(&Menus, "<span class=\"unavailable\">and Credits</span> Menus</h2>");
}
}
else
{
CopyStringToBuffer(&Menus, "<span class=\"unavailable\">, References ");
if(HasCreditsMenu)
{
CopyStringToBuffer(&Menus, "</span>and Credits Menus</h2>");
}
else
{
CopyStringToBuffer(&Menus, "and Credits</span> Menus</h2>");
}
} }
} }
else else
{ {
CopyStringToBuffer(&Menus, CopyStringToBuffer(&Menus,
" <h2><span class=\"unavailable\">References"); " <h2><span class=\"unavailable\">Quotes");
if(HasReferenceMenu)
{
CopyStringToBuffer(&Menus, ", </span>References ");
if(HasCreditsMenu) if(HasCreditsMenu)
{ {
CopyStringToBuffer(&Menus, " and</span> Credits Menus</h2>\n"); CopyStringToBuffer(&Menus, "and Credits Menus</h2>");
} }
else else
{ {
CopyStringToBuffer(&Menus, " and Credits Menus</span></h2>\n"); CopyStringToBuffer(&Menus, "<span class=\"unavailable\">and Credits</span> Menus</h2>");
}
}
else
{
CopyStringToBuffer(&Menus, ", References ");
if(HasCreditsMenu)
{
CopyStringToBuffer(&Menus, "</span>and Credits Menus</h2>");
}
else
{
CopyStringToBuffer(&Menus, "and Credits Menus</h2></span>");
}
} }
} }
if(HasReferenceMenu || HasCreditsMenu) if(HasQuoteMenu || HasReferenceMenu || HasCreditsMenu)
{ {
CopyStringToBuffer(&Menus, CopyStringToBuffer(&Menus,
" <span class=\"help_key\">o</span> <span class=\"help_text\">Open URL (in new tab)</span>\n"); " <span class=\"help_key\">o</span> <span class=\"help_text\">Open URL (in new tab)</span>\n");