[sysadmin-bin: 80/168] Extract the projects shortdesc from DOAP into the git module description



commit a72dd8e3d9c6af2e670da5610e6aa8587c91e463
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Thu Apr 16 12:51:13 2009 -0400

    Extract the projects shortdesc from DOAP into the git module description
    
    semi_rdf.py: Not the world's worse RDF/XML parser, but close
    extract-doap-shortdesc: Extract the DOAP shortdesc from an
      RDF/XML file.
    post-receive-update-description: Look for <projectname>.doap and
      use it to update the git module description from the shortdesc.
    gnome-post-receive: call post-receive-update-description

 extract-doap-shortdesc          |   17 +++++
 gnome-post-receive              |    1 +
 post-receive-update-description |   82 +++++++++++++++++++++
 semi_rdf.py                     |  150 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 250 insertions(+), 0 deletions(-)
---
diff --git a/extract-doap-shortdesc b/extract-doap-shortdesc
new file mode 100755
index 0000000..fa9c77b
--- /dev/null
+++ b/extract-doap-shortdesc
@@ -0,0 +1,17 @@
+#!/usr/bin/python
+
+import sys
+
+script_path = os.path.realpath(os.path.abspath(sys.argv[0]))
+script_dir = os.path.dirname(script_path)
+sys.path.insert(0, script_dir)
+
+import semi_rdf
+
+DOAP = "http://usefulinc.com/ns/doap#";
+
+nodes = semi_rdf.read_rdf(sys.stdin)
+for node in nodes:
+    if node.name != (DOAP, "Project"):
+        continue
+    print node.find_property((DOAP, "shortdesc"))
diff --git a/gnome-post-receive b/gnome-post-receive
index 1cc4be2..51dd38b 100755
--- a/gnome-post-receive
+++ b/gnome-post-receive
@@ -23,6 +23,7 @@ GIT_CONFIG="${GIT_DIR}/config"
 export GIT_CONFIG
 
 tee >($BINDIR/log-push 1>&2) \
+    >($BINDIR/post-receive-update-description 1>&2) \
     >($BINDIR/post-receive-notify-cia 1>&2) \
     >($BINDIR/post-receive-notify-updates 1>&2) \
     | $BINDIR/gnome-post-receive-email 1>&2
