hmml_to_html.c: Pull from insobot's quote store

#25

Also fix the forced integration
This commit is contained in:
Matt Mascarenhas 2017-08-09 01:57:09 +01:00
parent ad8fb22211
commit 5f21a9544d
1 changed files with 95 additions and 72 deletions

View File

@ -1,6 +1,6 @@
#if 0 #if 0
ctime -begin ${0%.*}.ctm ctime -begin ${0%.*}.ctm
gcc -g -no-pie -fsanitize=address -Wall -std=c99 -pipe $0 -o ${0%.*} hmml.a gcc -g -no-pie -fsanitize=address -Wall -std=c99 -pipe $0 -o ${0%.*} hmml.a -lcurl
ctime -end ${0%.*}.ctm ctime -end ${0%.*}.ctm
exit exit
#endif #endif
@ -18,6 +18,7 @@ typedef unsigned int bool;
#include "hmmlib.h" #include "hmmlib.h"
#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>
#define Kilobytes(Bytes) Bytes << 10 #define Kilobytes(Bytes) Bytes << 10
#define Megabytes(Bytes) Bytes << 20 #define Megabytes(Bytes) Bytes << 20
@ -809,78 +810,98 @@ StringToInt(char *String)
return Result; return Result;
} }
int size_t
BuildQuote(quote_info *Info, char *Speaker, int ID, char *QuoteDir) CurlIntoBuffer(char *InPtr, size_t CharLength, size_t Chars, char **OutputPtr)
{ {
char Path[255] = {0}; int Length = CharLength * Chars;
sprintf(Path, "%s/#%s", QuoteDir, Speaker); int i;
FILE *File; for(i = 0; InPtr[i] && i < Length; ++i)
if(!(File = fopen(Path, "r")))
{ {
perror(Path); *((*OutputPtr)++) = InPtr[i];
return 1;
} }
**OutputPtr = '\0';
return Length;
};
fseek(File, 0, SEEK_END); #include <time.h>
int Length = ftell(File);
fseek(File, 0, SEEK_SET); int
char *Buffer; BuildQuote(quote_info *Info, char *Speaker, int ID)
if(!(Buffer = malloc(Length))) {
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("BuildQuote"); 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);
} }
fread(Buffer, Length, 1, File);
fclose(File);
// TODO(matt): Search the quote store in reverse // TODO(matt): Search the quote store in reverse
char *InPtr = Buffer; QuoteStaging.Ptr = QuoteStaging.Location;
while(InPtr - Buffer < Length) while(*QuoteStaging.Ptr)
{ {
char InID[4] = { 0 }; char InID[4] = { 0 };
char InTime[16] = { 0 };
char *OutPtr = InID; char *OutPtr = InID;
while(*InPtr != ',') while(*QuoteStaging.Ptr != ',')
{ {
*OutPtr++ = *InPtr++; *OutPtr++ = *QuoteStaging.Ptr++;
} }
*OutPtr = '\0'; *OutPtr = '\0';
if(StringToInt(InID) == ID) if(StringToInt(InID) == ID)
{ {
InPtr += 2; QuoteStaging.Ptr += 1;
OutPtr = Info->Date; OutPtr = InTime;
while(*InPtr != '"') while(*QuoteStaging.Ptr != ',')
{ {
*OutPtr++ = *InPtr++; *OutPtr++ = *QuoteStaging.Ptr++;
} }
*OutPtr = '\0'; *OutPtr = '\0';
InPtr += 3; long int Time = StringToInt(InTime);
strftime(Info->Date, 32, "%d %B, %Y", gmtime(&Time));
QuoteStaging.Ptr += 1;
OutPtr = Info->Text; OutPtr = Info->Text;
while(*InPtr != '\n') while(*QuoteStaging.Ptr != '\n')
{ {
if(*InPtr == '\\') *OutPtr++ = *QuoteStaging.Ptr++;
{
++InPtr;
}
*OutPtr++ = *InPtr++;
} }
*--OutPtr = '\0'; *--OutPtr = '\0';
free(Buffer); FreeBuffer(&QuoteStaging);
return 0; return 0;
} }
else else
{ {
while(*InPtr != '\n') while(*QuoteStaging.Ptr != '\n')
{ {
++InPtr; ++QuoteStaging.Ptr;
} }
++InPtr; ++QuoteStaging.Ptr;
} }
} }
free(Buffer); FreeBuffer(&QuoteStaging);
return 1; return 1;
} }
@ -1215,7 +1236,7 @@ ParseConfig(buffer *Buffer, char *Username)
#endif #endif
void void
PrintUsage(char *BinaryLocation, char *DefaultCSSDir, char *DefaultImagesDir, char *DefaultJSDir, char *DefaultDefaultMedium, char *DefaultOutLocation, char *DefaultQuoteDir, char *DefaultTemplateLocation) PrintUsage(char *BinaryLocation, char *DefaultCSSDir, char *DefaultImagesDir, char *DefaultJSDir, char *DefaultDefaultMedium, char *DefaultOutLocation, char *DefaultTemplateLocation)
{ {
fprintf(stderr, "Usage: %s [option(s)] filename(s)\n" fprintf(stderr, "Usage: %s [option(s)] filename(s)\n"
"\n" "\n"
@ -1232,8 +1253,6 @@ PrintUsage(char *BinaryLocation, char *DefaultCSSDir, char *DefaultImagesDir, ch
" Override default default medium (\"%s\")\n" " Override default default medium (\"%s\")\n"
" -o <output location>\n" " -o <output location>\n"
" Override default output location (\"%s\")\n" " Override default output location (\"%s\")\n"
" -q <quotes directory path>\n"
" Override default quotes directory (\"%s\")\n"
" -t <template location>\n" " -t <template location>\n"
" Override default template location (\"%s\")\n" " Override default template location (\"%s\")\n"
" and automatically enable integration\n" " and automatically enable integration\n"
@ -1254,7 +1273,7 @@ PrintUsage(char *BinaryLocation, char *DefaultCSSDir, char *DefaultImagesDir, ch
" <!-- __CINERA_SCRIPT__ --> (must come after <!-- __CINERA_PLAYER__ -->)\n" " <!-- __CINERA_SCRIPT__ --> (must come after <!-- __CINERA_PLAYER__ -->)\n"
" Other available tags include:\n" " Other available tags include:\n"
" <!-- __CINERA_TITLE__ -->\n", " <!-- __CINERA_TITLE__ -->\n",
BinaryLocation, DefaultCSSDir, DefaultImagesDir, DefaultJSDir, DefaultDefaultMedium, DefaultQuoteDir, DefaultOutLocation, DefaultTemplateLocation); BinaryLocation, DefaultCSSDir, DefaultImagesDir, DefaultJSDir, DefaultDefaultMedium, DefaultOutLocation, DefaultTemplateLocation);
} }
int int
@ -1284,9 +1303,6 @@ main(int ArgC, char **Args)
char *DefaultOutIntegratedLocation = "out_integrated.html"; char *DefaultOutIntegratedLocation = "out_integrated.html";
char *OutIntegratedLocation = DefaultOutIntegratedLocation; char *OutIntegratedLocation = DefaultOutIntegratedLocation;
char *DefaultQuoteDir = "/home/matt/git/GitHub/insofaras/25fc16d58a297a486334";
char *QuoteDir = DefaultQuoteDir;
char *CINERA_MODE = getenv("CINERA_MODE"); char *CINERA_MODE = getenv("CINERA_MODE");
bool DefaultForceIntegration = FALSE; bool DefaultForceIntegration = FALSE;
@ -1294,7 +1310,7 @@ main(int ArgC, char **Args)
if(ArgC < 2) if(ArgC < 2)
{ {
PrintUsage(Args[0], DefaultCSSDir, DefaultImagesDir, DefaultJSDir, DefaultDefaultMedium, DefaultQuoteDir, DefaultOutLocation, DefaultTemplateLocation); PrintUsage(Args[0], DefaultCSSDir, DefaultImagesDir, DefaultJSDir, DefaultDefaultMedium, DefaultOutLocation, DefaultTemplateLocation);
return 1; return 1;
} }
@ -1322,8 +1338,6 @@ main(int ArgC, char **Args)
OutLocation = optarg; OutLocation = optarg;
OutIntegratedLocation = optarg; OutIntegratedLocation = optarg;
break; break;
case 'q':
QuoteDir = optarg;
case 't': case 't':
TemplateLocation = optarg; TemplateLocation = optarg;
CINERA_MODE="INTEGRATE"; CINERA_MODE="INTEGRATE";
@ -1332,7 +1346,7 @@ main(int ArgC, char **Args)
// Override config path, once we even have a default! // Override config path, once we even have a default!
case 'h': case 'h':
default: default:
PrintUsage(Args[0], DefaultCSSDir, DefaultImagesDir, DefaultJSDir, DefaultDefaultMedium, DefaultQuoteDir, DefaultOutLocation, DefaultTemplateLocation); PrintUsage(Args[0], DefaultCSSDir, DefaultImagesDir, DefaultJSDir, DefaultDefaultMedium, DefaultOutLocation, DefaultTemplateLocation);
return 1; return 1;
} }
} }
@ -1340,7 +1354,7 @@ main(int ArgC, char **Args)
if(optind == ArgC) if(optind == ArgC)
{ {
fprintf(stderr, "%s: requires at least one input .hmml file\n", Args[0]); fprintf(stderr, "%s: requires at least one input .hmml file\n", Args[0]);
PrintUsage(Args[0], DefaultCSSDir, DefaultImagesDir, DefaultJSDir, DefaultDefaultMedium, DefaultQuoteDir, DefaultOutLocation, DefaultTemplateLocation); PrintUsage(Args[0], DefaultCSSDir, DefaultImagesDir, DefaultJSDir, DefaultDefaultMedium, DefaultOutLocation, DefaultTemplateLocation);
return 1; return 1;
} }
@ -1377,21 +1391,6 @@ main(int ArgC, char **Args)
{ {
JSDir[StringLength(JSDir) - 1] = '\0'; JSDir[StringLength(JSDir) - 1] = '\0';
} }
if(QuoteDir[StringLength(QuoteDir) - 1] == '/')
{
QuoteDir[StringLength(QuoteDir) - 1] = '\0';
}
// TODO(matt): Put the Errors in the MemoryArena
buffer Errors;
Errors.ID = "Errors";
Errors.Size = Kilobytes(1);
if(!(Errors.Location = malloc(Errors.Size)))
{
perror(Args[0]); return 1;
}
Errors.Ptr = Errors.Location;
bool HaveErrors = FALSE;
buffer Template; buffer Template;
Template.ID = "Template"; Template.ID = "Template";
@ -1399,6 +1398,17 @@ main(int ArgC, char **Args)
{ {
if(CINERA_MODE && !StringsDiffer(CINERA_MODE, "INTEGRATE")) if(CINERA_MODE && !StringsDiffer(CINERA_MODE, "INTEGRATE"))
{ {
// TODO(matt): Put the Errors in the MemoryArena
buffer Errors;
Errors.ID = "Errors";
Errors.Size = Kilobytes(1);
if(!(Errors.Location = malloc(Errors.Size)))
{
perror(Args[0]); return 1;
}
Errors.Ptr = Errors.Location;
bool HaveErrors = FALSE;
FILE *TemplateFile; FILE *TemplateFile;
if(!(TemplateFile = fopen(TemplateLocation, "r"))) if(!(TemplateFile = fopen(TemplateLocation, "r")))
{ {
@ -1548,12 +1558,15 @@ main(int ArgC, char **Args)
} }
else else
{ {
if(!FoundIncludes){ CopyStringToBuffer(&Errors, "Template must include one <!-- __CINERA_INCLUDES__ --> tag\n"); }; if(!ForceIntegration)
if(!FoundMenus){ CopyStringToBuffer(&Errors, "Template must include one <!-- __CINERA_MENUS__ --> tag\n"); }; {
if(!FoundPlayer){ CopyStringToBuffer(&Errors, "Template must include one <!-- __CINERA_PLAYER__ --> tag\n"); }; if(!FoundIncludes){ CopyStringToBuffer(&Errors, "Template must include one <!-- __CINERA_INCLUDES__ --> tag\n"); };
if(!FoundScript){ CopyStringToBuffer(&Errors, "Template must include one <!-- __CINERA_SCRIPT__ --> tag\n"); }; if(!FoundMenus){ CopyStringToBuffer(&Errors, "Template must include one <!-- __CINERA_MENUS__ --> tag\n"); };
fprintf(stderr, "%s", Errors.Location); if(!FoundPlayer){ CopyStringToBuffer(&Errors, "Template must include one <!-- __CINERA_PLAYER__ --> tag\n"); };
free(Template.Location); free(Errors.Location); return 1; if(!FoundScript){ CopyStringToBuffer(&Errors, "Template must include one <!-- __CINERA_SCRIPT__ --> tag\n"); };
fprintf(stderr, "%s", Errors.Location);
free(Template.Location); free(Errors.Location); return 1;
}
} }
} }
} }
@ -1564,6 +1577,7 @@ main(int ArgC, char **Args)
if(!(MemoryArena.Location = calloc(MemoryArena.Size, 1))) if(!(MemoryArena.Location = calloc(MemoryArena.Size, 1)))
{ {
perror(Args[0]); perror(Args[0]);
free(Template.Location);
return 1; return 1;
} }
int ClaimedMemory = 0; int ClaimedMemory = 0;
@ -1627,6 +1641,7 @@ main(int ArgC, char **Args)
{ {
perror(Args[FileIndex]); perror(Args[FileIndex]);
free(MemoryArena.Location); free(MemoryArena.Location);
free(Template.Location);
return 1; return 1;
} }
@ -1719,6 +1734,7 @@ main(int ArgC, char **Args)
fprintf(stderr, "%s: Missing annotator in [video] node\n", Args[FileIndex]); fprintf(stderr, "%s: Missing annotator in [video] node\n", Args[FileIndex]);
hmml_free(&HMML); hmml_free(&HMML);
free(MemoryArena.Location); free(MemoryArena.Location);
free(Template.Location);
return 1; return 1;
} }
@ -1893,6 +1909,7 @@ main(int ArgC, char **Args)
"appear in the references menu\n", Args[FileIndex], Anno->line); "appear in the references menu\n", Args[FileIndex], Anno->line);
hmml_free(&HMML); hmml_free(&HMML);
free(MemoryArena.Location); free(MemoryArena.Location);
free(Template.Location);
return 1; return 1;
} }
++ReferencesArray[RefIdentifier - 1].IdentifierCount; ++ReferencesArray[RefIdentifier - 1].IdentifierCount;
@ -1909,6 +1926,7 @@ main(int ArgC, char **Args)
fprintf(stderr, "%s:%d: Too many timecodes associated with one reference (increase REF_MAX_IDENTIFIER)\n", Args[FileIndex], Anno->line); fprintf(stderr, "%s:%d: Too many timecodes associated with one reference (increase REF_MAX_IDENTIFIER)\n", Args[FileIndex], Anno->line);
hmml_free(&HMML); hmml_free(&HMML);
free(MemoryArena.Location); free(MemoryArena.Location);
free(Template.Location);
return 1; return 1;
} }
if(CurrentRef->isbn) if(CurrentRef->isbn)
@ -1936,6 +1954,7 @@ main(int ArgC, char **Args)
fprintf(stderr, "%s:%d: Reference must have an ISBN or URL\n", Args[FileIndex], Anno->line); fprintf(stderr, "%s:%d: Reference must have an ISBN or URL\n", Args[FileIndex], Anno->line);
hmml_free(&HMML); hmml_free(&HMML);
free(MemoryArena.Location); free(MemoryArena.Location);
free(Template.Location);
return 1; return 1;
} }
} }
@ -1949,6 +1968,7 @@ main(int ArgC, char **Args)
"appear in the references menu\n", Args[FileIndex], Anno->line); "appear in the references menu\n", Args[FileIndex], Anno->line);
hmml_free(&HMML); hmml_free(&HMML);
free(MemoryArena.Location); free(MemoryArena.Location);
free(Template.Location);
return 1; return 1;
} }
++ReferencesArray[UniqueRefs].IdentifierCount; ++ReferencesArray[UniqueRefs].IdentifierCount;
@ -1970,6 +1990,7 @@ main(int ArgC, char **Args)
fprintf(stderr, "%s:%d: Reference must have an ISBN or URL\n", Args[FileIndex], Anno->line); fprintf(stderr, "%s:%d: Reference must have an ISBN or URL\n", Args[FileIndex], Anno->line);
hmml_free(&HMML); hmml_free(&HMML);
free(MemoryArena.Location); free(MemoryArena.Location);
free(Template.Location);
return 1; return 1;
} }
@ -1990,6 +2011,7 @@ main(int ArgC, char **Args)
fprintf(stderr, "%s:%d: Reference must have an ISBN or URL", Args[FileIndex], Anno->line); fprintf(stderr, "%s:%d: Reference must have an ISBN or URL", Args[FileIndex], Anno->line);
hmml_free(&HMML); hmml_free(&HMML);
free(MemoryArena.Location); free(MemoryArena.Location);
free(Template.Location);
return 1; return 1;
} }
} }
@ -2062,15 +2084,16 @@ 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, QuoteDir) == 1) if(BuildQuote(&QuoteInfo, Anno->quote.author ? Anno->quote.author : HMML.metadata.stream_username ? HMML.metadata.stream_username : HMML.metadata.member, Anno->quote.id) == 1)
{ {
fprintf(stderr, "%s:%d: Quote #%s %d not found! Consider pulling the latest quotes\n", fprintf(stderr, "%s:%d: Quote #%s %d not found. Unlucky!\n",
Args[FileIndex], Args[FileIndex],
Anno->line, Anno->line,
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,
Anno->quote.id); Anno->quote.id);
hmml_free(&HMML); hmml_free(&HMML);
free(MemoryArena.Location); free(MemoryArena.Location);
free(Template.Location);
return 1; return 1;
} }