#! /usr/bin/env python

import sys, os, time, subprocess
import argparse
import pyinotify

parser = argparse.ArgumentParser(description='Create repomd metadata whenever repository content has changed')
parser.add_argument('repodir', help='Repository directory', default='/srv/rpm')
parser.add_argument('args', nargs=argparse.REMAINDER, help='additional createrepo arguments')

args = parser.parse_args()

class RepoUpdater:
  def __init__(self, repodir, args = None):
    self.repodir = os.path.abspath(str(repodir))

    cmd = [ "createrepo" ]
    if args:
      cmd.extend(args)
    cmd.append(repodir)
    self.createrepo_cmd = cmd

  def add_watch(self, watch_manager, mask):
    excl_dirs = [os.path.join(self.repodir, excl) for excl in [ "repodata", ".repodata" ]]
    excl = pyinotify.ExcludeFilter(excl_dirs)
    wdd = watch_manager.add_watch(self.repodir, mask, rec=True, auto_add=True, exclude_filter=excl)
    return wdd[self.repodir] > 0

  def do_update(self, path):
    subprocess.call(self.createrepo_cmd, stderr=subprocess.STDOUT)


class EventHandler(pyinotify.ProcessEvent):
  def __init__(self, repo_updater):
    self.repo_updater = repo_updater

  def process_default(self, event):
    if event.mask & pyinotify.IN_ISDIR:
      return
    time.sleep(0.2)
    self.repo_updater.do_update(event.pathname)

repo_updater = RepoUpdater(args.repodir, args.args)

wm = pyinotify.WatchManager()
handler = EventHandler(repo_updater)
notifier = pyinotify.Notifier(wm, handler)

mask = pyinotify.IN_CLOSE_WRITE | pyinotify.IN_DELETE | pyinotify.IN_MOVED_TO | pyinotify.IN_MOVED_FROM
if repo_updater.add_watch(wm, mask):
  print('Watching %s ...' % repo_updater.repodir)
  notifier.loop()

