umu-commander 1.4.0__py3-none-any.whl → 1.5.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of umu-commander might be problematic. Click here for more details.

umu_commander/classes.py CHANGED
@@ -1,14 +1,25 @@
1
1
  from dataclasses import dataclass
2
+ from enum import Enum
2
3
 
3
4
 
4
- # analogous to Proton version
5
5
  @dataclass
6
6
  class Element:
7
7
  group_id: str = ""
8
8
  value: str = ""
9
9
  info: str = ""
10
10
 
11
- # proton terminology for convenience
11
+ def as_proton_ver(self) -> "ProtonVer":
12
+ return ProtonVer(self.group_id, self.value, self.info)
13
+
14
+ def as_dll_override(self) -> "DLLOverride":
15
+ return DLLOverride(self.info, self.value)
16
+
17
+
18
+ @dataclass
19
+ class ProtonVer(Element):
20
+ def __init__(self, dir: str = "", version_num: str = "", user_count: str = ""):
21
+ super().__init__(group_id=dir, value=version_num, info=user_count)
22
+
12
23
  @property
13
24
  def dir(self):
14
25
  return self.group_id
@@ -21,23 +32,50 @@ class Element:
21
32
  def user_count(self):
22
33
  return self.info
23
34
 
24
- @user_count.setter
25
- def user_count(self, value):
26
- self.info = value
35
+
36
+ @dataclass
37
+ class DLLOverride(Element):
38
+ def __init__(self, label: str = "", override_str: str = ""):
39
+ super().__init__(group_id="", value=override_str, info=label)
40
+
41
+ @property
42
+ def override_str(self):
43
+ return self.value
44
+
45
+ @property
46
+ def label(self):
47
+ return self.info
48
+
49
+
50
+ @dataclass
51
+ class Value(Element):
52
+ def __init__(self, value: str):
53
+ super().__init__(value=value)
27
54
 
28
55
 
29
- # analogous to Proton directory
30
56
  @dataclass
31
57
  class Group:
32
58
  identity: str = ""
33
59
  label: str = ""
34
60
  elements: list[Element] = list
35
61
 
36
- # proton terminology for convenience
62
+
63
+ @dataclass
64
+ class ProtonDir(Group):
37
65
  @property
38
66
  def path(self):
39
67
  return self.identity
40
68
 
41
69
  @property
42
- def versions(self):
43
- return self.elements
70
+ def versions(self) -> list[ProtonVer]:
71
+ return [e.as_proton_ver() for e in self.elements]
72
+
73
+ @versions.setter
74
+ def versions(self, value):
75
+ self.elements = value
76
+
77
+
78
+ class ExitCode(Enum):
79
+ SUCCESS = 0
80
+ READING_ERROR = 1
81
+ INVALID_SELECTION = 2
@@ -1,22 +1,72 @@
1
1
  import os
2
+ import tomllib
2
3
  from pathlib import Path
3
4
 
