~epidermis/epidermis/devel

9 by David D Lowe
• Added partial repository browsing capability: (Find More button)
1
#!/usr/bin/env python
156 by David D Lowe
Update copyright headers to reflect GPL2.
2
# -*- coding: utf-8 -*-
3
# Copyright © David D Lowe 2008-2011
179 by David D Lowe
Deleted extra space from end of copyright header for strict compliance with PEP8.
4
# This program is free software under the terms of GPLv2. For more
156 by David D Lowe
Update copyright headers to reflect GPL2.
5
# information, see the file named COPYING distributed with this project.
6
24.1.15 by David Lowe
Loading and displaying repo
7
"""Runs validate(), update_downloads() and update_preview()
8
validate():Checks every pigment in repoDir to make sure it's state is not STATE_EMPTY or STATE_INCOMPLETE or STATE_INFO,
9
that all pigments have their data in a data/ folder,
10
and that all skins have their dependencies in the repo
11
Exitcode is the number of errors found
12
update_downloads():Writes downloads.xml
13
update_preview(): writes preview_summary.xml, preview_summary.tar.gz and fills previewDir
14
build_pigments(): makes .pigment files"""
15
# Does not check packs
24.1.11 by David D Lowe
Added translation capabilites using gettext.
16
150 by David D Lowe
Added from __future__ import absolute_import to every .py file and made the necessary change to allow for sane relative imports.
17
from __future__ import absolute_import
18
116 by David D Lowe
Refactored ChangeLog to standard format.
19
repoDir = "/var/www/ghns/"
107 by David D Lowe
Added skin generate_preview() method and made Creator interact with it correctly.
20
repoUrl = ""
24.1.15 by David Lowe
Loading and displaying repo
21
previewDir = "preview"
68 by David D Lowe
Epidermis now handles gnomeSplash and wallpaper pigments saved in the old way and automatically upgrades them.
22
ignoreSymlinkWarnings = False
9 by David D Lowe
• Added partial repository browsing capability: (Find More button)
23
31 by David D Lowe
Creator can now handle skin pigments.
24
# TODO: prepare repo for upload
25
# musn't link to localhost anymore, for example
26
9 by David D Lowe
• Added partial repository browsing capability: (Find More button)
27
import sys
28
import getopt
29
import os
30
from xml.dom import minidom
31
import xml
32
import subprocess
21 by David D Lowe
Massive rename: the program is now called Epidermis.
33
import pdb
34
9 by David D Lowe
• Added partial repository browsing capability: (Find More button)
35
24.1.15 by David Lowe
Loading and displaying repo
36
37
def main():
38
    _prepare_ep_paths()
27 by David D Lowe
• Included distutils setup.py file.
39
    
40
    stopat = 99
41
    if len(sys.argv) > 1:
42
        if sys.argv[1] == "--validate":
43
            stopat = 1
44
        elif sys.argv[1] == "--update-downloads":
45
            stopat = 2
46
        elif sys.argv[1] == "--update-preview":
47
            stopat = 3
48
        elif sys.argv[1] == "--build-pigments":
49
            stopat = 99
50
        else:
51
            print >> sys.stderr, "unrecognised argument: " + sys.argv[1]
52
            print >> sys.stderr, "reconginsed argumnts are: --validate , --update-downloads , --update-preview, --build-pigments"
68 by David D Lowe
Epidermis now handles gnomeSplash and wallpaper pigments saved in the old way and automatically upgrades them.
53
    
54
    print "validating pigments..."
24.1.15 by David Lowe
Loading and displaying repo
55
    errors, pigments = validate()
56
        
57
    if errors > 0:
58
        print >> sys.stderr, "found %s error(s)" % errors
59
60
        sys.exit(errors)
61
    else:
62
        print "no errors found, preliminary check passed"
68 by David D Lowe
Epidermis now handles gnomeSplash and wallpaper pigments saved in the old way and automatically upgrades them.
63
27 by David D Lowe
• Included distutils setup.py file.
64
    if stopat > 1:
