Don't wrap episode fields in tuples, only to immediately unwrap them.
[gpodder.git] / setup.py
blobf42a07c9610e18fdef03bddcf100385d94c17285
1 #!/usr/bin/env python3
4 # gPodder - A media aggregator and podcast client
5 # Copyright (c) 2005-2018 The gPodder Team
7 # gPodder is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
12 # gPodder is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21 import glob
22 import os
23 import re
24 import sys
25 from distutils.core import setup
27 installing = ('install' in sys.argv and '--help' not in sys.argv)
29 # distutils depends on setup.py beeing executed from the same dir.
30 # Most of our custom commands work either way, but this makes
31 # it work in all cases.
32 os.chdir(os.path.dirname(os.path.realpath(__file__)))
35 # Read the metadata from gPodder's __init__ module (doesn't need importing)
36 main_module = open('src/gpodder/__init__.py', 'r', encoding='utf-8').read()
37 metadata = dict(re.findall("__([a-z_]+)__\\s*=\\s*'([^']+)'", main_module))
39 author, email = re.match(r'^(.*) <(.*)>$', metadata['author']).groups()
42 class MissingFile(BaseException):
43 pass
46 def info(message, item=None):
47 print('=>', message, item if item is not None else '')
50 def find_data_files(uis, scripts):
51 # Support for installing only a subset of translations
52 linguas = os.environ.get('LINGUAS', None)
53 if linguas is not None:
54 linguas = linguas.split()
55 info('Selected languages (from $LINGUAS):', linguas)
57 for dirpath, dirnames, filenames in os.walk('share'):
58 if not filenames:
59 continue
61 # Skip data folders if we don't want the corresponding UI
62 share_gpodder_ui = os.path.join('share', 'gpodder', 'ui')
63 if uis is not None and dirpath.startswith(share_gpodder_ui):
64 dirparts = dirpath.split(os.sep)
65 if not any(part in uis for part in dirparts):
66 info('Skipping folder:', dirpath)
67 continue
69 # Skip translations if $LINGUAS is set
70 share_locale = os.path.join('share', 'locale')
71 if linguas is not None and dirpath.startswith(share_locale):
72 _, _, language, _ = dirpath.split(os.sep, 3)
73 if language not in linguas:
74 info('Skipping translation:', language)
75 continue
77 # Skip desktop stuff if we don't have any UIs requiring it
78 skip_folder = False
79 uis_requiring_freedesktop = ('gtk',)
80 freedesktop_folders = ('applications', 'dbus-1', 'icons', 'metainfo')
81 for folder in freedesktop_folders:
82 share_folder = os.path.join('share', folder)
83 if dirpath.startswith(share_folder) and uis is not None:
84 if not any(ui in uis_requiring_freedesktop for ui in uis):
85 info('Skipping freedesktop.org folder:', dirpath)
86 skip_folder = True
87 break
89 if skip_folder:
90 continue
92 # Skip manpages if their scripts are not going to be installed
93 share_man = os.path.join('share', 'man')
94 if dirpath.startswith(share_man):
95 def have_script(filename):
96 if not filename.endswith('.1'):
97 return True
99 basename, _ = os.path.splitext(filename)
100 result = any(os.path.basename(s) == basename for s in scripts)
101 if not result:
102 info('Skipping manpage without script:', filename)
103 return result
104 filenames = list(filter(have_script, filenames))
106 def convert_filename(filename):
107 filename = os.path.join(dirpath, filename)
109 # Skip header files generated by "make messages"
110 if filename.endswith('.h'):
111 return None
113 # Skip .in files, but check if their target exist
114 if filename.endswith('.in'):
115 filename = filename[:-3]
116 if installing and not os.path.exists(filename):
117 raise MissingFile(filename)
118 return None
120 return filename
122 filenames = [_f for _f in map(convert_filename, filenames) if _f]
123 if filenames:
124 # Some distros/ports install manpages into $PREFIX/man instead
125 # of $PREFIX/share/man (e.g. FreeBSD). To allow this, we strip
126 # the "share/" part if the variable GPODDER_MANPATH_NO_SHARE is
127 # set to any value in the environment.
128 if dirpath.startswith(share_man):
129 if 'GPODDER_MANPATH_NO_SHARE' in os.environ:
130 dirpath = dirpath.replace(share_man, 'man')
132 yield (dirpath, filenames)
135 def find_packages(uis):
136 src_gpodder = os.path.join('src', 'gpodder')
137 for dirpath, dirnames, filenames in os.walk(src_gpodder):
138 if '__init__.py' not in filenames:
139 continue
141 skip = False
142 dirparts = dirpath.split(os.sep)
143 dirparts.pop(0)
144 package = '.'.join(dirparts)
146 # Extract all parts of the package name ending in "ui"
147 ui_parts = [p for p in dirparts if p.endswith('ui')]
148 if uis is not None and ui_parts:
149 # Strip the trailing "ui", e.g. "gtkui" -> "gtk"
150 folder_uis = [p[:-2] for p in ui_parts]
151 for folder_ui in folder_uis:
152 if folder_ui not in uis:
153 info('Skipping package:', package)
154 skip = True
155 break
157 if not skip:
158 yield package
161 def find_scripts(uis):
162 # Functions for scripts to check if they should be installed
163 file_checks = {
164 'gpo': lambda uis: 'cli' in uis,
165 'gpodder': lambda uis: any(ui in uis for ui in ('gtk',)),
168 for dirpath, dirnames, filenames in os.walk('bin'):
169 for filename in filenames:
170 # If we have a set of uis, check if we can skip this file
171 if uis is not None and filename in file_checks:
172 if not file_checks[filename](uis):
173 info('Skipping script:', filename)
174 continue
176 yield os.path.join(dirpath, filename)
179 # Recognized UIs: cli, gtk (default: install all UIs)
180 uis = os.environ.get('GPODDER_INSTALL_UIS', None)
181 if uis is not None:
182 uis = uis.split()
184 info('Selected UIs (from $GPODDER_INSTALL_UIS):', uis)
187 try:
188 packages = list(sorted(find_packages(uis)))
189 scripts = list(sorted(find_scripts(uis)))
190 data_files = list(sorted(find_data_files(uis, scripts)))
191 except MissingFile as mf:
192 print("""
193 Missing file: %s
195 If you want to install, use "make install" instead of using
196 setup.py directly. See the README file for more information.
197 """ % mf, file=sys.stderr)
198 sys.exit(1)
201 setup(
202 name='gpodder',
203 version=metadata['version'],
204 description=metadata['tagline'],
205 license=metadata['license'],
206 url=metadata['url'],
208 author=author,
209 author_email=email,
211 package_dir={'': 'src'},
212 packages=packages,
213 scripts=scripts,
214 data_files=data_files,