Djangoアプリ用setupスクリプト
Djangoアプリを複数のWinマシンにインストールする必要に駆られて試行錯誤していたら、なんとなく形になったのでメモしておく。
- 20080410追記
- 国際化用ファイルの考慮が漏れていたので修正した。
setup.py
# -*- encoding: utf-8 -*- from distutils.core import setup import os APP_NAME = 'MyDjangoApplication' def fullsplit(path, result=None): """ Split a pathname into components (the opposite of os.path.join) in a platform-neutral way. """ if result is None: result = [] head, tail = os.path.split(path) if head == '': return [tail] + result if head == path: return result return fullsplit(head, [tail] + result) def separate_package(packages, tokens, ext): """ ワードリストをパッケージとパッケージからの相対パスに分離します。 @param packages パッケージのリスト @param tokens トークンのリスト @param ext ファイル拡張子 """ tmp = tokens[:] extra = [] for i in range(len(tmp)): candidate = ".".join(tmp) if candidate in packages: return candidate, '%s/*.%s' % ('/'.join(extra), ext) extra.insert(0, tmp.pop()) return None, None packages, data_files = [], {} root_dir = os.path.dirname(__file__) target_dir = os.path.join(root_dir, APP_NAME) for dirpath, dirnames, filenames in os.walk(target_dir): tokens = fullsplit(dirpath) for i, dirname in enumerate(dirnames): if dirname.startswith('.'): del dirnames[i] if '__init__.py' in filenames: package_name = '.'.join(tokens) packages.append(package_name) data_files[package_name] = [] for filename in filenames: if not '.' in filename: continue name, ext = filename.rsplit('.', 1) if ext in ['css', 'gif', 'jpg', 'jpeg', 'png', 'js', 'json', 'html', 'mo', 'po']: target_package, pattern = separate_package(packages, tokens, ext) if pattern and not pattern in data_files[target_package]: data_files[target_package].append(pattern) setup( name = APP_NAME, version = '1.0', packages = packages, package_data = data_files, )
使い方
Djangoアプリルートの親ディレクトリにsetup.pyを保存して、以下のコマンドを実行する。
python setup.py bdist_wininst
Django用setup.pyを修正してみる
Win用にDjango SVN版のインストーラを作成すると、管理画面のmediaファイルが正常に配置されないのでちょっと修正してみた。r7403r7411だとうまく動いてるみたい。
作成したものをここに置いておく。
from distutils.core import setup from distutils.command.install import INSTALL_SCHEMES import os import sys def fullsplit(path, result=None): """ Split a pathname into components (the opposite of os.path.join) in a platform-neutral way. """ if result is None: result = [] head, tail = os.path.split(path) if head == '': return [tail] + result if head == path: return result return fullsplit(head, [tail] + result) def separate_package(packages, tokens, ext): """ separate tokens to package and path. @param packages list of package @param tokens list of token @param ext extension of file """ tmp = tokens[:] extra = [] for i in range(len(tmp)): candidate = ".".join(tmp) if candidate in packages: return candidate, '%s/*.%s' % ('/'.join(extra), ext) extra.insert(0, tmp.pop()) return None, None # Tell distutils to put the data_files in platform-specific installation # locations. See here for an explanation: # http://groups.google.com/group/comp.lang.python/browse_thread/thread/35ec7b2fed36eaec/2105ee4d9e8042cb for scheme in INSTALL_SCHEMES.values(): scheme['data'] = scheme['purelib'] # Compile the list of packages available, because distutils doesn't have # an easy way to do this. packages, data_files = [], {} root_dir = os.path.dirname(__file__) if root_dir != '': os.chdir(root_dir) django_dir = 'django' for dirpath, dirnames, filenames in os.walk(django_dir): tokens = fullsplit(dirpath) for i, dirname in enumerate(dirnames): if dirname.startswith('.'): del dirnames[i] if '__init__.py' in filenames: package_name = '.'.join(tokens) packages.append(package_name) data_files[package_name] = [] for filename in filenames: if not '.' in filename: continue name, ext = filename.rsplit('.', 1) if ext in ['css', 'gif', 'jpg', 'jpeg', 'png', 'js', 'json', 'html', 'mo', 'po']: target_package, pattern = separate_package(packages, tokens, ext) if pattern and not pattern in data_files[target_package]: data_files[target_package].append(pattern) # Dynamically calculate the version based on django.VERSION. version_tuple = __import__('django').VERSION if version_tuple[2] is not None: version = "%d.%d_%s" % version_tuple else: version = "%d.%d" % version_tuple[:2] setup( name = "Django", version = version, url = 'http://www.djangoproject.com/', author = 'Lawrence Journal-World', author_email = 'holovaty@gmail.com', description = 'A high-level Python Web framework that encourages rapid development and clean, pragmatic design.', packages = packages, package_data = data_files, scripts = ['django/bin/django-admin.py'], )