#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ====================================================================
#    Licensed to the Apache Software Foundation (ASF) under one
#    or more contributor license agreements.  See the NOTICE file
#    distributed with this work for additional information
#    regarding copyright ownership.  The ASF licenses this file
#    to you under the Apache License, Version 2.0 (the
#    "License"); you may not use this file except in compliance
#    with the License.  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing,
#    software distributed under the License is distributed on an
#    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
#    KIND, either express or implied.  See the License for the
#    specific language governing permissions and limitations
#    under the License.
# ====================================================================

"""Usage: svn2feed.py [OPTION...] REPOS-PATH

Generate an RSS 2.0 or Atom 1.0 feed file containing commit
information for the Subversion repository located at REPOS-PATH.  Once
the maximum number of items is reached, older elements are removed.
The item title is the revision number, and the item description
contains the author, date, log messages and changed paths.

Options:

 -h, --help             Show this help message.

 -F, --format=FORMAT    Required option.  FORMAT must be one of:
                            'rss'  (RSS 2.0)
                            'atom' (Atom 1.0)
                        to select the appropriate feed format.

 -f, --feed-file=PATH   Store the feed in the file located at PATH, which will
                        be created if it does not exist, or overwritten if it
                        does.  If not provided, the script will store the feed
                        in the current working directory, in a file named
                        REPOS_NAME.rss or REPOS_NAME.atom (where REPOS_NAME is
                        the basename of the REPOS_PATH command-line argument,
                        and the file extension depends on the selected
                        format).

 -r, --revision=X[:Y]   Subversion revision (or revision range) to generate
                        info for.  If not provided, info for the single
                        youngest revision in the repository will be generated.

 -m, --max-items=N      Keep only N items in the feed file.  By default,
                        20 items are kept.

 -u, --item-url=URL     Use URL as the basis for generating feed item links.
                        This value is appended with '?rev=REV_NUMBER' to form
                        the actual item links.

 -U, --feed-url=URL     Use URL as the global link associated with the feed.

 -P, --svn-path=DIR     Look in DIR for the svnlook binary.  If not provided,
                        svnlook must be on the PATH.
"""

# TODO:
# --item-url should support arbitrary formatting of the revision number,
#   to be useful with web viewers other than ViewVC.
# Rather more than intended is being cached in the pickle file. Instead of
#   only old items being drawn from the pickle, all the global feed metadata
#   is actually set only on initial feed creation, and thereafter simply
#   re-used from the pickle each time.

# $HeadURL$
# $LastChangedDate$
# $LastChangedBy$
# $LastChangedRevision$

import sys

# Python 2.4 is required for subprocess
if sys.version_info < (2, 4):
    sys.stderr.write("Error: Python 2.4 or higher required.\n")
    sys.stderr.flush()
    sys.exit(1)

import getopt
import os
import subprocess
try:
  # Python <3.0
  import cPickle as pickle
except ImportError:
  # Python >=3.0
  import pickle
import datetime
import time

def usage_and_exit(errmsg=None):
    """Print a usage message, plus an ERRMSG (if provided), then exit.
    If ERRMSG is provided, the usage message is printed to stderr and
    the script exits with a non-zero error code.  Otherwise, the usage
    message goes to stdout, and the script exits with a zero
    errorcode."""
    if errmsg is None:
        stream = sys.stdout
    else:
        stream = sys.stderr
    stream.write("%s\n" % __doc__)
    stream.flush()
    if errmsg:
        stream.write("\nError: %s\n" % errmsg)
	stream.flush()
        sys.exit(2)
    sys.exit(0)

def check_url(url, opt):
    """Verify that URL looks like a valid URL or option OPT."""
    if not (url.startswith('https://') \
            or url.startswith('http://') \
            or url.startswith('file://')):
      usage_and_exit("svn2feed.py: Invalid url '%s' is specified for " \
                     "'%s' option" % (url, opt))


class Svn2Feed:
    def __init__(self, svn_path, repos_path, item_url, feed_file,
                 max_items, feed_url):
        self.repos_path = repos_path
        self.item_url = item_url
        self.feed_file = feed_file
        self.max_items = max_items
        self.feed_url = feed_url
        self.svnlook_cmd = 'svnlook'
        if svn_path is not None:
            self.svnlook_cmd = os.path.join(svn_path, 'svnlook')
        self.feed_title = ("%s's Subversion Commits Feed"
                % (os.path.basename(os.path.abspath(self.repos_path))))
        self.feed_desc = "The latest Subversion commits"

    def _get_item_dict(self, revision):
        revision = str(revision)

        cmd = [self.svnlook_cmd, 'info', '-r', revision, self.repos_path]
        proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
        proc.wait()
        info_lines = proc.stdout.readlines()

        cmd = [self.svnlook_cmd, 'changed', '-r', revision, self.repos_path]
        proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
        proc.wait()
        changed_data = proc.stdout.readlines()

        desc = ("\nRevision: %s\nLog: %sModified: \n%s"
                % (revision, info_lines[3], changed_data))

        item_dict = {
            'author': info_lines[0].strip('\n'),
            'title': "Revision %s" % revision,
            'link': self.item_url and "%s?rev=%s" % (self.item_url, revision),
            'date': self._format_updated_ts(info_lines[1]),
            'description': "<pre>" + desc + "</pre>",
            }

        return item_dict

    def _format_updated_ts(self, revision_ts):

        # Get "2006-08-10 20:17:08" from
        # "2006-07-28 20:17:18 +0530 (Fri, 28 Jul 2006)
        date = revision_ts[0:19]
        epoch = time.mktime(time.strptime(date, "%Y-%m-%d %H:%M:%S"))
        return time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(epoch))


