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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
|
#!/usr/bin/python
import os, sys, string, cgi
if sys.platform != 'win32':
from twisted.internet import glib2reactor
glib2reactor.install()
from dbus.mainloop.glib import DBusGMainLoop
DBusGMainLoop(set_as_default=True)
from twisted.internet import defer, reactor
from ubuntuone.platform.tools import SyncDaemonTool
TEMPLATE = """<!doctype html>
<html>
<head>
<meta charset=utf8>
<link href='http://fonts.googleapis.com/css?family=Ubuntu:400,700,400italic,700italic'
rel='stylesheet' type='text/css'>
<style>
body {
font-family: Ubuntu, sans-serif;
}
footer p {
position: fixed;
bottom: 5px;
right: 5px;
text-align: right;
opacity: 0.4;
font-size: 14px;
}
footer a {
display: block;
}
</style>
<title>Files in $foldername</title>
</head>
<body>
<h1>List of files in $foldername</h1>
<ul>
$begin_file_loop
<li><a href="${url}">${name}</a> (${size})</li>
$end_file_loop
</ul>
<footer>
<p>published with <a href="https://one.ubuntu.com"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFsAAAAhCAMAAACBUScMAAAAAXNSR0IArs4c6QAAAGNQTFRFMzMzPz8%2FTExMWVlZ3UcXZmZm31Ilc3Nz4V40f39%2F42lC5XVRjIyM54BfmJiY6YxupaWl65d87aKKsrKy8K6Zv7%2B%2F8rmny8vL9MW29tDE2NjY%2BNzT5eXl%2Bufh8vLy%2FPPw%2F%2F%2F%2F0a4i0gAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfbAhURJxBzvNnHAAAAGXRFWHRDb21tZW50AENyZWF0ZWQgd2l0aCBHSU1QV4EOFwAAAhRJREFUSMfd1tuSoyAQAFCcQRMlakSiQaPw%2F1%2B53TS65qKYmso8TL9w9cRAQ8ns3hjsu8F2zsu5%2FJgtdtjmY3af8I%2FZmv%2BqXQmKq%2FtfvkFjjaioaNAWGedZQ5PsVOhScOiWZOOjvR%2BGhxmOQRyn33ZBtuSCCok2RTm%2FoCvkXTeG9sPw8GTroJ1pa0rOmwc7M667x7aGME92boO2pGXPH2w3JeFqXu8ne9hpNzD2wsbRNVvanbZ%2B384oIz5ic5ryYCvKnqVdQZfBndu0TdjWhCxsk2C2JVy%2BsK1PNoO5FLQBOTZaC7JzrVXCE9h1SDmpdfVoH3l21VUPjUThU9v21Tf%2Fn50E%2F4jJ5mlLu%2FFz4dIictO2A94IlYJ37WUuRK7oGjUKGqWEJdCycamJdbwAhBxw2D3Vb9s%2Fiz9q13Ecn0eodMUBqqcb9R587w%2Fs8ZthRJ21MZurvvc7iLN8wz6wqG4vX%2BwL7bRt64jF1p6gd4RqGrTlun1j7ILLwVgNdgHVC2N2xCasC4uCtj8fGd7rWt3ZZ3xh9%2Fqpt8HtwG8hoLiFbMNfBI0VuAK%2BJNuCW7Ap2uC3T%2Fm2HcUUXdAeVu3nNUEbFmPcmd94Ta%2FYN9q1xV6iDb3n%2Fd%2BDcsXGHDxj4rkcnGybMnaCzTx1e2yrxZ18LF%2Bdndke%2FTmqd37HuisUIpdKLz9H59NdFy4rigITr05hJ4tQCtp%2FRgAMzqyMVToAAAAASUVORK5CYII%3D" alt="Ubuntu One"></a></p>
</footer>
</body>
</html>
"""
@defer.inlineCallbacks
def process_folder(folder):
sd = SyncDaemonTool()
template = TEMPLATE
template_file = None
try:
before, allafter = template.split("$begin_file_loop",1)
loop, after = allafter.split("$end_file_loop", 1)
except ValueError:
print "Template is invalid (does not contain $begin_file_loop and $end_file_loop)"
reactor.stop()
return
print "Examining folder %s" % (folder,)
# Confirm the folder is synced
try:
info = yield sd.get_metadata(path=folder)
except Exception as e:
if e.name == "org.freedesktop.DBus.Python.KeyError":
print "%s is not synced with Ubuntu One. Terminating." % (folder,)
reactor.stop()
return
raise
# Get file details for all files in the folder
filedetails = {}
for f in os.listdir(folder):
fn = os.path.join(folder, f)
if not os.path.isfile(fn):
continue
try:
fileinfo = yield sd.get_metadata(path=fn)
except:
pass
bytes = os.path.getsize(fn)
size = "large"
suffixes = { 1024: " bytes", 1024*1024: "KB", 1024*1024*1024: "MB", 1024*1024*1024*1024: "GB" }
for ceiling in sorted(suffixes.keys()):
if bytes < ceiling:
if ceiling == 1024:
subst = "%0.1d%s"
else:
subst = "%0.1f%s"
size = subst % (bytes / (ceiling / 1024.0), suffixes[ceiling])
break
filedetails[fn] = {"url": None, "name": os.path.split(fn)[1],
"size": size}
# now get the list of all public files
publicfiles = yield sd.get_public_files()
for pf in publicfiles:
if pf["path"] in filedetails:
filedetails[pf["path"]]["url"] = unicode(pf["public_url"])
unpublished = [x[0] for x in filedetails.items() if x[1]["url"] is None]
if unpublished:
print "Publishing %s file%s..." % (len(unpublished), "" if len(unpublished) == 1 else "s")
for fn in unpublished:
done = yield sd.change_public_access(fn, True)
print " published %s" % (fn,)
filedetails[fn]["url"] = unicode(done["public_url"])
else:
print "All files are already published."
print "Constructing the folder index..."
lines = [string.Template(loop).safe_substitute(x) for x in filedetails.values()
if x["name"] != "u1-folder-index.html"]
out = "%s%s%s" % (
string.Template(before).safe_substitute(
foldername=os.path.split(folder)[1]),
"".join(lines),
string.Template(after).safe_substitute(
foldername=os.path.split(folder)[1]))
outfn = os.path.join(folder, "u1-folder-index.html")
if os.path.exists(outfn):
fp = open(outfn)
existing_data = fp.read()
fp.close()
else:
existing_data = None
if existing_data == out:
print "Files have not changed; no need to write index"
print "Folder index available at %s" % filedetails[outfn]["url"]
else:
# write folder index and hang about until it's uploaded
print "Waiting for Ubuntu One to upload index..."
success_filter = lambda path, info: path == outfn
d = sd.wait_for_signals(signal_ok='UploadFinished', success_filter=success_filter)
fp = open(outfn, "w")
fp.write(out)
fp.close()
path, info = yield d
print "Done."
print "Publishing the folder index..."
# publish folder index
done = yield sd.change_public_access(outfn, True)
print "Folder index now available at %s" % unicode(done["public_url"])
reactor.stop()
if __name__ == '__main__':
if len(sys.argv) > 1:
folder = sys.argv[1]
else:
print "Syntax: %s folder" % sys.argv[0]
sys.exit(1)
folder = os.path.realpath(folder)
if not os.path.isdir(folder):
print "%s is not a folder. Terminating." % (folder,)
sys.exit(1)
reactor.callWhenRunning(process_folder, folder)
reactor.run()
|