24.1.15 by David Lowe
Loading and displaying repo
65
        update_downloads(pigments)
66
        
68 by David D Lowe
Epidermis now handles gnomeSplash and wallpaper pigments saved in the old way and automatically upgrades them.
67
    if stopat > 2:
68
        update_preview(pigments)
69
        
70
    if stopat > 3:
71
        build_pigments(pigments)
24.1.15 by David Lowe
Loading and displaying repo
72
73
def validate():
74
    """returns (errors, pigments)"""
150 by David D Lowe
Added from __future__ import absolute_import to every .py file and made the necessary change to allow for sane relative imports.
75
    from epidermis import const
76
    from epidermis import managepigments
77
    from epidermis.pigments import pigment
9 by David D Lowe
• Added partial repository browsing capability: (Find More button)
78
    
79
    errors = 0
80
    
24.1.15 by David Lowe
Loading and displaying repo
81
    readPigments = []
82
    for pigmentType in const.PIGMENT_TYPES[1:] + ["skin"]:
83
        plural = managepigments.get_pigment_type(pigmentType).directoryName
84
        for dir in os.listdir(os.path.join(repoDir, plural)):
85
            if os.path.isdir(os.path.join(repoDir,plural,dir)):
86
                curr = os.path.join(repoDir, plural, dir)
87
                if os.path.exists(os.path.join(curr,"pigment.xml")):
88
                    pigm = managepigments.create_pigment(pigmentType)
89
                    try:
90
                        if pigmentType == "skin":
91
                            pigm.read_with_pigments(os.path.join(curr, "pigment.xml"), readPigments)
92
                        else:
93
                            pigm.read(os.path.join(curr, "pigment.xml"))
94
                    except Exception, ee:
38 by David D Lowe
Fixed bug #303520 (No module named glib)
95
                        print "error: " + os.path.join(curr, "pigment.xml") + " cannot be read, following exception:"
24.1.15 by David Lowe
Loading and displaying repo
96
                        print "::", str(ee)
97
                        errors += 1
98
                    else:
99
                        newErrors = 0
24.1.19 by David D Lowe
Changed <pigment> element in pigment.xml to <codename>.
100
                        if not os.path.abspath(os.path.join(repoDir, plural, pigm.codeName)) == curr:
38 by David D Lowe
Fixed bug #303520 (No module named glib)
101
                            print "error: " + os.path.join(curr, "pigment.xml") + "'s directory does not match its codeName: " + pigm.codeName
24.1.19 by David D Lowe
Changed <pigment> element in pigment.xml to <codename>.
102
                            newErrors += 1
103
                        elif not os.path.isdir(os.path.join(curr, "data")):
38 by David D Lowe
Fixed bug #303520 (No module named glib)
104
                            print "error: Cannot find directory " + os.path.join(curr, "data")
24.1.15 by David Lowe
Loading and displaying repo
105
                            newErrors += 1
106
                        else:
107
                            for attach in pigm.attachments:
108
                                justFilename = attach[(-1*len(attach.split("/")[-1])):]
109
                                if not os.path.exists(os.path.join(curr, "data", justFilename)):
38 by David D Lowe
Fixed bug #303520 (No module named glib)
110
                                    print "error: " + os.path.join(curr, "pigment.xml") + " cannot be read, cannot find the following attachment in data:"
24.1.15 by David Lowe
Loading and displaying repo
111
                                    print "::", "\"" + justFilename + "\""
112
                                    newErrors += 1
68 by David D Lowe
Epidermis now handles gnomeSplash and wallpaper pigments saved in the old way and automatically upgrades them.
113
                                elif not os.access(os.path.join(curr, "data", justFilename), os.R_OK):
114
                                    print "error: " + os.path.join(curr, "pigment.xml") + " cannot be read, permission error for following attachment:"
115
                                    print "::", "\"" + justFilename + "\""
116
                                    newErrors += 1
117
                            for parent, dirs, files in os.walk(curr):
