Browse Source

Basic strategy execution

master
Denis Tereshkin 8 years ago
parent
commit
6268a57579
  1. 2
      .gitignore
  2. 13
      src/nailab/data/csvfolderdatasource.py
  3. 6
      src/nailab/data/datasourcemanager.py
  4. 0
      src/nailab/execution/__init__.py
  5. 23
      src/nailab/execution/executor.py
  6. 46
      src/nailab/ui/applicationwindow.py
  7. 74
      src/nailab/ui/tabmanager.py
  8. 64
      ui/nailab.glade

2
.gitignore vendored

@ -4,4 +4,4 @@ dist/*
build/* build/*
*.pyc *.pyc
src/*.egg-info/* src/*.egg-info/*
*~

13
src/nailab/data/csvfolderdatasource.py

@ -1,6 +1,8 @@
from nailab.data.datasource import DataSource from nailab.data.datasource import DataSource
from naiback.data.feeds.genericcsvfeed import GenericCSVFeed
import glob import glob
import os import os
@ -14,12 +16,17 @@ class CsvFolderDataSource(DataSource):
self._discover_feeds() self._discover_feeds()
def available_feeds(self): def available_feeds(self):
return self.feeds return [f[1] for f in self.feeds]
def get_feed(self, feed_id): def get_feed(self, feed_id):
pass for path, f_id in self.feeds:
if f_id == feed_id:
with open(path, 'r') as f:
return GenericCSVFeed(f)
raise NailabError('Unable to obtain feed: {}'.format(feed_id))
def _discover_feeds(self): def _discover_feeds(self):
files = glob.glob(self.path + '/*.csv') files = glob.glob(self.path + '/*.csv')
self.feeds = [os.path.basename(f) for f in files] self.feeds = [(f, os.path.basename(f)) for f in files]

6
src/nailab/data/datasourcemanager.py

@ -15,6 +15,12 @@ class DataSourceManager:
def add_source(self, source): def add_source(self, source):
self.sources.append(source) self.sources.append(source)
def get_source(self, name):
for source in self.sources:
if source.name == name:
return source
return None
def all_sources(self): def all_sources(self):
return self.sources[:] return self.sources[:]

0
src/nailab/execution/__init__.py

23
src/nailab/execution/executor.py

@ -0,0 +1,23 @@
from importlib.machinery import SourceFileLoader
import inspect
from naiback.strategy import Strategy
class Executor:
def __init__(self):
pass
def execute_from_file(self, path, feeds):
loader = SourceFileLoader('execution._current_strategy', path)
mod = loader.load_module()
for item in inspect.getmembers(mod, inspect.isclass):
klass = item[1]
if klass is not Strategy and issubclass(klass, Strategy):
strategy = klass()
for feed in feeds:
strategy.add_feed(feed)
strategy.run()

46
src/nailab/ui/applicationwindow.py

@ -1,20 +1,24 @@
from gi.repository import Gtk, GtkSource from gi.repository import Gtk, GtkSource
from nailab.data.datasource import DataSource
from nailab.data.datasourcemanager import DataSourceManager from nailab.data.datasourcemanager import DataSourceManager
from .sourceviewcontroller import SourceViewController from nailab.execution.executor import Executor
from .tabmanager import TabManager
class ApplicationWindow: class ApplicationWindow:
def __init__(self, builder): def __init__(self, builder):
self.window = builder.get_object('ApplicationWindow') self.window = builder.get_object('ApplicationWindow')
self._init_sourceeditor(builder) self.tab_manager = TabManager(builder.get_object('sourceNotebook'))
self._init_tv_datasource(builder) self._init_tv_datasource(builder)
handlers = { handlers = {
'on_ApplicationWindow_delete_event' : Gtk.main_quit, 'on_ApplicationWindow_delete_event' : Gtk.main_quit,
'on_OpenFile' : self.open_file 'on_OpenFile' : self.open_file,
'on_StrategyExecute' : self.strategy_execute
} }
builder.connect_signals(handlers) builder.connect_signals(handlers)
@ -27,34 +31,37 @@ class ApplicationWindow:
result = dlg.run() result = dlg.run()
if result == Gtk.ResponseType.OK: if result == Gtk.ResponseType.OK:
with open(dlg.get_filename(), 'r') as f: self.tab_manager.new_tab(dlg.get_filename())
self.sourceviewcontroller.set_source_text(f.read())
dlg.destroy() dlg.destroy()
def strategy_execute(self, arg):
sel = self.tv_datasources.get_selection()
model, rows = sel.get_selected_rows()
def _init_sourceeditor(self, builder): feeds = []
manager = GtkSource.LanguageManager() for row in rows:
buf = GtkSource.Buffer() (feed_id, source_name) = self.datasources_store.get(self.datasources_store.get_iter(row), 0, 1)
buf.set_language(manager.get_language('python')) source = self.datasourcemanager.get_source(source_name)
sv = builder.get_object('sourceview') if source is not None:
sv.set_buffer(buf) feed = source.get_feed(feed_id)
sv.set_monospace(True) feeds.append(feed)
self.sourceviewcontroller = SourceViewController(sv) e = Executor()
e.execute_from_file(self.tab_manager.get_current_source_path(), feeds)
def _init_tv_datasource(self, builder): def _init_tv_datasource(self, builder):
self.datasourcemanager = DataSourceManager() self.datasourcemanager = DataSourceManager()
self.datasourcemanager.load_sources() self.datasourcemanager.load_sources()
tv_datasources = builder.get_object('tv_datasources') tv_datasources = builder.get_object('tv_datasources')
self.tv_datasources = tv_datasources
self.datasources_store = Gtk.TreeStore(str) self.datasources_store = Gtk.TreeStore(str, str)
for source in self.datasourcemanager.all_sources(): for source in self.datasourcemanager.all_sources():
treeiter = self.datasources_store.append(None, (source.name,)) treeiter = self.datasources_store.append(None, (source.name, source.name))
for feed in source.available_feeds(): for feed in source.available_feeds():
self.datasources_store.append(treeiter, (feed,)) self.datasources_store.append(treeiter, (feed, source.name))
rendererText = Gtk.CellRendererText() rendererText = Gtk.CellRendererText()
@ -63,3 +70,8 @@ class ApplicationWindow:
tv_datasources.set_model(self.datasources_store) tv_datasources.set_model(self.datasources_store)
sel = tv_datasources.get_selection()
sel.set_mode(Gtk.SelectionMode.MULTIPLE)

74
src/nailab/ui/tabmanager.py

@ -0,0 +1,74 @@
from gi.repository import GObject, Gtk, GtkSource, Pango
from .sourceviewcontroller import SourceViewController
class TabManager(GObject.Object):
def __init__(self, notebook):
super().__init__()
self.notebook = notebook
self.widgets = {}
def new_tab(self, source_file):
with open(source_file, 'r') as f:
(sv, sv_controller) = self._init_sourceeditor()
sv_controller.set_source_text(f.read())
self.widgets[source_file] = sv
sv.show_all()
header = Gtk.HBox()
title_label = Gtk.Label(source_file)
image = Gtk.Image()
image.set_from_stock(Gtk.STOCK_CLOSE, Gtk.IconSize.MENU)
close_button = Gtk.Button()
close_button.set_image(image)
close_button.set_relief(Gtk.ReliefStyle.NONE)
close_button.connect('clicked', self.close_cb, source_file)
header.pack_start(title_label,
expand=True, fill=True, padding=0)
header.pack_end(close_button,
expand=False, fill=False, padding=0)
header.show_all()
index = self.notebook.append_page(sv, header)
self.notebook.set_current_page(index)
def close_cb(self, arg, source_file):
index = self._widget_num_by_source_file(source_file)
self.notebook.remove_page(index)
del self.widgets[source_file]
def get_current_source_path(self):
index = self.notebook.get_current_page()
w = self.notebook.get_nth_page(index)
for k, v in self.widgets.items():
if v == w:
return k
raise KeyError('Invalid widget')
def _init_sourceeditor(self):
scroll = Gtk.ScrolledWindow()
manager = GtkSource.LanguageManager()
buf = GtkSource.Buffer()
buf.set_language(manager.get_language('python'))
sv = GtkSource.View()
sv.set_buffer(buf)
sv.set_monospace(True)
style_ctx = sv.get_style_context()
self.provider = Gtk.CssProvider()
self.provider.load_from_data(b'GtkSourceView { font-family: "Monospace"; }')
style_ctx.add_provider(self.provider, Gtk.STYLE_PROVIDER_PRIORITY_USER)
sourceviewcontroller = SourceViewController(sv)
scroll.add(sv)
scroll.show()
return (scroll, sourceviewcontroller)
def _widget_num_by_source_file(self, source_file):
for i in range(0, self.notebook.get_n_pages()):
if self.widgets[source_file] == self.notebook.get_nth_page(i):
return i
return None

64
ui/nailab.glade

@ -2,7 +2,11 @@
<!-- Generated with glade 3.18.3 --> <!-- Generated with glade 3.18.3 -->
<interface> <interface>
<requires lib="gtk+" version="3.0"/> <requires lib="gtk+" version="3.0"/>
<requires lib="gtksourceview" version="3.0"/> <object class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-missing-image</property>
</object>
<object class="GtkListStore" id="model_dataSources"/> <object class="GtkListStore" id="model_dataSources"/>
<object class="GtkApplicationWindow" id="ApplicationWindow"> <object class="GtkApplicationWindow" id="ApplicationWindow">
<property name="width_request">1024</property> <property name="width_request">1024</property>
@ -34,6 +38,7 @@
<property name="hscroll_policy">natural</property> <property name="hscroll_policy">natural</property>
<property name="vscroll_policy">natural</property> <property name="vscroll_policy">natural</property>
<property name="model">model_dataSources</property> <property name="model">model_dataSources</property>
<property name="rubber_banding">True</property>
<property name="enable_grid_lines">both</property> <property name="enable_grid_lines">both</property>
<child internal-child="selection"> <child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection1"/> <object class="GtkTreeSelection" id="treeview-selection1"/>
@ -47,24 +52,26 @@
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkScrolledWindow" id="scrolledwindow2"> <object class="GtkNotebook" id="sourceNotebook">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="shadow_type">in</property>
<child> <child>
<object class="GtkSourceView" id="sourceview"> <placeholder/>
<property name="visible">True</property> </child>
<property name="can_focus">True</property> <child type="tab">
<property name="wrap_mode">word-char</property> <placeholder/>
<property name="monospace">True</property> </child>
<property name="show_line_numbers">True</property> <child>
<property name="show_line_marks">True</property> <placeholder/>
<property name="tab_width">4</property> </child>
<property name="auto_indent">True</property> <child type="tab">
<property name="insert_spaces_instead_of_tabs">True</property> <placeholder/>
<property name="highlight_current_line">True</property> </child>
<property name="smart_backspace">True</property> <child>
</object> <placeholder/>
</child>
<child type="tab">
<placeholder/>
</child> </child>
</object> </object>
<packing> <packing>
@ -202,6 +209,31 @@
<property name="use_underline">True</property> <property name="use_underline">True</property>
</object> </object>
</child> </child>
<child>
<object class="GtkMenuItem" id="menuitem1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Strategy</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu" id="menu1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkImageMenuItem" id="menuExecute">
<property name="label" translatable="yes">Execute
</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="image">image1</property>
<property name="use_stock">False</property>
<signal name="activate" handler="on_StrategyExecute" swapped="no"/>
</object>
</child>
</object>
</child>
</object>
</child>
</object> </object>
</child> </child>
</object> </object>

Loading…
Cancel
Save