New layout - REVIEW

- utilities.py and record_groups.py:
      Mopy/bash/patcher/oblivion/utilities.py -> Mopy/bash/patcher/utilities.py
      Mopy/bash/patcher/oblivion/record_groups.py -> Mopy/bash/patcher/record_groups.py

 Those two may be moved further up - not patcher specific (see #124).

- Mopy/bash/patcher/oblivion/patchers/* -> Mopy/bash/patcher/patchers/*
  Final ?

modified:   Mopy/bash/basher.py
modified:   Mopy/bash/bish.py
modified:   Mopy/bash/bosh.py
renamed:    Mopy/bash/patcher/oblivion/patchers/__init__.py -> Mopy/bash/patcher/patchers/__init__.py
renamed:    Mopy/bash/patcher/oblivion/patchers/base.py -> Mopy/bash/patcher/patchers/base.py
renamed:    Mopy/bash/patcher/oblivion/patchers/importers.py -> Mopy/bash/patcher/patchers/importers.py
renamed:    Mopy/bash/patcher/oblivion/patchers/multitweak_actors.py -> Mopy/bash/patcher/patchers/multitweak_actors.py
renamed:    Mopy/bash/patcher/oblivion/patchers/multitweak_assorted.py -> Mopy/bash/patcher/patchers/multitweak_assorted.py
renamed:    Mopy/bash/patcher/oblivion/patchers/multitweak_clothes.py -> Mopy/bash/patcher/patchers/multitweak_clothes.py
renamed:    Mopy/bash/patcher/oblivion/patchers/multitweak_names.py -> Mopy/bash/patcher/patchers/multitweak_names.py
renamed:    Mopy/bash/patcher/oblivion/patchers/multitweak_settings.py -> Mopy/bash/patcher/patchers/multitweak_settings.py
renamed:    Mopy/bash/patcher/oblivion/patchers/races_multitweaks.py -> Mopy/bash/patcher/patchers/races_multitweaks.py
renamed:    Mopy/bash/patcher/oblivion/patchers/special.py -> Mopy/bash/patcher/patchers/special.py
renamed:    Mopy/bash/patcher/oblivion/record_groups.py -> Mopy/bash/patcher/record_groups.py
renamed:    Mopy/bash/patcher/oblivion/utilities.py -> Mopy/bash/patcher/utilities.py
SpecialPatcher(object) + MI for common code in special patchers:

Check TODOs
game/oblivion/patcher package - notice specific game import in basher.py

Under #124

I had to rename the module to 'patcher' - good name ?

    Wrye Bash starting
    Using Wrye Bash Version 306
    Python version: 2.7.8
    wxPython version: 2.8.12.1 (msw-unicode)
    input encoding: None; output encoding: None; locale: ('el_GR', 'cp1253')
    Searching for game to manage:
    bush.py   81 detectGames: Detected the following supported games via Windows Registry:
    bush.py   83 detectGames:  oblivion: C:\GAMES\TESIV\Oblivion
    bush.py   95 detectGames: Detecting games via relative path and the -o argument:
    bush.py  144 setGame: No preferred game specified.
    bush.py   81 detectGames: Detected the following supported games via Windows Registry:
    bush.py   83 detectGames:  oblivion: C:\GAMES\TESIV\Oblivion
    bush.py   95 detectGames: Detecting games via relative path and the -o argument:
    bush.py  133 setGame: Specified game "oblivion" was found: C:\GAMES\TESIV\Oblivion
    testing UAC
    bosh.py 5542 __init__: Using libbsa API version: 2.0.0
    bosh.py 5548 __init__: Using libloadorder API version: 4.0.1
    bosh.py 5554 __init__: Using LOOT API version: 0.6.0
    C:\GAMES\TESIV\Oblivion
    basher.py  139 <module>: Comtypes is missing, features utilizing HTML will be disabled
    Traceback (most recent call last):
      File "Wrye Bash Launcher.pyw", line 87, in <module>
        bash.main()
      File "bash\bash.py", line 573, in main
        basher.InitSettings()
      File "bash\basher.py", line 17746, in InitSettings
        initPatchers()
      File "bash\basher.py", line 8129, in initPatchers
        globals()[x]() for x in bush.game.patchers
    TypeError: 'module' object is not iterable

--------------------------------------------------------------------------------
Notice: bush detection goes in cycles - at some point I got:

Wrye Bash starting
Using Wrye Bash Version 306
Python version: 2.7.8
wxPython version: 2.8.12.1 (msw-unicode)
input encoding: None; output encoding: None; locale: ('el_GR', 'cp1253')
Searching for game to manage:
bush.py   81 detectGames: Detected the following supported games via Windows Registry:
bush.py   83 detectGames:  oblivion: C:\GAMES\TESIV\Oblivion
bush.py   95 detectGames: Detecting games via relative path and the -o argument:
bush.py  144 setGame: No preferred game specified.
bush.py   81 detectGames: Detected the following supported games via Windows Registry:
bush.py   83 detectGames:  oblivion: C:\GAMES\TESIV\Oblivion
bush.py   95 detectGames: Detecting games via relative path and the -o argument:
bush.py  133 setGame: Specified game "oblivion" was found: C:\GAMES\TESIV\Oblivion
testing UAC
bush.py   81 detectGames: Detected the following supported games via Windows Registry:
bush.py   83 detectGames:  oblivion: C:\GAMES\TESIV\Oblivion
bush.py   95 detectGames: Detecting games via relative path and the -o argument:
bush.py  101 detectGames:  oblivion: C:\GAMES\TESIV\Oblivion
bush.py  144 setGame: No preferred game specified.
bush.py  151 setGame:  Using oblivion game: C:\GAMES\TESIV\Oblivion
bush.py   81 detectGames: Detected the following supported games via Windows Registry:
bush.py   83 detectGames:  oblivion: C:\GAMES\TESIV\Oblivion
bush.py   95 detectGames: Detecting games via relative path and the -o argument:
bush.py  101 detectGames:  oblivion: C:\GAMES\TESIV\Oblivion
bush.py  144 setGame: No preferred game specified.
bush.py  151 setGame:  Using oblivion game: C:\GAMES\TESIV\Oblivion
fail bash\game\oblivion\patchers\special.py
fail bash\basher.py
Traceback (most recent call last):
  File "Wrye Bash Launcher.pyw", line 87, in <module>
    bash.main()
  File "bash\bash.py", line 484, in main
    raise e
bash.bolt.BoltError: Error creating required Wrye Bash directories.  Please check the settings for the following paths in your bash.ini, the drive does not exist:

[General] sOblivionMods
    F:\Oblivion Mods2
Oblivion imports in Basher - dynamically create UI patcher classes - REVIEW
Rest of oblivion specific special patchers moved to oblivion/special.py module:

Squash of:

- CoblExhaustion moved to oblivion special patchers module (+ a newline)
- MFactMarker moved to oblivion special patchers module
- SEWorldEnforcer moved to oblivion special patchers module
- Fixup:
  Notice though that the CBash patchers worked just fine - TODO: check this
  The problem was that isActive was false -
          self.srcFiles = self.getConfigChecked() # this was empty
          # so this below was False
          self.isActive = bool(self.srcFiles) and (
              self.cobl in loadMods and bosh.modInfos.getVersionFloat(
                  self.cobl) > 1.65)
  The code in the CBash_CoblExhaustion patcher was:

          self.isActive = (self.cobl in loadMods and
                           bosh.modInfos.getVersionFloat(self.cobl) > 1.65)
  and loadMods is passed as a parameter - more robust apparently

  ----------------------------- Mopy/bash/basher.py -----------------------------
  index 38ff67b..9906e0a 100644
  @@ -8178,3 +8178,3 @@ class CBash_ContentsChecker(CBash_ContentsChecker,Patcher): pass
                          package=bush.game.__name__)
  -for name, typeInfo in gamePatcher.game_specific.items():
  +for name, typeInfo in gamePatcher.gameSpecificPatchers.items():
       globals()[name] = type(name, (typeInfo[0], Patcher), {})
  @@ -8183,2 +8183,7 @@ class CBash_ContentsChecker(CBash_ContentsChecker,Patcher): pass
           # get otherPatcherDict purpose
  +for name, typeInfo in gamePatcher.gameSpecificListPatchers.items():
  +    globals()[name] = type(name, (typeInfo[0], ListPatcher), {})
  +    if typeInfo[1]:
  +        otherPatcherDict[name] = typeInfo[1]() # TODO: works ? - I don't really
  +        # get otherPatcherDict purpose

  ----------------- Mopy/bash/game/oblivion/patcher/__init__.py -----------------
  index 93671dd..dc961db 100644
  @@ -29,3 +29,3 @@

  -game_specific = {
  +gameSpecificPatchers = {
       # special
  @@ -33,2 +33,6 @@
       "CBash_AlchemicalCatalogs": (CBash_AlchemicalCatalogs, AlchemicalCatalogs),
  +    "SEWorldEnforcer": (SEWorldEnforcer, CBash_SEWorldEnforcer),
  +    "CBash_SEWorldEnforcer": (CBash_SEWorldEnforcer, SEWorldEnforcer),
  +    }
  +gameSpecificListPatchers = {
       "CoblExhaustion": (CoblExhaustion, CBash_CoblExhaustion),
  @@ -37,4 +41,2 @@
       "CBash_MFactMarker": (CBash_MFactMarker, MFactMarker),
  -    "SEWorldEnforcer": (SEWorldEnforcer, CBash_SEWorldEnforcer),
  -    "CBash_SEWorldEnforcer": (CBash_SEWorldEnforcer, SEWorldEnforcer),
       }

  ------------------ Mopy/bash/game/skyrim/patcher/__init__.py ------------------
  index 122cabc..0aed459 100644
  @@ -28,2 +28,3 @@

  -game_specific = {}
  +gameSpecificPatchers = {}
  +gameSpecificListPatchers = {}
Merge branch 'utumno-layout' into dev - REVIEW:

This merge is an attempt to define the patcher layout as discussed in
#124. Also makes SpecialPatcher an object subclass and moves oblivion
specific patchers in a game.oblivion.patcher package. Review:

091bd592a73e72c72763677fa6272486cd80f80d: layout commit
10ca05fee73c4de206feaa31bab30333694ed818: SpecialPatcher(object)
fd73d1897d10f155fb933f2a74dd7e03d181f099: bush game init cycles
6f56335c161ccfeb9449abe75310422df105d3d9: dynamically create UI patchers