not stable! begin to realize save/open
This commit is contained in:
parent
8a93d853af
commit
9e29e5f9c8
4
forms.py
4
forms.py
@ -186,7 +186,7 @@ class MainFrame(wx.Frame):
|
||||
menubar.Append(menu, '&Run')
|
||||
|
||||
menu = wx.Menu()
|
||||
menu.Append(ID_SHOW_RESULT, 'Show numbers\tF7')
|
||||
menu.Append(ID_SHOW_RESULT, 'Show report\tF7')
|
||||
menu.AppendSeparator()
|
||||
menu.Append(ID_SHOW_PLOT, 'Show plot\tF8')
|
||||
menu.Append(ID_ADD_PLOT, 'Add plot')
|
||||
@ -228,7 +228,7 @@ class MainFrame(wx.Frame):
|
||||
tb1.SetToolBitmapSize(wx.Size(16, 16))
|
||||
|
||||
tb1.AddSimpleTool(ID_ADD_MODEL_SELECTED, "model-new", wx.Bitmap('share/model-add.png'),
|
||||
'Add spacification to selected model')
|
||||
'Add specification to selected model')
|
||||
tb1.AddSimpleTool(ID_DUPLICATE_MODEL, "model-dup", wx.Bitmap('share/model-dup.png'),
|
||||
'Duplicate selected model')
|
||||
tb1.AddSimpleTool(ID_DUPLICATE_TREE, "model-dup-tree", wx.Bitmap('share/model-dup-tree.png'),
|
||||
|
156
opal.py
156
opal.py
@ -13,14 +13,19 @@
|
||||
|
||||
import server
|
||||
import task
|
||||
|
||||
import wx
|
||||
import wx.propgrid as wxpg
|
||||
import wx.lib.plot as wxplot
|
||||
import forms
|
||||
wxpg = forms.wxpg
|
||||
wxplot = forms.wxplot
|
||||
from wx.lib.embeddedimage import PyEmbeddedImage
|
||||
|
||||
import time
|
||||
import threading
|
||||
import re
|
||||
from wx.lib.embeddedimage import PyEmbeddedImage
|
||||
import json
|
||||
import zlib
|
||||
from pprint import pprint
|
||||
|
||||
class ModelData:
|
||||
def __init__(self, server, model, parent_data = None):
|
||||
@ -38,9 +43,9 @@ class ModelData:
|
||||
|
||||
self.res = None
|
||||
|
||||
LINE_CURVE = 1
|
||||
LINE_MARKER = 2
|
||||
LINE_HISTOGRAM = 3
|
||||
LINE_CURVE = 1
|
||||
LINE_MARKER = 2
|
||||
LINE_HISTOGRAM = 3
|
||||
|
||||
class LineData:
|
||||
"""
|
||||
@ -63,6 +68,10 @@ class LineData:
|
||||
self.colour = colour # цвет: если не задан выбирается из списка
|
||||
self.style = style # стиль: если не задан, еспользуется по умолчанию
|
||||
|
||||
def GetModelTitle(self):
|
||||
container, item = self.ums_ptr
|
||||
return container.GetItemText(item)
|
||||
|
||||
def GetTitle(self):
|
||||
# если есть указатель на компонент с графиками,
|
||||
# извлекаем оттуда название
|
||||
@ -98,6 +107,7 @@ class MainFrame(forms.MainFrame):
|
||||
def __init__(self):
|
||||
forms.MainFrame.__init__(self, None)
|
||||
|
||||
self.model = None
|
||||
self.name_id = 1
|
||||
|
||||
s = server.LocalServer()
|
||||
@ -129,6 +139,10 @@ class MainFrame(forms.MainFrame):
|
||||
|
||||
self.Bind(wx.EVT_MENU, self.OnNewProject,
|
||||
id = forms.ID_NEW)
|
||||
self.Bind(wx.EVT_MENU, self.OnOpenProject,
|
||||
id = forms.ID_OPEN)
|
||||
self.Bind(wx.EVT_MENU, self.OnSaveProject,
|
||||
id = forms.ID_SAVE)
|
||||
|
||||
self.Bind(wx.EVT_MENU, self.OnTest,
|
||||
id = forms.ID_TEST)
|
||||
@ -283,7 +297,7 @@ class MainFrame(forms.MainFrame):
|
||||
"""
|
||||
def DoItem(item, model):
|
||||
sp.SetPyData(item, model)
|
||||
for spec in model.GetSpecs():
|
||||
for label, spec in model.GetSpecs().iteritems():
|
||||
child = sp.AppendItem(item, spec.GetTitle())
|
||||
DoItem(child, spec)
|
||||
|
||||
@ -294,7 +308,7 @@ class MainFrame(forms.MainFrame):
|
||||
sp.ExpandAll()
|
||||
sp.SortChildren(root)
|
||||
|
||||
def NewProject(self, model):
|
||||
def NewProject(self, model, create_default = True):
|
||||
"""
|
||||
Начать новый проект:
|
||||
0. Очичтить все компоненты
|
||||
@ -307,6 +321,8 @@ class MainFrame(forms.MainFrame):
|
||||
self.m_params.Clear()
|
||||
self.m_quick_result.Clear()
|
||||
self.m_plots.DeleteAllItems()
|
||||
# фиксируем выбранную модель
|
||||
self.model = model
|
||||
# Строим спецификации
|
||||
self.BuildSpecs(model)
|
||||
# Очищаем окно пользовательских моделей
|
||||
@ -314,7 +330,8 @@ class MainFrame(forms.MainFrame):
|
||||
um = self.m_user_models
|
||||
um.DeleteAllItems()
|
||||
um.AddRoot('root')
|
||||
self.AddModelToRoot(model)
|
||||
if create_default:
|
||||
self.AddModelToRoot(model)
|
||||
# Создаем корневой элемент для окна с графиками
|
||||
self.m_plots.AddRoot('root')
|
||||
|
||||
@ -329,8 +346,123 @@ class MainFrame(forms.MainFrame):
|
||||
model = f.GetSelectedModel()
|
||||
if model:
|
||||
self.NewProject(model)
|
||||
|
||||
self.do_nothing = False
|
||||
|
||||
def OnOpenProject(self, event):
|
||||
|
||||
def WalkModels(source, root, models, model_def = None):
|
||||
|
||||
for key, value in source.iteritems():
|
||||
label = value['model']
|
||||
if label not in models:
|
||||
raise KeyError, 'no "{}"'.format(label)
|
||||
data = ModelData(self.server, models[label], model_def)
|
||||
data.mdef.params = value['data']
|
||||
if 'result' in value:
|
||||
data.res = task.ResultData(value['result'])
|
||||
# тут надо проверить все добавленные параметры
|
||||
|
||||
item = um.AppendItem(root, key)
|
||||
um.SetPyData(item, data)
|
||||
model_items[key] = item
|
||||
WalkModels(value['um'], item, models[label].GetSpecs(), data)
|
||||
|
||||
try:
|
||||
infile = 'data.opl'
|
||||
data = {}
|
||||
with open(infile, 'rb') as f:
|
||||
data = json.loads(zlib.decompress(f.read()))
|
||||
|
||||
pprint(data)
|
||||
|
||||
tid = data['tid']
|
||||
model_label = data['model']
|
||||
model = self.server.CheckModel(tid, model_label)
|
||||
if not model:
|
||||
raise ValueError
|
||||
|
||||
self.NewProject(model, False)
|
||||
|
||||
um = self.m_user_models
|
||||
model_items = {}
|
||||
root = um.GetRootItem()
|
||||
WalkModels(data['um'], root, {model.GetLabel(): model})
|
||||
|
||||
# except KeyError, e:
|
||||
# wx.MessageBox("Can't parse saved file!", 'Error!')
|
||||
# except ValueError, e:
|
||||
# wx.MessageBox("Can't parse saved file!", 'Error!')
|
||||
except Exception, e:
|
||||
print 'Oops', type(e), e
|
||||
|
||||
|
||||
def OnSaveProject(self, event):
|
||||
|
||||
def WalkModels(item, dest):
|
||||
if item != um.GetRootItem():
|
||||
data = um.GetPyData(item)
|
||||
title = um.GetItemText(item)
|
||||
mdef = data.mdef
|
||||
dest[title] = {
|
||||
'model': mdef.DD.GetLabel(),
|
||||
'data': mdef.params,
|
||||
'um': {}
|
||||
}
|
||||
if data.res:
|
||||
dest[title]['result'] = data.res.DumpData()
|
||||
dest = dest[title]['um']
|
||||
|
||||
child, _ = um.GetFirstChild(item)
|
||||
while child.IsOk():
|
||||
WalkModels(child, dest)
|
||||
child = um.GetNextSibling(child)
|
||||
|
||||
def WalkPlots(root, dest):
|
||||
# по всеи элементам первого уровня
|
||||
item1, _ = self.m_plots.GetFirstChild(root)
|
||||
while item1.IsOk():
|
||||
# по всем элементам второго уровня
|
||||
item2, _ = self.m_plots.GetFirstChild(item1)
|
||||
lines = []
|
||||
while item2.IsOk():
|
||||
line = self.m_plots.GetPyData(item2)
|
||||
data = {
|
||||
'title': self.m_plots.GetItemText(item2),
|
||||
'colx': line.columns[0],
|
||||
'coly': line.columns[1],
|
||||
'model': line.GetModelTitle(),
|
||||
'type': line.type,
|
||||
}
|
||||
lines.append(data)
|
||||
item2 = self.m_plots.GetNextSibling(item2)
|
||||
title = self.m_plots.GetItemText(item1)
|
||||
dest.append([title, lines])
|
||||
item1 = self.m_plots.GetNextSibling(item1)
|
||||
|
||||
|
||||
wx.BeginBusyCursor()
|
||||
|
||||
data = {}
|
||||
|
||||
data['tid'] = self.model.GetTaskId()
|
||||
data['model'] = self.model.GetLabel()
|
||||
|
||||
um = self.m_user_models
|
||||
data['um'] = {}
|
||||
WalkModels(um.GetRootItem(), data['um'])
|
||||
|
||||
data['plots'] = []
|
||||
WalkPlots(self.m_plots.GetRootItem(), data['plots'])
|
||||
|
||||
# pprint(data)
|
||||
dump = json.dumps(data, indent = 2)
|
||||
with open('data.opl', 'wb') as f:
|
||||
f.write(zlib.compress(dump, 9))
|
||||
# f.write(dump)
|
||||
|
||||
wx.EndBusyCursor()
|
||||
|
||||
# Функции непосредственной работы с моделями:
|
||||
# создание, изменение, дублирование и прочее
|
||||
|
||||
@ -502,7 +634,6 @@ class MainFrame(forms.MainFrame):
|
||||
# то все субмодели должны быть пересчитаны
|
||||
Walk(item)
|
||||
|
||||
|
||||
def OnTest(self, event):
|
||||
|
||||
def Walk(item):
|
||||
@ -955,6 +1086,9 @@ class ThisApp(wx.App):
|
||||
# Запуск приложения
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
if __name__ == "__main__":
|
||||
def main():
|
||||
app = ThisApp(redirect = False)
|
||||
app.MainLoop()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
18
server.py
18
server.py
@ -17,6 +17,7 @@ import time
|
||||
import datetime
|
||||
import threading
|
||||
import subprocess
|
||||
import hashlib
|
||||
|
||||
import task
|
||||
|
||||
@ -47,8 +48,6 @@ class LocalServer:
|
||||
self.queue_lock = threading.Lock()
|
||||
|
||||
# init actions
|
||||
|
||||
self.log = open('log.txt', 'w')
|
||||
self.WriteToLog('local server initialized')
|
||||
|
||||
def Close(self):
|
||||
@ -61,7 +60,7 @@ class LocalServer:
|
||||
def WriteToLog(self, msg):
|
||||
tm = str(datetime.datetime.now())
|
||||
msg = tm + ' ' + msg
|
||||
self.log.write(msg + '\n')
|
||||
# self.log.write(msg + '\n')
|
||||
print msg
|
||||
|
||||
def TestTaskData(self, data):
|
||||
@ -86,13 +85,14 @@ class LocalServer:
|
||||
self.TestTaskData(data)
|
||||
|
||||
# вычисляем псевдоуникальный идентификатор модели
|
||||
tid = hash(data['meta'])
|
||||
tid = hashlib.md5(data['meta']).hexdigest()
|
||||
# сохраняем описание задачи
|
||||
self.tasks_meta[tid] = {
|
||||
'title': data.get('title', ''),
|
||||
'author': data.get('author', ''),
|
||||
'meta': data['meta'],
|
||||
'exec': line
|
||||
'exec': line,
|
||||
'models': []
|
||||
}
|
||||
|
||||
# выделяем описания моделей
|
||||
@ -101,6 +101,7 @@ class LocalServer:
|
||||
model_descr = task.DataDescription(None, label, data, tid)
|
||||
# добавляем в список описаний
|
||||
self.models.append(model_descr)
|
||||
self.tasks_meta[tid]['models'].append(model_descr)
|
||||
|
||||
self.WriteToLog('Task from "{}" asked'.format(line))
|
||||
except IOError, e:
|
||||
@ -116,6 +117,13 @@ class LocalServer:
|
||||
def GetTaskMeta(self, tid):
|
||||
return self.tasks_meta.get(tid)
|
||||
|
||||
def CheckModel(self, tid, model_label):
|
||||
models = self.tasks_meta[tid]['models']
|
||||
for model in models:
|
||||
if model_label == model.GetLabel():
|
||||
return model
|
||||
return None
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
|
||||
def CreateJob(self):
|
||||
|
18
setup.py
Normal file
18
setup.py
Normal file
@ -0,0 +1,18 @@
|
||||
from distutils.core import setup
|
||||
import py2exe
|
||||
|
||||
|
||||
excludes = ['_gtkagg', '_tkagg', 'bsddb', 'curses', 'email', 'pywin.debugger',
|
||||
'pywin.debugger.dbgcon', 'pywin.dialogs', 'tcl',
|
||||
'Tkconstants', 'Tkinter']
|
||||
setup(
|
||||
name = 'Opal',
|
||||
windows = ['opal.pyw'],
|
||||
options = { "py2exe": {
|
||||
"compressed": 2,
|
||||
"optimize": 2,
|
||||
"bundle_files": 1,
|
||||
"excludes": excludes,
|
||||
} },
|
||||
zipfile = None,
|
||||
)
|
65
task.py
65
task.py
@ -42,6 +42,17 @@ class Parameter:
|
||||
def Test(self, value):
|
||||
return True
|
||||
|
||||
def DumpData(self):
|
||||
"""
|
||||
Возвращает данные в стандартных контейнерах
|
||||
|
||||
READ ONLY!!!
|
||||
"""
|
||||
return self.data
|
||||
|
||||
def LoadData(self, data):
|
||||
self.data = data
|
||||
|
||||
class Value(Parameter):
|
||||
def __init__(self, label, value):
|
||||
if isinstance(value, dict):
|
||||
@ -70,6 +81,13 @@ class Column(Parameter):
|
||||
except:
|
||||
pass
|
||||
|
||||
def DumpData(self):
|
||||
return [
|
||||
self.GetLabel(),
|
||||
self.GetType(),
|
||||
self.GetTitle(),
|
||||
]
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
class DataDescription:
|
||||
@ -86,10 +104,12 @@ class DataDescription:
|
||||
par = Parameter(label, self.pdata[label])
|
||||
self.pdata[label] = par
|
||||
|
||||
self.specs = []
|
||||
# рекурсивное создание описаний спецификаций
|
||||
for label, data in self.data.get('spec', {}).iteritems():
|
||||
self.specs.append(DataDescription(self, label, data, self.tid))
|
||||
self.specs = { label: DataDescription(self, label, data, self.tid)
|
||||
for label, data in self.data.get('spec', {}).iteritems() }
|
||||
|
||||
# for label, data in self.data.get('spec', {}).iteritems():
|
||||
# self.specs.append(DataDescription(self, label, data, self.tid))
|
||||
|
||||
def GetLabel(self):
|
||||
return self.label
|
||||
@ -115,6 +135,9 @@ class DataDescription:
|
||||
def GetImage(self):
|
||||
return self.data.get('img')
|
||||
|
||||
def GetTaskId(self):
|
||||
return self.tid
|
||||
|
||||
def __getitem__(self, label):
|
||||
return self.pdata.get(label)
|
||||
|
||||
@ -158,16 +181,7 @@ class DataDefinition:
|
||||
|
||||
class ResultData:
|
||||
def __init__(self, data):
|
||||
self.data = {}
|
||||
for key, value in data.get('data', {}).iteritems():
|
||||
self.data[key] = Value(key, value)
|
||||
|
||||
table = data.get('table', [])
|
||||
self.head = {}
|
||||
self.table = []
|
||||
if table:
|
||||
self.head = [ Column(item) for item in table[0] ]
|
||||
self.table = table[1:]
|
||||
self.LoadData(data)
|
||||
|
||||
def GetColumns(self):
|
||||
return self.head
|
||||
@ -187,3 +201,28 @@ class ResultData:
|
||||
|
||||
def Zip(self, col1, col2):
|
||||
return [ (row[col1], row[col2]) for row in self.rows ]
|
||||
|
||||
def DumpData(self):
|
||||
data = {}
|
||||
if self.data:
|
||||
data['data'] = { key: self.data[key].DumpData()
|
||||
for key in self.data }
|
||||
|
||||
if self.head:
|
||||
head = [ col.DumpData() for col in self.columns ]
|
||||
body = self.table
|
||||
data['table'] = [head] + body
|
||||
return data
|
||||
|
||||
def LoadData(self, data):
|
||||
self.data = {}
|
||||
for key, value in data.get('data', {}).iteritems():
|
||||
self.data[key] = Value(key, value)
|
||||
|
||||
table = data.get('table', [])
|
||||
self.head = []
|
||||
self.table = []
|
||||
if table:
|
||||
self.head = [ Column(item) for item in table[0] ]
|
||||
self.table = table[1:]
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
|
||||
"n": {
|
||||
"type": "int",
|
||||
"default": 100,
|
||||
"default": 10,
|
||||
"title": "Steps",
|
||||
"comment": "Number of steps for algorithm"
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ def serie(n, d, h, l = 0):
|
||||
y = sin_taylor(l, d)
|
||||
yield (l, y)
|
||||
l += h
|
||||
time.sleep(0.01)
|
||||
# time.sleep(0.002)
|
||||
|
||||
def main():
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user