Fix search_ and player_location related bugs
On the search pages use the search_location and player_location, in addition to the base_url, to associate filter and index entries, such that the filter actually works. Fix the .index file location for projects with a search_location. As this is now consistent, we happen to fix a crash that happened when changing the search_location. New config option: deny_bespoke_templates Indexers may use the "template" attribute in the video node of an .hmml file to set a bespoke template for that entry, superseding any configured player_template. Setting "deny_bespoke_templates" to true prevents this.
This commit is contained in:
parent
e2ea8fdaf3
commit
9dfdc117be
197
cinera/cinera.c
197
cinera/cinera.c
|
@ -23,7 +23,7 @@ typedef struct
|
||||||
version CINERA_APP_VERSION = {
|
version CINERA_APP_VERSION = {
|
||||||
.Major = 0,
|
.Major = 0,
|
||||||
.Minor = 7,
|
.Minor = 7,
|
||||||
.Patch = 7
|
.Patch = 8
|
||||||
};
|
};
|
||||||
|
|
||||||
#include <stdarg.h> // NOTE(matt): varargs
|
#include <stdarg.h> // NOTE(matt): varargs
|
||||||
|
@ -1306,6 +1306,7 @@ video node of the entries for which they should be credited."
|
||||||
{ "db_location", "Absolute file path where the database file resides. If you run multiple instances of Cinera on the same machine, please ensure this db_location differs between them." },
|
{ "db_location", "Absolute file path where the database file resides. If you run multiple instances of Cinera on the same machine, please ensure this db_location differs between them." },
|
||||||
{ "default_medium", "The ID of a medium (see also medium) which will be the default for the project. May be overridden by setting the medium in the video node of an HMML file." },
|
{ "default_medium", "The ID of a medium (see also medium) which will be the default for the project. May be overridden by setting the medium in the video node of an HMML file." },
|
||||||
{ "deny", "See allow." },
|
{ "deny", "See allow." },
|
||||||
|
{ "deny_bespoke_templates", "Indexers may use the \"template\" attribute in the video node of an .hmml file to set a bespoke template for that entry, superseding any configured player_template. Setting \"deny_bespoke_templates\" to true prevents this." },
|
||||||
{ "genre", "This is a setting for the future. We currently only support the \"video\" genre, which is the default." },
|
{ "genre", "This is a setting for the future. We currently only support the \"video\" genre, which is the default." },
|
||||||
{ "global_search_dir", "Absolute directory path, where the global search page will be located, collating the search pages of all projects in the Cinera instance." },
|
{ "global_search_dir", "Absolute directory path, where the global search page will be located, collating the search pages of all projects in the Cinera instance." },
|
||||||
{ "global_search_template", "Path of a HTML template file relative to the global_templates_dir from which the global search page will be generated." },
|
{ "global_search_template", "Path of a HTML template file relative to the global_templates_dir from which the global search page will be generated." },
|
||||||
|
@ -1425,6 +1426,7 @@ typedef enum
|
||||||
IDENT_DB_LOCATION,
|
IDENT_DB_LOCATION,
|
||||||
IDENT_DEFAULT_MEDIUM,
|
IDENT_DEFAULT_MEDIUM,
|
||||||
IDENT_DENY,
|
IDENT_DENY,
|
||||||
|
IDENT_DENY_BESPOKE_TEMPLATES,
|
||||||
IDENT_GENRE,
|
IDENT_GENRE,
|
||||||
IDENT_GLOBAL_SEARCH_DIR,
|
IDENT_GLOBAL_SEARCH_DIR,
|
||||||
IDENT_GLOBAL_SEARCH_TEMPLATE,
|
IDENT_GLOBAL_SEARCH_TEMPLATE,
|
||||||
|
@ -4640,16 +4642,16 @@ PrintAssetsBlock_(db_block_assets *B, int LineNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
ConstructDirectoryPath(db_header_project *P, string *PageLocation, string *EntryOutput)
|
ConstructDirectoryPath(string *BaseDir, string *PageLocation, string *EntryOutput)
|
||||||
{
|
{
|
||||||
char *Result = 0;
|
char *Result = 0;
|
||||||
if(P)
|
if(BaseDir)
|
||||||
{
|
{
|
||||||
ExtendString0(&Result, Wrap0i(P->BaseDir, sizeof(P->BaseDir)));
|
ExtendString0(&Result, *BaseDir);
|
||||||
}
|
}
|
||||||
if(PageLocation && PageLocation->Length > 0)
|
if(PageLocation && PageLocation->Length > 0)
|
||||||
{
|
{
|
||||||
if(P)
|
if(BaseDir)
|
||||||
{
|
{
|
||||||
ExtendString0(&Result, Wrap0("/"));
|
ExtendString0(&Result, Wrap0("/"));
|
||||||
}
|
}
|
||||||
|
@ -4665,18 +4667,17 @@ ConstructDirectoryPath(db_header_project *P, string *PageLocation, string *Entry
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
ConstructHTMLIndexFilePath(db_header_project *P, string *PageLocation, string *EntryOutput)
|
ConstructHTMLIndexFilePath(string *BaseDir, string *PageLocation, string *EntryOutput)
|
||||||
{
|
{
|
||||||
char *Result = ConstructDirectoryPath(P, PageLocation, EntryOutput);
|
char *Result = ConstructDirectoryPath(BaseDir, PageLocation, EntryOutput);
|
||||||
ExtendString0(&Result, Wrap0("/index.html"));
|
ExtendString0(&Result, Wrap0("/index.html"));
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc
|
rc
|
||||||
ReadSearchPageIntoBuffer(db_header_project *P, file *File)
|
ReadSearchPageIntoBuffer(file *File, string *BaseDir, string *SearchLocation)
|
||||||
{
|
{
|
||||||
string SearchLocationL = Wrap0i(P->SearchLocation, sizeof(P->SearchLocation));
|
File->Path = ConstructHTMLIndexFilePath(BaseDir, SearchLocation, 0);
|
||||||
File->Path = ConstructHTMLIndexFilePath(P, &SearchLocationL, 0);
|
|
||||||
return ReadFileIntoBuffer(File);
|
return ReadFileIntoBuffer(File);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4690,11 +4691,9 @@ ReadGlobalSearchPageIntoBuffer(file *File)
|
||||||
}
|
}
|
||||||
|
|
||||||
rc
|
rc
|
||||||
ReadPlayerPageIntoBuffer(db_header_project *P, file *File, db_entry *Entry)
|
ReadPlayerPageIntoBuffer(file *File, string BaseDir, string PlayerLocation, string OutputLocation)
|
||||||
{
|
{
|
||||||
string EntryOutput = Wrap0i(Entry->OutputLocation, sizeof(Entry->OutputLocation));
|
File->Path = ConstructHTMLIndexFilePath(&BaseDir, &PlayerLocation, &OutputLocation);
|
||||||
string PlayerLocationL = Wrap0i(P->PlayerLocation, sizeof(P->PlayerLocation));
|
|
||||||
File->Path = ConstructHTMLIndexFilePath(P, &PlayerLocationL, &EntryOutput);
|
|
||||||
return ReadFileIntoBuffer(File);
|
return ReadFileIntoBuffer(File);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4718,7 +4717,10 @@ SnipeChecksumIntoHTML(db_asset *Asset, buffer *Checksum)
|
||||||
db_entry *Entry = LocateEntry(Landmark->Project, Landmark->EntryIndex);
|
db_entry *Entry = LocateEntry(Landmark->Project, Landmark->EntryIndex);
|
||||||
if(Entry)
|
if(Entry)
|
||||||
{
|
{
|
||||||
FileReadRC = ReadPlayerPageIntoBuffer(P, &HTML, Entry);
|
string BaseDir = Wrap0i(P->BaseDir, sizeof(P->BaseDir));
|
||||||
|
string PlayerLocation = Wrap0i(P->PlayerLocation, sizeof(P->PlayerLocation));
|
||||||
|
string OutputLocation = Wrap0i(Entry->OutputLocation, sizeof(Entry->OutputLocation));
|
||||||
|
FileReadRC = ReadPlayerPageIntoBuffer(&HTML, BaseDir, PlayerLocation, OutputLocation);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -4737,7 +4739,9 @@ SnipeChecksumIntoHTML(db_asset *Asset, buffer *Checksum)
|
||||||
{
|
{
|
||||||
if(P)
|
if(P)
|
||||||
{
|
{
|
||||||
FileReadRC = ReadSearchPageIntoBuffer(P, &HTML);
|
string BaseDir = Wrap0i(P->BaseDir, sizeof(P->BaseDir));
|
||||||
|
string SearchLocation = Wrap0i(P->SearchLocation, sizeof(P->SearchLocation));
|
||||||
|
FileReadRC = ReadSearchPageIntoBuffer(&HTML, &BaseDir, &SearchLocation);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -8653,31 +8657,27 @@ DeclaimPlayerBuffers(player_buffers *B)
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
ConstructIndexFilePath(db_header_project *Project)
|
ConstructIndexFilePath(string BaseDir, string SearchLocation, string ProjectID)
|
||||||
{
|
{
|
||||||
string SearchLocation = Wrap0i(Project->SearchLocation, sizeof(Project->SearchLocation));
|
char *Result = ConstructDirectoryPath(&BaseDir, &SearchLocation, 0);
|
||||||
char *Result = ConstructDirectoryPath(Project, &SearchLocation, 0);
|
|
||||||
ExtendString0(&Result, Wrap0("/"));
|
ExtendString0(&Result, Wrap0("/"));
|
||||||
ExtendString0(&Result, Wrap0i(Project->ID, sizeof(Project->ID)));
|
ExtendString0(&Result, ProjectID);
|
||||||
ExtendString0(&Result, ExtensionStrings[EXT_INDEX]);
|
ExtendString0(&Result, ExtensionStrings[EXT_INDEX]);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DeleteSearchPageFromFilesystem(db_header_project *Project) // NOTE(matt): Do we need to handle relocating, like the PlayerPage function?
|
DeleteSearchPageFromFilesystem(string BaseDir, string SearchLocation, string ProjectID) // NOTE(matt): Do we need to handle relocating, like the PlayerPage function?
|
||||||
{
|
{
|
||||||
string SearchLocationL = Wrap0i(Project->SearchLocation, sizeof(Project->SearchLocation));
|
char *SearchPagePath = ConstructHTMLIndexFilePath(&BaseDir, &SearchLocation, 0);
|
||||||
char *SearchPagePath = ConstructHTMLIndexFilePath(Project, &SearchLocationL, 0);
|
|
||||||
remove(SearchPagePath);
|
remove(SearchPagePath);
|
||||||
Free(SearchPagePath);
|
Free(SearchPagePath);
|
||||||
|
|
||||||
char *IndexFilePath = ConstructIndexFilePath(Project);
|
remove(DB.File.Path);
|
||||||
remove(IndexFilePath);
|
// TODO(matt): Consider the correctness of this.
|
||||||
Free(IndexFilePath);
|
|
||||||
// TODO(matt): Consider the correctness of this
|
|
||||||
FreeFile(&DB.File);
|
FreeFile(&DB.File);
|
||||||
|
|
||||||
char *SearchDirectory = ConstructDirectoryPath(Project, &SearchLocationL, 0);
|
char *SearchDirectory = ConstructDirectoryPath(&BaseDir, &SearchLocation, 0);
|
||||||
remove(SearchDirectory);
|
remove(SearchDirectory);
|
||||||
Free(SearchDirectory);
|
Free(SearchDirectory);
|
||||||
}
|
}
|
||||||
|
@ -8714,10 +8714,9 @@ PrintLineageAndEntry(string Lineage, string EntryID, string EntryTitle, bool App
|
||||||
}
|
}
|
||||||
|
|
||||||
rc
|
rc
|
||||||
DeletePlayerPageFromFilesystem(db_header_project *P, string EntryOutput, bool Relocating, bool Echo)
|
DeletePlayerPageFromFilesystem(string BaseDir, string PlayerLocation, string EntryOutput, bool Relocating, bool Echo)
|
||||||
{
|
{
|
||||||
string PlayerLocation = Wrap0i(P->PlayerLocation, sizeof(P->PlayerLocation));
|
char *OutputDirectoryPath = ConstructDirectoryPath(&BaseDir, &PlayerLocation, &EntryOutput);
|
||||||
char *OutputDirectoryPath = ConstructDirectoryPath(P, &PlayerLocation, &EntryOutput);
|
|
||||||
DIR *PlayerDir;
|
DIR *PlayerDir;
|
||||||
|
|
||||||
if((PlayerDir = opendir(OutputDirectoryPath))) // There is a directory for the Player, which there probably should be if not for manual intervention
|
if((PlayerDir = opendir(OutputDirectoryPath))) // There is a directory for the Player, which there probably should be if not for manual intervention
|
||||||
|
@ -8951,7 +8950,7 @@ HMMLToBuffers(buffers *CollationBuffers, template *BespokeTemplate, string BaseF
|
||||||
|
|
||||||
if(!HaveErrors)
|
if(!HaveErrors)
|
||||||
{
|
{
|
||||||
if(HMML.metadata.template)
|
if(!CurrentProject->DenyBespokeTemplates && HMML.metadata.template)
|
||||||
{
|
{
|
||||||
switch(PackTemplate(BespokeTemplate, Wrap0(HMML.metadata.template), TEMPLATE_BESPOKE, CurrentProject))
|
switch(PackTemplate(BespokeTemplate, Wrap0(HMML.metadata.template), TEMPLATE_BESPOKE, CurrentProject))
|
||||||
{
|
{
|
||||||
|
@ -8993,7 +8992,7 @@ HMMLToBuffers(buffers *CollationBuffers, template *BespokeTemplate, string BaseF
|
||||||
string NewOutputLocation = Wrap0i(N->WorkingThis.OutputLocation, sizeof(N->WorkingThis.OutputLocation));
|
string NewOutputLocation = Wrap0i(N->WorkingThis.OutputLocation, sizeof(N->WorkingThis.OutputLocation));
|
||||||
if(StringsDiffer(OldOutputLocation, NewOutputLocation))
|
if(StringsDiffer(OldOutputLocation, NewOutputLocation))
|
||||||
{
|
{
|
||||||
DeletePlayerPageFromFilesystem(N->Project, OldOutputLocation, FALSE, TRUE);
|
DeletePlayerPageFromFilesystem(CurrentProject->BaseDir, CurrentProject->PlayerLocation, OldOutputLocation, FALSE, TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10703,23 +10702,24 @@ void
|
||||||
InitIndexFile(project *P)
|
InitIndexFile(project *P)
|
||||||
{
|
{
|
||||||
DB.File.Buffer.ID = BID_DATABASE;
|
DB.File.Buffer.ID = BID_DATABASE;
|
||||||
DB.File = InitFile(&P->BaseDir, &P->ID, EXT_INDEX);
|
DB.File.Path = ConstructIndexFilePath(P->BaseDir, P->SearchLocation, P->ID);
|
||||||
ReadFileIntoBuffer(&DB.File); // NOTE(matt): Could we actually catch errors (permissions?) here and bail?
|
ReadFileIntoBuffer(&DB.File); // NOTE(matt): Could we actually catch errors (permissions?) here and bail?
|
||||||
if(!DB.File.Buffer.Location)
|
if(!DB.File.Buffer.Location)
|
||||||
{
|
{
|
||||||
char *BaseDir0 = MakeString0("l", &P->BaseDir);
|
string IndexFileDir = StripComponentFromPath(Wrap0(DB.File.Path));
|
||||||
DIR *OutputDirectoryHandle = opendir(BaseDir0);
|
char *IndexFileDir0 = MakeString0("l", &IndexFileDir);
|
||||||
|
DIR *OutputDirectoryHandle = opendir(IndexFileDir0);
|
||||||
if(!OutputDirectoryHandle)
|
if(!OutputDirectoryHandle)
|
||||||
{
|
{
|
||||||
if(!MakeDir(P->BaseDir))
|
if(!MakeDir(IndexFileDir))
|
||||||
{
|
{
|
||||||
LogError(LOG_ERROR, "Unable to create directory %.*s: %s", (int)P->BaseDir.Length, P->BaseDir.Base, strerror(errno));
|
LogError(LOG_ERROR, "Unable to create directory %.*s: %s", (int)P->BaseDir.Length, P->BaseDir.Base, strerror(errno));
|
||||||
fprintf(stderr, "Unable to create directory %.*s: %s\n", (int)P->BaseDir.Length, P->BaseDir.Base, strerror(errno));
|
fprintf(stderr, "Unable to create directory %.*s: %s\n", (int)P->BaseDir.Length, P->BaseDir.Base, strerror(errno));
|
||||||
Free(BaseDir0);
|
Free(IndexFileDir0);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Free(BaseDir0);
|
Free(IndexFileDir0);
|
||||||
closedir(OutputDirectoryHandle);
|
closedir(OutputDirectoryHandle);
|
||||||
|
|
||||||
DB.File.Handle = fopen(DB.File.Path, "w");
|
DB.File.Handle = fopen(DB.File.Path, "w");
|
||||||
|
@ -11905,7 +11905,7 @@ InsertNeighbourLink(db_header_project *P, db_entry *From, db_entry *To, enum8(li
|
||||||
{
|
{
|
||||||
MEM_TEST_INITIAL();
|
MEM_TEST_INITIAL();
|
||||||
file HTML = {};
|
file HTML = {};
|
||||||
ReadPlayerPageIntoBuffer(P, &HTML, From);
|
ReadPlayerPageIntoBuffer(&HTML, Wrap0i(P->BaseDir, sizeof(P->BaseDir)), Wrap0i(P->PlayerLocation, sizeof(P->PlayerLocation)), Wrap0i(From->OutputLocation, sizeof(From->OutputLocation)));
|
||||||
|
|
||||||
MEM_TEST_MID("InsertNeighbourLink1");
|
MEM_TEST_MID("InsertNeighbourLink1");
|
||||||
if(HTML.Buffer.Location)
|
if(HTML.Buffer.Location)
|
||||||
|
@ -12050,7 +12050,7 @@ DeleteNeighbourLinks(neighbourhood *N)
|
||||||
}
|
}
|
||||||
|
|
||||||
file HTML = {};
|
file HTML = {};
|
||||||
ReadPlayerPageIntoBuffer(N->Project, &HTML, Entry);
|
ReadPlayerPageIntoBuffer(&HTML, Wrap0i(N->Project->BaseDir, sizeof(N->Project->BaseDir)), Wrap0i(N->Project->PlayerLocation, sizeof(N->Project->PlayerLocation)), Wrap0i(Entry->OutputLocation, sizeof(Entry->OutputLocation)));
|
||||||
if(HTML.Buffer.Location)
|
if(HTML.Buffer.Location)
|
||||||
{
|
{
|
||||||
if(!(HTML.Handle = fopen(HTML.Path, "w"))) { FreeFile(&HTML); return RC_ERROR_FILE; };
|
if(!(HTML.Handle = fopen(HTML.Path, "w"))) { FreeFile(&HTML); return RC_ERROR_FILE; };
|
||||||
|
@ -12130,7 +12130,7 @@ MarkNextAsFirst(neighbourhood *N)
|
||||||
{
|
{
|
||||||
// TODO(matt): We added some untested logic in here. If things related to the prev / next links fail, we screwed up here
|
// TODO(matt): We added some untested logic in here. If things related to the prev / next links fail, we screwed up here
|
||||||
file HTML = {};
|
file HTML = {};
|
||||||
ReadPlayerPageIntoBuffer(N->Project, &HTML, N->Next);
|
ReadPlayerPageIntoBuffer(&HTML, Wrap0i(N->Project->BaseDir, sizeof(N->Project->BaseDir)), Wrap0i(N->Project->PlayerLocation, sizeof(N->Project->PlayerLocation)), Wrap0i(N->Next->OutputLocation, sizeof(N->Next->OutputLocation)));
|
||||||
if(HTML.Buffer.Location)
|
if(HTML.Buffer.Location)
|
||||||
{
|
{
|
||||||
buffer Link;
|
buffer Link;
|
||||||
|
@ -12167,32 +12167,32 @@ MarkNextAsFirst(neighbourhood *N)
|
||||||
void
|
void
|
||||||
MarkPrevAsFinal(neighbourhood *N)
|
MarkPrevAsFinal(neighbourhood *N)
|
||||||
{
|
{
|
||||||
file File = {};
|
file HTML = {};
|
||||||
ReadPlayerPageIntoBuffer(N->Project, &File, N->Prev);
|
ReadPlayerPageIntoBuffer(&HTML, Wrap0i(N->Project->BaseDir, sizeof(N->Project->BaseDir)), Wrap0i(N->Project->PlayerLocation, sizeof(N->Project->PlayerLocation)), Wrap0i(N->Prev->OutputLocation, sizeof(N->Prev->OutputLocation)));
|
||||||
|
|
||||||
if(File.Buffer.Location)
|
if(HTML.Buffer.Location)
|
||||||
{
|
{
|
||||||
File.Handle = fopen(File.Path, "w");
|
HTML.Handle = fopen(HTML.Path, "w");
|
||||||
buffer Link;
|
buffer Link;
|
||||||
ClaimBuffer(&Link, BID_LINK, Kilobytes(4));
|
ClaimBuffer(&Link, BID_LINK, Kilobytes(4));
|
||||||
|
|
||||||
|
|
||||||
fwrite(File.Buffer.Location, N->Prev->LinkOffsets.PrevStart + N->Prev->LinkOffsets.PrevEnd + N->Prev->LinkOffsets.NextStart, 1, File.Handle);
|
fwrite(HTML.Buffer.Location, N->Prev->LinkOffsets.PrevStart + N->Prev->LinkOffsets.PrevEnd + N->Prev->LinkOffsets.NextStart, 1, HTML.Handle);
|
||||||
|
|
||||||
CopyStringToBuffer(&Link,
|
CopyStringToBuffer(&Link,
|
||||||
" <div class=\"episodeMarker last\"><div>•</div><div>You have arrived at the (current) end of <cite>%.*s</cite></div><div>•</div></div>\n", (int)CurrentProject->Title.Length, CurrentProject->Title.Base);
|
" <div class=\"episodeMarker last\"><div>•</div><div>You have arrived at the (current) end of <cite>%.*s</cite></div><div>•</div></div>\n", (int)CurrentProject->Title.Length, CurrentProject->Title.Base);
|
||||||
|
|
||||||
fwrite(Link.Location, (Link.Ptr - Link.Location), 1, File.Handle);
|
fwrite(Link.Location, (Link.Ptr - Link.Location), 1, HTML.Handle);
|
||||||
|
|
||||||
fwrite(File.Buffer.Location + N->Prev->LinkOffsets.PrevStart + N->Prev->LinkOffsets.PrevEnd + N->Prev->LinkOffsets.NextStart + N->Prev->LinkOffsets.NextEnd,
|
fwrite(HTML.Buffer.Location + N->Prev->LinkOffsets.PrevStart + N->Prev->LinkOffsets.PrevEnd + N->Prev->LinkOffsets.NextStart + N->Prev->LinkOffsets.NextEnd,
|
||||||
File.Buffer.Size - (N->Prev->LinkOffsets.PrevStart + N->Prev->LinkOffsets.PrevEnd + N->Prev->LinkOffsets.NextStart + N->Prev->LinkOffsets.NextEnd),
|
HTML.Buffer.Size - (N->Prev->LinkOffsets.PrevStart + N->Prev->LinkOffsets.PrevEnd + N->Prev->LinkOffsets.NextStart + N->Prev->LinkOffsets.NextEnd),
|
||||||
1,
|
1,
|
||||||
File.Handle);
|
HTML.Handle);
|
||||||
|
|
||||||
N->Prev->LinkOffsets.NextEnd = Link.Ptr - Link.Location;
|
N->Prev->LinkOffsets.NextEnd = Link.Ptr - Link.Location;
|
||||||
|
|
||||||
DeclaimBuffer(&Link);
|
DeclaimBuffer(&Link);
|
||||||
fclose(File.Handle);
|
fclose(HTML.Handle);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -12200,7 +12200,7 @@ MarkPrevAsFinal(neighbourhood *N)
|
||||||
N->Prev->LinkOffsets = Blank;
|
N->Prev->LinkOffsets = Blank;
|
||||||
}
|
}
|
||||||
|
|
||||||
FreeFile(&File);
|
FreeFile(&HTML);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -12308,7 +12308,7 @@ DeleteFromDB(neighbourhood *N, string BaseFilename)
|
||||||
--NewEntryCount;
|
--NewEntryCount;
|
||||||
if(NewEntryCount == 0)
|
if(NewEntryCount == 0)
|
||||||
{
|
{
|
||||||
DeleteSearchPageFromFilesystem(N->Project);
|
DeleteSearchPageFromFilesystem(Wrap0i(N->Project->BaseDir, sizeof(N->Project->BaseDir)), Wrap0i(N->Project->SearchLocation, sizeof(N->Project->SearchLocation)), Wrap0i(N->Project->ID, sizeof(N->Project->ID)));
|
||||||
DeleteLandmarksForSearch(CurrentProject->Index);
|
DeleteLandmarksForSearch(CurrentProject->Index);
|
||||||
UpdateNeighbourhoodPointers(N, &DB.Metadata.Signposts);
|
UpdateNeighbourhoodPointers(N, &DB.Metadata.Signposts);
|
||||||
}
|
}
|
||||||
|
@ -12369,6 +12369,10 @@ GenerateFilterOfProjectAndChildren(buffer *Filter, db_header_project *StoredP, p
|
||||||
OpenNodeNewLine(Filter, &Filter->IndentLevel, NODE_DIV, 0);
|
OpenNodeNewLine(Filter, &Filter->IndentLevel, NODE_DIV, 0);
|
||||||
AppendStringToBuffer(Filter, Wrap0(" class=\"cineraFilterProject\" data-baseURL=\""));
|
AppendStringToBuffer(Filter, Wrap0(" class=\"cineraFilterProject\" data-baseURL=\""));
|
||||||
AppendStringToBuffer(Filter, P->BaseURL);
|
AppendStringToBuffer(Filter, P->BaseURL);
|
||||||
|
AppendStringToBuffer(Filter, Wrap0("\" data-searchLocation=\""));
|
||||||
|
AppendStringToBuffer(Filter, P->SearchLocation);
|
||||||
|
AppendStringToBuffer(Filter, Wrap0("\" data-playerLocation=\""));
|
||||||
|
AppendStringToBuffer(Filter, P->PlayerLocation);
|
||||||
AppendStringToBuffer(Filter, Wrap0("\">"));
|
AppendStringToBuffer(Filter, Wrap0("\">"));
|
||||||
|
|
||||||
OpenNodeNewLine(Filter, &Filter->IndentLevel, NODE_SPAN, 0);
|
OpenNodeNewLine(Filter, &Filter->IndentLevel, NODE_SPAN, 0);
|
||||||
|
@ -12406,6 +12410,8 @@ GenerateIndexOfProjectAndChildren(buffer *Index, db_header_project *StoredP, pro
|
||||||
AppendStringToBuffer(Index, P->ID);
|
AppendStringToBuffer(Index, P->ID);
|
||||||
AppendStringToBuffer(Index, Wrap0("\" data-baseURL=\""));
|
AppendStringToBuffer(Index, Wrap0("\" data-baseURL=\""));
|
||||||
AppendStringToBuffer(Index, P->BaseURL);
|
AppendStringToBuffer(Index, P->BaseURL);
|
||||||
|
AppendStringToBuffer(Index, Wrap0("\" data-searchLocation=\""));
|
||||||
|
AppendStringToBuffer(Index, P->SearchLocation);
|
||||||
AppendStringToBuffer(Index, Wrap0("\" data-playerLocation=\""));
|
AppendStringToBuffer(Index, Wrap0("\" data-playerLocation=\""));
|
||||||
AppendStringToBuffer(Index, P->PlayerLocation);
|
AppendStringToBuffer(Index, P->PlayerLocation);
|
||||||
AppendStringToBuffer(Index, Wrap0("\">"));
|
AppendStringToBuffer(Index, Wrap0("\">"));
|
||||||
|
@ -12909,9 +12915,10 @@ int
|
||||||
GeneratePlayerPage(neighbourhood *N, buffers *CollationBuffers, template *PlayerTemplate, string OutputLocation, bool Reinserting)
|
GeneratePlayerPage(neighbourhood *N, buffers *CollationBuffers, template *PlayerTemplate, string OutputLocation, bool Reinserting)
|
||||||
{
|
{
|
||||||
MEM_TEST_INITIAL();
|
MEM_TEST_INITIAL();
|
||||||
string PlayerLocationL = Wrap0i(N->Project->PlayerLocation, sizeof(N->Project->PlayerLocation));
|
|
||||||
MEM_TEST_MID("GeneratePlayerPage1");
|
MEM_TEST_MID("GeneratePlayerPage1");
|
||||||
char *PlayerPath = ConstructDirectoryPath(N->Project, &PlayerLocationL, &OutputLocation);
|
string BaseDir = Wrap0i(N->Project->BaseDir, sizeof(N->Project->BaseDir));
|
||||||
|
string PlayerLocation = Wrap0i(N->Project->PlayerLocation, sizeof(N->Project->PlayerLocation));
|
||||||
|
char *PlayerPath = ConstructDirectoryPath(&BaseDir, &PlayerLocation, &OutputLocation);
|
||||||
MEM_TEST_MID("GeneratePlayerPage2");
|
MEM_TEST_MID("GeneratePlayerPage2");
|
||||||
|
|
||||||
DIR *OutputDirectoryHandle;
|
DIR *OutputDirectoryHandle;
|
||||||
|
@ -12966,8 +12973,9 @@ GeneratePlayerPage(neighbourhood *N, buffers *CollationBuffers, template *Player
|
||||||
rc
|
rc
|
||||||
GenerateSearchPage(neighbourhood *N, buffers *CollationBuffers, db_header_project *StoredP, project *P)
|
GenerateSearchPage(neighbourhood *N, buffers *CollationBuffers, db_header_project *StoredP, project *P)
|
||||||
{
|
{
|
||||||
string SearchLocationL = Wrap0i(StoredP->SearchLocation, sizeof(StoredP->SearchLocation));
|
string BaseDir = Wrap0i(N->Project->BaseDir, sizeof(N->Project->BaseDir));
|
||||||
char *SearchPath = ConstructDirectoryPath(StoredP, &SearchLocationL, 0);
|
string SearchLocation = Wrap0i(N->Project->SearchLocation, sizeof(N->Project->SearchLocation));
|
||||||
|
char *SearchPath = ConstructDirectoryPath(&BaseDir, &SearchLocation, 0);
|
||||||
|
|
||||||
DIR *OutputDirectoryHandle;
|
DIR *OutputDirectoryHandle;
|
||||||
if(!(OutputDirectoryHandle = opendir(SearchPath))) // TODO(matt): open()
|
if(!(OutputDirectoryHandle = opendir(SearchPath))) // TODO(matt): open()
|
||||||
|
@ -12994,7 +13002,7 @@ GenerateSearchPage(neighbourhood *N, buffers *CollationBuffers, db_header_projec
|
||||||
}
|
}
|
||||||
case RC_NOOP:
|
case RC_NOOP:
|
||||||
{
|
{
|
||||||
DeleteSearchPageFromFilesystem(StoredP);
|
DeleteSearchPageFromFilesystem(BaseDir, SearchLocation, P->ID);
|
||||||
DeleteLandmarksForSearch(P->Index);
|
DeleteLandmarksForSearch(P->Index);
|
||||||
UpdateNeighbourhoodPointers(N, &DB.Metadata.Signposts);
|
UpdateNeighbourhoodPointers(N, &DB.Metadata.Signposts);
|
||||||
break;
|
break;
|
||||||
|
@ -13093,7 +13101,10 @@ DeleteEntry(neighbourhood *N, string BaseFilename)
|
||||||
{
|
{
|
||||||
LinkNeighbours(N, LINK_EXCLUDE);
|
LinkNeighbours(N, LINK_EXCLUDE);
|
||||||
|
|
||||||
DeletePlayerPageFromFilesystem(N->Project, BaseFilename, FALSE, TRUE);
|
string BaseDir = Wrap0i(N->Project->BaseDir, sizeof(N->Project->BaseDir));
|
||||||
|
string PlayerLocation = Wrap0i(N->Project->PlayerLocation, sizeof(N->Project->PlayerLocation));
|
||||||
|
DeletePlayerPageFromFilesystem(BaseDir, PlayerLocation, BaseFilename, FALSE, TRUE);
|
||||||
|
|
||||||
UpdateLandmarksForNeighbourhood(N, EDIT_DELETION);
|
UpdateLandmarksForNeighbourhood(N, EDIT_DELETION);
|
||||||
return RC_SUCCESS;
|
return RC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -13336,18 +13347,22 @@ rc
|
||||||
DeleteDeadDBEntries(neighbourhood *N, bool *Modified)
|
DeleteDeadDBEntries(neighbourhood *N, bool *Modified)
|
||||||
{
|
{
|
||||||
// TODO(matt): Additionally remove the BaseDir if it changed
|
// TODO(matt): Additionally remove the BaseDir if it changed
|
||||||
bool NewPlayerLocation = FALSE;
|
bool HasNewPlayerLocation = FALSE;
|
||||||
bool NewSearchLocation = FALSE;
|
bool HasNewSearchLocation = FALSE;
|
||||||
|
|
||||||
|
// TODO(matt): Here is where the relocation happens. This could be wrong
|
||||||
|
|
||||||
if(StringsDiffer(CurrentProject->BaseDir, Wrap0i(N->Project->BaseDir, sizeof(N->Project->BaseDir))) ||
|
if(StringsDiffer(CurrentProject->BaseDir, Wrap0i(N->Project->BaseDir, sizeof(N->Project->BaseDir))) ||
|
||||||
StringsDiffer(CurrentProject->PlayerLocation, Wrap0i(N->Project->PlayerLocation, sizeof(N->Project->PlayerLocation))))
|
StringsDiffer(CurrentProject->PlayerLocation, Wrap0i(N->Project->PlayerLocation, sizeof(N->Project->PlayerLocation))))
|
||||||
{
|
{
|
||||||
string PlayerLocationL = Wrap0i(N->Project->PlayerLocation, sizeof(N->Project->PlayerLocation));
|
string OldBaseDir = Wrap0i(N->Project->BaseDir, sizeof(N->Project->BaseDir));
|
||||||
char *OldPlayerDirectory = ConstructDirectoryPath(N->Project, &PlayerLocationL, 0);
|
string OldPlayerLocation = Wrap0i(N->Project->PlayerLocation, sizeof(N->Project->PlayerLocation));
|
||||||
|
char *OldPlayerDirectory = ConstructDirectoryPath(&OldBaseDir, &OldPlayerLocation, 0);
|
||||||
|
|
||||||
db_header_project NewProjectHeader = *N->Project;
|
db_header_project NewProjectHeader = *N->Project;
|
||||||
ClearCopyStringNoFormat(NewProjectHeader.BaseDir, sizeof(NewProjectHeader.BaseDir), CurrentProject->BaseDir);
|
ClearCopyStringNoFormat(NewProjectHeader.BaseDir, sizeof(NewProjectHeader.BaseDir), CurrentProject->BaseDir);
|
||||||
char *NewPlayerDirectory = ConstructDirectoryPath(&NewProjectHeader, &CurrentProject->PlayerLocation, 0);
|
string NewBaseDir = Wrap0i(NewProjectHeader.BaseDir, sizeof(NewProjectHeader.BaseDir));
|
||||||
|
char *NewPlayerDirectory = ConstructDirectoryPath(&NewBaseDir, &CurrentProject->PlayerLocation, 0);
|
||||||
|
|
||||||
printf("%sRelocating Player Page%s from %s to %s%s\n",
|
printf("%sRelocating Player Page%s from %s to %s%s\n",
|
||||||
ColourStrings[CS_REINSERTION], N->Project->EntryCount > 1 ? "s" : "",
|
ColourStrings[CS_REINSERTION], N->Project->EntryCount > 1 ? "s" : "",
|
||||||
|
@ -13358,29 +13373,35 @@ DeleteDeadDBEntries(neighbourhood *N, bool *Modified)
|
||||||
for(int EntryIndex = 0; EntryIndex < N->Project->EntryCount; ++EntryIndex)
|
for(int EntryIndex = 0; EntryIndex < N->Project->EntryCount; ++EntryIndex)
|
||||||
{
|
{
|
||||||
db_entry *This = FirstEntry + EntryIndex;
|
db_entry *This = FirstEntry + EntryIndex;
|
||||||
DeletePlayerPageFromFilesystem(N->Project, Wrap0i(This->OutputLocation, sizeof(This->OutputLocation)), TRUE, TRUE);
|
string BaseDir = Wrap0i(N->Project->BaseDir, sizeof(N->Project->BaseDir));
|
||||||
|
string PlayerLocation = Wrap0i(N->Project->PlayerLocation, sizeof(N->Project->PlayerLocation));
|
||||||
|
DeletePlayerPageFromFilesystem(BaseDir, PlayerLocation, Wrap0i(This->OutputLocation, sizeof(This->OutputLocation)), TRUE, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(PlayerLocationL.Length > 0)
|
if(OldPlayerLocation.Length > 0)
|
||||||
{
|
{
|
||||||
RemoveChildDirectories(Wrap0(OldPlayerDirectory), Wrap0i(N->Project->BaseDir, sizeof(N->Project->BaseDir)));
|
RemoveChildDirectories(Wrap0(OldPlayerDirectory), Wrap0i(N->Project->BaseDir, sizeof(N->Project->BaseDir)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Free(OldPlayerDirectory);
|
Free(OldPlayerDirectory);
|
||||||
ClearCopyStringNoFormat(N->Project->PlayerLocation, sizeof(N->Project->PlayerLocation), CurrentProject->PlayerLocation);
|
ClearCopyStringNoFormat(N->Project->PlayerLocation, sizeof(N->Project->PlayerLocation), CurrentProject->PlayerLocation);
|
||||||
NewPlayerLocation = TRUE;
|
HasNewPlayerLocation = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(StringsDiffer(CurrentProject->BaseDir, Wrap0i(N->Project->BaseDir, sizeof(N->Project->BaseDir))) ||
|
if(StringsDiffer(CurrentProject->BaseDir, Wrap0i(N->Project->BaseDir, sizeof(N->Project->BaseDir))) ||
|
||||||
StringsDiffer(CurrentProject->SearchLocation, Wrap0i(N->Project->SearchLocation, sizeof(N->Project->SearchLocation))))
|
StringsDiffer(CurrentProject->SearchLocation, Wrap0i(N->Project->SearchLocation, sizeof(N->Project->SearchLocation))))
|
||||||
{
|
{
|
||||||
string SearchLocationL = Wrap0i(N->Project->SearchLocation, sizeof(N->Project->SearchLocation));
|
string OldBaseDir = Wrap0i(N->Project->BaseDir, sizeof(N->Project->BaseDir));
|
||||||
char *OldSearchDirectory = ConstructDirectoryPath(N->Project, &SearchLocationL, 0);
|
string OldSearchLocation = Wrap0i(N->Project->SearchLocation, sizeof(N->Project->SearchLocation));
|
||||||
|
char *OldSearchDirectory = ConstructDirectoryPath(&OldBaseDir, &OldSearchLocation, 0);
|
||||||
|
|
||||||
db_header_project NewProjectHeader = *N->Project;
|
db_header_project NewProjectHeader = *N->Project;
|
||||||
ClearCopyStringNoFormat(NewProjectHeader.BaseDir, sizeof(NewProjectHeader.BaseDir), CurrentProject->BaseDir);
|
ClearCopyStringNoFormat(NewProjectHeader.BaseDir, sizeof(NewProjectHeader.BaseDir), CurrentProject->BaseDir);
|
||||||
ClearCopyStringNoFormat(NewProjectHeader.SearchLocation, sizeof(NewProjectHeader.SearchLocation), CurrentProject->SearchLocation);
|
ClearCopyStringNoFormat(NewProjectHeader.SearchLocation, sizeof(NewProjectHeader.SearchLocation), CurrentProject->SearchLocation);
|
||||||
char *NewSearchDirectory = ConstructDirectoryPath(&NewProjectHeader, &CurrentProject->SearchLocation, 0);
|
string NewBaseDir = Wrap0i(NewProjectHeader.BaseDir, sizeof(NewProjectHeader.BaseDir));
|
||||||
|
string NewSearchLocation = Wrap0i(NewProjectHeader.SearchLocation, sizeof(NewProjectHeader.SearchLocation));
|
||||||
|
|
||||||
|
char *NewSearchDirectory = ConstructDirectoryPath(&NewBaseDir, &NewSearchLocation, 0);
|
||||||
MakeDir(Wrap0(NewSearchDirectory));
|
MakeDir(Wrap0(NewSearchDirectory));
|
||||||
|
|
||||||
printf("%sRelocating Search Page from %s to %s%s\n",
|
printf("%sRelocating Search Page from %s to %s%s\n",
|
||||||
|
@ -13392,8 +13413,8 @@ DeleteDeadDBEntries(neighbourhood *N, bool *Modified)
|
||||||
Free(OldSearchPagePath);
|
Free(OldSearchPagePath);
|
||||||
Free(NewSearchPagePath);
|
Free(NewSearchPagePath);
|
||||||
|
|
||||||
char *OldSearchIndexPath = ConstructIndexFilePath(N->Project);
|
char *OldSearchIndexPath = ConstructIndexFilePath(OldBaseDir, OldSearchLocation, Wrap0i(N->Project->ID, sizeof(N->Project->ID)));
|
||||||
char *NewSearchIndexPath = ConstructIndexFilePath(&NewProjectHeader);
|
char *NewSearchIndexPath = ConstructIndexFilePath(NewBaseDir, NewSearchLocation, Wrap0i(N->Project->ID, sizeof(N->Project->ID)));
|
||||||
rename(OldSearchIndexPath, NewSearchIndexPath);
|
rename(OldSearchIndexPath, NewSearchIndexPath);
|
||||||
Free(OldSearchIndexPath);
|
Free(OldSearchIndexPath);
|
||||||
Free(NewSearchIndexPath);
|
Free(NewSearchIndexPath);
|
||||||
|
@ -13401,10 +13422,10 @@ DeleteDeadDBEntries(neighbourhood *N, bool *Modified)
|
||||||
Free(NewSearchDirectory);
|
Free(NewSearchDirectory);
|
||||||
|
|
||||||
FreeFile(&DB.File);
|
FreeFile(&DB.File);
|
||||||
DB.File = InitFile(&CurrentProject->BaseDir, &CurrentProject->ID, EXT_INDEX);
|
DB.File.Path = ConstructIndexFilePath(CurrentProject->BaseDir, CurrentProject->SearchLocation, CurrentProject->ID);
|
||||||
ReadFileIntoBuffer(&DB.File); // NOTE(matt): Could we actually catch errors (permissions?) here and bail?
|
ReadFileIntoBuffer(&DB.File); // NOTE(matt): Could we actually catch errors (permissions?) here and bail?
|
||||||
|
|
||||||
if(SearchLocationL.Length > 0)
|
if(OldSearchLocation.Length > 0)
|
||||||
{
|
{
|
||||||
RemoveChildDirectories(Wrap0(OldSearchDirectory), Wrap0i(N->Project->BaseDir, sizeof(N->Project->BaseDir)));
|
RemoveChildDirectories(Wrap0(OldSearchDirectory), Wrap0i(N->Project->BaseDir, sizeof(N->Project->BaseDir)));
|
||||||
}
|
}
|
||||||
|
@ -13412,7 +13433,7 @@ DeleteDeadDBEntries(neighbourhood *N, bool *Modified)
|
||||||
remove(OldSearchDirectory);
|
remove(OldSearchDirectory);
|
||||||
Free(OldSearchDirectory);
|
Free(OldSearchDirectory);
|
||||||
ClearCopyStringNoFormat(N->Project->SearchLocation, sizeof(N->Project->SearchLocation), CurrentProject->SearchLocation);
|
ClearCopyStringNoFormat(N->Project->SearchLocation, sizeof(N->Project->SearchLocation), CurrentProject->SearchLocation);
|
||||||
NewSearchLocation = TRUE;
|
HasNewSearchLocation = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(StringsDiffer(CurrentProject->BaseDir, Wrap0i(N->Project->BaseDir, sizeof(N->Project->BaseDir))))
|
if(StringsDiffer(CurrentProject->BaseDir, Wrap0i(N->Project->BaseDir, sizeof(N->Project->BaseDir))))
|
||||||
|
@ -13435,7 +13456,7 @@ DeleteDeadDBEntries(neighbourhood *N, bool *Modified)
|
||||||
*Modified = TRUE;
|
*Modified = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(NewPlayerLocation || NewSearchLocation)
|
if(HasNewPlayerLocation || HasNewSearchLocation)
|
||||||
{
|
{
|
||||||
if(!(DB.Metadata.File.Handle = fopen(DB.Metadata.File.Path, "w"))) { FreeBuffer(&DB.Metadata.File.Buffer); return RC_ERROR_FILE; }
|
if(!(DB.Metadata.File.Handle = fopen(DB.Metadata.File.Path, "w"))) { FreeBuffer(&DB.Metadata.File.Buffer); return RC_ERROR_FILE; }
|
||||||
ClearCopyStringNoFormat(N->Project->BaseDir, sizeof(N->Project->BaseDir), CurrentProject->BaseDir);
|
ClearCopyStringNoFormat(N->Project->BaseDir, sizeof(N->Project->BaseDir), CurrentProject->BaseDir);
|
||||||
|
@ -14113,13 +14134,16 @@ DeleteHTMLFilesOfProject(db_header_project *Project)
|
||||||
char *Ptr = (char *)Project;
|
char *Ptr = (char *)Project;
|
||||||
Ptr += sizeof(db_header_project) + sizeof(db_entry) * Project->EntryCount;
|
Ptr += sizeof(db_header_project) + sizeof(db_entry) * Project->EntryCount;
|
||||||
|
|
||||||
|
string BaseDir = Wrap0i(Project->BaseDir, sizeof(Project->BaseDir));
|
||||||
|
string PlayerLocation = Wrap0i(Project->PlayerLocation, sizeof(Project->PlayerLocation));
|
||||||
|
|
||||||
db_entry *Entry = LocateFirstEntry(Project);
|
db_entry *Entry = LocateFirstEntry(Project);
|
||||||
for(int i = 0; i < Project->EntryCount; ++i, ++Entry)
|
for(int i = 0; i < Project->EntryCount; ++i, ++Entry)
|
||||||
{
|
{
|
||||||
DeletePlayerPageFromFilesystem(Project, Wrap0i(Entry->OutputLocation, sizeof(Entry->OutputLocation)), FALSE, FALSE);
|
DeletePlayerPageFromFilesystem(BaseDir, PlayerLocation, Wrap0i(Entry->OutputLocation, sizeof(Entry->OutputLocation)), FALSE, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
DeleteSearchPageFromFilesystem(Project);
|
DeleteSearchPageFromFilesystem(BaseDir, PlayerLocation, Wrap0i(Project->ID, sizeof(Project->ID)));
|
||||||
|
|
||||||
return Ptr;
|
return Ptr;
|
||||||
}
|
}
|
||||||
|
@ -14132,7 +14156,9 @@ DeleteHTMLFilesOfProjectAndChildren(db_header_project *Project)
|
||||||
{
|
{
|
||||||
Ptr = DeleteHTMLFilesOfProjectAndChildren(Ptr);
|
Ptr = DeleteHTMLFilesOfProjectAndChildren(Ptr);
|
||||||
}
|
}
|
||||||
DeleteSearchPageFromFilesystem(Project);
|
string BaseDir = Wrap0i(Project->BaseDir, sizeof(Project->BaseDir));
|
||||||
|
string SearchLocation = Wrap0i(Project->SearchLocation, sizeof(Project->SearchLocation));
|
||||||
|
DeleteSearchPageFromFilesystem(BaseDir, SearchLocation, Wrap0i(Project->ID, sizeof(Project->ID)));
|
||||||
return Ptr;
|
return Ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14437,7 +14463,10 @@ SyncProjects_TopLevel(project_generations *G, project *C, db_block_projects **SP
|
||||||
|
|
||||||
if((*SChild)->ChildCount == 0 && (*SChild)->EntryCount == 0)
|
if((*SChild)->ChildCount == 0 && (*SChild)->EntryCount == 0)
|
||||||
{
|
{
|
||||||
DeleteSearchPageFromFilesystem(*SChild);
|
string BaseDir = Wrap0i((*SChild)->BaseDir, sizeof((*SChild)->BaseDir));
|
||||||
|
string SearchLocation = Wrap0i((*SChild)->SearchLocation, sizeof((*SChild)->SearchLocation));
|
||||||
|
string ProjectID = Wrap0i((*SChild)->ID, sizeof((*SChild)->ID));
|
||||||
|
DeleteSearchPageFromFilesystem(BaseDir, SearchLocation, ProjectID);
|
||||||
DeleteLandmarksForSearch(C->Index);
|
DeleteLandmarksForSearch(C->Index);
|
||||||
DeleteStaleAssets();
|
DeleteStaleAssets();
|
||||||
}
|
}
|
||||||
|
@ -14491,7 +14520,11 @@ SyncProjects(project_generations *G, project *C, db_header_project **SParent, db
|
||||||
|
|
||||||
if((*SChild)->ChildCount == 0 && (*SChild)->EntryCount == 0)
|
if((*SChild)->ChildCount == 0 && (*SChild)->EntryCount == 0)
|
||||||
{
|
{
|
||||||
DeleteSearchPageFromFilesystem(*SChild);
|
string BaseDir = Wrap0i((*SChild)->BaseDir, sizeof((*SChild)->BaseDir));
|
||||||
|
string SearchLocation = Wrap0i((*SChild)->SearchLocation, sizeof((*SChild)->SearchLocation));
|
||||||
|
string ProjectID = Wrap0i((*SChild)->ID, sizeof((*SChild)->ID));
|
||||||
|
DeleteSearchPageFromFilesystem(BaseDir, SearchLocation, ProjectID);
|
||||||
|
|
||||||
DeleteLandmarksForSearch(C->Index);
|
DeleteLandmarksForSearch(C->Index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -521,6 +521,7 @@ typedef struct project
|
||||||
string StreamUsername;
|
string StreamUsername;
|
||||||
string VODPlatform;
|
string VODPlatform;
|
||||||
|
|
||||||
|
bool DenyBespokeTemplates;
|
||||||
bool SingleBrowserTab;
|
bool SingleBrowserTab;
|
||||||
bool IgnorePrivacy;
|
bool IgnorePrivacy;
|
||||||
|
|
||||||
|
@ -917,6 +918,7 @@ InitTypeSpecs(void)
|
||||||
////
|
////
|
||||||
PushTypeSpecField(Root, FT_STRING, IDENT_UNIT, TRUE);
|
PushTypeSpecField(Root, FT_STRING, IDENT_UNIT, TRUE);
|
||||||
PushTypeSpecField(Root, FT_BARE, IDENT_TITLE_LIST_END, TRUE);
|
PushTypeSpecField(Root, FT_BARE, IDENT_TITLE_LIST_END, TRUE);
|
||||||
|
PushTypeSpecField(Root, FT_BOOLEAN, IDENT_DENY_BESPOKE_TEMPLATES, TRUE);
|
||||||
PushTypeSpecField(Root, FT_BOOLEAN, IDENT_IGNORE_PRIVACY, TRUE);
|
PushTypeSpecField(Root, FT_BOOLEAN, IDENT_IGNORE_PRIVACY, TRUE);
|
||||||
PushTypeSpecField(Root, FT_BOOLEAN, IDENT_SINGLE_BROWSER_TAB, TRUE);
|
PushTypeSpecField(Root, FT_BOOLEAN, IDENT_SINGLE_BROWSER_TAB, TRUE);
|
||||||
PushTypeSpecField(Root, FT_NUMBER, IDENT_PRIVACY_CHECK_INTERVAL, TRUE);
|
PushTypeSpecField(Root, FT_NUMBER, IDENT_PRIVACY_CHECK_INTERVAL, TRUE);
|
||||||
|
@ -997,6 +999,7 @@ InitTypeSpecs(void)
|
||||||
PushTypeSpecField(Project, FT_BARE, IDENT_TITLE_LIST_END, TRUE);
|
PushTypeSpecField(Project, FT_BARE, IDENT_TITLE_LIST_END, TRUE);
|
||||||
|
|
||||||
// NOTE(matt): Modes
|
// NOTE(matt): Modes
|
||||||
|
PushTypeSpecField(Project, FT_BOOLEAN, IDENT_DENY_BESPOKE_TEMPLATES, TRUE);
|
||||||
PushTypeSpecField(Project, FT_BOOLEAN, IDENT_IGNORE_PRIVACY, TRUE);
|
PushTypeSpecField(Project, FT_BOOLEAN, IDENT_IGNORE_PRIVACY, TRUE);
|
||||||
PushTypeSpecField(Project, FT_BOOLEAN, IDENT_SINGLE_BROWSER_TAB, TRUE);
|
PushTypeSpecField(Project, FT_BOOLEAN, IDENT_SINGLE_BROWSER_TAB, TRUE);
|
||||||
//
|
//
|
||||||
|
@ -3377,6 +3380,8 @@ PushProject(config *C, resolution_errors *E, config_verifiers *V, project *P, sc
|
||||||
config_bool_pair *This = ProjectTree->BoolPairs + i;
|
config_bool_pair *This = ProjectTree->BoolPairs + i;
|
||||||
switch(This->Key)
|
switch(This->Key)
|
||||||
{
|
{
|
||||||
|
case IDENT_DENY_BESPOKE_TEMPLATES:
|
||||||
|
{ P->DenyBespokeTemplates = This->Value; } break;
|
||||||
case IDENT_IGNORE_PRIVACY:
|
case IDENT_IGNORE_PRIVACY:
|
||||||
{ P->IgnorePrivacy = This->Value; } break;
|
{ P->IgnorePrivacy = This->Value; } break;
|
||||||
case IDENT_SINGLE_BROWSER_TAB:
|
case IDENT_SINGLE_BROWSER_TAB:
|
||||||
|
|
|
@ -34,10 +34,11 @@ function hideEntriesOfProject(ProjectElement)
|
||||||
ProjectElement.classList.add("off");
|
ProjectElement.classList.add("off");
|
||||||
}
|
}
|
||||||
var baseURL = ProjectElement.attributes.getNamedItem("data-baseURL").value;
|
var baseURL = ProjectElement.attributes.getNamedItem("data-baseURL").value;
|
||||||
|
var searchLocation = ProjectElement.attributes.getNamedItem("data-searchLocation").value;
|
||||||
for(var i = 0; i < projects.length; ++i)
|
for(var i = 0; i < projects.length; ++i)
|
||||||
{
|
{
|
||||||
var ThisProject = projects[i];
|
var ThisProject = projects[i];
|
||||||
if(ThisProject.baseURL === baseURL)
|
if(baseURL === ThisProject.baseURL && searchLocation === ThisProject.searchLocation)
|
||||||
{
|
{
|
||||||
ThisProject.filteredOut = true;
|
ThisProject.filteredOut = true;
|
||||||
if(ThisProject.entriesContainer != null)
|
if(ThisProject.entriesContainer != null)
|
||||||
|
@ -56,10 +57,11 @@ function showEntriesOfProject(ProjectElement)
|
||||||
ProjectElement.classList.remove("off");
|
ProjectElement.classList.remove("off");
|
||||||
}
|
}
|
||||||
var baseURL = ProjectElement.attributes.getNamedItem("data-baseURL").value;
|
var baseURL = ProjectElement.attributes.getNamedItem("data-baseURL").value;
|
||||||
|
var searchLocation = ProjectElement.attributes.getNamedItem("data-searchLocation").value;
|
||||||
for(var i = 0; i < projects.length; ++i)
|
for(var i = 0; i < projects.length; ++i)
|
||||||
{
|
{
|
||||||
var ThisProject = projects[i];
|
var ThisProject = projects[i];
|
||||||
if(ThisProject.baseURL === baseURL)
|
if(baseURL === ThisProject.baseURL && searchLocation === ThisProject.searchLocation)
|
||||||
{
|
{
|
||||||
ThisProject.filteredOut = false;
|
ThisProject.filteredOut = false;
|
||||||
if(ThisProject.entriesContainer != null)
|
if(ThisProject.entriesContainer != null)
|
||||||
|
@ -71,7 +73,7 @@ function showEntriesOfProject(ProjectElement)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideProjectSearchResults(baseURL)
|
function hideProjectSearchResults(baseURL, playerLocation)
|
||||||
{
|
{
|
||||||
var cineraResults = document.getElementById("cineraResults");
|
var cineraResults = document.getElementById("cineraResults");
|
||||||
if(cineraResults)
|
if(cineraResults)
|
||||||
|
@ -80,7 +82,8 @@ function hideProjectSearchResults(baseURL)
|
||||||
for(var i = 0; i < cineraResultsProjects.length; ++i)
|
for(var i = 0; i < cineraResultsProjects.length; ++i)
|
||||||
{
|
{
|
||||||
var resultBaseURL = cineraResultsProjects[i].attributes.getNamedItem("data-baseURL").value;
|
var resultBaseURL = cineraResultsProjects[i].attributes.getNamedItem("data-baseURL").value;
|
||||||
if(baseURL === resultBaseURL)
|
var resultPlayerLocation = cineraResultsProjects[i].attributes.getNamedItem("data-playerLocation").value;
|
||||||
|
if(baseURL === resultBaseURL && playerLocation === resultPlayerLocation)
|
||||||
{
|
{
|
||||||
cineraResultsProjects[i].style.display = "none";
|
cineraResultsProjects[i].style.display = "none";
|
||||||
return;
|
return;
|
||||||
|
@ -89,7 +92,7 @@ function hideProjectSearchResults(baseURL)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function showProjectSearchResults(baseURL)
|
function showProjectSearchResults(baseURL, playerLocation)
|
||||||
{
|
{
|
||||||
var cineraResults = document.getElementById("cineraResults");
|
var cineraResults = document.getElementById("cineraResults");
|
||||||
if(cineraResults)
|
if(cineraResults)
|
||||||
|
@ -98,7 +101,8 @@ function showProjectSearchResults(baseURL)
|
||||||
for(var i = 0; i < cineraResultsProjects.length; ++i)
|
for(var i = 0; i < cineraResultsProjects.length; ++i)
|
||||||
{
|
{
|
||||||
var resultBaseURL = cineraResultsProjects[i].attributes.getNamedItem("data-baseURL").value;
|
var resultBaseURL = cineraResultsProjects[i].attributes.getNamedItem("data-baseURL").value;
|
||||||
if(baseURL === resultBaseURL)
|
var resultPlayerLocation = cineraResultsProjects[i].attributes.getNamedItem("data-playerLocation").value;
|
||||||
|
if(baseURL === resultBaseURL && playerLocation === resultPlayerLocation)
|
||||||
{
|
{
|
||||||
cineraResultsProjects[i].style.display = "flex";
|
cineraResultsProjects[i].style.display = "flex";
|
||||||
return;
|
return;
|
||||||
|
@ -110,6 +114,7 @@ function showProjectSearchResults(baseURL)
|
||||||
function toggleEntriesOfProjectAndChildren(ProjectFilterElement)
|
function toggleEntriesOfProjectAndChildren(ProjectFilterElement)
|
||||||
{
|
{
|
||||||
var baseURL = ProjectFilterElement.attributes.getNamedItem("data-baseURL").value;
|
var baseURL = ProjectFilterElement.attributes.getNamedItem("data-baseURL").value;
|
||||||
|
var searchLocation = ProjectFilterElement.attributes.getNamedItem("data-searchLocation").value;
|
||||||
var shouldShow = ProjectFilterElement.classList.contains("off");
|
var shouldShow = ProjectFilterElement.classList.contains("off");
|
||||||
if(shouldShow)
|
if(shouldShow)
|
||||||
{
|
{
|
||||||
|
@ -125,7 +130,8 @@ function toggleEntriesOfProjectAndChildren(ProjectFilterElement)
|
||||||
for(var i = 0; i < projects.length; ++i)
|
for(var i = 0; i < projects.length; ++i)
|
||||||
{
|
{
|
||||||
var ThisProject = projects[i];
|
var ThisProject = projects[i];
|
||||||
if(ThisProject.baseURL === baseURL)
|
|
||||||
|
if(ThisProject.baseURL === baseURL && ThisProject.searchLocation === searchLocation)
|
||||||
{
|
{
|
||||||
if(shouldShow)
|
if(shouldShow)
|
||||||
{
|
{
|
||||||
|
@ -135,7 +141,7 @@ function toggleEntriesOfProjectAndChildren(ProjectFilterElement)
|
||||||
{
|
{
|
||||||
ThisProject.entriesContainer.style.display = "flex";
|
ThisProject.entriesContainer.style.display = "flex";
|
||||||
}
|
}
|
||||||
showProjectSearchResults(projects[i].baseURL);
|
showProjectSearchResults(ThisProject.baseURL, ThisProject.playerLocation);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -145,7 +151,7 @@ function toggleEntriesOfProjectAndChildren(ProjectFilterElement)
|
||||||
{
|
{
|
||||||
ThisProject.entriesContainer.style.display = "none";
|
ThisProject.entriesContainer.style.display = "none";
|
||||||
}
|
}
|
||||||
hideProjectSearchResults(ThisProject.baseURL);
|
hideProjectSearchResults(ThisProject.baseURL, ThisProject.playerLocation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,17 +161,17 @@ function toggleEntriesOfProjectAndChildren(ProjectFilterElement)
|
||||||
for(var j = 0; j < indexChildFilterProjects.length; ++j)
|
for(var j = 0; j < indexChildFilterProjects.length; ++j)
|
||||||
{
|
{
|
||||||
var ThisElement = indexChildFilterProjects[j];
|
var ThisElement = indexChildFilterProjects[j];
|
||||||
|
var baseURL = ThisElement.attributes.getNamedItem("data-baseURL").value;
|
||||||
|
var playerLocation = ThisElement.attributes.getNamedItem("data-playerLocation").value;
|
||||||
if(shouldShow)
|
if(shouldShow)
|
||||||
{
|
{
|
||||||
var baseURL = ThisElement.attributes.getNamedItem("data-baseURL").value;
|
|
||||||
showEntriesOfProject(ThisElement);
|
showEntriesOfProject(ThisElement);
|
||||||
showProjectSearchResults(baseURL);
|
showProjectSearchResults(baseURL, playerLocation);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var baseURL = ThisElement.attributes.getNamedItem("data-baseURL").value;
|
|
||||||
hideEntriesOfProject(ThisElement);
|
hideEntriesOfProject(ThisElement);
|
||||||
hideProjectSearchResults(baseURL);
|
hideProjectSearchResults(baseURL, playerLocation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -280,14 +286,17 @@ function prepareProjects()
|
||||||
{
|
{
|
||||||
var ID = projectsContainer[i].attributes.getNamedItem("data-project").value;
|
var ID = projectsContainer[i].attributes.getNamedItem("data-project").value;
|
||||||
var baseURL = projectsContainer[i].attributes.getNamedItem("data-baseURL").value;
|
var baseURL = projectsContainer[i].attributes.getNamedItem("data-baseURL").value;
|
||||||
|
var searchLocation = projectsContainer[i].attributes.getNamedItem("data-searchLocation").value;
|
||||||
var playerLocation = projectsContainer[i].attributes.getNamedItem("data-playerLocation").value;
|
var playerLocation = projectsContainer[i].attributes.getNamedItem("data-playerLocation").value;
|
||||||
var theme = projectsContainer[i].classList.item(1);
|
var theme = projectsContainer[i].classList.item(1);
|
||||||
|
|
||||||
projects[i] =
|
projects[i] =
|
||||||
{
|
{
|
||||||
baseURL: baseURL,
|
baseURL: baseURL,
|
||||||
|
searchLocation: searchLocation,
|
||||||
|
playerLocation: playerLocation,
|
||||||
playerURLPrefix: (baseURL ? baseURL + "/" : "") + (playerLocation ? playerLocation + "/" : ""),
|
playerURLPrefix: (baseURL ? baseURL + "/" : "") + (playerLocation ? playerLocation + "/" : ""),
|
||||||
indexLocation: (baseURL ? baseURL + "/" : "") + ID + ".index",
|
indexLocation: (baseURL ? baseURL + "/" : "") + (searchLocation ? searchLocation + "/" : "") + ID + ".index",
|
||||||
projectTitleElement: projectsContainer[i].querySelector(":scope > .cineraProjectTitle"),
|
projectTitleElement: projectsContainer[i].querySelector(":scope > .cineraProjectTitle"),
|
||||||
entriesContainer: projectsContainer[i].querySelector(":scope > .cineraIndexEntries"),
|
entriesContainer: projectsContainer[i].querySelector(":scope > .cineraIndexEntries"),
|
||||||
dayContainerPrototype: dayContainerPrototype.cloneNode(true),
|
dayContainerPrototype: dayContainerPrototype.cloneNode(true),
|
||||||
|
@ -529,6 +538,7 @@ function renderResults() {
|
||||||
if(projects[i].playerURLPrefix === episode.playerURLPrefix)
|
if(projects[i].playerURLPrefix === episode.playerURLPrefix)
|
||||||
{
|
{
|
||||||
projectContainer.setAttribute("data-baseURL", projects[i].baseURL);
|
projectContainer.setAttribute("data-baseURL", projects[i].baseURL);
|
||||||
|
projectContainer.setAttribute("data-playerLocation", projects[i].playerLocation);
|
||||||
if(projects[i].filteredOut)
|
if(projects[i].filteredOut)
|
||||||
{
|
{
|
||||||
projectContainer.style.display = "none";
|
projectContainer.style.display = "none";
|
||||||
|
|
Loading…
Reference in New Issue