118
                                if not os.access(os.path.realpath(parent), os.R_OK + os.X_OK):
119
                                    if not os.path.isdir(os.path.realpath(parent)):
120
                                        if not ignoreSymlinkWarnings:
121
                                            print "warning: " + parent + " is a symlink that points to a directory that does not exist"
122
                                    elif os.stat(parent).st_uid != 0:
123
                                        print "error: " + parent + " is not owned by root"
124
                                        newErrors +=1
125
                                        continue
126
                                    else:
127
                                        print "error: " + parent + " cannot be read, permissions problem"
128
                                        newErrors += 1
129
                                        continue
130
                                for file in files:
131
                                    if not os.access(os.path.realpath(os.path.join(parent, file)), os.R_OK):
132
                                        if not os.path.exists(os.path.realpath(os.path.join(parent, file))):
133
                                            if not ignoreSymlinkWarnings:
134
                                                print "warning: " + os.path.join(parent, file) + " is a symlink that points to a file that does not exist"
135
                                        elif os.stat(os.path.join(parent, file)).st_uid != 0:
136
                                            print "error: " + os.path.join(parent, file) + " is not owned by root"
137
                                            newErrors += 1
138
                                        else:
139
                                            print "error: " + os.path.join(parent, file) + " cannot be read, permissions problem"
140
                                            newErrors += 1
141
142
                            
24.1.15 by David Lowe
Loading and displaying repo
143
                        if newErrors == 0:
61 by David D Lowe
Cleaning up code.
144
                            if pigm.get_state() in (pigment.STATE_EMPTY, pigment.STATE_INCOMPLETE):
38 by David D Lowe
Fixed bug #303520 (No module named glib)
145
                                print "error: " + os.path.join(curr, "pigment.xml") + " is " + pigm.debug_get_state_str()
24.1.15 by David Lowe
Loading and displaying repo
146
                                errors += 1
43 by David D Lowe
Fixed crash after installation of pigments.
147
                            elif not pigm.is_attachment_correct():
148
                                print "error: " + os.path.join(curr, "pigment.xml") + " has an invalid attachment"
149
                                errors += 1
24.1.15 by David Lowe
Loading and displaying repo
150
                        else:
151
                            errors += newErrors
27 by David D Lowe
• Included distutils setup.py file.
152
                        if pigm.copyright.lower() == "unknown":
153
                            print "warning: " + os.path.join(curr, "pigment.xml") + " has unknown copyright"
24.1.15 by David Lowe
Loading and displaying repo
154
                        readPigments.append(pigm)
9 by David D Lowe
• Added partial repository browsing capability: (Find More button)
155
                else:
38 by David D Lowe
Fixed bug #303520 (No module named glib)
156
                    print "error: missing " + os.path.join(curr,"pigment.xml")
24.1.15 by David Lowe
Loading and displaying repo
157
                    errors += 1
158
                    
159
    
160
161
    return (errors, readPigments)
162
163
164
def update_downloads(pigments):
165
    """pigments: list of Pigment objects"""
150 by David D Lowe
Added from __future__ import absolute_import to every .py file and made the necessary change to allow for sane relative imports.
166
    from epidermis import const
167
    from epidermis import managepigments
168
    from epidermis.pigments import pigment
24.1.15 by David Lowe
Loading and displaying repo
169
    from xml.dom import minidom
170
    
171
    docDownloads = minidom.Document()
172
    rootDownloads = docDownloads.createElement("ghnsdownload")
107 by David D Lowe
Added skin generate_preview() method and made Creator interact with it correctly.
173
    rootDownloads.setAttribute("epidermisVersion","0.4")
24.1.15 by David Lowe
Loading and displaying repo
174
    docDownloads.appendChild(rootDownloads)
175
    
176
    stuffPreview = docDownloads.createElement("stuff")
177
    stuffPreview.setAttribute("category", "epidermis/repo_preview_summary")
178
    nn = docDownloads.createElement("name")
179
    nn.appendChild(docDownloads.createTextNode("Summary"))
