aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/Main.tsx2
-rw-r--r--src/client/views/collections/CollectionView.tsx1
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx32
-rw-r--r--src/scraping/buxton/scraper.py15
-rw-r--r--src/scraping/buxton/scripts/initialization.txt46
-rw-r--r--src/scraping/buxton/scripts/layout.txt1
-rw-r--r--src/server/index.ts29
-rw-r--r--src/server/remapUrl.ts2
8 files changed, 111 insertions, 17 deletions
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index 1cf13aa74..daa778ed3 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -7,6 +7,7 @@ import { Cast } from "../../new_fields/Types";
import { Doc, DocListCastAsync } from "../../new_fields/Doc";
import { List } from "../../new_fields/List";
import { DocServer } from "../DocServer";
+import { PivotView } from "./collections/collectionFreeForm/CollectionFreeFormView";
let swapDocs = async () => {
let oldDoc = await Cast(CurrentUserUtils.UserDocument.linkManagerDoc, Doc);
@@ -33,6 +34,7 @@ let swapDocs = async () => {
DocServer.init(window.location.protocol, window.location.hostname, 4321, info.email);
await Docs.Prototypes.initialize();
await CurrentUserUtils.loadUserDocument(info);
+ await PivotView.loadLayouts();
// updates old user documents to prevent chrome on tree view.
(await Cast(CurrentUserUtils.UserDocument.workspaces, Doc))!.chromeStatus = "disabled";
(await Cast(CurrentUserUtils.UserDocument.recentlyClosed, Doc))!.chromeStatus = "disabled";
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index f59fee985..59572b7e7 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -97,6 +97,7 @@ export class CollectionView extends React.Component<FieldViewProps> {
switch (this.props.Document.viewType) {
case CollectionViewType.Freeform: {
subItems.push({ description: "Custom", icon: "fingerprint", event: CollectionFreeFormView.AddCustomLayout(this.props.Document, this.props.fieldKey) });
+ subItems.push({ description: "Pivot", icon: "fingerprint", event: () => CollectionFreeFormView.SetPivotLayout(this.props.Document) });
break;
}
}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 7ba13e961..17c4e83b0 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -37,6 +37,7 @@ import "./CollectionFreeFormView.scss";
import { MarqueeView } from "./MarqueeView";
import React = require("react");
import { DocumentType, Docs } from "../../../documents/Documents";
+import { RouteStore } from "../../../../server/RouteStore";
library.add(faEye as any, faTable, faPaintBrush, faExpandArrowsAlt, faCompressArrowsAlt, faCompass, faUpload, faBraille, faChalkboard);
@@ -48,6 +49,20 @@ export const panZoomSchema = createSchema({
arrangeInit: ScriptField,
});
+export namespace PivotView {
+
+ export let arrangeInit: string;
+ export let arrangeScript: string;
+
+ export async function loadLayouts() {
+ let response = await fetch(Utils.prepend("/layoutscripts"));
+ let scripts = JSON.parse(await response.text());
+ arrangeInit = scripts[0];
+ arrangeScript = scripts[1];
+ }
+
+}
+
type PanZoomDocument = makeInterface<[typeof panZoomSchema, typeof positionSchema, typeof pageSchema]>;
const PanZoomDocument = makeInterface(panZoomSchema, positionSchema, pageSchema);
@@ -787,6 +802,23 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
};
}
+ public static SetPivotLayout = (target: Doc) => {
+ let setSpecifiedLayoutField = (originalText: string, key: string, params: Record<string, string>, requiredType?: string) => {
+ const script = CompileScript(originalText, {
+ params,
+ requiredType,
+ typecheck: false
+ });
+ if (!script.compiled) {
+ console.log(script.errors.map(error => error.messageText).join("\n"));
+ return;
+ }
+ target[key] = new ScriptField(script);
+ };
+ setSpecifiedLayoutField(PivotView.arrangeInit, "arrangeInit", { collection: "Doc", docs: "Doc[]" }, undefined);
+ setSpecifiedLayoutField(PivotView.arrangeScript, "arrangeScript", { doc: "Doc", index: "number", collection: "Doc", state: "any", docs: "Doc[]" }, "{x: number, y: number, width?: number, height?: number}");
+ }
+
render() {
const easing = () => this.props.Document.panTransformType === "Ease";
Doc.UpdateDocumentExtensionForField(this.props.DataDoc ? this.props.DataDoc : this.props.Document, this.props.fieldKey);
diff --git a/src/scraping/buxton/scraper.py b/src/scraping/buxton/scraper.py
index f0f45d8f9..1c19118fd 100644
--- a/src/scraping/buxton/scraper.py
+++ b/src/scraping/buxton/scraper.py
@@ -17,6 +17,7 @@ dist = "../../server/public/files"
db = MongoClient("localhost", 27017)["Dash"]
target_collection = db.newDocuments
+target_doc_title = "Workspace 1"
schema_guids = []
common_proto_id = ""
@@ -69,7 +70,7 @@ def text_doc_map(string_list):
return listify(proxify_guids(list(map(guid_map, string_list))))
-def write_schema(parse_results, display_fields, storage_key):
+def write_collection(parse_results, display_fields, storage_key, viewType=2):
view_guids = parse_results["child_guids"]
data_doc = parse_results["schema"]
@@ -90,7 +91,7 @@ def write_schema(parse_results, display_fields, storage_key):
"zoomBasis": 1,
"zIndex": 2,
"libraryBrush": False,
- "viewType": 2
+ "viewType": viewType
},
"__type": "Doc"
}
@@ -237,7 +238,7 @@ def parse_document(file_name: str):
copyfile(dir_path + "/" + image, dir_path +
"/" + image.replace(".", "_o.", 1))
copyfile(dir_path + "/" + image, dir_path +
- "/" + image.replace(".", "_m.", 1))
+ "/" + image.replace(".", "_m.", 1))
print(f"extracted {count} images...")
def sanitize(line): return re.sub("[\n\t]+", "", line).replace(u"\u00A0", " ").replace(
@@ -381,22 +382,22 @@ candidates = 0
for file_name in os.listdir(source):
if file_name.endswith('.docx'):
candidates += 1
- schema_guids.append(write_schema(
+ schema_guids.append(write_collection(
parse_document(file_name), ["title", "data"], "image_data"))
print("writing parent schema...")
-parent_guid = write_schema({
+parent_guid = write_collection({
"schema": {
"_id": guid(),
"fields": {},
"__type": "Doc"
},
"child_guids": schema_guids
-}, ["title", "short_description", "original_price"], "data")
+}, ["title", "short_description", "original_price"], "data", 1)
print("appending parent schema to main workspace...\n")
target_collection.update_one(
- {"fields.title": "WS collection 1"},
+ {"fields.title": target_doc_title},
{"$push": {"fields.data.fields": {"fieldId": parent_guid, "__type": "proxy"}}}
)
diff --git a/src/scraping/buxton/scripts/initialization.txt b/src/scraping/buxton/scripts/initialization.txt
new file mode 100644
index 000000000..53f3f0d53
--- /dev/null
+++ b/src/scraping/buxton/scripts/initialization.txt
@@ -0,0 +1,46 @@
+const field = collection.pivotField || "title";
+const width = collection.pivotWidth || 200;
+
+const groups = new Map;
+
+for (const doc of docs) {
+ const val = doc[field];
+ if (val === undefined) continue;
+
+ const l = groups.get(val);
+ if (l) {
+ l.push(doc);
+ } else {
+ groups.set(val, [doc]);
+ }
+
+}
+
+let minSize = Infinity;
+
+groups.forEach((val, key) => {
+ minSize = Math.min(minSize, val.length);
+});
+
+const numCols = collection.pivotNumColumns || Math.ceil(Math.sqrt(minSize));
+
+const docMap = new Map;
+const groupNames = [];
+
+let x = 0;
+groups.forEach((val, key) => {
+ let y = 0;
+ let xCount = 0;
+ groupNames.push({type:"text", text:String(key), x, y:width + 50, width: width * 1.25 * numCols, height:100, fontSize:collection.pivotFontSize});
+ for (const doc of val) {
+ docMap.set(doc, {x: x + xCount * width * 1.25, y:-y, width, height:width});
+ xCount++;
+ if (xCount >= numCols) {
+ xCount = 0;
+ y += width * 1.25;
+ }
+ }
+ x += width * 1.25 * (numCols + 1);
+});
+
+return {state:{ map: docMap}, views:groupNames }; \ No newline at end of file
diff --git a/src/scraping/buxton/scripts/layout.txt b/src/scraping/buxton/scripts/layout.txt
new file mode 100644
index 000000000..46b6dbaac
--- /dev/null
+++ b/src/scraping/buxton/scripts/layout.txt
@@ -0,0 +1 @@
+return state.map.get(doc) \ No newline at end of file
diff --git a/src/server/index.ts b/src/server/index.ts
index 1e811c1b2..d735a6d8c 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -148,24 +148,33 @@ app.get("/pull", (req, res) =>
res.redirect("/");
}));
-app.get("/buxton/:clear", (req, res) => {
- if (req.params.clear === "true") {
- deleteFields().then(() => upload_buxton_docs(res));
- } else {
- upload_buxton_docs(res);
- }
-});
-
-let upload_buxton_docs = (res: Response) => {
+app.get("/buxton", (req, res) => {
let buxton_scraping = path.join(__dirname, '../scraping/buxton');
exec('python scraper.py', { cwd: buxton_scraping }, (err, stdout, sterr) => {
if (err) {
res.send(err.message);
return;
}
+ console.log(stdout);
res.redirect("/");
});
-};
+});
+
+app.get('/layoutscripts', (req, res) => {
+ let scripts: string[] = [];
+ let handler = (err: NodeJS.ErrnoException | null, data: Buffer) => {
+ if (err) {
+ console.log(err.message);
+ return;
+ }
+ scripts.push(data.toString());
+ if (scripts.length === 2) {
+ res.send(JSON.stringify(scripts));
+ }
+ };
+ fs.readFile(path.join(__dirname, '../scraping/buxton/scripts/initialization.txt'), handler);
+ fs.readFile(path.join(__dirname, '../scraping/buxton/scripts/layout.txt'), handler);
+});
app.get("/version", (req, res) => {
exec('"C:\\Program Files\\Git\\bin\\git.exe" rev-parse HEAD', (err, stdout, stderr) => {
diff --git a/src/server/remapUrl.ts b/src/server/remapUrl.ts
index 69c766d56..5218a239a 100644
--- a/src/server/remapUrl.ts
+++ b/src/server/remapUrl.ts
@@ -2,6 +2,8 @@ import { Database } from "./database";
import { Search } from "./Search";
import * as path from 'path';
+//npx ts-node src/server/remapUrl.ts
+
const suffixMap: { [type: string]: true } = {
"video": true,
"pdf": true,