4
- from umu_commander.classes import Element
5
-
6
- PROTON_DIRS: list[str] = [
7
- os.path.join(Path.home(), ".local/share/Steam/compatibilitytools.d/"),
8
- os.path.join(Path.home(), ".local/share/umu/compatibilitytools"),
9
- ]
10
- # where UMU saves its UMU-Proton versions
11
- UMU_PROTON_DIR: str = os.path.join(
12
- Path.home(), ".local/share/Steam/compatibilitytools.d/"
13
- )
14
- DB_NAME: str = "tracking.json"
15
- DB_DIR: str = os.path.join(Path.home(), ".local/share/umu/compatibilitytools")
16
- CONFIG_NAME: str = "umu-config.toml"
17
- # default WINE prefix directory
18
- PREFIX_DIR: str = os.path.join(Path.home(), ".local/share/wineprefixes/")
19
- # Label, override string, follow the example
20
- DLL_OVERRIDES_OPTIONS: list[Element] = [
21
- Element(info="winhttp for BepInEx", value="winhttp.dll=n;")
22
- ]
5
+ import tomli_w
6
+
7
+ from umu_commander.classes import DLLOverride
8
+
9
+ CONFIG_DIR: str = os.path.join(Path.home(), ".config")
10
+ CONFIG_NAME: str = "umu-commander.toml"
11
+
12
+
13
+ class Configuration:
14
+ PROTON_PATHS: tuple[str, ...] = (
15
+ os.path.join(Path.home(), ".local/share/Steam/compatibilitytools.d/"),
16
+ os.path.join(Path.home(), ".local/share/umu/compatibilitytools"),
17
+ )
18
+ UMU_PROTON_PATH: str = os.path.join(
19
+ Path.home(), ".local/share/Steam/compatibilitytools.d/"
20
+ )
21
+ DB_NAME: str = "tracking.json"
22
+ DB_DIR: str = os.path.join(Path.home(), ".local/share/umu/compatibilitytools")
23
+ UMU_CONFIG_NAME: str = "umu-config.toml"
24
+ DEFAULT_PREFIX_DIR: str = os.path.join(Path.home(), ".local/share/wineprefixes/")
25
+ DLL_OVERRIDES_OPTIONS: tuple[DLLOverride, ...] = (
26
+ DLLOverride("winhttp for BepInEx", "winhttp.dll=n;"),
27
+ )
28
+
29
+ @staticmethod
30
+ def load():
31
+ try:
32
+ with open(os.path.join(CONFIG_DIR, CONFIG_NAME), "rb") as conf_file:
33
+ toml_conf = tomllib.load(conf_file)
34
+ toml_conf["DLL_OVERRIDES_OPTIONS"] = tuple(
35
+ [
36
+ DLLOverride(label, override_str)
37
+ for label, override_str in toml_conf[
38
+ "DLL_OVERRIDES_OPTIONS"
39
+ ].items()
40
+ ]
41
+ )
42
+
43
+ for key, value in toml_conf.items():
44
+ setattr(Configuration, key, value)
45
+
46
+ except FileNotFoundError:
47
+ Configuration.dump()
48
+
49
+ @staticmethod
50
+ def dump():
51
+ if not os.path.exists(CONFIG_DIR):
52
+ os.mkdir(CONFIG_DIR)
53
+
54
+ with open(os.path.join(CONFIG_DIR, CONFIG_NAME), "wb") as conf_file:
55
+ toml_conf = Configuration._get_attributes()
56
+ toml_conf["DLL_OVERRIDES_OPTIONS"] = dict(
57
+ [
58
+ (override.info, override.value)
59
+ for override in Configuration.DLL_OVERRIDES_OPTIONS
60
+ ]
61
+ )
62
+
63
+ tomli_w.dump(toml_conf, conf_file)
64
+
65
+ @staticmethod
66
+ def _get_attributes():
67
+ attributes = {}
68
+ for key, value in vars(Configuration).items():
69
+ if not key.startswith("__") and not callable(getattr(Configuration, key)):
70
+ attributes[key] = value
71
+
72
+ return attributes
@@ -0,0 +1,43 @@
1
+ import json
2
+ import os
3
+ from collections import defaultdict
4
+
5
+ from umu_commander.configuration import Configuration as config
6
+
7
+
8
+ class Database:
9
+ _db: defaultdict[str, defaultdict[str, list[str]]]
10
+
11
+ @staticmethod
12
+ def load():
13
+ if not os.path.exists(config.DB_DIR):
14
+ os.mkdir(config.DB_DIR)
15
+
16
+ try:
17
+ with open(os.path.join(config.DB_DIR, config.DB_NAME), "rt") as db_file:
18
+ Database._db = defaultdict(lambda: defaultdict(list))
19
+ Database._db.update(json.load(db_file))
20
+
21
+ except FileNotFoundError:
22
+ Database._db = defaultdict(lambda: defaultdict(list))
23
+
24
+ @staticmethod
25
+ def dump():
26
+ with open(os.path.join(config.DB_DIR, config.DB_NAME), "wt") as db_file:
27
+ # noinspection PyTypeChecker
28
+ json.dump(Database._db, db_file, indent="\t")
29
+
30
+ @staticmethod
31
+ def get(
32
+ proton_dir: str = None, proton_ver: str = None
33
+ ) -> dict[str, dict[str, list[str]]] | dict[str, list[str]] | list[str]:
34
+ if proton_dir is None and proton_ver is None:
35
+ return Database._db
36
+
37
+ if proton_ver is None:
38
+ return Database._db[proton_dir]
39
+
40
+ if proton_ver not in Database._db[proton_dir]:
41
+ Database._db[proton_dir][proton_ver] = []
42
+
43
+ return Database._db[proton_dir][proton_ver]
umu_commander/main.py CHANGED
@@ -1,9 +1,13 @@
1
1
  #!/usr/bin/python3
2
+ import os
2
3
  import sys
3
4
  from json import JSONDecodeError
4
5
 
