Warning: session_start(): open(/var/lib/php/sessions/sess_8akol2bsoq62s4f1cjib4qvg0q, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
!7
// TODO: prevent non-master users from setting createdBy field manually
!include early #1031277 // BEA general includes
!include once #1030833 // BEACalculations
set flag defaultDefaultClassFinder_debug.
set flag CleanImports.
set flag DynModule.
set flag NoNanoHTTPD.
rewrite BEA with BEAObject.
mainPackage gazelle
mainClassName main
module GazelleBEA > DynGazelleRocks {
switchable bool mirrorBEAObjects; // don't do it for now
switchable bool enableAutoRuns = true;
switchable bool enableNewBEAObjectNotis = true;
switchable bool printAllConceptChanges;
switchable bool useShadowLogger = true;
switchable bool autoActivateDynamicObjects = true;
transient ReliableSingleThread_Multi rstAutoRuns = new(1000, lambda1 performAutoRuns);
transient Q notificationQ;
transient ReliableSingleThread_Multi rstDistributeNewObject = new(1000, lambda1 distributeNewObject_impl);
transient Set newObjectsDistributed = weakSet();
transient ReliableSingleThread_Multi rstUpdateBEAMirrors = new(100, c -> enter { c.updateMirrorPost(); });
transient ReliableSingleThread_Multi rstAutoActivateDynamicObjects = new(100, c -> enter { autoActivateDynamicObject(c); });
transient BEACalculations calculations = new(this);
transient BEACalculations calc = calculations;
transient int newFieldsToShow = 3;
transient bool allowAnonymousInputUpload = true; // TODO
switchable int maxInputLength = 50000;
transient ConceptClassesDependentValue inputsWithoutRewrites;
transient ConceptClassesDependentValue inputsWithoutMatches;
transient ConceptClassesDependentValue syntacticPatternsWithoutRewrites;
// add more fields here
!include #1030883 // DB quickImport mix-in
void init {
super.init();
//set quickDBReloadEnabled;
botName = heading = adminName = "Gazelle BEA";
set enableVars;
unset showTalkToBotLink;
unset phoneNumberSpecialInputField;
unset showMetaBotOnEveryPage;
}
void startDB {
db();
db_mainConcepts().useBackRefsForSearches = true;
inputsWithoutRewrites = ConceptClassesDependentValue(litset(BEA), () -> countPred(beaList("Input"), c -> empty(beaBackRefs(c, "Rewrite"))));
inputsWithoutMatches = ConceptClassesDependentValue(litset(BEA), () -> countPred(beaList("Input"), c -> empty(beaBackRefs(c, "Match"))));
syntacticPatternsWithoutRewrites = ConceptClassesDependentValue(litset(BEA), () -> countPred(beaList("Syntactic Pattern"), c -> empty(beaBackRefs(c, "Rewrite"))));
if (useShadowLogger) {
ConceptsShadowLogger shadowLogger = new(db_mainConcepts());
shadowLogger.install();
//shadowLogger.writer = printWriter(deflaterOutputStream_syncFlush_append(programFile("shadow.log.deflated")));
shadowLogger.writer = filePrintWriter_append(programFile("shadow.log"));
dm_doEvery(10.0, r { shadowLogger.flush(); });
ownResource(shadowLogger);
}
if (printAllConceptChanges) printAllConceptChanges();
}
void start {
S name = mcDollar() + "BEAObject";
print(+name);
assertEquals(BEAObject, callF(defaultDefaultClassFinder(), name));
assertEquals(ConceptWithGlobalID, callF(defaultDefaultClassFinder(), mcDollar() + "ConceptWithGlobalID"));
seedDBFrom(#1030602);
set botDisabled;
set storeBaseClassesInStructure;
super.start();
print("main concepts: " + db_mainConcepts() + ", count: " + db_mainConcepts().countConcepts());
print(renderConceptClassesWithCount(db_mainConcepts()));
print("Inputs: " + n2(beaCount("Input")));
set showCRUDToEveryone;
//set showOnlySelectedObject;
// reload module when lib changes
dm_onSnippetTranspiled(voidfunc(S snippetID) {
if (sameSnippetID(snippetID, #1030952))
dm_reloadModule();
});
if (!enabled) ret;
// mirror all objects to be sure
rstUpdateBEAMirrors.addAll(list(BEAObject));
newObjectsDistributed.addAll(list(BEAObject));
/*onIndividualConceptChange_notOnAllChanged(BEAObject,
p -> { calculations.makeSyntacticPattern(p); });*/
onIndividualConceptChange_notOnAllChanged(BEAObject,
o -> {
if (enableAutoRuns) rstAutoRuns.add(o);
if (enableNewBEAObjectNotis && newObjectsDistributed.add(o))
rstDistributeNewObject.add(o);
});
notificationQ = dm_startQ();
// fix refs occasionally
dm_doEvery(5*60.0, r-enter {
print(ConceptsRefChecker(db_mainConcepts()).runAndFixAll());
});
}
void makeIndices :: after {
indexConceptFieldDesc(BEAObject, "_modified");
indexConceptFieldIC(BEAObject, "type");
indexConceptFieldIC(BEAObject, "text");
}
L crudClasses(Req req) {
ret listPlus(super.crudClasses(req), BEAObject, /*BEAPatternList*/);
}
Set hiddenCrudClasses() {
Set set = super.hiddenCrudClasses();
addAll(set, Conversation, ExecutedStep, InputHandled);
ret set;
}
S authFormHeading() {
ret h3("Gazelle BEA");
}
void makeFramer(Req req) {
super.makeFramer(req);
req.framer.addInHead(hjs_autoExpandingTextAreas());
}
HCRUD_Concepts crudData(Class c, Req req) {
HCRUD_Concepts cc = super.crudData(c, req);
if (c == BEAObject) {
cc.humanizeFieldNames = false;
cc.convertConceptValuesToRefs = true;
cc.itemName = () -> "BEA Object";
cc.onCreate.add(o ->
cset(o, createdBy := currentUser()));
cc.getObjectForDuplication = id -> {
MapSO item = cc.getObjectForDuplication_base(id);
item.put(createdBy := req.auth.user!); // set default creator to current user
item.put(createdFrom := getConcept(toLong(id)));
ret item;
};
cc.emptyObject = () -> {
MapSO item = cc.emptyObject_base();
item.put(type := "");
ret item;
};
Set deletableRefs = litciset("Match");
cc.objectCanBeDeleted = id -> {
BEA o = cast cc.conceptForID(id);
ret userCanEditObject(user(req), o)
&& all(findBackRefs(BEAObject, o), x -> contains(deletableRefs, x.type()));
};
cc.actuallyDeleteConcept = o -> {
deleteConcepts(filter(findBackRefs(BEAObject, o),
o2 -> contains(deletableRefs, o2.type())));
cdelete(o);
};
}
ret cc;
}
HCRUD makeCRUD(Class c, Req req, HTMLFramer1 framer) {
HCRUD crud = super.makeCRUD(c, req, framer);
HCRUD_Concepts data = cast crud.data;
crud.showOnlySelected = true;
crud.showSearchField = true;
if (data.customFilter == null)
crud.descending = true; // show latest objects first by default except when searching
crud.cleanItemIDs = true;
if (c == BEAObject) {
crud.cellColumnToolTips = true;
crud.unshownFields = litset("mirrorPost", "globalID");
crud.showTextFieldsAsAutoExpandingTextAreas = true;
HCRUD_Concepts cc = cast crud.data;
S typeFilter = req.get("type");
if (nempty(typeFilter))
cc.addCIFilter(type := typeFilter);
crud.renderCmds = map -> {
BEAObject o = getConcept BEAObject(crud.itemIDAsLong(map));
new LS cmds;
// special commands for BEA types or objects with certain fields
if (nempty(o.text()))
cmds.add(
targetBlank(addParamsToURL(baseLink + "/query",
q := o.text(), algorithm := "process input"),
"Use text as query"));
if (o.typeIs("Input")) {
cmds.add(ahref(addParamsToURL(crudLink(BEAObject),
cmd := "new",
title := "Add Pattern For Input",
f_type := "Pattern",
f_text := getStringOpt text(o),
f_shouldMatch := o.id, metaInfo_shouldMatch := "concept",
), "Add pattern"));
cmds.add(ahref(appendParamsToURL(baseLink + "/query", q := o.text(), algorithm := "Apply all text functions"),
"Apply all text functions"));
}
if (o.typeIs("Pattern"))
cmds.add(ahref(appendParamsToURL(baseLink + "/query", q := o.id, algorithm := "Run pattern"),
"Try-run pattern against all inputs"));
if (o.typeIsOneOf("Pattern", "Syntactic Pattern")) {
cmds.add(ahref(appendParamsToURL(baseLink + "/reactAllInputsWithPattern", patternID := o.id),
"React pattern with all inputs"));
cmds.add(ahref(appendParamsToURL(baseLink + "/convertSyntacticToSemanticMatchesForWholePattern", patternID := o.id),
"Convert all syntactic matches to semantic matches"));
}
if (o.typeIs("Match")) {
cmds.add(ahref(appendParamsToURL(baseLink + "/query", q := o.id, algorithm := "Find rewrites for match"),
"Find rewrites"));
if (beaTypeIs(beaGet pattern(o), "Syntactic Pattern"))
cmds.add(ahref(appendParamsToURL(baseLink + "/convertSyntacticToSemanticMatches", matchID := o.id),
"Convert to semantic matches"));
}
cmds.add(
ahref(addParamsToURL(baseLink + "/markUseful",
redirect := beaShortURL(o),
objectID := o.id),
"Mark useful"));
cmds.add(
ahref(addParamsToURL(baseLink + "/markBad",
redirect := beaShortURL(o),
objectID := o.id),
"Mark bad"));
cmds.add(addCommentHTML(o));
if (o.typeIsOneOf("Script", "Step in script") || eqic(beforeVerticalBar(o.type()), "Instruction"))
cmds.add(
ahref(addParamsToURL(baseLink + "/runInstruction",
instruction := o.id),
"Run"));
if (o.typeIs("Function Result")) {
if (eqic(cget resultType(o), "string"))
cmds.add(
ahref(addParamsToURL(baseLink + "/convertResultToInput",
result := o.id),
"Convert to input"));
}
if (o.typeIs("Auto Run"))
cmds.add(
ahref(addParamsToURL(baseLink + "/performAutoRunOnAllObjects", autoRun := o.id), "Run on all objects"));
if (o.getClass() != BEA)
cmds.add(
ahref(addParamsToURL(baseLink + "/migrateToBase", id := o.id), "Migrate to BEAObject"));
cmds.add(
ahref(addParamsToURL(baseLink + "/performAutoRuns",
onObject := o.id),
"Perform auto runs on this object"));
framer.addInHead(hjs_copyToClipboard());
cmds.add(ahref_onClick(formatFunctionCall copyToClipboard(jsQuote(o.globalIDStr())), "Copy global ID [" + o.globalIDStr() + "]"));
LS items = llNempties(
crud.renderCmds_base(map),
!o.typeIsOneOf("Input", "Pattern", "Syntactic Pattern")
? null : addRewriteHTML(o),
!canAutoMigrate(o) ? null
: ahref(addParamsToURL(baseLink + "/autoMigrate", id := o.id), "Auto-migrate to " + shortClassName(defaultCustomClass(o))));
if (isObjectWithCode(o) && isMasterAuthed(req))
items.add(ahref(baseLink + "/activateDynamicObject?id=" + o.id, "Activate custom code"));
if (fileNotEmpty(javaSourceFileForObject(o)))
cmds.add(ahref(baseLink + "/javaSource?id=" + o.id, "Show Java source"));
// add more commands here
addAll(items, o.directCmds());
items.add(hPopDownButton(cmds));
ret joinNemptiesWithVBar(items);
};
cc.massageItemMapForList = (item, map) -> {
BEAObject o = cast item;
if (o.typeIs("Input")) {
Cl matches = objectsWhereNotIC(objectsWhereCI(findBackRefs(o, BEAObject), type := "match"),
label := "bad");
map/Map.put("Best Matches", HTML(hparagraphs(
lmap matchDescHTML(takeFirst(3, matches)))));
}
S idField = crud.idField();
O id = map/Map.get(idField);
if (id instanceof S)
map/Map.put(idField, HTML(ahref(beaShortURL(o), id)));
if (o.typeIs("Function Result")) {
O value = o~.result;
map/Map.put("result", HTML(javaValueToHTML(value)));
}
if (o.typeIs("Match")) {
SS mapping = o.mapping();
if (mapping != null)
map/Map.put("mapping", HTML(
joinWithBR(map(mapping, (k, v) ->
htmlEncode2(k) + "=" + calculations.bestInputHTML(v)))));
}
if (o.getClass() != BEA)
map/Map.put("Java Class", shortClassName(o));
if (eq(req.get("showSimpleObjectScore"), "1"))
map/Map.put("Simple object score" := calculations.simpleObjectScore(o));
}; // end of massageItemMapForList
crud.massageFormMatrix = (map, matrix) -> {
for (int i = 1; i <= newFieldsToShow; i++) {
S nf = "newField" + i;
S refSelector =
crud.renderInput("\*nf*/_conceptValue",
cc.makeConceptsComboBox("\*nf*/_conceptValue", BEAObject), null)
+ hjs([[$("[name=]] + nf + [[_conceptValue]").hide()]]);
S userSelector =
crud.renderInput("\*nf*/_userValue",
cc.makeConceptsComboBox("\*nf*/_userValue", User), null)
+ hjs([[$("[name=]] + nf + [[_userValue]").hide()]]);
LS types = ll("String", "BEAObject", "Bool", "User");
S typeSelector = hselect_list(types, name := "\*nf*/_type",
onchange := [[
var value = this.value;
$("[name=]] + nf + [[_value]").toggle(value == "String" || value == "Bool");
$("#]] + nf + [[_refBox").toggle(value == "BEAObject");
$("#]] + nf + [[_userSel").toggle(value == "User");
]]);
matrix.add(ll("Add field:
" + htextfield("\*nf*/_name", title := "New field name"),
htmlTable2_noHtmlEncode(ll(ll(
// string input
//htextfield("\*nf*/_value"),
htextarea("",
name := "\*nf*/_value",
class := "auto-expand",
style := "max-height: 10em; width: 300px; vertical-align: top",
) +
span(refSelector, id := "\*nf*/_refBox", style := "display: none"),
span(userSelector, id := "\*nf*/_userSel", style := "display: none"),
"Type", typeSelector
)),
noHeader := true,
tableParams := litobjectarray(style := "width: 100%"))));
}
};
crud.preprocessUpdateParams = params -> {
params = cloneMap(params);
// drop empty strings
//removeFromMapWhereValue(params, v -> eq(v, ""));
params = mapValues(params, v -> eq(v, "") ? null : v);
for (int i = 1; i <= max(newFieldsToShow, 10); i++) {
S nf = "newField" + i;
S name = params.get("\*nf*/_name"),
type = params.get("\*nf*/_type"),
refValue = params.get("\*nf*/_conceptValue"),
userValue = params.get("\*nf*/_userValue"),
value = params.get("\*nf*/_value");
if (eqic(type, "BEAObject")) {
value = refValue;
params.put("metaInfo_" + name, "concept");
} else if (eqic(type, "User")) {
value = userValue;
params.put("metaInfo_" + name, "concept");
} else if (eqic(type, "Bool"))
params.put("metaInfo_" + name, "bool");
if (eq(value, "")) value = null;
if (nempty(name) /*&& neqOneOf(value, null, "")*/)
params.put(crud.fieldPrefix + name, value);
}
ret params;
};
// regular users can only edit their own objects
if (!isMasterAuthed(req))
cc.objectCanBeEdited = id -> userCanEditObject(user(req), (BEA) cc.conceptForID(id));
} // end of CRUD customization for BEAObject
ret crud;
}
bool userCanEditObject(User user, BEA o) {
ret cget createdBy(o) == user;
}
O serveBotFunction(Req req, S function, Map data, User user) {
if (eq(function, "beaList")) {
long changedAfter = toLong(data.get("changedAfter"));
double pollFor = min(bot_maxPollSeconds, toLong(data.get("pollFor"))); // how long to poll (seconds)
long startTime = sysNow();
// We're super-anal about catching all changes. This will probably never trigger
if (changedAfter > 0 && changedAfter == now()) sleep(1);
Cl objects;
while true {
objects = changedAfter == 0 ? list(BEAObject)
: conceptsWithFieldGreaterThan_sorted(BEAObject, _modified := changedAfter);
// return when there are results, no polling or poll expired
if (nempty(objects) || pollFor == 0 || elapsedSeconds_sysNow(startTime) >= pollFor)
ret serveJSON_breakAtLevels(2, result := map(objects, obj ->
litorderedmap(gid := str(obj.globalID()), struct := obj.structureString())
));
// sleep and try again
sleep(bot_pollInterval);
}
}
ret super.serveBotFunction(req, function, data, user);
}
O serveOtherPage2(Req req) null {
printVars_str serveOtherPage2(uri := req.uri);
try object super.serveOtherPage2(req);
S uri = dropTrailingSlashIfNemptyAfterwards(req.uri);
new Matches m;
if (swic_notSame(uri, "/beaCRUD/", m))
ret renderBEAObjectTable(req, urldecode(m.rest()));
if (eq(uri, "/inputs"))
ret renderBEAObjectTable(req, "input");
if (eq(uri, "/syntacticMatchesTable"))
ret hrefresh(baseLink + "/matchesTable?syntacticOnly=1");
if (eq(uri, "/matchesTable")) {
bool syntacticOnly = eq("1", req.get("syntacticOnly"));
new L list;
for (BEA match : beaList("Match")) {
BEA input = cgetOpt BEA(match, "input");
BEA pat = cgetOpt BEA(match, "pattern");
if (syntacticOnly && !calculations.isSyntacticPattern(pat)) continue;
continue if calculations.patternAlwaysMatches(pat);
SS mapping = match.mapping();
if (input == null || pat == null || mapping == null) continue;
list.add(match);
}
list = sortedByCalculatedFieldDesc(list,
match -> conceptID(cgetBEA input(match)));
new HTMLPaginator paginator;
paginator.processParams(req.params());
paginator.baseLink = addParamsToURL(baseLink,
filterKeys(req.params(), p -> eq(p, "syntacticOnly")));
paginator.max = l(list);
req.framer.add(divUnlessEmpty(paginator.renderNav()));
list = subList(list, paginator.visibleRange());
new L