180
    pp = docDownloads.createElement("payload")
181
    pp.appendChild(docDownloads.createTextNode(repoUrl + "preview_summary.tar.gz"))
182
    for ii in (nn, pp):
183
        stuffPreview.appendChild(ii)
184
    rootDownloads.appendChild(stuffPreview) 
185
    
186
    for pigm in pigments:
187
        stuff = docDownloads.createElement("stuff")
188
        stuff.setAttribute("category", "epidermis/pigment/" + pigm.type.codeName)
189
        for lang in pigm.humanName.keys():
190
            name = docDownloads.createElement("name")
191
            name.setAttribute("lang", lang)
192
            name.appendChild(docDownloads.createTextNode(pigm.get_human_name(lang)))
193
            stuff.appendChild(name)
194
        author = docDownloads.createElement("author")
195
        author.appendChild(docDownloads.createTextNode(pigm.author))
196
        licence = docDownloads.createElement("licence")
197
        licence.appendChild(docDownloads.createTextNode(pigm.copyright))
198
        version = docDownloads.createElement("version")
199
        version.appendChild(docDownloads.createTextNode("1.0"))
200
        release = docDownloads.createElement("release")
201
        release.appendChild(docDownloads.createTextNode("1"))
202
        releasedate = docDownloads.createElement("releasedate")
203
        payload = docDownloads.createElement("payload")
204
        payload.appendChild(docDownloads.createTextNode(\
205
            os.path.join(repoDir, pigm.type.directoryName, pigm.codeName, pigm.codeName + "_" + pigm.type.codeName + ".pigment")))
206
        for ii in (author, licence, version, release, releasedate, payload):
207
            stuff.appendChild(ii)
208
        rootDownloads.appendChild(stuff)
209
    
210
    fileDownloads = open(os.path.join(repoDir, "downloads.xml"), "w")
211
    docDownloads.writexml(fileDownloads)
212
    fileDownloads.close()
148 by David D Lowe
Pretty print xml documents in convenience_scripts
213
    
214
    subprocess.call(["xml_pp","-i",os.path.join(repoDir, "downloads.xml")])
215
    subprocess.call(["chmod", "644", os.path.join(repoDir, "downloads.xml")])
24.1.15 by David Lowe
Loading and displaying repo
216
217
    print "Wrote %s" % os.path.join(repoDir, "downloads.xml")
218
    
219
    
220
    
221
def update_preview(pigments):
222
    """pigments: a list of Pigment objects"""
150 by David D Lowe
Added from __future__ import absolute_import to every .py file and made the necessary change to allow for sane relative imports.
223
    from epidermis import const
224
    from epidermis import managepigments
225
    from epidermis.pigments import pigment
24.1.15 by David Lowe
Loading and displaying repo
226
    from xml.dom import minidom
227
    
228
    docSummary = minidom.Document()
229
    rootSummary = docSummary.createElement("previewSummary")
230
    docSummary.appendChild(rootSummary)
231
    
232
    ptElement = {}
233
    for pt in const.PIGMENT_TYPES:
234
        ptElement[pt] = docSummary.createElement(managepigments.get_pigment_type(pt).directoryName)
235
        rootSummary.appendChild(ptElement[pt])
236
    
237
    for pigm in pigments:
238
        item = docSummary.createElement("item")
239
        item.setAttribute("id", pigm.type.abbreviation + "-" + pigm.codeName)
240
        for lang in pigm.humanName.keys():
241
            name = docSummary.createElement("name")
242
            name.setAttribute("lang", lang)
243
            name.appendChild(docSummary.createTextNode(pigm.get_human_name(lang)))
244
            item.appendChild(name)
24.1.19 by David D Lowe
Changed <pigment> element in pigment.xml to <codename>.
245
        pigmentEl = docSummary.createElement("codename")
24.1.15 by David Lowe
Loading and displaying repo
246
        pigmentEl.appendChild(docSummary.createTextNode(pigm.codeName))
