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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
|
#!/usr/bin/env python2.6
# -*- coding: utf-8 -*-
# Copyright © David D Lowe 2008-2011
# This program is free software under the terms of GPLv2. For more
# information, see the file named COPYING distributed with this project.
from __future__ import absolute_import
from distutils.core import setup
from distutils.command.build import build
from distutils.command.build_py import build_py
from distutils.core import Command
import distutils.command.clean
import distutils.command.sdist
import os, sys
import glob
from subprocess import call
import gettext
from xml.dom import minidom
# Epidermis version
try:
import epidermis.const
constPath = os.path.abspath(epidermis.const.__file__)
if constPath[-4:] in (".pyc", ".pyo"):
constPath = constPath[:-1]
if not os.path.samefile(constPath, os.path.join(os.path.dirname(os.path.abspath(__file__)),"epidermis/const.py")):
print >> sys.stderr, "could not import %s" % os.path.join(os.path.dirname(os.path.abspath(__file__)), "epidermis/const.py")
raise
del(constPath)
except:
print >> sys.stderr, "Could not find version, because python couldn't import epidermis.const"
raise
def main():
data_files = glob.glob("data/*") # data_files a list of strings
# of the relative paths of all non-py files that should be included
# ex: data_files is ['data/creator.glade', 'data/epidermis.glade', ...]
# Check python version
if sys.version < '2.6' or sys.version >= '3.0':
class IncorrectPythonVersion():
def __str__(self): return "Incorrect python version, need 2.6"
raise(IncorrectPythonVersion())
setup( name="epidermis", # this should start with a lowercase letter
#so that it can be used as a debian package name later on
version=epidermis.const.VERSION, # string, version of your program, not python version
description="Epidermis theme manager for your GNOME desktop on Ubuntu", # short
author="David D Lowe",
author_email="daviddlowesemail@find-me-at-epidermis.tuxfamily.org",
url="http://epidermis.tuxfamily.org", # home page for end-users
license="GPL v2",
packages=["epidermis", "epidermis.pigments"], # python packages, not debian packages
py_modules=["pshell_service"],
data_files=[('share/epidermis/data/', data_files),
('/etc/', ['linux/epidermis.conf']),
('share/applications', ['build/i18n/epidermis.desktop']),
('/usr/share/pixmaps', ['data/epidermis.svg']),
('/usr/share/icons/gnome/scalable/mimetypes', ['linux/gnome-mime-application-x-pigment.svg']),
('/usr/share/icons/gnome/32x32/mimetypes', ['linux/gnome-mime-application-x-pigment.png']),
('/usr/share/gconf/schemas', ['linux/epidermis.schemas']),
('/etc/dbus-1/system.d', ['linux/org.tuxfamily.epidermis.Shell.conf']),
('/usr/share/polkit-1/actions', ['build/i18n/org.tuxfamily.epidermis.shell.policy']),
('share/mime/packages/', ['linux/epidermis.xml']),
('share/apport/package-hooks/', ['linux/source_epidermis.py']),
('/etc/apport/crashdb.conf.d/', ['linux/epidermis-crashdb.conf']),
('/usr/share/gnome/help/epidermis/C', glob.glob('help/C/*.xml')),
('/usr/share/gnome/help/epidermis/C/images', glob.glob('help/C/images/*')),
('/usr/share/omf/epidermis', glob.glob('help/lang/*.omf'))],
# data_files is a list of tuples
# each tuple contaning an installation path and a list of data files
scripts=["run.py"], # the script that should be run
classifiers=["Development Status :: 5 - Production/Stable", "Intended Audience :: End Users/Desktop", "License :: OSI Approved :: GNU General Public License (GPL)", "Operating System :: POSIX :: Linux"],
# a bunch of optional tags, a list of classifiers can be found at http://pypi.python.org/pypi?:action=list_classifiers
long_description="""Epidermis changes the appearance of your Ubuntu GNOME desktop in all its aspects in one click. Epidermis 'skins' change the appearance of your desktop wallpaper, Metacity windows border theme, your GTK controls theme, your icon theme, your mouse cursor theme, your GRUB bootsplash screen, your GDM login screen theme and your Usplash boot splash image.
Each of these customisations are downloaded in 'pigments' which are available from an Epidermis 'repository'.
Epidermis was written in python with pygtk.
Find more information at http://epidermis.tuxfamily.org and https://launchpad.net/epidermis/""",
cmdclass={"build":build_with_options,
"build_py": build_py_keep_permissions,
"build_dbus_service":build_dbus_service,
"build_mo":build_mo,
"clean":total_clean,
"sdist":sdist})
class build_with_options(build):
"""This class is the same as distutils.command.build.build but with
one additional option: --installation-dir="""
user_options = build.user_options
user_options.append(('installation-dir=',None,"The directory where pshell_service.py is to be found"))
sub_commands = build.sub_commands
sub_commands.append(('build_dbus_service',None))
sub_commands.append(('build_mo',None))
def initialize_options(self):
build.initialize_options(self)
self.installation_dir = None
def finalize_options(self):
build.finalize_options(self)
class build_py_keep_permissions(build_py):
def copy_file(self, infile, outfile,
preserve_mode=1, preserve_times=1, link=None, level=1):
"""Override preserve_mode and set it to 1"""
build_py.copy_file(self, infile=infile, outfile=outfile, preserve_mode=1,
preserve_times=preserve_times, link=link, level=level)
class build_dbus_service(Command):
description = "Build DBus .service file, modifying it so that it points to the correct script"
user_options = []
def initialize_options(self):
pass
def finalize_options(self):
pass
def run(self):
if not os.path.isdir("linux"):
self.warn("No linux/ directory")
return
self.mkpath("build/config")
installation_dir = self.get_finalized_command('build').installation_dir
if installation_dir is None:
install_lib = self.get_finalized_command('install_lib')
lib_install_dir = install_lib.install_dir
else:
lib_install_dir = installation_dir
self.make_file(["linux/org.tuxfamily.epidermis.Shell.service.in"],
"build/config/org.tuxfamily.epidermis.Shell.service",
self._build_dbus_service,[lib_install_dir])
self.distribution.data_files.append(("/usr/share/dbus-1/system-services",
["build/config/org.tuxfamily.epidermis.Shell.service"]))
@staticmethod
def _build_dbus_service(lib_install_dir):
"""Write build/config/org.tuxfamily.epidermis.Shell.service
correctly"""
if lib_install_dir[-1] == "/": lib_install_dir = lib_install_dir[:-1]
output = ""
ff = open("linux/org.tuxfamily.epidermis.Shell.service.in","r")
for line in ff.readlines():
if line.strip()[:5] == "Exec=":
line = line.replace("$REPLACE_ME$", lib_install_dir)
output += line
ff.close()
ff = open("build/config/org.tuxfamily.epidermis.Shell.service","w")
ff.write(output)
ff.close()
class build_mo(Command):
description = "Build .mo files and other translated files"
user_options = []
def initialize_options(self):
pass
def finalize_options(self):
pass
def run(self):
if not os.path.exists(os.path.join(os.path.dirname(__file__),
"convenience_scripts/translate.py")):
self.warn("could not find %s" % (os.path.join(os.path.dirname(__file__), "convenience_scripts/translate.py")))
raise
rp = os.path.join(os.path.dirname(os.path.realpath(__file__)))
# generate the .mo files from the existing .po files
environ = os.environ
environ["MO_BUILD_DIR"] = os.path.join(rp, "build/i18n")
self.mkpath("build/i18n")
def call_translate():
call(["python", "convenience_scripts/translate.py",
"--generate-mo", "--ignore-bzr"], cwd=rp, env=environ)
self.execute(call_translate, [])
mo_files = []
# mo_files is a list of tuples, each tuple containing one string specifying the location and a list of files
# to be installed in that location
# eg: [('/usr/share/locale/en_GB/LC_MESSAGES', ['po/en_GB/LC_MESSAGES/epidermis.mo'])
for lang in os.listdir("build/i18n/po"):
if os.path.isdir(os.path.join("build/i18n/po", lang, "LC_MESSAGES")):
if len(glob.glob(os.path.join("build/i18n/po",lang,"LC_MESSAGES","*.mo"))) <= 0:
print >> sys.stderr, "could not find %s" % os.path.join("build/i18n/po",lang,"LC_MESSAGES","*.mo")
raise
mo_files.append((os.path.join("/usr/share/locale", lang, "LC_MESSAGES"),
glob.glob(os.path.join("build/i18n/po", lang, "LC_MESSAGES") + "/*.mo")))
self.distribution.data_files.extend(mo_files)
# similar to mo_files but for docbooks
docbooks = []
omfs = []
for lang in os.listdir("build/i18n/help"):
if os.path.isdir(os.path.join("build/i18n/help", lang)):
docbooks.append((os.path.join("/usr/share/gnome/help/epidermis", lang),
glob.glob(os.path.join("build/i18n/help", lang) + "/*.xml")))
omfs.extend(glob.glob(os.path.join("build/i18n/help",lang) + "/*.omf"))
if os.path.isdir(os.path.join("build/i18n/help",lang,"images")):
docbooks.append((os.path.join("/usr/share/gnome/help/epidermis",lang,"images"),
glob.glob(os.path.join("build/i18n/help",lang,"images") + "/*")))
if len(omfs) > 0:
docbooks.append(('/usr/share/omf/epidermis',omfs))
self.distribution.data_files.extend(docbooks)
# this fallback returns None, used to verify if strings have been
# translated
class Fallback(gettext.NullTranslations):
def gettext(self, msg):
return None
# get Translations objects
translations = {}
for lang in os.listdir("build/i18n/po"):
if os.path.isfile(os.path.join("build/i18n/po/%s/LC_MESSAGES/epidermis.mo") % lang):
translations[lang] = gettext.translation(epidermis.const.APP_NAME,
localedir="build/i18n/po",languages=[lang])
# add i18n strings to .policy file (build it)
policy = minidom.parse("linux/org.tuxfamily.epidermis.shell.policy")
for action in policy.getElementsByTagName("action"):
for tagname in ("description", "message"):
text = self.get_first_text(
action.getElementsByTagName(tagname)[0])
for trans in translations:
translations[trans].add_fallback(Fallback())
node = policy.createElement(tagname)
node.setAttribute("xml:lang", trans)
newtext = translations[trans].gettext(text)
if newtext:
node.appendChild(policy.createTextNode(newtext.decode('utf-8')))
action.appendChild(node)
action.appendChild(policy.createTextNode("\n".decode('utf-8')))
output = policy.toxml()
open("build/i18n/org.tuxfamily.epidermis.shell.policy","w").write(
output.encode('utf-8'))
# add i18n strings to .desktop file (build it)
output = ""
for line in open("linux/epidermis.desktop","r").readlines():
output += line
if line.startswith("Name=") or line.startswith("Comment="):
sides = line.split("=")
for trans in translations:
newtext = translations[trans].gettext(sides[1][:-1])
if newtext:
output += "%s[%s]=%s\n" % (sides[0], trans, newtext)
open("build/i18n/epidermis.desktop","w").write(output)
@staticmethod
def get_first_text(thexml):
"""Get text of XML node (ignores comments)"""
import xml.dom
for el in thexml.childNodes:
if el.nodeType == xml.dom.Node.TEXT_NODE:
return el.data
return None
class total_clean(distutils.command.clean.clean):
description = distutils.command.clean.clean.description + \
", delete build_base directory (usually build/) and any built " + \
" .mo files"
def run(self):
# run usual clean command:
distutils.command.clean.clean.run(self)
# now delete build/ directory recursively
if os.path.exists(self.build_base):
distutils.dir_util.remove_tree(self.build_base,
dry_run=self.dry_run)
else:
distutils.log.warn("'%s' does not exist -- can't clean it",
self.build_base)
# delete any .mo directories
po_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)),"po")
for ff in os.listdir(os.path.join(os.path.dirname(__file__), "po")):
if os.path.isdir(os.path.join(po_dir, ff, "LC_MESSAGES")):
distutils.dir_util.remove_tree(os.path.join(po_dir, ff),
dry_run=self.dry_run)
class sdist(distutils.command.sdist.sdist):
def prune_file_list(self):
distutils.command.sdist.sdist.prune_file_list(self)
self.filelist.exclude_pattern("~$", is_regex=1) # exclude backup files ending with ~
self.filelist.exclude_pattern(".pyc$", is_regex=1) # exclude .pyc files
if __name__ == "__main__":
main()
|