~ubuntu-branches/ubuntu/natty/miro/natty

« back to all changes in this revision

Viewing changes to .pc/50_miro_debug_fix.patch/platform/gtk-x11/setup.py

  • Committer: Bazaar Package Importer
  • Author(s): Bryce Harrington
  • Date: 2011-01-22 02:46:33 UTC
  • mfrom: (1.4.10 upstream) (1.7.5 experimental)
  • Revision ID: james.westby@ubuntu.com-20110122024633-kjme8u93y2il5nmf
Tags: 3.5.1-1ubuntu1
* Merge from debian.  Remaining ubuntu changes:
  - Use python 2.7 instead of python 2.6
  - Relax dependency on python-dbus to >= 0.83.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/env python
2
 
 
3
 
# Miro - an RSS based video player application
4
 
# Copyright (C) 2005-2010 Participatory Culture Foundation
5
 
#
6
 
# This program is free software; you can redistribute it and/or modify
7
 
# it under the terms of the GNU General Public License as published by
8
 
# the Free Software Foundation; either version 2 of the License, or
9
 
# (at your option) any later version.
10
 
#
11
 
# This program is distributed in the hope that it will be useful,
12
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
# GNU General Public License for more details.
15
 
#
16
 
# You should have received a copy of the GNU General Public License
17
 
# along with this program; if not, write to the Free Software
18
 
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
19
 
#
20
 
# In addition, as a special exception, the copyright holders give
21
 
# permission to link the code of portions of this program with the OpenSSL
22
 
# library.
23
 
#
24
 
# You must obey the GNU General Public License in all respects for all of
25
 
# the code used other than OpenSSL. If you modify file(s) with this
26
 
# exception, you may extend this exception to your version of the file(s),
27
 
# but you are not obligated to do so. If you do not wish to do so, delete
28
 
# this exception statement from your version. If you delete this exception
29
 
# statement from all source files in the program, then also delete it here.
30
 
 
31
 
################################################################
32
 
## No user-serviceable parts inside                           ##
33
 
################################################################
34
 
 
35
 
import sys
36
 
 
37
 
# verify we have required bits for compiling Miro
38
 
 
39
 
try:
40
 
    from Pyrex.Compiler import Version
41
 
    if Version.version.split(".") < ["0", "9", "6", "4"]:
42
 
        print "Pyrex 0.9.6.4 or greater required.  You have version %s." % Version.version
43
 
        sys.exit(1)
44
 
except ImportError:
45
 
    print "Pyrex not found.  Please install Pyrex."
46
 
    sys.exit(1)
47
 
 
48
 
from distutils.cmd import Command
49
 
from distutils.core import setup
50
 
from distutils.extension import Extension
51
 
from distutils.errors import DistutilsOptionError
52
 
from distutils.util import change_root
53
 
from distutils import dir_util, log, sysconfig
54
 
from glob import glob
55
 
from string import Template
56
 
import distutils.command.install_data
57
 
import os
58
 
import pwd
59
 
import subprocess
60
 
import platform
61
 
import re
62
 
import time
63
 
import shutil
64
 
 
65
 
from Pyrex.Distutils import build_ext
66
 
 
67
 
#### useful paths to have around ####
68
 
def is_root_dir(d):
69
 
    """
70
 
    bdist_rpm and possibly other commands copies setup.py into a subdir of
71
 
    platform/gtk-x11.  This makes it hard to find the root directory.  We work
72
 
    our way up the path until our is_root_dir test passes.
73
 
    """
74
 
    return os.path.exists(os.path.join(d, "MIRO_ROOT"))
75
 
 
76
 
def get_root_dir():
77
 
    root_try = os.path.abspath(os.path.dirname(__file__))
78
 
    while True:
79
 
        if is_root_dir(root_try):
80
 
            root_dir = root_try
81
 
            break
82
 
        if root_try == '/':
83
 
            raise RuntimeError("Couldn't find Miro root directory")
84
 
        root_try = os.path.abspath(os.path.join(root_try, '..'))
85
 
    return root_dir
86
 
 
87
 
root_dir = get_root_dir()
88
 
portable_dir = os.path.join(root_dir, 'portable')
89
 
portable_frontend_dir = os.path.join(portable_dir, 'frontends')
90
 
portable_xpcom_dir = os.path.join(portable_frontend_dir, 'widgets', 'gtk',
91
 
                                  'xpcom')
92
 
dl_daemon_dir = os.path.join(portable_dir, 'dl_daemon')
93
 
test_dir = os.path.join(portable_dir, 'test')
94
 
