Instaget

From TIP Wiki

Jump to: navigation, search

Instaget is a Python script which automatically downloads the latest Subversion revision updates of the media packages if there are any. It will only download the ones that have been updated, and only if there are any updates.

Both must go in the same folder. Read the section that pertains to you for system specific instructions.

Windows

Make sure you have Python installed. Then create a folder called tip and put instaget.py and instaget.conf in there. Also in there create another folder called base.

Sanity Check:

  • /tip/instaget.py - FILE
  • /tip/instaget.conf - FILE
  • /tip/base - FOLDER

Simply double clicking on instaget.py should work. It should then give you a menu asking what you'd like to do.

IMPORTANT: This program relies on the appearance of file extensions. Please read how to show extensions for known file types and then run the program. Failure to do so will confuse the program, and more so, you.

  • 1. This option checks everything for updates, and if there are, downloads them and installs them
  • 2. This option lets you download a specific file if you're missing something
  • 3. This option downloads everything for the first time. Use this if you don't have the game yet

Linux, Mac OS X, and Everything Else

If you are on anything else, such as Linux or Mac OS X, you most likely already have Python installed. You can try making the script executable if you know how (If in a Desktop Environment, right click > Properties. Otherwise, chmod +x instaget.py), and then simply double clicking on it or issuing ./instaget.py. Otherwise, if neither works, then open a terminal and go to where the script is and type:

python instaget.py

It will print out the usage information:

Instaget: The Instagib Project Updater
Usage: instaget [SWITCH]
Switches:
  -h, --help            displays this help message
  -i, --initial         downloads all of the pk3s
  -c, --check           checks a specific package
  -a, --all             checks all of the packages
  -d, --download        downloads the specific pk3
Examples:
  Downloading all of the pk3s for the first time:
    python instaget.py -i
  Check only one of the pk3s:
    python instaget.py -c players.pk3
  Check all of the pk3s:
    python instaget.py -a
  Download a specific pk3:
    python instaget.py -d players.pk3

It should be pretty straightforward. If you guys have any problems, please post on the forums.

Latest Revision

Here is the latest revision, just to look at. To download, use the link above:

instaget.py

#! /usr/bin/python
 
import os # For system method
import sys # For exit method
import getopt # For the getopt stuff
from stat import * # To check if base/ is there
import zipfile # To read md5 hash inside zip file
from glob import glob # To look for the pk3s
import urllib2 # To download wget haha
import shutil # To move files around
from ConfigParser import SafeConfigParser # to parse the conf file
 
class Configuration:
    def __init__ (self, fileName):
        cp = SafeConfigParser()
        cp.read(fileName)
        self.__parser = cp
        self.fileName = fileName
 
    def __getattr__ (self, name):
        if name in self.__parser.sections():
            return Section(name, self.__parser)
        else:
            return None
 
    def __str__ (self):
        p = self.__parser
        result = []
        result.append('<Configuration from %s>' % self.fileName)
        for s in p.sections():
            result.append('[%s]' % s)
            for o in p.options(s):
                result.append('%s=%s' % (o, p.get(s, o)))
        return '\n'.join(result)
 
class Section:
    def __init__ (self, name, parser):
        self.name = name
        self.__parser = parser
    def __getattr__ (self, name):
        return self.__parser.get(self.name, name)
 
conf = Configuration('instaget.conf')
 
def getPk3Hash(thezip):
   # This retrieves the md5 sum from the md5hash file in the zip file
   f = zipfile.ZipFile(thezip, "r")
   line = f.read(thezip[5:] + ".md5") # Get the file.pk3.md5
   return line[:32] # Return the md5 hash which are the first 32 digits
 
def downloadHashes():
   # Will need to get all of the file.zip.md5 files
   os.system("wget -N " + conf.site.packages + " -nd -r -l1 --no-parent -A md5")
 
def downloadEverything():
   # Retrieve all of the pk3s
   os.system("wget -nd -r -l1 --no-parent -A pk3 " + conf.site.packages)
   # The following will check if base/ is there, if not, it'll create it
   # Then it'll move the pk3s into it
   try:
      mode = os.stat("base")[ST_MODE]
      if S_ISDIR(mode):
         pk3s = glob("*.pk3")
         for pk3 in pk3s:
            print "moving " + pk3 + " to base/"
            shutil.move(pk3, "base")
   except OSError:
      os.system("mkdir base")
      pk3s = glob("*.pk3")
      for pk3 in pk3s:
         print "moving " + pk3 + " to base/"
         shutil.move(pk3, "base")
 
   if sys.platform == 'win32':
      getWin32Binaries()
   elif sys.platform == 'linux2':
      getLinuxBinaries()
   elif sys.platform == 'darwin':
      getMacBinaries()
   else:
      print "Not on windows or linux, unable to download the binaries :("
 
