import click
from os import path, listdir, rename, remove
from multiprocessing import Pool
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
from threading import Condition

from .dropbox import DropboxContainer


def get_settings(fs_config):

    import ConfigParser

    class MyParser(ConfigParser.SafeConfigParser):

        def as_dict(self):
            d = dict(self._sections)
            for k in d:
                d[k] = dict(self._defaults, **d[k])
                d[k].pop('__name__', None)
            return d

    parser = MyParser()
    parser.read(fs_config)
    return parser.as_dict()['app:briefkasten']


class MyHandler(FileSystemEventHandler):

    def __init__(self, main_loop_cond):
        self.main_loop_cond = main_loop_cond

    def on_modified(self, event):
        self.main_loop_cond.acquire()
        self.main_loop_cond.notify()
        self.main_loop_cond.release()
        print "directory modified"


def run_watchdog():
    # once a day we should scan for old drop boxes
    # at noon we should test pgp keys
    # also: scan for and clean up watchdog entries
    pass


def process_drop(drop):
    try:
        rename(
            path.join(drop.container.fs_submission_queue, drop.drop_id),
            path.join(drop.container.fs_scratchdir, drop.drop_id)
        )
    except:
        return

    drop.process()

    # remove token from scratch dir, we're done
    remove(path.join(drop.container.fs_scratchdir, drop.drop_id))


@click.command(help='debug a single drop')
@click.option(
    '--root',
    '-r',
    default='var/drops/',
    help='''location of the dropbox container directory''')
@click.argument(
    'drop_id',
    required=False,
    default=None,
)
def debug(root, drop_id=None):     # pragma: no cover
    root = DropboxContainer(root=root)
    for drop in root:
        print(drop)


@click.command(help='Scans dropbox directory for unprocessed drops and processes them')
@click.option(
    '--root',
    '-r',
    default='var/drops/',
    help='''location of the dropbox container directory''')
def main(root):     # pragma: no cover
    drop_root = DropboxContainer(root=root)
    settings = drop_root.settings

    workers = Pool(processes=settings.get('num_workers', 1))

    condition = Condition()
    event_handler = MyHandler(condition)

    observer = Observer()
    observer.schedule(event_handler, drop_root.fs_submission_queue, recursive=False)
    observer.start()

    condition.acquire()
    while True:
        for drop_id in listdir(drop_root.fs_submission_queue):
            print(drop_id)
            drop = drop_root.get_dropbox(drop_id)
            if(drop.status_int == 20):
                if drop.num_attachments > 0:
                    workers.map_async(process_drop, [drop])
                else:
                    process_drop(drop)

        # Wait for directory content to change
        condition.wait()

    condition.release()

@@ -51,16 +51,37 @@
  remove%0A
+from sys import exit%0A
 from mul
@@ -105,16 +105,50 @@
 rt Pool%0A
+from signal import signal, SIGINT%0A
 from wat
@@ -1027,16 +1027,121 @@
 fied%22%0A%0A%0A
+def keyboard_interrupt_handler(signal, frame):%0A    print 'Caught keyboard interrupt. Exit.'%0A    exit(0)%0A%0A
 def run_
@@ -2381,93 +2381,357 @@
     
-workers = Pool(processes=settings.get('num_workers', 1))%0A%0A    condition = Condition()
+# Setup multiprocessing pool with that amount of workers as%0A    # implied by the amount of worker jails%0A    workers = Pool(processes=settings.get('num_workers', 1))%0A%0A    # Setup the condition object that we will wait for, it%0A    # signals changes in the directory%0A    condition = Condition()%0A%0A    # Setup and run the actual file system event watcher
 %0A   
@@ -2768,17 +2768,16 @@
 dition)%0A
-%0A
     obse
@@ -2897,24 +2897,137 @@
 er.start()%0A%0A
+    signal( SIGINT, keyboard_interrupt_handler )%0A%0A    # grab lock, scan submission dir for jobs and process them%0A
     conditio
@@ -3198,46 +3198,171 @@
 id)%0A
-            if(drop.status_int == 20):
+%0A            # Only look at drops that actually are for us%0A            if(drop.status_int == 20):%0A                # process drops without attachments synchronously
 %0A   

Add some documentation