class Svn2RSS(Svn2Feed):
    def __init__(self, svn_path, repos_path, item_url, feed_file,
                 max_items, feed_url):
        Svn2Feed.__init__(self, svn_path, repos_path, item_url, feed_file,
                          max_items, feed_url)
        try:
            import PyRSS2Gen
        except ImportError:
            sys.stderr.write("""
Error: Required PyRSS2Gen module not found.  You can download the PyRSS2Gen
module from:

    http://www.dalkescientific.com/Python/PyRSS2Gen.html

""")
            sys.exit(1)
        self.PyRSS2Gen = PyRSS2Gen

        (file, ext) = os.path.splitext(self.feed_file)
        self.pickle_file = file + ".pickle"
        if os.path.exists(self.pickle_file):
            self.rss = pickle.load(open(self.pickle_file, "r"))
        else:
            self.rss = self.PyRSS2Gen.RSS2(
                    title = self.feed_title,
                    link = self.feed_url,
                    description = self.feed_desc,
                    lastBuildDate = datetime.datetime.now(),
                    items = [])

    @staticmethod
    def get_default_file_extension():
        return ".rss"

    def add_revision_item(self, revision):
        rss_item = self._make_rss_item(revision)
        self.rss.items.insert(0, rss_item)
        if len(self.rss.items) > self.max_items:
            del self.rss.items[self.max_items:]

    def write_output(self):
        s = pickle.dumps(self.rss)
        f = open(self.pickle_file, "w")
        f.write(s)
        f.close()

        f = open(self.feed_file, "w")
        self.rss.write_xml(f)
        f.close()

    def _make_rss_item(self, revision):
        info = self._get_item_dict(revision)

        rss_item = self.PyRSS2Gen.RSSItem(
                author = info['author'],
                title = info['title'],
                link = info['link'],
                description = info['description'],
                guid = self.PyRSS2Gen.Guid(info['link']),
                pubDate = info['date'])
        return rss_item


class Svn2Atom(Svn2Feed):
    def __init__(self, svn_path, repos_path, item_url, feed_file,
                 max_items, feed_url):
        Svn2Feed.__init__(self, svn_path, repos_path, item_url, feed_file,
                          max_items, feed_url)
        from xml.dom import getDOMImplementation
        self.dom_impl = getDOMImplementation()

        self.pickle_file = self.feed_file + ".pickle"
        if os.path.exists(self.pickle_file):
            self.document = pickle.load(open(self.pickle_file, "r"))
            self.feed = self.document.getElementsByTagName('feed')[0]
        else:
            self._init_atom_document()

    @staticmethod
    def get_default_file_extension():
        return ".atom"

    def add_revision_item(self, revision):
        item = self._make_atom_item(revision)

        total = 0
        for childNode in self.feed.childNodes:
            if childNode.nodeName == 'entry':
                if total == 0:
                    self.feed.insertBefore(item, childNode)
                    total += 1
                total += 1
                if total > self.max_items:
                    self.feed.removeChild(childNode)
        if total == 0:
            self.feed.appendChild(item)

    def write_output(self):
        s = pickle.dumps(self.document)
        f = open(self.pickle_file, "w")
        f.write(s)
        f.close()

        f = open(self.feed_file, "w")
        f.write(self.document.toxml())
        f.close()

    def _make_atom_item(self, revision):
        info = self._get_item_dict(revision)

        doc = self.document
        entry = doc.createElement("entry")

        id = doc.createElement("id")
        entry.appendChild(id)
        id.appendChild(doc.createTextNode(info['link']))

        title = doc.createElement("title")
        entry.appendChild(title)
        title.appendChild(doc.createTextNode(info['title']))

        updated = doc.createElement("updated")
        entry.appendChild(updated)
        updated.appendChild(doc.createTextNode(info['date']))

        link = doc.createElement("link")
        entry.appendChild(link)
        link.setAttribute("href", info['link'])

        summary = doc.createElement("summary")
        entry.appendChild(summary)
        summary.appendChild(doc.createTextNode(info['description']))

        author = doc.createElement("author")
        entry.appendChild(author)
        aname = doc.createElement("name")
        author.appendChild(aname)
        aname.appendChild(doc.createTextNode(info['author']))

        return entry

    def _init_atom_document(self):
        doc = self.document = self.dom_impl.createDocument(None, None, None)
        feed = self.feed = doc.createElement("feed")
        doc.appendChild(feed)

        feed.setAttribute("xmlns", "http://www.w3.org/2005/Atom")

        title = doc.createElement("title")
        feed.appendChild(title)
        title.appendChild(doc.createTextNode(self.feed_title))

        id = doc.createElement("id")
        feed.appendChild(id)
        id.appendChild(doc.createTextNode(self.feed_url))

        updated = doc.createElement("updated")
        feed.appendChild(updated)
        now = datetime.datetime.now()
        updated.appendChild(doc.createTextNode(self._format_date(now)))

        link = doc.createElement("link")
        feed.appendChild(link)
        link.setAttribute("href", self.feed_url)

        author = doc.createElement("author")
        feed.appendChild(author)
        aname = doc.createElement("name")
        author.appendChild(aname)
        aname.appendChild(doc.createTextNode("subversion"))

    def _format_date(self, dt):
        """ input date must be in GMT """
        return ("%04d-%02d-%02dT%02d:%02d:%02d.%02dZ"
                % (dt.year, dt.month, dt.day, dt.hour, dt.minute,
                   dt.second, dt.microsecond))