resource_dir = os.path.join(root_dir, 'resources')
95
 
platform_dir = os.path.join(root_dir, 'platform', 'gtk-x11')
96
 
platform_package_dir = os.path.join(platform_dir, 'plat')
97
 
platform_widgets_dir = os.path.join(platform_package_dir, 'frontends',
98
 
                                    'widgets')
99
 
 
100
 
# insert the root_dir to the beginning of sys.path so that we can
101
 
# pick up portable and other packages
102
 
sys.path.insert(0, root_dir)
103
 
 
104
 
# later when we install the portable modules, they will be in the miro package,
105
 
# but at this point, they are in a package named "portable", so let's hack it
106
 
import portable
107
 
sys.modules['miro'] = portable
108
 
import plat
109
 
sys.modules['miro'].plat = plat
110
 
 
111
 
# little hack to get the version from the current app.config.template
112
 
from miro import util
113
 
app_config = os.path.join(resource_dir, 'app.config.template')
114
 
appVersion = util.read_simple_config_file(app_config)['appVersion']
115
 
 
116
 
# RPM hack
117
 
if 'bdist_rpm' in sys.argv:
118
 
    appVersion = appVersion.replace('-', '_')
119
 
 
120
 
def getlogin():
121
 
    """Does a best-effort attempt to return the login of the user running the
122
 
    script.
123
 
    """
124
 
    try:
125
 
        return os.environ['LOGNAME']
126
 
    except KeyError:
127
 
        pass
128
 
    try:
129
 
        return os.environ['USER']
130
 
    except KeyError:
131
 
        pass
132
 
    pwd.getpwuid(os.getuid())[0]
133
 
 
134
 
def read_file(path):
135
 
    f = open(path)
136
 
    try:
137
 
        return f.read()
138
 
    finally:
139
 
        f.close()
140
 
 
141
 
def write_file(path, contents):
142
 
    f = open(path, 'w')
143
 
    try:
144
 
        f.write(contents)
145
 
    finally:
146
 
        f.close()
147
 
 
148
 
def expand_file_contents(path, **values):
149
 
    """Do a string expansion on the contents of a file using the same rules as
150
 
    string.Template from the standard library.
151
 
    """
152
 
    template = Template(read_file(path))
153
 
    expanded = template.substitute(**values)
154
 
    write_file(path, expanded)
155
 
 
156
 
def get_command_output(cmd, warnOnStderr=True, warnOnReturnCode=True):
157
 
    """Wait for a command and return its output.  Check for common errors and
158
 
    raise an exception if one of these occurs.
159
 
    """
160
 
    p = subprocess.Popen(cmd, shell=True, close_fds=True,
161
 
                         stdout=subprocess.PIPE, stderr=subprocess.PIPE)
162
 
    stdout, stderr = p.communicate()
163
 
    if warnOnStderr and stderr != '':
164
 
        raise RuntimeError("%s outputted the following error:\n%s" % (cmd, stderr))
165
 
    if warnOnReturnCode and p.returncode != 0:
166
 
        raise RuntimeError("%s had non-zero return code %d" % (cmd, p.returncode))
167
 
    return stdout
168
 
 
169
 
def parse_pkg_config(command, components, options_dict = None):
170
 
    """Helper function to parse compiler/linker arguments from
171
 
    pkg-config and update include_dirs, library_dirs, etc.
172
 
 
173
 
    We return a dict with the following keys, which match up with keyword
174
 
    arguments to the setup function: include_dirs, library_dirs, libraries,
175
 
    extra_compile_args.
176
 
 
177
 
    Command is the command to run (pkg-config, etc).
178
 
    Components is a string that lists the components to get options for.
179
 
 
180
 
    If options_dict is passed in, we add options to it, instead of starting
181
 
    from scratch.
182
 
    """
183
 
    if options_dict is None:
184
 
        options_dict = {
185
 
            'include_dirs' : [],
186
 
            'library_dirs' : [],
187
 
            'runtime_dirs' : [],
188
 
            'libraries' : [],
189
 
            'extra_compile_args' : []
190
 
        }
191
 
    commandLine = "%s --cflags --libs %s" % (command, components)
192
 
    output = get_command_output(commandLine).strip()
193
 
    for comp in output.split():
194
 
        prefix, rest = comp[:2], comp[2:]
195
 
        if prefix == '-I':
196
 
            options_dict['include_dirs'].append(rest)
197
 
        elif prefix == '-L':
198
 
            options_dict['library_dirs'].append(rest)
199
 
        elif prefix == '-l':
