diff --git a/.gitignore b/.gitignore index b40374c..bd249e7 100644 --- a/.gitignore +++ b/.gitignore @@ -139,5 +139,14 @@ debian/files # autoconf stuff *.cache/ *.scan -Makefile config.status + +# instantiated template files +Makefile +bin/simbuto +etc/simbuto/conf/gui.conf +lib/simbuto/python/simbuto/__init__.py +lib/simbuto/python/simbuto/config.py +lib/simbuto/python/simbuto/manager.py +share/applications/simbuto.desktop + diff --git a/Makefile.in b/Makefile.in index 8f8d7e5..60dfc5a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -49,9 +49,15 @@ pdfdir:=@pdfdir@ # ps documentation [DOCDIR] psdir:=@psdir@ +PACKAGE_VERSION := @PACKAGE_VERSION@ +PACKAGE_NAME := @PACKAGE_NAME@ +PACKAGE_STRING := @PACKAGE_STRING@ + configure_dirs = bindir sbindir libexecdir sysconfdir sharedstatedir \ localstatedir runstatedir libdir includedir oldincludedir datarootdir \ datadir infodir localedir mandir docdir htmldir dvidir pdfdir psdir +configure_vars = $(configure_dirs) PACKAGE_VERSION PACKAGE_STRING PACKAGE_NAME \ + PACKAGE_URL $(foreach configure_dir,$(configure_dirs),\ $(eval $(configure_dir) := $(abspath $(DESTDIR)/$($(configure_dir))))) @@ -96,9 +102,18 @@ PANDOCOPTS = -f markdown -t man --standalone IN_FILES = $(shell find $(local_dirs) -type f -iname '*.in') IN_FILES_INSTANTIATED = $(IN_FILES:.in=) +SIMBUTOVERSION := @PACKAGE_VERSION@ +SIMBUTODATE := $(shell date +%F) + +CONFIGURE_AC = configure.ac + +# get information from changelog +DEBIAN_CHANGELOG = debian/changelog +DEBIAN_CHANGELOG_VERSION = $(shell perl -ne 'if(s/^simbuto\s*\((.*?)\).*$$/$$1/g){print;exit}' $(DEBIAN_CHANGELOG)) + # default target .PHONY: all -all: $(MOFILES) $(GFMANPAGES) $(SIMBUTOPYTHONINIT) $(IN_FILES_INSTANTIATED) +all: $(MOFILES) $(GFMANPAGES) $(SIMBUTOPYTHONINIT) $(IN_FILES_INSTANTIATED) $(CONFIGURE_AC) # create rule to install a FILE into the TARGET_DIRECTORY @@ -130,7 +145,7 @@ $(foreach configure_dir,$(configure_dirs),\ # build the manpages # manpages: -%.1: %.1.md +%.1: %.1.md $(DEBIAN_CHANGELOG) pandoc $(PANDOCOPTS) -Vfooter='Version $(SIMBUTOVERSION)' -Vdate='$(SIMBUTODATE)' -o $@ $< # create the pot-file with all translatable strings from the srcfiles @@ -150,10 +165,12 @@ $(sort $(install_target_dirs)): % : mkdir -p $@ @echo $@ >> $(installed_files_file) +$(CONFIGURE_AC): $(DEBIAN_CHANGELOG) + perl -pi -e 's#^(\s*AC_INIT\([^,]*,\s*\[)([.0-9_a-zA-Z-]+)(\]\s*,.*\))#$${1}$(DEBIAN_CHANGELOG_VERSION)$${3}#g' $@ # substitute variables in a file $(IN_FILES_INSTANTIATED): % : %.in Makefile - perl -pe '$(foreach configure_dir,$(configure_dirs),s#[@]$(configure_dir)[@]#$($(configure_dir))#g;)' < $< > $@ + perl -pe '$(foreach var,$(configure_vars),s#[@]$(var)[@]#$($(var))#g;)' < $< > $@ .PHONY: bin_executable bin_executable: $(local_bindir_toinstall) @@ -181,6 +198,7 @@ uninstall: clean: rm -f $(MOFILES) $(POTFILE) $(GFMANPAGES) rm -rf $(addprefix $(DEBIAN)/,files *.substvars *.debhelper simbuto debhelper-build-stamp *.debhelper.log) + rm -f $(IN_FILES_INSTANTIATED) rm -f $(installed_files_file) diff --git a/bin/simbuto b/bin/simbuto deleted file mode 100755 index 52328fd..0000000 --- a/bin/simbuto +++ /dev/null @@ -1,132 +0,0 @@ -#!/usr/bin/env python3 -import sys, os -import logging -import argparse -import locale -# set locale -locale.setlocale(locale.LC_ALL, '') - -logger = logging.getLogger(__name__) -logger.addHandler(logging.StreamHandler()) - -#################### -### LIBRARY PATH ### -#################### -# add /usr/lib/simbuto/python to the module paths -sys.path.insert(1,"/home/yann/.local/lib/simbuto/python") -import simbuto -import simbuto.config - -################ -### LANGUAGE ### -################ -simbuto.config.install_language_globally() - -####################### -### Argument Parser ### -####################### -argparser = argparse.ArgumentParser(description = _("Simbuto - a simple " - "graphical budgeting tool"),add_help=False) -argparser.add_argument('filename', nargs="?", help=_("the budget file to open")) -argparser.add_argument('-h','--help', action='help', help=_( - "show help message and exit")) -argparser.add_argument('-v','--verbose', action='store_true', - help=_("verbose output")) -argparser.add_argument('-d','--debug', action='store_true', - help=_("even more verbose output")) -argparser.add_argument('--version', action='version', - help=_("show version info and exit"), - version = "{p} {v}".format(p=_("Simbuto"),v=simbuto.VERSION) - ) -# parse the arguments -args = argparser.parse_args() - -##################### -### CONFIGURATION ### -##################### -# make sure, there is a personal configuration folder -simbuto.config.make_sure_there_is_simbuto_dotfolder() -# read the personal configuration -config = simbuto.config.get_personal_configuration() -# read system gui configuration as well -config.read(["/home/yann/.local/etc/simbuto/conf/gui.conf"]) - -#################### -### Logger setup ### -#################### -simbuto.config.setup_logger_from_config(logger = logger, - section="logging", config = config) - -if args.debug: - for handler in logger.handlers: - handler.setLevel(logging.DEBUG) - logger.setLevel(logging.DEBUG) - logger.propagate = True -if args.verbose: - for handler in logger.handlers: handler.setLevel(logging.INFO) - logger.setLevel(logging.INFO) - logger.propagate = True - -logger.info(_("This is simbuto version {}").format(simbuto.VERSION)) -logger.debug(_("command-line: {}").format(sys.argv)) -logger.debug(_("parsed arguments: {}").format(args)) -logger.info(_("simbuto is still in early development phase...")) - -##################### -### SignalManager ### -##################### -import simbuto.signalmanager -# a signal manager -signalmanager = simbuto.signalmanager.SignalManager() -# set the logger -signalmanager.logger = logger -# add signals -signalmanager.add_signals(["save-to-file"]) - -###################### -### SimbutoManager ### -###################### -import simbuto.manager -# a signal manager -manager = simbuto.manager.SimbutoManager() -# set the logger -manager.logger = logger -# set the signalmanager -manager.signalmanager = signalmanager -# connect signals -signalmanager.connect_to_signal( - name="read-from-file", action = manager.read_text_from_file) -signalmanager.connect_to_signal( - name="save-to-file", action = manager.save_text_to_file) -signalmanager.connect_to_signal( - name="md5sum-of-file", action = manager.md5sum_of_file) -signalmanager.connect_to_signal( - name="create-graph-from-text", action = manager.create_png_graph_from_text) - -########### -### Gui ### -########### -import simbuto.gui -# a gui -gui = simbuto.gui.SimbutoGui() -# set the logger -gui.logger = logger -# set the signalmanager -gui.signalmanager = signalmanager -# set the config -gui.set_config(config) -# set up the gui -gui.setup_gui() - -signalmanager.connect_to_signal( - name="get-editor-content", action = gui.get_current_editor_content) - -if args.filename: - logger.info(_("specified file to open via command line: {}").format( - args.filename)) - gui.fill_editor_from_file(args.filename) -else: - logger.debug(_("no file specified to open via command line")) - -# run the gui -gui.run() diff --git a/debian/changelog b/debian/changelog index f9dd87e..cf2b6a1 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,6 @@ simbuto (0.1.8) UNRELEASED; urgency=medium - * add Swedish and French translation + * add parts of Swedish and French translation -- Yann Büchau Sun, 19 Feb 2017 11:47:01 +0100 diff --git a/etc/simbuto/conf/gui.conf b/etc/simbuto/conf/gui.conf deleted file mode 100644 index c0f5359..0000000 --- a/etc/simbuto/conf/gui.conf +++ /dev/null @@ -1,6 +0,0 @@ -[gui-general] -# where is the glade file? -gladefile = /home/yann/.local/share/simbuto/gui/simbuto.glade -# where is the window icon? -icon = /home/yann/.local/share/icons/hicolor/scalable/apps/simbuto.svg - diff --git a/lib/simbuto/python/simbuto/__init__.py b/lib/simbuto/python/simbuto/__init__.py.in similarity index 95% rename from lib/simbuto/python/simbuto/__init__.py rename to lib/simbuto/python/simbuto/__init__.py.in index e8e8af0..7659ef5 100644 --- a/lib/simbuto/python/simbuto/__init__.py +++ b/lib/simbuto/python/simbuto/__init__.py.in @@ -6,7 +6,7 @@ # Internal modules # the version -VERSION = "0.1.8" +VERSION = "@PACKAGE_VERSION@" __version__ = VERSION diff --git a/lib/simbuto/python/simbuto/config.py b/lib/simbuto/python/simbuto/config.py deleted file mode 100644 index 9e9f516..0000000 --- a/lib/simbuto/python/simbuto/config.py +++ /dev/null @@ -1,112 +0,0 @@ -#!/usr/bin/env python3 -import os, glob -import gettext -import logging -import configparser -import shutil -import locale - -# install the user language globally -def install_language_globally(): - # get user system language - user_language = locale.getlocale()[0] # get the locale - # init translation - lang = gettext.translation( - domain = 'simbuto', # domain - localedir = '/home/yann/.local/share/locale', # language folder - languages = [user_language.split("_")[0]], # user language - fallback = True - ) - lang.install() # install the language - -def personal_simbuto_dotfolder(): - # home directory - home = os.path.expanduser("~") - # dotfolder - dotfolder = ".simbuto" - # add dotfolder - path = os.path.join(home,dotfolder) - # return path - return path - -def copy_minimal_simbuto_dotfolder(): - shutil.copytree( # copy - "/home/yann/.local/etc/simbuto/skel/simbuto-home", # skeleton folder - personal_simbuto_dotfolder() # to home directory - ) - -def make_sure_there_is_simbuto_dotfolder(): - # if there is no personal dotfolder, copy the skeleton - if not os.path.exists(personal_simbuto_dotfolder()): - copy_minimal_simbuto_dotfolder() - -def get_personal_configuration(): - # a ConfigParser - config = configparser.ConfigParser() - # configuration folder - conffolder = os.path.join(personal_simbuto_dotfolder(),"conf") - # all personal configuration files - configfiles = glob.glob(os.path.join(conffolder,"*.conf")) - # read all configuration files - config.read(configfiles) - # return the ConfigParser - return config - -# setup logging from configuration file section -def setup_logger_from_config(logger,section,config=None): - if not isinstance(config, configparser.ConfigParser): - # get the configuration - config = get_configuration() - - # if this section is not in the config, leave the logger as is - try: configsection = config[section] - except: return logger - - # initialize logging - # set loglevel possiblities - loglevels = { - 'debug' :logging.DEBUG, - 'info' :logging.INFO, - 'warning' :logging.WARNING, - 'error' :logging.ERROR, - 'critical':logging.CRITICAL - } - - # get loglevel from config - loglevel = loglevels.get(configsection.get('loglevel','warning').lower(), - logging.WARNING) - # get file from config - logfile = configsection.get('logfile', None) - - # create a handler - if logfile: - try: - # create a file handler and log to that file - handler = logging.FileHandler(filename = logfile, encoding="UTF-8") - except: # e.g. file permissions don't work - # create a stream handler and log to stderr - handler = logging.StreamHandler() - else: - # create a stream handler and log to stderr - handler = logging.StreamHandler() - # set the loglevel for the handler and the logger - handler.setLevel(loglevel) - logger.setLevel(loglevel) - - # create a formatter - formatter = logging.Formatter( - fmt="%(asctime)s [%(levelname)s] %(module)s: %(message)s", - datefmt="%Y-%m-%d %H:%M:%S" - ) - - # add the formatter to the handler - handler.setFormatter(formatter) - - # add the handler to the logger - logger.handlers = [handler] - - # return the logger - return logger - - - diff --git a/lib/simbuto/python/simbuto/manager.py b/lib/simbuto/python/simbuto/manager.py deleted file mode 100644 index 1ef88ef..0000000 --- a/lib/simbuto/python/simbuto/manager.py +++ /dev/null @@ -1,146 +0,0 @@ -#!/usr/bin/env python3 -# system modules -import logging -import hashlib -import datetime - -# external modules -from rpy2.rinterface import RRuntimeError -from rpy2.robjects import r as R # be able to talk to R - -# internal modules -from . import signalmanager -from . import WithLogger - -# signal manager class -class SimbutoManager(WithLogger): - def __init__(self): - # source R functions - R.source("/home/yann/.local/lib/simbuto/r/simbuto-functions.R") - - ################## - ### Properties ### - ################## - @property - def signalmanager(self): - return self._signalmanager - - @signalmanager.setter - def signalmanager(self, manager): - assert isinstance(manager, signalmanager.SignalManager) - self._signalmanager = manager - - - ### methods ### - def read_text_from_file(self, filename): - """ Read text from the given file in utf-8 - Args: - filename (path): the path to save the text to - Returns: - text (str or None): The text read. None if reading didn't work. - """ - try: - with open(filename, "r", encoding="utf-8") as f: - text = f.read() - self.logger.debug(_("Read {} characters from file '{}'").format( - len(text),filename)) - return text - except: - self.logger.warning( - _("Reading from file '{}' didn't work!").format(filename)) - return None - - def save_text_to_file(self, filename, text): - """ Save the given text to file in utf-8 - Args: - filename (path): the path to save the text to - text (str): the text to save - Returns: - success (bool): True if it worked, False otherwise - """ - self.logger.debug(_("Saving {} characters to file '{}'...").format( - len(text),filename)) - try: - with open(filename, "w", encoding="utf-8") as f: - f.write(text) - self.logger.debug(_("Saved {} characters to file '{}'").format( - len(text),filename)) - return True - except: - self.logger.warning( - _("Saving {} characters to file '{}' didn't work!").format( - len(text),filename)) - return False - - ### md5sums differ ### - def md5sum_of_file(self, filename): - """ Return the given file's md5sum in hexdigits - Args: - filename (path): the file to calculate the md5sum from - Returns: - md5sum (str): the md5sum of the file - """ - try: - with open(filename,"r") as f: - # hash the file content - md5 = hashlib.md5(f.read().encode('utf-8')).hexdigest() - self.logger.debug(_("md5sum of file '{}' is '{}'").format( - filename,md5)) - return md5 - except OSError: - self.logger.warning(_("Calculating md5sum of file '{}' " - "didn't work!").format(filename)) - return None - - - ################ - ### Plotting ### - ################ - def create_png_graph_from_text(self, text, filename, - width = 600, height = 400, - start = datetime.datetime.now(), - end = datetime.datetime.now() + datetime.timedelta(365), - opening_stock = 0, - ensemble_size = 100, - use_ensemble = False): - """ Create a png graph from simbuto csv-like text - Args: - text (str): the csv-like simbuto budget - filename (path): the output png file path - width, height [Optional(int)]: width and height of the png file. - Defaults to 600x400px. - start [Optional(datetime.datetime)]: the start day of the budget - calculation and plotting. Defaults to the current day. - end [Optional(datetime.datetime)]: the end time of the budget - calculation and plotting. Defaults to the current day plus one - year. - use_ensemble [Optional(bool)]: calculat an ensemble? Defaults to - False. - ensemble_size [Optional(int)]: The ensemble size to use. Defaults to - 100. - opening_stock [Optional(float)]: The opening stock. Defaults to 0. - Returns: - success (bool): True if graph png file was created, False otherwise - """ - start_date = R("as.Date('{}-{}-{}')".format( - start.year,start.month,start.day)) - end_date = R("as.Date('{}-{}-{}')".format( - end.year,end.month,end.day)) - if not use_ensemble: - ensemble_size = R("NULL") - try: - # append newline - if not text.endswith("\n"): text += "\n" - # create the budget from text - budget_frame = R.read_budget_from_text(text = text, - opening_stock = opening_stock) - # create the timeseries from the budget - timeseries_frame = R.timeseries_from_budget(budget = budget_frame, - start = start_date, end = end_date, ensemble_size=ensemble_size) - # plot to png - R.plot_budget_timeseries_to_png(filename=filename, - timeseries = timeseries_frame, width = width, height = height) - return True - except RRuntimeError: - self.logger.warning(_("R could not read from text")) - return False diff --git a/locale/de/LC_MESSAGES/simbuto.po b/locale/de/LC_MESSAGES/simbuto.po index 634a3a3..3b1141c 100644 --- a/locale/de/LC_MESSAGES/simbuto.po +++ b/locale/de/LC_MESSAGES/simbuto.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-05-25 18:20+0200\n" +"POT-Creation-Date: 2017-05-25 23:34+0200\n" "PO-Revision-Date: 2017-02-19 12:07+0100\n" "Last-Translator: \n" "Language-Team: \n" diff --git a/locale/fr/LC_MESSAGES/simbuto.po b/locale/fr/LC_MESSAGES/simbuto.po index ef4b784..ea254ac 100644 --- a/locale/fr/LC_MESSAGES/simbuto.po +++ b/locale/fr/LC_MESSAGES/simbuto.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-05-25 18:20+0200\n" +"POT-Creation-Date: 2017-05-25 23:34+0200\n" "PO-Revision-Date: 2017-02-19 13:36+0100\n" "Last-Translator: \n" "Language-Team: \n" diff --git a/locale/sv/LC_MESSAGES/simbuto.po b/locale/sv/LC_MESSAGES/simbuto.po index da85744..d4586b4 100644 --- a/locale/sv/LC_MESSAGES/simbuto.po +++ b/locale/sv/LC_MESSAGES/simbuto.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-05-25 18:20+0200\n" +"POT-Creation-Date: 2017-05-25 23:34+0200\n" "PO-Revision-Date: 2017-05-24 23:18+0200\n" "Last-Translator: \n" "Language-Team: \n" diff --git a/man/man1/simbuto.1.md b/man/man1/simbuto.1.md index 6df0503..5f69695 100644 --- a/man/man1/simbuto.1.md +++ b/man/man1/simbuto.1.md @@ -39,15 +39,15 @@ ENVIRONMENT =========== -| Variable | Impact | -|-------------------------|----------------------------------| -|**LANG** or **LANGUAGE** | UI language, defaults to English | +| Variable | Impact | +|----------|----------------------------------| +|**LANG** | UI language, defaults to English | AUTHOR ====== -Yann Büchau +Yann Büchau diff --git a/share/applications/simbuto.desktop b/share/applications/simbuto.desktop deleted file mode 100644 index 53611c8..0000000 --- a/share/applications/simbuto.desktop +++ /dev/null @@ -1,17 +0,0 @@ -[Desktop Entry] -Version=1.0 -Type=Application -MimeType=application/x-simbuto; -Name=Simbuto -Name[de]=Simbuto -Name[en]=Simbuto -GenericName=Budgeting -GenericName[de]=Kostenplanung -GenericName[en]=Budgeting -Comment[de]=einfaches Kostenplanungstool -Comment[en]=simple budgeting tool -Exec=/home/yann/.local/bin/simbuto %f -Icon=/home/yann/.local/share/icons/hicolor/scalable/apps/simbuto.svg -Categories=Office;Finance; -Terminal=false -StartupNotify=True