Commit bf4a89f2 authored by Franziska Koehn's avatar Franziska Koehn
Browse files

xsagtk deleted

parent 810320d2
Flask==0.10.1
itsdangerous==0.24
Jinja2==2.7.3
MarkupSafe==0.23
matplotlib==1.4.3
nose==1.3.7
numpy==1.9.2
pyparsing==2.0.3
python-dateutil==2.4.2
pytz==2015.4
requests==2.7.0
six==1.9.0
Werkzeug==0.10.4
......@@ -6,12 +6,8 @@ if __name__ == "__main__":
parser = ArgumentParser(description='search and download gui')
parser.add_argument('--host', type=str, help='hostname or ip-address (including port).', default="http://localhost:8080")
parser.add_argument('--user', type=str, help='user:passw', default=":")
parser.add_argument('--gui', '-g', type=str, default='gtk', choices=['gtk', 'web'], help="Choose which GUI you would like to launch. Default is GTK")
args = parser.parse_args()
if args.gui == "gtk":
from xsagtk.xsa_app_main import start_xsa_gui
start_xsa_gui(args)
elif args.gui == "web":
from xsaweb.main import start_web_gui
start_web_gui(args)
from xsaweb.main import start_web_gui
start_web_gui(args)
"""
:Author: Franziska Koehn
:Created: 2015/01/13
This module houses classes relating to the GUI-representation of the chart.
"""
from gi.repository import Gtk
from gi.repository import GObject
class ChartView(Gtk.HPaned):
"""Container with all widgets for working with the chart."""
results = []
bar_chart = None
canvas = None
def __init__(self):
"""Creates chart-area."""
super(ChartView, self).__init__()
self.set_position(250)
v_box = Gtk.VBox()
self.add1(v_box)
hBox_type = Gtk.HBox()
v_box.pack_start(hBox_type, False, True, 0)
label_type = Gtk.Label()
label_type.set_text("Type: ")
hBox_type.pack_start(label_type, False, True, 0)
self.combobox = Gtk.ComboBox.new_with_model_and_entry(Gtk.ListStore(str, str))
self.combobox.set_entry_text_column(0)
hBox_type.pack_start(self.combobox, True, True, 0)
sw_hist_values = Gtk.ScrolledWindow()
v_box.pack_start(sw_hist_values, True, True, 0)
self.TreeViewChartValues = TreeViewChartValues()
sw_hist_values.add(self.TreeViewChartValues)
changed_cb = lambda *_: self.update_chart()
self.combobox.connect('changed', changed_cb)
self.TreeViewChartValues.connect("values-changed", changed_cb)
self.update_chart()
from matplotlib.backends.backend_gtk3cairo import FigureCanvasGTK3Cairo as FigureCanvas
self.canvas = FigureCanvas(self.bar_chart)
self.add2(self.canvas)
def update_chart(self):
"""Creates the chart from all values from TreeViewChartValues"""
import xsa.chart as chart
substrings = []
strings = []
it = self.combobox.get_active_iter()
if it is not None:
field = self.combobox.get_model()[it][1]
for r in self.results:
strings.append(r[field])
for sub in self.TreeViewChartValues.store:
if not sub[0] == self.TreeViewChartValues.inital_value:
substrings.append(sub[0])
data = chart.count_substrings(substrings, strings)
self.bar_chart = chart.create(data,len(self.results), len(self.TreeViewChartValues.store)-1, self.bar_chart)
if self.canvas is not None:
self.canvas.draw()
def update(self, data, root_type):
"""
Updates chart and combobox of types for given Root-Type and results.
**Parameters**
:data: JsonTable, results of search
:root_type: str, Root-Type of search
"""
self.results = data
import xsa.datatypereader as type_reader
store = Gtk.ListStore(str, str)
if data != []:
for key in data.headers():
label = type_reader.get_field_label_by_key(root_type, key)
store.append([label, key])
self.combobox.set_model(store)
self.combobox.set_active(0)
self.update_chart()
class TreeViewChartValues(Gtk.TreeView, GObject.GObject):
"""TreeView for creating the Search-Strings, shown in the chart."""
inital_value = "..."
"""Start-string for new inserted row."""
tooltip = 'Delete by using right click'
"""Tooltip that will be shown for each row and each column"""
__gsignals__= {'values-changed': (GObject.SIGNAL_RUN_FIRST, None,())}
def __init__(self):
"""Creats the model and column."""
super(TreeViewChartValues, self).__init__()
self.create_model()
self.create_column()
def on_treeview_button_press_event(treeview, event):
if event.button == 3:
x = int(event.x)
y = int(event.y)
path_info = treeview.get_path_at_pos(x, y)
if path_info is not None:
path, col, cellx, celly = path_info
iter = self.store.get_iter(path)
if self.store.get_value(iter,0) != self.inital_value:
self.store.remove(iter)
self.emit("values-changed")
self.connect('button_press_event', on_treeview_button_press_event)
self.set_tooltip_column(1)
def create_column(self):
"""Creates column and its edited-callback."""
def cell_edited_callback(cellrenderertext, path_string, new_text, *_):
it = self.store.get_iter_from_string(path_string)
it_last = self.store.get_iter(len(self.store)-1)
self.store.set(it, 0, new_text)
if not (it_last is None) and (self.store.get_value(it_last, 0) != self.inital_value):
self.store.append([self.inital_value, self.tooltip])
self.emit("values-changed")
rendererText = Gtk.CellRendererText()
rendererText.set_property('editable', True)
rendererText.connect('edited', cell_edited_callback, 2)
column = Gtk.TreeViewColumn("Chart Values (Type Substrings)", rendererText, text=0)
column.set_sort_column_id(0)
self.append_column(column)
def create_model(self):
"""creates store and set it as model."""
self.store = Gtk.ListStore(str, str) # Search-String, tooltip
self.store.append([self.inital_value, self.tooltip])
self.set_model(self.store)
"""
:Author: Franziska Koehn
:Created: 2015/01/13
This module contains the controller that provides the communication between views.
"""
from gi.repository import Gtk
from gi.repository import GObject
import xsa.datatypereader
from xsagtk.message_dialogs import create_error_message
class QueryController(GObject.GObject):
"""Provides communication between different views."""
root_key = 'root'
query_key = 'query'
labels_key = 'labels'
results = []
_host = ""
_user = ""
_passw = ""
_root = ""
_query = []
_labels = []
@property
def root(self):
"""Root-Type of search"""
return self._root
@root.setter
def root(self, new_root):
self._root = new_root
@property
def labels(self):
"""Fields of search (label of fields)"""
return self._labels
@labels.setter
def labels(self, new_labels):
self._labels = new_labels
@property
def query(self):
"""List including constraints of query."""
return self._query
@query.setter
def query(self, new_query):
self._query = new_query
@property
def host(self):
"""Host-address"""
return self._host
@host.setter
def host(self, new_host):
self._host = new_host
@property
def credentials_tuple(self):
"""Credentials as tuple (user-name, password)"""
return (self._user, self._passw)
@credentials_tuple.setter
def credentials_tuple(self, creds):
self._user, self._passw = creds
@property
def credentials(self):
"""Credentials as http-auth-string (user-name:password)"""
return "%s:%s" % self.credentials_tuple
@credentials.setter
def credentials(self, new_creds):
self._user, _, self._passw = new_creds.partition(":")
def __init__(self, main, queryview, menuview, chartview, resultsview, statusbar):
"""
Connects signals to views and contains definitions for callbacks of toolbar-buttons.
**Parameters**
:main: Gtk.Window, main-window
:queryview: a Gtk.Container, View for creating queries
:menuview: a Gtk.Container, View for Menu/Toolbar
:chartview: a Gtk.Container, View including all widgets for the chart
:resultsview: a Gtk.Container, View for showing the results of the search
:statusbar: a Gtk.Container, Statusbar
"""
super(QueryController, self).__init__()
self.main = main
self.queryview = queryview
self.menuview = menuview
self.chartview = chartview
self.resultsview = resultsview
self.statusbar = statusbar
def callback_get_additional_data(*_):
self.get_additional_data()
def callback_export_csv(*_):
self.export_csv()
def callback_edit_Server_Settings(*_):
print(_)
self.edit_server_settings()
def callback_toggle_selection(*_):
self.resultsview.toggle_selection()
def callback_download(*_):
self.download_files()
def callback_save_query(*_):
self.update_data()
self.save_query()
def callback_load_query(*_):
self.load_query()
def callback_send_query(*_):
self.update_data()
self.send_query()
self.menuview.connect("spawn-connection-dialog", callback_edit_Server_Settings)
self.menuview.connect("send-query", callback_send_query)
self.menuview.connect("toggle-selection", callback_toggle_selection)
self.menuview.connect("download-selection", callback_download)
self.menuview.connect("save-query", callback_save_query)
self.menuview.connect("load-query", callback_load_query)
self.menuview.connect("get-additional-data",callback_get_additional_data)
self.menuview.connect("export-csv", callback_export_csv)
def update_data(self):
"""updates root, query and labels"""
self.root = self.queryview.get_root_type()
self.query = self.queryview.get_query()
self.labels = self.queryview.get_fields()
#TODO host/username/password
def get_additional_data(self):
"""queries for additional data for all items in the result-table"""
rest = xsa.datatypereader.get_comparison_extra_source(self.root)
new_data_sets = []
for r in self.results:
new_data_sets.append(xsa.queries.query_for_additional_data(rest, r, self.host, self.credentials_tuple))
keys = []
for data_set in new_data_sets:
for key in data_set.keys():
keys.append(key)
new_result = []
for data_set in new_data_sets:
dic = {}
for key in keys:
try:
dic[key] = data_set[key]
except:
dic[key] = "N/A"
new_result.append(dic)
from xsa.jsonutil import JsonTable
self.results = JsonTable(new_result)
self.resultsview.show_data(self.results, self.root)
self.chartview.update(self.results, self.root)
def export_csv(self):
"""Exports Result-Table as CSV to chosen destination."""
dialog = Gtk.FileChooserDialog( "Save as...",
None,
Gtk.FileChooserAction.SAVE,
(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
dialog.set_default_response(Gtk.ResponseType.CANCEL)
response = dialog.run()
if response == Gtk.ResponseType.OK:
self.results.dump_csv(dialog.get_filename())
dialog.destroy()
def edit_server_settings(self):
"""Creates Dialog to edit server-settings and save changes."""
dialog = Gtk.Dialog( "Server Settings",
None, 0,
( Gtk.STOCK_OK, Gtk.ResponseType.OK,
"Cancel", Gtk.ResponseType.CANCEL)
)
dialog.set_resizable(False)
dialog.set_size_request(330, 180)
hbox = Gtk.HBox(False, 8)
hbox.set_border_width(8)
dialog.vbox.pack_start(hbox, True, True, 0)
stock = Gtk.Image.new_from_stock(Gtk.STOCK_DIALOG_AUTHENTICATION, Gtk.IconSize.DIALOG)
hbox.pack_start(stock, False, False, 0)
table = Gtk.Table(2, 3)
table.set_row_spacings(4)
table.set_col_spacings(4)
hbox.pack_start(table, True, True, 0)
label_user = Gtk.Label()
label_user.set_text("User:")
table.attach(label_user, 0, 1, 0, 1)
entry_user = Gtk.Entry()
entry_user.set_text(self.credentials_tuple[0])
table.attach(entry_user, 1, 2, 0, 1)
label_passw = Gtk.Label()
label_passw.set_text("Password:")
table.attach(label_passw, 0, 1, 1, 2)
entry_passw = Gtk.Entry()
entry_passw.set_visibility(False)
entry_passw.set_text(self.credentials_tuple[1])
table.attach(entry_passw, 1, 2, 1, 2)
label_host = Gtk.Label()
label_host.set_text("Host:")
table.attach(label_host, 0, 1, 2, 3)
entry_host = Gtk.Entry()
entry_host.set_text(self.host)
table.attach(entry_host, 1, 2, 2, 3)
dialog.show_all()
response = dialog.run()
if response == Gtk.ResponseType.OK:
self.credentials_tuple = (entry_user.get_text(),entry_passw.get_text())
self.host = entry_host.get_text()
#TODO implement method to test connection
dialog.destroy()
def download_files(self):
"""Downloads files from selected items of Result-Table"""
if self.resultsview.get_selected_items() == []:
return
dialog = Gtk.FileChooserDialog( "Open..",
None,
Gtk.FileChooserAction.SELECT_FOLDER,
(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
dialog.set_default_response(Gtk.ResponseType.OK)
response = dialog.run()
if response == Gtk.ResponseType.OK:
rest = xsa.datatypereader.get_rest(self.root)
enabled = (d for d in self.resultsview.get_store() if d[0])
for d in enabled:
def stop_spinner(_row):
_row[2] = False # Hide spinner
_row[0] = False # Checkbox to false
d[3] = 0
d[2] = True # Show Spinner
xsa.queries.download_async( d[1],
self.host,
self.credentials_tuple,
rest,
dialog.get_filename(),
cb=stop_spinner,
cb_args=(d,)
)
dialog.destroy()
def save_query(self):
"""Saves defined query as JSON-file"""
import json
data = {}
data.update({self.root_key: self.root})
data.update({self.query_key: self.query})
data.update({self.labels_key: self.labels})
dialog = Gtk.FileChooserDialog( "Save as..",
None,
Gtk.FileChooserAction.SAVE,
(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
dialog.set_default_response(Gtk.ResponseType.OK)
response = dialog.run()
if response == Gtk.ResponseType.OK:
with open(dialog.get_filename(),'w') as file:
file_data = json.dumps(data)
file.write(file_data)
dialog.destroy()
def load_query(self):
"""Loads a Query from a JSON-File"""
import json
dialog = Gtk.FileChooserDialog( "Load..",
None,
Gtk.FileChooserAction.OPEN,
(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
dialog.set_default_response(Gtk.ResponseType.OK)
response = dialog.run()
if response == Gtk.ResponseType.OK:
with open(dialog.get_filename(), 'r') as file:
f= json.load(file)
self.queryview.set_data(root_field = f[self.root_key],
query = f[self.query_key],
field_labels = f[self.labels_key]
)
dialog.destroy()
def send_query(self):
"""Sends defined query to server, using xsa.queries"""
import xsa.errors
user, passw = self.credentials_tuple
fields = xsa.datatypereader.get_fields_from_labels(self.labels,self.root)
if passw =='' or user=='' or self.host=='':
create_error_message("Please set your password, user-name and host-address (use button 'Server Settings').")
return
if self.query==[]:
create_error_message("Please define a query.")
return
try:
self.results = xsa.queries.search_for( self.host, self.root, self.query, fields, user, passw)
except Exception as e:
create_error_message(e)
self.results = []
self.resultsview.show_data(self.results, self.root)
self.statusbar.push(0, "%s Results"%len(self.results))
self.chartview.update(self.results, self.root)
if self.results == []:
self.menuview.disable_download_button(False, "No Results for downloading")
self.menuview.disable_export_button(False, "No Results for exporting")
self.menuview.disable_adddata_button(False, "No Results for getting additional data")
return
else:
try:
xsa.datatypereader.get_rest(self.root)
self.menuview.disable_download_button(True, "Download selected items from result-table")
except Exception as e:
self.menuview.disable_download_button(False, str(e))
try:
xsa.datatypereader.get_comparison_extra_source(self.root)
self.menuview.disable_adddata_button(True, "Get additional data")
except Exception as e:
self.menuview.disable_adddata_button(False, str(e))
self.menuview.disable_export_button(True, "Export Result-Table as csv-file")
"""
:Author: Franziska Koehn
:Created: 2015/01/13
This module contains the MenuView (a ToolBar).
"""
from gi.repository import Gtk
from gi.repository import GObject
class MenuView(Gtk.Toolbar):
"""A ToolBar containing Buttons"""
__gsignals__ = {
'spawn-connection-dialog': (GObject.SIGNAL_RUN_FIRST, None,()),
'get-additional-data': (GObject.SIGNAL_RUN_FIRST, None,()),
"send-query": (GObject.SIGNAL_RUN_FIRST, None,()),
"toggle-selection": (GObject.SIGNAL_RUN_FIRST, None,()),
"download-selection": (GObject.SIGNAL_RUN_FIRST, None,()),
"save-query": (GObject.SIGNAL_RUN_FIRST, None,()),
"load-query": (GObject.SIGNAL_RUN_FIRST, None,()),
"export-csv": (GObject.SIGNAL_RUN_FIRST, None,())
}
def __init__(self, *args, **kwargs):
"""Creates buttons for this Toolbar and defines signals when this buttons will be pressed.
**Parameters**
:\*args: arguments passed to Gtk.Toolbar-constructor
:\*\*kwargs: keyword-arguments passed to Gtk.Toolbar-constructor
"""
super(MenuView, self).__init__(*args, **kwargs)
#self.set_orientation(Gtk.ORIENTATION_HORIZONTAL)
self.set_style(Gtk.ToolbarStyle.BOTH)