200
 
            options_dict['libraries'].append(rest)
201
 
        else:
202
 
            options_dict['extra_compile_args'].append(comp)
203
 
 
204
 
    commandLine = "%s --variable=libdir %s" % (command, components)
205
 
    output = get_command_output(commandLine).strip()
206
 
    options_dict['runtime_dirs'].append(output)
207
 
 
208
 
    return options_dict
209
 
 
210
 
def package_exists(package_name):
211
 
    """
212
 
    Return True if the package is present in the system.  False otherwise.
213
 
    The check is made with pkg-config.
214
 
    """
215
 
    # pkg-config returns 0 if the package is present
216
 
    return subprocess.call(['pkg-config', '--exists', package_name]) == 0
217
 
 
218
 
def generate_miro():
219
 
    f = open(os.path.join(platform_dir, "miro"), "w")
220
 
    f.write(
221
 
"""#!/bin/sh
222
 
# This file is generated by setup.py.
223
 
DEBUG=0
224
 
 
225
 
for arg in $@
226
 
do
227
 
    case $arg in
228
 
    "--debug")    DEBUG=1;;
229
 
    esac
230
 
done
231
 
 
232
 
if [ $DEBUG = 1 ]
233
 
then
234
 
    echo "DEBUGGING MODE."
235
 
    PYTHON=`which python`
236
 
    GDB=`which gdb`
237
 
 
238
 
    if [ -z $GDB ]
239
 
    then
240
 
        echo "gdb cannot be found on your path.  aborting....";
241
 
        exit;
242
 
    fi
243
 
 
244
 
    $GDB -ex 'set breakpoint pending on' -ex 'run' --args $PYTHON ./miro.real --sync "$@"
245
 
else
246
 
    miro.real "$@"
247
 
fi
248
 
""")
249
 
    f.close()
250
 
 
251
 
 
252
 
#### Xlib Extension ####
253
 
xlib_ext = \
254
 
    Extension("miro.plat.xlibhelper",
255
 
        [ os.path.join(platform_package_dir,'xlibhelper.pyx') ],
256
 
        library_dirs = ['/usr/X11R6/lib'],
257
 
        libraries = ['X11'],
258
 
    )
259
 
 
260
 
pygtkhacks_ext = \
261
 
    Extension("miro.frontends.widgets.gtk.pygtkhacks",
262
 
        [ os.path.join(portable_frontend_dir, 'widgets', 'gtk',
263
 
            'pygtkhacks.pyx') ],
264
 
        **parse_pkg_config('pkg-config',
265
 
            'pygobject-2.0 gtk+-2.0 glib-2.0 gthread-2.0')
266
 
    )
267
 
 
268
 
#### Build the data_files list ####
269
 
def listfiles(path):
270
 
    return [f for f in glob(os.path.join(path, '*')) if os.path.isfile(f)]
271
 
 
272
 
data_files = []
273
 
# append the root resource directory.
274
 
# filter out app.config.template (which is handled specially)
275
 
files = [f for f in listfiles(resource_dir) \
276
 
        if os.path.basename(f) != 'app.config.template']
277
 
data_files.append(('/usr/share/miro/resources/', files))
278
 
# handle the sub directories.
279
 
for dir in ('searchengines', 'images', 'testdata',
280
 
        os.path.join('testdata', 'stripperdata'),
281
 
        os.path.join('testdata', 'locale', 'fr', 'LC_MESSAGES')):
282
 
    source_dir = os.path.join(resource_dir, dir)
283
 
    dest_dir = os.path.join('/usr/share/miro/resources/', dir)
284
 
    data_files.append((dest_dir, listfiles(source_dir)))
285
 
 
286
 
for mem in ["24", "48", "72", "128"]:
287
 
    d = os.path.join("icons", "hicolor", "%sx%s" % (mem, mem), "apps")
288
 
    source = os.path.join(platform_dir, d, "miro.png")
289
 
    dest = os.path.join("/usr/share/", d)
290
 
    data_files.append((dest, [source]))
291
 
 
292
 
# add ADOPTERS file, the desktop file, mime data, and man page
293
 
data_files += [
294
 
    ('/usr/share/miro/resources',
295
 
     [os.path.join(root_dir, 'ADOPTERS')]),
296
 
    ('/usr/share/pixmaps',
297
 
     glob(os.path.join(platform_dir, 'miro.xpm'))),
298
 
    ('/usr/share/applications',
299
 
     [os.path.join(platform_dir, 'miro.desktop')]),
300
 
    ('/usr/share/mime/packages',
301
 
     [os.path.join(platform_dir, 'miro.xml')]),
302
 
    ('/usr/share/man/man1',
303
 
     [os.path.join(platform_dir, 'miro.1.gz')]),
304
 
    ('/usr/share/man/man1',
305
 
     [os.path.join(platform_dir, 'miro.real.1.gz')]),
306
 
]
307
 
 
308
 
 
309
 