247
        copyright = docSummary.createElement("copyright")
248
        copyright.appendChild(docSummary.createTextNode(pigm.copyright))
249
        for it in (pigmentEl, copyright):
250
            item.appendChild(it)
251
        for lang in pigm.description.keys():
252
            description = docSummary.createElement("description")
253
            description.setAttribute("lang", lang)
254
            description.appendChild(docSummary.createTextNode(pigm.get_description(lang)))
255
            item.appendChild(description)
256
        author = docSummary.createElement("author")
257
        author.appendChild(docSummary.createTextNode(pigm.author))
258
        item.appendChild(author)
259
        if pigm.type.codeName == "skin":
77 by David D Lowe
Skins no longer require a linked pigment from every type.
260
            for pt2 in pigm.linkedPigments.keys():
100 by David D Lowe
Replaced Usplash with Xsplash.
261
                if pt2 in const.PIGMENT_TYPES[1:]:
262
                    link = docSummary.createElement(pt2 + "Dependancy")
263
                    link.appendChild(docSummary.createTextNode(pigm.linkedPigments[pt2].codeName))
264
                    item.appendChild(link)
107 by David D Lowe
Added skin generate_preview() method and made Creator interact with it correctly.
265
        preview = docSummary.createElement("preview")
266
        preview.appendChild(docSummary.createTextNode(previewDir + "/" + pigm.type.directoryName + \
267
            "/" + pigm.codeName + "/" + pigm.previewFilename))
268
        item.appendChild(preview)
24.1.15 by David Lowe
Loading and displaying repo
269
        ptElement[pigm.type.codeName].appendChild(item)
270
    
271
    fileSummary = open(os.path.join(repoDir, "preview_summary.xml"), "w")
272
    docSummary.writexml(fileSummary)
273
    fileSummary.close()
148 by David D Lowe
Pretty print xml documents in convenience_scripts
274
    
275
    import subprocess
276
    subprocess.call(["xml_pp", "-i", os.path.join(repoDir, "preview_summary.xml")])
277
    subprocess.call(["chmod", "644", os.path.join(repoDir, "preview_summary.xml")])
24.1.15 by David Lowe
Loading and displaying repo
278
279
    print "Wrote %s" % os.path.join(repoDir, "preview_summary.xml")    
280
    
281
    subprocess.call(["rm", "-f", "-r", os.path.join(repoDir, previewDir)])
282
    subprocess.call(["mkdir", "-p", os.path.join(repoDir, previewDir)])
283
    for pt in const.PIGMENT_TYPES:
284
        subprocess.call(["mkdir", "-p", os.path.join(repoDir, previewDir, managepigments.get_pigment_type(pt).directoryName)])
285
    for pigm in pigments:
286
        if len(pigm.previewFilename) > 0:
287
            subprocess.call(["mkdir", "-p", os.path.join(repoDir, previewDir, pigm.type.directoryName, pigm.codeName)])
288
            subprocess.call(["cp", os.path.join(repoDir, pigm.type.directoryName, pigm.codeName, pigm.previewFilename), \
289
                os.path.join(repoDir, previewDir, pigm.type.directoryName, pigm.codeName)])
290
    
291
    subprocess.call(["tar", "-cf", "preview_summary.tar", "preview_summary.xml", previewDir], cwd=repoDir)
292
    subprocess.call(["rm", "-f", "preview_summary.tar.gz"], cwd=repoDir)
293
    subprocess.call(["gzip", "preview_summary.tar"], cwd=repoDir)
294
    
295
    print "Finished %s/ and preview_summary.tar.gz" % previewDir
296
297
def build_pigments(pigments):
298
    """Builds .pigment files from the pigment.xml, preview and data in the repo
148 by David D Lowe
Pretty print xml documents in convenience_scripts
299
    pigments: list of Pigment objects in the repo
300
    Updates pigment.xml to be pretty printed as well"""
24.1.15 by David Lowe
Loading and displaying repo
301
    
