Source code for PyPoE.poe.path
"""
Overview
===============================================================================
+----------+------------------------------------------------------------------+
| Path | PyPoE/poe/path.py |
+----------+------------------------------------------------------------------+
| Version | 1.0.0a0 |
+----------+------------------------------------------------------------------+
| Revision | $Id: e0133d976e9bec360dd743009b66a7f719090a8b $ |
+----------+------------------------------------------------------------------+
| Author | Omega_K2 |
+----------+------------------------------------------------------------------+
Description
===============================================================================
Utilities for retrieving Path of Exile related paths.
Agreement
===============================================================================
See PyPoE/LICENSE
Documentation
===============================================================================
.. autoclass:: PoEPath
:special-members: __init__
"""
# =============================================================================
# Imports
# =============================================================================
# Python
import sys
import os
try:
import winreg
except ImportError:
winreg = None
# self
from PyPoE.poe.constants import VERSION, DISTRIBUTOR
# =============================================================================
# Globals
# =============================================================================
__all__ = ['PoEPath']
# =============================================================================
# Classes
# =============================================================================
class PoEPathList(list):
"""
Special list object to make managing list objects easier.
Only PoEPathValue objects are appended by PoEPath, but it can be otherwise
used just like a regular list.
It addition it performs existence checks on the items added by default.
"""
def __init__(self, only_existing=True):
self._only_existing = True
def append(self, path, version, distributor):
if path is None:
return
# Will fix wrong slashes in registry
path = os.path.realpath(path)
if self._only_existing and not os.path.exists(path):
return
list.append(self, PoEPathValue(path, version, distributor))
class PoEPathValue(str):
def __new__(self, path, version, distributor):
"""
Parameters
----------
path : str
Path to the base path of exile folder
version : VERSION
Combination of PoEPath VERSION
distributor : DISTRIBUTOR
Combination of PoEPath DISTRIBUTOR values
"""
self.path = path
self.version = version
self.distributor = distributor
return str.__new__(self, path)
[docs]class PoEPath(object):
"""
Class for retrieving default paths related to path of exile.
.. warning::
Currently this only works on the Windows platform, as there is no
official Path of Exile client on Linux.
"""
[docs] def __init__(self, version=VERSION.DEFAULT, distributor=DISTRIBUTOR.DEFAULT):
"""
Change the version or distributor if you only watch to search for
specific installations.
Parameters
----------
version : VERSION
Combination of :class:`PyPoE.poe.constants.VERSION` constants
distributor : DISTRIBUTOR
Combination of :class:`PyPoE.poe.constants.DISTRIBUTOR` constants
"""
self.version = version
self.distributor = distributor
def _get_winreg_path(self, regpath, regkey, user=True):
if user:
key = winreg.HKEY_CURRENT_USER
else:
key = winreg.HKEY_LOCAL_MACHINE
try:
obj = winreg.OpenKey(key, regpath)
path = winreg.QueryValueEx(obj, regkey)[0]
obj.Close()
# missing key raises FileNotFoundError
except FileNotFoundError:
return None
return path
[docs] def get_installation_paths(self, only_existing=True):
"""
Returns a PoEPathList instance containing PoEPathValues depending on
the version and distributor values set on class construction.
Parameters
----------
only_existing : bool
If True, only existing directory will be returned.
Returns
-------
list
returns a PoEPathList containing PoEPathValues
"""
paths = PoEPathList(only_existing)
# Currently PoE only runs on windows
if sys.platform != 'win32':
return paths
# TODO: Possibly find a way to reduce this spaghetti like code
if self.distributor & DISTRIBUTOR.GGG:
for item in (
(r'Software\GrindingGearGames\Path of Exile', VERSION.STABLE),
(r'Software\GrindingGearGames\Path of Exile - beta', VERSION.BETA),
(r'Software\GrindingGearGames\Path of Exile - Alpha',
VERSION.ALPHA)
):
if self.version & item[1]:
basepath = self._get_winreg_path(item[0], 'InstallLocation')
paths.append(basepath, item[1], DISTRIBUTOR.GGG)
if self.distributor & DISTRIBUTOR.STEAM:
basepath = self._get_winreg_path(r'Software\Valve\Steam',
'SteamPath')
# Steam does have a beta, but it is installed into the same directory
# AFAIK, there is no safe way to determine which is installed
# unless we hook into steam
if basepath and self.version ^ VERSION.ALL:
# Steam Common folder
basepath = os.path.join(basepath, 'SteamApps', 'common')
# Seems to be both beta, and live folder
basepath = os.path.join(basepath, 'Path of Exile')
paths.append(basepath, VERSION.ALL, DISTRIBUTOR.STEAM)
if self.distributor & DISTRIBUTOR.GARENA:
if self.version & VERSION.STABLE:
basepath = self._get_winreg_path(
r'SOFTWARE\Wow6432Node\Garena\PoE',
'Path',
user=False
)
paths.append(basepath, VERSION.STABLE, DISTRIBUTOR.GARENA)
return paths