# if we're not doing "python setup.py clean", then we can do a bunch of things
310
 
# that have file-related side-effects
311
 
if not "clean" in sys.argv:
312
 
    generate_miro()
313
 
    # gzip the man page
314
 
    os.system ("gzip -9 < %s > %s" % (os.path.join(platform_dir, 'miro.1'), os.path.join(platform_dir, 'miro.1.gz')))
315
 
    # copy miro.1.gz to miro.real.1.gz so that lintian complains less
316
 
    os.system ("cp %s %s" % (os.path.join(platform_dir, 'miro.1.gz'), os.path.join(platform_dir, 'miro.real.1.gz')))
317
 
 
318
 
 
319
 
#### Our specialized install_data command ####
320
 
class install_data(distutils.command.install_data.install_data):
321
 
    """install_data extends to default implementation so that it automatically
322
 
    installs app.config from app.config.template.
323
 
    """
324
 
 
325
 
    def install_app_config(self):
326
 
        source = os.path.join(resource_dir, 'app.config.template')
327
 
        dest = '/usr/share/miro/resources/app.config'
328
 
 
329
 
        config_file = util.read_simple_config_file(source)
330
 
        print "Trying to figure out the git revision...."
331
 
        if config_file["appVersion"].endswith("git"):
332
 
            revision = util.query_revision()
333
 
            if revision is None:
334
 
                revision = "unknown"
335
 
                revisionurl = "unknown"
336
 
                revisionnum = "unknown"
337
 
            else:
338
 
                revisionurl = revision[0]
339
 
                revisionnum = revision[1]
340
 
                revision = "%s - %s" % (revisionurl, revisionnum)
341
 
        else:
342
 
            revisionurl = ""
343
 
            revisionnum = ""
344
 
            revision = ""
345
 
        print "Using %s" % revisionnum
346
 
 
347
 
        if self.root:
348
 
            dest = change_root(self.root, dest)
349
 
        self.mkpath(os.path.dirname(dest))
350
 
        # We don't use the dist utils copy_file() because it only copies
351
 
        # the file if the timestamp is newer
352
 
        shutil.copyfile(source, dest)
353
 
        expand_file_contents(dest, APP_REVISION=revision,
354
 
                             APP_REVISION_NUM=revisionnum,
355
 
                             APP_REVISION_URL=revisionurl,
356
 
                             APP_PLATFORM='gtk-x11',
357
 
                             BUILD_MACHINE="%s@%s" % (getlogin(),
358
 
                                                      os.uname()[1]),
359
 
                             BUILD_TIME=str(time.time()),
360
 
                             MOZILLA_LIB_PATH="")
361
 
        self.outfiles.append(dest)
362
 
 
363
 
        locale_dir = os.path.join (resource_dir, "locale")
364
 
 
365
 
        for source in glob (os.path.join (locale_dir, "*.mo")):
366
 
            lang = os.path.basename(source)[:-3]
367
 
            if 'LINGUAS' in os.environ and lang not in os.environ['LINGUAS']:
368
 
                continue
369
 
            dest = '/usr/share/locale/%s/LC_MESSAGES/miro.mo' % lang
370
 
            if self.root:
371
 
                dest = change_root(self.root, dest)
372
 
            self.mkpath(os.path.dirname(dest))
373
 
            self.copy_file(source, dest)
374
 
            self.outfiles.append(dest)
375
 
 
376
 
    def run(self):
377
 
        distutils.command.install_data.install_data.run(self)
378
 
        self.install_app_config()
379
 
 
380
 
 
381
 
class test_system(Command):
382
 
    description = "Allows you to test configurations without compiling or running."
383
 
    user_options = []
384
 
 
385
 
    def initialize_options(self):
386
 
        pass
387
 
 
388
 
    def finalize_options(self):
389
 
        pass
390
 
 
391
 
    def run(self):
392
 
        # FIXME - try importing and all that other stuff to make sure
393
 
        # we have most of the pieces here?
394
 
        pass
395
 
 
396
 
#### install_theme installs a specified theme .zip
397
 
class install_theme(Command):
398
 
    description = 'Install a provided theme to /usr/share/miro/themes'
399
 
    user_options = [("theme=", None, 'ZIP file containing the theme')]
