changeset 121:804211b988aa

Move zeiterfassung and zeitsort to an own module in getan Both scripts can be installed via setup.py
author Björn Ricks <bjoern.ricks@intevation.de>
date Mon, 12 Dec 2011 10:19:52 +0100
parents efff8b9e7046
children 653767ecb0fe
files contrib/zeiterfassung contrib/zeitsort getan/contrib/__init__.py getan/contrib/zeiterfassung.py getan/contrib/zeitsort.py setup.py
diffstat 5 files changed, 325 insertions(+), 322 deletions(-) [+]
line wrap: on
line diff
--- a/contrib/zeiterfassung	Mon Dec 12 09:58:17 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,272 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-# zeiterfassung
-# -------------
-# (c) 2008 by Sascha L. Teichmann <sascha.teichmann@intevation.de>
-#
-# Simple script which generates lines for zeiterfassung.txt files.
-#
-# This is Free Software licensed under the terms of GPLv3 or later.
-# For details see LICENSE coming with the source of 'getan'.
-#
-import os
-import os.path
-import sys
-import getopt
-import re
-import codecs
-
-from pysqlite2 import dbapi2 as db
-
-from datetime import date, datetime
-
-DEFAULT_DATABASE = "time.db"
-
-TYPE_OF_ENTRY = "?"
-
-WORKPACKAGE = re.compile("^\[(\w*)(\s|\])")
-
-USAGE = '''usage: %s <options>
-    with <options>
-    [--user=|-u <user>]        : Name of user,          default: $USER
-    [--database=|-d <database>]: getan database,        default: time.db
-    [--project=|-p <key>]      : Key of output project, default: all
-    [--encoding=|-e encoding]  : encoding of output,    default: none
-    [--week=]|-w <week>]       : week of year
-    [--year=]|-y <year>]       : year
-    [--list|-l]                : list all projects
-    [--help|-h]                : This text
-    [--emtpy|-m]               : show empty projects
-    [--lastweek|-c]            : entries of last working week'''
-
-LIST_PROJECTS = '''
-SELECT key, description, active FROM projects
-'''
-
-PROJECT_ID_BY_KEY = '''
-SELECT id, description FROM projects where key = :key
-'''
-
-ALL_PROJECT_IDS = '''
-SELECT id, key, description FROM projects
-'''
-
-WEEK_ENTRIES = '''
-SELECT 
-    date(start_time) AS t, 
-    sum(strftime('%s', stop_time) - strftime('%s', start_time)), 
-    'no description' AS description
-FROM entries 
-WHERE 
-    project_id = :project_id AND 
-    (strftime('%Y', start_time) ) = :year AND
-    (description IS NULL or length(description) = 0) -- trim() function is missing
-    AND (strftime('%W', start_time) = :week OR strftime('%W', stop_time) = :week)
-GROUP BY round(julianday(start_time))
-UNION
-SELECT date(start_time) AS s, strftime('%s', stop_time) - strftime('%s', start_time), description
-FROM entries 
-WHERE 
-    project_id = :project_id AND 
-    (strftime('%Y', start_time) ) = :year AND
-    description IS NOT NULL AND length(description) > 0
-    AND (strftime('%W', start_time) = :week OR strftime('%W', stop_time) = :week)
-ORDER BY t
-'''
-
-ENTRIES = '''
-SELECT 
-    date(start_time), 
-    sum(strftime('%s', stop_time) - strftime('%s', start_time)), 
-    'no description' AS description
-FROM entries 
-WHERE 
-    project_id = :project_id AND 
-    (description IS NULL or length(description) = 0) -- trim() function is missing
-GROUP BY round(julianday(start_time))
-UNION
-SELECT date(start_time), strftime('%s', stop_time) - strftime('%s', start_time), description
-FROM entries 
-WHERE 
-    project_id = :project_id AND 
-    description IS NOT NULL AND length(description) > 0
-'''
-
-ENTRIES_YEAR = '''
-SELECT 
-    date(start_time), 
-    sum(strftime('%s', stop_time) - strftime('%s', start_time)), 
-    'no description' AS description
-FROM entries 
-WHERE 
-    project_id = :project_id AND 
-    (description IS NULL or length(description) = 0) -- trim() function is missing
-GROUP BY round(julianday(start_time))
-UNION
-SELECT date(start_time), strftime('%s', stop_time) - strftime('%s', start_time), description
-FROM entries 
-WHERE 
-    project_id = :project_id AND 
-    (strftime('%Y', start_time) ) = :year AND
-    description IS NOT NULL AND length(description) > 0
-'''
-
-def human_time(s):
-    h = s / 3600
-    m = (s % 3600) / 60
-    if (s % 60) >= 30:
-        m += 1
-        if m == 60:
-            m = 0
-            h += 1
-    return "%2d:%02d" % (h, m)
-
-class TermError(Exception):
-
-    def __init__(self, msg):
-        Exception.__init__(self)
-        self.msg = msg
-
-    def __str__(self):
-        return repr(self.msg)
-
-def tolerantClose(c):
-    if c:
-        try: c.close()
-        except: pass
-
-def usage(exit_code = 0):
-    print USAGE % sys.argv[0]
-    sys.exit(exit_code)
-
-def main():
-
-    database      = DEFAULT_DATABASE
-    user          = None
-    list_projects = False
-    project       = None
-    encoding      = None
-    week          = None
-    year          = None
-    empty_proj    = False
-
-    opts, args = getopt.getopt(
-        sys.argv[1:],
-        'd:u:p:e:hl:w:y:mc',
-        ['database=', 'user=', 'project=', 'encoding=', 'help', 'list', 'week=',
-            'year=', 'empty', 'lastweek'])
-
-    for opt, val in opts:
-        if opt in ("--database", "-d"):
-            database = val
-        elif opt in ("--user", "-u"):
-            user = val
-        elif opt in ("--project", "-p"):
-            project = val
-        elif opt in ("--encoding", "-e"):
-            encoding = val
-        elif opt in ("--help", "-h"):
-            usage()
-        elif opt in ("--list", "-l"):
-            list_projects = True
-        elif opt in ("--week", "-w"):
-            week = val
-        elif opt in ("--lastweek", "-c") and not week:
-            currentweek = datetime.now().isocalendar()[1]
-            lastweek = currentweek - 1
-            if lastweek <= 0:
-                lastweek = 52
-            week = str(lastweek)
-        elif opt in ("--year", "-y"):
-            year = val
-        elif opt in ("--empty", "-m"):
-            empty_proj = True
-
-    if not user:
-        user = os.getenv("USER")
-
-    proj_year = year
-    if not proj_year:
-        proj_year = date.today().strftime("%Y")
-
-    if encoding:
-        Writer = codecs.getwriter(encoding)
-        sys.stdout = Writer(sys.stdout)
-
-    if not os.path.isfile(database):
-        print >> sys.stderr, "'%s' does not exist or is not a file." % database
-        sys.exit(1)
-
-    con, cur = None, None
-    try:
-        try:
-            con = db.connect(database)
-            if encoding:
-                con.text_factory = lambda s: s.decode(encoding)
-            cur = con.cursor()
-
-            if list_projects:
-                cur.execute(LIST_PROJECTS)
-                while True:
-                    row = cur.fetchone()
-                    if not row: break
-                    print "%s %s %s" % (row[0], row[2] and "*" or "-", row[1])
-            else:
-                if project:
-                    cur.execute(PROJECT_ID_BY_KEY, { 'key': project })
-                    row = cur.fetchone()
-                    if row is None:
-                        raise TermError("There is no project with key '%s'" % project)
-                    project_ids = [[row[0], project, row[1]]]
-                else:
-                    cur.execute(ALL_PROJECT_IDS);
-                    project_ids = cur.fetchall()
-
-                total = 0
-                for project_id, project, proj_desc in project_ids:
-                    if not week is None:
-                        cur.execute(WEEK_ENTRIES, {'project_id': project_id, 'week': week, 'year' : proj_year})
-                    elif not year:
-                        cur.execute(ENTRIES, {'project_id': project_id})
-                    else:
-                        cur.execute(ENTRIES_YEAR, {'project_id': project_id, 'year':proj_year})
-                    total_proj = 0
-                    row = cur.fetchone()
-                    if row or empty_proj:
-                        print "# project: %s (%s)" % (project, proj_desc)
-                    while row:
-                        d = date(*map(int, row[0].split('-'))) 
-                        t = max(60, row[1])
-                        c = row[2]
-                        total_proj += t
-                        workpackage = "----"
-                        if c:
-                            m = WORKPACKAGE.match(c)
-                            if m:
-                                workpackage = m.group(1)
-                                c = c[m.end():].strip()
-                            c = c.replace('\x1b', '')
-                        print "%s %sh %s %-3s [%s] %s" % (
-                            d.strftime("%d.%m.%Y"),
-                            human_time(t),
-                            TYPE_OF_ENTRY,
-                            user,
-                            workpackage,
-                            c)
-                        row = cur.fetchone()
-                    total += total_proj
-                    if empty_proj or total_proj > 0:
-                        print "# total: %sh\n\n" % human_time(total_proj)
-                print "# total all projects: %sh\n\n" % human_time(total)
-        finally:
-            tolerantClose(cur)
-            tolerantClose(con)
-
-    except TermError, e:
-        print >> sys.stderr, "error: %s" % e.msg
-
-if __name__ == '__main__':
-    main()
-
-# vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8:
--- a/contrib/zeitsort	Mon Dec 12 09:58:17 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-# zeitsort
-# --------
-# (c) 2008 by Sascha L. Teichmann <sascha.teichmann@intevation.de>
-#
-# Simple script which sorts lines of zeiterfassung.txt files by date.
-#
-# This is Free Software licensed under the terms of GPLv3 or later.
-# For details see LICENSE coming with the source of 'getan'.
-#
-
-import sys
-import re
-
-from datetime import date
-
-DATE = re.compile("(\d\d)\.(\d\d)\.(\d\d\d\d)")
-
-def date_cmp(a, b):
-    ma = DATE.search(a)
-    mb = DATE.search(b)
-    if not ma and not mb: return cmp(a, b)
-    if ma and not mb: return -1
-    if not ma and mb: return +1
-    da = date(int(ma.group(3)), int(ma.group(2)), int(ma.group(1)))
-    db = date(int(mb.group(3)), int(mb.group(2)), int(mb.group(1)))
-    return cmp(da, db)
-
-def main():
-    all = []
-    while True:
-        line = sys.stdin.readline()
-        if not line: break
-        if not DATE.search(line):
-            # handle multi lines
-            if not all: all.append(line)
-            else:       all[-1] += line
-        else:
-            all.append(line)
-    all.sort(date_cmp)
-    sys.stdout.write(''.join(all))
-    sys.stdout.flush()
-
-if __name__ == '__main__':
-    main()
-
-# vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/getan/contrib/zeiterfassung.py	Mon Dec 12 10:19:52 2011 +0100
@@ -0,0 +1,272 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# zeiterfassung
+# -------------
+# (c) 2008 by Sascha L. Teichmann <sascha.teichmann@intevation.de>
+#
+# Simple script which generates lines for zeiterfassung.txt files.
+#
+# This is Free Software licensed under the terms of GPLv3 or later.
+# For details see LICENSE coming with the source of 'getan'.
+#
+import os
+import os.path
+import sys
+import getopt
+import re
+import codecs
+
+from pysqlite2 import dbapi2 as db
+
+from datetime import date, datetime
+
+DEFAULT_DATABASE = "time.db"
+
+TYPE_OF_ENTRY = "?"
+
+WORKPACKAGE = re.compile("^\[(\w*)(\s|\])")
+
+USAGE = '''usage: %s <options>
+    with <options>
+    [--user=|-u <user>]        : Name of user,          default: $USER
+    [--database=|-d <database>]: getan database,        default: time.db
+    [--project=|-p <key>]      : Key of output project, default: all
+    [--encoding=|-e encoding]  : encoding of output,    default: none
+    [--week=]|-w <week>]       : week of year
+    [--year=]|-y <year>]       : year
+    [--list|-l]                : list all projects
+    [--help|-h]                : This text
+    [--emtpy|-m]               : show empty projects
+    [--lastweek|-c]            : entries of last working week'''
+
+LIST_PROJECTS = '''
+SELECT key, description, active FROM projects
+'''
+
+PROJECT_ID_BY_KEY = '''
+SELECT id, description FROM projects where key = :key
+'''
+
+ALL_PROJECT_IDS = '''
+SELECT id, key, description FROM projects
+'''
+
+WEEK_ENTRIES = '''
+SELECT 
+    date(start_time) AS t, 
+    sum(strftime('%s', stop_time) - strftime('%s', start_time)), 
+    'no description' AS description
+FROM entries 
+WHERE 
+    project_id = :project_id AND 
+    (strftime('%Y', start_time) ) = :year AND
+    (description IS NULL or length(description) = 0) -- trim() function is missing
+    AND (strftime('%W', start_time) = :week OR strftime('%W', stop_time) = :week)
+GROUP BY round(julianday(start_time))
+UNION
+SELECT date(start_time) AS s, strftime('%s', stop_time) - strftime('%s', start_time), description
+FROM entries 
+WHERE 
+    project_id = :project_id AND 
+    (strftime('%Y', start_time) ) = :year AND
+    description IS NOT NULL AND length(description) > 0
+    AND (strftime('%W', start_time) = :week OR strftime('%W', stop_time) = :week)
+ORDER BY t
+'''
+
+ENTRIES = '''
+SELECT 
+    date(start_time), 
+    sum(strftime('%s', stop_time) - strftime('%s', start_time)), 
+    'no description' AS description
+FROM entries 
+WHERE 
+    project_id = :project_id AND 
+    (description IS NULL or length(description) = 0) -- trim() function is missing
+GROUP BY round(julianday(start_time))
+UNION
+SELECT date(start_time), strftime('%s', stop_time) - strftime('%s', start_time), description
+FROM entries 
+WHERE 
+    project_id = :project_id AND 
+    description IS NOT NULL AND length(description) > 0
+'''
+
+ENTRIES_YEAR = '''
+SELECT 
+    date(start_time), 
+    sum(strftime('%s', stop_time) - strftime('%s', start_time)), 
+    'no description' AS description
+FROM entries 
+WHERE 
+    project_id = :project_id AND 
+    (description IS NULL or length(description) = 0) -- trim() function is missing
+GROUP BY round(julianday(start_time))
+UNION
+SELECT date(start_time), strftime('%s', stop_time) - strftime('%s', start_time), description
+FROM entries 
+WHERE 
+    project_id = :project_id AND 
+    (strftime('%Y', start_time) ) = :year AND
+    description IS NOT NULL AND length(description) > 0
+'''
+
+def human_time(s):
+    h = s / 3600
+    m = (s % 3600) / 60
+    if (s % 60) >= 30:
+        m += 1
+        if m == 60:
+            m = 0
+            h += 1
+    return "%2d:%02d" % (h, m)
+
+class TermError(Exception):
+
+    def __init__(self, msg):
+        Exception.__init__(self)
+        self.msg = msg
+
+    def __str__(self):
+        return repr(self.msg)
+
+def tolerantClose(c):
+    if c:
+        try: c.close()
+        except: pass
+
+def usage(exit_code = 0):
+    print USAGE % sys.argv[0]
+    sys.exit(exit_code)
+
+def main():
+
+    database      = DEFAULT_DATABASE
+    user          = None
+    list_projects = False
+    project       = None
+    encoding      = None
+    week          = None
+    year          = None
+    empty_proj    = False
+
+    opts, args = getopt.getopt(
+        sys.argv[1:],
+        'd:u:p:e:hl:w:y:mc',
+        ['database=', 'user=', 'project=', 'encoding=', 'help', 'list', 'week=',
+            'year=', 'empty', 'lastweek'])
+
+    for opt, val in opts:
+        if opt in ("--database", "-d"):
+            database = val
+        elif opt in ("--user", "-u"):
+            user = val
+        elif opt in ("--project", "-p"):
+            project = val
+        elif opt in ("--encoding", "-e"):
+            encoding = val
+        elif opt in ("--help", "-h"):
+            usage()
+        elif opt in ("--list", "-l"):
+            list_projects = True
+        elif opt in ("--week", "-w"):
+            week = val
+        elif opt in ("--lastweek", "-c") and not week:
+            currentweek = datetime.now().isocalendar()[1]
+            lastweek = currentweek - 1
+            if lastweek <= 0:
+                lastweek = 52
+            week = str(lastweek)
+        elif opt in ("--year", "-y"):
+            year = val
+        elif opt in ("--empty", "-m"):
+            empty_proj = True
+
+    if not user:
+        user = os.getenv("USER")
+
+    proj_year = year
+    if not proj_year:
+        proj_year = date.today().strftime("%Y")
+
+    if encoding:
+        Writer = codecs.getwriter(encoding)
+        sys.stdout = Writer(sys.stdout)
+
+    if not os.path.isfile(database):
+        print >> sys.stderr, "'%s' does not exist or is not a file." % database
+        sys.exit(1)
+
+    con, cur = None, None
+    try:
+        try:
+            con = db.connect(database)
+            if encoding:
+                con.text_factory = lambda s: s.decode(encoding)
+            cur = con.cursor()
+
+            if list_projects:
+                cur.execute(LIST_PROJECTS)
+                while True:
+                    row = cur.fetchone()
+                    if not row: break
+                    print "%s %s %s" % (row[0], row[2] and "*" or "-", row[1])
+            else:
+                if project:
+                    cur.execute(PROJECT_ID_BY_KEY, { 'key': project })
+                    row = cur.fetchone()
+                    if row is None:
+                        raise TermError("There is no project with key '%s'" % project)
+                    project_ids = [[row[0], project, row[1]]]
+                else:
+                    cur.execute(ALL_PROJECT_IDS);
+                    project_ids = cur.fetchall()
+
+                total = 0
+                for project_id, project, proj_desc in project_ids:
+                    if not week is None:
+                        cur.execute(WEEK_ENTRIES, {'project_id': project_id, 'week': week, 'year' : proj_year})
+                    elif not year:
+                        cur.execute(ENTRIES, {'project_id': project_id})
+                    else:
+                        cur.execute(ENTRIES_YEAR, {'project_id': project_id, 'year':proj_year})
+                    total_proj = 0
+                    row = cur.fetchone()
+                    if row or empty_proj:
+                        print "# project: %s (%s)" % (project, proj_desc)
+                    while row:
+                        d = date(*map(int, row[0].split('-'))) 
+                        t = max(60, row[1])
+                        c = row[2]
+                        total_proj += t
+                        workpackage = "----"
+                        if c:
+                            m = WORKPACKAGE.match(c)
+                            if m:
+                                workpackage = m.group(1)
+                                c = c[m.end():].strip()
+                            c = c.replace('\x1b', '')
+                        print "%s %sh %s %-3s [%s] %s" % (
+                            d.strftime("%d.%m.%Y"),
+                            human_time(t),
+                            TYPE_OF_ENTRY,
+                            user,
+                            workpackage,
+                            c)
+                        row = cur.fetchone()
+                    total += total_proj
+                    if empty_proj or total_proj > 0:
+                        print "# total: %sh\n\n" % human_time(total_proj)
+                print "# total all projects: %sh\n\n" % human_time(total)
+        finally:
+            tolerantClose(cur)
+            tolerantClose(con)
+
+    except TermError, e:
+        print >> sys.stderr, "error: %s" % e.msg
+
+if __name__ == '__main__':
+    main()
+
+# vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/getan/contrib/zeitsort.py	Mon Dec 12 10:19:52 2011 +0100
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# zeitsort
+# --------
+# (c) 2008 by Sascha L. Teichmann <sascha.teichmann@intevation.de>
+#
+# Simple script which sorts lines of zeiterfassung.txt files by date.
+#
+# This is Free Software licensed under the terms of GPLv3 or later.
+# For details see LICENSE coming with the source of 'getan'.
+#
+
+import sys
+import re
+
+from datetime import date
+
+DATE = re.compile("(\d\d)\.(\d\d)\.(\d\d\d\d)")
+
+def date_cmp(a, b):
+    ma = DATE.search(a)
+    mb = DATE.search(b)
+    if not ma and not mb: return cmp(a, b)
+    if ma and not mb: return -1
+    if not ma and mb: return +1
+    da = date(int(ma.group(3)), int(ma.group(2)), int(ma.group(1)))
+    db = date(int(mb.group(3)), int(mb.group(2)), int(mb.group(1)))
+    return cmp(da, db)
+
+def main():
+    all = []
+    while True:
+        line = sys.stdin.readline()
+        if not line: break
+        if not DATE.search(line):
+            # handle multi lines
+            if not all: all.append(line)
+            else:       all[-1] += line
+        else:
+            all.append(line)
+    all.sort(date_cmp)
+    sys.stdout.write(''.join(all))
+    sys.stdout.flush()
+
+if __name__ == '__main__':
+    main()
+
+# vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8:
--- a/setup.py	Mon Dec 12 09:58:17 2011 +0100
+++ b/setup.py	Mon Dec 12 10:19:52 2011 +0100
@@ -29,7 +29,10 @@
       package_data = {"" : ["*.txt"],
                      },
       entry_points = { "console_scripts": ["getan=getan.main:main",
-          "getan-classic=getan.classic.getan:main"] },
+          "getan-classic=getan.classic.getan:main",
+          "zeiterfassung=getan.contrib.zeiterfassung:main",
+          "zeitsort=getan.contrib.zeitsort:main",
+          ] },
       classifiers=[
           "Topic :: Utilities",
           "Environment :: Console",
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)