# Download something to the base directory
def getForBase(url):
   os.system("wget -P base/ " + url + " -N")
 
# Download something to the current directory
def getHere(url):
   os.system("wget " + url + " -N")
 
# Download the binhash to the current directory
def getBinHash(url):
   os.system("wget " + url + " -O - > binhash.remote")
 
# Get all of the windows binaries
def getWin32Binaries():
    getForBase(conf.windows.cgame)
    getForBase(conf.windows.qagame)
    getForBase(conf.windows.ui)
    getHere(conf.windows.tip)
    getHere(conf.windows.binhash)
 
# Get all of the linux binaries
def getLinuxBinaries():
    getForBase(conf.linux.cgame)
    getForBase(conf.linux.qagame)
    getForBase(conf.linux.ui)
    getHere(conf.linux.tip)
    getHere(conf.linux.tipded)
    getHere(conf.linux.binhash)
 
# Get all of the mac binaries
def getMacBinaries():
    # Don't replace this, only binhash method
    os.system("wget " + conf.mac.app + " -O - > tip.app.tar.gz -N")
    os.system("rm -rf tip.app")
    os.system("tar xvzf tip.app.tar.gz")
    os.system("rm tip.app.tar.gz")
    getHere(conf.mac.binhash)
 
# Check all of the pk3s
def checkAllPk3s():
   # We should first download the hashes
   downloadHashes()
   failed = 0 # This will check how many updates are needed
 
   pk3s = glob("base/*.pk3")
   for pk3 in pk3s:
      f = open(pk3[5:] + ".md5", "r")
      rHash = f.readline()[:32]
      lHash = getPk3Hash(pk3)
      print "---------------------------------------------"
      print "File: " + pk3
      print "Remote Hash: " + rHash
      print "Local Hash:  " + lHash
 
      # Check if the md5 hashes are equal
      if (lHash != rHash):
         print "MD5 Hash Mismatch..."
         failed = failed + 1
         downloadSpecific(pk3[5:])
      else:
         print "Successful match"
      f.close()
 
   print "---------------------------------------------"
   if failed == 0:
      print "No updates available"
   else:
      print "Downloaded %i updates" % failed
 
   # Remove the .md5 files
   print "Removing the MD5 Hash files..."
 
   if sys.platform == 'win32':
      os.system("del *.md5")
   else:
      os.system("rm -v *.md5")
 
# Compares hashes and if mismatch, downloads file
def compareHashes(first, second, url, file, inBase):
   print "File: " + file
   print "Local Hash:  " + first
   print "Remote Hash: " + second
 
   if first != second:
      print "MD5 Hash Mismatch..."
      if not inBase:
         cmd = "wget " + url + " -N"
      else:
         cmd = "wget -P base/ " + url + " -N"
      os.system(cmd)
   else:
      print "Successful match"
 
def checkMacBinaries():
   lhash = open("binhash", "r")
   tipdedl = loc.readline()[:32]
   lhash.close()
   print "Downloading the remote hash file..."
   getBinHash(conf.mac.binhash)
   rem = open("binhash.remote", "r")
   rhash = rem.readline()[:32]
   rem.close()
 
   print "Comparing tip.app"
   print "Local Hash:  " + lhash
   print "Remote Hash: " + rhash
 
   if rhash != lhash:
      print "MD5 Hash Mismatch..."
      os.system("wget " + conf.mac.app + " -O - > tip.app.tar.gz -N")
   else:
      print "Successful match"
 
   os.system("rm -v binhash")
   shutil.move("binhash.remote", "binhash")
 
def checkLinuxBinaries():
   loc = open("binhash", "r")
   tipdedl = loc.readline()
   tipdedl = loc.readline()[:32]
   tipl = loc.readline()[:32]
   cgamei386l = cgamei386l[:32]
   qagamei3861 = loc.readline()[:32]
   uii386l = loc.readline()[:32]
   loc.close()
 
   print "Downloading the remote hash file..."
   getBinHash(conf.linux.binhash)
 
   rem = open("binhash.remote", "r")
   tipdedr = rem.readline()[:32]
   tipr = rem.readline()[:32]
   cgamei386r = rem.readline()[:32]
   qagamei386r = rem.readline()[:32]
   uii386r = rem.readline()[:32]
   rem.close()
 
   compareHashes(cgamei386l, cgamei386r, conf.linux.cgame, "cgamei386.so", False)
   compareHashes(qagamei386l, qagamei386r, conf.linux.qagame, "qagamei386.so", False)
   compareHashes(uii386l, uii386r, conf.linux.ui, "uii386.so", False)
   compareHashes(tipl, tipr, conf.linux.tip, "tip.i386", True)
   compareHashes(tipdedl, tipdedr, conf.linux.tipded, "tipded.i386", True)
 
   os.system("rm -v binhash")
   shutil.move("binhash.remote", "binhash")
 