diff --git a/post-receive-update-description b/post-receive-update-description
new file mode 100755
index 0000000..df97fc0
--- /dev/null
+++ b/post-receive-update-description
@@ -0,0 +1,82 @@
+#!/bin/bash
+
+BINDIR=/home/admin/gitadmin-bin
+
+GIT_DIR=$(git rev-parse --git-dir 2>/dev/null)
+
+# Use the directory name with .git stripped as a short identifier
+absdir=$(cd $GIT_DIR && pwd)
+projectshort=$(basename ${absdir%.git})
+
+update_description_from_file() {
+    rev=$1
+    path=$2
+    mode=$3
+
+    if [ "$path" != "$projectshort.doap" ] ; then
+        return
+    fi
+
+    shortdesc=$(git cat-file blob "$newrev:$path" | $BINDIR/extract-doap-shortdesc)
+    echo $shortdesc > $GIT_DIR/description
+}
+
+update_description() {
+    oldrev=$1
+    newrev=$2
+    refname=$3
+
+    branchname=${refname#refs/heads/}
+    if [ "$branchname" = "$refname" ] ; then
+        # not a branch update
+	return 0
+    fi
+
+    if [ "$branchname" != "master" ] ; then
+	# Only pay attention to the master branch
+	return 0
+    fi
+
+    if expr $newrev : "^0\+$" > /dev/null 2>&1; then
+        # Branch deletion; (shouldn't really happen for the master branch)
+	return 0
+    fi
+
+    if expr $oldrev : "^0\+$" > /dev/null 2>&1; then
+	# Branch creation
+	git ls-tree $newrev | (
+	    while read mode objtype sha path ; do
+		if [ $objtype = blob ] ; then
+		    update_description_from_file $newrev $path $mode
+		fi
+	    done
+	)
+    else
+	# Branch update
+	git diff-tree $oldrev $newrev | (
+	    while read srcmode destmode srcsha destsha status srcpath destpath ; do
+		if [ $status = 'D' ] ; then
+		    continue # deleted
+		fi
+
+		# destpath only present for copies/renames
+		if [ x"$destpath" = x ] ; then
+		    destpath=$srcpath
+		fi
+
+		# Strip colon from the source mode
+		srcmode=${srcmode#:}
+
+		update_description_from_file $newrev $destpath $destmode
+	    done
+	)
+    fi
+}
+
+if [ $# = 3 ] ; then
+    update_description $@ || exit 1
+else
+    while read oldrev newrev refname; do
+	update_description $oldrev $newrev $refname || exit 1
+    done
+fi
diff --git a/semi_rdf.py b/semi_rdf.py
new file mode 100755
index 0000000..9f113de
--- /dev/null
+++ b/semi_rdf.py
@@ -0,0 +1,150 @@
+#!/usr/bin/python
+#
+# A non-validating, semi-compliant parser for XML/RDF; it's meant
+# to handle most things that would be in a DOAP file.
+#
+# Copyright (C) 2009  Red Hat, Inc
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, If not, see
+# http://www.gnu.org/licenses/.
+#
+import re
+import sys
+import xml.sax
+
+RDF = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+XML = "http://www.w3.org/XML/1998/namespace";
+
+WHITESPACE_RE = re.compile("\s+")
+
+class Node:
+    def __init__(self, name, about):
+        self.name  = name
+        self.about = None
+        self.properties = []
+
+    def find_property(self, name, lang="en"):
+        value = None
+        for (n, l, v) in self.properties:
+            if n == name:
+                if l == lang:
+                    return v
+                elif l == None or value == None:
+                    value = v
+
+        return value
+
+class RdfHandler(xml.sax.handler.ContentHandler):
+    def __init__(self):
+        self.nodes = []
+        self.__node_stack = []
+        self.__property_stack = []
+        self.__lang_stack = []
+        self.__object = None
+        self.__depth = 0
+
+    def characters(self, s):
+        if isinstance(self.__object, basestring):
+            self.__object += s
+        elif s.strip() != "":
+            self.__object = s
+
+    def startElementNS(self, name, qname, attributes):
+        if name == (RDF, "RDF"):
+            return
+
+        self.__depth += 1
+        try:
+            lang = attributes.getValue((XML, "lang"))
+        except KeyError:
+            if self.__depth > 1:
+                lang = self.__lang_stack[-1]
+            else:
+                lang = None
+        self.__lang_stack.append(lang)
+
+        if self.__depth % 2 == 0:
+            node = None
+            resource = None
+            for attrname in attributes.getNames():
+                if attrname == (XML, "lang"):
+                    pass
+                elif attrname == (RDF, "resource"):
+                    resource = attrname
+                elif attrname == (RDF, "parseType"):
+                    parseType = attributes.getValue(attrname)
+                    if parseType == "resource":
+                        if node == None:
+                            node = Node(None, None)
+                else:
+                    if node == None:
+                        node = Node(None, None)
+                    node.properties.append((attrname, lang, attributes.getValue(attrname)))
+            self.__property_stack.append((name, lang, resource))
+            if node is not None:
+                print node.properties
+                self.__node_stack.append(node)
+                self.__depth += 1
+        else:
+            node = Node(name, None)
+            self.__node_stack.append(node)
+            for attrname in attributes.getNames():
+                if attrname == (RDF, "about"):
+                    node.about = attributes.getValue(attrname)
+                else:
+                    node.properties.append((attrname, lang, attributes.getValue(attrname)))
+
+    def popProperty(self):
+        (predicate, lang, resource) = self.__property_stack.pop()
+        if self.__object:
+            obj = self.__object
+            if isinstance(obj, basestring):
+                obj = obj.strip()
+                obj = WHITESPACE_RE.sub(" ", obj)
+        else:
+            obj = resource
+        self.__object = None
+        self.__node_stack[-1].properties.append((predicate, lang, obj))
+
+    def popNode(self):
+        node = self.__node_stack.pop()
+        self.__object = node
+        self.nodes.append(node)
+        return node
+
+    def endElementNS(self, name, qname):
+        if name == (RDF, "RDF"):
+            return
+
+        if self.__depth % 2 == 0:
+            self.popProperty()
+        else:
+            node = self.popNode()
+            if (node.name == None): # omitted blank node
+                self.popProperty()
+                self.__depth -= 1
+
+        self.__lang_stack.pop()
+        self.__depth -= 1
+
+def read_rdf(f):
+    handler = RdfHandler()
+
+    parser = xml.sax.make_parser()
+    parser.setContentHandler(handler)
+    parser.setFeature(xml.sax.handler.feature_namespaces, 1)
+    parser.parse(f)
+
+    return handler.nodes
+



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]