150 by David D Lowe
Added from __future__ import absolute_import to every .py file and made the necessary change to allow for sane relative imports.
302
    from epidermis import const
303
    from epidermis import managepigments
24.1.15 by David Lowe
Loading and displaying repo
304
    
305
    
306
    for pigm in pigments:
307
        curr = os.path.join(repoDir, pigm.type.directoryName, pigm.codeName)
308
        sys.stdout.write(os.path.join(curr, pigm.codeName + "_" + pigm.type.codeName + ".pigment") + " ... ")
116 by David D Lowe
Refactored ChangeLog to standard format.
309
        sys.stdout.flush()
24.1.15 by David Lowe
Loading and displaying repo
310
        
311
        try:
312
            subprocess.call(["mkdir", "-p", "/tmp/epidermis/build_pigment/"])
313
            subprocess.call("rm -r -f /tmp/epidermis/build_pigment/*", shell=True)
148 by David D Lowe
Pretty print xml documents in convenience_scripts
314
            subprocess.call(["xml_pp", "-i", os.path.join(curr, "pigment.xml")])
315
            subprocess.call(["chmod", "644", os.path.join(curr, "pigment.xml")])
24.1.15 by David Lowe
Loading and displaying repo
316
            if len(pigm.previewFilename) > 0:
317
                subprocess.call(["cp", "-r", "data/", "pigment.xml", pigm.previewFilename, "/tmp/epidermis/build_pigment"], cwd=curr)
9 by David D Lowe
• Added partial repository browsing capability: (Find More button)
318
            else:
24.1.15 by David Lowe
Loading and displaying repo
319
                subprocess.call(["cp", "-r", "data/", "pigment.xml", "/tmp/epidermis/build_pigment"], cwd=curr)
320
            subprocess.call(["mkdir", "/tmp/epidermis/build_pigment/information"])
321
            subprocess.call(["mv", "pigment.xml", "information/"], cwd="/tmp/epidermis/build_pigment")
322
            if len(pigm.previewFilename) > 0:
323
                subprocess.call(["mv", pigm.previewFilename, "information/"], cwd="/tmp/epidermis/build_pigment")
324
            subprocess.call(["tar", "-cf", "build.tar", "data/", "information/"], cwd="/tmp/epidermis/build_pigment")
325
            subprocess.call(["gzip", "build.tar"], cwd="/tmp/epidermis/build_pigment")
68 by David D Lowe
Epidermis now handles gnomeSplash and wallpaper pigments saved in the old way and automatically upgrades them.
326
            subprocess.call(["mv", "-f", os.path.join("/tmp/epidermis/build_pigment", "build.tar.gz"), \
24.1.15 by David Lowe
Loading and displaying repo
327
                os.path.join(curr, pigm.codeName + "_" + pigm.type.codeName + ".pigment")])
328
        except Exception, ee:
329
            print ""
330
            raise(ee)
331
        else:
332
            print "built"
9 by David D Lowe
• Added partial repository browsing capability: (Find More button)
333
    
24.1.15 by David Lowe
Loading and displaying repo
334
335
def _prepare_ep_paths():
336
    ep_path = determine_path()[:(-1*len(determine_path().split("/")[-1]))]
150 by David D Lowe
Added from __future__ import absolute_import to every .py file and made the necessary change to allow for sane relative imports.
337
    sys.path.insert(1, ep_path)
24.1.15 by David Lowe
Loading and displaying repo
338
339
340
def determine_path ():
341
    """Borrowed from wxglade.py"""
342
    try:
343
        root = __file__
344
        if os.path.islink (root):
345
            root = os.path.realpath (root)
346
        return os.path.dirname (os.path.abspath (root))
347
    except Exception, ee:
348
        print >> sys.stderr, "I'm sorry, but something is wrong."
349
        print >> sys.stderr, "There is no __file__ variable. Please contact the author."
350
        sys.exit (1)
351
        raise(ee)
352
353
if __name__ == "__main__":
354
    main()
21 by David D Lowe
Massive rename: the program is now called Epidermis.
355