def main():
    # Parse the command-line options and arguments.
    try:
        opts, args = getopt.gnu_getopt(sys.argv[1:], "hP:r:u:f:m:U:F:",
                                       ["help",
                                        "svn-path=",
                                        "revision=",
                                        "item-url=",
                                        "feed-file=",
                                        "max-items=",
                                        "feed-url=",
                                        "format=",
                                        ])
    except getopt.GetoptError as msg:
        usage_and_exit(msg)

    # Make sure required arguments are present.
    if len(args) != 1:
        usage_and_exit("You must specify a repository path.")
    repos_path = os.path.abspath(args[0])

    # Now deal with the options.
    max_items = 20
    commit_rev = svn_path = None
    item_url = feed_url = None
    feed_file = None
    feedcls = None
    feed_classes = { 'rss': Svn2RSS, 'atom': Svn2Atom }

    for opt, arg in opts:
        if opt in ("-h", "--help"):
            usage_and_exit()
        elif opt in ("-P", "--svn-path"):
            svn_path = arg
        elif opt in ("-r", "--revision"):
            commit_rev = arg
        elif opt in ("-u", "--item-url"):
            item_url = arg
            check_url(item_url, opt)
        elif opt in ("-f", "--feed-file"):
            feed_file = arg
        elif opt in ("-m", "--max-items"):
            try:
               max_items = int(arg)
            except ValueError as msg:
               usage_and_exit("Invalid value '%s' for --max-items." % (arg))
            if max_items < 1:
               usage_and_exit("Value for --max-items must be a positive "
                              "integer.")
        elif opt in ("-U", "--feed-url"):
            feed_url = arg
            check_url(feed_url, opt)
        elif opt in ("-F", "--format"):
            try:
                feedcls = feed_classes[arg]
            except KeyError:
                usage_and_exit("Invalid value '%s' for --format." % arg)

    if feedcls is None:
        usage_and_exit("Option -F [--format] is required.")

    if item_url is None:
        usage_and_exit("Option -u [--item-url] is required.")

    if feed_url is None:
        usage_and_exit("Option -U [--feed-url] is required.")

    if commit_rev is None:
        svnlook_cmd = 'svnlook'
        if svn_path is not None:
            svnlook_cmd = os.path.join(svn_path, 'svnlook')
        cmd = [svnlook_cmd, 'youngest', repos_path]
        proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
        proc.wait()
        cmd_out = proc.stdout.readlines()
        try:
            revisions = [int(cmd_out[0])]
        except IndexError as msg:
            usage_and_exit("svn2feed.py: Invalid value '%s' for " \
                           "REPOS-PATH" % (repos_path))
    else:
        try:
            rev_range = commit_rev.split(':')
            len_rev_range = len(rev_range)
            if len_rev_range == 1:
                revisions = [int(commit_rev)]
            elif len_rev_range == 2:
                start, end = rev_range
                start = int(start)
                end = int(end)
                if (start > end):
                    tmp = start
                    start = end
                    end = tmp
                revisions = list(range(start, end + 1)[-max_items:])
            else:
                raise ValueError()
        except ValueError as msg:
            usage_and_exit("svn2feed.py: Invalid value '%s' for --revision." \
                           % (commit_rev))

    if feed_file is None:
        feed_file = (os.path.basename(repos_path) +
                     feedcls.get_default_file_extension())

    feed = feedcls(svn_path, repos_path, item_url, feed_file, max_items,
                   feed_url)
    for revision in revisions:
        feed.add_revision_item(revision)
    feed.write_output()


if __name__ == "__main__":
    main()
