[geneagrapher] 01/226: * Established geneagrapher repository tree. * Imported geneagrapher source.

Doug Torrance dtorrance-guest at moszumanska.debian.org
Sat Jul 11 17:10:30 UTC 2015


This is an automated email from the git hooks/post-receive script.

dtorrance-guest pushed a commit to branch master
in repository geneagrapher.

commit adff25e2350d7be0aa7e50666e8cbdb56a329e82
Author: David Alber <alber.david at gmail.com>
Date:   Wed Apr 2 02:35:35 2008 +0000

     * Established geneagrapher repository tree.
     * Imported geneagrapher source.
---
 src/GGraph.py     | 107 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/geneagraph.py | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/grab.py       |  57 ++++++++++++++++++++++++++
 3 files changed, 283 insertions(+)

diff --git a/src/GGraph.py b/src/GGraph.py
new file mode 100644
index 0000000..20b5559
--- /dev/null
+++ b/src/GGraph.py
@@ -0,0 +1,107 @@
+class Record:
+    "Record of a mathematician in the graph."
+    def __init__(self, name, institution, year, id):
+        self.name = name
+        self.institution = institution
+        self.year = year
+        self.id = id
+
+    def __cmp__(self, r2):
+        return self.id.__cmp__(r2.id)
+
+    
+
+class Node:
+    "Node in the graph."
+    def __init__(self, record, ancestors):
+        self.record = record
+        self.ancestors = ancestors
+        self.already_printed = False
+
+    def __str__(self):
+        if self.record.institution != '':
+            if self.record.year > -1:
+                return self.record.name.encode('iso-8859-1', 'replace') + ' \\n' + self.record.institution.encode('iso-8859-1', 'replace') + ' (' + str(self.record.year) + ')'
+            else:
+                return self.record.name.encode('iso-8859-1', 'replace') + ' \\n' + self.record.institution.encode('iso-8859-1', 'replace')
+        else:
+            if self.record.year > -1:
+                return self.record.name.encode('iso-8859-1', 'replace') + ' \\n(' + str(self.record.year) + ')'
+            else:
+                return self.record.name.encode('iso-8859-1', 'replace')
+
+    def __cmp__(self, n2):
+        return self.record.__cmp__(n2.record)
+
+    def addAncestor(self, ancestor):
+        self.ancestors.append(ancestor)
+
+    def id(self):
+        return self.record.id
+
+
+class Graph:
+    def __init__(self, head, displayHead=True):
+        self.head = head
+        self.nodes = {head.id(): head}
+        self.displayHead = displayHead
+        
+    def hasNode(self, id):
+        return self.nodes.has_key(id)
+
+    def getNode(self, id):
+        return self.nodes[id]
+
+    def getNodeList(self):
+        return self.nodes.keys()
+
+    def addNode(self, name, institution, year, id, ancestors):
+        record = Record(name, institution, year, id)
+        node = Node(record, ancestors)
+        self.nodes[id] = node
+
+    def generateDotFile(self):
+        if self.displayHead:
+            queue = [self.head.id()]
+        else:
+            queue = self.head.ancestors
+        edges = ""
+        dotfile = ""
+        
+        dotfile += """digraph genealogy {
+        graph [charset="iso-8859-1"];
+        node [shape=plaintext];
+	edge [style=bold];\n\n"""
+
+        while len(queue) > 0:
+            node_id = queue.pop()
+            node = self.getNode(node_id)
+
+            if node.already_printed:
+                continue
+            else:
+                node.already_printed = True
+            
+            # Add this node's advisors to queue.
+            queue += node.ancestors
+        
+            # Print this node's information.
+            dotfile += "\t" + str(node_id) + " [label=\" " + str(node) + "\"];\n"
+
+            # Store the connection information for this node.
+            for advisor in node.ancestors:
+                edges += "\n\t" + str(advisor) + " -> " + str(node_id) + ";"
+
+        # Now print the connections between the nodes.
+        dotfile += edges
+
+        dotfile += "\n}\n"
+        return dotfile
+
+    def printDotFile(self):
+        print self.generateDotFile()
+
+    def writeDotFile(self, filename):
+        outfile = open(filename, 'w')
+        outfile.write(self.generateDotFile())
+        outfile.close()
diff --git a/src/geneagraph.py b/src/geneagraph.py
new file mode 100644
index 0000000..482eb9b
--- /dev/null
+++ b/src/geneagraph.py
@@ -0,0 +1,119 @@
+#!/usr/bin/python
+
+import cgi
+import random
+import os
+import time
+from grab import *
+from GGraph import *
+#import cgitb; cgitb.enable() # for debugging, comment out for production
+
+form = cgi.FieldStorage()
+name = form.getfirst("name", "")
+extra = form.getfirst("extra", "")
+nodes = form.getlist("node")
+output = form.getfirst("output", "png")
+
+# Save the input to log file.
+f = open("/var/log/geneagraph", "a")
+f.write(time.strftime('%m/%d/%Y %H:%M:%S'))
+f.write(" ")
+f.write(os.environ['REMOTE_ADDR'])
+f.write("\n")
+if name != "":
+	f.write("\tName: ")
+	f.write(name)
+	f.write("\n")
+if extra != "":
+	f.write("\tExtra: ")
+	f.write(extra)
+	f.write("\n")
+if len(nodes) > 0:
+	f.write("\t")
+	f.write(str(nodes))
+	f.write("\n")
+f.close()
+
+try:
+	if len(name) > 100:
+		raise ValueError("Name field longer than maximum allowed length (100 characters).")
+	if len(extra) > 100:
+		raise ValueError("Extra field longer than maximum allowed length (100 characters).")
+	if len(nodes) > 5:
+	#if len(nodes) > 50:
+		raise ValueError("Only five node URLs may be supplied.")
+
+# Replace special characters in name and extra with backslashed form
+	name = name.replace('\\', '\\\\')
+	name = name.replace('\"', '\\"')
+	extra = extra.replace('\\', '\\\\')
+	extra = extra.replace('"', '\\"')
+
+	record = Record(name, extra, -1, 0)
+
+	printHead = True
+	if name == "" and extra == "":
+		printHead = False
+
+	advisors = []
+	for index in range(len(nodes)):
+		if not nodes[index].isspace():
+			if nodes[index].find('id.php?id=') > -1:
+				id = nodes[index].split('id.php?id=')[1].strip()
+				if id.isdigit():
+					advisors.append(int(id))
+				else:
+					raise ValueError("Node " + str(index+1) + " was improperly formatted.")
+			else:
+				raise ValueError("Node " + str(index+1) + " was improperly formatted.")
+
+		
+	node = Node(record, advisors)
+	graph = Graph(node, printHead)
+
+	for advisor in advisors:
+		extractNodeInformation(advisor, graph)
+
+	fnum = str(int(random.random()*1000000000000000))
+	filename = '/tmp/' + fnum + '.dot'
+	graph.writeDotFile(filename)
+
+	if output == "dot":
+		print "Content-Type: text/html"
+		print
+		print "<html><body><pre>"
+		f = open(filename, "r")
+		file = f.read()
+		f.close()
+		print file
+		print "</pre></body></html>"
+	elif output == "png" or output == "ps":
+		psfilename = '/tmp/' + fnum + '.ps'
+		command = '/usr/local/bin/dot -Tps ' + filename + ' -o ' + psfilename
+		os.system(command)
+		if output == "png":
+			pngfilename = '/tmp/' + fnum + '.png'
+			command = '/usr/bin/convert -density 144 -geometry 50% ' + psfilename + ' ' + pngfilename
+			os.system(command)
+			print "Content-type: image/png"
+			print "Content-Disposition: attachment; filename=genealogy.png"
+			print
+			f = open(pngfilename, "r")
+		elif output == "ps":
+			print "Content-Type: application/postscript"
+			print
+			f = open(psfilename, "r")
+		file = f.read()
+		f.close()
+		print file
+	else: # improper output chosen
+		raise ValueError("Return type was improperly formatted. Go back and check it out.")
+
+	command = '/bin/rm /tmp/' + fnum + '.*'
+	os.system(command)
+
+except ValueError, e:
+	print "Content-type: text/html"
+	print
+	print e, "<br>Go back and check it out."
+	raise SystemExit
diff --git a/src/grab.py b/src/grab.py
new file mode 100644
index 0000000..3d0310f
--- /dev/null
+++ b/src/grab.py
@@ -0,0 +1,57 @@
+import urllib
+from GGraph import *
+
+#id = 7401
+
+def extractNodeInformation(id, graph):
+    search_list = [id]
+
+    while len(search_list) > 0:
+        id = search_list.pop()
+        #url = 'http://genealogy.math.ndsu.nodak.edu/html/id.phtml?id=' + str(id)
+        url = 'http://genealogy.math.ndsu.nodak.edu/id.php?id=' + str(id)
+        #url = 'http://www.genealogy.ams.org/html/id.phtml?id=' + str(id)
+        page = urllib.urlopen(url)
+
+        advisors = []
+        name = ''
+        institution = ''
+        year = -1
+
+        line = page.readline()
+        if line.find("<html>An error occurred in the forwarding block") > -1:
+            # Then a bad URL was given. Throw an exception.
+            raise ValueError("Invalid address given: " + url)
+
+
+        while line != '':
+            line = page.readline()
+            line = line.decode('utf-8')
+            if line.find('h2 style=') > -1:
+            	line = page.readline()
+            	line = line.decode('utf-8')
+                name = line.split('</h2>')[0].strip()
+
+            if line.find('#006633; margin-left: 0.5em">') > -1:
+                inst_year = line.split('#006633; margin-left: 0.5em">')[1].split("</span>")[:2]
+                institution = inst_year[0].strip()
+                if inst_year[1].strip().isdigit():
+                    year = int(inst_year[1].strip())
+
+            if line.find('Advisor') > -1:
+                if line.find('a href=\"id.php?id=') > -1:
+                    # Extract link to advisor page.
+                    advisor_id = int(line.split('a href=\"id.php?id=')[1].split('\">')[0])
+                    advisors.append(advisor_id)
+                    if not graph.hasNode(advisor_id) and search_list.count(advisor_id) == 0:
+                        search_list.append(advisor_id)
+            elif line.find('Student(s)') > -1 or line.find('No students known') > -1:
+                break
+
+        #    print name.encode('iso-8859-1', 'replace')
+        #    print institution.encode('iso-8859-1', 'replace'), year
+        #    print advisors
+
+        if not graph.hasNode(id):
+            # Add node to graph.
+            graph.addNode(name, institution, year, id, advisors)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/geneagrapher.git



More information about the debian-science-commits mailing list