1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
from htmlentitydefs import name2codepoint
import os
import os.path
import re
import time
import urllib2
import ibid
def ago(delta, units=None):
parts = []
for unit, value in (('year', delta.days/365), ('month', delta.days/30 % 12), ('day', delta.days % 30), ('hour', delta.seconds/3600), ('minute', delta.seconds/60 % 60), ('second', delta.seconds % 60), ('millisecond', delta.microseconds/1000)):
if value > 0 and (unit != 'millisecond' or len(parts) == 0):
parts.append('%s %s%s' % (value, unit, value != 1 and 's' or ''))
if units and len(parts) >= units:
break
formatted = ' and '.join(parts)
return formatted.replace(' and ', ', ', len(parts)-2)
def substitute_entity(match):
ent = match.group(2)
if match.group(1) == "#":
return unichr(int(ent))
else:
cp = name2codepoint.get(ent)
if cp:
return unichr(cp)
else:
return match.group()
def decode_htmlentities(string):
entity_re = re.compile("&(#?)(\d{1,5}|\w{1,8});")
return entity_re.subn(substitute_entity, string)[0]
def cacheable_download(url, cachefile):
"""Download url to cachefile if it's modified since cachefile.
Specify cachefile in the form pluginname/cachefile.
Returns complete path to downloaded file."""
# We do allow absolute paths, for people who know what they are doing,
# but the common use case should be pluginname/cachefile.
if cachefile[0] not in (os.sep, os.altsep):
cachedir = ibid.config.plugins['cachedir']
if not cachedir:
cachedir = os.path.join(ibid.options['base'], 'cache')
elif cachedir[0] == "~":
cachedir = os.path.expanduser(cachedir)
plugindir = os.path.join(cachedir, os.path.dirname(cachefile))
if not os.path.isdir(plugindir):
os.makedirs(plugindir)
cachefile = os.path.join(cachedir, cachefile)
exists = os.path.isfile(cachefile)
req = urllib2.Request(url)
if exists:
modified = os.path.getmtime(cachefile)
modified = time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(modified))
req.add_header("If-Modified-Since", modified)
try:
connection = urllib2.urlopen(req)
except urllib2.HTTPError, e:
if e.code == 304 and exists:
return cachefile
else:
raise
# Download into a temporary file, in case something goes wrong
downloadfile = os.path.join(plugindir, ".download." + os.path.basename(cachefile))
outfile = file(downloadfile, "wb")
buf = "x"
while len(buf) > 0:
buf = connection.read(1024)
outfile.write(buf)
outfile.close()
try:
os.rename(downloadfile, cachefile)
except OSError:
# Are we on a system that doesn't support atomic renames?
os.remove(cachefile)
os.rename(downloadfile, cachefile)
return cachefile
def file_in_path(program):
path = os.environ.get("PATH", os.defpath).split(os.pathsep)
path = [os.path.join(dir, program) for dir in path]
path = [True for file in path if os.path.isfile(file)]
return bool(path)
def unicode_output(output, errors="strict"):
try:
encoding = os.getenv("LANG").split(".")[1]
except:
encoding = "ascii"
return unicode(output, encoding, errors)
|