File: setup.py

package info (click to toggle)
unknown-horizons 2019.1-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 347,832 kB
  • sloc: python: 46,804; xml: 3,137; sql: 1,189; sh: 736; makefile: 40; perl: 35
file content (254 lines) | stat: -rwxr-xr-x 8,594 bytes parent folder | download | duplicates (4)
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
#!/usr/bin/env python3
# ###################################################
# Copyright (C) 2008-2017 The Unknown Horizons Team
# team@unknown-horizons.org
# This file is part of Unknown Horizons.
#
# Unknown Horizons 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 2 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, write to the
# Free Software Foundation, Inc.,
# 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
# ###################################################


import distutils.cmd
import glob
import json
import os
import platform
import sys
from distutils.command.build import build
from distutils.core import setup
from distutils.spawn import find_executable
from shutil import copytree, rmtree

import horizons
from horizons.constants import VERSION
from horizons.ext import polib

# Ensure we are in the correct directory
os.chdir(os.path.realpath(os.path.dirname(__file__)))

if platform.dist()[0].lower() in ('debian', 'ubuntu'):
	executable_path = 'games'
else:
	executable_path = 'bin'


# this trick is for setting RELEASE_VERSION if the code is cloned from git repository
if os.path.exists('.git'):
	with open('content/packages/gitversion.txt', 'w') as f:
		f.write(VERSION.RELEASE_VERSION)

data = [
  (executable_path, ('unknown-horizons', )),
  ('share/pixmaps', ('content/packages/unknown-horizons.xpm', )),
  ('share/unknown-horizons', ('content/settings-template.xml', )),
  ('share/man/man6', ('content/packages/unknown-horizons.6', )),
]

for root, dirs, files in [x for x in os.walk('content') if len(x[2])]:
	data.append(('share/unknown-horizons/{0!s}'.format(root),
		['{0!s}/{1!s}'.format(root, f) for f in files]))

packages = []
for root, dirs, files in os.walk('horizons'):
	packages.append(root)

# Add enet files for build platform
systemtype = platform.system().lower()
arch = platform.machine()
enetdir = "horizons/network/{0!s}-x{1!s}".format(systemtype, arch[-2:])
package_data = {enetdir: ['*.so']}


