Uru Library Manager (an alternative)
Uru Library Manager (ULM) has become the default way of sharing and downloading user-created content for Uru. It basically handles a list of Ages, and a list of files for each Age with mirrors and checksums.
The main issue with ULM is the fact that it’s written using .NET 2.0. I can’t make it run on Linux.
I finally got around to writing a CLI-based Python script to download Ages from ULM into the current directory.
#! /usr/bin/env python
import pycurl
import StringIO
import sys
import re
import md5
import base64
import os
baseurl = 'http://ulm.hbyte.net/library.php'
ages = None
# We should ignore SIGPIPE when using pycurl.NOSIGNAL - see
# the libcurl tutorial for more info.
try:
import signal
from signal import SIGPIPE, SIG_IGN
signal.signal(signal.SIGPIPE, signal.SIG_IGN)
except ImportError:
pass
def getAges():
sio = StringIO.StringIO()
c = pycurl.Curl()
c.setopt(c.URL, baseurl + '/LinkingBooks.txt')
c.setopt(c.HTTPGET, True)
c.setopt(pycurl.WRITEFUNCTION, sio.write)
c.setopt(c.VERBOSE, 0)
c.perform()
c.close()
return sio.getvalue().splitlines()
def parseVersion(lines):
ret = {}
lncount = 0
version = None
i = 0
while i < len(lines):
line = lines[i].strip()
if line is '' or line.isspace():
i += 1
lncount += 1
continue
m = re.search("(?<=[[]version )\d(?=[]])", line)
if not m is None:
if version is None:
version = int(m.group(0))
else:
i = len(lines)
break
else:
(name, value) = line.split(':', 1)
if name.endswith('file'):
if name in ret:
ret[name].append(value)
else:
ret[name] = [value,]
else:
ret[name] = value
i += 1
lncount += 1
return (lncount, version, ret)
def parseAge(string):
ret = {}
lns = string.splitlines(True)
i = 0
while i < len(lns):
line = lns[i].strip()
if line is '':
i += 1
continue
#print line
if not line.startswith("[version"):
try:
(name, value) = line.split(':', 1)
except ValueError:
(name, value) = line.split('=', 1)
ret[name] = value
i += 1
else:
(c, v, r) = parseVersion(lns[i:])
i += c
print "We have version %d" % v
ret[v] = r
#print ret
return ret
def progress(download_t, download_d, upload_t, upload_d):
try:
if(prog == None): print "We have some issues..."
except NameError:
prog = 0.0
if download_t == 0:
prog += 0.1
if prog >= 1.0: prog = 0.0
else:
prog = float(download_d) / float(download_t)
s = int(prog*50)
r = 50-s
print "\r[" + "="*s + " "*r + "] %3d%%" % (int(prog*100)),
a = True
while a:
userIn = raw_input("> ")
if userIn.startswith('quit'):
a = False
elif userIn.startswith('help'):
print "Plasma Content Distributor"
print " Darryl 'Paradox' Pogue "
print "=========================="
print "Commands are as follows:"
print " help - print this message"
print " quit - exit the program"
print " lib [url] - change the base library"
print " list - download the list of Ages"
print " get [ID] - download an Age from the Age list"
print " ver [ID] - download the specified Age version"
print " back - return to the main prompt"
elif userIn.startswith('lib '):
gets = userIn.split(' ')
if (len(gets) < 2):
print "You did not provide a library URL"
else:
baseurl = gets[1]
elif userIn.startswith('list'):
ages = getAges()
for age in ages:
if age != '':
print "[%02d] %s" % (ages.index(age) + 1, age)
elif userIn.startswith('get '):
gets = userIn.split(' ')
if ages is None:
print "Need a list of Ages! (Try 'list' at the prompt)"
elif (len(gets) len(ages)) or (int(gets[1]) maxVer:
maxVer = k
b = True
while b:
ageIn = raw_input(">> ")
if ageIn.startswith('back'):
b = False
elif ageIn.startswith('quit'):
b = False
a = False
elif ageIn.startswith('help'):
print "Plasma Content Distributor"
print " Darryl 'Paradox' Pogue "
print "=========================="
print "Commands are as follows:"
print " help - print this message"
print " quit - exit the program"
print " ver [ID] - download the specified Age version"
print " back - return to the main prompt"
elif ageIn.startswith('ver '):
ip = ageIn.split(' ')
if (len(ip) maxVer) or (int(ip[1]) <= 0):
print "Invalid selection"
else:
print "Downloading version %d" % int(ip[1])
key = ret[int(ip[1])]
mirr = key['mirror']
for k in key.iterkeys():
if k.endswith('file'):
filearr = key[k]
for fi in filearr:
(name, md5hash) = fi.split('=', 1)
out = open(name, 'w')
d = pycurl.Curl()
d.setopt(c.URL, mirr + '/' + name)
d.setopt(c.HTTPGET, True)
d.setopt(pycurl.FILE, out);
d.setopt(c.VERBOSE, 0)
d.perform()
d.close()
out.close()
out = open(name, 'r')
digest = md5.new(out.read()).digest()
out.close()
if(base64.encodestring(digest).strip() == md5hash):
print "Saved file " + name
else:
print "Checksum hash failure on file " + name
os.remove(name)
b = False
else:
print "Unrecognized command!"
else:
print "Unrecognized command!"
sys.exit()

diafero said,
Sunday, December 7, 2008 at 7:26
Thanks for that script :)
However, ULM ran great for me on Linux (till I uninstalled it), using wine and installing the .NET Framework 2 in it.