--- /dev/null
+
+Changes
+=======
+
+
+
+
--- /dev/null
+Licence: short_licence
--- /dev/null
+#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 <youremail@example.com>"
+ $(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
+
+
--- /dev/null
+Your Game Title
+===============
+
+Entry in PyWeek #22 <http://www.pyweek.org/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
+
--- /dev/null
+
+
+TODO
+====
+
--- /dev/null
+title=tabakrolletjie
+author=yourgameauthor
+api=1
+orientation=landscape
--- /dev/null
+#fake configure for pywebsite, to support the common
+# ./configure;make;make install
+
+#python config.py -auto
--- /dev/null
+Place your game's data files in here (images, fonts, map files, sounds,
+etc).
--- /dev/null
+'''
+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)
+
--- /dev/null
+import tabakrolletjie.__main__
+if __name__ == "__main__":
+ tabakrolletjie.__main__.main()
--- /dev/null
+import yourgameshortname.main
+if __name__ == "__main__":
+ yourgameshortname.main.main()
--- /dev/null
+#!/usr/bin/env python
+
+import tabakrolletjie.__main__
+if __name__ == "__main__":
+ tabakrolletjie.__main__.main()
+
--- /dev/null
+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("..")
--- /dev/null
+if __name__ == "__main__":
+ import main
+ main.main()
--- /dev/null
+
+def main():
+ """ your app starts here
+ """
--- /dev/null
+'''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)
+