400
 
 
401
 
    def initialize_options(self):
402
 
        self.theme = None
403
 
 
404
 
    def finalize_options(self):
405
 
        if self.theme is None:
406
 
            raise DistutilsOptionError, "must supply a theme ZIP file"
407
 
        if not os.path.exists(self.theme):
408
 
            raise DistutilsOptionError, "theme file does not exist"
409
 
        import zipfile
410
 
        if not zipfile.is_zipfile(self.theme):
411
 
            raise DistutilsOptionError, "theme file is not a ZIP file"
412
 
        zf = zipfile.ZipFile(self.theme)
413
 
        appConfig = zf.read('app.config')
414
 
        themeName = None
415
 
        for line in appConfig.split('\n'):
416
 
            if '=' in line:
417
 
                name, value = line.split('=', 1)
418
 
                name = name.strip()
419
 
                value = value.lstrip()
420
 
                if name == 'themeName':
421
 
                    themeName = value
422
 
        if themeName is None:
423
 
            raise DistutilsOptionError, "invalid theme file"
424
 
        self.zipfile = zf
425
 
        self.theme_name = themeName
426
 
        self.theme_dir = '/usr/share/miro/themes/%s' % themeName
427
 
 
428
 
    def run(self):
429
 
        if os.path.exists(self.theme_dir):
430
 
            shutil.rmtree(self.theme_dir)
431
 
        os.makedirs(self.theme_dir)
432
 
        for name in self.zipfile.namelist():
433
 
            if name.startswith('xul/'):
434
 
                # ignore XUL stuff, we don't need it on Linux
435
 
                continue
436
 
            print 'installing', os.path.join(self.theme_dir, name)
437
 
            if name[-1] == '/':
438
 
                os.makedirs(os.path.join(self.theme_dir, name))
439
 
            else:
440
 
                f = file(os.path.join(self.theme_dir, name), 'wb')
441
 
                f.write(self.zipfile.read(name))
442
 
                f.close()
443
 
        print """%s theme installed.
444
 
 
445
 
To use this theme, run:
446
 
 
447
 
    miro --theme="%s"
448
 
""" % (self.theme_name, self.theme_name)
449
 
 
450
 
class clean(Command):
451
 
    description = 'Cleans the build and dist directories'
452
 
    user_options = []
453
 
 
454
 
    def initialize_options(self):
455
 
        pass
456
 
 
457
 
    def finalize_options(self):
458
 
        pass
459
 
 
460
 
    def run(self):
461
 
        if os.path.exists('./build/'):
462
 
            print "removing build directory"
463
 
            shutil.rmtree('./build/')
464
 
 
465
 
        if os.path.exists('./dist/'):
466
 
            print "removing dist directory"
467
 
            shutil.rmtree('./dist/')
468
 
 
469
 
ext_modules = []
470
 
ext_modules.append(xlib_ext)
471
 
ext_modules.append(pygtkhacks_ext)
472
 
 
473
 
#### Run setup ####
474
 
setup(name='miro',
475
 
    version=appVersion,
476
 
    author='Participatory Culture Foundation',
477
 
    author_email='feedback@pculture.org',
478
 
    url='http://www.getmiro.com/',
479
 
    download_url='http://www.getmiro.com/downloads/',
480
 
    scripts = [
481
 
        os.path.join(platform_dir, 'miro'),
482
 
        os.path.join(platform_dir, 'miro.real')
483
 
    ],
484
 
    data_files=data_files,
485
 
    ext_modules=ext_modules,
486
 
    packages = [
487
 
        'miro',
488
 
        'miro.dl_daemon',
489
 
        'miro.test',
490
 
        'miro.dl_daemon.private',
491
 
        'miro.frontends',
492
 
        'miro.frontends.cli',
493
 
        'miro.frontends.shell',
494
 
        'miro.frontends.widgets',
495
 
        'miro.frontends.widgets.gtk',
496
 
        'miro.plat',
497
 
        'miro.plat.frontends',
498
 
        'miro.plat.frontends.widgets',
499
 
        'miro.plat.renderers',
500
 
    ],
501
 
    package_dir = {
502
 
        'miro': portable_dir,
503
 
        'miro.test': test_dir,
504
 
        'miro.plat': platform_package_dir,
505
 
    },
506
 
    cmdclass = {
507
 
        'test_system': test_system,
508
 
        'build_ext': build_ext,
509
 
        'install_data': install_data,
510
 
        'install_theme': install_theme,
511
 
        'clean': clean,
512
 
    }
513
 
)