aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbackend/server.py16
-rw-r--r--src/App.vue24
2 files changed, 31 insertions, 9 deletions
diff --git a/backend/server.py b/backend/server.py
index 4a364c3..095acff 100755
--- a/backend/server.py
+++ b/backend/server.py
@@ -15,7 +15,8 @@ SEARCH_SUGG_LIMIT = 5
usageInfo = f"usage: {sys.argv[0]}\n"
usageInfo += "Starts a server that listens for GET requests to http://" + hostname + ":" + str(port) + ".\n"
usageInfo += "Responds to path+query /data/type1?name=name1 with JSON data.\n"
-usageInfo += "An additional query parameter tree=reduced is usable to get reduced-tree data\n"
+usageInfo += "The parameter 'name' can be omitted in order to specify the root node.\n"
+usageInfo += "An additional query parameter tree=reduced is usable to get reduced-tree data.\n"
usageInfo += "\n"
usageInfo += "If type1 is 'node': Responds with map from names to TolNode objects for node name1 and it's children.\n"
usageInfo += "If type1 is 'chain': Like 'node', but gets nodes from name1 up to the root, and their direct children.\n"
@@ -72,8 +73,14 @@ class InfoResponse:
# Connect to db
dbCon = sqlite3.connect(dbFile)
+# Get root node
+dbCur = dbCon.cursor()
+query = "SELECT name FROM nodes LEFT JOIN edges ON nodes.name = edges.child WHERE edges.parent IS NULL LIMIT 1"
+(rootName,) = dbCur.execute(query).fetchone()
+
# Some functions
def lookupNodes(names, useReducedTree):
+ global dbCon
# Get node info
nameToNodes = {}
cur = dbCon.cursor()
@@ -127,6 +134,7 @@ def lookupNodes(names, useReducedTree):
#
return nameToNodes
def lookupName(name, useReducedTree):
+ global dbCon
cur = dbCon.cursor()
results = []
hasMore = False
@@ -171,6 +179,7 @@ def lookupName(name, useReducedTree):
hasMore = True
return SearchSuggResponse(results, hasMore)
def lookupNodeInfo(name, useReducedTree):
+ global dbCon
cur = dbCon.cursor()
# Get node-object info
nameToNodes = lookupNodes([name], useReducedTree)
@@ -221,16 +230,17 @@ def lookupNodeInfo(name, useReducedTree):
class DbServer(BaseHTTPRequestHandler):
def do_GET(self):
+ global rootName
# Parse URL
urlParts = urllib.parse.urlparse(self.path)
path = urllib.parse.unquote(urlParts.path)
queryDict = urllib.parse.parse_qs(urlParts.query)
# Check first element of path
match = re.match(r"/([^/]+)/(.+)", path)
- if match != None and match.group(1) == "data" and "name" in queryDict and \
+ if match != None and match.group(1) == "data" and \
("tree" not in queryDict or queryDict["tree"][0] == "reduced"):
reqType = match.group(2)
- name = queryDict["name"][0]
+ name = queryDict["name"][0] if "name" in queryDict else rootName
useReducedTree = "tree" in queryDict
# Check query string
if reqType == "node":
diff --git a/src/App.vue b/src/App.vue
index d0d9a86..3309879 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -42,9 +42,8 @@ function getReverseAction(action: AutoAction): AutoAction | null {
}
// Initialise tree-of-life data
-const ROOT_NAME = "cellular organisms";
const initialTolMap: TolMap = new Map();
-initialTolMap.set(ROOT_NAME, new TolNode());
+initialTolMap.set("", new TolNode());
// Configurable options
const defaultLytOpts: LayoutOptions = {
@@ -99,7 +98,7 @@ const defaultUiOpts = {
export default defineComponent({
data(){
- let layoutTree = initLayoutTree(initialTolMap, ROOT_NAME, 0);
+ let layoutTree = initLayoutTree(initialTolMap, "", 0);
layoutTree.hidden = true;
return {
tolMap: initialTolMap,
@@ -670,14 +669,27 @@ export default defineComponent({
},
// Helper methods
initTreeFromServer(){
- let urlPath = '/data/node?name=' + encodeURIComponent(ROOT_NAME);
+ let urlPath = '/data/node';
urlPath += this.uiOpts.useReducedTree ? '&tree=reduced' : '';
fetch(urlPath)
.then(response => response.json())
.then(obj => {
+ // Get root node name
+ let rootName = null;
+ let nodeNames = Object.getOwnPropertyNames(obj);
+ for (let n of nodeNames){
+ if (obj[n].parent == null){
+ rootName = n;
+ break;
+ }
+ }
+ if (rootName == null){
+ throw new Error('Server response has no root node');
+ }
+ // Initialise tree
this.tolMap.clear();
- Object.getOwnPropertyNames(obj).forEach(key => {this.tolMap.set(key, obj[key])});
- this.layoutTree = initLayoutTree(this.tolMap, this.layoutTree.name, 0);
+ nodeNames.forEach(n => {this.tolMap.set(n, obj[n])});
+ this.layoutTree = initLayoutTree(this.tolMap, rootName, 0);
this.activeRoot = this.layoutTree;
this.layoutMap = initLayoutMap(this.layoutTree);
this.updateAreaDims().then(() => {