From 5f9246f53255bf5ee33a7ffc69ca65cea4e05a33 Mon Sep 17 00:00:00 2001 From: Neil Date: Sat, 3 Sep 2016 22:29:45 +0200 Subject: [PATCH] Create Repo. Add Skellington 2.3 created project outline --- BUGS.txt | 1 + CHANGES.txt | 7 + LICENSE.txt | 1 + Makefile | 70 ++++++++++ README.txt | 51 +++++++ TODO.txt | 5 + android.txt | 4 + configure | 4 + data/README.txt | 2 + pyweek_upload.py | 198 ++++++++++++++++++++++++++ run_game.py | 3 + run_game.pyw | 3 + scripts/tabakrolletjie | 6 + setup.py | 277 +++++++++++++++++++++++++++++++++++++ tabakrolletjie/__init__.py | 3 + tabakrolletjie/__main__.py | 4 + tabakrolletjie/data.py | 27 ++++ 17 files changed, 666 insertions(+) create mode 100644 BUGS.txt create mode 100644 CHANGES.txt create mode 100644 LICENSE.txt create mode 100644 Makefile create mode 100644 README.txt create mode 100644 TODO.txt create mode 100644 android.txt create mode 100755 configure create mode 100644 data/README.txt create mode 100644 pyweek_upload.py create mode 100644 run_game.py create mode 100644 run_game.pyw create mode 100755 scripts/tabakrolletjie create mode 100755 setup.py create mode 100644 tabakrolletjie/__init__.py create mode 100644 tabakrolletjie/__main__.py create mode 100644 tabakrolletjie/data.py diff --git a/BUGS.txt b/BUGS.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/BUGS.txt @@ -0,0 +1 @@ + diff --git a/CHANGES.txt b/CHANGES.txt new file mode 100644 index 0000000..9da9763 --- /dev/null +++ b/CHANGES.txt @@ -0,0 +1,7 @@ + +Changes +======= + + + + diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..63d5fc3 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1 @@ +Licence: short_licence diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a12b51d --- /dev/null +++ b/Makefile @@ -0,0 +1,70 @@ +#fake Makefile for tabakrolletjie, to support the common +# ./configure;make;make install + +PYTHON = python + +#build: Setup setup.py +build: setup.py + $(PYTHON) setup.py build + +#install: Setup setup.py +install: setup.py + $(PYTHON) setup.py install + +#Setup: +# $(PYTHON) configure.py + +test check tests: + $(PYTHON) run_tests.py + +testall: + python2.5 setup.py test + python2.6 setup.py test + python3.1 setup.py test + make checkdocs + +#docs: install +# cd docs/utils +# $(PYTHON) makedocs.py + +clean: + rm -rf build dist MANIFEST .coverage + rm -f tabakrolletjie/*~ + rm -rf bin develop-eggs eggs parts .installed.cfg tabakrolletjie.egg-info + find . -name *.pyc -exec rm {} \; + find . -name *.swp -exec rm {} \; + $(PYTHON) setup.py clean + +# push changes +push: + #bzr push lp:tabakrolletjie + svn commit + +# commit changes +commit: + #bzr commit + svn commit + +#upload to pypi +upload: + make clean + #if you have your gpg key set up... sign your release. + #$(PYTHON) setup.py sdist upload --sign --identity="Your Name " + $(PYTHON) setup.py sdist upload + +sdist: + make clean + make testall + $(PYTHON) setup.py sdist + +checkdocs: + $(PYTHON) setup.py checkdocs -setuptools + +showdocs: + $(PYTHON) setup.py showdocs -setuptools + +coverage: + coverage run run_tests.py + coverage report -m + + diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..0fa18a5 --- /dev/null +++ b/README.txt @@ -0,0 +1,51 @@ +Your Game Title +=============== + +Entry in PyWeek #22 +URL: http://ctpug.org.za/gitweb/tabakrolletjie +Team: YOUR TEAM NAME (leave the "Team: bit") +Members: YOUR TEAM MEMBERS (leave the "Members: bit") +License: see LICENSE.txt + + +Running the Game +---------------- + +On Windows or Mac OS X, locate the "run_game.pyw" file and double-click it. + +Othewise open a terminal / console and "cd" to the game directory and run: + + python run_game.py + + +How to Play the Game +-------------------- + +An entry for pyweek 22 + +Move the cursor around the screen with the mouse. + +Press the left mouse button to fire the ducks. + + +Development notes +----------------- + +Creating a source distribution with:: + + python setup.py sdist + +You may also generate Windows executables and OS X applications:: + + python setup.py py2exe + python setup.py py2app + +Upload files to PyWeek with:: + + python pyweek_upload.py + +Upload to the Python Package Index with:: + + python setup.py register + python setup.py sdist upload + diff --git a/TODO.txt b/TODO.txt new file mode 100644 index 0000000..1bad070 --- /dev/null +++ b/TODO.txt @@ -0,0 +1,5 @@ + + +TODO +==== + diff --git a/android.txt b/android.txt new file mode 100644 index 0000000..e4cdc5e --- /dev/null +++ b/android.txt @@ -0,0 +1,4 @@ +title=tabakrolletjie +author=yourgameauthor +api=1 +orientation=landscape diff --git a/configure b/configure new file mode 100755 index 0000000..546f631 --- /dev/null +++ b/configure @@ -0,0 +1,4 @@ +#fake configure for pywebsite, to support the common +# ./configure;make;make install + +#python config.py -auto diff --git a/data/README.txt b/data/README.txt new file mode 100644 index 0000000..18bcae8 --- /dev/null +++ b/data/README.txt @@ -0,0 +1,2 @@ +Place your game's data files in here (images, fonts, map files, sounds, +etc). diff --git a/pyweek_upload.py b/pyweek_upload.py new file mode 100644 index 0000000..053a0cc --- /dev/null +++ b/pyweek_upload.py @@ -0,0 +1,198 @@ +''' +Upload script specifically engineered for the PyWeek challenge. + +Handles authentication and gives upload progress feedback. +''' +import sys, os, httplib, cStringIO, socket, time, getopt + +class Upload: + def __init__(self, filename): + self.filename = filename + +boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' +sep_boundary = '\n--' + boundary +end_boundary = sep_boundary + '--' + +def mimeEncode(data, sep_boundary=sep_boundary, end_boundary=end_boundary): + '''Take the mapping of data and construct the body of a + multipart/form-data message with it using the indicated boundaries. + ''' + ret = cStringIO.StringIO() + for key, value in data.items(): + # handle multiple entries for the same name + if type(value) != type([]): value = [value] + for value in value: + ret.write(sep_boundary) + if isinstance(value, Upload): + ret.write('\nContent-Disposition: form-data; name="%s"'%key) + filename = os.path.basename(value.filename) + ret.write('; filename="%s"\n\n'%filename) + value = open(os.path.join(value.filename), "rb").read() + else: + ret.write('\nContent-Disposition: form-data; name="%s"'%key) + ret.write("\n\n") + value = str(value) + ret.write(str(value)) + if value and value[-1] == '\r': + ret.write('\n') # write an extra newline + ret.write(end_boundary) + return ret.getvalue() + +class Progress: + def __init__(self, info, data): + self.info = info + self.tosend = len(data) + self.total = self.tosend/1024 + self.data = cStringIO.StringIO(data) + self.start = self.now = time.time() + self.sent = 0 + self.num = 0 + self.stepsize = self.total / 100 or 1 + self.steptimes = [] + self.display() + + def __iter__(self): return self + + def next(self): + self.num += 1 + if self.sent >= self.tosend: + print self.info, 'done', ' '*(75-len(self.info)-6) + sys.stdout.flush() + raise StopIteration + + chunk = self.data.read(1024) + self.sent += len(chunk) + #print (self.num, self.stepsize, self.total, self.sent, self.tosend) + + if self.num % self.stepsize: + return chunk + self.display() + return chunk + + def display(self): + # figure how long we've spent - guess how long to go + now = time.time() + steptime = now - self.now + self.steptimes.insert(0, steptime) + if len(self.steptimes) > 5: + self.steptimes.pop() + steptime = sum(self.steptimes) / len(self.steptimes) + self.now = now + eta = steptime * ((self.total - self.num)/self.stepsize) + + # tell it like it is (or might be) + if now - self.start > 3: + M = eta / 60 + H = M / 60 + M = M % 60 + S = eta % 60 + if self.total: + s = '%s %2d%% (ETA %02d:%02d:%02d)'%(self.info, + self.num * 100. / self.total, H, M, S) + else: + s = '%s 0%% (ETA %02d:%02d:%02d)'%(self.info, H, M, S) + elif self.total: + s = '%s %2d%%'%(self.info, self.num * 100. / self.total) + else: + s = '%s %d done'%(self.info, self.num) + sys.stdout.write(s + ' '*(75-len(s)) + '\r') + sys.stdout.flush() + +class progressHTTPConnection(httplib.HTTPConnection): + def progress_send(self, str): + """Send `str' to the server.""" + if self.sock is None: + self.connect() + + p = Progress('Uploading', str) + for chunk in p: + sent = 0 + while sent != len(chunk): + try: + sent += self.sock.send(chunk) + except socket.error, v: + if v[0] == 32: # Broken pipe + self.close() + raise + p.display() + +class progressHTTP(httplib.HTTP): + _connection_class = progressHTTPConnection + def _setup(self, conn): + httplib.HTTP._setup(self, conn) + self.progress_send = self._conn.progress_send + +def http_request(data, server, port, url): + h = progressHTTP(server, port) + + data = mimeEncode(data) + h.putrequest('POST', url) + h.putheader('Content-type', 'multipart/form-data; boundary=%s'%boundary) + h.putheader('Content-length', str(len(data))) + h.putheader('Host', server) + h.endheaders() + + h.progress_send(data) + + errcode, errmsg, headers = h.getreply() + + f = h.getfile() + response = f.read().strip() + f.close() + + print '%s %s'%(errcode, errmsg) + if response: print response + +def usage(): + print '''This program is to be used to upload files to the PyWeek system. +You may use it to upload screenshots or code submissions. + +REQUIRED ARGUMENTS: + -u username + -p password + -d description of file + -c file to upload + -e entry short name + +OPTIONAL ARGUMENTS: + -s file is a screenshot + -f file is FINAL submission + -h override default host name (www.pyweek.org) + -P override default host port (80) + +In order to qualify for judging at the end of the challenge, you MUST +upload your source and check the "Final Submission" checkbox. +''' + + +if __name__ == '__main__': + try: + optlist, args = getopt.getopt(sys.argv[1:], 'e:u:p:sfd:h:P:c:') + except getopt.GetoptError, message: + print message + usage() + sys.exit(1) + host = 'www.pyweek.org' + port = 80 + data = dict(version=2) + optional = {} + url = None + for opt, arg in optlist: + if opt == '-u': data['user'] = arg + elif opt == '-p': data['password'] = arg + elif opt == '-s': optional['is_screenshot'] = 'yes' + elif opt == '-f': optional['is_final'] = 'yes' + elif opt == '-d': data['description'] = arg + elif opt == '-c': data['content_file'] = Upload(arg) + elif opt == '-e': url = '/e/%s/oup/'%arg + elif opt == '-h': host = arg + elif opt == '-P': port = int(arg) + + if len(data) < 4 or url is None: + print 'Required argument missing' + usage() + sys.exit(1) + + data.update(optional) + http_request(data, host, port, url) + diff --git a/run_game.py b/run_game.py new file mode 100644 index 0000000..31e7bb0 --- /dev/null +++ b/run_game.py @@ -0,0 +1,3 @@ +import tabakrolletjie.__main__ +if __name__ == "__main__": + tabakrolletjie.__main__.main() diff --git a/run_game.pyw b/run_game.pyw new file mode 100644 index 0000000..1a6f51f --- /dev/null +++ b/run_game.pyw @@ -0,0 +1,3 @@ +import yourgameshortname.main +if __name__ == "__main__": + yourgameshortname.main.main() diff --git a/scripts/tabakrolletjie b/scripts/tabakrolletjie new file mode 100755 index 0000000..a6d8097 --- /dev/null +++ b/scripts/tabakrolletjie @@ -0,0 +1,6 @@ +#!/usr/bin/env python + +import tabakrolletjie.__main__ +if __name__ == "__main__": + tabakrolletjie.__main__.main() + diff --git a/setup.py b/setup.py new file mode 100755 index 0000000..e6b1a53 --- /dev/null +++ b/setup.py @@ -0,0 +1,277 @@ +import os + +# usage: python setup.py command +# +# sdist - build a source dist +# py2exe - build an exe +# py2app - build an app +# cx_freeze - build a linux binary (not implemented) +# +# the goods are placed in the dist dir for you to .zip up or whatever... + + +APP_NAME = 'tabakrolletjie' +DESCRIPTION = open('README.txt').read() +CHANGES = open('CHANGES.txt').read() +TODO = open('TODO.txt').read() + + + +METADATA = { + 'name':APP_NAME, + 'version': '0.0.1', + 'license': 'short_licence', + 'description': 'An entry for pyweek 22', + 'author': 'Adrianna Pinksa, Simon Cross and Neil Muller', + #'author_email': '', + 'url': 'http://ctpug.org.za/gitweb/tabakrolletjie', + 'classifiers': [ + 'Development Status :: 4 - Beta', + 'Intended Audience :: End Users/Desktop', + 'Intended Audience :: Information Technology', + 'License :: OSI Approved :: BSD License', + 'Operating System :: OS Independent', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.5', + 'Programming Language :: Python :: 2.6', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.0', + 'Programming Language :: Python :: 3.1', + 'Programming Language :: Python :: 3.2', + 'Topic :: Software Development :: Libraries :: pygame', + 'Topic :: Games/Entertainment :: Real Time Strategy', + ], + + + 'py2exe.target':'', + #'py2exe.icon':'icon.ico', #64x64 + 'py2exe.binary':APP_NAME, #leave off the .exe, it will be added + + 'py2app.target':APP_NAME, + 'py2app.icon':'icon.icns', #128x128 + + #'cx_freeze.cmd':'~/src/cx_Freeze-3.0.3/FreezePython', + 'cx_freeze.cmd':'cxfreeze', + 'cx_freeze.target':'%s_linux' % APP_NAME, + 'cx_freeze.binary':APP_NAME, + } + +files_to_remove = ['tk84.dll', + '_ssl.pyd', + 'tcl84.dll', + os.path.join('numpy','core', '_dotblas.pyd'), + os.path.join('numpy', 'linalg', 'lapack_lite.pyd'), +] + + +directories_to_remove = [os.path.join('numpy', 'distutils'), + 'distutils', + 'tcl', +] + + +cmdclass = {} +PACKAGEDATA = { + 'cmdclass': cmdclass, + + 'package_dir': {'tabakrolletjie': 'tabakrolletjie', + }, + 'packages': ['tabakrolletjie', + ], + 'scripts': ['scripts/tabakrolletjie'], +} + +PACKAGEDATA.update(METADATA) + + +from distutils.core import setup, Extension +try: + import py2exe +except: + pass + +import sys +import glob +import os +import shutil + +try: + cmd = sys.argv[1] +except IndexError: + print 'Usage: setup.py install|py2exe|py2app|cx_freeze' + raise SystemExit + +# utility for adding subdirectories +def add_files(dest,generator): + for dirpath, dirnames, filenames in generator: + for name in 'CVS', '.svn': + if name in dirnames: + dirnames.remove(name) + + for name in filenames: + if '~' in name: continue + suffix = os.path.splitext(name)[1] + if suffix in ('.pyc', '.pyo'): continue + if name[0] == '.': continue + filename = os.path.join(dirpath, name) + dest.append(filename) + +# define what is our data +_DATA_DIR = os.path.join('tabakrolletjie', 'data') +data = [] +add_files(data,os.walk(_DATA_DIR)) + + + + +#data_dirs = [os.path.join(f2.replace(_DATA_DIR, 'data'), '*') for f2 in data] +data_dirs = [os.path.join(f2.replace(_DATA_DIR, 'data')) for f2 in data] +PACKAGEDATA['package_data'] = {'tabakrolletjie': data_dirs} + + + + + +data.extend(glob.glob('*.txt')) +#data.append('MANIFEST.in') +# define what is our source +src = [] +add_files(src,os.walk('tabakrolletjie')) +src.extend(glob.glob('*.py')) + + + + +# build the sdist target +if cmd not in "py2exe py2app cx_freeze".split(): + f = open("MANIFEST.in","w") + for l in data: f.write("include "+l+"\n") + for l in src: f.write("include "+l+"\n") + f.close() + + setup(**PACKAGEDATA) + +# build the py2exe target +if cmd in ('py2exe',): + dist_dir = os.path.join('dist',METADATA['py2exe.target']) + data_dir = dist_dir + + src = 'run_game.py' + dest = METADATA['py2exe.binary']+'.py' + shutil.copy(src,dest) + + setup( + options={'py2exe':{ + 'dist_dir':dist_dir, + 'dll_excludes':['_dotblas.pyd','_numpy.pyd', 'numpy.linalg.lapack_lite.pyd', 'numpy.core._dotblas.pyd'] + files_to_remove, + 'excludes':['matplotlib', 'tcl', 'OpenGL'], + 'ignores':['matplotlib', 'tcl', 'OpenGL'], + 'bundle_files':1, + }}, +# windows=[{ + console=[{ + 'script':dest, + #'icon_resources':[(1,METADATA['py2exe.icon'])], + }], + ) + +# build the py2app target +if cmd == 'py2app': + dist_dir = os.path.join('dist',METADATA['py2app.target']+'.app') + data_dir = os.path.join(dist_dir,'Contents','Resources') + from setuptools import setup + + src = 'run_game.py' + dest = METADATA['py2app.target']+'.py' + shutil.copy(src,dest) + + APP = [dest] + DATA_FILES = [] + OPTIONS = {'argv_emulation': True, + #'iconfile':METADATA['py2app.icon'] + } + + setup( + app=APP, + data_files=DATA_FILES, + options={'py2app': OPTIONS}, + setup_requires=['py2app'], + ) + +# make the cx_freeze target +if cmd == 'cx_freeze': + app_dist_dir = METADATA['cx_freeze.target'] + "_" + METADATA['version'] + dist_dir = os.path.join('dist', app_dist_dir) + data_dir = dist_dir + + modules_exclude = "tcl,tk" + cmd_args = (METADATA['cx_freeze.cmd'], dist_dir, METADATA['cx_freeze.binary'], modules_exclude) + sys_cmd = '%s --install-dir=%s --target-name=%s --exclude-modules=%s run_game.py' % cmd_args + print sys_cmd + os.system(sys_cmd) + + import shutil + if os.path.exists(os.path.join(data_dir, "tcl")): + shutil.rmtree( os.path.join(data_dir, "tcl") ) + if os.path.exists(os.path.join(data_dir, "tk")): + shutil.rmtree( os.path.join(data_dir, "tk") ) + + + +# recursively make a bunch of folders +def make_dirs(dname_): + parts = list(os.path.split(dname_)) + dname = None + while len(parts): + if dname == None: + dname = parts.pop(0) + else: + dname = os.path.join(dname,parts.pop(0)) + if not os.path.isdir(dname): + os.mkdir(dname) + +# copy data into the binaries +if cmd in ('py2exe','cx_freeze','py2app'): + dest = data_dir + for fname in data: + dname = os.path.join(dest,os.path.dirname(fname)) + make_dirs(dname) + if not os.path.isdir(fname): + #print (fname,dname) + shutil.copy(fname,dname) + +# make a tgz files. +if cmd == 'cx_freeze': + sys_cmd = "cd dist; tar -vczf %s.tgz %s/" % (app_dist_dir,app_dist_dir) + os.system(sys_cmd) + + +# remove files from the zip. +if 0 and cmd in ('py2exe'): + import shutil + + #shutil.rmtree( os.path.join('dist') ) + #shutil.rmtree( os.path.join('build') ) + + + os.system("unzip dist/library.zip -d dist\library") + + for fn in files_to_remove: + os.remove( os.path.join('dist', 'library', fn) ) + + + for d in directories_to_remove: + if os.path.exists( os.path.join('dist', 'library', d) ): + shutil.rmtree( os.path.join('dist', 'library', d) ) + + os.remove( os.path.join('dist', 'library.zip') ) + + + os.chdir("dist") + os.chdir("library") + + os.system("zip -r -9 ..\library.zip .") + + os.chdir("..") + os.chdir("..") diff --git a/tabakrolletjie/__init__.py b/tabakrolletjie/__init__.py new file mode 100644 index 0000000..6cd298b --- /dev/null +++ b/tabakrolletjie/__init__.py @@ -0,0 +1,3 @@ +if __name__ == "__main__": + import main + main.main() diff --git a/tabakrolletjie/__main__.py b/tabakrolletjie/__main__.py new file mode 100644 index 0000000..dbb20cd --- /dev/null +++ b/tabakrolletjie/__main__.py @@ -0,0 +1,4 @@ + +def main(): + """ your app starts here + """ diff --git a/tabakrolletjie/data.py b/tabakrolletjie/data.py new file mode 100644 index 0000000..66b66bb --- /dev/null +++ b/tabakrolletjie/data.py @@ -0,0 +1,27 @@ +'''Simple data loader module. + +Loads data files from the "data" directory shipped with a game. + +Enhancing this to handle caching etc. is left as an exercise for the reader. + +Note that pyglet users should probably just add the data directory to the +pyglet.resource search path. +''' + +import os + +data_py = os.path.abspath(os.path.dirname(__file__)) +data_dir = os.path.normpath(os.path.join(data_py, '..', 'data')) + +def filepath(filename): + '''Determine the path to a file in the data directory. + ''' + return os.path.join(data_dir, filename) + +def load(filename, mode='rb'): + '''Open a file in the data directory. + + "mode" is passed as the second arg to open(). + ''' + return open(os.path.join(data_dir, filename), mode) + -- 2.34.1