def checkWin32Binaries():
   loc = open("binhash", "r")
   cgamex86l = loc.readline()
   cgamex86l = cgamex86l[:32]
   qagamex861 = loc.readline()[:32]
   tipl = loc.readline()[:32]
   uix86l = loc.readline()[:32]
   loc.close()
 
   print "Downloading the remote hash file..."
   getBinHash(conf.windows.binhash)
 
   rem = open("binhash.remote", "r")
   cgamex86r = rem.readline()[:32]
   qagamex86r = rem.readline()[:32]
   tipr = rem.readline()[:32]
   uix86r = rem.readline()[:32]
   rem.close()
 
   compareHashes(cgamex86l, cgamex86r, conf.windows.cgame, "cgamex86.dll", False)
   compareHashes(qagamex861, qagamex86r, conf.windows.qagame, "qagamei386.so", False)
   compareHashes(uix86l, uix86r, conf.windows.ui, "uix86.dll", False)
   compareHashes(tipl, tipr, conf.windows.tip, "tip.exe", True)
 
   os.system("del binhash")
   shutil.move("binhash.remote", "binhash")
 
# This downloads a specific file
def downloadSpecific(thefile):
   # If it's a pk3
   if thefile.endswith(".pk3"):
      url = conf.site.packages + thefile
      dest = "base/" + thefile
      print "Downloading " + thefile + " from " + url + " to " + dest
      os.system("wget -P base/ " + url + " -N")
   # If it's a dynamic link library
   elif thefile.endswith(".dll"):
      url = conf.site.dlls + thefile
      dest = "base/" + thefile
      print "Downloading " + thefile + " from " + url + " to " + dest
      os.system("wget -P base/ " + url + " -N")
   # If it's an exe
   elif thefile.endswith(".exe"):
      url = conf.site.exe
      print "Downloading " + thefile + " from " + url
      os.system("wget " + url + " -N")
   # If it's the mac app file
   elif thefile.endswith(".app"):
      getMacBinaries()
      print "Downloading tip.app.tar.gz from the subversion repository"
   # If it's a shared library
   elif thefile.endswith(".so"):
      url = conf.site.sos + thefile
      dest = "base/" + thefile
      print "Downloading " + thefile + " from " + url + " to " + dest
      os.system("wget -P base/ " + url + " -N")
   # If it's a linux binary
   elif thefile.endswith(".i386"):
      url = conf.site.i386s + thefile
      print "Downloading " + thefile + " from " + url + " to " + dest
      os.system("wget " + url + " -N")
   else:
      print "What the heck? Make sure you typed the name correctly"
      raw_input("Press enter to exit...")
      sys.exit(2)
 
# Download wget if it's not here already
def download(url):
   import urllib
   webFile = urllib.urlopen(url)
   localFile = open(url.split('/')[-1], 'w')
   localFile.write(webFile.read())
   webFile.close()
   localFile.close()
 
# Basically a -h
def Usage():
   print "Instaget: The Instagib Project Updater"
   print "Usage: instaget [SWITCH]"
   print "Switches:"
   print "  -h, --help\t\tdisplays this help message"
   print "  -i, --initial\t\tdownloads all of the pk3s and binaries"
   print "  -a, --all\t\tchecks all packages (And binaries if on windows)"
   print "  -d, --download=FILE\tdownloads a specific file (pk3, exe, or dll)"
   print "  -b, --binaries\tchecks your binaries ONLY for updates"
   print "  -m, --media\t\tchecks your media ONLY for updates"
   print "Examples:"
   print "  Downloading all of the pk3s for the first time:"
   print "    python instaget.py -i"
   print "  Check everything for updates:"
   print "    python instaget.py -a"
   print "  Download something in specific:"
   print "    python instaget.py -d players.pk3"
   print "  Check binaries ONLY for updates:"
   print "    python instaget.py -b"
   print "  Check media ONLY for updates:"
   print "    python instaget.py -m"
 
