patternpythonMinor
Updating libgdx game framework library files
Viewed 0 times
updatinggamelibgdxfileslibraryframework
Problem
I wrote a script that updates some library files for the game framework libgdx by grabbing the latest nightly build .zip file from a server and extracting the contents to the appropriate locations.
```
#!/usr/bin/python
__appname__ = 'libgdx_library_updater'
__version__ = "0.1"
__author__ = "Jon Renner "
__url__ = "http://github.com/jrenner/libgdx-updater"
__licence__ = "MIT"
import os, time, sys, urllib2, re, datetime, tempfile, zipfile, argparse
# error handling functions and utils
def fatal_error(msg):
print "ERROR: %s" % msg
sys.exit(1)
def warning_error(msg):
print "WARNING: %s" % msg
if not FORCE:
answer = confirm("abort? (Y/n): ")
if answer in YES:
fatal_error("USER QUIT")
def confirm(msg):
answer = raw_input(msg)
return answer.lower()
def human_time(t):
minutes = t / 60
seconds = t % 60
return "%.0fm %.1fs" % (minutes, seconds)
# constants
YES = ['y', 'ye', 'yes', '']
# for finding the time of the latest nightly build from the web page html
DATE_RE = r"[0-9]{1,2}-[A-Za-z]{3,4}-[0-9]{4}\s[0-9]+:[0-9]+"
REMOTE_DATE_FORMAT = "%d-%b-%Y %H:%M"
SUPPORTED_PLATFORMS = ['android', 'desktop', 'gwt']
CORE_LIBS = ["gdx.jar",
"gdx-sources.jar"]
DESKTOP_LIBS = ["gdx-backend-lwjgl.jar",
"gdx-backend-lwjgl-natives.jar",
"gdx-natives.jar"]
ANDROID_LIBS = ["gdx-backend-android.jar",
"armeabi/libgdx.so",
"armeabi/libandroidgl20.so",
"armeabi-v7a/libgdx.so",
"armeabi-v7a/libandroidgl20.so"]
GWT_LIBS = ["gdx-backend-gwt.jar"]
# parse arguments
EPILOGUE_TEXT = "%s\n%s" % (__author__, __url__) + "\nUSE AT YOUR OWN RISK!"
parser = argparse.ArgumentParser(description='LibGDX Library Updater %s' % __version__, epilog=EPILOGUE_TEXT)
parser.add_argument('-d', '--directory', help='set the libgdx project/workspace directory', default=os.getcwd())
parser.add_argument('-i'
```
#!/usr/bin/python
__appname__ = 'libgdx_library_updater'
__version__ = "0.1"
__author__ = "Jon Renner "
__url__ = "http://github.com/jrenner/libgdx-updater"
__licence__ = "MIT"
import os, time, sys, urllib2, re, datetime, tempfile, zipfile, argparse
# error handling functions and utils
def fatal_error(msg):
print "ERROR: %s" % msg
sys.exit(1)
def warning_error(msg):
print "WARNING: %s" % msg
if not FORCE:
answer = confirm("abort? (Y/n): ")
if answer in YES:
fatal_error("USER QUIT")
def confirm(msg):
answer = raw_input(msg)
return answer.lower()
def human_time(t):
minutes = t / 60
seconds = t % 60
return "%.0fm %.1fs" % (minutes, seconds)
# constants
YES = ['y', 'ye', 'yes', '']
# for finding the time of the latest nightly build from the web page html
DATE_RE = r"[0-9]{1,2}-[A-Za-z]{3,4}-[0-9]{4}\s[0-9]+:[0-9]+"
REMOTE_DATE_FORMAT = "%d-%b-%Y %H:%M"
SUPPORTED_PLATFORMS = ['android', 'desktop', 'gwt']
CORE_LIBS = ["gdx.jar",
"gdx-sources.jar"]
DESKTOP_LIBS = ["gdx-backend-lwjgl.jar",
"gdx-backend-lwjgl-natives.jar",
"gdx-natives.jar"]
ANDROID_LIBS = ["gdx-backend-android.jar",
"armeabi/libgdx.so",
"armeabi/libandroidgl20.so",
"armeabi-v7a/libgdx.so",
"armeabi-v7a/libandroidgl20.so"]
GWT_LIBS = ["gdx-backend-gwt.jar"]
# parse arguments
EPILOGUE_TEXT = "%s\n%s" % (__author__, __url__) + "\nUSE AT YOUR OWN RISK!"
parser = argparse.ArgumentParser(description='LibGDX Library Updater %s' % __version__, epilog=EPILOGUE_TEXT)
parser.add_argument('-d', '--directory', help='set the libgdx project/workspace directory', default=os.getcwd())
parser.add_argument('-i'
Solution
Your code looks pretty good. Some notes:
-
According to PEP8, imports should be written in separate lines.
-
-
-
That's an opinion: I prefer to write multi-line lists/dictionaries in JSON style. You save indentation space and the reordering of elements is straightforward (all at the meager cost of two lines):
-
Functions
-
Those functions
-
Function
Or:
-
-
There are a lot of imperative snippets that could be written functionally, for example this simple list-comprehension replaces a dozen lines from your code:
-
According to PEP8, imports should be written in separate lines.
-
fatal_error: I'd probably write the signature this way: fatal_error(msg, code=1).-
INTERACTIVE -> interactive. According to PEP8, global variables should be written lower-case.-
That's an opinion: I prefer to write multi-line lists/dictionaries in JSON style. You save indentation space and the reordering of elements is straightforward (all at the meager cost of two lines):
DESKTOP_LIBS = [
"gdx-backend-lwjgl.jar",
"gdx-backend-lwjgl-natives.jar",
"gdx-natives.jar",
]-
Functions
download_libgdx_zip and search_for_lib_locations are written (unnecessarily IMO) in a very imperative fashion. I'd probably refactor it with a functional approach in mind. At least don't reuse the same variable name to hold different values (i.e. total_size), as that takes away the sacred mathematical meaning of =.-
Those functions
run_xyz(locations, archive) look very similar, why not a unique run(platform, locations, archive).-
Function
found_all_in_set can be written:def found_all_in_set(lib_set, found_list):
return all(lib in found_list for lib in lib_set)Or:
def found_all_in_set(lib_set, found_list):
return set(lib_list).issubset(set(found_list))-
if ARCHIVE == None: -> if ARCHIVE is None: although I prefer the (almost) equivalent, more declarative if not ARCHIVE:.-
There are a lot of imperative snippets that could be written functionally, for example this simple list-comprehension replaces a dozen lines from your code:
platforms = [platform for (platform, libs) in zip(platforms, libs_list)
if found_all_in_set(libs, found_libraries)]Code Snippets
DESKTOP_LIBS = [
"gdx-backend-lwjgl.jar",
"gdx-backend-lwjgl-natives.jar",
"gdx-natives.jar",
]def found_all_in_set(lib_set, found_list):
return all(lib in found_list for lib in lib_set)def found_all_in_set(lib_set, found_list):
return set(lib_list).issubset(set(found_list))platforms = [platform for (platform, libs) in zip(platforms, libs_list)
if found_all_in_set(libs, found_libraries)]Context
StackExchange Code Review Q#27715, answer score: 2
Revisions (0)
No revisions yet.