~osomon/phatch/extract-all-metadata

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
# Copyright (C) 2007-2008 www.stani.be
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see http://www.gnu.org/licenses/

__all__ = ['get_context', 'join']


import os
import sys

import desktop


def endswith(x, suffices):
    for suffix in suffices:
        if x.endswith(suffix):
            return True
    return False


_CONTEXT = {}

# PLATFORM
if sys.platform.startswith('win'):
    _CONTEXT['platform'] = 'windows'
elif sys.platform.startswith('darwin'):
    _CONTEXT['platform'] = 'apple'
else:
    #assume linux
    _CONTEXT['platform'] = 'linux'

UNIX = _CONTEXT['platform'] in ('linux', 'apple')

# SETUP
if hasattr(sys, 'frozen'):
    _CONTEXT['distribute'] = 'frozen'
elif not endswith(sys.argv[0], ('.py', 'nosetests')):
    _CONTEXT['distribute'] = 'package'
else:
    _CONTEXT['distribute'] = 'source'

_CONTEXT['context'] = (_CONTEXT['platform'], _CONTEXT['distribute'])


class ContextError(Exception):
    pass


def join(*args):
    path = os.path.abspath(os.path.join(*args))
    if not os.path.exists(path):
        raise ContextError(path)
    return path


def join_create(*args):
    path = os.path.abspath(os.path.join(*args))
    if not os.path.exists(path):
        os.mkdir(path)
    return path


def _find_parent(path, base):
    if base == os.path.basename(path):
        return path
    if not path:
        raise ContextError('Can not find "%s" parent path.' % base)
    return _find_parent(os.path.abspath(os.path.join(path, '..')), base)


def _find_source_path(base_source):
    # __file__ may only be used to locate the source files
    return _find_parent(
        os.path.abspath(
            os.path.dirname(unicode(__file__, sys.getfilesystemencoding())),
        ),
        base_source,
    )


def get_context(app_name, base_source='source', sys_prefix=None):
    """Finds the right paths depending on the context, which consists of the
    platform and how it is distributed.

    context = (platform, distribute)
    platform = 'linux', 'apple' or 'windows'
    distribute = 'frozen', 'package' or 'source'
    """
    if sys_prefix is None:
        sys_prefix = sys.prefix
    context = _CONTEXT.copy()
    # initialize APP_NAME
    context['app_name'] = app_name
    # initialize APP_ROOT and DATA_PATH
    if context['distribute'] == 'source':
        # source: eg. trunk/source
        context['app_source_path'] = _find_source_path(base_source)
        # data: eg. trunk/data
        context['app_data_path'] = join(
            context['app_source_path'], '..', 'data')
        # doc: eg. trunk/doc
        context['app_doc_path'] = join(
            context['app_source_path'], '..', 'doc')
        # locale: eg. trunk/locale
        context['app_locale_path'] = join(
            context['app_source_path'], '..', 'locale')
    elif context['context'] == ('linux', 'package'):
        # source: eg. /usr/share/phatch/source
        context['app_source_path'] = _find_source_path(base_source)
        # data: eg. /usr/share/phatch/data
        context['app_data_path'] = join(sys_prefix, 'share', app_name, 'data')
        # doc: eg. /usr/share/doc/phatch/
        context['app_doc_path'] = join(sys_prefix, 'share', 'doc', app_name)
        # locale: eg. /usr/share/locale/
        context['app_locale_path'] = join(sys_prefix, 'share', 'locale')
    #elif context['context'] == ('apple', 'frozen'):
    #    # TODO: implement this!
    #    APP_ROOT = os.path.dirname(os.path.dirname(unicode(sys.executable,
    #        sys.getfilesystemencoding())))
    #    # eg. Phatch.app/Contents/Resources/
    #    context['app_data_path'] = join(APP_ROOT, 'Contents', 'Resources')
    #elif context['context'] == ('windows', 'frozen'):
    #    # The same as the exe dir
    #    APP_ROOT = os.path.dirname(unicode(sys.executable,
    #        sys.getfilesystemencoding()))
    #    context['app_data_path'] = os.path.join(APP_ROOT, 'data')
    else:
        raise ContextError(
            'Sorry your context%(context)s is not yet supported.' % context)

    # other data pats
    context['app_images_path'] = join(context['app_data_path'], 'images')

    # user paths
    context['desktop_path'] = desktop.DESKTOP_PATH
    context['user_path'] = desktop.USER_PATH
    if context['platform'] == 'linux':
        context['user_cache_path'] = join_create(desktop.USER_CACHE_PATH,
            app_name)
        context['user_config_path'] = join_create(desktop.USER_CONFIG_PATH,
            app_name)
        context['user_data_path'] = join_create(desktop.USER_DATA_PATH,
            app_name)
    else:
        dot = '.' + app_name
        context['user_cache_path'] = join_create(desktop.USER_PATH, dot,
            'cache')
        context['user_config_path'] = join_create(desktop.USER_PATH, dot,
            'config')
        context['user_data_path'] = join_create(desktop.USER_PATH, dot,
            'data')
    return context


if __name__ == '__main__':
    import pprint
    pprint.pprint(get_context('app', base_source='phatch'))