if __name__ == "__main__":
   try:
      opts, args = getopt.getopt(sys.argv[1:], 'hiadb:', ["help", "initial", "all", "download=", "binaries"])
   except getopt.GetoptError:
      Usage()
      sys.exit(2)
 
   if not opts:
      if sys.platform == 'win32':
         if sys.platform == 'win32':
            if (not os.path.exists("wget.exe")):
               download(conf.site.tools + "wget.exe")
               print "Re-Run the program. You didn't have wget and it has just been downloaded."
               raw_input("Press enter to exit...")
               sys.exit(2)
         print "Type the number of the option you'd like to do:"
         print "1. All\t\t\t\tchecks all of the packages"
         print "2. Download\t\t\tdownloads a specific pk3"
         print "3. Initial\t\t\tdownloads all of the pk3s and binaries"
         print "4. Check Binaries Only\t\tchecks your binaries"
         print "5. Check Media Only\t\tchecks your media pk3s"
         option = int(raw_input("So what will it be? "))
 
         if option == 1:
            checkAllPk3s()
            checkWin32Binaries()
         elif option == 2:
            pk3 = raw_input("What package? (Include the extension at the end, ex. bots.pk3): ")
            downloadSpecific(pk3)
         elif option == 3:
            downloadEverything()
         elif option == 4:
            if sys.platform == 'win32':
                checkWin32Binaries()
            elif sys.platform == 'linux2':
                checkLinuxBinaries()
            elif sys.platform == 'darwin':
                checkMacBinaries()
            else:
                print "There are no pre-built binaries for your system, what are you on, a Toaster?"
         elif option == 5:
            checkAllPk3s()
         else:
            print "What the heck? You entered a non-existant option!"
 
         raw_input("Press enter to exit...")
         sys.exit(2)
 
      Usage()
      sys.exit(2)
 
   package = "None"
 
   for o, a in opts:
      if o in ("-h", "--help"):
         Usage()
         sys.exit(2)
      if o in ("-i", "--initial"):
         downloadEverything()
      if o in ("-a", "--all"):
         checkAllPk3s()
         if sys.platform == 'win32':
            checkWin32Binaries()
         elif sys.platform == 'linux2':
            checkLinuxBinaries()
         elif sys.platform == 'darwin':
            checkMacBinaries()
      if o in ("-d", "--download"):
         downloadSpecific(a)
      if o in ("-b", "--binaries"):
          if sys.platform == 'win32':
              checkWin32Binaries()
          elif sys.platform == 'linux2':
              checkLinuxBinaries()
          elif sys.platform == 'darwin':
              checkMacBinaries()
          else:
              print "There are no pre-built binaries for your system, what are you on, a Toaster?"
      if o in ("-m", "--media"):
          checkAllPk3s()
 
   print "Done doing whatever it is you chose to do :D"

instaget.conf

[windows]
binhash="http://svn.jorgepena.be/tipsrc/trunk/hashes/winhash"
cgame="http://svn.jorgepena.be/tipsrc/trunk/code/win32/msvc/build/release/cgamex86.dll"
qagame="http://svn.jorgepena.be/tipsrc/trunk/code/win32/msvc/build/release/qagamex86.dll"
ui="http://svn.jorgepena.be/tipsrc/trunk/code/win32/msvc/build/release/uix86.dll"
tip="http://svn.jorgepena.be/tipsrc/trunk/code/win32/msvc/build/release/tip.exe"
 
[linux]
binhash="http://svn.jorgepena.be/tipsrc/trunk/hashes/linhash"
cgame="http://svn.jorgepena.be/tipsrc/trunk/build/release-linux-i386/base/cgamei386.so"
qagame="http://svn.jorgepena.be/tipsrc/trunk/build/release-linux-i386/base/qagamei386.so"
ui="http://svn.jorgepena.be/tipsrc/trunk/build/release-linux-i386/base/uii386.so"
tip="http://svn.jorgepena.be/tipsrc/trunk/build/release-linux-i386/tip.i386"
tipded="http://svn.jorgepena.be/tipsrc/trunk/build/release-linux-i386/tipded.i386"
 
[mac]
binhash="http://svn.jorgepena.be/tipsrc/trunk/hashes/machash"
app="http://svn.jorgepena.be/viewvc/viewvc.cgi/trunk/build/release-darwin-ub/tip.app.tar.gz?view=tar"
 
[site]
packages="http://instagib.jorgepena.be/downloads/packages/"
tools="http://instagib.jorgepena.be/downloads/tools/"
dlls="http://svn.jorgepena.be/tipsrc/trunk/code/win32/msvc/build/release/"
exe="http://svn.jorgepena.be/tipsrc/trunk/code/win32/msvc/build/release/tip.exe"
sos="http://svn.jorgepena.be/tipsrc/trunk/build/release-linux-i386/base/"
i386s="http://svn.jorgepena.be/tipsrc/trunk/build/release-linux-i386/"
Personal tools