[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [39859] trunk/blender: Credits generator which cross references with the patch tracker to credit the original authors .

Campbell Barton ideasman42 at gmail.com
Fri Sep 2 05:42:18 CEST 2011


Revision: 39859
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=39859
Author:   campbellbarton
Date:     2011-09-02 03:42:16 +0000 (Fri, 02 Sep 2011)
Log Message:
-----------
Credits generator which cross references with the patch tracker to credit the original authors.

the script has a unix-name <> real-name mapping which is not totally complete since I couldn't find everyones real names.

In this case the commit name is credited.

Also added a link to the credits page in the splash.

Modified Paths:
--------------
    trunk/blender/source/blender/windowmanager/intern/wm_operators.c

Added Paths:
-----------
    trunk/blender/intern/tools/credits_svn_gen.py

Added: trunk/blender/intern/tools/credits_svn_gen.py
===================================================================
--- trunk/blender/intern/tools/credits_svn_gen.py	                        (rev 0)
+++ trunk/blender/intern/tools/credits_svn_gen.py	2011-09-02 03:42:16 UTC (rev 39859)
@@ -0,0 +1,473 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  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, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+"""
+This script generates a credits list for:
+
+   http://www.blender.org/development/credits
+
+
+To use this script you'll need to set 2 variables (below)
+
+eg:
+
+   svn_log = "somelog.xml"
+   tracker_csv = "tracker_report-2011-09-02.csv"
+
+
+The first is the result of running this:
+
+   svn log https://svn.blender.org/svnroot/bf-blender/trunk/blender -v --xml
+
+The csv file must be saved from the tracker, be sure to select all patches
+not just open ones.
+
+
+Running this script will create a file called 'credits.html',
+the resulting data is then be copied into the Development/Credits page
+in blender.org's typo3.
+"""
+
+# -----------------------------------------------------------------------------
+# Generic Class and parsing code, could be useful for all sorts of cases
+
+class SvnCommit(object):
+    """Just data store really"""
+    __slots__ = ("revision",
+                 "author",
+                 "date",
+                 "message",
+                 "paths",
+                 )
+
+    def __init__(self, xml):
+        self.revision = int(xml.attributes["revision"].nodeValue)
+
+        elems = xml.getElementsByTagName("author")
+        self.author = elems[0].firstChild.nodeValue
+
+        elems = xml.getElementsByTagName("date")
+        self.date = elems[0].firstChild.nodeValue
+
+        # treat the message
+        # possible there is no message
+        elems = xml.getElementsByTagName("msg")
+        message = getattr(elems[0].firstChild, "nodeValue", "")
+        message = " ".join(message.split())
+        self.message = message
+
+        # for now we ignore: elem.attributes["kind"]
+        self.paths = [(elem.attributes["action"].value,
+                       elem.firstChild.nodeValue,
+                       )
+                      for elem in xml.getElementsByTagName("path")]
+
+    def __repr__(self):
+        repr_dict = {}
+        for attr in self.__slots__:
+            repr_dict[attr] = getattr(self, attr)
+        return repr(repr_dict)
+
+
+def parse_commits(filepath):
+    import xml.dom.minidom
+    from xml.dom.minidom import parse
+
+    svn_xml = parse(filepath)
+    # almost certainly only 1 but, just incase
+
+    commits = []
+
+    for log_list in svn_xml.getElementsByTagName("log"):
+        log_entries = log_list.getElementsByTagName("logentry")
+        for commit_xml in log_entries:
+
+            # get all data from the commit into a dict for more easy checking.
+            commits.append(SvnCommit(commit_xml))
+
+    return commits
+
+
+# -----------------------------------------------------------------------------
+# Special checks to extract the credits
+
+#svn_log = "/dsk/data/src/blender/svn_log_verbose.xml"
+svn_log = "/dsk/data/src/blender/svn_log_verbose.xml"
+tracker_csv = "/l/tracker_report-2011-09-02.csv"
+
+# TODO, there are for sure more companies then are currently listed.
+# 1 liners for in wiki syntax
+contrib_companies = [
+    "<b>Unity Technologies</b> - FBX Exporter",
+    "<b>BioSkill GmbH</b> - H3D compatibility for X3D Exporter, "
+    "OBJ Nurbs Import/Export",
+]
+
+# ignore commits containing these messages
+ignore_msg = (
+    "SVN maintenance",
+    )
+
+# ignore these paths
+# implicitly ignore anything _not_ in /trunk/blender
+ignore_dir = (
+    "/trunk/blender/extern/",
+    "/trunk/blender/scons/",
+    "/trunk/blender/intern/opennl/",
+    "/trunk/blender/intern/moto/",
+    )
+
+ignore_revisions = {2,  # initial commit by Hans
+                    }
+
+# important, second value _must_ be the name used by projects.blender.org
+# anyone who ever committed to blender
+author_name_mapping = {
+    "alexk": "Alexander Kuznetsov",
+    "aligorith": "Joshua Leung",
+    "antont": "Toni Alatalo",
+    "aphex": "Simon Clitherow",
+    "artificer": "Ben Batt",
+    "ascotan": "Joseph Gilbert",
+    "bdiego": "Diego Borghetti",
+    "bebraw": "Juho Vepsalainen",
+    "ben2610": "Benoit Bolsee",
+    "billrey": "William Reynish",
+    "bjornmose": "Jens Ole Wund",
+    "blendix": "Brecht Van Lommel",
+    "briggs": "Geoffrey Bantle",
+    "broken": "Matt Ebb",
+    "campbellbarton": "Campbell Barton",
+    "cessen": "Nathan Vegdahl",
+    "damien78": "Damien Plisson",
+    "desoto": "Chris Burt",
+    "dfelinto": "Dalai Felinto",
+    "dingto": "Thomas Dinges",
+    "djcapelis": "D.J. Capelis",
+    "dougal2": "Doug Hammond",
+    "elubie": "Andrea Weikert",
+    "erwin": "Erwin Coumans",
+    "genscher": "Daniel Genrich",
+    "goofster": "Roel Spruit",
+    "gsrb3d": "gsr b3d",
+    "guitargeek": "Johnny Matthews",
+    "hans": "Hans Lambermont",
+    "harkyman": "Roland Hess",
+    "hos": "Chris Want",
+    "ianwill": "Willian Padovani Germano",
+    "imbusy": "Lukas Steiblys",
+    "intrr": "Alexander Ewering",
+    "jbakker": "Jeroen Bakker",
+    "jensverwiebe": "Jens Verwiebe",
+    "jesterking": "Nathan Letwory",
+    "jhk": "Janne Karhu",
+    "jiri": "Jiri Hnidek",
+    "joeedh": "Joseph Eagar",
+    "jwilkins": "Jason Wilkins",
+    "kazanbas": "Arystanbek Dyussenov",
+    "kester": "Kester Maddock",
+    "khughes": "Ken Hughes",
+    "kwk": "Konrad Kleine",
+    "letterrip": "Tom Musgrove",
+    "lmg": "M.G. Kishalmi",
+    "lukastoenne": "Lukas Toenne",
+    "lukep": "Jean-Luc Peurière",
+    "lusque": "Ervin Weber",
+    "mal_cando": "Mal Duffin",
+    "merwin": "Mike Erwin",
+    "mfoxdogg": "Michael Fox",
+    "mindrones": "Luca Bonavita",
+    "mmikkelsen": "Morten Mikkelsen",
+    "moguri": "Mitchell Stokes",
+    "nazgul": "Sergey Sharybin",
+    "nexyon": "Joerg Mueller",
+    "nicholasbishop": "Nicholas Bishop",
+    "n_t": "Nils Thuerey",
+    "pidhash": "Joilnen Leite",
+    "psy-fi": "Antony Riakiotakis",
+    "schlaile": "Peter Schlaile",
+    "scourage": "Robert Holcomb",
+    "sgefant": "Stefan Gartner",
+    "sirdude": "sirdude",
+    "smerch": "Alex Sytnik",
+    "snailrose": "Charlie Carley",
+    "stiv": "Stephen Swaney",
+    "theeth": "Martin Poirier",
+    "ton": "Ton Roosendaal",
+    "vekoon": "Elia Sarti",
+    "xat": "Xavier Thomas",
+    "zaghaghi": "Hamed Zaghaghi",
+    "zanqdo": "Daniel Salazar",
+    "zuster": "Daniel Dunbar",
+
+    # TODO, find remaining names
+
+    "cmccad": "",
+    "eeshlo": "",
+    "frank": "",
+    "guignot": "",
+    "h_xnan": "",
+    "halley": "",
+    "jaguarandi": "",
+    "jandro": "",
+    "jbinto": "",
+    "kakbarnf": "",
+    "larstiq": "",
+    "loczar": "",
+    "lonetech": "",
+    "maarten": "",
+    "mein": "",
+    "mfreixas": "",
+    "michel": "",
+    "migius": "",
+    "mikasaari": "",
+    "nlin": "",
+    "phaethon": "",
+    "phase": "",
+    "phlo": "",
+    "rwenzlaff": "",
+    "sateh": "",
+    "themyers": "",
+    }
+
+# lame, fill in empty key/values
+empty = []
+for key, value in author_name_mapping.items():
+    if not value:
+        empty.append(key)
+for e in empty:
+    author_name_mapping[e] = e.title()
+del empty, e
+
+# useful reverse lookup RealName -> UnixName
+author_name_mapping_reverse = {}
+for key, value in author_name_mapping.items():
+    author_name_mapping_reverse[value] = key
+
+
+def build_patch_name_map(filepath):
+    """ Uses the CSV from the patch tracker to build a
+        patch <-> author name mapping.
+    """
+    patches = {}
+    import csv
+    tracker = csv.reader(open(filepath, 'r'), delimiter=';', quotechar='|')
+    for i, row in enumerate(tracker):
+        if i == 0:
+            id_index = row.index("artifact_id")
+            author_index = row.index("submitter_name")
+            date_index = row.index("open_date")
+            status_index = row.index("status_name")  # Open/Closed
+            min_len = max(id_index, author_index, status_index, date_index)
+        else:
+            if len(row) < min_len:
+                continue
+
+            # lets just store closed patches, saves time
+            if row[status_index].strip("\"") == 'Closed':
+                patches[int(row[id_index])] = {
+                    "author": row[author_index].strip("\"").strip().title(),
+                    "date": row[date_index].strip("\""),
+                    }
+    return patches
+
+
+def patch_numbers_from_log(msg):
+    """ Weak method to pull patch numbers out of a commit log.
+        rely on the fact that its unlikely any given number
+        will match up with a closed patch but its possible.
+    """
+    patches = []
+    msg = msg.replace(",", " ")
+    msg = msg.replace(".", " ")
+    msg = msg.replace("-", " ")
+    for w in msg.split():
+        if      (w[0].isdigit() or
+                (len(w) > 2 and w[0] == "[" and w[1] == "#") or
+                (len(w) > 1 and w[0] == "#")):
+            
+            try:
+                num = int(w.strip("[]#"))
+            except ValueError:
+                num = -1
+
+            if num != -1:
+                patches.append(num)
+
+    return patches
+
+
+def patch_find_author(commit, patch_map):
+    patches = patch_numbers_from_log(commit.message)
+    for p in patches:
+        if p in patch_map:
+            patch = patch_map[p]
+
+            print(author_name_mapping[commit.author],
+                  "committing patch for",
+                  patch["author"],
+                  commit.revision,
+                  )
+
+            return p, patch["author"]
+
+    return None, None
+
+
+class Credit(object):
+    __slots__ = ("commits",
+                 "is_patch"

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list