-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmake_json_smart.py
More file actions
146 lines (112 loc) · 4.19 KB
/
make_json_smart.py
File metadata and controls
146 lines (112 loc) · 4.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import subprocess
import pymysql
import json
import codecs
import os
def diff(first, second):
second = set(second)
return [item for item in first if item not in second]
def renderTree(fileName, picName):
subprocess.call(["C:\\Program Files (x86)\\Graphviz2.38\\bin\\dot.exe", "-Tplain", fileName, "-o", picName])
def makeFile(tree, fileName):
file = codecs.open(fileName, 'w', 'utf-8')
file.write('digraph G {\n')
for nodeId in tree:
node = tree[nodeId]
name = node['rus_name'] if node['rus_name'] else node['name']
name = str(node['id'])
file.write('N' + str(node['id']) + ' [shape=ellipse]\n')
for nodeId in tree:
node = tree[nodeId]
if int(node['parent_id']) == 0:
continue
file.write('N' + str(node['parent_id']) + ' -> N' + str(node['id']) + ';\n')
file.write("overlap=false\
}")
file.close()
def fillCSV(prefix, tree, nodeId, file):
if tree[nodeId]['name'] == '':
name = 'N' + str(nodeId)
else:
name = tree[nodeId]['name']
file.write(prefix + name + ',\n')
for childId in tree[nodeId]['children']:
fillCSV(prefix + name + '.', tree, childId, file)
def makeCSV(tree, fileName):
file = codecs.open(fileName, 'w', 'utf-8')
file.write('id,value\n')
rootId = findRoot(tree)
fillCSV('', tree, rootId, file)
file.close()
def findRoot(tree):
for nodeId in tree:
if not tree[nodeId]['parent_id']:
return nodeId
return False
def buildTree(species):
newNodes = getNodesByIds(species)
nodes = newNodes
while True:
parentIds = [newNodes[node]['parent_id'] for node in newNodes]
parentIds = diff(list(set(parentIds)), nodes.keys())
if not parentIds:
break
newNodes = getNodesByIds(parentIds)
nodes = {**nodes, **newNodes}
if len(parentIds) == 1 and parentIds[0] == 0:
break
for nodeId in nodes:
if nodes[nodeId]['parent_id']:
nodes[nodes[nodeId]['parent_id']]['children'].append(nodeId)
nodes[nodeId]['best_name'] = nodes[nodeId]['rus_name'] if nodes[nodeId]['rus_name'] else nodes[nodeId]['name']
for nodeId in list(nodes):
if len(nodes[nodeId]['children']) == 1 and nodes[nodeId]['parent_id'] != 0:
nodes[nodes[nodeId]['children'][0]]['parent_id'] = nodes[nodeId]['parent_id']
nodes[nodes[nodeId]['parent_id']]['children'].remove(nodeId)
nodes[nodes[nodeId]['parent_id']]['children'].append(nodes[nodeId]['children'][0])
del nodes[nodeId]
return nodes
def getNodesByIds(ids):
cursor.execute('SELECT * FROM tree WHERE id IN (' + ','.join([str(id) for id in ids]) + ')')
nodes = {}
for row in cursor.fetchall():
nodes[row['id']] = row
nodes[row['id']]['children'] = []
return nodes
def getSpecies(limit):
cursor.execute('SELECT id FROM tree WHERE wiki_image IS NOT NULL and rus_name IS NOT NULL ORDER BY refs DESC LIMIT ' + str(limit))
return [row['id'] for row in cursor.fetchall()]
connection = pymysql.connect(host='localhost', user='root', password='', db='tree', charset='utf8mb4', cursorclass=pymysql.cursors.DictCursor)
cursor = connection.cursor()
species = getSpecies(500)
tree = buildTree(species)
makeFile(tree, 'tree.gv')
renderTree('tree.gv', 'computed.txt')
os.remove('tree.gv')
file = open('computed.txt', 'r')
lines = file.read().strip().split('\n')
file.close()
os.remove('computed.txt')
firstLine = lines[0].split(' ')
width = float(firstLine[2])
height = float(firstLine[3])
for line in lines:
parts = line.split(' ')
if parts[0] == 'node':
nodeId = int(parts[1][1:])
tree[nodeId]['x'] = float(parts[2]) / width
tree[nodeId]['y'] = float(parts[3]) / height
data = {};
for nodeId in tree:
node = tree[nodeId]
data[nodeId] = {}
data[nodeId]['id'] = nodeId
data[nodeId]['x'] = node['x'] * 2 - 0.5
data[nodeId]['y'] = node['y']
data[nodeId]['name'] = node['name']
data[nodeId]['children'] = node['children']
data[nodeId]['parent'] = node['parent_id']
file = open('tree.js', 'w')
file.write('const TREE_DATA = ' + json.dumps(data))
file.close()
connection.close()