#!/usr/bin/env python
import git, mmap, datetime
import PyRSS2Gen as pyrss

NUM_POSTS = 100
DEBUG = False

RSS_FILE = "/srv/git/pushes.rss"
if DEBUG:
    RSS_FILE = "/srv/git/pushes-test.rss"

def lines_rev(f):
    "Generator to go through lines in file in reverse order"

    # Map the whole file
    m = mmap.mmap( f.fileno(), 0, access = mmap.ACCESS_READ )

    last = len(m)
    p = m.rfind("\n")

    while p not in [-1]:
        yield m[p:last]

        last = p
        p = m.rfind("\n", 0, p)

    m.close()

def count_commits(path, hasha, hashb):
    try:
        repo = git.Repo( path )
    except git.errors.NoSuchPathError:
        return 0

    try:
        if hasha == "0000000000000000000000000000000000000000":
            commits = list( repo.iter_commits( "%s" % hashb ) )
        else:
            commits = list( repo.iter_commits( "%s...%s" % (hasha, hashb) ) )
    except git.errors.GitCommandError:
        commits = []

    return len(commits)

def get_repo_url(path):
    name = path[len("/srv/git/"):]
    return "https://www.studentrobotics.org/cgit/%s" % (name)

def commit_get_repo(c):
    "Give the shortname for the repository that the given commit is in"
    path = c.repo.working_dir
    prefix = "/srv/git/"
    return path[len(prefix):]

def get_commit_url(c):
    "Get the cgit URL for the given commit"
    name = commit_get_repo(c)
    return "https://www.studentrobotics.org/cgit/%s/commit/?id=%s" % (name, c.sha)

def get_shortlog( path, hasha, hashb ):
    try:
        repo = git.Repo( path )
    except git.errors.NoSuchPathError:
        return ""

    try:
        commits = list( repo.iter_commits( "%s...%s" % (hasha, hashb) ) )
    except git.errors.GitCommandError:
        return ""

    s = "<p>"
    for commit in commits:
        msg = commit.message
        nl = msg.find("\n")
        if nl != -1:
            msg = msg[:nl]
        msg = msg[:80]

        s += """%(author)s: <a href="%(url)s">%(summary)s</a>\n<br/>""" % \
            { "author" : commit.author.name,
              "summary": msg,
              "url" : get_commit_url(commit) }

    s += "</p>"

    return s

items = []

f = open("/srv/git/push-log", "r")

for l in lines_rev(f):
    l = l.strip()
    if l == "":
        continue

    t = l.split()
    if len(t) < 5:
        "Skip this entry."
        continue

    timestamp, user, path, hasha, hashb = t

    n_commits = count_commits( path, hasha, hashb )
    if n_commits == 0:
        "Skip this item"
        continue

    data = { "user": user,
             "num_commits": n_commits,
             "repo": path[len("/srv/git/"):],
             "repo_url": get_repo_url(path),
             "shortlog": get_shortlog( path, hasha, hashb ) }

    cstr = "commit"
    if data["num_commits"] > 1:
        cstr += "s"
    data["cstr"] = cstr

    item = pyrss.RSSItem(
        title = "%(repo)s: %(num_commits)i %(cstr)s pushed by %(user)s" % data,

        description = """%(user)s pushed %(num_commits)i %(cstr)s to <a href="%(repo_url)s">%(repo)s</a>:<br/>%(shortlog)s\n""" % data,

        pubDate = datetime.datetime.fromtimestamp(int(timestamp)),
        guid = pyrss.Guid( l ) )

    items.append( item )

    if len(items) == NUM_POSTS:
        break

rss = pyrss.RSS2(
    title = "Student Robotics Git Pushes",
    link = "http://git.studentrobotics.org/",
    description = "The last %i pushes to the Student Robotics git repositories." % NUM_POSTS,
    lastBuildDate = datetime.datetime.now(),
    items = items )

rss.write_xml( open( RSS_FILE , "w") )
