Index: bin/stamp
===================================================================
--- bin/stamp	(revision 35)
+++ bin/stamp	(revision 58)
@@ -3,5 +3,5 @@
 import sys
 from datetime import datetime
-from stamper import DATETIME_FORMAT, Stamper
+from stamper import Stamper
 
 
@@ -24,5 +24,5 @@
     if len(sys.argv) == 1:
         # stamp!
-        s.stamp(datetime.today().strftime(DATETIME_FORMAT), 
+        s.stamp(datetime.today().strftime(s.datetime_format),
                 None, None, None)
 
@@ -35,5 +35,5 @@
         customer = sys.argv[1]
         description = ' '.join(sys.argv[2:])
-        s.stamp(current_start, datetime.today().strftime(DATETIME_FORMAT),
+        s.stamp(current_start, datetime.today().strftime(s.datetime_format),
                 customer, description)
 
Index: etc/stamper.conf
===================================================================
--- etc/stamper.conf	(revision 58)
+++ etc/stamper.conf	(revision 58)
@@ -0,0 +1,22 @@
+#
+# stamper.conf - Stamper configuration file
+#
+
+[stamps]
+path = ~/.workstamps.json
+date_format = %%Y-%%m-%%d
+time_format = %%H:%%M:%%S
+datetime_format = %%Y-%%m-%%d %%H:%%M
+
+[sum]
+hours_day = 8
+
+[charts]
+path = ~/.workstamps-charts
+
+[collector]
+base_url = http://localhost:8000
+login_path = /stamper/login/
+listen_path = /stamper/listen/
+user = CHANGEME
+password = SECRET
Index: stamper/__init__.py
===================================================================
--- stamper/__init__.py	(revision 27)
+++ stamper/__init__.py	(revision 58)
@@ -1,2 +1,1 @@
-from stamper import DATETIME_FORMAT
 from stamper import Stamper
Index: stamper/config.py
===================================================================
--- stamper/config.py	(revision 58)
+++ stamper/config.py	(revision 58)
@@ -0,0 +1,62 @@
+
+import os
+from ConfigParser import SafeConfigParser
+
+
+class Config(object):
+    def __init__(self, path=None):
+        self.path = path
+        self.default_paths = [
+            os.path.expanduser('~/'),
+            os.path.join(os.path.dirname(__file__),'../etc')
+        ]
+        self.config = {}
+
+    @property
+    def filename(self):
+        return 'stamper.conf'
+
+    @property
+    def sections(self):
+        return['stamps', 'sum', 'charts', 'collector']
+
+    def look_for_config(self):
+        """
+        Look for the configuration file, following the path names listed in
+        the default paths
+        """
+        for path in self.default_paths:
+            full_path = os.path.join(path, self.filename)
+            if os.path.isfile(full_path):
+                self.path = full_path
+                return full_path
+        # if we reach here, self.path will be still None, no valid
+        # config files were found, and so we raise an exception
+        raise IOError('ERROR - Can not find ' + self.filename + \
+                      ' in your environment')
+
+    def load(self):
+        if not self.path:
+            full_path = self.look_for_config()
+        parser = SafeConfigParser()
+        parser.read(full_path)
+        for section in self.sections:
+            self.config[section] = {}
+            for name, value in parser.items(section):
+                self.config[section][name] = value
+        return self.config
+
+    def get(self, section, parameter=None):
+        if section not in self.config.keys():
+            # perhaps the config hasn't been loaded yet
+            self.load()
+
+        if section not in self.sections:
+            raise IndexError('ERROR - ' + section + \
+                             ' is not one of the available sections: ' + \
+                             ', '.join(self.sections))
+
+        if parameter:
+            return self.config[section][parameter]
+
+        return self.config[section]
Index: stamper/stamper.py
===================================================================
--- stamper/stamper.py	(revision 56)
+++ stamper/stamper.py	(revision 58)
@@ -10,26 +10,20 @@
 
 from .http import HTTPClient
-
-
-STAMPS_FILE = os.path.expanduser('~/.workstamps.json')
-CHARTS_DIR = os.path.expanduser('~/.workstamps-charts')
-DATE_FORMAT = '%Y-%m-%d'
-TIME_FORMAT = '%H:%M:%S'
-DATETIME_FORMAT = '%Y-%m-%d %H:%M'
-HOURS_DAY = 8
-SECS_DAY = HOURS_DAY * 60 * 60
-REMOTE_BASE_URL = 'https://localhost'
-# IMPORTANT: keep the trailing / on these _URL variables
-REMOTE_LOGIN_URL = '/stamper/login/'
-REMOTE_PUSH_URL = '/stamper/listen/'
-REMOTE_USER = None
-REMOTE_PASSWORD = None
+from .config import Config
 
 
 class Stamper(object):
 
-    def __init__(self, stamps_file=STAMPS_FILE, charts_dir=CHARTS_DIR):
-        self.stamps_file = stamps_file
-        self.charts_dir = charts_dir
+    def __init__(self, config_file=None):
+        self.config = Config(config_file)
+        self.stamps_file = os.path.expanduser(
+            self.config.get('stamps', 'path'))
+        self.charts_dir = os.path.expanduser(
+            self.config.get('charts', 'path'))
+        self.date_format = self.config.get('stamps', 'date_format')
+        self.time_format = self.config.get('stamps', 'time_format')
+        self.datetime_format = self.config.get('stamps', 'datetime_format')
+        self.hours_day = int(self.config.get('sum', 'hours_day'))
+        self.collector = self.config.get('collector')
         self.ensure_stamps_file()
         self.ensure_charts_dir()
@@ -96,6 +90,6 @@
 
     def worktime(self, start, end):
-        worktime = (datetime.strptime(end, DATETIME_FORMAT) -
-                    datetime.strptime(start, DATETIME_FORMAT))
+        worktime = (datetime.strptime(end, self.datetime_format) -
+                    datetime.strptime(start, self.datetime_format))
         return worktime.seconds
 
@@ -126,13 +120,13 @@
         if '--' in stamp_filter:
             filter_from, filter_to = stamp_filter.split('--')
-            filter_from = datetime.strptime(filter_from, DATE_FORMAT)
-            filter_to = datetime.strptime(filter_to, DATE_FORMAT)
+            filter_from = datetime.strptime(filter_from, self.date_format)
+            filter_to = datetime.strptime(filter_to, self.date_format)
 
         elif stamp_filter.startswith('*'):
-            filter_to = datetime.strptime(stamp_filter, '*'+DATE_FORMAT)
+            filter_to = datetime.strptime(stamp_filter, '*'+self.date_format)
             filter_to = filter_to.replace(hour=0, minute=0, second=0)
 
         elif stamp_filter.endswith('*'):
-            filter_from = datetime.strptime(stamp_filter, DATE_FORMAT+'*')
+            filter_from = datetime.strptime(stamp_filter, self.date_format+'*')
             filter_from = filter_from.replace(hour=0, minute=0, second=0)
 
@@ -167,5 +161,5 @@
             # maybe they are giving us a fixed date
             try:
-                filter_from = datetime.strptime(stamp_filter, DATE_FORMAT)
+                filter_from = datetime.strptime(stamp_filter, self.date_format)
             except:
                 # nothing to be used as a filter, go on, printing a warning
@@ -192,6 +186,6 @@
             # customer will be None for "start" stamps, having no end time
             if customer:
-                start = datetime.strptime(stamp['start'], DATETIME_FORMAT)
-                end = datetime.strptime(stamp['end'], DATETIME_FORMAT)
+                start = datetime.strptime(stamp['start'], self.datetime_format)
+                end = datetime.strptime(stamp['end'], self.datetime_format)
                 if filter_from and start < filter_from:
                     # if there is a filter setting a starting date for the
@@ -219,7 +213,7 @@
                     # it
                     continue
-                start = datetime.strptime(stamp['start'], DATETIME_FORMAT)
+                start = datetime.strptime(stamp['start'], self.datetime_format)
                 start_day = start.strftime('%Y-%m-%d')
-                end = datetime.strptime(stamp['end'], DATETIME_FORMAT)
+                end = datetime.strptime(stamp['end'], self.datetime_format)
                 if filter_from and start < filter_from:
                     # if there is a filter setting a starting date for the
@@ -255,5 +249,5 @@
         filter_from, filter_to = self.validate_filter(stamp_filter)
         for stamp in self.stamps:
-            start = datetime.strptime(stamp['start'], DATETIME_FORMAT)
+            start = datetime.strptime(stamp['start'], self.datetime_format)
             start_day = start.strftime('%Y-%m-%d')
             if filter_from and start < filter_from:
@@ -284,5 +278,5 @@
         filter_from, filter_to = self.validate_filter(stamp_filter)
         chart = pygal.Bar(title='Work hours per day',
-                          range=(0, HOURS_DAY),
+                          range=(0, self.hours_day),
                           x_title='Days',
                           y_title='Work hours',
@@ -380,10 +374,11 @@
                 totalSecs, sec = divmod(seconds, 60)
                 hr, min = divmod(totalSecs, 60)
-                totalDays, remaining = divmod(seconds, SECS_DAY)
+                totalDays, remaining = divmod(seconds,
+                                              (self.hours_day * 60 * 60))
                 remainingMin, remainingSec = divmod(remaining, (60))
                 remainingHr, remainingMin = divmod(remainingMin, (60))
                 print('----- %d:%02d:%02d -----' % (hr, min, sec))
                 print('--- %d days, remaining: %d:%02d (%d hours/day) ---' % (
-                    totalDays, remainingHr, remainingMin, HOURS_DAY
+                    totalDays, remainingHr, remainingMin, self.hours_day
                 ))
 
@@ -444,7 +439,7 @@
                 if customer and customer != stamp['customer']:
                     continue
-                start = datetime.strptime(stamp['start'], DATETIME_FORMAT)
+                start = datetime.strptime(stamp['start'], self.datetime_format)
                 start_day = start.strftime('%Y-%m-%d')
-                end = datetime.strptime(stamp['end'], DATETIME_FORMAT)
+                end = datetime.strptime(stamp['end'], self.datetime_format)
                 if filter_from and start < filter_from:
                     # if there is a filter setting a starting date for the
@@ -458,6 +453,7 @@
 
         stamps = json.dumps(stamps, indent=4)
-        http_client = HTTPClient(REMOTE_BASE_URL)
-        http_client.post(REMOTE_LOGIN_URL, {'username': REMOTE_USER,
-                                            'password': REMOTE_PASSWORD})
-        http_client.post(REMOTE_PUSH_URL, {'stamps': stamps})
+        http_client = HTTPClient(self.collector['base_url'])
+        http_client.post(self.collector['login_path'],
+                         {'username': self.collector['user'],
+                          'password': self.collector['password']})
+        http_client.post(self.collector['listen_path'], {'stamps': stamps})
