From 15072d7a4390ccaf9d58ca58e8a1513163d3c7f6 Mon Sep 17 00:00:00 2001 From: John Kirkham Date: Wed, 8 Jun 2016 11:51:48 -0400 Subject: [PATCH 01/10] config: Add a PyQt4 app to fill in the config. --- config.py | 62 ++++++++++++++++++ config.ui | 183 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 245 insertions(+) create mode 100644 config.py create mode 100644 config.ui diff --git a/config.py b/config.py new file mode 100644 index 0000000..1bef650 --- /dev/null +++ b/config.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python + + +from __future__ import print_function + +from collections import OrderedDict +import json +import sys + +from PyQt4 import QtCore, QtGui, uic + + +# Python 3 compatibility +try: + xrange +except NameError: + xrange = range + + +class Config(QtGui.QDialog): + """ + Parses the configuration the user applies + """ + + def __init__(self): + super(Config, self).__init__() + + self.config = OrderedDict() + + self.ui = uic.loadUi("config.ui") + self.ui.show() + + btn = self.ui.buttonBox.button( + QtGui.QDialogButtonBox.Ok + ) + btn.clicked.connect(self.accept) + + def accept(self): + table = self.ui.tableWidget + for i in xrange(table.rowCount()): + header_i = str(table.verticalHeaderItem(i).text()) + self.config[header_i] = "" + item_i = table.item(0, i) + if item_i: + self.config[header_i] = str(item_i.text()) + + filename = QtGui.QFileDialog.getSaveFileName( + self, + "Save file", + "", + "*.json" + ) + with open(filename, "w") as f: + json.dump(self.config, f, indent=True) + +def main(*argv): + app = QtGui.QApplication(sys.argv) + window = Config() + return app.exec_() + +if __name__ == "__main__": + sys.exit(main(*sys.argv)) diff --git a/config.ui b/config.ui new file mode 100644 index 0000000..63ed4f9 --- /dev/null +++ b/config.ui @@ -0,0 +1,183 @@ + + + Dialog + + + + 0 + 0 + 598 + 648 + + + + + 0 + 0 + + + + Dialog + + + false + + + + + + + + true + + + false + + + false + + + + Rig_Name + + + + + User + + + + + Proj_Code + + + + + Rec_Sys + + + + + Behav_Code_Ver + + + + + NS_Path + + + + + Behav_Path + + + + + Jpos_X_Ch + + + + + Jpos_Y_Ch + + + + + Mpos_X_Ch + + + + + Mpos_Y_Ch + + + + + Lick_Ch + + + + + Rew_Ch + + + + + Trial_Start_Ch + + + + + Trial_Event_Ch + + + + + Input + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + <b>Lab Data Configuration Generator</b> + + + Qt::AutoText + + + false + + + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + From f0b4f95e2404731331dc166b97a00cb7c4cf3a10 Mon Sep 17 00:00:00 2001 From: John Kirkham Date: Wed, 8 Jun 2016 14:07:45 -0400 Subject: [PATCH 02/10] config: Support PyQt or PySide. --- config.py | 37 +++++++++++++++++++++++++++---------- config.ui | 2 +- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/config.py b/config.py index 1bef650..9d88080 100644 --- a/config.py +++ b/config.py @@ -3,12 +3,15 @@ from __future__ import print_function -from collections import OrderedDict +import collections as col import json +import os import sys -from PyQt4 import QtCore, QtGui, uic - +try: + from PySide import QtCore, QtGui, QtUiTools +except ImportError: + from PyQt4 import QtCore, QtGui, uic # Python 3 compatibility try: @@ -22,18 +25,27 @@ class Config(QtGui.QDialog): Parses the configuration the user applies """ - def __init__(self): - super(Config, self).__init__() + def __init__(self, *args, **kwargs): + super(Config, self).__init__(*args, **kwargs) + self.modal = True - self.config = OrderedDict() + self.config = col.OrderedDict() - self.ui = uic.loadUi("config.ui") - self.ui.show() + try: + self.ui = QtUiTools.QUiLoader().load("config.ui") + except NameError: + self.ui = uic.loadUi("config.ui") - btn = self.ui.buttonBox.button( + btn_box = self.ui.buttonBox + ok_btn = btn_box.button( QtGui.QDialogButtonBox.Ok ) - btn.clicked.connect(self.accept) + ok_btn.clicked.connect(self.accept) + + def show(self): + self.ui.show() + self.ui.activateWindow() + self.ui.raise_() def accept(self): table = self.ui.tableWidget @@ -50,12 +62,17 @@ def accept(self): "", "*.json" ) + # PySide gives us a tuple. + # The actual filename is first + if isinstance(filename, tuple): + filename = filename[0] with open(filename, "w") as f: json.dump(self.config, f, indent=True) def main(*argv): app = QtGui.QApplication(sys.argv) window = Config() + window.show() return app.exec_() if __name__ == "__main__": diff --git a/config.ui b/config.ui index 63ed4f9..aca09e1 100644 --- a/config.ui +++ b/config.ui @@ -130,7 +130,7 @@ - + <b>Lab Data Configuration Generator</b> From f3a26208598989567835727c70b352c438923cba Mon Sep 17 00:00:00 2001 From: John Kirkham Date: Wed, 8 Jun 2016 17:41:58 -0400 Subject: [PATCH 03/10] config_app: Handle location adjustment. --- config.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/config.py b/config.py index 9d88080..52cac6f 100644 --- a/config.py +++ b/config.py @@ -19,6 +19,7 @@ except NameError: xrange = range +script_dir = os.path.dirname(os.path.abspath(__file__)) class Config(QtGui.QDialog): """ @@ -31,10 +32,14 @@ def __init__(self, *args, **kwargs): self.config = col.OrderedDict() + config_ui = os.path.join( + script_dir, + "config.ui" + ) try: - self.ui = QtUiTools.QUiLoader().load("config.ui") + self.ui = QtUiTools.QUiLoader().load(config_ui) except NameError: - self.ui = uic.loadUi("config.ui") + self.ui = uic.loadUi(config_ui) btn_box = self.ui.buttonBox ok_btn = btn_box.button( From 1308781edd8958e18034ec6ab4fda51c6c6c9769 Mon Sep 17 00:00:00 2001 From: John Kirkham Date: Wed, 8 Jun 2016 17:38:46 -0400 Subject: [PATCH 04/10] config -> config_app --- config.py => config_app.py | 8 ++++---- config.ui => config_app.ui | 0 2 files changed, 4 insertions(+), 4 deletions(-) rename config.py => config_app.py (91%) rename config.ui => config_app.ui (100%) diff --git a/config.py b/config_app.py similarity index 91% rename from config.py rename to config_app.py index 52cac6f..d80de28 100644 --- a/config.py +++ b/config_app.py @@ -32,14 +32,14 @@ def __init__(self, *args, **kwargs): self.config = col.OrderedDict() - config_ui = os.path.join( + config_app_ui = os.path.join( script_dir, - "config.ui" + "config_app.ui" ) try: - self.ui = QtUiTools.QUiLoader().load(config_ui) + self.ui = QtUiTools.QUiLoader().load(config_app_ui) except NameError: - self.ui = uic.loadUi(config_ui) + self.ui = uic.loadUi(config_app_ui) btn_box = self.ui.buttonBox ok_btn = btn_box.button( diff --git a/config.ui b/config_app.ui similarity index 100% rename from config.ui rename to config_app.ui From 97c86a932444f929d9b9afbac4385052e3026c89 Mon Sep 17 00:00:00 2001 From: John Kirkham Date: Wed, 8 Jun 2016 17:49:06 -0400 Subject: [PATCH 05/10] config_app: Create a module with the config app. --- config/__init__.py | 0 config_app.py => config/config_app.py | 0 config_app.ui => config/config_app.ui | 0 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 config/__init__.py rename config_app.py => config/config_app.py (100%) rename config_app.ui => config/config_app.ui (100%) diff --git a/config/__init__.py b/config/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/config_app.py b/config/config_app.py similarity index 100% rename from config_app.py rename to config/config_app.py diff --git a/config_app.ui b/config/config_app.ui similarity index 100% rename from config_app.ui rename to config/config_app.ui From cd93c094cfb3c2113df0941f8b1eb6767bb8ef75 Mon Sep 17 00:00:00 2001 From: John Kirkham Date: Wed, 8 Jun 2016 17:49:34 -0400 Subject: [PATCH 06/10] config_app: Make an executable module. --- config/__main__.py | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 config/__main__.py diff --git a/config/__main__.py b/config/__main__.py new file mode 100644 index 0000000..de95820 --- /dev/null +++ b/config/__main__.py @@ -0,0 +1,6 @@ +import sys + +import config_app + +if __name__ == "__main__": + sys.exit(config_app.main(*sys.argv)) From f71b4457e98f0fb677b39691219af55034bbdb98 Mon Sep 17 00:00:00 2001 From: John Kirkham Date: Wed, 8 Jun 2016 22:39:18 -0400 Subject: [PATCH 07/10] README: Add a very brief readme. --- README.rst | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 README.rst diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..7614de9 --- /dev/null +++ b/README.rst @@ -0,0 +1,4 @@ +lab_config +========== + +Some lab configuration tools. From fe0b74cac2b182988f00bdd92ccb9ad35ae4e6be Mon Sep 17 00:00:00 2001 From: John Kirkham Date: Wed, 8 Jun 2016 22:42:31 -0400 Subject: [PATCH 08/10] setup: Add a setup file to enable simple installation. --- setup.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 setup.py diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..680f665 --- /dev/null +++ b/setup.py @@ -0,0 +1,26 @@ +import os + +from distutils.core import setup + +pkg_dir = os.path.dirname(os.path.abspath( + __file__ +)) + +readme = "" +readme_filename = os.path.join(pkg_dir, "README.rst") +with open(readme_filename, "r") as readme_file: + readme = readme_file.read() + +setup( + name="lab_config", + version="0.1.0", + license="BSD??", + description="A package of utilities in use in our lab.", + long_description=readme, + author="John Kirkham", + author_email="kirkhamj@janelia.hhmi.org", + url="https://github.com/DudLab/lab_config", + packages=["config"], + package_data={"config": ["*.ui"]}, + classifiers=[] +) From b9eb1285e84178ef89e7b8a26c6c87493df66de7 Mon Sep 17 00:00:00 2001 From: John Kirkham Date: Wed, 8 Jun 2016 23:27:44 -0400 Subject: [PATCH 09/10] conda.recipe: Add a recipe to build and package this with conda. --- conda.recipe/meta.yaml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 conda.recipe/meta.yaml diff --git a/conda.recipe/meta.yaml b/conda.recipe/meta.yaml new file mode 100644 index 0000000..76746d8 --- /dev/null +++ b/conda.recipe/meta.yaml @@ -0,0 +1,28 @@ +package: + name: lab_config + version: {{ environ.get('GIT_DESCRIBE_TAG', '')[1:] }}{{ '+' + environ.get('GIT_DESCRIBE_NUMBER', '0') + '.' + environ.get('GIT_DESCRIBE_HASH', '0') if environ.get('GIT_DESCRIBE_NUMBER', '0') != '0' else "" }} + +source: + git_url: .. + git_tag: HEAD + +build: + number: 0 + script: python setup.py install + +requirements: + build: + - python + + run: + - python + - pyside + +test: + imports: + - config + +about: + home: https://github.com/DudLab/lab_config + license: BSD??? + summary: A package of utilities in use in our lab. From 48186196955a2456141a302e65b650a54aec4171 Mon Sep 17 00:00:00 2001 From: John Kirkham Date: Wed, 8 Jun 2016 23:42:34 -0400 Subject: [PATCH 10/10] constructor.config: Adds a way to package this with constructor. --- constructor.config/construct.yaml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 constructor.config/construct.yaml diff --git a/constructor.config/construct.yaml b/constructor.config/construct.yaml new file mode 100644 index 0000000..66bd8b9 --- /dev/null +++ b/constructor.config/construct.yaml @@ -0,0 +1,15 @@ +name: lab_config +version: "0.1.0" + +channels: + - http://repo.continuum.io/pkgs/free/ + - https://conda.anaconda.org/jakirkham + +specs: + - lab_config + +keep_pkgs: true + +conda_default_channels: + - http://repo.continuum.io/pkgs/free/ + - https://conda.anaconda.org/jakirkham