@sjcrh/proteinpaint-server 2.163.1 → 2.164.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -3
- package/routes/aiProjectAdmin.js +6 -7
- package/routes/aiProjectSelectedWSImages.js +31 -2
- package/routes/termdb.chat.js +17 -1
- package/src/app.js +243 -205
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sjcrh/proteinpaint-server",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.164.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "a genomics visualization tool for exploring a cohort's genotype and phenotype data",
|
|
6
6
|
"main": "src/app.js",
|
|
@@ -62,11 +62,11 @@
|
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
64
|
"@sjcrh/augen": "2.143.0",
|
|
65
|
-
"@sjcrh/proteinpaint-python": "2.
|
|
65
|
+
"@sjcrh/proteinpaint-python": "2.164.1",
|
|
66
66
|
"@sjcrh/proteinpaint-r": "2.152.1-0",
|
|
67
67
|
"@sjcrh/proteinpaint-rust": "2.157.0",
|
|
68
68
|
"@sjcrh/proteinpaint-shared": "2.163.1",
|
|
69
|
-
"@sjcrh/proteinpaint-types": "2.
|
|
69
|
+
"@sjcrh/proteinpaint-types": "2.164.1",
|
|
70
70
|
"@types/express": "^5.0.0",
|
|
71
71
|
"@types/express-session": "^1.18.1",
|
|
72
72
|
"better-sqlite3": "^12.4.1",
|
package/routes/aiProjectAdmin.js
CHANGED
|
@@ -154,17 +154,16 @@ function deleteProject(connection, projectId) {
|
|
|
154
154
|
runMultiStmtSQL(connection, stmts, "delete");
|
|
155
155
|
}
|
|
156
156
|
function addProject(connection, project) {
|
|
157
|
-
if (!project.users || !Array.isArray(project.users) || project.users.length === 0) {
|
|
158
|
-
throw new Error("project.users must be a non-empty array of emails");
|
|
159
|
-
}
|
|
160
157
|
const projectSql = `INSERT INTO project (name, filter)
|
|
161
158
|
VALUES (?, ?)`;
|
|
162
159
|
const projectParams = [project.name, JSON.stringify(project.filter)];
|
|
163
160
|
const row = runSQL(connection, projectSql, projectParams, "add");
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
161
|
+
if (project.users) {
|
|
162
|
+
const userSql = `INSERT INTO project_users (project_id, email)
|
|
163
|
+
VALUES (?, ?)`;
|
|
164
|
+
const userParams = project.users.map((email) => [row.lastInsertRowid, email]);
|
|
165
|
+
runMultiStmtSQL(connection, [{ sql: userSql, params: userParams }], "add");
|
|
166
|
+
}
|
|
168
167
|
const classSql = `INSERT INTO project_classes (project_id, label, color, key_shortcut)
|
|
169
168
|
VALUES (?, ?, ?, ?)`;
|
|
170
169
|
const classParams = project.classes.map((c) => [row.lastInsertRowid, c.label, c.color, c.key_shortcut || ""]);
|
|
@@ -22,8 +22,20 @@ function init({ genomes }) {
|
|
|
22
22
|
const ds = g.datasets[query.dslabel];
|
|
23
23
|
if (!ds) throw "invalid dataset name";
|
|
24
24
|
const projectId = query.projectId;
|
|
25
|
-
const
|
|
25
|
+
const wsimagesFilenamesArg = query.wsimagesFilenames;
|
|
26
|
+
let wsimagesFilenames = [];
|
|
26
27
|
const wsimages = [];
|
|
28
|
+
if (Array.isArray(wsimagesFilenamesArg) && wsimagesFilenamesArg.length === 1 && wsimagesFilenamesArg[0] === "all") {
|
|
29
|
+
if (ds.queries?.WSImages?.getAllWSImages) {
|
|
30
|
+
try {
|
|
31
|
+
wsimagesFilenames = await ds.queries.WSImages.getAllWSImages(projectId);
|
|
32
|
+
} catch (e) {
|
|
33
|
+
console.error("Failed to get WSI image list via helper, falling back to provided param", e);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
} else {
|
|
37
|
+
wsimagesFilenames = wsimagesFilenamesArg;
|
|
38
|
+
}
|
|
27
39
|
if (ds.queries.WSImages.getWSIAnnotations) {
|
|
28
40
|
for (const wsimageFilename of wsimagesFilenames) {
|
|
29
41
|
const wsimage = {
|
|
@@ -84,6 +96,12 @@ function validateWSIAnnotationsQuery(ds, connection) {
|
|
|
84
96
|
AND pa.status = 1
|
|
85
97
|
ORDER BY pa.timestamp DESC, pa.id DESC
|
|
86
98
|
`;
|
|
99
|
+
const GET_PROJECT_IMAGES_SQL = `
|
|
100
|
+
SELECT DISTINCT pi.image_path AS image_path
|
|
101
|
+
FROM project_images pi
|
|
102
|
+
WHERE pi.project_id = ?
|
|
103
|
+
ORDER BY pi.id
|
|
104
|
+
`;
|
|
87
105
|
if (!ds.queries) ds.queries = {};
|
|
88
106
|
if (!ds.queries.WSImages) ds.queries.WSImages = {};
|
|
89
107
|
ds.queries.WSImages.getWSIAnnotations = async (projectId, filename) => {
|
|
@@ -103,7 +121,8 @@ function validateWSIAnnotationsQuery(ds, connection) {
|
|
|
103
121
|
}
|
|
104
122
|
return {
|
|
105
123
|
zoomCoordinates: coords,
|
|
106
|
-
class: r.label ?? ""
|
|
124
|
+
class: r.label ?? "",
|
|
125
|
+
timestamp: r.timestamp
|
|
107
126
|
};
|
|
108
127
|
});
|
|
109
128
|
} catch (error) {
|
|
@@ -111,6 +130,16 @@ function validateWSIAnnotationsQuery(ds, connection) {
|
|
|
111
130
|
return [];
|
|
112
131
|
}
|
|
113
132
|
};
|
|
133
|
+
ds.queries.WSImages.getAllWSImages = async (projectId) => {
|
|
134
|
+
try {
|
|
135
|
+
const stmt = connection.prepare(GET_PROJECT_IMAGES_SQL);
|
|
136
|
+
const rows = stmt.all(projectId);
|
|
137
|
+
return (rows || []).map((r) => r.image_path);
|
|
138
|
+
} catch (error) {
|
|
139
|
+
console.error("Error loading project images list:", error);
|
|
140
|
+
return [];
|
|
141
|
+
}
|
|
142
|
+
};
|
|
114
143
|
}
|
|
115
144
|
function validateWSIClassesQuery(ds, connection) {
|
|
116
145
|
if (!ds.queries) ds.queries = {};
|
package/routes/termdb.chat.js
CHANGED
|
@@ -2,6 +2,7 @@ import { ChatPayload } from "#types/checkers";
|
|
|
2
2
|
import { run_rust } from "@sjcrh/proteinpaint-rust";
|
|
3
3
|
import serverconfig from "../src/serverconfig.js";
|
|
4
4
|
import { mayLog } from "#src/helpers.ts";
|
|
5
|
+
import { run_python } from "@sjcrh/proteinpaint-python";
|
|
5
6
|
const api = {
|
|
6
7
|
endpoint: "termdb/chat",
|
|
7
8
|
methods: {
|
|
@@ -23,7 +24,22 @@ function init({ genomes }) {
|
|
|
23
24
|
if (!g) throw "invalid genome";
|
|
24
25
|
const ds = g.datasets?.[q.dslabel];
|
|
25
26
|
if (!ds) throw "invalid dslabel";
|
|
26
|
-
|
|
27
|
+
if (serverconfig.features.pythonChatBot) {
|
|
28
|
+
const chatbot_input2 = {
|
|
29
|
+
prompt: q.prompt,
|
|
30
|
+
genome: q.genome,
|
|
31
|
+
dslabel: q.dslabel
|
|
32
|
+
//terms_tsv_path: df
|
|
33
|
+
};
|
|
34
|
+
try {
|
|
35
|
+
const ai_output_data2 = await run_python("chatBot.py", JSON.stringify(chatbot_input2));
|
|
36
|
+
res.send(ai_output_data2);
|
|
37
|
+
} catch (error) {
|
|
38
|
+
const errmsg = "Error running chatBot Python script:" + error;
|
|
39
|
+
throw new Error(errmsg);
|
|
40
|
+
}
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
27
43
|
const serverconfig_ds_entries = serverconfig.genomes.find((genome) => genome.name == q.genome).datasets.find((dslabel) => dslabel.name == ds.label);
|
|
28
44
|
console.log("serverconfig_ds_entries:", serverconfig_ds_entries);
|
|
29
45
|
if (!serverconfig_ds_entries.aifiles) {
|