summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile9
-rw-r--r--src/audio/.gitignore1
-rw-r--r--src/audio/Makefile10
-rw-r--r--src/audio/audio-interface.vala16
-rw-r--r--src/audio/audio.vala36
-rw-r--r--src/audio/main.vala20
-rw-r--r--src/backup/.gitignore1
-rw-r--r--src/backup/Makefile10
-rw-r--r--src/backup/main.vala5
-rw-r--r--src/cli/.gitignore1
-rw-r--r--src/cli/Makefile11
-rw-r--r--src/cli/cli.vala11
-rw-r--r--src/cli/main.vala32
-rw-r--r--src/config/.gitignore1
-rw-r--r--src/config/Makefile10
-rw-r--r--src/config/config-interface.vala16
-rw-r--r--src/config/config.vala18
-rw-r--r--src/config/main.vala13
-rw-r--r--src/curses-ui/.gitignore1
-rw-r--r--src/curses-ui/Makefile10
-rw-r--r--src/curses-ui/clock.vala1
-rw-r--r--src/curses-ui/curses-ui.vala18
-rw-r--r--src/curses-ui/dialog.vala6
-rw-r--r--src/curses-ui/logo.vala28
-rw-r--r--src/curses-ui/main.vala28
-rw-r--r--src/curses-ui/message_box.vala4
-rw-r--r--src/curses-ui/message_box_overlay.vala6
-rw-r--r--src/curses-ui/numbers.vala2
-rw-r--r--src/database/.gitignore1
-rw-r--r--src/database/Makefile10
-rw-r--r--src/database/database.vala271
-rw-r--r--src/database/db-interface.vala113
-rw-r--r--src/database/main.vala21
-rwxr-xr-xsrc/display-on-off/display-on-off.sh26
-rw-r--r--src/input-device/.gitignore1
-rw-r--r--src/input-device/Makefile10
-rw-r--r--src/input-device/input-device-interface.vala2
-rw-r--r--src/input-device/input-device.vala15
-rw-r--r--src/input-device/main.vala31
-rw-r--r--src/invoice/.gitignore2
-rw-r--r--src/invoice/Makefile13
-rw-r--r--src/invoice/invoice.vala81
-rw-r--r--src/invoice/main.vala11
-rw-r--r--src/invoice/single.vala4
-rw-r--r--src/libcairobarcode/code39.vala128
-rw-r--r--src/libcairobarcode/ean.vala142
-rw-r--r--src/libcairobarcode/error.vala19
-rw-r--r--src/mail/.gitignore1
-rw-r--r--src/mail/Makefile10
-rw-r--r--src/mail/mail.vala58
-rw-r--r--src/mail/mailer-interface.vala14
-rw-r--r--src/mail/mailer.vala34
-rw-r--r--src/mail/main.vala15
-rw-r--r--src/meson.build52
-rw-r--r--src/pdf-invoice/.gitignore3
-rw-r--r--src/pdf-invoice/Makefile13
-rw-r--r--src/pdf-invoice/main.vala22
-rw-r--r--src/pdf-invoice/pdf-invoice-interface.vala4
-rw-r--r--src/pdf-invoice/pdf-invoice.vala78
-rw-r--r--src/pdf-invoice/test.vala24
-rw-r--r--src/pdf-stock/.gitignore3
-rw-r--r--src/pdf-stock/Makefile20
-rw-r--r--src/pdf-stock/main.vala11
-rw-r--r--src/pdf-stock/pdf-stock-interface.vala3
-rw-r--r--src/pdf-stock/pdf-stock.vala10
-rw-r--r--src/pdf-stock/test.vala8
-rw-r--r--src/pgp/.gitignore1
-rw-r--r--src/pgp/Makefile10
-rw-r--r--src/pgp/main.vala18
-rw-r--r--src/pgp/pgp-interface.vala6
-rw-r--r--src/pgp/pgp.vala10
-rw-r--r--src/scanner-session/.gitignore1
-rw-r--r--src/scanner-session/Makefile10
-rw-r--r--src/scanner-session/main.vala11
-rw-r--r--src/scanner-session/scannersession-interface.vala22
-rw-r--r--src/scanner-session/scannersession.vala386
-rw-r--r--src/serial-device/.gitignore1
-rw-r--r--src/serial-device/Makefile10
-rw-r--r--src/serial-device/main.vala24
-rw-r--r--src/serial-device/serial-device.vala22
-rw-r--r--src/web/.gitignore1
-rw-r--r--src/web/Makefile10
-rw-r--r--src/web/csv.vala12
-rw-r--r--src/web/main.vala57
-rw-r--r--src/web/template.vala41
-rw-r--r--src/web/web.vala153
-rw-r--r--src/web/websession.vala14
87 files changed, 1566 insertions, 863 deletions
diff --git a/src/Makefile b/src/Makefile
deleted file mode 100644
index d5bb40f..0000000
--- a/src/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-DAEMONS=audio backup cli config curses-ui database input-device invoice mail pdf-invoice pdf-stock pgp scanner-session serial-device input-device web
-
-all:
- @$(foreach dir,$(DAEMONS),cd $(dir) && echo "Building $(dir)..." && make --no-print-directory all ; cd ..;)
-
-clean:
- @$(foreach dir,$(DAEMONS),cd $(dir) && make --no-print-directory clean ; cd ..;)
-
-.PHONY: all clean
diff --git a/src/audio/.gitignore b/src/audio/.gitignore
deleted file mode 100644
index d5cc284..0000000
--- a/src/audio/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-audio
diff --git a/src/audio/Makefile b/src/audio/Makefile
deleted file mode 100644
index 950287a..0000000
--- a/src/audio/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-all: audio
- @echo > /dev/null
-
-audio: main.vala audio.vala audio-interface.vala ../config/config-interface.vala
- valac -X -w -o $@ --pkg gstreamer-1.0 --pkg gio-2.0 $^
-
-clean:
- rm -rf audio
-
-.PHONY: all clean
diff --git a/src/audio/audio-interface.vala b/src/audio/audio-interface.vala
index fe13af5..721a484 100644
--- a/src/audio/audio-interface.vala
+++ b/src/audio/audio-interface.vala
@@ -17,8 +17,16 @@
public interface AudioPlayer : Object {
public abstract signal void end_of_stream();
- public abstract void play_system(string file) throws IOError;
- public abstract string get_random_user_theme() throws IOError;
- public abstract string[] get_user_themes() throws IOError;
- public abstract void play_user(string theme, string type) throws IOError;
+ public abstract void play_system(string file) throws DBusError, IOError;
+ public abstract string get_random_user_theme() throws DBusError, IOError;
+ public abstract string[] get_user_themes() throws DBusError, IOError;
+ public abstract void play_user(string theme, string type) throws DBusError, IOError;
+}
+
+public enum AudioType {
+ ERROR,
+ LOGIN,
+ LOGOUT,
+ PURCHASE,
+ INFO
}
diff --git a/src/audio/audio.vala b/src/audio/audio.vala
index 9afb840..0d969e2 100644
--- a/src/audio/audio.vala
+++ b/src/audio/audio.vala
@@ -30,24 +30,31 @@ public class AudioPlayerImplementation {
return true;
}
- public AudioPlayerImplementation(string path) throws IOError {
+ public AudioPlayerImplementation(string path) throws IOError, DBusError {
this.path = path;
var alsa = Gst.ElementFactory.make("alsasink", "alsa");
- if (alsa == null)
- throw new GLib.IOError.FAILED("Cannot find alsa GStreamer plugin");
+ if (alsa == null) {
+ var msg = _("Cannot find alsa GStreamer plugin");
+ stderr.printf(msg);
+ throw new GLib.IOError.FAILED(msg);
+ }
p = Gst.ElementFactory.make("playbin", "player");
- if (p == null)
- throw new GLib.IOError.FAILED("Cannot find playbin2 GStreamer plugin");
+ if (p == null) {
+ var msg = _("Cannot find playbin2 GStreamer plugin");
+ stderr.printf(msg);
+ throw new GLib.IOError.FAILED(msg);
+ }
p.set("audio-sink", alsa);
p.get_bus().add_watch(Priority.DEFAULT, bus_callback);
}
- public void play_system(string file) {
+ public void play_system(string file) throws IOError, DBusError {
p.set_state(Gst.State.NULL);
- p.uri = "file://" + path + "system/" + file;
+ p.uri = "file://" + Path.build_filename(path, "system", file);
+ stdout.printf("Play: %s\n", p.uri);
p.set_state(Gst.State.PLAYING);
}
@@ -76,18 +83,19 @@ public class AudioPlayerImplementation {
return files[index];
}
- public string get_random_user_theme() {
- return get_random_file(path + "user/");
+ public string get_random_user_theme() throws IOError, DBusError {
+ return get_random_file(Path.build_filename(path, "user"));
}
- public string[] get_user_themes() {
- return get_files(path + "user/");
+ public string[] get_user_themes() throws IOError, DBusError {
+ return get_files(Path.build_filename(path, "user"));
}
- public void play_user(string theme, string type) {
+ public void play_user(string theme, string type) throws IOError, DBusError {
p.set_state(Gst.State.NULL);
- var file = get_random_file(path + "user/" + theme+ "/" + type);
- p.uri = "file://" + path + "user/" + theme+ "/" + type + "/" + file;
+ var file = get_random_file(Path.build_filename(path, "user", theme, type));
+ p.uri = "file://" + Path.build_filename(path, "user", theme, type, file);
+ stdout.printf("Play: %s\n", p.uri);
p.set_state(Gst.State.PLAYING);
}
}
diff --git a/src/audio/main.vala b/src/audio/main.vala
index ac64f52..2fdaf61 100644
--- a/src/audio/main.vala
+++ b/src/audio/main.vala
@@ -18,22 +18,28 @@ AudioPlayerImplementation player;
public static int main(string[] args) {
Gst.init(ref args);
+ Intl.setlocale(LocaleCategory.ALL, "");
+ Intl.textdomain("shopsystem");
+
Bus.own_name(
BusType.SYSTEM,
"io.mainframe.shopsystem.AudioPlayer",
BusNameOwnerFlags.NONE,
- on_bus_aquired,
+ on_bus_acquired,
() => {},
- () => stderr.printf("Could not aquire name\n"));
+ () => stderr.printf(_("Could not acquire name\n")));
try {
Config cfg = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Config", "/io/mainframe/shopsystem/config");
- var path = cfg.get_string("AUDIO", "path");
+ var datapath = cfg.get_string("GENERAL", "datapath");
+ var path = Path.build_filename(datapath, "sounds");
player = new AudioPlayerImplementation(path);
} catch(IOError e) {
- error("IOError: %s\n", e.message);
+ error(_("IO Error: %s\n"), e.message);
} catch(KeyFileError e) {
- error("Config Error: %s\n", e.message);
+ error(_("Config Error: %s\n"), e.message);
+ } catch(DBusError e) {
+ error(_("DBus Error: %s\n"), e.message);
}
new MainLoop().run();
@@ -41,10 +47,10 @@ public static int main(string[] args) {
return 0;
}
-void on_bus_aquired(DBusConnection con) {
+void on_bus_acquired(DBusConnection con) {
try {
con.register_object("/io/mainframe/shopsystem/audio", player);
} catch(IOError e) {
- stderr.printf("Could not register service\n");
+ stderr.printf(_("Could not register service\n"));
}
}
diff --git a/src/backup/.gitignore b/src/backup/.gitignore
deleted file mode 100644
index ec76ec2..0000000
--- a/src/backup/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-backup
diff --git a/src/backup/Makefile b/src/backup/Makefile
deleted file mode 100644
index de8eee3..0000000
--- a/src/backup/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-all: backup
- @echo > /dev/null
-
-backup: main.vala ../mail/mailer-interface.vala ../config/config-interface.vala
- valac -X -w -o $@ --pkg gio-2.0 $^
-
-clean:
- rm -f backup
-
-.PHONY: all clean
diff --git a/src/backup/main.vala b/src/backup/main.vala
index 4aed71f..670e56a 100644
--- a/src/backup/main.vala
+++ b/src/backup/main.vala
@@ -14,6 +14,9 @@
*/
public static int main(string[] args) {
+ Intl.setlocale(LocaleCategory.ALL, "");
+ Intl.textdomain("shopsystem");
+
try {
Mailer mailer = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Mail", "/io/mainframe/shopsystem/mailer");
Config cfg = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Config", "/io/mainframe/shopsystem/config");
@@ -35,7 +38,7 @@ public static int main(string[] args) {
mailer.send_mail(mailpath);
} catch(Error e) {
- stderr.printf("Error: %s\n", e.message);
+ stderr.printf(_("Error: %s\n"), e.message);
}
return 0;
diff --git a/src/cli/.gitignore b/src/cli/.gitignore
deleted file mode 100644
index 573c0c4..0000000
--- a/src/cli/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-cli
diff --git a/src/cli/Makefile b/src/cli/Makefile
deleted file mode 100644
index f042ca8..0000000
--- a/src/cli/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-all: cli
- @echo > /dev/null
-
-cli: main.vala cli.vala cli-interface.vala ../config/config-interface.vala
- valac -X -w -o $@ --pkg linux --pkg posix --pkg gio-2.0 $^
-
-
-clean:
- rm -rf cli
-
-.PHONY: all clean
diff --git a/src/cli/cli.vala b/src/cli/cli.vala
index bc6fe9d..0d0e9d4 100644
--- a/src/cli/cli.vala
+++ b/src/cli/cli.vala
@@ -15,14 +15,13 @@
[DBus (name = "io.mainframe.shopsystem.Cli")]
public class CliImpl {
-
public signal void received_barcode(string barcode);
public CliImpl() {
- }
+ }
- public void send(string msg) {
- stdout.printf("Sending: %s\n", msg);
- received_barcode(msg);
- }
+ public void send(string msg) throws IOError, DBusError {
+ stdout.printf(_("Sending: %s\n"), msg);
+ received_barcode(msg);
+ }
}
diff --git a/src/cli/main.vala b/src/cli/main.vala
index a3208dd..aacb3ba 100644
--- a/src/cli/main.vala
+++ b/src/cli/main.vala
@@ -18,20 +18,23 @@ MainLoop ml;
string[] commands;
public static int main(string[] args) {
+ Intl.setlocale(LocaleCategory.ALL, "");
+ Intl.textdomain("shopsystem");
+
if (args.length == 1) {
- stdout.printf("Nothing to send.\nUsage: %s <commnds to send...>\nExample: %s \"USER 1\" \"LOGOUT\"\n", args[0], args[0]);
+ stdout.printf(_("Nothing to send.\nUsage: %s <commands to send...>\nExample: %s \"USER 1\" \"LOGOUT\"\n"), args[0], args[0]);
return 0;
}
commands = args[1:args.length];
-
+
cli = new CliImpl();
Bus.own_name(
BusType.SYSTEM,
"io.mainframe.shopsystem.Cli",
BusNameOwnerFlags.NONE,
- on_bus_aquired,
- on_name_aquired,
- () => stderr.printf("Could not aquire name\n"));
+ on_bus_acquired,
+ on_name_acquired,
+ () => stderr.printf(_("Could not acquire name\n")));
ml = new MainLoop();
@@ -40,9 +43,13 @@ public static int main(string[] args) {
return 0;
}
-void on_name_aquired() {
+void on_name_acquired() {
foreach (string cmd in commands) {
- cli.send(cmd);
+ try {
+ cli.send(cmd);
+ } catch (Error e) {
+ stderr.printf(_("Error sending command: %s"), e.message);
+ }
}
// wait a minimal amount of time, to ensure the event was sent
@@ -51,15 +58,14 @@ void on_name_aquired() {
ml.quit ();
return false;
});
- time.attach (ml.get_context ());
-
+ time.attach (ml.get_context ());
}
-void on_bus_aquired(DBusConnection con) {
+void on_bus_acquired(DBusConnection con) {
try {
- con.register_object("/io/mainframe/shopsystem/cli", cli);
+ con.register_object("/io/mainframe/shopsystem/cli", cli);
} catch(IOError e) {
- stderr.printf("Could not register service\n");
+ stderr.printf(_("Could not register service\n"));
}
-} \ No newline at end of file
+}
diff --git a/src/config/.gitignore b/src/config/.gitignore
deleted file mode 100644
index 04204c7..0000000
--- a/src/config/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-config
diff --git a/src/config/Makefile b/src/config/Makefile
deleted file mode 100644
index d93d5df..0000000
--- a/src/config/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-all: config
- @echo > /dev/null
-
-config: main.vala config.vala config-interface.vala
- valac -X -w -o $@ --pkg gio-2.0 $^
-
-clean:
- rm -rf config
-
-.PHONY: all clean
diff --git a/src/config/config-interface.vala b/src/config/config-interface.vala
index c34e3a7..369071e 100644
--- a/src/config/config-interface.vala
+++ b/src/config/config-interface.vala
@@ -15,12 +15,12 @@
[DBus (name = "io.mainframe.shopsystem.Config")]
public interface Config : Object {
- public abstract bool has_group(string group_name) throws IOError, KeyFileError;
- public abstract bool has_key(string group_name, string key) throws IOError, KeyFileError;
- public abstract string get_string(string group_name, string key) throws IOError, KeyFileError;
- public abstract bool get_boolean(string group_name, string key) throws IOError, KeyFileError;
- public abstract int get_integer(string group_name, string key) throws IOError, KeyFileError;
- public abstract int64 get_int64(string group_name, string key) throws IOError, KeyFileError;
- public abstract uint64 get_uint64(string group_name, string key) throws IOError, KeyFileError;
- public abstract double get_double(string group_name, string key) throws IOError, KeyFileError;
+ public abstract bool has_group(string group_name) throws DBusError, IOError, KeyFileError;
+ public abstract bool has_key(string group_name, string key) throws DBusError, IOError, KeyFileError;
+ public abstract string get_string(string group_name, string key) throws DBusError, IOError, KeyFileError;
+ public abstract bool get_boolean(string group_name, string key) throws DBusError, IOError, KeyFileError;
+ public abstract int get_integer(string group_name, string key) throws DBusError, IOError, KeyFileError;
+ public abstract int64 get_int64(string group_name, string key) throws DBusError, IOError, KeyFileError;
+ public abstract uint64 get_uint64(string group_name, string key) throws DBusError, IOError, KeyFileError;
+ public abstract double get_double(string group_name, string key) throws DBusError, IOError, KeyFileError;
}
diff --git a/src/config/config.vala b/src/config/config.vala
index 60fd835..bc476f4 100644
--- a/src/config/config.vala
+++ b/src/config/config.vala
@@ -23,39 +23,39 @@ public class Cfg {
this.file = new KeyFile();
this.file.load_from_file(file, KeyFileFlags.NONE);
} catch(Error e) {
- error("Could not load configuration file: %s", e.message);
+ error(_("Could not load configuration file: %s"), e.message);
}
}
- public bool has_group(string group_name) throws KeyFileError {
+ public bool has_group(string group_name) throws DBusError, IOError, KeyFileError {
return file.has_group(group_name);
}
- public bool has_key(string group_name, string key) throws KeyFileError {
+ public bool has_key(string group_name, string key) throws DBusError, IOError, KeyFileError {
return file.has_key(group_name, key);
}
- public string get_string(string group_name, string key) throws KeyFileError {
+ public string get_string(string group_name, string key) throws DBusError, IOError, KeyFileError {
return file.get_string(group_name, key);
}
- public bool get_boolean(string group_name, string key) throws KeyFileError {
+ public bool get_boolean(string group_name, string key) throws DBusError, IOError, KeyFileError {
return file.get_boolean(group_name, key);
}
- public int get_integer(string group_name, string key) throws KeyFileError {
+ public int get_integer(string group_name, string key) throws DBusError, IOError, KeyFileError {
return file.get_integer(group_name, key);
}
- public int64 get_int64(string group_name, string key) throws KeyFileError {
+ public int64 get_int64(string group_name, string key) throws DBusError, IOError, KeyFileError {
return file.get_int64(group_name, key);
}
- public uint64 get_uint64(string group_name, string key) throws KeyFileError {
+ public uint64 get_uint64(string group_name, string key) throws DBusError, IOError, KeyFileError {
return file.get_uint64(group_name, key);
}
- public double get_double(string group_name, string key) throws KeyFileError {
+ public double get_double(string group_name, string key) throws DBusError, IOError, KeyFileError {
return file.get_double(group_name, key);
}
diff --git a/src/config/main.vala b/src/config/main.vala
index 5ae15be..1a5328d 100644
--- a/src/config/main.vala
+++ b/src/config/main.vala
@@ -16,27 +16,28 @@
Cfg cfg;
public static int main(string[] args) {
- string binarylocation = File.new_for_path(args[0]).get_parent().get_path();
+ Intl.setlocale(LocaleCategory.ALL, "");
+ Intl.textdomain("shopsystem");
- cfg = new Cfg(binarylocation + "/../../ktt-shopsystem.cfg");
+ cfg = new Cfg("/etc/shopsystem/config.ini");
Bus.own_name(
BusType.SYSTEM,
"io.mainframe.shopsystem.Config",
BusNameOwnerFlags.NONE,
- on_bus_aquired,
+ on_bus_acquired,
() => {},
- () => stderr.printf("Could not aquire name\n"));
+ () => stderr.printf(_("Could not acquire name\n")));
new MainLoop().run();
return 0;
}
-void on_bus_aquired(DBusConnection con) {
+void on_bus_acquired(DBusConnection con) {
try {
con.register_object("/io/mainframe/shopsystem/config", cfg);
} catch(IOError e) {
- stderr.printf("Could not register service\n");
+ stderr.printf(_("Could not register service\n"));
}
}
diff --git a/src/curses-ui/.gitignore b/src/curses-ui/.gitignore
deleted file mode 100644
index b66c764..0000000
--- a/src/curses-ui/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-curses-ui
diff --git a/src/curses-ui/Makefile b/src/curses-ui/Makefile
deleted file mode 100644
index 1ca68cf..0000000
--- a/src/curses-ui/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-all: curses-ui
- @echo > /dev/null
-
-curses-ui: *.vala ../audio/audio-interface.vala ../scanner-session/scannersession-interface.vala
- valac -X -w -o $@ --pkg curses -X -lncursesw --pkg posix --pkg gio-2.0 $^
-
-clean:
- rm -rf curses-ui
-
-.PHONY: all clean
diff --git a/src/curses-ui/clock.vala b/src/curses-ui/clock.vala
index dd3ddcd..43ca48b 100644
--- a/src/curses-ui/clock.vala
+++ b/src/curses-ui/clock.vala
@@ -1,4 +1,5 @@
/* Copyright 2013, Sebastian Reichel <sre@ring0.de>
+ * Copyright 2018, Malte Modler <malte@malte-modler.de>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
diff --git a/src/curses-ui/curses-ui.vala b/src/curses-ui/curses-ui.vala
index ab34787..539c959 100644
--- a/src/curses-ui/curses-ui.vala
+++ b/src/curses-ui/curses-ui.vala
@@ -1,4 +1,6 @@
/* Copyright 2013, Sebastian Reichel <sre@ring0.de>
+ * Copyright 2017-2018, Johannes Rudolph <johannes.rudolph@gmx.com>
+ * Copyright 2018, Malte Modler <malte@malte-modler.de>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -21,7 +23,7 @@ public class CursesUI {
//StatusPanel statuswin;
MessageBoxOverlay mbOverlay;
- public CursesUI() {
+ public CursesUI(string configdir) {
/* unicode support */
Intl.setlocale(LocaleCategory.CTYPE, "");
@@ -37,8 +39,8 @@ public class CursesUI {
Curses.init_pair(1, Curses.Color.GREEN, Curses.Color.BLACK);
Curses.init_pair(2, Curses.Color.WHITE, Curses.Color.RED);
- /* initialize widgets */
- banner = new Logo();
+ /* initialize widgets */
+ banner = new Logo(configdir);
//statuswin = new StatusPanel();
messages = new MessageBox();
clkwin = new ClockWindow();
@@ -68,18 +70,18 @@ public class CursesUI {
//}
public void log(MessageType type, string message) {
- switch (type) {
+ switch (type) {
case MessageType.WARNING:
messages.add(message, MessageBox.WARN_COLOR);
break;
- case MessageType.ERROR:
+ case MessageType.ERROR:
messages.add(message, MessageBox.ERROR_COLOR);
break;
default:
messages.add(message, MessageBox.INFO_COLOR);
break;
}
-
+
}
public void log_overlay(string title, string message, int closeAfter) {
@@ -87,7 +89,7 @@ public class CursesUI {
Timeout.add_seconds(closeAfter, closeMbOverlay);
}
- public void dialog_open(string title, string message, int closeAfter=0) {
+ public void dialog_open(string title, string message, int closeAfter=0) {
dialog = new Dialog(message, title, closeAfter);
if (closeAfter > 0) {
Timeout.add_seconds(closeAfter, close);
@@ -102,7 +104,7 @@ public class CursesUI {
return false;
}
- bool close() {
+ bool close() {
dialog_close();
// just call me once
return false;
diff --git a/src/curses-ui/dialog.vala b/src/curses-ui/dialog.vala
index 7d2902b..e7ae0b8 100644
--- a/src/curses-ui/dialog.vala
+++ b/src/curses-ui/dialog.vala
@@ -51,7 +51,7 @@ public class Dialog {
if (countdownValue > 0) {
Timeout.add_seconds(1, decrementTitleCountdown);
- }
+ }
}
private void setTitle() {
@@ -61,7 +61,7 @@ public class Dialog {
}
int title_x = (dialogWidth-title.length)/2;
win.mvaddstr(0, title_x, title);
- win.mvaddch(0, title_x-2, Acs.RTEE);
+ win.mvaddch(0, title_x-2, Acs.RTEE);
win.mvaddch(0, title_x-1, ' ');
win.mvaddch(0, title_x+title.length, ' ');
win.mvaddch(0, title_x+title.length+1, Acs.LTEE);
@@ -70,7 +70,7 @@ public class Dialog {
win.mvaddch(0, title_x+title.length+3, Acs.HLINE);
}
- private bool decrementTitleCountdown() {
+ private bool decrementTitleCountdown() {
countdownValue--;
setTitle();
win.refresh();
diff --git a/src/curses-ui/logo.vala b/src/curses-ui/logo.vala
index dbc716d..1bb609b 100644
--- a/src/curses-ui/logo.vala
+++ b/src/curses-ui/logo.vala
@@ -1,4 +1,5 @@
/* Copyright 2013, Sebastian Reichel <sre@ring0.de>
+ * Copyright 2017-2018, Johannes Rudolph <johannes.rudolph@gmx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -18,17 +19,30 @@ using Curses;
public class Logo {
Window win;
- public Logo() {
+ public Logo(string configdir) {
win = new Window(8, COLS - 2, 0, 1);
win.bkgdset(COLOR_PAIR(1) | Attribute.BOLD);
win.addstr("\n");
- win.addstr(" _ ___ _____ ____ _ \n");
- win.addstr(" | |/ / ||_ _| / ___|| |__ ___ _ __ \n");
- win.addstr(" | ' /| __|| | \\___ \\| '_ \\ / _ \\| '_ \\ \n");
- win.addstr(" | . \\| |_ | | ___) | | | | (_) | |_) )\n");
- win.addstr(" |_|\\_\\\\__||_| |____/|_| |_|\\___/| .__/ \n");
- win.addstr(" |_| \n");
+
+ var logofilename = Path.build_filename(configdir, "logo.txt");
+ var file = File.new_for_path(logofilename);
+ if (!file.query_exists()) {
+ stderr.printf (_("File '%s' doesn't exist.\n"), file.get_path ());
+ }
+
+ try {
+ // Open file for reading and wrap returned FileInputStream into a
+ // DataInputStream, so we can read line by line
+ var dis = new DataInputStream(file.read());
+ string line;
+ // Read lines until end of file (null) is reached
+ while ((line = dis.read_line(null)) != null) {
+ win.addstr(line+"\n");
+ }
+ } catch(Error e) {
+ error (_("Error: %s"), e.message);
+ }
win.clrtobot();
diff --git a/src/curses-ui/main.vala b/src/curses-ui/main.vala
index da822a9..adeb67f 100644
--- a/src/curses-ui/main.vala
+++ b/src/curses-ui/main.vala
@@ -1,4 +1,6 @@
/* Copyright 2013, Sebastian Reichel <sre@ring0.de>
+ * Copyright 2017-2018, Johannes Rudolph <johannes.rudolph@gmx.com>
+ * Copyright 2018, Malte Modler <malte@malte-modler.de>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -22,7 +24,9 @@ private static void play(string file) {
try {
audio.play_system(file);
} catch(IOError e) {
- ui.log(MessageType.WARNING, "could not play audio: %s".printf(e.message));
+ ui.log(MessageType.WARNING, _("could not play audio: %s").printf(e.message));
+ } catch(DBusError e) {
+ ui.log(MessageType.WARNING, _("could not play audio: %s").printf(e.message));
}
}
@@ -42,31 +46,39 @@ public void log_handler(string? log_domain, LogLevelFlags flags, string message)
public static int main(string[] args) {
loop = new MainLoop();
+ Intl.setlocale(LocaleCategory.ALL, "");
+ Intl.textdomain("shopsystem");
+
/* handle unix signals */
- Unix.signal_add(Posix.SIGTERM, handle_signals);
- Unix.signal_add(Posix.SIGINT, handle_signals);
+ Unix.signal_add(Posix.Signal.TERM, handle_signals);
+ Unix.signal_add(Posix.Signal.INT, handle_signals);
try {
audio = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.AudioPlayer", "/io/mainframe/shopsystem/audio");
scanner = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.ScannerSession", "/io/mainframe/shopsystem/scanner_session");
+
+ var configdir = "/etc/shopsystem";
+ ui = new CursesUI(configdir);
} catch(IOError e) {
- error("IOError: %s\n", e.message);
+ error(_("IO Error: %s\n"), e.message);
+ } catch(DBusError e) {
+ error(_("DBus Error: %s\n"), e.message);
+ } catch(KeyFileError e) {
+ error(_("KeyFile Error: %s\n"), e.message);
}
- ui = new CursesUI();
-
Log.set_default_handler(log_handler);
scanner.msg.connect(msg_handler);
scanner.msg_overlay.connect(msg_overlay_handler);
- ui.log(MessageType.INFO, "KtT Shop System has been started");
+ ui.log(MessageType.INFO, _("Shop System has been started"));
play("startup.ogg");
/* run mainloop */
loop.run();
- ui.log(MessageType.INFO, "Stopping Shop System");
+ ui.log(MessageType.INFO, _("Stopping Shop System"));
play("shutdown.ogg");
/* leave curses mode */
diff --git a/src/curses-ui/message_box.vala b/src/curses-ui/message_box.vala
index d6823fe..70c4d10 100644
--- a/src/curses-ui/message_box.vala
+++ b/src/curses-ui/message_box.vala
@@ -41,7 +41,7 @@ public class MessageBox {
init_pair (INFO_COLOR, Color.WHITE, Color.BLACK);
init_pair (WARN_COLOR, Color.YELLOW, Color.BLACK);
- init_pair (ERROR_COLOR, Color.RED, Color.BLACK);
+ init_pair (ERROR_COLOR, Color.RED, Color.BLACK);
}
public void add(string msg, short color_pair = MessageBox.INFO_COLOR) {
@@ -49,7 +49,7 @@ public class MessageBox {
if(now.get_day_of_year() != last.get_day_of_year() || now.get_year() != last.get_year()) {
string curtime = now.format("%Y-%m-%d");
- subwin.addstr("\nDate Changed: " + curtime);
+ subwin.addstr(_("\nDate Changed: ") + curtime);
}
last = now;
diff --git a/src/curses-ui/message_box_overlay.vala b/src/curses-ui/message_box_overlay.vala
index 721ab06..7b5a09b 100644
--- a/src/curses-ui/message_box_overlay.vala
+++ b/src/curses-ui/message_box_overlay.vala
@@ -37,13 +37,13 @@ public class MessageBoxOverlay {
Timeout.add_seconds(1, decrementTitleCountdown);
}
- private void setTitle() {
+ private void setTitle() {
var title = " === %s (%d) === ".printf(dialogTitle, countdownValue);
int title_x = (COLS - title.length)/2;
- win.mvaddstr(0, title_x, title);
+ win.mvaddstr(0, title_x, title);
}
- private bool decrementTitleCountdown() {
+ private bool decrementTitleCountdown() {
countdownValue--;
setTitle();
win.refresh();
diff --git a/src/curses-ui/numbers.vala b/src/curses-ui/numbers.vala
index 200cf63..5cbcd23 100644
--- a/src/curses-ui/numbers.vala
+++ b/src/curses-ui/numbers.vala
@@ -1,4 +1,6 @@
/* Copyright 2013, Sebastian Reichel <sre@ring0.de>
+ * Copyright 2017-2018, Johannes Rudolph <johannes.rudolph@gmx.com>
+ * Copyright 2018, Malte Modler <malte@malte-modler.de>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
diff --git a/src/database/.gitignore b/src/database/.gitignore
deleted file mode 100644
index aa0d57e..0000000
--- a/src/database/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-database
diff --git a/src/database/Makefile b/src/database/Makefile
deleted file mode 100644
index fac0f08..0000000
--- a/src/database/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-all: database
- @echo > /dev/null
-
-database: main.vala database.vala db-interface.vala ../config/config-interface.vala ../price.vapi
- valac -X -w -o $@ --pkg sqlite3 --pkg gee-0.8 --pkg gio-2.0 $^
-
-clean:
- rm -rf db
-
-.PHONY: all clean
diff --git a/src/database/database.vala b/src/database/database.vala
index 0d3d1ff..52c5dd2 100644
--- a/src/database/database.vala
+++ b/src/database/database.vala
@@ -1,4 +1,5 @@
/* Copyright 2012-2013, Sebastian Reichel <sre@ring0.de>
+ * Copyright 2017-2018, Johannes Rudolph <johannes.rudolph@gmx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -24,7 +25,7 @@ public class DataBase : Object {
int rc = db.prepare_v2(query, -1, out stmt);
if(rc != Sqlite.OK) {
- error("could not prepare statement: %s", query);
+ error(_("Error: could not prepare statement: %s"), query);
}
}
@@ -77,7 +78,7 @@ public class DataBase : Object {
rc = Sqlite.Database.open(file, out db);
if(rc != Sqlite.OK) {
- error("could not open database!");
+ error(_("Error: could not open database!"));
}
/* setup queries */
@@ -127,6 +128,7 @@ public class DataBase : Object {
queries["user_disable"] = "UPDATE users SET disabled = ? WHERE id = ?";
queries["last_timestamp"] = "SELECT timestamp FROM sales ORDER BY timestamp DESC LIMIT 1";
queries["category_list"] = "SELECT id, name FROM categories";
+ queries["category_add"] = "INSERT INTO categories('name') VALUES (?)";
queries["supplier_list"] = "SELECT id, name, postal_code, city, street, phone, website FROM supplier";
queries["supplier_get"] = "SELECT id, name, postal_code, city, street, phone, website FROM supplier WHERE id = ?";
queries["supplier_add"] = "INSERT INTO supplier('name', 'postal_code', 'city', 'street', 'phone', 'website') VALUES (?, ?, ?, ?, ?, ?)";
@@ -139,6 +141,10 @@ public class DataBase : Object {
queries["alias_ean_add"] = "INSERT OR IGNORE INTO ean_aliases (id, real_ean) VALUES (?, ?)";
queries["alias_ean_get"] = "SELECT real_ean FROM ean_aliases WHERE id = ?";
queries["alias_ean_list"] = "SELECT id, real_ean FROM ean_aliases ORDER BY id ASC";
+ queries["userid_rfid"] = "SELECT user FROM rfid_users WHERE rfid = ?";
+ queries["rfid_userid"] = "SELECT rfid FROM rfid_users WHERE user = ?";
+ queries["rfid_insert"] = "INSERT OR REPLACE INTO rfid_users ('user','rfid') VALUES (?,?)";
+ queries["rfid_delete_user"] = "DELETE FROM rfid_users WHERE user = ?";
/* compile queries into statements */
foreach(var entry in queries.entries) {
@@ -151,7 +157,7 @@ public class DataBase : Object {
#endif
}
- public GLib.HashTable<string,string> get_products() {
+ public GLib.HashTable<string,string> get_products() throws DBusError, IOError, DatabaseError {
var result = new GLib.HashTable<string,string>(null, null);
statements["products"].reset();
@@ -274,13 +280,13 @@ public class DataBase : Object {
}
#endif
- public StockEntry[] get_stock() {
- StockEntry[] result = {};
+ public DetailedProduct[] get_stock() throws DBusError, IOError, DatabaseError {
+ DetailedProduct[] result = {};
statements["stock_status"].reset();
while(statements["stock_status"].step() == Sqlite.ROW) {
- StockEntry entry = {
- statements["stock_status"].column_text(0),
+ DetailedProduct entry = {
+ uint64.parse(statements["stock_status"].column_text(0)),
statements["stock_status"].column_text(1),
statements["stock_status"].column_text(2),
statements["stock_status"].column_int(3),
@@ -294,7 +300,23 @@ public class DataBase : Object {
return result;
}
- public PriceEntry[] get_prices(uint64 product) {
+ public DetailedProduct get_product_for_ean(uint64 ean) throws DBusError, IOError, DatabaseError {
+ DetailedProduct p = {};
+
+ try {
+ p.ean = ean_alias_get(ean);
+ p.name = get_product_name(p.ean);
+ p.category = get_product_category(p.ean);
+ p.amount = get_product_amount(p.ean);
+ p.memberprice = get_product_price(1, p.ean);
+ p.guestprice = get_product_price(0, p.ean);
+ return p;
+ } catch(DatabaseError e){
+ throw e;
+ }
+ }
+
+ public PriceEntry[] get_prices(uint64 product) throws DBusError, IOError, DatabaseError {
PriceEntry[] result = {};
statements["prices"].reset();
@@ -312,7 +334,7 @@ public class DataBase : Object {
return result;
}
- public RestockEntry[] get_restocks(uint64 product, bool descending) {
+ public RestockEntry[] get_restocks(uint64 product, bool descending) throws DBusError, IOError, DatabaseError {
RestockEntry[] result = {};
var statement = statements[descending ? "restocks_desc" : "restocks_asc"];
@@ -336,7 +358,7 @@ public class DataBase : Object {
return result;
}
- public bool buy(int32 user, uint64 article) throws DatabaseError {
+ public bool buy(int32 user, uint64 article) throws DBusError, IOError, DatabaseError {
int rc = 0;
int64 timestamp = (new DateTime.now_utc()).to_unix();
@@ -347,12 +369,12 @@ public class DataBase : Object {
rc = statements["purchase"].step();
if(rc != Sqlite.DONE)
- throw new DatabaseError.INTERNAL_ERROR("internal error: %d", rc);
+ throw new DatabaseError.INTERNAL_ERROR(_("internal error: %d"), rc);
return true;
}
- public string get_product_name(uint64 article) throws DatabaseError {
+ public string get_product_name(uint64 article) throws DBusError, IOError, DatabaseError {
statements["product_name"].reset();
statements["product_name"].bind_text(1, "%llu".printf(article));
@@ -362,13 +384,13 @@ public class DataBase : Object {
case Sqlite.ROW:
return statements["product_name"].column_text(0);
case Sqlite.DONE:
- throw new DatabaseError.PRODUCT_NOT_FOUND("unknown product: %llu", article);
+ throw new DatabaseError.PRODUCT_NOT_FOUND(_("unknown product: %llu"), article);
default:
- throw new DatabaseError.INTERNAL_ERROR("internal error: %d", rc);
+ throw new DatabaseError.INTERNAL_ERROR(_("internal error: %d"), rc);
}
}
- public string get_product_category(uint64 article) throws DatabaseError {
+ public string get_product_category(uint64 article) throws DBusError, IOError, DatabaseError {
statements["product_category"].reset();
statements["product_category"].bind_text(1, "%llu".printf(article));
@@ -378,13 +400,13 @@ public class DataBase : Object {
case Sqlite.ROW:
return statements["product_category"].column_text(0);
case Sqlite.DONE:
- throw new DatabaseError.PRODUCT_NOT_FOUND("unknown product: %llu", article);
+ throw new DatabaseError.PRODUCT_NOT_FOUND(_("unknown product: %llu"), article);
default:
- throw new DatabaseError.INTERNAL_ERROR("internal error: %d", rc);
+ throw new DatabaseError.INTERNAL_ERROR(_("internal error: %d"), rc);
}
}
- public int get_product_amount(uint64 article) throws DatabaseError {
+ public int get_product_amount(uint64 article) throws DBusError, IOError, DatabaseError {
statements["product_amount"].reset();
statements["product_amount"].bind_text(1, "%llu".printf(article));
@@ -394,13 +416,13 @@ public class DataBase : Object {
case Sqlite.ROW:
return statements["product_amount"].column_int(0);
case Sqlite.DONE:
- throw new DatabaseError.PRODUCT_NOT_FOUND("unknown product: %llu", article);
+ throw new DatabaseError.PRODUCT_NOT_FOUND(_("unknown product: %llu"), article);
default:
- throw new DatabaseError.INTERNAL_ERROR("internal error: %d", rc);
+ throw new DatabaseError.INTERNAL_ERROR(_("internal error: %d"), rc);
}
}
- public bool get_product_deprecated(uint64 article) throws DatabaseError {
+ public bool get_product_deprecated(uint64 article) throws DBusError, IOError, DatabaseError {
statements["product_deprecated"].reset();
statements["product_deprecated"].bind_text(1, "%llu".printf(article));
@@ -410,13 +432,13 @@ public class DataBase : Object {
case Sqlite.ROW:
return statements["product_deprecated"].column_int(0) == 1;
case Sqlite.DONE:
- throw new DatabaseError.PRODUCT_NOT_FOUND("unknown product: %llu", article);
+ throw new DatabaseError.PRODUCT_NOT_FOUND(_("unknown product: %llu"), article);
default:
- throw new DatabaseError.INTERNAL_ERROR("internal error: %d", rc);
+ throw new DatabaseError.INTERNAL_ERROR(_("internal error: %d"), rc);
}
}
- public void product_deprecate(uint64 article, bool value) throws DatabaseError {
+ public void product_deprecate(uint64 article, bool value) throws DBusError, IOError, DatabaseError {
int rc;
statements["product_set_deprecated"].reset();
@@ -425,10 +447,10 @@ public class DataBase : Object {
rc = statements["product_set_deprecated"].step();
if(rc != Sqlite.DONE)
- throw new DatabaseError.INTERNAL_ERROR("internal error: %d", rc);
+ throw new DatabaseError.INTERNAL_ERROR(_("internal error: %d"), rc);
}
- public Price get_product_price(int user, uint64 article) throws DatabaseError {
+ public Price get_product_price(int user, uint64 article) throws DBusError, IOError, DatabaseError {
int64 timestamp = (new DateTime.now_utc()).to_unix();
bool member = user != 0;
@@ -445,13 +467,13 @@ public class DataBase : Object {
else
return statements["price"].column_int(1);
case Sqlite.DONE:
- throw new DatabaseError.PRODUCT_NOT_FOUND("unknown product: %llu", article);
+ throw new DatabaseError.PRODUCT_NOT_FOUND(_("unknown product: %llu"), article);
default:
- throw new DatabaseError.INTERNAL_ERROR("internal error: %d", rc);
+ throw new DatabaseError.INTERNAL_ERROR(_("internal error: %d"), rc);
}
}
- public string undo(int32 user) throws DatabaseError {
+ public string undo(int32 user) throws DBusError, IOError, DatabaseError {
uint64 pid = 0;
int rc = 0;
string pname;
@@ -464,12 +486,12 @@ public class DataBase : Object {
case Sqlite.ROW:
pid = uint64.parse(statements["last_purchase"].column_text(0));
pname = get_product_name(pid);
- write_to_log("Remove purchase of %s", pname);
+ stderr.printf(_("Remove purchase of %s"), pname);
break;
case Sqlite.DONE:
- throw new DatabaseError.PRODUCT_NOT_FOUND("undo not possible without purchases");
+ throw new DatabaseError.PRODUCT_NOT_FOUND(_("undo not possible without purchases"));
default:
- throw new DatabaseError.INTERNAL_ERROR("internal error: %d", rc);
+ throw new DatabaseError.INTERNAL_ERROR(_("internal error: %d"), rc);
}
statements["undo"].reset();
@@ -477,12 +499,12 @@ public class DataBase : Object {
rc = statements["undo"].step();
if(rc != Sqlite.DONE)
- throw new DatabaseError.INTERNAL_ERROR("internal error: %d", rc);
+ throw new DatabaseError.INTERNAL_ERROR(_("internal error: %d"), rc);
return pname;
}
- public void restock(int user, uint64 product, uint amount, uint price, int supplier, int64 best_before_date) throws DatabaseError {
+ public void restock(int user, uint64 product, uint amount, uint price, int supplier, int64 best_before_date) throws DBusError, IOError, DatabaseError {
int rc = 0;
int64 timestamp = (new DateTime.now_utc()).to_unix();
@@ -504,10 +526,10 @@ public class DataBase : Object {
rc = statements["stock"].step();
if(rc != Sqlite.DONE)
- throw new DatabaseError.INTERNAL_ERROR("internal error: %d", rc);
+ throw new DatabaseError.INTERNAL_ERROR(_("internal error: %d"), rc);
}
- public void new_product(uint64 id, string name, int category, int memberprice, int guestprice) throws DatabaseError {
+ public void new_product(uint64 id, string name, int category, int memberprice, int guestprice) throws DBusError, IOError, DatabaseError {
statements["product_create"].reset();
statements["product_create"].bind_text(1, @"$id");
statements["product_create"].bind_text(2, name);
@@ -518,13 +540,13 @@ public class DataBase : Object {
if(rc == Sqlite.CONSTRAINT) {
throw new DatabaseError.CONSTRAINT_FAILED(db.errmsg());
} else if(rc != Sqlite.DONE) {
- throw new DatabaseError.INTERNAL_ERROR("internal error: %d", rc);
+ throw new DatabaseError.INTERNAL_ERROR(_("internal error: %d"), rc);
}
new_price(id, 0, memberprice, guestprice);
}
- public void new_price(uint64 product, int64 timestamp, int memberprice, int guestprice) throws DatabaseError {
+ public void new_price(uint64 product, int64 timestamp, int memberprice, int guestprice) throws DBusError, IOError, DatabaseError {
statements["price_create"].reset();
statements["price_create"].bind_text(1, @"$product");
statements["price_create"].bind_int64(2, timestamp);
@@ -533,11 +555,11 @@ public class DataBase : Object {
int rc = statements["price_create"].step();
if(rc != Sqlite.DONE) {
- throw new DatabaseError.INTERNAL_ERROR("internal error: %d", rc);
+ throw new DatabaseError.INTERNAL_ERROR(_("internal error: %d"), rc);
}
}
- public bool check_user_password(int32 user, string password) {
+ public bool check_user_password(int32 user, string password) throws DBusError, IOError, DatabaseError {
statements["password_get"].reset();
statements["password_get"].bind_int(1, user);
@@ -551,7 +573,7 @@ public class DataBase : Object {
}
}
- public void set_user_password(int32 user, string password) throws DatabaseError {
+ public void set_user_password(int32 user, string password) throws DBusError, IOError, DatabaseError {
var pwhash = Checksum.compute_for_string(ChecksumType.SHA256, password);
int rc;
@@ -560,7 +582,7 @@ public class DataBase : Object {
statements["user_auth_create"].bind_int(1, user);
rc = statements["user_auth_create"].step();
if(rc != Sqlite.DONE)
- throw new DatabaseError.INTERNAL_ERROR("internal error: %d", rc);
+ throw new DatabaseError.INTERNAL_ERROR(_("internal error: %d"), rc);
/* set password */
statements["password_set"].reset();
@@ -568,31 +590,31 @@ public class DataBase : Object {
statements["password_set"].bind_int(2, user);
rc = statements["password_set"].step();
if(rc != Sqlite.DONE)
- throw new DatabaseError.INTERNAL_ERROR("internal error: %d", rc);
+ throw new DatabaseError.INTERNAL_ERROR(_("internal error: %d"), rc);
}
- public void set_sessionid(int user, string sessionid) throws DatabaseError {
+ public void set_sessionid(int user, string sessionid) throws DBusError, IOError, DatabaseError {
statements["session_set"].reset();
statements["session_set"].bind_text(1, sessionid);
statements["session_set"].bind_int(2, user);
int rc = statements["session_set"].step();
if(rc != Sqlite.DONE)
- throw new DatabaseError.INTERNAL_ERROR("internal error: %d", rc);
+ throw new DatabaseError.INTERNAL_ERROR(_("internal error: %d"), rc);
}
- public int get_user_by_sessionid(string sessionid) throws DatabaseError {
+ public int get_user_by_sessionid(string sessionid) throws DBusError, IOError, DatabaseError {
statements["session_get"].reset();
statements["session_get"].bind_text(1, sessionid);
if(statements["session_get"].step() == Sqlite.ROW) {
return statements["session_get"].column_int(0);
} else {
- throw new DatabaseError.SESSION_NOT_FOUND("No such session available in database!");
+ throw new DatabaseError.SESSION_NOT_FOUND(_("No such session available in database!"));
}
}
- public UserInfo get_user_info(int user) throws DatabaseError {
+ public UserInfo get_user_info(int user) throws DBusError, IOError, DatabaseError {
var result = UserInfo();
statements["userinfo"].reset();
statements["userinfo"].bind_int(1, user);
@@ -613,15 +635,26 @@ public class DataBase : Object {
result.soundTheme = statements["userinfo"].column_text(10);
result.joined_at = statements["userinfo"].column_int64(11);
} else if(rc == Sqlite.DONE) {
- throw new DatabaseError.USER_NOT_FOUND("user not found");
+ throw new DatabaseError.USER_NOT_FOUND(_("user not found"));
} else {
- throw new DatabaseError.INTERNAL_ERROR("internal error: %d", rc);
+ throw new DatabaseError.INTERNAL_ERROR(_("internal error: %d"), rc);
+ }
+
+ statements["rfid_userid"].reset();
+ statements["rfid_userid"].bind_int(1, user);
+ rc = statements["rfid_userid"].step();
+
+ string[] rfid = {};
+ while(rc == Sqlite.ROW) {
+ rfid += statements["rfid_userid"].column_text(0);
+ rc = statements["rfid_userid"].step();
}
+ result.rfid = rfid;
return result;
}
- public UserAuth get_user_auth(int user) throws DatabaseError {
+ public UserAuth get_user_auth(int user) throws DBusError, IOError, DatabaseError {
var result = UserAuth();
result.id = user;
result.superuser = false;
@@ -641,13 +674,13 @@ public class DataBase : Object {
} else if(rc == Sqlite.DONE) {
/* entry not found, we return defaults */
} else {
- throw new DatabaseError.INTERNAL_ERROR("internal error: %d", rc);
+ throw new DatabaseError.INTERNAL_ERROR(_("internal error: %d"), rc);
}
return result;
}
- public void set_user_auth(UserAuth auth) throws DatabaseError {
+ public void set_user_auth(UserAuth auth) throws DBusError, IOError, DatabaseError {
int rc;
/* create user auth line if not existing */
@@ -655,7 +688,7 @@ public class DataBase : Object {
statements["user_auth_create"].bind_int(1, auth.id);
rc = statements["user_auth_create"].step();
if(rc != Sqlite.DONE)
- throw new DatabaseError.INTERNAL_ERROR("internal error: %d", rc);
+ throw new DatabaseError.INTERNAL_ERROR(_("internal error: %d"), rc);
/* set authentication */
statements["userauth_set"].reset();
@@ -666,21 +699,21 @@ public class DataBase : Object {
rc = statements["userauth_set"].step();
if(rc != Sqlite.DONE)
- throw new DatabaseError.INTERNAL_ERROR("internal error: %d", rc);
+ throw new DatabaseError.INTERNAL_ERROR(_("internal error: %d"), rc);
}
- public string get_username(int user) throws DatabaseError {
+ public string get_username(int user) throws DBusError, IOError, DatabaseError {
statements["username"].reset();
statements["username"].bind_int(1, user);
if(statements["username"].step() == Sqlite.ROW) {
return statements["username"].column_text(0)+" "+statements["username"].column_text(1);
} else {
- throw new DatabaseError.USER_NOT_FOUND("No such user available in database!");
+ throw new DatabaseError.USER_NOT_FOUND(_("No such user available in database!"));
}
}
- public string get_user_theme(int user, string fallback) throws DatabaseError {
+ public string get_user_theme(int user, string fallback) throws DBusError, IOError, DatabaseError {
statements["user_theme_get"].reset();
statements["user_theme_get"].bind_text(1, fallback);
statements["user_theme_get"].bind_int(2, user);
@@ -688,11 +721,11 @@ public class DataBase : Object {
if(statements["user_theme_get"].step() == Sqlite.ROW) {
return statements["user_theme_get"].column_text(0);
} else {
- throw new DatabaseError.USER_NOT_FOUND("No such user available in database!");
+ throw new DatabaseError.USER_NOT_FOUND(_("No such user available in database!"));
}
}
- public void set_userTheme(int user, string userTheme) throws DatabaseError {
+ public void set_userTheme(int user, string userTheme) throws DBusError, IOError, DatabaseError {
statements["user_theme_set"].reset();
if (userTheme == "") {
statements["user_theme_set"].bind_null(1);
@@ -703,10 +736,10 @@ public class DataBase : Object {
int rc = statements["user_theme_set"].step();
if(rc != Sqlite.DONE)
- throw new DatabaseError.INTERNAL_ERROR("internal error: %d", rc);
+ throw new DatabaseError.INTERNAL_ERROR(_("internal error: %d"), rc);
}
- public InvoiceEntry[] get_invoice(int user, int64 from=0, int64 to=-1) throws DatabaseError {
+ public InvoiceEntry[] get_invoice(int user, int64 from=0, int64 to=-1) throws DBusError, IOError, DatabaseError {
InvoiceEntry[] result = {};
if(to == -1) {
@@ -731,13 +764,13 @@ public class DataBase : Object {
}
if(rc != Sqlite.DONE) {
- throw new DatabaseError.INTERNAL_ERROR("internal error: %d", rc);
+ throw new DatabaseError.INTERNAL_ERROR(_("internal error: %d"), rc);
}
return result;
}
- public int64 get_first_purchase(int user) {
+ public int64 get_first_purchase(int user) throws DBusError, IOError, DatabaseError {
statements["purchase_first"].reset();
statements["purchase_first"].bind_int(1, user);
@@ -747,7 +780,7 @@ public class DataBase : Object {
return 0;
}
- public int64 get_last_purchase(int user) {
+ public int64 get_last_purchase(int user) throws DBusError, IOError, DatabaseError {
statements["purchase_last"].reset();
statements["purchase_last"].bind_int(1, user);
@@ -757,7 +790,7 @@ public class DataBase : Object {
return 0;
}
- public StatsInfo get_stats_info() {
+ public StatsInfo get_stats_info() throws DBusError, IOError, DatabaseError {
var result = StatsInfo();
DateTime now = new DateTime.now_local();
@@ -832,7 +865,7 @@ public class DataBase : Object {
return result;
}
- public int[] get_member_ids() {
+ public int[] get_member_ids() throws DBusError, IOError, DatabaseError {
int[] result = {};
statements["user_get_ids"].reset();
@@ -842,7 +875,7 @@ public class DataBase : Object {
return result;
}
- public int[] get_system_member_ids() {
+ public int[] get_system_member_ids() throws DBusError, IOError, DatabaseError {
int[] result = {};
statements["system_user_get_ids"].reset();
@@ -852,7 +885,7 @@ public class DataBase : Object {
return result;
}
- public void user_disable(int user, bool value) throws DatabaseError {
+ public void user_disable(int user, bool value) throws DBusError, IOError, DatabaseError {
int rc;
/* create user auth line if not existing */
@@ -860,7 +893,7 @@ public class DataBase : Object {
statements["user_auth_create"].bind_int(1, user);
rc = statements["user_auth_create"].step();
if(rc != Sqlite.DONE)
- throw new DatabaseError.INTERNAL_ERROR("internal error: %d", rc);
+ throw new DatabaseError.INTERNAL_ERROR(_("internal error: %d"), rc);
/* set disabled flag */
statements["user_disable"].reset();
@@ -868,10 +901,10 @@ public class DataBase : Object {
statements["user_disable"].bind_int(2, user);
rc = statements["user_disable"].step();
if(rc != Sqlite.DONE)
- throw new DatabaseError.INTERNAL_ERROR("internal error: %d", rc);
+ throw new DatabaseError.INTERNAL_ERROR(_("internal error: %d"), rc);
}
- public void user_replace(UserInfo u) throws DatabaseError {
+ public void user_replace(UserInfo u) throws DBusError, IOError, DatabaseError {
statements["user_replace"].reset();
statements["user_replace"].bind_int(1, u.id);
statements["user_replace"].bind_text(2, u.email);
@@ -889,32 +922,47 @@ public class DataBase : Object {
int rc = statements["user_replace"].step();
if(rc != Sqlite.DONE)
- throw new DatabaseError.INTERNAL_ERROR("internal error: %d", rc);
+ throw new DatabaseError.INTERNAL_ERROR(_("internal error: %d"), rc);
+
+ statements["rfid_delete_user"].reset();
+ statements["rfid_delete_user"].bind_int(1, u.id);
+ rc = statements["rfid_delete_user"].step();
+ if(rc != Sqlite.DONE)
+ throw new DatabaseError.INTERNAL_ERROR(_("internal error: %d"), rc);
+
+ foreach (string rfid in u.rfid) {
+ statements["rfid_insert"].reset();
+ statements["rfid_insert"].bind_int(1, u.id);
+ statements["rfid_insert"].bind_text(2, rfid);
+ rc = statements["rfid_insert"].step();
+ if(rc != Sqlite.DONE)
+ throw new DatabaseError.INTERNAL_ERROR(_("internal error: %d"), rc);
+ }
}
- public bool user_is_disabled(int user) throws DatabaseError {
+ public bool user_is_disabled(int user) throws DBusError, IOError, DatabaseError {
return get_user_info(user).disabled;
}
- public bool user_exists(int user) throws DatabaseError {
+ public bool user_exists(int user) throws DBusError, IOError, DatabaseError {
if(user in get_member_ids())
return true;
return false;
}
- public bool user_equals(UserInfo u) throws DatabaseError {
+ public bool user_equals(UserInfo u) throws DBusError, IOError, DatabaseError {
var dbu = get_user_info(u.id);
return u.equals(dbu);
}
- public int64 get_timestamp_of_last_purchase() {
+ public int64 get_timestamp_of_last_purchase() throws DBusError, IOError, DatabaseError {
statements["last_timestamp"].reset();
if(statements["last_timestamp"].step() != Sqlite.ROW)
return 0;
return statements["last_timestamp"].column_int64(0);
}
- public Category[] get_category_list() {
+ public Category[] get_category_list() throws DBusError, IOError, DatabaseError {
Category[] result = {};
statements["category_list"].reset();
@@ -930,7 +978,24 @@ public class DataBase : Object {
return result;
}
- public Supplier[] get_supplier_list() {
+ public void add_category(string name) throws DBusError, IOError, DatabaseError {
+ /* check if category already exists */
+ foreach(var c in get_category_list()) {
+ if(name == c.name) {
+ return;
+ }
+ }
+
+ statements["category_add"].reset();
+ statements["category_add"].bind_text(1, name);
+ int rc = statements["category_add"].step();
+
+ if(rc != Sqlite.DONE) {
+ throw new DatabaseError.INTERNAL_ERROR(_("internal error: %d"), rc);
+ }
+ }
+
+ public Supplier[] get_supplier_list() throws DBusError, IOError, DatabaseError {
Supplier[] result = {};
statements["supplier_list"].reset();
@@ -951,7 +1016,7 @@ public class DataBase : Object {
return result;
}
- public Supplier get_supplier(int id) {
+ public Supplier get_supplier(int id) throws DBusError, IOError, DatabaseError {
Supplier result = Supplier();
statements["supplier_get"].reset();
@@ -978,7 +1043,7 @@ public class DataBase : Object {
return result;
}
- public void add_supplier(string name, string postal_code, string city, string street, string phone, string website) throws DatabaseError {
+ public void add_supplier(string name, string postal_code, string city, string street, string phone, string website) throws DBusError, IOError, DatabaseError {
statements["supplier_add"].reset();
statements["supplier_add"].bind_text(1, name);
statements["supplier_add"].bind_text(2, postal_code);
@@ -989,11 +1054,11 @@ public class DataBase : Object {
int rc = statements["supplier_add"].step();
if(rc != Sqlite.DONE) {
- throw new DatabaseError.INTERNAL_ERROR("internal error: %d", rc);
+ throw new DatabaseError.INTERNAL_ERROR(_("internal error: %d"), rc);
}
}
- public int[] get_users_with_sales(int64 timestamp_from, int64 timestamp_to) {
+ public int[] get_users_with_sales(int64 timestamp_from, int64 timestamp_to) throws DBusError, IOError, DatabaseError {
var result = new int[0];
statements["users_with_sales"].reset();
statements["users_with_sales"].bind_int64(1, timestamp_from);
@@ -1006,7 +1071,7 @@ public class DataBase : Object {
return result;
}
- public Price get_user_invoice_sum(int user, int64 timestamp_from, int64 timestamp_to) {
+ public Price get_user_invoice_sum(int user, int64 timestamp_from, int64 timestamp_to) throws DBusError, IOError, DatabaseError {
Price result = 0;
statements["user_invoice_sum"].reset();
@@ -1020,7 +1085,7 @@ public class DataBase : Object {
return result;
}
- public Price cashbox_status() {
+ public Price cashbox_status() throws DBusError, IOError, DatabaseError {
Price result = 0;
statements["cashbox_status"].reset();
@@ -1031,7 +1096,7 @@ public class DataBase : Object {
return result;
}
- public void cashbox_add(int user, Price amount, int64 timestamp) throws DatabaseError {
+ public void cashbox_add(int user, Price amount, int64 timestamp) throws DBusError, IOError, DatabaseError {
statements["cashbox_add"].reset();
statements["cashbox_add"].bind_int(1, user);
statements["cashbox_add"].bind_int(2, amount);
@@ -1040,11 +1105,11 @@ public class DataBase : Object {
int rc = statements["cashbox_add"].step();
if(rc != Sqlite.DONE) {
- throw new DatabaseError.INTERNAL_ERROR("internal error: %d", rc);
+ throw new DatabaseError.INTERNAL_ERROR(_("internal error: %d"), rc);
}
}
- public CashboxDiff[] cashbox_history() {
+ public CashboxDiff[] cashbox_history() throws DBusError, IOError, DatabaseError {
CashboxDiff[] result = {};
statements["cashbox_history"].reset();
@@ -1062,7 +1127,7 @@ public class DataBase : Object {
return result;
}
- public CashboxDiff[] cashbox_changes(int64 start, int64 stop) {
+ public CashboxDiff[] cashbox_changes(int64 start, int64 stop) throws DBusError, IOError, DatabaseError {
CashboxDiff[] result = {};
statements["cashbox_changes"].reset();
@@ -1082,7 +1147,7 @@ public class DataBase : Object {
return result;
}
- public void ean_alias_add(uint64 ean, uint64 real_ean) throws DatabaseError {
+ public void ean_alias_add(uint64 ean, uint64 real_ean) throws DBusError, IOError, DatabaseError {
statements["alias_ean_add"].reset();
statements["alias_ean_add"].bind_text(1, "%llu".printf(ean));
statements["alias_ean_add"].bind_text(2, "%llu".printf(real_ean));
@@ -1090,11 +1155,11 @@ public class DataBase : Object {
int rc = statements["alias_ean_add"].step();
if(rc != Sqlite.DONE) {
- throw new DatabaseError.INTERNAL_ERROR("internal error: %d", rc);
+ throw new DatabaseError.INTERNAL_ERROR(_("internal error: %d"), rc);
}
}
- public uint64 ean_alias_get(uint64 ean) {
+ public uint64 ean_alias_get(uint64 ean) throws DBusError, IOError, DatabaseError {
uint64 result = ean;
statements["alias_ean_get"].reset();
@@ -1106,7 +1171,7 @@ public class DataBase : Object {
return result;
}
- public EanAlias[] ean_alias_list() {
+ public EanAlias[] ean_alias_list() throws DBusError, IOError, DatabaseError {
EanAlias[] result = {};
statements["alias_ean_list"].reset();
@@ -1131,12 +1196,12 @@ public class DataBase : Object {
return 1;
}
- public BestBeforeEntry?[] bestbeforelist() {
+ public BestBeforeEntry?[] bestbeforelist() throws DBusError, IOError, DatabaseError {
var bbdlist = new GLib.GenericArray<BestBeforeEntry?>();
foreach(var product in get_stock()) {
var amount = product.amount;
- var pid = uint64.parse(product.id);
+ var pid = product.ean;
if(amount <= 0)
continue;
@@ -1160,4 +1225,20 @@ public class DataBase : Object {
return bbdlist.data;
}
+
+ public int get_userid_for_rfid(string rfid) throws DBusError, IOError, DatabaseError {
+ statements["userid_rfid"].reset();
+ statements["userid_rfid"].bind_text(1, rfid);
+
+ int rc = statements["userid_rfid"].step();
+
+ switch(rc) {
+ case Sqlite.ROW:
+ return statements["userid_rfid"].column_int(0);
+ case Sqlite.DONE:
+ throw new DatabaseError.RFID_NOT_FOUND(_("unknown rfid: %s"), rfid);
+ default:
+ throw new DatabaseError.INTERNAL_ERROR(_("internal error: %d"), rc);
+ }
+ }
}
diff --git a/src/database/db-interface.vala b/src/database/db-interface.vala
index ac8c215..f2d3e87 100644
--- a/src/database/db-interface.vala
+++ b/src/database/db-interface.vala
@@ -1,4 +1,5 @@
/* Copyright 2013, Sebastian Reichel <sre@ring0.de>
+ * Copyright 2017-2018, Johannes Rudolph <johannes.rudolph@gmx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -15,56 +16,61 @@
[DBus (name = "io.mainframe.shopsystem.Database")]
public interface Database : Object {
- public abstract StockEntry[] get_stock() throws IOError;
- public abstract PriceEntry[] get_prices(uint64 product) throws IOError;
- public abstract RestockEntry[] get_restocks(uint64 product, bool descending) throws IOError;
- public abstract bool buy(int32 user, uint64 article) throws IOError, DatabaseError;
- public abstract string get_product_name(uint64 article) throws IOError, DatabaseError;
- public abstract string get_product_category(uint64 article) throws IOError, DatabaseError;
- public abstract int get_product_amount(uint64 article) throws IOError, DatabaseError;
- public abstract bool get_product_deprecated(uint64 article) throws IOError, DatabaseError;
- public abstract void product_deprecate(uint64 article, bool value) throws IOError, DatabaseError;
- public abstract Price get_product_price(int user, uint64 article) throws IOError, DatabaseError;
- public abstract string undo(int32 user) throws IOError, DatabaseError;
- public abstract void restock(int user, uint64 product, uint amount, uint price, int supplier, int64 best_before_date) throws IOError, DatabaseError;
- public abstract void new_product(uint64 id, string name, int category, int memberprice, int guestprice) throws IOError, DatabaseError;
- public abstract void new_price(uint64 product, int64 timestamp, int memberprice, int guestprice) throws IOError, DatabaseError;
- public abstract bool check_user_password(int32 user, string password) throws IOError;
- public abstract void set_user_password(int32 user, string password) throws IOError, DatabaseError;
- public abstract void set_sessionid(int user, string sessionid) throws IOError, DatabaseError;
- public abstract void set_userTheme(int user, string userTheme) throws IOError, DatabaseError;
- public abstract int get_user_by_sessionid(string sessionid) throws IOError, DatabaseError;
- public abstract UserInfo get_user_info(int user) throws IOError, DatabaseError;
- public abstract UserAuth get_user_auth(int user) throws IOError, DatabaseError;
- public abstract void set_user_auth(UserAuth auth) throws IOError, DatabaseError;
- public abstract string get_username(int user) throws IOError, DatabaseError;
- public abstract string get_user_theme(int user, string fallback) throws IOError, DatabaseError;
- public abstract InvoiceEntry[] get_invoice(int user, int64 from=0, int64 to=-1) throws IOError, DatabaseError;
- public abstract int64 get_first_purchase(int user) throws IOError;
- public abstract int64 get_last_purchase(int user) throws IOError;
- public abstract StatsInfo get_stats_info() throws IOError;
- public abstract int[] get_member_ids() throws IOError;
- public abstract int[] get_system_member_ids() throws IOError;
- public abstract void user_disable(int user, bool value) throws IOError, DatabaseError;
- public abstract void user_replace(UserInfo u) throws IOError, DatabaseError;
- public abstract bool user_is_disabled(int user) throws IOError, DatabaseError;
- public abstract bool user_exists(int user) throws IOError, DatabaseError;
- public abstract bool user_equals(UserInfo u) throws IOError, DatabaseError;
- public abstract int64 get_timestamp_of_last_purchase() throws IOError;
- public abstract Category[] get_category_list() throws IOError;
- public abstract Supplier[] get_supplier_list() throws IOError;
- public abstract Supplier get_supplier(int id) throws IOError;
- public abstract void add_supplier(string name, string postal_code, string city, string street, string phone, string website) throws IOError, DatabaseError;
- public abstract int[] get_users_with_sales(int64 timestamp_from, int64 timestamp_to) throws IOError;
- public abstract Price get_user_invoice_sum(int user, int64 timestamp_from, int64 timestamp_to) throws IOError;
- public abstract Price cashbox_status() throws IOError;
- public abstract void cashbox_add(int user, Price amount, int64 timestamp) throws IOError, DatabaseError;
- public abstract CashboxDiff[] cashbox_history() throws IOError;
- public abstract CashboxDiff[] cashbox_changes(int64 start, int64 stop) throws IOError;
- public abstract void ean_alias_add(uint64 ean, uint64 real_ean) throws IOError, DatabaseError;
- public abstract uint64 ean_alias_get(uint64 ean) throws IOError;
- public abstract EanAlias[] ean_alias_list() throws IOError;
- public abstract BestBeforeEntry[] bestbeforelist() throws IOError;
+ public abstract DetailedProduct[] get_stock() throws DBusError, IOError;
+ public abstract DetailedProduct get_product_for_ean(uint64 ean) throws DBusError, IOError, DatabaseError;
+ public abstract PriceEntry[] get_prices(uint64 product) throws DBusError, IOError;
+ public abstract RestockEntry[] get_restocks(uint64 product, bool descending) throws DBusError, IOError;
+ public abstract bool buy(int32 user, uint64 article) throws DBusError, IOError, DatabaseError;
+ public abstract string get_product_name(uint64 article) throws DBusError, IOError, DatabaseError;
+ public abstract string get_product_category(uint64 article) throws DBusError, IOError, DatabaseError;
+ public abstract int get_product_amount(uint64 article) throws DBusError, IOError, DatabaseError;
+ public abstract bool get_product_deprecated(uint64 article) throws DBusError, IOError, DatabaseError;
+ public abstract void product_deprecate(uint64 article, bool value) throws DBusError, IOError, DatabaseError;
+ public abstract Price get_product_price(int user, uint64 article) throws DBusError, IOError, DatabaseError;
+ public abstract string undo(int32 user) throws DBusError, IOError, DatabaseError;
+ public abstract void restock(int user, uint64 product, uint amount, uint price, int supplier, int64 best_before_date) throws DBusError, IOError, DatabaseError;
+ public abstract void new_product(uint64 id, string name, int category, int memberprice, int guestprice) throws DBusError, IOError, DatabaseError;
+ public abstract void new_price(uint64 product, int64 timestamp, int memberprice, int guestprice) throws DBusError, IOError, DatabaseError;
+ public abstract bool check_user_password(int32 user, string password) throws DBusError, IOError;
+ public abstract void set_user_password(int32 user, string password) throws DBusError, IOError, DatabaseError;
+ public abstract void set_sessionid(int user, string sessionid) throws DBusError, IOError, DatabaseError;
+ public abstract void set_userTheme(int user, string userTheme) throws DBusError, IOError, DatabaseError;
+ public abstract int get_user_by_sessionid(string sessionid) throws DBusError, IOError, DatabaseError;
+ public abstract UserInfo get_user_info(int user) throws DBusError, IOError, DatabaseError;
+ public abstract UserAuth get_user_auth(int user) throws DBusError, IOError, DatabaseError;
+ public abstract void set_user_auth(UserAuth auth) throws DBusError, IOError, DatabaseError;
+ public abstract string get_username(int user) throws DBusError, IOError, DatabaseError;
+ public abstract string get_user_theme(int user, string fallback) throws DBusError, IOError, DatabaseError;
+ public abstract InvoiceEntry[] get_invoice(int user, int64 from=0, int64 to=-1) throws DBusError, IOError, DatabaseError;
+ public abstract int64 get_first_purchase(int user) throws DBusError, IOError;
+ public abstract int64 get_last_purchase(int user) throws DBusError, IOError;
+ public abstract StatsInfo get_stats_info() throws DBusError, IOError;
+ public abstract int[] get_member_ids() throws DBusError, IOError, DatabaseError;
+ public abstract int[] get_system_member_ids() throws DBusError, IOError, DatabaseError;
+ public abstract void user_disable(int user, bool value) throws DBusError, IOError, DatabaseError;
+ public abstract void user_replace(UserInfo u) throws DBusError, IOError, DatabaseError;
+ public abstract bool user_is_disabled(int user) throws DBusError, IOError, DatabaseError;
+ public abstract bool user_exists(int user) throws DBusError, IOError, DatabaseError;
+ public abstract bool user_equals(UserInfo u) throws DBusError, IOError, DatabaseError;
+ public abstract int64 get_timestamp_of_last_purchase() throws DBusError, IOError;
+ public abstract Category[] get_category_list() throws DBusError, IOError, DatabaseError;
+ public abstract int add_category(string name) throws DBusError, IOError, DatabaseError;
+ public abstract Supplier[] get_supplier_list() throws DBusError, IOError;
+ public abstract Supplier get_supplier(int id) throws DBusError, IOError;
+ public abstract void add_supplier(string name, string postal_code, string city, string street, string phone, string website) throws DBusError, IOError, DatabaseError;
+ public abstract int[] get_users_with_sales(int64 timestamp_from, int64 timestamp_to) throws DBusError, IOError;
+ public abstract Price get_user_invoice_sum(int user, int64 timestamp_from, int64 timestamp_to) throws DBusError, IOError;
+ public abstract Price cashbox_status() throws DBusError, IOError;
+ public abstract void cashbox_add(int user, Price amount, int64 timestamp) throws DBusError, IOError, DatabaseError;
+ public abstract CashboxDiff[] cashbox_history() throws DBusError, IOError;
+ public abstract CashboxDiff[] cashbox_changes(int64 start, int64 stop) throws DBusError, IOError;
+ public abstract void ean_alias_add(uint64 ean, uint64 real_ean) throws DBusError, IOError, DatabaseError;
+ public abstract uint64 ean_alias_get(uint64 ean) throws DBusError, IOError;
+ public abstract EanAlias[] ean_alias_list() throws DBusError, IOError;
+ public abstract BestBeforeEntry[] bestbeforelist() throws DBusError, IOError;
+ public abstract int get_userid_for_rfid(string rfid) throws DBusError, IOError, DatabaseError;
+ public abstract void addrfid(string rfid, int user) throws DBusError, IOError, DatabaseError;
+ public abstract void delete_rfid_for_user(int user) throws DBusError, IOError, DatabaseError;
}
public struct Category {
@@ -72,8 +78,8 @@ public struct Category {
public string name;
}
-public struct StockEntry {
- public string id;
+public struct DetailedProduct {
+ public uint64 ean;
public string name;
public string category;
public int amount;
@@ -126,6 +132,7 @@ public struct UserInfo {
public bool disabled;
public bool hidden;
public string soundTheme;
+ public string[] rfid;
public bool equals(UserInfo x) {
if(id != x.id) return false;
@@ -140,6 +147,7 @@ public struct UserInfo {
if(joined_at != x.joined_at) return false;
if(disabled != x.disabled) return false;
if(hidden != x.hidden) return false;
+ if(rfid != x.rfid) return false;
return true;
}
@@ -197,4 +205,5 @@ public errordomain DatabaseError {
SESSION_NOT_FOUND,
USER_NOT_FOUND,
CONSTRAINT_FAILED,
+ RFID_NOT_FOUND,
}
diff --git a/src/database/main.vala b/src/database/main.vala
index 72e3813..bd4c7dc 100644
--- a/src/database/main.vala
+++ b/src/database/main.vala
@@ -13,40 +13,41 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-public static void write_to_log(string message, ...) {
- /* TODO: send message via DBus? Replace some write_to_log by throwing an error? */
-}
-
DataBase db;
public static int main(string[] args) {
+ Intl.setlocale(LocaleCategory.ALL, "");
+ Intl.textdomain("shopsystem");
+
try {
Config cfg = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Config", "/io/mainframe/shopsystem/config");
var dbfile = cfg.get_string("DATABASE", "file");
db = new DataBase(dbfile);
} catch(IOError e) {
- error("IOError: %s\n", e.message);
+ error(_("IO Error: %s\n"), e.message);
} catch(KeyFileError e) {
- error("Config Error: %s\n", e.message);
+ error(_("Config Error: %s\n"), e.message);
+ } catch(DBusError e) {
+ error(_("DBus Error: %s\n"), e.message);
}
Bus.own_name(
BusType.SYSTEM,
"io.mainframe.shopsystem.Database",
BusNameOwnerFlags.NONE,
- on_bus_aquired,
+ on_bus_acquired,
() => {},
- () => stderr.printf("Could not aquire name\n"));
+ () => stderr.printf(_("Could not acquire name\n")));
new MainLoop().run();
return 0;
}
-void on_bus_aquired(DBusConnection con) {
+void on_bus_acquired(DBusConnection con) {
try {
con.register_object("/io/mainframe/shopsystem/database", db);
} catch(IOError e) {
- stderr.printf("Could not register service\n");
+ stderr.printf(_("Could not register service\n"));
}
}
diff --git a/src/display-on-off/display-on-off.sh b/src/display-on-off/display-on-off.sh
new file mode 100755
index 0000000..23ab10a
--- /dev/null
+++ b/src/display-on-off/display-on-off.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+function getMqttConfig
+{
+ echo `busctl --system call io.mainframe.shopsystem.Config /io/mainframe/shopsystem/config io.mainframe.shopsystem.Config GetString ss MQTT $1 | sed -s "s;s ;;"`
+}
+
+BROKER=$(getMqttConfig broker)
+TOPIC=$(getMqttConfig topic)
+ON=$(getMqttConfig displayOn)
+OFF=$(getMqttConfig displayOff)
+
+mosquitto_sub -h $BROKER -t $TOPIC | while read RAW_DATA
+do
+ case $RAW_DATA in
+ $ON)
+ vbetool dpms on
+ ;;
+ $OFF)
+ vbetool dpms off
+ ;;
+ *)
+ #vbetool dpms on
+ ;;
+ esac
+done
diff --git a/src/input-device/.gitignore b/src/input-device/.gitignore
deleted file mode 100644
index 3ba6df4..0000000
--- a/src/input-device/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-input-device
diff --git a/src/input-device/Makefile b/src/input-device/Makefile
deleted file mode 100644
index aba6c73..0000000
--- a/src/input-device/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-all: input-device
- @echo > /dev/null
-
-input-device: main.vala input-device.vala input-device-interface.vala ../config/config-interface.vala
- valac -X -w -o $@ --pkg linux --pkg posix --pkg gio-2.0 $^
-
-clean:
- rm -rf input-device
-
-.PHONY: all clean
diff --git a/src/input-device/input-device-interface.vala b/src/input-device/input-device-interface.vala
index 067b827..9b16da4 100644
--- a/src/input-device/input-device-interface.vala
+++ b/src/input-device/input-device-interface.vala
@@ -16,5 +16,5 @@
[DBus (name = "io.mainframe.shopsystem.InputDevice")]
public interface InputDevice : Object {
public abstract signal void received_barcode(string barcode);
- public abstract void blink(uint duration) throws IOError;
+ public abstract void blink(uint duration) throws IOError, DBusError;
}
diff --git a/src/input-device/input-device.vala b/src/input-device/input-device.vala
index 6988c6d..1dba213 100644
--- a/src/input-device/input-device.vala
+++ b/src/input-device/input-device.vala
@@ -1,4 +1,5 @@
/* Copyright 2015, Sebastian Reichel <sre@ring0.de>
+ * Copyright 2017-2018, Johannes Rudolph <johannes.rudolph@gmx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -23,7 +24,7 @@ public class Device {
public Device(string device) {
if (device == "ignore") {
- stdout.printf("Ignoring InputDevice!\n");
+ stdout.printf(_("Ignoring InputDevice!\n"));
return;
}
try {
@@ -36,10 +37,10 @@ public class Device {
Posix.fcntl(fd, Posix.F_SETFL, flags | Posix.O_NONBLOCK);
if(!(io_read.add_watch(IOCondition.IN | IOCondition.HUP, device_read) != 0)) {
- error("Could not bind IOChannel");
+ error(_("Could not bind IOChannel"));
}
} catch(FileError e) {
- error("FileError: %s", e.message);
+ error(_("File Error: %s"), e.message);
}
}
@@ -211,7 +212,7 @@ public class Device {
char key = '\0';
if((cond & IOCondition.HUP) == IOCondition.HUP)
- error("Lost device");
+ error(_("Lost device"));
do {
int fd = source.unix_get_fd();
@@ -220,7 +221,7 @@ public class Device {
/* short read */
if (s != sizeof(Linux.Input.Event)) {
if(s > 0)
- stdout.printf("short read!\n");
+ stdout.printf(_("short read!\n"));
return true;
}
@@ -245,7 +246,7 @@ public class Device {
buffer += "%c".printf(key);
} while(key != '\n');
- stdout.printf("barcode: %s\n", buffer);
+ stdout.printf(_("barcode: %s\n"), buffer);
if(buffer.has_prefix("USER ") || buffer.has_prefix("STOCK") || buffer.has_prefix("AMOUNT ")) {
if(!check_code39_checksum(buffer))
@@ -315,7 +316,7 @@ public class Device {
/**
* @param duration duration of the blink in 0.1 seconds
*/
- public void blink(uint duration) {
+ public void blink(uint duration) throws IOError, DBusError {
/* not supported */
}
}
diff --git a/src/input-device/main.vala b/src/input-device/main.vala
index 8578033..487c028 100644
--- a/src/input-device/main.vala
+++ b/src/input-device/main.vala
@@ -1,4 +1,5 @@
/* Copyright 2015, Sebastian Reichel <sre@ring0.de>
+ * Copyright 2017-2018, Johannes Rudolph <johannes.rudolph@gmx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -13,35 +14,47 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-Device dev;
+Device devScanner;
+Device devRfid;
public static int main(string[] args) {
+ Intl.setlocale(LocaleCategory.ALL, "");
+ Intl.textdomain("shopsystem");
+
try {
Config cfg = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Config", "/io/mainframe/shopsystem/config");
- dev = new Device(cfg.get_string("INPUT", "device"));
+ devScanner = new Device(cfg.get_string("INPUT", "barcodescanner"));
+ devRfid = new Device(cfg.get_string("INPUT", "rfidreader"));
} catch(IOError e) {
- error("IOError: %s\n", e.message);
+ error(_("IO Error: %s\n"), e.message);
} catch(KeyFileError e) {
- error("Config Error: %s\n", e.message);
+ error(_("Config Error: %s\n"), e.message);
+ } catch(DBusError e) {
+ error(_("DBus Error: %s\n"), e.message);
}
Bus.own_name(
BusType.SYSTEM,
"io.mainframe.shopsystem.InputDevice",
BusNameOwnerFlags.NONE,
- on_bus_aquired,
+ on_bus_acquired,
() => {},
- () => stderr.printf("Could not aquire name\n"));
+ () => stderr.printf(_("Could not acquire name\n")));
new MainLoop().run();
return 0;
}
-void on_bus_aquired(DBusConnection con) {
+void on_bus_acquired(DBusConnection con) {
+ try {
+ con.register_object("/io/mainframe/shopsystem/device/scanner", devScanner);
+ } catch(IOError e) {
+ stderr.printf(_("Could not register service\n"));
+ }
try {
- con.register_object("/io/mainframe/shopsystem/device", dev);
+ con.register_object("/io/mainframe/shopsystem/device/rfid", devRfid);
} catch(IOError e) {
- stderr.printf("Could not register service\n");
+ stderr.printf(_("Could not register service\n"));
}
}
diff --git a/src/invoice/.gitignore b/src/invoice/.gitignore
deleted file mode 100644
index 0d4d46e..0000000
--- a/src/invoice/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-invoice
-single-invoice
diff --git a/src/invoice/Makefile b/src/invoice/Makefile
deleted file mode 100644
index 73eaf48..0000000
--- a/src/invoice/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-all: invoice single-invoice
- @echo > /dev/null
-
-invoice: main.vala invoice.vala ../mail/mailer-interface.vala ../pdf-invoice/pdf-invoice-interface.vala ../database/db-interface.vala ../config/config-interface.vala ../price.vapi
- valac -X -w -o $@ --pkg gio-2.0 $^
-
-single-invoice: single.vala invoice.vala ../mail/mailer-interface.vala ../pdf-invoice/pdf-invoice-interface.vala ../database/db-interface.vala ../config/config-interface.vala ../price.vapi
- valac -X -w -o $@ --pkg gio-2.0 $^
-
-clean:
- rm -f invoice single-invoice
-
-.PHONY: all clean
diff --git a/src/invoice/invoice.vala b/src/invoice/invoice.vala
index 1e6dd58..e83f4bf 100644
--- a/src/invoice/invoice.vala
+++ b/src/invoice/invoice.vala
@@ -32,16 +32,29 @@ public class InvoiceImplementation {
Database db;
PDFInvoice pdf;
string datadir;
-
- public InvoiceImplementation() throws IOError, KeyFileError {
+ string mailfromaddress;
+ string treasurermailaddress;
+ string shortname;
+ string spacename;
+ string vat;
+ string jverein_membership_number;
+
+ public InvoiceImplementation() throws DBusError, IOError, KeyFileError {
mailer = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Mail", "/io/mainframe/shopsystem/mailer");
db = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Database", "/io/mainframe/shopsystem/database");
pdf = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.InvoicePDF", "/io/mainframe/shopsystem/invoicepdf");
Config cfg = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Config", "/io/mainframe/shopsystem/config");
- datadir = cfg.get_string("INVOICE", "datadir");
+ var datapath = cfg.get_string("GENERAL", "datapath");
+ datadir = Path.build_filename(datapath, "invoice");
+ mailfromaddress = cfg.get_string("MAIL", "mailfromaddress");
+ treasurermailaddress = cfg.get_string("MAIL", "treasurermailaddress");
+ shortname = cfg.get_string("GENERAL", "shortname");
+ spacename = cfg.get_string("GENERAL", "spacename");
+ vat = cfg.get_string("INVOICE", "vat");
+ jverein_membership_number = cfg.get_string("JVEREIN", "membership_number");
}
- public void send_invoice(bool temporary, int64 timestamp, int user) throws IOError, InvoicePDFError, DatabaseError {
+ public void send_invoice(bool temporary, int64 timestamp, int user) throws DBusError, IOError, InvoicePDFError, DatabaseError {
int64 prevtimestamp = timestamp - day_in_seconds;
if(!temporary)
@@ -67,9 +80,9 @@ public class InvoiceImplementation {
string treasurer_path = mailer.create_mail();
Mail treasurer_mail = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Mail", treasurer_path);
- treasurer_mail.from = {"KtT Shopsystem", "shop@kreativitaet-trifft-technik.de"};
+ treasurer_mail.from = {shortname + " Shopsystem", mailfromaddress};
treasurer_mail.subject = mailtitle;
- treasurer_mail.add_recipient({"Schatzmeister", "shop-einzug@kreativitaet-trifft-technik.de"}, RecipientType.TO);
+ treasurer_mail.add_recipient({"Schatzmeister", treasurermailaddress}, RecipientType.TO);
var csvinvoicedata = "";
foreach(var userid in users) {
@@ -82,7 +95,7 @@ public class InvoiceImplementation {
var invoicedata = generate_invoice(temporary, timestamp, userid, invoiceid);
string mail_path = mailer.create_mail();
Mail mail = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Mail", mail_path);
- mail.from = {"KtT Shopsystem", "shop@kreativitaet-trifft-technik.de"};
+ mail.from = {shortname + " Shopsystem", mailfromaddress};
mail.subject = mailtitle;
mail.add_recipient({@"$(userdata.firstname) $(userdata.lastname)", userdata.email}, RecipientType.TO);
@@ -109,11 +122,15 @@ public class InvoiceImplementation {
}
}
- public void send_invoices(bool temporary, int64 timestamp) throws IOError, InvoicePDFError, DatabaseError {
+ public void send_invoices(bool temporary, int64 timestamp) throws DBusError, IOError, InvoicePDFError, DatabaseError {
int64 prevtimestamp = timestamp - day_in_seconds;
+ string due_date_string = "";
- if(!temporary)
+ if(!temporary) {
prevtimestamp = new DateTime.from_unix_local(timestamp).add_months(-1).to_unix();
+ var due_date = new DateTime.from_unix_local(timestamp).add_days(10);
+ due_date_string = due_date.format("%d.%m.%Y");
+ }
Timespan ts = get_timespan(temporary, prevtimestamp);
Timespan tst = get_timespan(false, prevtimestamp);
@@ -135,10 +152,17 @@ public class InvoiceImplementation {
string treasurer_path = mailer.create_mail();
Mail treasurer_mail = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Mail", treasurer_path);
- treasurer_mail.from = {"KtT Shopsystem", "shop@kreativitaet-trifft-technik.de"};
+ treasurer_mail.from = {shortname + " Shopsystem", mailfromaddress};
treasurer_mail.subject = mailtitle;
- treasurer_mail.add_recipient({"Schatzmeister", "shop-einzug@kreativitaet-trifft-technik.de"}, RecipientType.TO);
+ treasurer_mail.add_recipient({"Schatzmeister", treasurermailaddress}, RecipientType.TO);
var csvinvoicedata = "";
+ var csvjvereininvoicedata = "";
+ if(jverein_membership_number == "extern") {
+ csvjvereininvoicedata = "Ext_Mitglieds_Nr;Betrag;Buchungstext;Fälligkeit;Intervall;Endedatum";
+ }
+ else {
+ csvjvereininvoicedata = "Mitglieds_Nr;Betrag;Buchungstext;Fälligkeit;Intervall;Endedatum";
+ }
foreach(var userid in users) {
number++;
@@ -149,7 +173,7 @@ public class InvoiceImplementation {
string mail_path = mailer.create_mail();
Mail mail = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Mail", mail_path);
- mail.from = {"KtT Shopsystem", "shop@kreativitaet-trifft-technik.de"};
+ mail.from = {shortname + " Shopsystem", mailfromaddress};
mail.subject = mailtitle;
mail.add_recipient({@"$(userdata.firstname) $(userdata.lastname)", userdata.email}, RecipientType.TO);
@@ -165,17 +189,19 @@ public class InvoiceImplementation {
if(!temporary) {
treasurer_mail.add_attachment(invoicedata.pdffilename, "application/pdf", invoicedata.pdfdata);
csvinvoicedata += @"$(userdata.id),$(userdata.lastname),$(userdata.firstname),$invoiceid,$total_sum\n";
+ csvjvereininvoicedata += @"$(userdata.id);$total_sum;Shopsystem Rechnung Nummer $invoiceid;$due_date_string;0;$due_date_string\n";
}
}
if(!temporary) {
treasurer_mail.set_main_part(get_treasurer_text(), MessageType.PLAIN);
treasurer_mail.add_attachment("invoice.csv", "text/csv; charset=utf-8", csvinvoicedata.data);
+ treasurer_mail.add_attachment("jvereininvoice.csv", "text/csv; charset=utf-8", csvjvereininvoicedata.data);
mailer.send_mail(treasurer_path);
}
}
- public InvoiceData generate_invoice(bool temporary, int64 timestamp, int userid, string invoiceid) throws IOError, InvoicePDFError, DatabaseError {
+ public InvoiceData generate_invoice(bool temporary, int64 timestamp, int userid, string invoiceid) throws DBusError, IOError, InvoicePDFError, DatabaseError {
int64 prevtimestamp = timestamp - day_in_seconds;
if(!temporary)
prevtimestamp = new DateTime.from_unix_local(timestamp).add_months(-1).to_unix();
@@ -222,11 +248,13 @@ public class InvoiceImplementation {
string text;
try {
- FileUtils.get_contents(datadir + "/treasurer.mail.txt", out text);
+ FileUtils.get_contents(Path.build_filename(datadir, "/treasurer.mail.txt"), out text);
} catch(GLib.FileError e) {
- throw new IOError.FAILED("Could not open invoice template: %s", e.message);
+ throw new IOError.FAILED(_("Could not open invoice template: %s"), e.message);
}
+ text = text.replace("{{{SHORTNAME}}}", shortname);
+
return text;
}
@@ -284,19 +312,36 @@ public class InvoiceImplementation {
table = generate_invoice_table_html(entries);
if(filename == "")
- throw new IOError.FAILED("Unknown MessageType");
+ throw new IOError.FAILED(_("Unknown MessageType"));
try {
- FileUtils.get_contents(datadir + "/" + filename, out text);
+ FileUtils.get_contents(Path.build_filename(datadir, filename), out text);
} catch(GLib.FileError e) {
- throw new IOError.FAILED("Could not open invoice template: %s", e.message);
+ throw new IOError.FAILED(_("Could not open invoice template: %s"), e.message);
}
text = text.replace("{{{ADDRESS}}}", address);
text = text.replace("{{{LASTNAME}}}", name);
+ text = text.replace("{{{SPACENAME}}}", spacename);
text = text.replace("{{{INVOICE_TABLE}}}", table);
text = text.replace("{{{SUM_MONTH}}}", "%d,%02d".printf(total_sum / 100, total_sum % 100));
+ if(vat == "yes") {
+ text = text.replace("{{{VAT}}}", "");
+ } else {
+ string vattext;
+ string vattextfilename;
+ vattextfilename = (type == MessageType.HTML) ? "vat.html" : "vat.txt";
+
+ try {
+ FileUtils.get_contents(Path.build_filename(datadir, vattextfilename), out vattext);
+ } catch(GLib.FileError e) {
+ throw new IOError.FAILED(_("Could not open VAT template: %s"), e.message);
+ }
+
+ text = text.replace("{{{VAT}}}", vattext);
+ }
+
return text;
}
diff --git a/src/invoice/main.vala b/src/invoice/main.vala
index b341adb..f5ec69b 100644
--- a/src/invoice/main.vala
+++ b/src/invoice/main.vala
@@ -16,11 +16,14 @@
InvoiceImplementation invoice;
public static void help(string name) {
- stderr.printf("Usage: %s <temporary> [timestamp]\n", name);
- stderr.printf("Possible values for <temporary>: temporary, final\n");
+ stderr.printf(_("Usage: %s <temporary> [timestamp]\n"), name);
+ stderr.printf(_("Possible values for <temporary>: temporary, final\n"));
}
public static int main(string[] args) {
+ Intl.setlocale(LocaleCategory.ALL, "");
+ Intl.textdomain("shopsystem");
+
bool temporary = false;
int64 timestamp = new DateTime.now_local().to_unix();
@@ -45,14 +48,14 @@ public static int main(string[] args) {
try {
invoice = new InvoiceImplementation();
} catch(Error e) {
- stderr.printf("Error: %s\n", e.message);
+ stderr.printf(_("Error: %s\n"), e.message);
return 1;
}
try {
invoice.send_invoices(temporary, timestamp);
} catch(Error e) {
- stderr.printf("Error: %s\n", e.message);
+ stderr.printf(_("Error: %s\n"), e.message);
return 1;
}
diff --git a/src/invoice/single.vala b/src/invoice/single.vala
index 54cba26..6f54afe 100644
--- a/src/invoice/single.vala
+++ b/src/invoice/single.vala
@@ -48,14 +48,14 @@ public static int main(string[] args) {
try {
invoice = new InvoiceImplementation();
} catch(Error e) {
- stderr.printf("Error: %s\n", e.message);
+ stderr.printf(_("Error: %s\n"), e.message);
return 1;
}
try {
invoice.send_invoice(temporary, timestamp, user);
} catch(Error e) {
- stderr.printf("Error: %s\n", e.message);
+ stderr.printf(_("Error: %s\n"), e.message);
return 1;
}
diff --git a/src/libcairobarcode/code39.vala b/src/libcairobarcode/code39.vala
new file mode 100644
index 0000000..ca5451c
--- /dev/null
+++ b/src/libcairobarcode/code39.vala
@@ -0,0 +1,128 @@
+/* Copyright 2014, Sebastian Reichel <sre@ring0.de>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+public class Code39 {
+ Cairo.Context ctx;
+ double width;
+ double height;
+
+ /* 0 = wide black, 1 = narrow black, 2 = wide white, 3 = narrow white */
+ const uint32[] lookup_table = {
+ 0x1d8cd, 0xd9dc, 0x1c9dc, 0xc9dd, 0x1d8dc, 0xd8dd, 0x1c8dd, 0x1d9cc,
+ 0xd9cd, 0x1c9cd, 0xdd9c, 0x1cd9c, 0xcd9d, 0x1dc9c, 0xdc9d, 0x1cc9d,
+ 0x1dd8c, 0xdd8d, 0x1cd8d, 0x1dc8d, 0xddd8, 0x1cdd8, 0xcdd9, 0x1dcd8,
+ 0xdcd9, 0x1ccd9, 0x1ddc8, 0xddc9, 0x1cdc9, 0x1dcc9, 0x9ddc, 0x18ddc,
+ 0x8ddd, 0x19cdc, 0x9cdd, 0x18cdd, 0x19dcc, 0x9dcd, 0x18dcd, 0x1999d,
+ 0x199d9, 0x19d99, 0x1d999, 0x19ccd
+ };
+
+ public Code39(Cairo.Context ctx, double width, double height) {
+ this.ctx = ctx;
+ this.width = width;
+ this.height = height;
+ }
+
+ private int lookup_index(char c) throws BarcodeError {
+ if(c >= '0' && c <= '9')
+ return c - '0';
+ if(c >= 'A' && c <= 'Z')
+ return c - 'A' + 10;
+ switch (c) {
+ case '-':
+ return 36;
+ case '.':
+ return 37;
+ case ' ':
+ return 38;
+ case '$':
+ return 39;
+ case '/':
+ return 40;
+ case '+':
+ return 41;
+ case '%':
+ return 42;
+ case '*':
+ return 43;
+ default:
+ throw new BarcodeError.UNEXPECTED_CHARACTER("Character '%c' is not allowed in Code 39".printf(c));
+ }
+ }
+
+ private uint32 lookup(char c) throws BarcodeError {
+ return lookup_table[lookup_index(c)];
+ }
+
+ private void draw_line(bool black, double linewidth) {
+ double x,y;
+
+ if(black)
+ ctx.set_source_rgb(0, 0, 0);
+ else
+ ctx.set_source_rgb(1, 1, 1);
+
+ ctx.rel_line_to(0,height);
+ ctx.rel_move_to(linewidth,-height);
+
+ ctx.get_current_point(out x, out y);
+ ctx.stroke();
+ ctx.move_to(x,y);
+ }
+
+ public void draw(string code) throws BarcodeError {
+ string mycode = code;
+
+ if(!mycode.has_prefix("*"))
+ mycode = "*" + mycode;
+ if(!mycode.has_suffix("*"))
+ mycode = mycode + "*";
+
+ double linewidth = width / (mycode.length * 13.0);
+
+ ctx.save();
+ ctx.set_line_width(linewidth);
+ ctx.move_to(0,0);
+ ctx.rel_move_to(0.5*linewidth,0);
+
+ for(int i=0; i<mycode.length; i++) {
+ var format = lookup(mycode[i]);
+
+ for(int j=8; j>=0; j--) {
+ var line = (format >> (2*j)) & 0x3;
+
+ switch(line) {
+ case 0:
+ draw_line(true, linewidth);
+ draw_line(true, linewidth);
+ break;
+ case 1:
+ draw_line(true, linewidth);
+ break;
+ case 2:
+ draw_line(false, linewidth);
+ draw_line(false, linewidth);
+ break;
+ default:
+ draw_line(false, linewidth);
+ break;
+ }
+ }
+
+ draw_line(false, linewidth);
+ }
+
+ ctx.restore();
+ }
+}
diff --git a/src/libcairobarcode/ean.vala b/src/libcairobarcode/ean.vala
new file mode 100644
index 0000000..4a4f621
--- /dev/null
+++ b/src/libcairobarcode/ean.vala
@@ -0,0 +1,142 @@
+/* Copyright 2014, Sebastian Reichel <sre@ring0.de>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+public class EAN {
+ Cairo.Context ctx;
+ double width;
+ double height;
+ const double marker_length_diff = 10.0;
+ double basex;
+ double basey;
+
+ const uint8[] C = { 0x00, 0x0b, 0x0d, 0x0e, 0x13, 0x19, 0x1c, 0x15, 0x16, 0x1a };
+
+ static uint8[,] lookup = {
+ { 0x0d, 0x19, 0x13, 0x3d, 0x23, 0x31, 0x2f, 0x3b, 0x37, 0x0b }, /* L */
+ { 0x27, 0x33, 0x1b, 0x21, 0x1d, 0x39, 0x05, 0x11, 0x09, 0x17 }, /* G */
+ { 0x72, 0x66, 0x6c, 0x42, 0x5c, 0x4e, 0x50, 0x44, 0x48, 0x74 } /* R */
+ };
+
+ public EAN(Cairo.Context ctx, double width, double height) {
+ this.ctx = ctx;
+ this.width = width / 95.0;
+ this.height = height;
+ }
+
+ private void draw_line(bool black) {
+ double x,y;
+
+ if(black)
+ ctx.set_source_rgb(0, 0, 0);
+ else
+ ctx.set_source_rgb(1, 1, 1);
+
+ ctx.rel_line_to(0,height);
+ ctx.rel_move_to(width,-height);
+
+ ctx.get_current_point(out x, out y);
+ ctx.stroke();
+ ctx.move_to(x,y);
+ }
+
+ private void draw_startstop() {
+ draw_line(true);
+ draw_line(false);
+ draw_line(true);
+ }
+
+ private void draw_middle() {
+ draw_line(false);
+ draw_line(true);
+ draw_line(false);
+ draw_line(true);
+ draw_line(false);
+ }
+
+ private void draw_number_text(uint8 number) {
+ double x, y;
+ ctx.get_current_point(out x, out y);
+ ctx.set_source_rgb(0, 0, 0);
+
+ ctx.stroke();
+ ctx.move_to(x,y);
+ }
+
+ private void draw_number(uint8 number, uint8 type) {
+ draw_number_text(number);
+
+ for(int i=6; i>=0; i--) {
+ var bit = (lookup[type,number] >> i) & 1;
+ draw_line(bit == 1);
+ }
+ }
+
+ private uint8 get_number(string ean, int pos) {
+ return (uint8) int.parse("%c".printf(ean[pos]));
+ }
+
+ private void draw13(string ean) {
+ /* need some extra space for the checksum */
+ width = (width * 95.0) / 102.0;
+
+ uint8 LG = C[get_number(ean, 0)];
+
+ draw_startstop();
+ for(int i=1, x = 5; i<7; i++, x--) {
+ uint8 type = (uint8) (LG >> x) & 1;
+ draw_number(get_number(ean,i), type);
+ }
+ draw_middle();
+ for(int i=7; i<13; i++)
+ draw_number(get_number(ean,i), 2);
+ draw_startstop();
+
+ /* remove extra space for the checksum */
+ width = (width * 102.0) / 95.0;
+
+ }
+
+ private void draw8(string ean) {
+ draw_startstop();
+ for(int i=0; i<4; i++)
+ draw_number(get_number(ean,i), 0);
+ draw_middle();
+ for(int i=4; i<8; i++)
+ draw_number(get_number(ean,i), 2);
+ draw_startstop();
+ }
+
+ public void draw(string ean) throws BarcodeError {
+ ctx.save();
+ ctx.set_line_width(width);
+ ctx.get_current_point(out basex, out basey);
+ ctx.rel_move_to(0.5*width,0);
+
+ for(int i=0; i<ean.length; i++) {
+ if(ean[i] < '0' || ean[i] > '9') {
+ throw new BarcodeError.UNEXPECTED_CHARACTER("Character '%c' is not allowed in EAN".printf(ean[i]));
+ }
+ }
+
+ if(ean.length == 13)
+ draw13(ean);
+ else if(ean.length == 8)
+ draw8(ean);
+ else
+ throw new BarcodeError.UNEXPECTED_LENGTH("length of EAN is incorrect (must be 8 or 13)");
+
+ ctx.restore();
+ }
+}
diff --git a/src/libcairobarcode/error.vala b/src/libcairobarcode/error.vala
new file mode 100644
index 0000000..f81df91
--- /dev/null
+++ b/src/libcairobarcode/error.vala
@@ -0,0 +1,19 @@
+/* Copyright 2014, Sebastian Reichel <sre@ring0.de>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+public errordomain BarcodeError {
+ UNEXPECTED_CHARACTER,
+ UNEXPECTED_LENGTH
+}
diff --git a/src/mail/.gitignore b/src/mail/.gitignore
deleted file mode 100644
index f2ae723..0000000
--- a/src/mail/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-mailer
diff --git a/src/mail/Makefile b/src/mail/Makefile
deleted file mode 100644
index 6ec153c..0000000
--- a/src/mail/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-all: mailer
- @echo > /dev/null
-
-mailer: main.vala mailer.vala mail.vala mailer-interface.vala ../config/config-interface.vala
- valac -X -w -o $@ --vapidir=../../vapi --pkg posix --pkg libesmtp --pkg gio-2.0 --pkg gmime-2.6 -X -D_GNU_SOURCE -X -lesmtp -X -lssl -X -lcrypto -X -ldl -X -pthread $^
-
-clean:
- rm -f mailer
-
-.PHONY: all clean
diff --git a/src/mail/mail.vala b/src/mail/mail.vala
index 41153f8..f6cedc0 100644
--- a/src/mail/mail.vala
+++ b/src/mail/mail.vala
@@ -19,16 +19,18 @@ public class MailImplementation {
private GMime.Part? main_text = null;
private GMime.Part? main_html = null;
private GMime.Part[] attachments;
+ private DateTime gdate;
- private GMime.FilterCRLF filter;
+ private GMime.FilterUnix2Dos filter_unix2dos;
+ private GMime.FilterSmtpData filter_smtp;
private string[] recipients;
private string? reversepath;
public MailContact from { set {
- string sender = value.name + " " + "<" + value.email + ">";
reversepath = value.email;
- m.set_sender(sender);
+ m.add_mailbox(GMime.AddressType.SENDER, value.name, value.email);
+ m.add_mailbox(GMime.AddressType.FROM, value.name, value.email);
}}
public string subject {
@@ -37,7 +39,7 @@ public class MailImplementation {
return (result == null) ? "" : result;
}
set {
- m.set_subject(value);
+ m.set_subject(value, "utf-8");
}
}
@@ -53,30 +55,36 @@ public class MailImplementation {
public string reply_to {
owned get {
- var result = m.get_reply_to();
+ var result = m.get_reply_to().to_string(new GMime.FormatOptions(), true);
return (result == null) ? "" : result;
}
set {
- m.set_reply_to(value);
+ m.add_mailbox(GMime.AddressType.REPLY_TO, "", value);
}
}
public MailDate date {
owned get {
MailDate result = {};
- m.get_date(out result.date, out result.tz_offset);
+ result.timezone = this.gdate.get_timezone_abbreviation();
+ result.date = this.gdate.to_unix();
return result;
}
set {
- m.set_date((ulong) value.date, value.tz_offset);
+ var timezone = new TimeZone(value.timezone);
+ this.gdate = new DateTime.from_unix_utc((int64) value.date).to_timezone(timezone);
+ m.set_date(this.gdate);
}
}
public MailImplementation() {
m = new GMime.Message(true);
- m.set_header("X-Mailer", "KtT Shopsystem");
+ m.set_header("X-Mailer", "KtT Shopsystem", "utf-8");
+ this.gdate = new DateTime.now_local();
+ m.set_date(this.gdate);
attachments = new GMime.Part[0];
- filter = new GMime.FilterCRLF(true, true);
+ filter_smtp = new GMime.FilterSmtpData();
+ filter_unix2dos = new GMime.FilterUnix2Dos(true);
recipients = new string[0];
}
@@ -89,41 +97,37 @@ public class MailImplementation {
public void set_subject(string subject) {
m.set_subject(subject);
}
-
- public void set_date(uint64 date, int tz_offset) {
- m.set_date((ulong) date, tz_offset);
- }
#endif
- public void add_recipient(MailContact contact, GMime.RecipientType type) {
- m.add_recipient(type, contact.name, contact.email);
+ public void add_recipient(MailContact contact, GMime.AddressType type) throws DBusError, IOError {
+ m.add_mailbox(type, contact.name, contact.email);
recipients += contact.email;
}
- public void set_main_part(string text, MessageType type) {
+ public void set_main_part(string text, MessageType type) throws DBusError, IOError {
GMime.DataWrapper content = new GMime.DataWrapper.with_stream(
new GMime.StreamMem.with_buffer(text.data),
GMime.ContentEncoding.DEFAULT);
GMime.Part? part = new GMime.Part();
- part.set_content_object(content);
+ part.set_content(content);
switch(type) {
case MessageType.HTML:
- part.set_content_type(new GMime.ContentType.from_string("text/html; charset=utf-8"));
+ part.set_content_type(GMime.ContentType.parse(new GMime.ParserOptions(), "text/html; charset=utf-8"));
part.set_content_encoding(part.get_best_content_encoding(GMime.EncodingConstraint.7BIT));
main_html = part;
break;
case MessageType.PLAIN:
default:
- part.set_content_type(new GMime.ContentType.from_string("text/plain; charset=utf-8; format=flowed"));
+ part.set_content_type(GMime.ContentType.parse(new GMime.ParserOptions(), "text/plain; charset=utf-8; format=flowed"));
part.set_content_encoding(part.get_best_content_encoding(GMime.EncodingConstraint.7BIT));
main_text = part;
break;
}
}
- public void add_attachment(string filename, string content_type, uint8[] data) {
+ public void add_attachment(string filename, string content_type, uint8[] data) throws DBusError, IOError {
GMime.Part part = new GMime.Part();
GMime.DataWrapper content = new GMime.DataWrapper.with_stream(
@@ -133,8 +137,8 @@ public class MailImplementation {
/* configure part */
part.set_disposition("attachment");
part.set_filename(filename);
- part.set_content_type(new GMime.ContentType.from_string(content_type));
- part.set_content_object(content);
+ part.set_content_type(GMime.ContentType.parse(new GMime.ParserOptions(), content_type));
+ part.set_content(content);
part.set_content_encoding(part.get_best_content_encoding(GMime.EncodingConstraint.7BIT));
attachments += part;
@@ -190,11 +194,13 @@ public class MailImplementation {
[DBus (visible = false)]
public string generate() {
update_mime_part();
- string result = m.to_string();
+ string result = m.to_string(new GMime.FormatOptions());
uint8[] crlfdata;
+ uint8[] smtpdata;
size_t prespace;
- filter.filter(result.data, 0, out crlfdata, out prespace);
- return (string) crlfdata;
+ filter_unix2dos.filter(result.data, 0, out crlfdata, out prespace);
+ filter_smtp.filter(crlfdata, 0, out smtpdata, out prespace);
+ return (string) smtpdata;
}
[DBus (visible = false)]
diff --git a/src/mail/mailer-interface.vala b/src/mail/mailer-interface.vala
index 54b4865..019585b 100644
--- a/src/mail/mailer-interface.vala
+++ b/src/mail/mailer-interface.vala
@@ -15,9 +15,9 @@
[DBus (name = "io.mainframe.shopsystem.Mailer")]
public interface Mailer : Object {
- public abstract string create_mail() throws IOError;
- public abstract void delete_mail(string path) throws IOError;
- public abstract void send_mail(string path) throws IOError;
+ public abstract string create_mail() throws IOError, DBusError;
+ public abstract void delete_mail(string path) throws IOError, DBusError;
+ public abstract void send_mail(string path) throws IOError, DBusError;
}
[DBus (name = "io.mainframe.shopsystem.Mail")]
@@ -28,9 +28,9 @@ public interface Mail : Object {
public abstract string reply_to { owned get; set; }
public abstract MailDate date { owned get; set; }
- public abstract void add_recipient(MailContact contact, RecipientType type = RecipientType.TO) throws IOError;
- public abstract void set_main_part(string text, MessageType type = MessageType.PLAIN) throws IOError;
- public abstract void add_attachment(string filename, string content_type, uint8[] data) throws IOError;
+ public abstract void add_recipient(MailContact contact, RecipientType type = RecipientType.TO) throws IOError, DBusError;
+ public abstract void set_main_part(string text, MessageType type = MessageType.PLAIN) throws IOError, DBusError;
+ public abstract void add_attachment(string filename, string content_type, uint8[] data) throws IOError, DBusError;
}
public struct MailAttachment {
@@ -51,7 +51,7 @@ public struct MailContact {
public struct MailDate {
uint64 date;
- int tz_offset;
+ string timezone;
}
public enum MessageType {
diff --git a/src/mail/mailer.vala b/src/mail/mailer.vala
index 3ec9381..642ceaa 100644
--- a/src/mail/mailer.vala
+++ b/src/mail/mailer.vala
@@ -56,10 +56,10 @@ public class MailerImplementation {
return 1;
}
- public MailerImplementation() throws IOError {
+ public MailerImplementation() throws DBusError, IOError {
int result;
- GMime.init(0);
+ GMime.init();
Smtp.auth_client_init();
session = Smtp.Session();
@@ -67,7 +67,7 @@ public class MailerImplementation {
send_queue = new Queue<MailImplementation>();
/* ignore SIGPIPE, as suggested by libESMTP */
- Posix.signal(Posix.SIGPIPE, Posix.SIG_IGN);
+ Posix.signal(Posix.Signal.PIPE, Posix.SIG_IGN);
/* get configuration */
Config config = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Config", "/io/mainframe/shopsystem/config");
@@ -76,7 +76,7 @@ public class MailerImplementation {
var cfgport = config.get_integer("MAIL", "port");
server = @"$cfgserv:$cfgport";
} catch(KeyFileError e) {
- throw new IOError.FAILED("server or port configuration is missing");
+ throw new IOError.FAILED(_("server or port configuration is missing"));
}
try {
@@ -96,7 +96,7 @@ public class MailerImplementation {
/* setup server */
result = session.set_server(server);
if(result == 0)
- throw new IOError.FAILED("could not setup server");
+ throw new IOError.FAILED(_("could not setup server"));
/* Use TLS if possible */
if (starttls)
@@ -104,7 +104,7 @@ public class MailerImplementation {
else
result = session.starttls_enable(Smtp.StartTlsOption.DISABLED);
if(result == 0)
- throw new IOError.FAILED("could not configure STARTTLS");
+ throw new IOError.FAILED(_("could not configure STARTTLS"));
/* setup authentication */
if(username != "") {
@@ -120,7 +120,7 @@ public class MailerImplementation {
GMime.shutdown();
}
- public string create_mail() throws IOError {
+ public string create_mail() throws DBusError, IOError {
string path = @"/io/mainframe/shopsystem/mail/$mailcounter";
var mail = new MailImplementation();
@@ -136,17 +136,17 @@ public class MailerImplementation {
return path;
}
- public void delete_mail(string path) throws IOError {
+ public void delete_mail(string path) throws DBusError, IOError {
if(!(path in mails))
- throw new IOError.NOT_FOUND("No such mail");
+ throw new IOError.NOT_FOUND(_("No such mail"));
mail_bus.unregister_object(mails[path].registration_id);
mails.remove(path);
}
- public void send_mail(string path) throws IOError {
+ public void send_mail(string path) throws DBusError, IOError {
if(!(path in mails))
- throw new IOError.NOT_FOUND("No such mail");
+ throw new IOError.NOT_FOUND(_("No such mail"));
send_queue.push_tail(mails[path].mail);
delete_mail(path);
@@ -172,12 +172,16 @@ public class MailerImplementation {
message.set_reverse_path(current_mail.get_reverse_path());
int result = session.start_session();
- if(result == 0)
- throw new IOError.FAILED("eSMTP: Start Session failed!");
+ if(result == 0) {
+ stderr.printf(_("eSMTP: Start Session failed!"));
+ return false;
+ }
unowned Smtp.Status status = message.transfer_status();
- if(status.code < 200 || status.code >= 300)
- throw new IOError.FAILED("Reply from SMTP-Server: %s", status.text);
+ if(status.code < 200 || status.code >= 300) {
+ stderr.printf(_("Reply from SMTP-Server: %s"));
+ return false;
+ }
current_mail = null;
diff --git a/src/mail/main.vala b/src/mail/main.vala
index 0c36f6b..b3a7088 100644
--- a/src/mail/main.vala
+++ b/src/mail/main.vala
@@ -17,30 +17,33 @@ MailerImplementation m;
DBusConnection mail_bus;
public static int main(string[] args) {
+ Intl.setlocale(LocaleCategory.ALL, "");
+ Intl.textdomain("shopsystem");
+
try {
m = new MailerImplementation();
- } catch(IOError e) {
- stderr.printf("Error: %s\n", e.message);
+ } catch(Error e) {
+ stderr.printf(_("Error: %s\n"), e.message);
}
Bus.own_name(
BusType.SYSTEM,
"io.mainframe.shopsystem.Mail",
BusNameOwnerFlags.NONE,
- on_mail_bus_aquired,
+ on_mail_bus_acquired,
() => {},
- () => stderr.printf("Error: Could not aquire name\n"));
+ () => stderr.printf(_("Error: Could not acquire name\n")));
new MainLoop().run();
return 0;
}
-void on_mail_bus_aquired(DBusConnection con) {
+void on_mail_bus_acquired(DBusConnection con) {
try {
mail_bus = con;
con.register_object("/io/mainframe/shopsystem/mailer", m);
} catch(IOError e) {
- stderr.printf("Error: Could not register service\n");
+ stderr.printf(_("Error: Could not register service\n"));
}
}
diff --git a/src/meson.build b/src/meson.build
new file mode 100644
index 0000000..8f7ed3d
--- /dev/null
+++ b/src/meson.build
@@ -0,0 +1,52 @@
+add_project_arguments(['--vapidir', join_paths(meson.current_source_dir(), '..', 'vapi')], language: 'vala')
+add_project_arguments('-DGETTEXT_PACKAGE="shopsystem"', language:'c')
+
+glib_dep = dependency('glib-2.0')
+gobject_dep = dependency('gobject-2.0')
+gio_dep = dependency('gio-2.0')
+gstreamer_dep = dependency('gstreamer-1.0')
+gee_dep = dependency('gee-0.8')
+sqlite_dep = dependency('sqlite3')
+gmime_dep = dependency('gmime-3.0')
+rsvg_dep = dependency('librsvg-2.0')
+pangocairo_dep = dependency('pangocairo')
+cairo_dep = dependency('cairo')
+archive_dep = dependency('libarchive')
+soup_dep = dependency('libsoup-2.4')
+
+gpgme_lib = meson.get_compiler('c').find_library('gpgme')
+gpgme_vapi = meson.get_compiler('vala').find_library('gpgme', dirs: join_paths(meson.current_source_dir(), '..', 'vapi'))
+gpgerror_vapi = meson.get_compiler('vala').find_library('gpg-error', dirs: join_paths(meson.current_source_dir(), '..', 'vapi'))
+gpgme_dep = declare_dependency(dependencies: [gpgme_lib, gpgme_vapi, gpgerror_vapi])
+
+esmtp_lib = meson.get_compiler('c').find_library('libesmtp')
+esmtp_vapi = meson.get_compiler('vala').find_library('libesmtp')
+esmtp_dep = declare_dependency(dependencies: [esmtp_lib, esmtp_vapi])
+
+curses_lib = meson.get_compiler('c').find_library('ncursesw')
+curses_vapi = meson.get_compiler('vala').find_library('curses')
+curses_dep = declare_dependency(dependencies: [curses_lib, curses_vapi])
+
+gdk_dep = meson.get_compiler('vala').find_library('gdk-2.0') # gdk is only needed for librsvg vapi, not really used, so we only check for the vapi file
+posix_dep = meson.get_compiler('vala').find_library('posix')
+linux_dep = meson.get_compiler('vala').find_library('linux')
+
+libcairobarcode = library('cairobarcode', ['libcairobarcode/ean.vala', 'libcairobarcode/code39.vala', 'libcairobarcode/error.vala'], soversion: '0', version: meson.project_version(), dependencies: [gio_dep, cairo_dep], install: true, install_dir: [true, true, true])
+executable('shop-audio', ['audio/main.vala', 'audio/audio.vala', 'audio/audio-interface.vala', 'config/config-interface.vala'], dependencies :[gio_dep, gstreamer_dep], install: true, install_dir: join_paths(get_option('libexecdir'), 'shopsystem'))
+executable('shop-backup', ['backup/main.vala', 'mail/mailer-interface.vala', 'config/config-interface.vala'], dependencies: [gio_dep], install: true, install_dir: join_paths(get_option('libexecdir'), 'shopsystem'))
+executable('shop-cli', ['cli/main.vala', 'cli/cli.vala', 'cli/cli-interface.vala', 'config/config-interface.vala'], dependencies: [gio_dep], install: true, install_dir: join_paths(get_option('libexecdir'), 'shopsystem'))
+executable('shop-config', ['config/main.vala', 'config/config.vala', 'config/config-interface.vala'], dependencies: [gio_dep], install: true, install_dir: join_paths(get_option('libexecdir'), 'shopsystem'))
+executable('shop-curses-ui', ['curses-ui/clock.vala', 'curses-ui/curses-ui.vala', 'curses-ui/dialog.vala', 'curses-ui/logo.vala', 'curses-ui/main.vala', 'curses-ui/message_box.vala', 'curses-ui/message_box_overlay.vala', 'curses-ui/numbers.vala', 'curses-ui/status.vala', 'audio/audio-interface.vala', 'scanner-session/scannersession-interface.vala', 'config/config-interface.vala'], dependencies: [gio_dep, posix_dep, curses_dep], install: true, install_dir: join_paths(get_option('libexecdir'), 'shopsystem'))
+executable('shop-database', ['database/main.vala', 'database/database.vala', 'database/db-interface.vala', 'config/config-interface.vala', 'price.vapi'], dependencies: [gio_dep, gee_dep, sqlite_dep], install: true, install_dir: join_paths(get_option('libexecdir'), 'shopsystem'))
+executable('shop-input-device', ['input-device/main.vala', 'input-device/input-device.vala', 'input-device/input-device-interface.vala', 'config/config-interface.vala'], dependencies: [gio_dep, linux_dep], install: true, install_dir: join_paths(get_option('libexecdir'), 'shopsystem'))
+executable('shop-invoice', ['invoice/main.vala', 'invoice/invoice.vala', 'mail/mailer-interface.vala', 'pdf-invoice/pdf-invoice-interface.vala', 'database/db-interface.vala', 'config/config-interface.vala', 'price.vapi'], dependencies: [gio_dep], install: true, install_dir: join_paths(get_option('libexecdir'), 'shopsystem'))
+executable('shop-single-invoice', ['invoice/single.vala', 'invoice/invoice.vala', 'mail/mailer-interface.vala', 'pdf-invoice/pdf-invoice-interface.vala', 'database/db-interface.vala', 'config/config-interface.vala', 'price.vapi'], dependencies: [gio_dep], install: true, install_dir: join_paths(get_option('libexecdir'), 'shopsystem'))
+executable('shop-mailer', ['mail/main.vala', 'mail/mailer.vala', 'mail/mail.vala', 'mail/mailer-interface.vala', 'config/config-interface.vala'], dependencies: [gio_dep, posix_dep, esmtp_dep, gmime_dep], install: true, install_dir: join_paths(get_option('libexecdir'), 'shopsystem'))
+executable('shop-pdf-invoice', ['pdf-invoice/main.vala', 'pdf-invoice/pdf-invoice.vala', 'pdf-invoice/pdf-invoice-interface.vala', 'config/config-interface.vala', 'database/db-interface.vala', 'price.vapi'], dependencies: [gio_dep, pangocairo_dep, rsvg_dep, gdk_dep, posix_dep], install: true, install_dir: join_paths(get_option('libexecdir'), 'shopsystem'))
+executable('shop-test-pdf-invoice', ['pdf-invoice/test.vala', 'pdf-invoice/pdf-invoice-interface.vala', 'database/db-interface.vala', 'price.vapi'], dependencies: [gio_dep, pangocairo_dep, rsvg_dep, gdk_dep, posix_dep], install: true, install_dir: join_paths(get_option('libexecdir'), 'shopsystem'))
+executable('shop-pdf-stock', ['pdf-stock/main.vala', 'pdf-stock/pdf-stock.vala', 'database/db-interface.vala', 'price.vapi'], dependencies: [gio_dep, pangocairo_dep, cairo_dep, posix_dep], link_with: libcairobarcode, install: true, install_dir: join_paths(get_option('libexecdir'), 'shopsystem'))
+executable('shop-test-pdf-stock', ['pdf-stock/test.vala', 'pdf-stock/pdf-stock-interface.vala'], dependencies: [gio_dep], install: true, install_dir: join_paths(get_option('libexecdir'), 'shopsystem'))
+executable('shop-pgp', ['pgp/main.vala', 'pgp/pgp.vala', 'pgp/pgp-interface.vala', 'config/config-interface.vala'], dependencies: [gio_dep, gpgme_dep, archive_dep], c_args: ['-D_FILE_OFFSET_BITS=64'], install: true, install_dir: join_paths(get_option('libexecdir'), 'shopsystem'))
+executable('shop-scanner-session', ['scanner-session/main.vala', 'scanner-session/scannersession.vala', 'scanner-session/scannersession-interface.vala', 'database/db-interface.vala', 'input-device/input-device-interface.vala', 'cli/cli-interface.vala', 'audio/audio-interface.vala', 'price.vapi'], dependencies: [gio_dep], install: true, install_dir: join_paths(get_option('libexecdir'), 'shopsystem'))
+executable('shop-serial-device', ['serial-device/main.vala', 'serial-device/serial-device.vala', 'config/config-interface.vala'], dependencies: [gio_dep, linux_dep], install: true, install_dir: join_paths(get_option('libexecdir'), 'shopsystem'))
+executable('shop-web', ['web/main.vala', 'web/web.vala', 'web/websession.vala', 'web/csv.vala', 'web/template.vala', 'database/db-interface.vala', 'pgp/pgp-interface.vala', 'price.vapi', 'config/config-interface.vala', 'audio/audio-interface.vala', 'pdf-stock/pdf-stock-interface.vala'], dependencies: [gio_dep, gee_dep, soup_dep, posix_dep], install: true, install_dir: join_paths(get_option('libexecdir'), 'shopsystem'))
diff --git a/src/pdf-invoice/.gitignore b/src/pdf-invoice/.gitignore
deleted file mode 100644
index 0b84a09..0000000
--- a/src/pdf-invoice/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-pdf-invoice
-test
-test.pdf
diff --git a/src/pdf-invoice/Makefile b/src/pdf-invoice/Makefile
deleted file mode 100644
index 9805f6e..0000000
--- a/src/pdf-invoice/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-all: pdf-invoice
- @echo > /dev/null
-
-pdf-invoice: main.vala pdf-invoice.vala pdf-invoice-interface.vala ../config/config-interface.vala ../database/db-interface.vala ../price.vapi
- valac -X -w -g -o $@ --pkg pangocairo --pkg librsvg-2.0 --pkg posix --pkg gdk-2.0 --pkg gio-2.0 $^
-
-test: pdf-invoice-interface.vala ../database/db-interface.vala test.vala ../price.vapi
- valac -X -w -o $@ --pkg gio-2.0 $^
-
-clean:
- rm -rf pdf-invoice test
-
-.PHONY: all clean
diff --git a/src/pdf-invoice/main.vala b/src/pdf-invoice/main.vala
index 3d8e298..4217eb8 100644
--- a/src/pdf-invoice/main.vala
+++ b/src/pdf-invoice/main.vala
@@ -16,32 +16,38 @@
private string datadir;
public static int main(string[] args) {
+ Intl.setlocale(LocaleCategory.ALL, "");
+ Intl.textdomain("shopsystem");
+
try {
Config cfg = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Config", "/io/mainframe/shopsystem/config");
- datadir = cfg.get_string("INVOICE", "datadir");
+ var datapath = cfg.get_string("GENERAL", "datapath");
+ datadir = Path.build_filename(datapath, "invoice");
+ } catch(DBusError e) {
+ error(_("DBus Error: %s\n"), e.message);
} catch(IOError e) {
- error("IOError: %s\n", e.message);
+ error(_("IO Error: %s\n"), e.message);
} catch(KeyFileError e) {
- error("Config Error: %s\n", e.message);
+ error(_("Config Error: %s\n"), e.message);
}
Bus.own_name(
BusType.SYSTEM,
"io.mainframe.shopsystem.InvoicePDF",
BusNameOwnerFlags.NONE,
- on_bus_aquired,
+ on_bus_acquired,
() => {},
- () => stderr.printf("Could not aquire name\n"));
+ () => stderr.printf(_("Could not acquire name\n")));
new MainLoop().run();
return 0;
}
-void on_bus_aquired(DBusConnection conn) {
+void on_bus_acquired(DBusConnection conn) {
try {
conn.register_object("/io/mainframe/shopsystem/invoicepdf", new InvoicePDF(datadir));
- } catch(IOError e) {
- stderr.printf("Could not register service\n");
+ } catch(Error e) {
+ stderr.printf(_("Could not register service: %s\n"), e.message);
}
}
diff --git a/src/pdf-invoice/pdf-invoice-interface.vala b/src/pdf-invoice/pdf-invoice-interface.vala
index 8fccbf0..41abc6d 100644
--- a/src/pdf-invoice/pdf-invoice-interface.vala
+++ b/src/pdf-invoice/pdf-invoice-interface.vala
@@ -43,6 +43,6 @@ public interface PDFInvoice : Object {
public abstract InvoiceRecipient invoice_recipient { set; owned get; }
public abstract InvoiceEntry[] invoice_entries { set; owned get; }
- public abstract uint8[] generate() throws IOError, InvoicePDFError;
- public abstract void clear() throws IOError;
+ public abstract uint8[] generate() throws DBusError, IOError, InvoicePDFError;
+ public abstract void clear() throws DBusError, IOError;
}
diff --git a/src/pdf-invoice/pdf-invoice.vala b/src/pdf-invoice/pdf-invoice.vala
index c50fe6c..d3177c9 100644
--- a/src/pdf-invoice/pdf-invoice.vala
+++ b/src/pdf-invoice/pdf-invoice.vala
@@ -1,4 +1,5 @@
/* Copyright 2013, Sebastian Reichel <sre@ring0.de>
+ * Copyright 2017-2018, Johannes Rudolph <johannes.rudolph@gmx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -15,6 +16,8 @@
[DBus (name = "io.mainframe.shopsystem.InvoicePDF")]
public class InvoicePDF {
+ Config cfg;
+
/* A4 sizes (in points, 72 DPI) */
private const double width = 595.27559; /* 210mm */
private const double height = 841.88976; /* 297mm */
@@ -60,8 +63,14 @@ public class InvoicePDF {
"Dezember"
};
- public InvoicePDF(string datadir) {
+ string longname;
+ string vat;
+
+ public InvoicePDF(string datadir) throws DBusError, IOError, KeyFileError {
this.datadir = datadir;
+ cfg = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Config", "/io/mainframe/shopsystem/config");
+ longname = cfg.get_string("GENERAL", "longname");
+ vat = cfg.get_string("INVOICE", "vat");
}
private void render_svg(Cairo.Context ctx, string file) {
@@ -69,7 +78,7 @@ public class InvoicePDF {
var svg = new Rsvg.Handle.from_file(file);
svg.render_cairo(ctx);
} catch(Error e) {
- error("Could not load SVG: %s\n", e.message);
+ error(_("Could not load SVG: %s\n"), e.message);
}
}
@@ -77,18 +86,18 @@ public class InvoicePDF {
ctx.save();
ctx.translate(-20, 818);
ctx.scale(1.42, 1.42);
- render_svg(ctx, datadir + "/footer-line.svg");
+ render_svg(ctx, Path.build_filename(datadir, "footer-line.svg"));
ctx.restore();
}
private void draw_logo(Cairo.Context ctx) {
ctx.save();
ctx.translate(366,25);
- render_svg(ctx, datadir + "/logo.svg");
+ render_svg(ctx, Path.build_filename(datadir, "logo.svg"));
ctx.restore();
}
- private void draw_address(Cairo.Context ctx) {
+ private void draw_address(Cairo.Context ctx) throws DBusError, IOError, KeyFileError {
ctx.save();
ctx.set_source_rgb(0, 0, 0);
ctx.set_line_width(1.0);
@@ -104,8 +113,7 @@ public class InvoicePDF {
ctx.set_font_size(8.45);
ctx.move_to(56.5, 142);
- /* TODO: get string from config file */
- ctx.show_text("Kreativität trifft Technik e.V., Bahnhofsplatz 10, 26122 Oldenburg");
+ ctx.show_text(cfg.get_string("INVOICE", "addressrow"));
/* actually LMRoman12 */
ctx.select_font_face("LMSans10", Cairo.FontSlant.NORMAL, Cairo.FontWeight.NORMAL);
@@ -194,13 +202,12 @@ public class InvoicePDF {
ctx.move_to(56.5, 323);
- /* TODO: get text from config file */
ctx.show_text(@"Rechnung Nr. $invoice_id");
ctx.restore();
}
- private void draw_footer_text_left(Cairo.Context ctx) {
+ private void draw_footer_text_left(Cairo.Context ctx) throws DBusError, IOError, KeyFileError {
ctx.save();
ctx.move_to(64.0, 742.0);
ctx.set_source_rgb(0, 0, 0);
@@ -224,8 +231,7 @@ public class InvoicePDF {
/* set page width */
layout.set_width((int) 140 * Pango.SCALE);
- /* TODO: get text from config file */
- var text = "<b>Kreativität trifft Technik e.V.</b>\nAmtsgericht Oldenburg VR 201044\n\nHackspace „Mainframe“\nFabLab „Fab-O-Lab“\nSchnittstelle „Schnittstelle“\n\nBahnhofsplatz 10 • 26122 Oldenburg";
+ var text = cfg.get_string("INVOICE", "footer1");
/* write invoice date */
layout.set_markup(text, text.length);
@@ -237,7 +243,7 @@ public class InvoicePDF {
ctx.restore();
}
- private void draw_footer_text_middle(Cairo.Context ctx) {
+ private void draw_footer_text_middle(Cairo.Context ctx) throws DBusError, IOError, KeyFileError {
ctx.save();
ctx.move_to(216.5, 742.0);
ctx.set_source_rgb(0, 0, 0);
@@ -261,8 +267,7 @@ public class InvoicePDF {
/* set page width */
layout.set_width((int) 190 * Pango.SCALE);
- /* TODO: get text from config file */
- var text = "<b>Mail:</b> vorstand@kreativitaet-trifft-technik.de\n<b>Web:</b> www.kreativitaet-trifft-technik.de\n\n\n\n<b>BGB-Vorstand:</b>\nPatrick Günther, Michael Pensler, Jan Janssen";
+ var text = cfg.get_string("INVOICE", "footer2");
/* write invoice date */
layout.set_markup(text, text.length);
@@ -274,7 +279,7 @@ public class InvoicePDF {
ctx.restore();
}
- private void draw_footer_text_right(Cairo.Context ctx) {
+ private void draw_footer_text_right(Cairo.Context ctx) throws DBusError, IOError, KeyFileError {
ctx.save();
ctx.move_to(410.0, 742.0);
ctx.set_source_rgb(0, 0, 0);
@@ -298,8 +303,7 @@ public class InvoicePDF {
/* set page width */
layout.set_width((int) 150 * Pango.SCALE);
- /* TODO: get text from config file */
- var text = "<b>Raiffeisenbank Oldenburg</b>\nIBAN: DE34 2806 0228 0037 0185 00\nBIC: GENODEF1OL2\n\n\n<b>Finanzamt Oldenburg</b>\nAls gemeinnützig anerkannt.\nSteuer Nr.: 64/220/18413";
+ var text = cfg.get_string("INVOICE", "footer3");
/* write invoice date */
layout.set_markup(text, text.length);
@@ -328,7 +332,7 @@ public class InvoicePDF {
return "Moin";
}
- private void draw_first_page_text(Cairo.Context ctx) {
+ private void draw_first_page_text(Cairo.Context ctx) throws IOError {
ctx.save();
ctx.move_to(56.5, 352.5);
ctx.set_source_rgb(0, 0, 0);
@@ -358,13 +362,29 @@ public class InvoicePDF {
/* load text template */
try {
var text = "";
- FileUtils.get_contents(datadir + "/pdf-template.txt", out text);
+ FileUtils.get_contents(Path.build_filename(datadir, "pdf-template.txt"), out text);
text = text.replace("{{{ADDRESS}}}", address);
text = text.replace("{{{LASTNAME}}}", invoice_recipient.lastname);
text = text.replace("{{{SUM}}}", @"$sum");
+ text = text.replace("{{{ORGANIZATION}}}", longname);
+
+ if(vat == "yes") {
+ text = text.replace("{{{VAT}}}", "");
+ } else {
+ string vattext;
+
+ try {
+ FileUtils.get_contents(Path.build_filename(datadir, "vat.txt"), out vattext);
+ } catch(GLib.FileError e) {
+ throw new IOError.FAILED(_("Could not open VAT template: %s"), e.message);
+ }
+
+ text = text.replace("{{{VAT}}}", vattext);
+ }
+
layout.set_markup(text, text.length);
} catch(GLib.FileError e) {
- error("File Error: %s\n", e.message);
+ error(_("File Error: %s\n"), e.message);
}
/* render text */
@@ -448,11 +468,11 @@ public class InvoicePDF {
var price = @"$(e.price)€".replace(".", ",");
if(e.price > 999999) {
- throw new InvoicePDFError.PRICE_TOO_HIGH("Prices > 9999.99€ are not supported!");
+ throw new InvoicePDFError.PRICE_TOO_HIGH(_("Prices > 9999.99€ are not supported!"));
}
if(tm.get_year() > 9999) {
- throw new InvoicePDFError.TOO_FAR_IN_THE_FUTURE("Years after 9999 are not supported!");
+ throw new InvoicePDFError.TOO_FAR_IN_THE_FUTURE(_("Years after 9999 are not supported!"));
}
/* if date remains the same do not add it again */
@@ -568,7 +588,7 @@ public class InvoicePDF {
/* retry adding the entry */
if(!draw_invoice_table_entry(ctx, y, entry, out y)) {
- throw new InvoicePDFError.ARTICLE_NAME_TOO_LONG("Article name \"%s\" does not fit on a single page!", entry.product.name);
+ throw new InvoicePDFError.ARTICLE_NAME_TOO_LONG(_("Article name \"%s\" does not fit on a single page!"), entry.product.name);
}
}
}
@@ -597,7 +617,7 @@ public class InvoicePDF {
return Cairo.Status.SUCCESS;
}
- public uint8[] generate() throws InvoicePDFError {
+ public uint8[] generate() throws DBusError, IOError, InvoicePDFError, KeyFileError {
data = null;
var document = new Cairo.PdfSurface.for_stream(pdf_write, width, height);
@@ -605,16 +625,16 @@ public class InvoicePDF {
var ctx = new Cairo.Context(document);
if(invoice_id == "")
- throw new InvoicePDFError.NO_INVOICE_ID("No invoice ID given!");
+ throw new InvoicePDFError.NO_INVOICE_ID(_("No invoice ID given!"));
if(invoice_entries == null)
- throw new InvoicePDFError.NO_INVOICE_DATA("No invoice data given!");
+ throw new InvoicePDFError.NO_INVOICE_DATA(_("No invoice data given!"));
if(invoice_date == 0)
- throw new InvoicePDFError.NO_INVOICE_DATE("No invoice date given!");
+ throw new InvoicePDFError.NO_INVOICE_DATE(_("No invoice date given!"));
if(invoice_recipient.firstname == "" && invoice_recipient.lastname == "")
- throw new InvoicePDFError.NO_INVOICE_RECIPIENT("No invoice recipient given!");
+ throw new InvoicePDFError.NO_INVOICE_RECIPIENT(_("No invoice recipient given!"));
/* first page */
draw_logo(ctx);
@@ -638,7 +658,7 @@ public class InvoicePDF {
return data;
}
- public void clear() {
+ public void clear() throws DBusError, IOError {
invoice_date = 0;
invoice_id = "";
invoice_recipient.firstname = "";
diff --git a/src/pdf-invoice/test.vala b/src/pdf-invoice/test.vala
index e55f3a3..5eb7f52 100644
--- a/src/pdf-invoice/test.vala
+++ b/src/pdf-invoice/test.vala
@@ -14,7 +14,13 @@
*/
public static int main(string args[]) {
- PDFInvoice invoice = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.InvoicePDF", "/io/mainframe/shopsystem/invoicepdf");
+ PDFInvoice invoice;
+
+ try {
+ invoice = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.InvoicePDF", "/io/mainframe/shopsystem/invoicepdf");
+ } catch(IOError e) {
+ error(_("IO Error: %s\n"), e.message);
+ }
InvoiceRecipient r = {
"Max",
@@ -43,10 +49,20 @@ public static int main(string args[]) {
invoice.invoice_entries = {e1};
/* generate pdf */
- var pdfdata = invoice.generate();
+ try {
+ var pdfdata = invoice.generate();
- /* write pdf into file */
- FileUtils.set_contents("test.pdf", (string) pdfdata, pdfdata.length);
+ /* write pdf into file */
+ FileUtils.set_contents("test.pdf", (string) pdfdata, pdfdata.length);
+ } catch(DBusError e) {
+ error(_("DBus Error: %s\n"), e.message);
+ } catch(IOError e) {
+ error(_("IO Error: %s\n"), e.message);
+ } catch(InvoicePDFError e) {
+ error(_("Invoice PDF Error: %s\n"), e.message);
+ } catch(FileError e) {
+ error(_("File Error: %s\n"), e.message);
+ }
return 0;
}
diff --git a/src/pdf-stock/.gitignore b/src/pdf-stock/.gitignore
deleted file mode 100644
index 58a1e54..0000000
--- a/src/pdf-stock/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-pdf-stock
-test
-test.pdf
diff --git a/src/pdf-stock/Makefile b/src/pdf-stock/Makefile
deleted file mode 100644
index a9ad1a6..0000000
--- a/src/pdf-stock/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-include ../../config.mk
-
-LIBCAIROBARCODE=-X -I../../libcairobarcode -X -L../../libcairobarcode -X -lcairobarcode
-
-all: pdf-stock
- @echo > /dev/null
-
-pdf-stock: main.vala pdf-stock.vala ../database/db-interface.vala ../price.vapi ../../libcairobarcode/libcairobarcode.vapi
- valac -X -w ${LIBCAIROBARCODE} -o $@ --pkg cairo --pkg pangocairo --pkg gio-2.0 --pkg posix $^
-
-test: test.vala pdf-stock-interface.vala
- valac -X -w -o $@ --pkg gio-2.0 $^
-
-run: pdf-stock
- LD_LIBRARY_PATH=../../libcairobarcode ./pdf-stock
-
-clean:
- rm -rf pdf-stock test
-
-.PHONY: all clean run
diff --git a/src/pdf-stock/main.vala b/src/pdf-stock/main.vala
index 49613f4..10aef60 100644
--- a/src/pdf-stock/main.vala
+++ b/src/pdf-stock/main.vala
@@ -14,23 +14,26 @@
*/
public static int main(string[] args) {
+ Intl.setlocale(LocaleCategory.ALL, "");
+ Intl.textdomain("shopsystem");
+
Bus.own_name(
BusType.SYSTEM,
"io.mainframe.shopsystem.StockPDF",
BusNameOwnerFlags.NONE,
- on_bus_aquired,
+ on_bus_acquired,
() => {},
- () => stderr.printf("Could not aquire name\n"));
+ () => stderr.printf(_("Could not acquire name\n")));
new MainLoop().run();
return 0;
}
-void on_bus_aquired(DBusConnection conn) {
+void on_bus_acquired(DBusConnection conn) {
try {
conn.register_object("/io/mainframe/shopsystem/stockpdf", new StockPDF());
} catch(IOError e) {
- stderr.printf("Could not register service\n");
+ stderr.printf(_("Could not register service\n"));
}
}
diff --git a/src/pdf-stock/pdf-stock-interface.vala b/src/pdf-stock/pdf-stock-interface.vala
index be49a20..87d9f61 100644
--- a/src/pdf-stock/pdf-stock-interface.vala
+++ b/src/pdf-stock/pdf-stock-interface.vala
@@ -15,6 +15,5 @@
[DBus (name = "io.mainframe.shopsystem.StockPDF")]
public interface PDFStock : Object {
- // if false, only products with an amount > 0 are selected
- public abstract uint8[] generate(bool allProducts) throws IOError;
+ public abstract uint8[] generate(bool allProducts) throws DBusError, IOError;
}
diff --git a/src/pdf-stock/pdf-stock.vala b/src/pdf-stock/pdf-stock.vala
index ac51c23..6270c43 100644
--- a/src/pdf-stock/pdf-stock.vala
+++ b/src/pdf-stock/pdf-stock.vala
@@ -40,7 +40,7 @@ public class StockPDF {
EAN ean;
Cairo.Context ctx;
Pango.Layout layout;
- StockEntry[] stock;
+ DetailedProduct[] stock;
/* pdf data */
private uint8[] data;
@@ -99,7 +99,7 @@ public class StockPDF {
ctx.restore();
}
- private void render_table_row(StockEntry product) throws BarcodeError {
+ private void render_table_row(DetailedProduct product) throws BarcodeError {
ctx.set_line_width(0.8);
/* borders */
@@ -117,7 +117,7 @@ public class StockPDF {
/* EAN */
ctx.move_to(col1 + padding, y + padding);
- ean.draw(product.id);
+ ean.draw(@"$(product.ean)");
/* Product Name */
ctx.move_to(col2 + padding, y);
@@ -125,7 +125,7 @@ public class StockPDF {
layout.set_wrap(Pango.WrapMode.WORD_CHAR);
layout.set_spacing((int) (-padding * Pango.SCALE));
layout.set_width((int) (col3-col2) * Pango.SCALE);
- var text = @"$(product.id)\n$(product.name)";
+ var text = @"$(product.ean)\n$(product.name)";
layout.set_text(text, text.length);
Pango.cairo_update_layout(ctx, layout);
Pango.cairo_show_layout(ctx, layout);
@@ -154,7 +154,7 @@ public class StockPDF {
return Cairo.Status.SUCCESS;
}
- public uint8[] generate(bool allProducts) {
+ public uint8[] generate(bool allProducts) throws DBusError, IOError {
data = null;
var surface = new Cairo.PdfSurface.for_stream(pdf_write, a4w, a4h);
diff --git a/src/pdf-stock/test.vala b/src/pdf-stock/test.vala
index cc3da4f..92b6232 100644
--- a/src/pdf-stock/test.vala
+++ b/src/pdf-stock/test.vala
@@ -16,12 +16,14 @@
public static int main(string args[]) {
try {
PDFStock stock = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.StockPDF", "/io/mainframe/shopsystem/stockpdf");
- var pdfdata = stock.generate();
+ var pdfdata = stock.generate(true);
FileUtils.set_contents("test.pdf", (string) pdfdata, pdfdata.length);
} catch(IOError e) {
- error("IOError: %s", e.message);
+ error(_("IO Error: %s"), e.message);
} catch(FileError e) {
- error("FileError: %s", e.message);
+ error(_("File Error: %s"), e.message);
+ } catch(DBusError e) {
+ error(_("DBus Error: %s"), e.message);
}
return 0;
diff --git a/src/pgp/.gitignore b/src/pgp/.gitignore
deleted file mode 100644
index c8886a7..0000000
--- a/src/pgp/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-pgp
diff --git a/src/pgp/Makefile b/src/pgp/Makefile
deleted file mode 100644
index 6292111..0000000
--- a/src/pgp/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-all: pgp
- @echo > /dev/null
-
-pgp: main.vala pgp.vala pgp-interface.vala ../config/config-interface.vala
- valac --Xcc="-D_FILE_OFFSET_BITS=64" -X -w -o $@ --vapidir ../../vapi -X -lgpgme --pkg gpgme --pkg gio-2.0 --pkg libarchive $^
-
-clean:
- rm -rf pgp
-
-.PHONY: all clean
diff --git a/src/pgp/main.vala b/src/pgp/main.vala
index c866c7b..74bcf0e 100644
--- a/src/pgp/main.vala
+++ b/src/pgp/main.vala
@@ -21,33 +21,37 @@ PGPKeyArchive pgp;
Config cfg;
public static int main(string[] args) {
+ Intl.setlocale(LocaleCategory.ALL, "");
+ Intl.textdomain("shopsystem");
+
try {
cfg = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Config", "/io/mainframe/shopsystem/config");
pgp = new PGPKeyArchive(cfg.get_string("PGP", "keyring"));
+ } catch(DBusError e) {
+ error(_("DBus Error: %s\n"), e.message);
} catch(IOError e) {
- error("IOError: %s\n", e.message);
+ error(_("IO Error: %s\n"), e.message);
} catch(KeyFileError e) {
- error("Config Error: %s\n", e.message);
+ error(_("Config Error: %s\n"), e.message);
}
-
Bus.own_name(
BusType.SYSTEM,
"io.mainframe.shopsystem.PGP",
BusNameOwnerFlags.NONE,
- on_bus_aquired,
+ on_bus_acquired,
() => {},
- () => stderr.printf("Could not aquire name\n"));
+ () => stderr.printf(_("Could not acquire name\n")));
new MainLoop().run();
return 0;
}
-void on_bus_aquired(DBusConnection con) {
+void on_bus_acquired(DBusConnection con) {
try {
con.register_object("/io/mainframe/shopsystem/pgp", pgp);
} catch(IOError e) {
- stderr.printf("Could not register service\n");
+ stderr.printf(_("Could not register service\n"));
}
}
diff --git a/src/pgp/pgp-interface.vala b/src/pgp/pgp-interface.vala
index 62bfe67..2621fae 100644
--- a/src/pgp/pgp-interface.vala
+++ b/src/pgp/pgp-interface.vala
@@ -15,7 +15,7 @@
[DBus (name = "io.mainframe.shopsystem.PGP")]
public interface PGP : Object {
- public abstract string[] import_archive(uint8[] data) throws IOError;
- public abstract string[] list_keys() throws IOError;
- public abstract string get_key(string fingerprint) throws IOError;
+ public abstract string[] import_archive(uint8[] data) throws IOError, DBusError;
+ public abstract string[] list_keys() throws IOError, DBusError;
+ public abstract string get_key(string fingerprint) throws IOError, DBusError;
}
diff --git a/src/pgp/pgp.vala b/src/pgp/pgp.vala
index bb48c61..6d9bed0 100644
--- a/src/pgp/pgp.vala
+++ b/src/pgp/pgp.vala
@@ -42,13 +42,13 @@ public class PGPKeyArchive {
gpg.set_armor(true);
}
- public string[] import_archive(uint8[] data) {
+ public string[] import_archive(uint8[] data) throws DBusError, IOError {
string[] result = {};
unowned Archive.Entry entry;
var archive = new Archive.Read();
/* support all formats & compression types */
- archive.support_compression_all();
+ archive.support_filter_all();
archive.support_format_all();
/* load test archive for now */
@@ -93,7 +93,7 @@ public class PGPKeyArchive {
return result;
}
- public string[] list_keys() {
+ public string[] list_keys() throws DBusError, IOError {
string[] result = {};
GPG.Key key;
@@ -108,7 +108,7 @@ public class PGPKeyArchive {
return result;
}
- public string get_key(string fingerprint) {
+ public string get_key(string fingerprint) throws DBusError, IOError {
GPG.Data keydata;
GPG.Data.create(out keydata);
@@ -120,7 +120,7 @@ public class PGPKeyArchive {
keydata.read(data);
return (string) data;
} else {
- stdout.printf("error!\n");
+ stdout.printf(_("Error!\n"));
return "";
}
}
diff --git a/src/scanner-session/.gitignore b/src/scanner-session/.gitignore
deleted file mode 100644
index b16547e..0000000
--- a/src/scanner-session/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-scanner-session
diff --git a/src/scanner-session/Makefile b/src/scanner-session/Makefile
deleted file mode 100644
index 5320025..0000000
--- a/src/scanner-session/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-all: scanner-session
- @echo > /dev/null
-
-scanner-session: main.vala scannersession.vala scannersession-interface.vala ../database/db-interface.vala ../input-device/input-device-interface.vala ../cli/cli-interface.vala ../audio/audio-interface.vala ../price.vapi
- valac -X -w -o $@ --pkg gio-2.0 $^
-
-clean:
- rm -rf scanner-session
-
-.PHONY: all clean
diff --git a/src/scanner-session/main.vala b/src/scanner-session/main.vala
index 2ed94f9..3b876c5 100644
--- a/src/scanner-session/main.vala
+++ b/src/scanner-session/main.vala
@@ -16,13 +16,16 @@
ScannerSessionImplementation session;
public static int main(string[] args) {
+ Intl.setlocale(LocaleCategory.ALL, "");
+ Intl.textdomain("shopsystem");
+
Bus.own_name(
BusType.SYSTEM,
"io.mainframe.shopsystem.ScannerSession",
BusNameOwnerFlags.NONE,
- on_bus_aquired,
+ on_bus_acquired,
() => {},
- () => stderr.printf("Could not aquire name\n"));
+ () => stderr.printf(_("Could not acquire name\n")));
session = new ScannerSessionImplementation();
@@ -31,10 +34,10 @@ public static int main(string[] args) {
return 0;
}
-void on_bus_aquired(DBusConnection con) {
+void on_bus_acquired(DBusConnection con) {
try {
con.register_object("/io/mainframe/shopsystem/scanner_session", session);
} catch(IOError e) {
- stderr.printf("Could not register service\n");
+ stderr.printf(_("Could not register service\n"));
}
}
diff --git a/src/scanner-session/scannersession-interface.vala b/src/scanner-session/scannersession-interface.vala
index 89498df..c19a434 100644
--- a/src/scanner-session/scannersession-interface.vala
+++ b/src/scanner-session/scannersession-interface.vala
@@ -24,3 +24,25 @@ public enum MessageType {
WARNING,
ERROR
}
+
+public enum ScannerSessionCodeType {
+ USER,
+ GUEST,
+ UNDO,
+ LOGOUT,
+ EAN,
+ RFIDEM4100,
+ UNKNOWN
+}
+
+public enum ScannerSessionState {
+ READY,
+ USER
+}
+
+public struct ScannerResult {
+ public MessageType type;
+ public string message;
+ public AudioType audioType;
+ public string nextScannerdata;
+}
diff --git a/src/scanner-session/scannersession.vala b/src/scanner-session/scannersession.vala
index 9638ef5..796cf93 100644
--- a/src/scanner-session/scannersession.vala
+++ b/src/scanner-session/scannersession.vala
@@ -1,4 +1,5 @@
/* Copyright 2012-2013, Sebastian Reichel <sre@ring0.de>
+ * Copyright 2017-2018, Johannes Rudolph <johannes.rudolph@gmx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -16,16 +17,19 @@
[DBus (name = "io.mainframe.shopsystem.ScannerSession")]
public class ScannerSessionImplementation {
private int user = 0;
- private string name = "Guest";
+ private string name = _("Guest");
private bool logged_in = false;
private bool disabled = false;
private string theme = "beep";
private Database db;
private AudioPlayer audio;
- private InputDevice dev;
+ private InputDevice devScanner;
+ private InputDevice devRfid;
private Cli cli;
+ private ScannerSessionState state = ScannerSessionState.READY;
+ private DetailedProduct[] shoppingCard = {};
public signal void msg(MessageType type, string message);
public signal void msg_overlay(string title, string message);
@@ -33,14 +37,16 @@ public class ScannerSessionImplementation {
public ScannerSessionImplementation() {
try {
db = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Database", "/io/mainframe/shopsystem/database");
- dev = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.InputDevice", "/io/mainframe/shopsystem/device");
+ devScanner = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.InputDevice", "/io/mainframe/shopsystem/device/scanner");
+ devRfid = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.InputDevice", "/io/mainframe/shopsystem/device/rfid");
cli = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Cli", "/io/mainframe/shopsystem/cli");
audio = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.AudioPlayer", "/io/mainframe/shopsystem/audio");
- dev.received_barcode.connect(handle_barcode);
+ devScanner.received_barcode.connect(handle_barcode);
+ devRfid.received_barcode.connect(handle_barcode);
cli.received_barcode.connect(handle_barcode);
} catch(IOError e) {
- error("IOError: %s\n", e.message);
+ error(_("IO Error: %s\n"), e.message);
}
}
@@ -51,19 +57,21 @@ public class ScannerSessionImplementation {
msg(type, message);
}
- private void logout() {
- logged_in = false;
- }
-
- private bool login(int user) throws IOError {
+ private bool login(int user) throws DBusError, IOError {
this.user = user;
- try {
- this.name = db.get_username(user);
- this.disabled = db.user_is_disabled(user);
- } catch(DatabaseError e) {
- send_message(MessageType.ERROR, "Error (user=%d): %s", user, e.message);
- return false;
+ if (user != 0) {
+ try {
+ this.name = db.get_username(user);
+ this.disabled = db.user_is_disabled(user);
+ } catch(DatabaseError e) {
+ send_message(MessageType.ERROR, _("Error (user=%d): %s"), user, e.message);
+ return false;
+ }
+ } else {
+ this.name = _("Guest");
+ this.disabled = false;
}
+
this.logged_in = true;
try {
@@ -78,141 +86,255 @@ public class ScannerSessionImplementation {
return true;
}
- private void handle_barcode(string scannerdata) {
- try {
- stdout.printf("scannerdata: %s\n", scannerdata);
- if(interpret(scannerdata))
- dev.blink(1000);
- } catch(IOError e) {
- send_message(MessageType.ERROR, "IOError: %s", e.message);
- } catch(DatabaseError e) {
- send_message(MessageType.ERROR, "DatabaseError: %s", e.message);
- }
- }
-
- private bool interpret(string scannerdata) throws DatabaseError, IOError {
- if(scannerdata.has_prefix("USER ")) {
- string str_id = scannerdata.substring(5);
- int32 id = int.parse(str_id);
+ private ScannerSessionCodeType getCodeType(string scannerdata) {
+ if(scannerdata.has_prefix("USER ")){
+ return ScannerSessionCodeType.USER;
+ } else if(scannerdata == "GUEST") {
+ return ScannerSessionCodeType.GUEST;
+ } else if(scannerdata == "UNDO") {
+ return ScannerSessionCodeType.UNDO;
+ } else if(scannerdata == "LOGOUT") {
+ return ScannerSessionCodeType.LOGOUT;
+ } else if(scannerdata.length == 10) {
+ return ScannerSessionCodeType.RFIDEM4100;
+ } else {
+ //Handle EAN Code
+ uint64 id = 0;
+ scannerdata.scanf("%llu", out id);
/* check if scannerdata has valid format */
- if(scannerdata != "USER %d".printf(id)) {
- audio.play_system("error.ogg");
- send_message(MessageType.ERROR, "Invalid User ID: %s", scannerdata);
- return false;
- }
-
- if(logged_in) {
- send_message(MessageType.WARNING, "Last user forgot to logout");
- logout();
+ if(scannerdata != "%llu".printf(id) && scannerdata != "%08llu".printf(id) && scannerdata != "%013llu".printf(id)) {
+ return ScannerSessionCodeType.UNKNOWN;
}
+ return ScannerSessionCodeType.EAN;
+ }
+ }
- if(login(id)) {
- audio.play_user(theme, "login");
- send_message(MessageType.INFO, "Login: %s (%d)", name, user);
- return true;
- } else {
+ private void play_audio(AudioType audioType) throws DBusError, IOError {
+ switch (audioType) {
+ case AudioType.ERROR:
audio.play_system("error.ogg");
- send_message(MessageType.ERROR, "Login failed (User ID = %d)", id);
- return false;
- }
- } else if(scannerdata == "GUEST") {
- if(logged_in) {
- send_message(MessageType.WARNING, "Last user forgot to logout");
- logout();
- }
-
- if(login(0)) {
+ break;
+ case AudioType.LOGIN:
audio.play_user(theme, "login");
- send_message(MessageType.INFO, "Login: %s (%d)", name, user);
- return true;
- } else {
- audio.play_system("error.ogg");
- send_message(MessageType.ERROR, "Login failed (User ID = 0)");
- return false;
- }
- } else if(scannerdata == "UNDO") {
- if(!logged_in) {
- audio.play_system("error.ogg");
- send_message(MessageType.ERROR, "Can't undo if not logged in!");
- return false;
- } else {
- string product = db.undo(user);
+ break;
+ case AudioType.LOGOUT:
+ audio.play_user(theme, "logout");
+ break;
+ case AudioType.PURCHASE:
+ audio.play_user(theme, "purchase");
+ break;
+ case AudioType.INFO:
+ audio.play_user(theme, "login");
+ break;
+ }
+ }
- if(product != "") {
- audio.play_user(theme, "purchase");
- send_message(MessageType.INFO, "Removed purchase of %s", product);
- return true;
+ private ScannerResult handleReadyState(string scannerdata) throws DatabaseError, DBusError, IOError {
+ ScannerSessionCodeType codeType = getCodeType(scannerdata);
+ ScannerResult scannerResult = ScannerResult();
+ switch (codeType) {
+ case ScannerSessionCodeType.USER:
+ int32 userid = int.parse(scannerdata.substring(5));
+ if(login(userid)) {
+ scannerResult.type = MessageType.INFO;
+ scannerResult.message = _("Login: %s (%d)").printf(name, user);
+ scannerResult.audioType = AudioType.LOGIN;
+ shoppingCard = {};
+ state = ScannerSessionState.USER;
} else {
- audio.play_user(theme, "error");
- send_message(MessageType.ERROR, "Couldn't undo last purchase!");
- return false;
+ scannerResult.type = MessageType.ERROR;
+ scannerResult.message = _("Login failed (User ID = %d)").printf(userid);
+ scannerResult.audioType = AudioType.ERROR;
+ state = ScannerSessionState.READY;
+ }
+ return scannerResult;
+ case ScannerSessionCodeType.GUEST:
+ if(login(0)) {
+ scannerResult.type = MessageType.INFO;
+ scannerResult.message = _("Login as Guest");
+ scannerResult.audioType = AudioType.LOGIN;
+ shoppingCard = {};
+ state = ScannerSessionState.USER;
+ } else {
+ scannerResult.type = MessageType.ERROR;
+ scannerResult.message = _("Login failed (Guest)");
+ scannerResult.audioType = AudioType.ERROR;
+ state = ScannerSessionState.READY;
+ }
+ return scannerResult;
+ case ScannerSessionCodeType.EAN:
+ uint64 ean = 0;
+ scannerdata.scanf("%llu", out ean);
+ var p = DetailedProduct();
+ try {
+ p = db.get_product_for_ean(ean);
+ } catch(IOError e) {
+ scannerResult.type = MessageType.ERROR;
+ scannerResult.message = _("Internal Error!");
+ scannerResult.audioType = AudioType.ERROR;
+ return scannerResult;
+ } catch(DatabaseError e) {
+ if(e is DatabaseError.PRODUCT_NOT_FOUND) {
+ scannerResult.type = MessageType.ERROR;
+ scannerResult.message = _("Error: unknown product: %llu").printf(ean);
+ scannerResult.audioType = AudioType.ERROR;
+ } else {
+ scannerResult.type = MessageType.ERROR;
+ scannerResult.message = _("Error: %s").printf(e.message);
+ scannerResult.audioType = AudioType.ERROR;
+ }
+ return scannerResult;
}
- }
- } else if(scannerdata == "LOGOUT") {
- if(logged_in) {
- audio.play_user(theme, "logout");
- send_message(MessageType.INFO, "Logout!");
- logout();
- return true;
- }
- return false;
- } else {
- uint64 id = 0;
- scannerdata.scanf("%llu", out id);
+ var mprice = p.memberprice;
+ var gprice = p.guestprice;
+ var pname = p.name;
- /* check if scannerdata has valid format */
- if(scannerdata != "%llu".printf(id) && scannerdata != "%08llu".printf(id) && scannerdata != "%013llu".printf(id)) {
- audio.play_user(theme, "error");
- send_message(MessageType.ERROR, "invalid product: %s", scannerdata);
- return false;
- }
+ scannerResult.type = MessageType.INFO;
+ scannerResult.message = _("Article info: %s (Member: %s €, Guest: %s €").printf(@"$pname", @"$mprice", @"$gprice");
+ scannerResult.audioType = AudioType.ERROR;
+ state = ScannerSessionState.READY;
+ return scannerResult;
+ case ScannerSessionCodeType.RFIDEM4100:
+ int user = db.get_userid_for_rfid(scannerdata);
+ scannerResult.nextScannerdata = @"USER $user";
+ return scannerResult;
+ default:
+ state = ScannerSessionState.READY;
+ return scannerResult;
+ }
+ }
- string name = "unknown product";
+ private ScannerResult handleUserState(string scannerdata) throws DatabaseError, DBusError, IOError {
+ ScannerSessionCodeType codeType = getCodeType(scannerdata);
+ ScannerResult scannerResult = ScannerResult();
+ switch (codeType) {
+ case ScannerSessionCodeType.EAN:
+ uint64 ean = 0;
+ scannerdata.scanf("%llu", out ean);
+ var p = DetailedProduct();
+ try {
+ p = db.get_product_for_ean(ean);
+ } catch(IOError e) {
+ scannerResult.type = MessageType.ERROR;
+ scannerResult.message = _("Internal Error!");
+ scannerResult.audioType = AudioType.ERROR;
+ return scannerResult;
+ } catch(DatabaseError e) {
+ if(e is DatabaseError.PRODUCT_NOT_FOUND) {
+ scannerResult.type = MessageType.ERROR;
+ scannerResult.message = _("Error: unknown product: %llu").printf(ean);
+ scannerResult.audioType = AudioType.ERROR;
+ } else {
+ scannerResult.type = MessageType.ERROR;
+ scannerResult.message = _("Error: %s").printf(e.message);
+ scannerResult.audioType = AudioType.ERROR;
+ }
+ return scannerResult;
+ }
- try {
- id = db.ean_alias_get(id);
- name = db.get_product_name(id);
- } catch(IOError e) {
- audio.play_user(theme, "error");
- send_message(MessageType.ERROR, "Internal Error!");
- return false;
- } catch(DatabaseError e) {
- if(e is DatabaseError.PRODUCT_NOT_FOUND) {
- audio.play_user(theme, "error");
- var msg = "Error: unknown product: %llu".printf(id);
- send_message(MessageType.ERROR, msg);
- msg_overlay("Attention", msg);
+ shoppingCard += p;
+
+ Price price = p.memberprice;
+
+ if(user == 0){
+ price = p.guestprice;
+ }
+
+ scannerResult.type = MessageType.INFO;
+ scannerResult.message = _("Article added to shopping card: %s (%s €)").printf(@"$(p.name)", @"$price");
+ scannerResult.audioType = AudioType.PURCHASE;
+ state = ScannerSessionState.USER;
+ break;
+ case ScannerSessionCodeType.UNDO:
+ if(shoppingCard.length > 0){
+ var removedProduct = shoppingCard[shoppingCard.length-1];
+ shoppingCard = shoppingCard[0:shoppingCard.length-1];
+ scannerResult.type = MessageType.INFO;
+ scannerResult.message = _("Removed last Item from Shopping Cart: %s").printf(@"$(removedProduct.name)");
+ scannerResult.audioType = AudioType.INFO;
} else {
- audio.play_user(theme, "error");
- send_message(MessageType.ERROR, "Error: %s", e.message);
+ scannerResult.type = MessageType.INFO;
+ scannerResult.message = _("No more Items on your Shopping Cart");
+ scannerResult.audioType = AudioType.ERROR;
}
- return false;
- }
+ break;
+ case ScannerSessionCodeType.LOGOUT:
+ scannerResult = logout();
+ break;
+ case ScannerSessionCodeType.USER:
+ case ScannerSessionCodeType.GUEST:
+ case ScannerSessionCodeType.RFIDEM4100:
+ /* Logout old user session (and buy articles) */
+ scannerResult = logout();
+ scannerResult.nextScannerdata = scannerdata;
+ break;
+ }
- if(!logged_in) {
- var mprice = db.get_product_price(1, id);
- var gprice = db.get_product_price(0, id);
- var msg = @"article info: $name (Member: $mprice €, Guest: $gprice €)";
- audio.play_system("error.ogg");
- send_message(MessageType.INFO, msg);
- send_message(MessageType.ERROR, "Login required for purchase!");
- msg_overlay("Attention", "%s\nLogin required for purchase!".printf(msg));
+ return scannerResult;
+ }
- return false;
+ private ScannerResult buyShoppingCard() throws DatabaseError, DBusError, IOError {
+ ScannerResult scannerResult = ScannerResult();
+ uint8 amountOfItems = 0;
+ Price totalPrice = 0;
+ uint8 i = 0;
+ DetailedProduct p = DetailedProduct();
+ for(i = 0; i < shoppingCard.length; i++) {
+ p = shoppingCard[i];
+ db.buy(user, p.ean);
+ amountOfItems++;
+ Price price = p.memberprice;
+ if(user == 0) {
+ price = p.guestprice;
}
+ totalPrice += price;
+ }
+ scannerResult.type = MessageType.INFO;
+ scannerResult.message = @_("%s bought %d items for %s €").printf(@"$name", amountOfItems, @"$totalPrice");
+ scannerResult.audioType = AudioType.INFO;
+ return scannerResult;
+ }
- if(db.buy(user, id)) {
- var price = db.get_product_price(user, id);
- audio.play_user(theme, "purchase");
- send_message(MessageType.INFO, @"article bought: $name ($price €)");
- return true;
- } else {
- audio.play_user(theme, "error");
- send_message(MessageType.ERROR, "purchase failed!");
- return false;
- }
+ private void handle_barcode(string scannerdata) {
+ try {
+ stdout.printf("scannerdata: %s\n", scannerdata);
+ if(interpret(scannerdata))
+ devScanner.blink(1000);
+ } catch(DBusError e) {
+ send_message(MessageType.ERROR, _("DBus Error: %s"), e.message);
+ } catch(IOError e) {
+ send_message(MessageType.ERROR, _("IO Error: %s"), e.message);
+ } catch(DatabaseError e) {
+ send_message(MessageType.ERROR, _("Database Error: %s"), e.message);
+ }
+ }
+
+ private bool interpret(string scannerdata) throws DatabaseError, DBusError, IOError {
+ ScannerResult scannerResult = ScannerResult();
+ switch (state) {
+ case ScannerSessionState.READY:
+ scannerResult = handleReadyState(scannerdata);
+ break;
+ case ScannerSessionState.USER:
+ scannerResult = handleUserState(scannerdata);
+ break;
}
+
+ play_audio(scannerResult.audioType);
+ send_message(scannerResult.type, scannerResult.message);
+ if(scannerResult.nextScannerdata != null){
+ interpret(scannerResult.nextScannerdata);
+ }
+ return true;
+ }
+
+ private ScannerResult logout() throws DatabaseError, DBusError, IOError {
+ ScannerResult scannerResult = buyShoppingCard();
+ scannerResult.audioType = AudioType.LOGOUT;
+ logged_in = false;
+ state = ScannerSessionState.READY;
+ return scannerResult;
}
}
diff --git a/src/serial-device/.gitignore b/src/serial-device/.gitignore
deleted file mode 100644
index e455d42..0000000
--- a/src/serial-device/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-serial-device
diff --git a/src/serial-device/Makefile b/src/serial-device/Makefile
deleted file mode 100644
index d80279d..0000000
--- a/src/serial-device/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-all: serial-device
- @echo > /dev/null
-
-serial-device: main.vala serial-device.vala ../input-device/input-device-interface.vala ../config/config-interface.vala
- valac -X -w -o $@ --pkg linux --pkg posix --pkg gio-2.0 $^
-
-clean:
- rm -rf serial-device
-
-.PHONY: all clean
diff --git a/src/serial-device/main.vala b/src/serial-device/main.vala
index 0dea907..95926b5 100644
--- a/src/serial-device/main.vala
+++ b/src/serial-device/main.vala
@@ -1,4 +1,5 @@
/* Copyright 2013, Sebastian Reichel <sre@ring0.de>
+ * Copyright 2017-2018, Johannes Rudolph <johannes.rudolph@gmx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -13,35 +14,40 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-Device dev;
+Device scanner;
public static int main(string[] args) {
+ Intl.setlocale(LocaleCategory.ALL, "");
+ Intl.textdomain("shopsystem");
+
try {
Config cfg = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Config", "/io/mainframe/shopsystem/config");
- dev = new Device(cfg.get_string("INPUT", "device"), 9600, 8, 1);
+ scanner = new Device(cfg.get_string("INPUT", "barcodescanner"), 9600, 8, 1);
} catch(IOError e) {
- error("IOError: %s\n", e.message);
+ error(_("IO Error: %s\n"), e.message);
} catch(KeyFileError e) {
- error("Config Error: %s\n", e.message);
+ error(_("Config Error: %s\n"), e.message);
+ } catch(DBusError e) {
+ error(_("DBus Error: %s\n"), e.message);
}
Bus.own_name(
BusType.SYSTEM,
"io.mainframe.shopsystem.InputDevice",
BusNameOwnerFlags.NONE,
- on_bus_aquired,
+ on_bus_acquired,
() => {},
- () => stderr.printf("Could not aquire name\n"));
+ () => stderr.printf(_("Could not acquire name\n")));
new MainLoop().run();
return 0;
}
-void on_bus_aquired(DBusConnection con) {
+void on_bus_acquired(DBusConnection con) {
try {
- con.register_object("/io/mainframe/shopsystem/device", dev);
+ con.register_object("/io/mainframe/shopsystem/devicescanner", scanner);
} catch(IOError e) {
- stderr.printf("Could not register service\n");
+ stderr.printf(_("Could not register service\n"));
}
}
diff --git a/src/serial-device/serial-device.vala b/src/serial-device/serial-device.vala
index 549cd74..3900128 100644
--- a/src/serial-device/serial-device.vala
+++ b/src/serial-device/serial-device.vala
@@ -36,11 +36,11 @@ public class Device {
if(lockfile.load_contents(null, out data, null)) {
pid = int.parse((string) data);
} else {
- error("Can't read lock file!\n");
+ error(_("Can't read lock file!\n"));
}
if(Posix.kill(pid, 0) == 0) {
- error("serial device is locked!\n");
+ error(_("serial device is locked!\n"));
}
}
@@ -52,11 +52,11 @@ public class Device {
if(fd < 0) {
fd = -1;
lockfile.delete();
- error("Could not open device!\n");
+ error(_("Could not open device!\n"));
}
} catch(Error e) {
- error("Could not create lock file: %s!\n", e.message);
+ error(_("Could not create lock file: %s!\n"), e.message);
}
@@ -160,12 +160,12 @@ public class Device {
io_read = new IOChannel.unix_new(fd);
io_read.set_line_term("\r\n", 2);
if(io_read.set_encoding(null) != IOStatus.NORMAL)
- error("Failed to set encoding");
+ error(_("Failed to set encoding"));
if(!(io_read.add_watch(IOCondition.IN | IOCondition.HUP, device_read) != 0)) {
- error("Could not bind IOChannel");
+ error(_("Could not bind IOChannel"));
}
} catch(IOChannelError e) {
- error("IOChannel: %s", e.message);
+ error(_("IOChannel: %s"), e.message);
}
}
@@ -186,7 +186,7 @@ public class Device {
size_t len, term_char;
if((cond & IOCondition.HUP) == IOCondition.HUP)
- error("Lost device");
+ error(_("Lost device"));
try {
ret = gio.read_line(out msg, out len, out term_char);
@@ -204,11 +204,11 @@ public class Device {
received_barcode(msg);
}
catch(IOChannelError e) {
- stderr.printf("IOChannel Error: %s", e.message);
+ stderr.printf(_("IOChannel Error: %s"), e.message);
return false;
}
catch(ConvertError e) {
- stderr.printf("Convert Error: %s", e.message);
+ stderr.printf(_("Convert Error: %s"), e.message);
return false;
}
return true;
@@ -272,7 +272,7 @@ public class Device {
/**
* @param duration duration of the blink in 0.1 seconds
*/
- public void blink(uint duration) {
+ public void blink(uint duration) throws IOError, DBusError {
uint size = (byterate/1000) * duration;
var msg = new uint8[size];
Posix.memset(msg, 0xFF, msg.length);
diff --git a/src/web/.gitignore b/src/web/.gitignore
deleted file mode 100644
index c077218..0000000
--- a/src/web/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-web
diff --git a/src/web/Makefile b/src/web/Makefile
deleted file mode 100644
index 94aab97..0000000
--- a/src/web/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-all: web
- @echo > /dev/null
-
-web: main.vala web.vala websession.vala csv.vala template.vala ../database/db-interface.vala ../pgp/pgp-interface.vala ../price.vapi ../config/config-interface.vala ../audio/audio-interface.vala ../pdf-stock/pdf-stock-interface.vala
- valac -X -w -o $@ --vapidir=../../vapi --enable-experimental --pkg gee-0.8 --pkg gio-2.0 --pkg libsoup-2.4 --pkg posix $^
-
-clean:
- rm -rf web
-
-.PHONY: all clean
diff --git a/src/web/csv.vala b/src/web/csv.vala
index 299af8d..6356f77 100644
--- a/src/web/csv.vala
+++ b/src/web/csv.vala
@@ -1,4 +1,5 @@
/* Copyright 2012, Sebastian Reichel <sre@ring0.de>
+ * Copyright 2017-2018, Johannes Rudolph <johannes.rudolph@gmx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -16,7 +17,7 @@
public class CSVMemberFile {
private UserInfo[] members;
- public Gee.List<int> missing_unblocked_members() throws DatabaseError, IOError {
+ public Gee.List<int> missing_unblocked_members() throws DatabaseError, IOError, DBusError {
var result = new Gee.ArrayList<int>();
var dbusers = db.get_member_ids();
@@ -66,6 +67,15 @@ public class CSVMemberFile {
m.pgp = csv_value(linedata[9]);
m.hidden = int.parse(csv_value(linedata[10])) != 0;
m.disabled = int.parse(csv_value(linedata[11])) != 0;
+ string[] rfid = {};
+ if(csv_value(linedata[12]) != "")
+ rfid += csv_value(linedata[12]);
+ if(csv_value(linedata[13]) != "")
+ rfid += csv_value(linedata[13]);
+ if(csv_value(linedata[14]) != "")
+ rfid += csv_value(linedata[14]);
+ m.rfid = rfid;
+
m.soundTheme = "";
if(csv_value(linedata[0]) != "EXTERNEMITGLIEDSNUMMER")
members += m;
diff --git a/src/web/main.vala b/src/web/main.vala
index aefe7fd..4c89e40 100644
--- a/src/web/main.vala
+++ b/src/web/main.vala
@@ -20,38 +20,59 @@ public Config cfg;
public AudioPlayer audio;
public PDFStock pdfStock;
string templatedir;
+string? shortname;
public static int main(string[] args) {
+ Intl.setlocale(LocaleCategory.ALL, "");
+ Intl.textdomain("shopsystem");
+
TlsCertificate? cert = null;
string certificate = "";
string privatekey = "";
uint port = 8080;
try {
- db = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Database", "/io/mainframe/shopsystem/database");
- pgp = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.PGP", "/io/mainframe/shopsystem/pgp");
- cfg = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Config", "/io/mainframe/shopsystem/config");
- audio = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.AudioPlayer", "/io/mainframe/shopsystem/audio");
+ db = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Database", "/io/mainframe/shopsystem/database");
+ pgp = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.PGP", "/io/mainframe/shopsystem/pgp");
+ cfg = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Config", "/io/mainframe/shopsystem/config");
+ audio = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.AudioPlayer", "/io/mainframe/shopsystem/audio");
pdfStock = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.StockPDF", "/io/mainframe/shopsystem/stockpdf");
-
- templatedir = cfg.get_string("WEB", "filepath");
+ var datapath = cfg.get_string("GENERAL", "datapath");
+ templatedir = Path.build_filename(datapath, "templates");
port = cfg.get_integer("WEB", "port");
+ } catch(IOError e) {
+ error(_("IO Error: %s\n"), e.message);
+ } catch(KeyFileError e) {
+ error(_("KeyFile Error: %s\n"), e.message);
+ } catch(DBusError e) {
+ error(_("DBus Error: %s\n"), e.message);
+ }
- try {
- certificate = cfg.get_string("WEB", "cert");
- privatekey = cfg.get_string("WEB", "key");
- } catch(KeyFileError e) {
- warning("KeyFileError: %s\n", e.message);
- }
+ try {
+ certificate = cfg.get_string("WEB", "cert");
+ privatekey = cfg.get_string("WEB", "key");
+ } catch(KeyFileError e) {
+ warning(_("KeyFile Error: %s\n"), e.message);
} catch(IOError e) {
- error("IOError: %s\n", e.message);
+ error(_("IO Error: %s\n"), e.message);
+ } catch(DBusError e) {
+ error(_("DBus Error: %s\n"), e.message);
+ }
+
+ try {
+ shortname = cfg.get_string("GENERAL", "shortname");
} catch(KeyFileError e) {
- error("KeyFileError: %s\n", e.message);
+ shortname = "";
+ warning(_("KeyFile Error: %s\n"), e.message);
+ } catch(IOError e) {
+ error(_("IO Error: %s\n"), e.message);
+ } catch(DBusError e) {
+ error(_("DBus Error: %s\n"), e.message);
}
- stdout.printf("Web Server Port: %u\n", port);
- stdout.printf("TLS certificate: %s\n", certificate);
- stdout.printf("TLS private key: %s\n", privatekey);
+ stdout.printf(_("Web Server Port: %u\n"), port);
+ stdout.printf(_("TLS certificate: %s\n"), certificate);
+ stdout.printf(_("TLS private key: %s\n"), privatekey);
/* attach WebServer to MainLoop */
try {
@@ -59,7 +80,7 @@ public static int main(string[] args) {
cert = new TlsCertificate.from_files(certificate, privatekey);
new WebServer(port, cert);
} catch(Error e) {
- error("Could not start Webserver: %s\n", e.message);
+ error(_("Could not start Webserver: %s\n"), e.message);
}
/* start MainLoop */
diff --git a/src/web/template.vala b/src/web/template.vala
index b5265d8..009ebcf 100644
--- a/src/web/template.vala
+++ b/src/web/template.vala
@@ -24,44 +24,48 @@ public class WebTemplate {
public uint8[] data { get { return template.data; } }
public WebTemplate(string file, WebSession login) throws TemplateError {
- var b = File.new_for_path(templatedir+"base.html");
- var m = File.new_for_path(templatedir+"menu.html");
- var f = File.new_for_path(templatedir+file);
+ var bf = Path.build_filename(templatedir, "base.html");
+ var b = File.new_for_path(bf);
+ var mf = Path.build_filename(templatedir, "menu.html");
+ var m = File.new_for_path(mf);
+ var ff = Path.build_filename(templatedir, file);
+ var f = File.new_for_path(ff);
File fauth;
if(login.logged_in)
- fauth = File.new_for_path(templatedir+"menu_logout.html");
+ fauth = File.new_for_path(Path.build_filename(templatedir, "menu_logout.html"));
else
- fauth = File.new_for_path(templatedir+"menu_login.html");
+ fauth = File.new_for_path(Path.build_filename(templatedir, "menu_login.html"));
uint8[] basis, menu, template, auth;
if(!b.query_exists())
- throw new TemplateError.NOT_FOUND(templatedir+"base.html not found!");
+ throw new TemplateError.NOT_FOUND(_("%s not found!").printf(bf));
if(!m.query_exists())
- throw new TemplateError.NOT_FOUND(templatedir+"menu.html not found!");
+ throw new TemplateError.NOT_FOUND(_("%s not found!").printf(mf));
if(!fauth.query_exists())
- throw new TemplateError.NOT_FOUND(fauth.get_path()+" not found!");
+ throw new TemplateError.NOT_FOUND(_("%s not found!").printf(fauth.get_path()));
if(!f.query_exists())
- throw new TemplateError.NOT_FOUND(templatedir+file+" not found!");
+ throw new TemplateError.NOT_FOUND(_("%s not found!").printf(ff));
try {
if(!b.load_contents(null, out basis, null))
- throw new TemplateError.NOT_LOADABLE(templatedir+"base.html could not be loaded!");
+ throw new TemplateError.NOT_LOADABLE(_("%s could not be loaded!").printf(bf));
if(!m.load_contents(null, out menu, null))
- throw new TemplateError.NOT_LOADABLE(templatedir+"menu.html could not be loaded!");
+ throw new TemplateError.NOT_LOADABLE(_("%s could not be loaded!").printf(mf));
if(!fauth.load_contents(null, out auth, null))
- throw new TemplateError.NOT_LOADABLE(fauth.get_path()+" could not be loaded!");
+ throw new TemplateError.NOT_LOADABLE(_("%s could not be loaded!").printf(fauth.get_path()));
if(!f.load_contents(null, out template, null))
- throw new TemplateError.NOT_LOADABLE(templatedir+file+" could not be loaded!");
+ throw new TemplateError.NOT_LOADABLE(_("%s could not be loaded!").printf(ff));
} catch(Error e) {
- throw new TemplateError.NOT_LOADABLE("could not load templates!");
+ throw new TemplateError.NOT_LOADABLE(_("could not load templates!"));
}
this.template = ((string) basis).replace("{{{NAVBAR}}}", ((string) menu));
+ this.template = this.template.replace("{{{SHORTNAME}}}", shortname);
this.template = this.template.replace("{{{AUTH}}}", ((string) auth));
this.template = this.template.replace("{{{CONTENT}}}", ((string) template));
this.template = this.template.replace("{{{USERNAME}}}", login.name);
@@ -71,17 +75,18 @@ public class WebTemplate {
}
public WebTemplate.DATA(string file) throws TemplateError {
- var f = File.new_for_path(templatedir+file);
+ var ff = Path.build_filename(templatedir, file);
+ var f = File.new_for_path(ff);
uint8[] template;
if(!f.query_exists())
- throw new TemplateError.NOT_FOUND(templatedir+file+" not found!");
+ throw new TemplateError.NOT_FOUND(_("%s not found!").printf(ff));
try {
if(!f.load_contents(null, out template, null))
- throw new TemplateError.NOT_LOADABLE(templatedir+file+" could not be loaded!");
+ throw new TemplateError.NOT_LOADABLE(_("%s could not be loaded!").printf(ff));
} catch(Error e) {
- throw new TemplateError.NOT_LOADABLE("could not load templates!");
+ throw new TemplateError.NOT_LOADABLE(_("could not load templates!"));
}
this.template = (string) template;
diff --git a/src/web/web.vala b/src/web/web.vala
index 5a44409..3098308 100644
--- a/src/web/web.vala
+++ b/src/web/web.vala
@@ -1,4 +1,5 @@
/* Copyright 2012, Sebastian Reichel <sre@ring0.de>
+ * Copyright 2017-2018, Johannes Rudolph <johannes.rudolph@gmx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -20,7 +21,8 @@ public class WebServer {
try {
var l = new WebSession(server, msg, path, query, client);
var t = new WebTemplate("index.html", l);
- t.replace("TITLE", "KtT Shop System");
+ t.replace("TITLE", shortname + " Shop System");
+ t.replace("SHORTNAME", shortname);
t.menu_set_active("home");
msg.set_response("text/html", Soup.MemoryUse.COPY, t.data);
msg.set_status(200);
@@ -31,6 +33,8 @@ public class WebServer {
handler_400(server, msg, path, query, client, e.message);
} catch(IOError e) {
handler_400(server, msg, path, query, client, e.message);
+ } catch(DBusError e) {
+ handler_400(server, msg, path, query, client, e.message);
}
}
@@ -39,7 +43,7 @@ public class WebServer {
var l = new WebSession(server, msg, path, query, client);
l.logout();
var t = new WebTemplate("logout.html", l);
- t.replace("TITLE", "KtT Shop System");
+ t.replace("TITLE", shortname + " Shop System");
t.menu_set_active("home");
msg.set_response("text/html", Soup.MemoryUse.COPY, t.data);
msg.set_status(200);
@@ -50,6 +54,8 @@ public class WebServer {
handler_400(server, msg, path, query, client, e.message);
} catch(IOError e) {
handler_400(server, msg, path, query, client, e.message);
+ } catch(DBusError e) {
+ handler_400(server, msg, path, query, client, e.message);
}
}
@@ -96,7 +102,7 @@ public class WebServer {
}
var t = new WebTemplate("users/index.html", session);
- t.replace("TITLE", "KtT Shop System: User");
+ t.replace("TITLE", shortname + " Shop System: User");
t.menu_set_active("users");
var data = "";
foreach(var m in db.get_member_ids()) {
@@ -118,6 +124,8 @@ public class WebServer {
handler_400(server, msg, path, query, client, e.message);
} catch(IOError e) {
handler_400(server, msg, path, query, client, e.message);
+ } catch(DBusError e) {
+ handler_400(server, msg, path, query, client, e.message);
}
}
@@ -130,7 +138,7 @@ public class WebServer {
}
var t = new WebTemplate("users/import-pgp.html", session);
- t.replace("TITLE", "KtT Shop System: PGP Key Import");
+ t.replace("TITLE", shortname + " Shop System: PGP Key Import");
t.menu_set_active("users");
Soup.Buffer filedata;
@@ -171,6 +179,8 @@ public class WebServer {
handler_400(server, msg, path, query, client, e.message);
} catch(IOError e) {
handler_400(server, msg, path, query, client, e.message);
+ } catch(DBusError e) {
+ handler_400(server, msg, path, query, client, e.message);
}
}
@@ -182,7 +192,7 @@ public class WebServer {
return;
}
var t = new WebTemplate("users/import.html", session);
- t.replace("TITLE", "KtT Shop System: User Import");
+ t.replace("TITLE", shortname + " Shop System: User Import");
t.menu_set_active("users");
Soup.Buffer filedata;
@@ -275,6 +285,8 @@ public class WebServer {
handler_400(server, msg, path, query, client, e.message);
} catch(IOError e) {
handler_400(server, msg, path, query, client, e.message);
+ } catch(DBusError e) {
+ handler_400(server, msg, path, query, client, e.message);
}
}
@@ -315,6 +327,8 @@ public class WebServer {
handler_400(server, msg, path, query, client, e.message);
} catch(IOError e) {
handler_400(server, msg, path, query, client, e.message);
+ } catch(DBusError e) {
+ handler_400(server, msg, path, query, client, e.message);
}
}
@@ -322,12 +336,12 @@ public class WebServer {
try {
var session = new WebSession(server, msg, path, query, client);
- if(id != session.user && !(session.superuser || session.auth_users)) {
+ if(id == 0 || id != session.user && !(session.superuser || session.auth_users)) {
handler_403(server, msg, path, query, client);
return;
}
var t = new WebTemplate("users/entry.html", session);
- t.replace("TITLE", "KtT Shop System: User Info %llu".printf(id));
+ t.replace("TITLE", shortname + " Shop System: User Info %llu".printf(id));
t.menu_set_active("users");
var userinfo = db.get_user_info(id);
@@ -343,6 +357,7 @@ public class WebServer {
t.replace("PGPKEYID", userinfo.pgp);
t.replace("DISABLED", userinfo.disabled ? "true" : "false");
t.replace("HIDDEN", userinfo.hidden ? "true" : "false");
+ t.replace("RFID", string.joinv("<br>",userinfo.rfid));
var userauth = db.get_user_auth(id);
t.replace("ISSUPERUSER", userauth.superuser ? "true" : "false");
@@ -400,6 +415,8 @@ public class WebServer {
handler_400(server, msg, path, query, client, e.message);
} catch(IOError e) {
handler_400(server, msg, path, query, client, e.message);
+ } catch(DBusError e) {
+ handler_400(server, msg, path, query, client, e.message);
}
}
@@ -431,7 +448,7 @@ public class WebServer {
return;
}
var t = new WebTemplate("users/invoice.html", l);
- t.replace("TITLE", "KtT Shop System: User Invoice %llu".printf(id));
+ t.replace("TITLE", shortname + " Shop System: User Invoice %llu".printf(id));
t.menu_set_active("users");
/* years, in which something has been purchased by the user */
@@ -517,6 +534,8 @@ public class WebServer {
handler_400(server, msg, path, query, client, e.message);
} catch(IOError e) {
handler_400(server, msg, path, query, client, e.message);
+ } catch(DBusError e) {
+ handler_400(server, msg, path, query, client, e.message);
}
}
@@ -553,12 +572,12 @@ public class WebServer {
try {
var l = new WebSession(server, msg, path, query, client);
var t = new WebTemplate("products/index.html", l);
- t.replace("TITLE", "KtT Shop System: Product List");
+ t.replace("TITLE", shortname + " Shop System: Product List");
t.menu_set_active("products");
string table = "";
foreach(var e in db.get_stock()) {
- table += @"<tr><td><a href=\"/products/$(e.id)\">$(e.id)</a></td><td><a href=\"/products/$(e.id)\">$(e.name)</a></td><td>$(e.category)</td><td>$(e.amount)</td><td>$(e.memberprice)€</td><td>$(e.guestprice)€</td></tr>";
+ table += @"<tr><td><a href=\"/products/$(e.ean)\">$(e.ean)</a></td><td><a href=\"/products/$(e.ean)\">$(e.name)</a></td><td>$(e.category)</td><td>$(e.amount)</td><td>$(e.memberprice)€</td><td>$(e.guestprice)€</td></tr>";
}
t.replace("DATA", table);
@@ -583,6 +602,8 @@ public class WebServer {
handler_400(server, msg, path, query, client, e.message);
} catch(IOError e) {
handler_400(server, msg, path, query, client, e.message);
+ } catch(DBusError e) {
+ handler_400(server, msg, path, query, client, e.message);
}
}
@@ -590,7 +611,7 @@ public class WebServer {
try {
var l = new WebSession(server, msg, path, query, client);
var t = new WebTemplate("products/bestbefore.html", l);
- t.replace("TITLE", "KtT Shop System: Best Before List");
+ t.replace("TITLE", shortname + " Shop System: Best Before List");
t.menu_set_active("products");
string table = "";
@@ -615,6 +636,8 @@ public class WebServer {
handler_400(server, msg, path, query, client, e.message);
} catch(IOError e) {
handler_400(server, msg, path, query, client, e.message);
+ } catch(DBusError e) {
+ handler_400(server, msg, path, query, client, e.message);
}
}
@@ -638,6 +661,8 @@ public class WebServer {
handler_400(server, msg, path, query, client, e.message);
} catch(IOError e) {
handler_400(server, msg, path, query, client, e.message);
+ } catch(DBusError e) {
+ handler_400(server, msg, path, query, client, e.message);
}
}
@@ -645,7 +670,7 @@ public class WebServer {
try {
var l = new WebSession(server, msg, path, query, client);
var t = new WebTemplate("products/entry.html", l);
- t.replace("TITLE", "KtT Shop System: Product %llu".printf(id));
+ t.replace("TITLE", shortname + " Shop System: Product %llu".printf(id));
t.menu_set_active("products");
/* ean */
@@ -718,6 +743,8 @@ public class WebServer {
handler_400(server, msg, path, query, client, e.message);
} catch(IOError e) {
handler_400(server, msg, path, query, client, e.message);
+ } catch(DBusError e) {
+ handler_400(server, msg, path, query, client, e.message);
}
}
@@ -734,9 +761,7 @@ public class WebServer {
var pdfdata = pdfStock.generate(allProducts);
msg.set_status(200);
msg.set_response("application/pdf", Soup.MemoryUse.COPY, pdfdata);
- } catch(DatabaseError e) {
- handler_400(server, msg, path, query, client, e.message);
- } catch(IOError e) {
+ } catch(Error e) {
handler_400(server, msg, path, query, client, e.message);
}
}
@@ -765,18 +790,18 @@ public class WebServer {
if (!postdata.contains("apply_inventory")) {
// PUT / show changes and request an apply
foreach(var e in db.get_stock()) {
- var realAmountStr = postdata.get(e.id);
+ var realAmountStr = postdata.get(e.ean.to_string());
if (realAmountStr != null && realAmountStr.length > 0) {
var realAmount = int.parse(realAmountStr);
var amountStyleClass = "success";
if (realAmount < e.amount) {
- amountStyleClass = "error";
+ amountStyleClass = "danger";
} else if (realAmount > e.amount) {
amountStyleClass = "info";
}
var diff = realAmount - e.amount;
- table += @"<tr class='$(amountStyleClass)'><td>$(e.id)</td><td>$(e.name)</td><td>$(e.category)</td><td>$(e.amount)</td><td>"
- + @"$(realAmount) <strong>[ $(diff) ]</strong><input type=\"hidden\" name=\"$(e.id)\" value=\"$(realAmount)\"></td></tr>";
+ table += @"<tr class='$(amountStyleClass)'><td>$(e.ean)</td><td>$(e.name)</td><td>$(e.category)</td><td>$(e.amount)</td><td>"
+ + @"$(realAmount) <strong>[ $(diff) ]</strong><input type=\"hidden\" name=\"$(e.ean)\" value=\"$(realAmount)\"></td></tr>";
}
}
actionTemplate = """<input type="hidden" name="apply_inventory" value="true"><button type="submit" class="btn btn-primary">Apply Changes</button>""";
@@ -800,9 +825,9 @@ public class WebServer {
var supplierId = int.parse(postdata.get("supplierId"));
var userId = int.parse(postdata.get("userId"));
foreach(var e in db.get_stock()) {
- var realAmountStr = postdata.get(e.id);
+ var realAmountStr = postdata.get(e.ean.to_string());
if (realAmountStr != null && realAmountStr.length > 0) {
- var pId = uint64.parse(e.id);
+ var pId = uint64.parse(e.ean.to_string());
var realAmount = int.parse(realAmountStr);
if (realAmount < e.amount) {
// Loss transaction
@@ -835,7 +860,7 @@ public class WebServer {
// default GET / list products with a form
var tabindexCounter = 1;
foreach(var e in db.get_stock()) {
- table += @"<tr><td><a href=\"/products/$(e.id)\">$(e.id)</a></td><td><a href=\"/products/$(e.id)\">$(e.name)</a></td><td>$(e.category)</td><td>$(e.amount)</td><td><input type=\"number\" name=\"$(e.id)\" tabindex=\"$(tabindexCounter)\"></td></tr>";
+ table += @"<tr><td><a href=\"/products/$(e.ean)\">$(e.ean)</a></td><td><a href=\"/products/$(e.ean)\">$(e.name)</a></td><td>$(e.category)</td><td>$(e.amount)</td><td><input type=\"number\" name=\"$(e.ean)\" tabindex=\"$(tabindexCounter)\"></td></tr>";
tabindexCounter++;
}
actionTemplate = """<button type="submit" class="btn btn-primary">Preview</button>""";
@@ -857,9 +882,7 @@ public class WebServer {
} catch(TemplateError e) {
stderr.printf(e.message+"\n");
handler_404(server, msg, path, query, client);
- } catch(DatabaseError e) {
- handler_400(server, msg, path, query, client, e.message);
- } catch(IOError e) {
+ } catch(Error e) {
handler_400(server, msg, path, query, client, e.message);
}
}
@@ -868,7 +891,7 @@ public class WebServer {
try {
var session = new WebSession(server, msg, path, query, client);
var template = new WebTemplate("products/new.html", session);
- template.replace("TITLE", "KtT Shop System: New Product");
+ template.replace("TITLE", shortname + " Shop System: New Product");
template.menu_set_active("products");
if(!session.superuser && !session.auth_products) {
@@ -911,6 +934,8 @@ public class WebServer {
handler_400(server, msg, path, query, client, e.message);
} catch(IOError e) {
handler_400(server, msg, path, query, client, e.message);
+ } catch(DBusError e) {
+ handler_400(server, msg, path, query, client, e.message);
}
}
@@ -924,7 +949,7 @@ public class WebServer {
}
var template = new WebTemplate("products/restock.html", session);
- template.replace("TITLE", "KtT Shop System: Restock Product %llu".printf(id));
+ template.replace("TITLE", shortname + " Shop System: Restock Product %llu".printf(id));
template.replace("NAME", db.get_product_name(id));
template.menu_set_active("products");
@@ -968,6 +993,8 @@ public class WebServer {
handler_400(server, msg, path, query, client, e.message);
} catch(IOError e) {
handler_400(server, msg, path, query, client, e.message);
+ } catch(DBusError e) {
+ handler_400(server, msg, path, query, client, e.message);
}
}
@@ -982,7 +1009,7 @@ public class WebServer {
}
var template = new WebTemplate("products/newprice.html", session);
- template.replace("TITLE", "KtT Shop System: New Price for Product %llu".printf(id));
+ template.replace("TITLE", shortname + " Shop System: New Price for Product %llu".printf(id));
template.replace("NAME", db.get_product_name(id));
template.menu_set_active("products");
@@ -1014,6 +1041,8 @@ public class WebServer {
handler_400(server, msg, path, query, client, e.message);
} catch(IOError e) {
handler_400(server, msg, path, query, client, e.message);
+ } catch(DBusError e) {
+ handler_400(server, msg, path, query, client, e.message);
}
}
@@ -1021,7 +1050,7 @@ public class WebServer {
try {
var l = new WebSession(server, msg, path, query, client);
var t = new WebTemplate("aliases/index.html", l);
- t.replace("TITLE", "KtT Shop System: Alias List");
+ t.replace("TITLE", shortname + " Shop System: Alias List");
t.menu_set_active("aliases");
string table = "";
@@ -1046,6 +1075,8 @@ public class WebServer {
handler_400(server, msg, path, query, client, e.message);
} catch(IOError e) {
handler_400(server, msg, path, query, client, e.message);
+ } catch(DBusError e) {
+ handler_400(server, msg, path, query, client, e.message);
}
}
@@ -1053,7 +1084,7 @@ public class WebServer {
try {
var session = new WebSession(server, msg, path, query, client);
var template = new WebTemplate("aliases/new.html", session);
- template.replace("TITLE", "KtT Shop System: New Alias");
+ template.replace("TITLE", shortname + " Shop System: New Alias");
template.menu_set_active("aliases");
if(!session.superuser && !session.auth_products) {
@@ -1093,6 +1124,8 @@ public class WebServer {
handler_400(server, msg, path, query, client, e.message);
} catch(IOError e) {
handler_400(server, msg, path, query, client, e.message);
+ } catch(DBusError e) {
+ handler_400(server, msg, path, query, client, e.message);
}
}
@@ -1101,7 +1134,7 @@ public class WebServer {
try {
var l = new WebSession(server, msg, path, query, client);
var t = new WebTemplate("stats/index.html", l);
- t.replace("TITLE", "KtT Shop System: Statistics");
+ t.replace("TITLE", shortname + " Shop System: Statistics");
t.menu_set_active("stats");
var stats = db.get_stats_info();
@@ -1134,7 +1167,7 @@ public class WebServer {
var t = new WebTemplate("stats/stock.html", l);
string data = db.get_stats_stock().json;
t.replace("DATA", data);
- t.replace("TITLE", "KtT Shop System: Statistics: Stock");
+ t.replace("TITLE", shortname + " Shop System: Statistics: Stock");
t.menu_set_active("stats");
msg.set_response("text/html", Soup.MemoryUse.COPY, t.data);
msg.set_status(200);
@@ -1150,7 +1183,7 @@ public class WebServer {
var t = new WebTemplate("stats/profit_per_day.html", l);
string data = db.get_stats_profit_per_day().json;
t.replace("DATA", data);
- t.replace("TITLE", "KtT Shop System: Statistics: Profit");
+ t.replace("TITLE", shortname + " Shop System: Statistics: Profit");
t.menu_set_active("stats");
msg.set_response("text/html", Soup.MemoryUse.COPY, t.data);
msg.set_status(200);
@@ -1166,7 +1199,7 @@ public class WebServer {
var t = new WebTemplate("stats/profit_per_weekday.html", l);
string data = db.get_stats_profit_per_weekday().json;
t.replace("DATA", data);
- t.replace("TITLE", "KtT Shop System: Statistics: Profit/Weekday");
+ t.replace("TITLE", shortname + " Shop System: Statistics: Profit/Weekday");
t.menu_set_active("stats");
msg.set_response("text/html", Soup.MemoryUse.COPY, t.data);
msg.set_status(200);
@@ -1182,7 +1215,7 @@ public class WebServer {
var t = new WebTemplate("stats/profit_per_product.html", l);
string data = db.get_stats_profit_per_products().json;
t.replace("DATA", data);
- t.replace("TITLE", "KtT Shop System: Statistics: Profit/Product");
+ t.replace("TITLE", shortname + " Shop System: Statistics: Profit/Product");
t.menu_set_active("stats");
msg.set_response("text/html", Soup.MemoryUse.COPY, t.data);
msg.set_status(200);
@@ -1217,7 +1250,7 @@ public class WebServer {
void handler_img(Soup.Server server, Soup.Message msg, string path, GLib.HashTable? query, Soup.ClientContext client) {
try {
- var f = File.new_for_path(templatedir+path);
+ var f = File.new_for_path(Path.build_filename(templatedir, path));
uint8[] data = null;
if(f.query_exists() && f.load_contents(null, out data, null)) {
@@ -1226,7 +1259,25 @@ public class WebServer {
return;
}
} catch(Error e) {
- error("there has been some error: %s!\n", e.message);
+ error(_("Error: %s\n"), e.message);
+ }
+
+ handler_404(server, msg, path, query, client);
+ return;
+ }
+
+ void handler_font(Soup.Server server, Soup.Message msg, string path, GLib.HashTable? query, Soup.ClientContext client) {
+ try {
+ var f = File.new_for_path(Path.build_filename(templatedir, path));
+ uint8[] data = null;
+
+ if(f.query_exists() && f.load_contents(null, out data, null)) {
+ msg.set_response("application/octet-stream; charset=binary", Soup.MemoryUse.COPY, data);
+ msg.set_status(200);
+ return;
+ }
+ } catch(Error e) {
+ error(_("Error: %s\n"), e.message);
}
handler_404(server, msg, path, query, client);
@@ -1260,6 +1311,8 @@ public class WebServer {
} catch(IOError e) {
stderr.printf(e.message+"\n");
handler_400_fallback(server, msg, path, query, client);
+ } catch(DBusError e) {
+ handler_400(server, msg, path, query, client, e.message);
}
}
@@ -1284,6 +1337,8 @@ public class WebServer {
handler_400(server, msg, path, query, client, e.message);
} catch(IOError e) {
handler_400(server, msg, path, query, client, e.message);
+ } catch(DBusError e) {
+ handler_400(server, msg, path, query, client, e.message);
}
}
@@ -1291,7 +1346,7 @@ public class WebServer {
try {
var session = new WebSession(server, msg, path, query, client);
var template = new WebTemplate("errors/todo.html", session);
- template.replace("TITLE", "KtT Shop System: ToDo");
+ template.replace("TITLE", shortname + " Shop System: ToDo");
template.menu_set_active("");
msg.set_response("text/html", Soup.MemoryUse.COPY, template.data);
msg.set_status(200);
@@ -1302,6 +1357,8 @@ public class WebServer {
handler_400(server, msg, path, query, client, e.message);
} catch(IOError e) {
handler_400(server, msg, path, query, client, e.message);
+ } catch(DBusError e) {
+ handler_400(server, msg, path, query, client, e.message);
}
}
@@ -1336,7 +1393,7 @@ public class WebServer {
hist += "</tr>\n";
}
- template.replace("TITLE", "KtT Shop System: Cashbox");
+ template.replace("TITLE", shortname + " Shop System: Cashbox");
template.replace("CASHBOX_STATUS", status);
template.replace("CASHBOX_HISTORY", hist);
template.menu_set_active("cashbox");
@@ -1349,6 +1406,8 @@ public class WebServer {
handler_400(server, msg, path, query, client, e.message);
} catch(IOError e) {
handler_400(server, msg, path, query, client, e.message);
+ } catch(DBusError e) {
+ handler_400(server, msg, path, query, client, e.message);
}
}
@@ -1362,7 +1421,7 @@ public class WebServer {
}
var template = new WebTemplate("cashbox/add.html", session);
- template.replace("TITLE", "KtT Shop System: Cashbox Balance");
+ template.replace("TITLE", shortname + " Shop System: Cashbox Balance");
template.menu_set_active("cashbox");
bool error = false;
@@ -1420,6 +1479,8 @@ public class WebServer {
handler_400(server, msg, path, query, client, e.message);
} catch(IOError e) {
handler_400(server, msg, path, query, client, e.message);
+ } catch(DBusError e) {
+ handler_400(server, msg, path, query, client, e.message);
}
}
@@ -1434,7 +1495,7 @@ public class WebServer {
try {
var session = new WebSession(server, msg, path, query, client);
var template = new WebTemplate("cashbox/selection.html", session);
- template.replace("TITLE", "KtT Shop System: Cashbox Detail");
+ template.replace("TITLE", shortname + " Shop System: Cashbox Detail");
template.menu_set_active("cashbox");
msg.set_response("text/html", Soup.MemoryUse.COPY, template.data);
msg.set_status(200);
@@ -1445,6 +1506,8 @@ public class WebServer {
handler_400(server, msg, path, query, client, e.message);
} catch(IOError e) {
handler_400(server, msg, path, query, client, e.message);
+ } catch(DBusError e) {
+ handler_400(server, msg, path, query, client, e.message);
}
}
}
@@ -1504,9 +1567,8 @@ public class WebServer {
}
var template = new WebTemplate("cashbox/detail.html", session);
- template.replace("TITLE", "KtT Shop System: Cashbox Detail");
+ template.replace("TITLE", shortname + " Shop System: Cashbox Detail");
template.menu_set_active("cashbox");
-
template.replace("DATE", start.format("%B %Y"));
template.replace("DEBIT", debit.to_string());
template.replace("LOSS", loss.to_string());
@@ -1526,6 +1588,8 @@ public class WebServer {
handler_400(server, msg, path, query, client, e.message);
} catch(IOError e) {
handler_400(server, msg, path, query, client, e.message);
+ } catch(DBusError e) {
+ handler_400(server, msg, path, query, client, e.message);
}
}
@@ -1537,7 +1601,7 @@ public class WebServer {
options |= Soup.ServerListenOptions.HTTPS;
if(!srv.listen_all(port, options)) {
- throw new GLib.IOError.FAILED("Could not setup webserver!");
+ throw new GLib.IOError.FAILED(_("Could not setup webserver!"));
}
/* index */
@@ -1550,6 +1614,7 @@ public class WebServer {
srv.add_handler("/js", handler_js);
srv.add_handler("/css", handler_css);
srv.add_handler("/img", handler_img);
+ srv.add_handler("/fonts", handler_font);
/* cashbox */
srv.add_handler("/cashbox", handler_cashbox);
diff --git a/src/web/websession.vala b/src/web/websession.vala
index ae3cafc..85fd516 100644
--- a/src/web/websession.vala
+++ b/src/web/websession.vala
@@ -82,7 +82,7 @@ public class WebSession {
return result;
}
- private void setup_auth(int user) throws DatabaseError, IOError {
+ private void setup_auth(int user) throws DatabaseError, IOError, DBusError {
var auth = db.get_user_auth(user);
this.disabled = db.user_is_disabled(user);
this.superuser = auth.superuser;
@@ -92,7 +92,7 @@ public class WebSession {
this.logged_in = true;
}
- public void logout() throws DatabaseError, IOError {
+ public void logout() throws DatabaseError, IOError, DBusError {
if(logged_in) {
db.set_sessionid(user, "");
superuser = false;
@@ -103,7 +103,7 @@ public class WebSession {
}
}
- public WebSession(Soup.Server server, Soup.Message msg, string path, GLib.HashTable<string,string>? query, Soup.ClientContext client) throws DatabaseError, IOError {
+ public WebSession(Soup.Server server, Soup.Message msg, string path, GLib.HashTable<string,string>? query, Soup.ClientContext client) throws DatabaseError, IOError, DBusError {
var cookies = Soup.cookies_from_request(msg);
/* Check for existing session */
@@ -128,9 +128,9 @@ public class WebSession {
return;
}
var form_data = Soup.Form.decode((string) msg.request_body.data);
- if (form_data == null || !form_data.contains("user") || !form_data.contains("password")) {
- return;
- }
+ if (form_data == null || !form_data.contains("user") || !form_data.contains("password")) {
+ return;
+ }
/* get credentials */
@@ -162,7 +162,7 @@ public class WebSession {
setup_auth(user);
} else {
- stderr.printf("Login for user id %d failed\n", userid);
+ stderr.printf(_("Login for user id %d failed\n"), userid);
/* login failed */
failed=true;
}