5
- from umu_commander import db, tracking, umu_config
6
- from umu_commander.configuration import *
6
+ from umu_commander import tracking, umu_config
7
+ from umu_commander.classes import ExitCode
8
+ from umu_commander.configuration import CONFIG_DIR, CONFIG_NAME
9
+ from umu_commander.configuration import Configuration as config
10
+ from umu_commander.database import Database as db
7
11
 
8
12
 
9
13
  def print_help():
@@ -15,16 +19,24 @@ def print_help():
15
19
  )
16
20
 
17
21
 
18
- def main() -> int:
22
+ def main() -> ExitCode:
23
+ try:
24
+ config.load()
25
+ except (JSONDecodeError, KeyError):
26
+ config_path: str = os.path.join(CONFIG_DIR, CONFIG_NAME)
27
+ print(f"Config file at {config_path} could not be read.")
28
+ os.rename(config_path, os.path.join(CONFIG_DIR, CONFIG_NAME + ".old"))
29
+
19
30
  try:
20
31
  db.load()
21
32
  except JSONDecodeError:
22
- print(f"Tracking file at {os.path.join(DB_DIR, DB_NAME)} could not be read.")
23
- return 2
33
+ db_path: str = os.path.join(config.DB_DIR, config.DB_NAME)
34
+ print(f"Tracking file at {db_path} could not be read.")
35
+ os.rename(db_path, os.path.join(config.DB_DIR, config.DB_NAME + ".old"))
24
36
 
25
37
  if len(sys.argv) == 1:
26
38
  print_help()
27
- return 0
39
+ return ExitCode.SUCCESS
28
40
 
29
41
  verb: str = sys.argv[1]
30
42
  match verb:
@@ -43,13 +55,14 @@ def main() -> int:
43
55
  case _:
44
56
  print("Invalid verb.")
45
57
  print_help()
46
- return 3
58
+ return ExitCode.INVALID_SELECTION
47
59
 
48
60
  tracking.untrack_unlinked()
49
61
  db.dump()
62
+ config.dump()
50
63
 
51
- return 0
64
+ return ExitCode.SUCCESS
52
65
 
53
66
 
54
67
  if __name__ == "__main__":
55
- exit(main())
68
+ exit(main().value)
umu_commander/proton.py CHANGED
@@ -2,12 +2,13 @@ import os
2
2
  import re
3
3
  import subprocess
4
4
 
5
- from umu_commander.classes import Element, Group
6
- from umu_commander.configuration import DB_NAME, PROTON_DIRS, UMU_PROTON_DIR
5
+ from umu_commander.classes import ProtonDir, ProtonVer
6
+ from umu_commander.configuration import Configuration as config
7
+ from umu_commander.database import Database as db
7
8
 
8
9
 
9
- def _natural_sort_proton_ver_key(e: Element, _nsre=re.compile(r"(\d+)")):
10
- s: str = e.value
10
+ def _natural_sort_proton_ver_key(p: ProtonVer, _nsre=re.compile(r"(\d+)")):
11
+ s: str = p.version_num
11
12
  return [int(text) if text.isdigit() else text for text in _nsre.split(s)]
12
13
 
13
14
 
@@ -31,33 +32,48 @@ def refresh_proton_versions():
31
32
  break
32
33
 
33
34
 
34
- def _sort_proton_versions(versions: list[Element]) -> list[Element]:
35
+ def _sort_proton_versions(versions: list[ProtonVer]) -> list[ProtonVer]:
35
36
  return sorted(versions, key=_natural_sort_proton_ver_key, reverse=True)
36
37
 
37
38
 