class _build_i18n(distutils.cmd.Command):
	"""
	Derived from https://launchpad.net/python-distutils-extra
	to avoid an additional dependency
	"""
	description = "integrate the gettext framework"
	user_options = [
		('desktop-files=', None, '.desktop.in files that should be merged'),
		('text-domains=', None, 'list of pairs of gettext domains & directory that holds the i18n files'),
		('bug-contact=', None, 'contact address for msgid bugs')
	]

	def initialize_options(self):
		self.desktop_files = []
		self.text_domains = []
		self.bug_contact = None

	def finalize_options(self):
		if not self.text_domains:
			self.text_domains = [(self.distribution.metadata.name, "po")]

	def generate_mo_files(self, domain, po_dir):
		if not os.path.isdir(po_dir):
			return []
		po_files = glob.glob("{}/*.po".format(po_dir))
		if po_files and not find_executable('msgfmt'):
			raise RuntimeError(
				"Can't generate language files, needs msgfmt. "
				"Only native language (English) will be available. "
				"Try installing the package 'gettext' or 'msgfmt'.")

		# If there is a po/LINGUAS file, or the LINGUAS environment variable
		# is set, only compile the languages listed there
		selected_languages = None
		linguas_file = os.path.join(po_dir, "LINGUAS")
		if os.path.isfile(linguas_file):
			with open(linguas_file) as f:
				selected_languages = f.read().split()
		if "LINGUAS" in os.environ:
			selected_languages = os.environ["LINGUAS"].split()

		translation_stats = {}
		mo_files = []
		for po_file in po_files:
			lang = os.path.basename(po_file[:-3])
			if selected_languages and lang not in selected_languages:
				continue
			mo_dir = os.path.join("content", "lang", lang, "LC_MESSAGES")
			mo_file = os.path.join(mo_dir, "{}.mo".format(domain))
			if not os.path.exists(mo_dir):
				os.makedirs(mo_dir)
			cmd = ["msgfmt", po_file, "-o", mo_file]
			po_mtime = os.path.getmtime(po_file)
			mo_mtime = os.path.exists(mo_file) and \
				os.path.getmtime(mo_file) or 0
			if po_mtime > mo_mtime:
				self.spawn(cmd)

			percent_translated = polib.pofile(po_file).percent_translated()
			translation_stats[lang] = percent_translated

			targetpath = os.path.join("share/locale", lang, "LC_MESSAGES")
			mo_files.append((targetpath, [mo_file]))

		# Write translation stats to file and have it included in package
		stats_filename = os.path.join('content', 'lang', 'stats.json')
		with open(stats_filename, 'w') as f:
			json.dump(translation_stats, f)

		self.distribution.data_files.append((os.path.join('share', 'locale'), [stats_filename]))

		return mo_files

	def generate_atlases(self, size):
		import subprocess
		horizons_path = os.path.dirname(horizons.__file__)
		args = [sys.executable, os.path.join(horizons_path, 'engine', 'generate_atlases.py'), str(size)]
		process = subprocess.Popen(args)

	def run(self):
		"""
		Update the language files, generate mo files and add them
		to the to be installed files

		NOTE: This code is partly broken and hack-fixed to the state where it appears to work.
		It should be removed, since nobody understands the code well enough to be able to maintain it.

		"""
		text_domains = {}
		try:
			text_domains = eval(self.text_domains)
		except:
			pass

		if self.desktop_files and not find_executable('intltool-merge'):
			self.warn(
				"Can't generate desktop files, needs intltool-merge. "
				"Try installing the package 'intltool'.")
			return

		if self.bug_contact is not None:
			os.environ["XGETTEXT_ARGS"] = "--msgid-bugs-address={0}".format(self.bug_contact)
		data_files = self.distribution.data_files
		if data_files is None:
			# in case not data_files are defined in setup.py
			self.distribution.data_files = data_files = []

		mo_files_generated = False
		for (domain, po_dir) in text_domains:
			try:
				mo_files = self.generate_mo_files(domain, po_dir)
				if mo_files:
					mo_files_generated = True
				data_files.extend(mo_files)
			except RuntimeError as e:
				print(str(e))
				return

		# merge .in with translation
		for (option, switch) in ((self.desktop_files, "-d"),):
			try:
				file_set = eval(option)
			except:
				continue
			for (target, po_dir, files) in file_set:
				build_target = os.path.join("build", target)
				if not os.path.exists(build_target):
					os.makedirs(build_target)
				files_merged = []
				for file in files:
					if file.endswith(".in"):
						file_merged = os.path.basename(file[:-3])
					else:
						file_merged = os.path.basename(file)
					file_merged = os.path.join(build_target, file_merged)
					cmd = ["intltool-merge", switch, po_dir, file, file_merged]
					mtime_merged = os.path.exists(file_merged) and \
						os.path.getmtime(file_merged) or 0
					mtime_file = os.path.getmtime(file)
					if mo_files_generated or mtime_merged < mtime_file:
						# Only build if output is older than input (.po,.in)
						self.spawn(cmd)
					files_merged.append(file_merged)
				data_files.append((target, files_merged))

		# Since specifying a .mofile dir is not supported, we manually move build/mo/
		# to a place more appropriate in our opinion, currently content/lang/
		if os.path.exists(os.path.join("build", "mo")):
			# it appears build/mo should always magically appear,
			# but does not on some gentoo machines.
			# there, everything is placed in content/lang, so it's fine
			# on other machines, we have to move stuff around like that:
			if os.path.exists(os.path.join("content", "lang")):
				rmtree(os.path.join("content", "lang"))
			copytree(os.path.join("build", "mo"), os.path.join("content", "lang"))

		#self.generate_atlases(2048)


build.sub_commands.append(('build_i18n', None))

cmdclass = {
    'build_i18n': _build_i18n,
}

setup(
    name='UnknownHorizons',
    version=VERSION.RELEASE_VERSION,
    description='Realtime Economy Simulation and Strategy Game',
    author='The Unknown Horizons Team',
    author_email='team@unknown-horizons.org',
    url='http://www.unknown-horizons.org',
    packages=packages,
    package_data=package_data,
    data_files=data,
    cmdclass=cmdclass)

# after installation remove gitversion.txt
if os.path.exists('.git'):
	os.unlink('content/packages/gitversion.txt')