38
- def collect_proton_versions(sort: bool = False) -> list[Group]:
39
- version_groups: list[Group] = []
40
- for proton_dir in PROTON_DIRS:
41
- versions: list[Element] = [
42
- Element(proton_dir, version, "")
39
+ def collect_proton_versions(
40
+ sort: bool = False, user_count: bool = False
41
+ ) -> list[ProtonDir]:
42
+ def get_user_count(proton_dir: str, proton_ver) -> str:
43
+ return (
44
+ "(" + str(len(db.get(proton_dir, proton_ver))) + ")"
45
+ if proton_ver in db.get(proton_dir)
46
+ else "(-)"
47
+ )
48
+
49
+ proton_dirs: list[ProtonDir] = []
50
+ for proton_dir in config.PROTON_PATHS:
51
+ versions: list[ProtonVer] = [
52
+ ProtonVer(
53
+ proton_dir,
54
+ version,
55
+ get_user_count(proton_dir, version) if user_count else "",
56
+ )
43
57
  for version in os.listdir(proton_dir)
44
- if version != DB_NAME
58
+ if os.path.isdir(os.path.join(proton_dir, version))
45
59
  ]
60
+
46
61
  if sort:
47
62
  versions = sorted(versions, key=_natural_sort_proton_ver_key, reverse=True)
48
63
 
49
- version_groups.append(
50
- Group(proton_dir, f"Proton versions in {proton_dir}:", versions)
64
+ proton_dirs.append(
65
+ ProtonDir(proton_dir, f"Proton versions in {proton_dir}:", versions)
51
66
  )
52
67
 
53
- return version_groups
68
+ return proton_dirs
54
69
 
55
70
 
56
71
  def get_latest_umu_proton():
57
- umu_proton_versions: list[Element] = [
58
- Element(UMU_PROTON_DIR, version, "")
59
- for version in os.listdir(UMU_PROTON_DIR)
60
- if "UMU" in version and version != DB_NAME
72
+ umu_proton_versions: list[ProtonVer] = [
73
+ ProtonVer(config.UMU_PROTON_PATH, version)
74
+ for version in os.listdir(config.UMU_PROTON_PATH)
75
+ if "UMU" in version
76
+ and os.path.isdir(os.path.join(config.UMU_PROTON_PATH, version))
61
77
  ]
62
78
  umu_proton_versions = sorted(
63
79
  umu_proton_versions, key=_natural_sort_proton_ver_key, reverse=True
umu_commander/tracking.py CHANGED
@@ -1,8 +1,8 @@
1
+ import os
1
2
  import shutil
2
3
 
3
- from umu_commander import db
4
- from umu_commander.classes import Group
5
- from umu_commander.configuration import *
4
+ from umu_commander.classes import ProtonDir, ProtonVer
5
+ from umu_commander.database import Database as db
6
6
  from umu_commander.proton import (
7
7
  collect_proton_versions,
8
8
  get_latest_umu_proton,
@@ -15,55 +15,49 @@ from umu_commander.util import (
15
15
 
16
16
  def untrack(quiet: bool = False):
17
17
  current_dir: str = os.getcwd()
18
- for proton_dir in db.copy().keys():
18
+ for proton_dir in db.get().keys():
19
19
  for proton_ver in db.get(proton_dir):
20
- db.remove_from(proton_dir, proton_ver, current_dir)
20
+ if current_dir in db.get(proton_dir, proton_ver):
21
+ db.get(proton_dir, proton_ver).remove(current_dir)
21
22
 
22
23
  if not quiet:
23
24
  print("Directory removed from all user lists.")
24
25
 
25
26
 
26
- def track(proton: Element = None, refresh_versions: bool = True, quiet: bool = False):
27
+ def track(
28
+ proton_ver: ProtonVer = None, refresh_versions: bool = True, quiet: bool = False
29
+ ):
27
30
  if refresh_versions:
28
31
  refresh_proton_versions()
29
32
 
30
- if proton is None:
31
- proton: Element = get_selection(
33
+ if proton_ver is None:
34
+ proton_ver: ProtonVer = get_selection(
32
35
  "Select Proton version to add directory as user:",
33
36
  None,
34
37
  collect_proton_versions(sort=True),
35
- )
38
+ ).as_proton_ver()
36
39
 
37
40
  untrack(quiet=True)
38
41
  current_directory: str = os.getcwd()
39
- db.add_to(proton.dir, proton.version_num, current_directory)
42
+ db.get(proton_ver.dir, proton_ver.version_num).append(current_directory)
40
43
 
41
44
  if not quiet:
42
45
  print(
43
- f"Directory {current_directory} added to Proton version's {proton.version_num} in {proton.dir} user list."
46
+ f"Directory {current_directory} added to Proton version's {proton_ver.version_num} in {proton_ver.dir} user list."
44
47
  )
45
48
 
46
49
 
47
50
  def users():
48
- proton_version_dirs: list[Group] = collect_proton_versions(sort=True)
49
-
50
- for proton_dir in proton_version_dirs:
51
- for proton in proton_dir.versions:
52
- if proton.version_num in db.get(proton.dir):
53
- proton.user_count = (
54
- "(" + str(len(db.get(proton.dir, proton.version_num))) + ")"
55
- )
56
- else:
57
- proton.user_count = "(-)"
51
+ proton_dirs: list[ProtonDir] = collect_proton_versions(sort=True, user_count=True)
58
52
 
59
- proton: Element = get_selection(
60
- "Select Proton version to view user list:", None, proton_version_dirs
61
- )
53
+ proton_ver: ProtonVer = get_selection(
54
+ "Select Proton version to view user list:", None, proton_dirs
55
+ ).as_proton_ver()
62
56
 
63
- if proton.dir in db.copy() and proton.version_num in db.get(proton.dir):
64
- version_users: list[str] = db.get(proton.dir, proton.version_num)
57
+ if proton_ver.dir in db.get() and proton_ver.version_num in db.get(proton_ver.dir):
58
+ version_users: list[str] = db.get(proton_ver.dir, proton_ver.version_num)
65
59
  if len(version_users) > 0:
66
- print(f"Directories using {proton.version_num} of {proton.dir}:")
60
+ print(f"Directories using {proton_ver.version_num} of {proton_ver.dir}:")
67
61
  print(*version_users, sep="\n")
68
62
  else:
69
63
  print("No directories currently use this version.")
@@ -72,7 +66,7 @@ def users():
72
66
 
73
67
 
74
68
  def delete():
75
- for proton_dir in db.copy().keys():
69
+ for proton_dir in db.get().keys():
76
70
  for proton_ver, version_users in db.get(proton_dir).copy().items():
77
71
  if proton_ver == get_latest_umu_proton():
78
72
  continue
@@ -86,12 +80,12 @@ def delete():
86
80
  shutil.rmtree(os.path.join(proton_dir, proton_ver))
87
81
  except FileNotFoundError:
88
82
  pass
89
- db.delete(proton_dir, proton_ver)
83
+ del db.get(proton_dir)[proton_ver]
90
84
 
91
85
 
92
86
  def untrack_unlinked():
93
- for proton_dir in db.copy().keys():
94
- for proton_ver, version_users in db.get(proton_dir).items():
87
+ for proton_dir in db.get().keys():
88
+ for proton_ver, version_users in db.get()[proton_dir].items():
95
89
  for user in version_users:
96
90
  if not os.path.exists(user):
97
- db.remove_from(proton_dir, proton_ver, user)
91
+ db.get(proton_dir, proton_ver).remove(user)
@@ -1,67 +1,56 @@
1
+ import os
1
2
  import subprocess
2
3
  import tomllib
3
- from collections.abc import Mapping
4
4
  from typing import Any
5
5
 
6
+ import tomli_w
7
+
6
8
  from umu_commander import tracking
7
- from umu_commander.configuration import *
9
+ from umu_commander.classes import DLLOverride, ProtonVer
10
+ from umu_commander.configuration import Configuration as config
8
11
  from umu_commander.proton import collect_proton_versions, refresh_proton_versions
9
12
  from umu_commander.util import (
10
13
  get_selection,
11
- values_to_elements,
14
+ strings_to_values,
12
15
  )
13
16
 
14
17
 
15
- def _write(params: Mapping[str, Any]):
16
- config: str = "[umu]\n"
17
- for key in set(params.keys()) - {"env", "launch_args"}:
18
- config += f'{key} = "{params[key]}"\n'
19
-
20
- config += f"launch_args = {params["launch_args"]}\n"
21
-
22
- config += "\n[env]\n"
23
- for key, value in params["env"].items():
24
- config += f'{key} = "{value}"\n'
25
-
26
- config_file = open(CONFIG_NAME, "wt")
27
- config_file.write(config)
28
- config_file.close()
29
-
30
-
31
18
  def create():
32
19
  refresh_proton_versions()
33
20
 
34
- params: dict[str, Any] = {"env": {}}
21
+ params: dict[str, Any] = {"umu": {}, "env": {}}
35
22
 
36
23
  # Prefix selection
37
24
  selection: str = get_selection(
38
25
  "Select wine prefix:",
39
- values_to_elements([*os.listdir(PREFIX_DIR), "Current directory"]),
26
+ strings_to_values(
27
+ [*os.listdir(config.DEFAULT_PREFIX_DIR), "Current directory"]
28
+ ),
40
29
  None,
41
30
  ).value
42
31
 
43
32
  if selection == "Current directory":
44
- params["prefix"] = os.path.join(os.getcwd(), "prefix")
33
+ params["umu"]["prefix"] = os.path.join(os.getcwd(), "prefix")
45
34
  else:
46
- params["prefix"] = os.path.join(PREFIX_DIR, selection)
35
+ params["umu"]["prefix"] = os.path.join(config.DEFAULT_PREFIX_DIR, selection)
47
36
 
48
37
  # Proton selection
49
38
  selected_umu_latest: bool = False
50
- proton: Element = get_selection(
39
+ proton_ver: ProtonVer = get_selection(
51
40
  "Select Proton version:",
52
- values_to_elements(["Always latest UMU Proton"]),
53
- [*collect_proton_versions(sort=True)],
54
- )
55
- if proton.value == "Always latest UMU Proton":
41
+ strings_to_values(["Always latest UMU Proton"]),
42
+ collect_proton_versions(sort=True),
43
+ ).as_proton_ver()
44
+ if proton_ver.version_num == "Always latest UMU Proton":
56
45
  selected_umu_latest = True
57
46
  else:
58
- params["proton"] = os.path.join(proton.dir, proton.version_num)
47
+ params["umu"]["proton"] = os.path.join(proton_ver.dir, proton_ver.version_num)
59
48
 
60
49
  # Select DLL overrides
61
- possible_overrides: list[Element] = [
62
- Element(info="Reset"),
63
- Element(info="Done"),
64
- *DLL_OVERRIDES_OPTIONS,
50
+ possible_overrides: list[DLLOverride] = [
51
+ DLLOverride(label="Reset"),
52
+ DLLOverride(label="Done"),
53
+ *config.DLL_OVERRIDES_OPTIONS,
65
54
  ]
66
55
  selected: set[int] = set()
67
56
  while True:
@@ -69,7 +58,7 @@ def create():
69
58
  for idx, override in enumerate(possible_overrides):
70
59
  if idx in selected:
71
60
  idx = "Y"
72
- print(f"{idx}) {override.info}")
61
+ print(f"{idx}) {override.label}")
73
62
 
74
63
  try:
75
64
  index: int = int(input("? "))
@@ -92,12 +81,14 @@ def create():
92
81
  params["env"]["WINEDLLOVERRIDES"] = ""
93
82
  for selection in selected:
94
83
  # noinspection PyTypeChecker
95
- params["env"]["WINEDLLOVERRIDES"] += possible_overrides[selection].value
84
+ params["env"]["WINEDLLOVERRIDES"] += possible_overrides[
85
+ selection
86
+ ].override_str
96
87
 
97
88
  # Set language locale
98
89
  match get_selection(
99
90
  "Select locale:",
100
- values_to_elements(["Default", "Japanese"]),
91
+ strings_to_values(["Default", "Japanese"]),
101
92
  None,
102
93
  ).value:
103
94
  case "Default":
@@ -109,7 +100,7 @@ def create():
109
100
  launch_args: list[str] = input(
110
101
  "Enter executable options, separated by spaces:\n? "
111
102
  ).split()
112
- params["launch_args"] = launch_args
103
+ params["umu"]["launch_args"] = launch_args
113
104
 
114
105
  # Select executable name
115
106
  files: list[str] = [
@@ -118,30 +109,31 @@ def create():
118
109
  if os.path.isfile(os.path.join(os.getcwd(), file))
119
110
  ]
120
111
  executable_name: str = get_selection(
121
- "Select game executable:", values_to_elements(files), None
112
+ "Select game executable:", strings_to_values(files), None
122
113
  ).value
123
- params["exe"] = executable_name
114
+ params["umu"]["exe"] = executable_name
124
115
 
125
116
  try:
126
- _write(params)
127
- print(f"Configuration file {CONFIG_NAME} created at {os.getcwd()}.")
117
+ with open(config.UMU_CONFIG_NAME, "wb") as file:
118
+ tomli_w.dump(params, file)
119
+
120
+ print(f"Configuration file {config.UMU_CONFIG_NAME} created at {os.getcwd()}.")
128
121
  print(f"Use by running umu-commander run.")
129
122
  if not selected_umu_latest:
130
- tracking.track(proton, False)
123
+ tracking.track(proton_ver, False)
131
124
  except:
132
- print("Could not create configuration file.")
125
+ print("Could not create configiguration file.")
133
126
 
134
127
 
135
128
  def run():
136
- with open(CONFIG_NAME, "rb") as toml_file:
137
- # noinspection PyTypeChecker
138
- config = tomllib.load(toml_file)
129
+ with open(config.UMU_CONFIG_NAME, "rb") as toml_file:
130
+ toml_conf = tomllib.load(toml_file)
139
131
 
140
- if not os.path.exists(config["umu"]["prefix"]):
141
- os.mkdir(config["umu"]["prefix"])
132
+ if not os.path.exists(toml_conf["umu"]["prefix"]):
133
+ os.mkdir(toml_conf["umu"]["prefix"])
142
134
 
143
- os.environ.update(config.get("env", {}))
135
+ os.environ.update(toml_conf.get("env", {}))
144
136
  subprocess.run(
145
- args=["umu-run", "--config", CONFIG_NAME],
137
+ args=["umu-run", "--config", config.UMU_CONFIG_NAME],
146
138
  env=os.environ,
147
139
  )
umu_commander/util.py CHANGED
@@ -1,9 +1,8 @@
1
- from umu_commander.classes import Group
2
- from umu_commander.configuration import *
1
+ from umu_commander.classes import Element, ExitCode, Group, Value
3
2
 
4
3
 
5
- def values_to_elements(values: list[str]) -> list[Element]:
6
- return [Element(value=value) for value in values]
4
+ def strings_to_values(values: list[str]) -> list[Value]:
5
+ return [Value(value) for value in values]
7
6
 
8
7
 
9
8
  def _selection_set_valid(
@@ -59,7 +58,7 @@ def get_selection(
59
58
  ) -> Element:
60
59
  if not _selection_set_valid(selection_elements, selection_groups):
61
60
  print("Nothing to select from.")
62
- exit(4)
61
+ exit(ExitCode.INVALID_SELECTION)
63
62
 
64
63
  if selection_groups is None:
65
64
  selection_groups = []
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: umu-commander
3
- Version: 1.4.0
3
+ Version: 1.5.2
4
4
  Summary: umu-commander is an interactive CLI tool to help you manage umu.
5
5
  Project-URL: Homepage, https://github.com/Mpaxlamitsounas/umu-commander
6
6
  Project-URL: Issues, https://github.com/Mpaxlamitsounas/umu-commander/issues
@@ -21,7 +21,15 @@ What directories each Proton version is being used by is tracked within `trackin
21
21
 
22
22
  Vanilla umu configuration files currently do not support setting environmental variables, this tool adds such functionality by adding an extra TOML table in the umu config itself. An example config is available under the name `example_config.toml`.
23
23
 
24
- umu-commander will look for your installed Proton versions using a predetermined list of directories, if you notice some versions missing, the listed can be edited within the `configuration.py` file in the src directory.
24
+ ### Config
25
+ The configuration file lives at `~/.config/umu-commander.toml`. Within it, you can edit the following:
26
+ * PROTON_PATHS: List of directories umu-commander will search for Proton versions.
27
+ * UMU_PROTON_PATH: Directory where umu itself downloads its umu Proton versions.
28
+ * DB_NAME: Tracking DB filename.
29
+ * DB_DIR: Directory where the Tracking DB is stored.
30
+ * UMU_CONFIG_NAME: Name of the umu config created using umu-commander run.
31
+ * DEFAULT_PREFIX_DIR: Directory where WINE prefixes are scanned.
32
+ * [DLL_OVERRIDES_OPTIONS]: Category to list possible DLL overrides in "Label" = "Override string" format.
25
33
 
26
34
  ### Verbs
27
35
  umu-commander needs one of the following verbs specified after the executable name:
@@ -0,0 +1,14 @@
1
+ umu_commander/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ umu_commander/classes.py,sha256=SW8k4TrP4-W4DdaQC_P88wBIgeJ3TIaV7lyt32IfVD8,1654
3
+ umu_commander/configuration.py,sha256=tzVFoQx7M1RGGtP_c_k3IUVFNcLwsmjbQplTeKlFUnM,2398
4
+ umu_commander/database.py,sha256=rkjEEy-Em9ghZOypsWyKTlNjDNMU4XXWuthnpfa6yz4,1343
5
+ umu_commander/main.py,sha256=LWLLzMO2xm-45USc0Uw1-oTdPW14tOd0-WAbnLvFTQg,1966
6
+ umu_commander/proton.py,sha256=QWqU5N2v-QqP_d-kFGXxXiCufLFQywnMNrbuLXaINZk,2572
7
+ umu_commander/tracking.py,sha256=MVj-GfbROyqhKa-m6557RGCzavTxgphNBVPJNtSTe3k,3058
8
+ umu_commander/umu_config.py,sha256=3b5XeTZppmLpxUGBHi4JSBc7zmKxNKjboldwGfLE0rc,4091
9
+ umu_commander/util.py,sha256=mBRdLs-dnrTE_23qSb9wZ7tw4WmcNU3AS9oJFrVLgH4,2642
10
+ umu_commander-1.5.2.dist-info/METADATA,sha256=E-8ommUma55wG-liyjohc6eaIh1IE3B6NxpMpx1Lzsg,3180
11
+ umu_commander-1.5.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
12
+ umu_commander-1.5.2.dist-info/entry_points.txt,sha256=7RGP35zAHeEojZ-sv7JIITuMeH_VVNuG2g2_SUrUnbM,58
13
+ umu_commander-1.5.2.dist-info/licenses/LICENSE.txt,sha256=yipFXBRmVZ2Q44x1q18HccPUAECBQLXAOAr21aS57uY,1071
14
+ umu_commander-1.5.2.dist-info/RECORD,,
umu_commander/db.py DELETED
@@ -1,66 +0,0 @@
1
- import json
2
- from collections import defaultdict
3
- from json import JSONDecodeError
4
-
5
- from umu_commander.configuration import *
6
-
7
- _db: defaultdict[str, defaultdict[str, list[str]]]
8
-
9
-
10
- def load():
11
- global _db
12
-
13
- if not os.path.exists(DB_DIR):
14
- os.mkdir(DB_DIR)
15
-
16
- try:
17
- with open(os.path.join(DB_DIR, DB_NAME), "rt") as db_file:
18
- _db = defaultdict(lambda: defaultdict(list))
19
- _db.update(json.load(db_file))
20
-
21
- except JSONDecodeError:
22
- print(f"Could not decode DB file, is it valid JSON?")
23
- raise JSONDecodeError("", "", 0)
24
-
25
- except FileNotFoundError:
26
- _db = defaultdict(lambda: defaultdict(list))
27
-
28
-
29
- def dump():
30
- with open(os.path.join(DB_DIR, DB_NAME), "wt") as db_file:
31
- # noinspection PyTypeChecker
32
- json.dump(_db, db_file, indent="\t")
33
-
34
-
35
- def copy():
36
- return _db.copy()
37
-
38
-
39
- def get(proton_dir: str, proton_ver: str = None) -> dict[str, list[str]] | list[str]:
40
- if proton_ver is None:
41
- return _db[proton_dir]
42
-
43
- return _db[proton_dir][proton_ver]
44
-
45
-
46
- # add user_dir to proton_ver's of proton_dir list of users
47
- def add_to(proton_dir: str, proton_ver: str, user_dir: str):
48
- global _db
49
-
50
- if proton_ver not in _db[proton_dir]:
51
- _db[proton_dir][proton_ver] = []
52
-
53
- _db[proton_dir][proton_ver].append(user_dir)
54
-
55
-
56
- def remove_from(proton_dir: str, proton_ver: str, user_dir: str):
57
- global _db
58
-
59
- if user_dir in _db[proton_dir][proton_ver]:
60
- _db[proton_dir][proton_ver].remove(user_dir)
61
-
62
-
63
- def delete(proton_dir: str, proton_ver: str):
64
- global _db
65
-
66
- del _db[proton_dir][proton_ver]
@@ -1,14 +0,0 @@
1
- umu_commander/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- umu_commander/classes.py,sha256=-_5vgcWIwQ3btE8yVc1v8sbBKH9iAR_qqO0XogtqhK8,784
3
- umu_commander/configuration.py,sha256=EOlXyB5xs2befhNdmUzlgWzZqUVAuOhfAEp3P7DCcPc,798
4
- umu_commander/db.py,sha256=T_Rw2WbPi3Ig4kS1xUhfeLeH0IXm7ZIFwx_KOsrvij8,1596
5
- umu_commander/main.py,sha256=CW8GopWCOLzWMS8_43RihRmjm_4yu0IXVGiMC7yap2k,1306
6
- umu_commander/proton.py,sha256=KrkrBcNlRNpfwtAloUQQbThw6ioWiDgtQCqqlHYEQRg,2031
7
- umu_commander/tracking.py,sha256=NdRarb_r65pDZXZer9Ls4uWqYhEd48qODp9hF68xpEQ,3219
8
- umu_commander/umu_config.py,sha256=jBpIvf55QmolgHX43XM5Lmg_xUbL13zCLZMjqdAGalE,4189
9
- umu_commander/util.py,sha256=f5YaYvyug4Tv8ydkhFy-AwEgWtVycV9-576A7h1D-dg,2644
10
- umu_commander-1.4.0.dist-info/METADATA,sha256=r7MWhMvSQwoXcoB_2ukpOtZ5uF3gHljvJ88dc7xNF-c,2791
11
- umu_commander-1.4.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
12
- umu_commander-1.4.0.dist-info/entry_points.txt,sha256=7RGP35zAHeEojZ-sv7JIITuMeH_VVNuG2g2_SUrUnbM,58
13
- umu_commander-1.4.0.dist-info/licenses/LICENSE.txt,sha256=yipFXBRmVZ2Q44x1q18HccPUAECBQLXAOAr21aS57uY,1071
14
- umu_commander-1.4.0.dist-info/RECORD,,