mcmu 1.4.0.dev0__tar.gz → 2.0.0.dev2__tar.gz
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.
- {mcmu-1.4.0.dev0 → mcmu-2.0.0.dev2}/CHANGELOG.md +64 -35
- {mcmu-1.4.0.dev0 → mcmu-2.0.0.dev2}/PKG-INFO +6 -3
- {mcmu-1.4.0.dev0 → mcmu-2.0.0.dev2}/README.md +4 -0
- {mcmu-1.4.0.dev0 → mcmu-2.0.0.dev2}/TODO.md +1 -2
- mcmu-2.0.0.dev2/UPGRADING.md +9 -0
- {mcmu-1.4.0.dev0 → mcmu-2.0.0.dev2}/pyproject.toml +1 -2
- {mcmu-1.4.0.dev0 → mcmu-2.0.0.dev2}/src/mcmu/ModrinthAPI.py +3 -3
- {mcmu-1.4.0.dev0 → mcmu-2.0.0.dev2}/src/mcmu/__main__.py +32 -60
- {mcmu-1.4.0.dev0 → mcmu-2.0.0.dev2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {mcmu-1.4.0.dev0 → mcmu-2.0.0.dev2}/.github/ISSUE_TEMPLATE/custom.md +0 -0
- {mcmu-1.4.0.dev0 → mcmu-2.0.0.dev2}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {mcmu-1.4.0.dev0 → mcmu-2.0.0.dev2}/.github/pull_request_template.md +0 -0
- {mcmu-1.4.0.dev0 → mcmu-2.0.0.dev2}/.gitignore +0 -0
- {mcmu-1.4.0.dev0 → mcmu-2.0.0.dev2}/CODE_OF_CONDUCT.md +0 -0
- {mcmu-1.4.0.dev0 → mcmu-2.0.0.dev2}/CONTRIBUTING.md +0 -0
- {mcmu-1.4.0.dev0 → mcmu-2.0.0.dev2}/LICENSE +0 -0
- {mcmu-1.4.0.dev0 → mcmu-2.0.0.dev2}/Makefile +0 -0
- {mcmu-1.4.0.dev0 → mcmu-2.0.0.dev2}/SECURITY.md +0 -0
- {mcmu-1.4.0.dev0 → mcmu-2.0.0.dev2}/requirements.txt +0 -0
- {mcmu-1.4.0.dev0 → mcmu-2.0.0.dev2}/src/mcmu/__init__.py +0 -0
|
@@ -1,6 +1,30 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## [
|
|
3
|
+
## [v2.0.0.dev2] - 2026-03-17
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
* Now shows 100 search results instead of 10
|
|
8
|
+
|
|
9
|
+
### Removed
|
|
10
|
+
|
|
11
|
+
* Removed -v and --version
|
|
12
|
+
|
|
13
|
+
## [v2.0.0.dev1] - 2026-03-17
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
* Changed the name of the file when downloading
|
|
18
|
+
|
|
19
|
+
### Removed
|
|
20
|
+
|
|
21
|
+
* Removed the need for the config file
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
* Fixed displaying mod name when upgrading
|
|
26
|
+
|
|
27
|
+
## [v1.4.0.dev0] - 2026-03-16
|
|
4
28
|
|
|
5
29
|
### Added
|
|
6
30
|
|
|
@@ -10,19 +34,19 @@
|
|
|
10
34
|
|
|
11
35
|
* Put API request code into separate file *ModrinthAPI.py*
|
|
12
36
|
|
|
13
|
-
## [
|
|
37
|
+
## [v1.3.0] - 2026-03-15
|
|
14
38
|
|
|
15
39
|
### Added
|
|
16
40
|
|
|
17
41
|
* Comments to the code
|
|
18
42
|
|
|
19
|
-
## [
|
|
43
|
+
## [v1.3.0a1] - 2026-03-15
|
|
20
44
|
|
|
21
45
|
### Removed
|
|
22
46
|
|
|
23
47
|
* Removed print statement for parameters
|
|
24
48
|
|
|
25
|
-
## [
|
|
49
|
+
## [v1.3.0a0] - 2026-03-15
|
|
26
50
|
|
|
27
51
|
This release brings a new feature! You can now search mods on Modrinth!
|
|
28
52
|
|
|
@@ -39,19 +63,19 @@ This release brings a new feature! You can now search mods on Modrinth!
|
|
|
39
63
|
* Does'nt ask to download mod if it is already installed
|
|
40
64
|
* Now most command lines options are mutually exclusive
|
|
41
65
|
|
|
42
|
-
## [
|
|
66
|
+
## [v1.2.1] - 2026-03-13
|
|
43
67
|
|
|
44
68
|
### Changed
|
|
45
69
|
|
|
46
70
|
* Change help message for the -g command line argument
|
|
47
71
|
|
|
48
|
-
## [
|
|
72
|
+
## [v1.2.0] - 2026-03-13
|
|
49
73
|
|
|
50
74
|
Happy Pi days for reals this time
|
|
51
75
|
|
|
52
76
|
No changes from [1.2.0rc0](#120rc0---2026-03-13)
|
|
53
77
|
|
|
54
|
-
## [
|
|
78
|
+
## [v1.2.0rc0] - 2026-03-13
|
|
55
79
|
|
|
56
80
|
If no serious bugs are found this release will become [1.2.0](#120---2026-03-13)
|
|
57
81
|
|
|
@@ -68,7 +92,7 @@ If no serious bugs are found this release will become [1.2.0](#120---2026-03-13)
|
|
|
68
92
|
|
|
69
93
|
* Removed Mod class
|
|
70
94
|
|
|
71
|
-
## [
|
|
95
|
+
## [v1.2.0a1] - 2026-03-13
|
|
72
96
|
|
|
73
97
|
### Changed
|
|
74
98
|
|
|
@@ -79,7 +103,7 @@ If no serious bugs are found this release will become [1.2.0](#120---2026-03-13)
|
|
|
79
103
|
|
|
80
104
|
* Removed Mod.install()
|
|
81
105
|
|
|
82
|
-
## [
|
|
106
|
+
## [v1.2.0a0] - 2026-03-13
|
|
83
107
|
|
|
84
108
|
### Added
|
|
85
109
|
|
|
@@ -92,19 +116,19 @@ If no serious bugs are found this release will become [1.2.0](#120---2026-03-13)
|
|
|
92
116
|
* Now asks for permission to remove mod
|
|
93
117
|
* Moved *minecraft_mod.py* code into *__main__.py*
|
|
94
118
|
|
|
95
|
-
## [
|
|
119
|
+
## [v1.2.0.dev1] - 2026-03-13
|
|
96
120
|
|
|
97
121
|
### Added
|
|
98
122
|
|
|
99
123
|
* Added a message when a mod is removed
|
|
100
124
|
|
|
101
|
-
## [
|
|
125
|
+
## [v1.2.0.dev0] - 2026-03-13
|
|
102
126
|
|
|
103
127
|
### Changed
|
|
104
128
|
|
|
105
129
|
* Made update messages pretty
|
|
106
130
|
|
|
107
|
-
## [
|
|
131
|
+
## [v1.1.1] - 2026-03-13
|
|
108
132
|
|
|
109
133
|
Happy almost Pi Day! Here is the newest stable release.
|
|
110
134
|
|
|
@@ -238,26 +262,31 @@ This is the first release candidate for version [1.0.0+1.21.11].
|
|
|
238
262
|
|
|
239
263
|
- Initial Release
|
|
240
264
|
|
|
241
|
-
[0.1.0]: https://github.com/Josiah-Jarvis/
|
|
242
|
-
[0.1.1]: https://github.com/Josiah-Jarvis/
|
|
243
|
-
[0.1.2]: https://github.com/Josiah-Jarvis/
|
|
244
|
-
[0.1.3]: https://github.com/Josiah-Jarvis/
|
|
245
|
-
[0.1.4]: https://github.com/Josiah-Jarvis/
|
|
246
|
-
[0.2.0]: https://github.com/Josiah-Jarvis/
|
|
247
|
-
[0.2.1]: https://github.com/Josiah-Jarvis/
|
|
248
|
-
[0.2.2]: https://github.com/Josiah-Jarvis/
|
|
249
|
-
[1.0.0rc0]: https://github.com/Josiah-Jarvis/
|
|
250
|
-
[1.0.0rc1]: https://github.com/Josiah-Jarvis/
|
|
251
|
-
[1.0.0]: https://github.com/Josiah-Jarvis/
|
|
252
|
-
[1.1.0.dev0]: https://github.com/Josiah-Jarvis/
|
|
253
|
-
[1.1.0.dev1]: https://github.com/Josiah-Jarvis/
|
|
254
|
-
[1.1.0]: https://github.com/Josiah-Jarvis/
|
|
255
|
-
[1.1.1a0]: https://github.com/Josiah-Jarvis/
|
|
256
|
-
[
|
|
257
|
-
[
|
|
258
|
-
[
|
|
259
|
-
[
|
|
260
|
-
[
|
|
261
|
-
[
|
|
262
|
-
[
|
|
263
|
-
[
|
|
265
|
+
[0.1.0]: https://github.com/Josiah-Jarvis/MCMU/releases/tag/0.1.0
|
|
266
|
+
[0.1.1]: https://github.com/Josiah-Jarvis/MCMU/releases/tag/0.1.1
|
|
267
|
+
[0.1.2]: https://github.com/Josiah-Jarvis/MCMU/releases/tag/0.1.2
|
|
268
|
+
[0.1.3]: https://github.com/Josiah-Jarvis/MCMU/releases/tag/0.1.3
|
|
269
|
+
[0.1.4]: https://github.com/Josiah-Jarvis/MCMU/releases/tag/0.1.4
|
|
270
|
+
[0.2.0]: https://github.com/Josiah-Jarvis/MCMU/releases/tag/0.2.0
|
|
271
|
+
[0.2.1]: https://github.com/Josiah-Jarvis/MCMU/releases/tag/0.2.1
|
|
272
|
+
[0.2.2]: https://github.com/Josiah-Jarvis/MCMU/releases/tag/0.2.2
|
|
273
|
+
[1.0.0rc0]: https://github.com/Josiah-Jarvis/MCMU/releases/tag/1.0.0rc0
|
|
274
|
+
[1.0.0rc1]: https://github.com/Josiah-Jarvis/MCMU/releases/tag/1.0.0rc1
|
|
275
|
+
[1.0.0]: https://github.com/Josiah-Jarvis/MCMU/releases/tag/1.0.0
|
|
276
|
+
[1.1.0.dev0]: https://github.com/Josiah-Jarvis/MCMU/releases/tag/1.1.0.dev0
|
|
277
|
+
[1.1.0.dev1]: https://github.com/Josiah-Jarvis/MCMU/releases/tag/1.1.0.dev1
|
|
278
|
+
[1.1.0]: https://github.com/Josiah-Jarvis/MCMU/releases/tag/1.1.0
|
|
279
|
+
[1.1.1a0]: https://github.com/Josiah-Jarvis/MCMU/releases/tag/1.1.1a0
|
|
280
|
+
[v1.1.1]: https://github.com/Josiah-Jarvis/MCMU/releases/tag/v1.1.1
|
|
281
|
+
[v1.2.0.dev0]: https://github.com/Josiah-Jarvis/MCMU/releases/tag/v1.2.0.dev0
|
|
282
|
+
[v1.2.0a0]: https://github.com/Josiah-Jarvis/MCMU/releases/tag/v1.2.0a0
|
|
283
|
+
[v1.2.0a1]: https://github.com/Josiah-Jarvis/MCMU/releases/tag/v1.2.0a1
|
|
284
|
+
[v1.2.0rc0]: https://github.com/Josiah-Jarvis/MCMU/releases/tag/v1.2.0rc0
|
|
285
|
+
[v1.2.0]: https://github.com/Josiah-Jarvis/MCMU/releases/tag/v1.2.0
|
|
286
|
+
[v1.2.1]: https://github.com/Josiah-Jarvis/MCMU/releases/tag/v1.2.1
|
|
287
|
+
[v1.3.0a0]: https://github.com/Josiah-Jarvis/MCMU/releases/tag/v1.3.0a0
|
|
288
|
+
[v1.3.0a1]: https://github.com/Josiah-Jarvis/MCMU/releases/tag/v1.3.0a1
|
|
289
|
+
[v1.3.0]: https://github.com/Josiah-Jarvis/MCMU/releases/tag/v1.3.0
|
|
290
|
+
[v1.4.0.dev0]: https://github.com/Josiah-Jarvis/MCMU/releases/tag/v1.4.0.dev0
|
|
291
|
+
[v2.0.0.dev1]: https://github.com/Josiah-Jarvis/MCMU/releases/tag/v2.0.0.dev0
|
|
292
|
+
[v2.0.0.dev2]: https://github.com/Josiah-Jarvis/MCMU/releases/tag/v2.0.0.dev2
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mcmu
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0.dev2
|
|
4
4
|
Summary: A utility to update Minecraft java edition mods from Modrinth
|
|
5
5
|
Project-URL: homepage, https://github.com/Josiah-Jarvis/MCMU
|
|
6
6
|
Project-URL: source, https://github.com/Josiah-Jarvis/MCMU/
|
|
7
7
|
Project-URL: download, https://pypi.org/project/mcmu/#files
|
|
8
8
|
Project-URL: changelog, https://github.com/Josiah-Jarvis/MCMU/blob/master/CHANGELOG.md
|
|
9
|
-
Project-URL: releasenotes, https://github.com/Josiah-Jarvis/MCMU/compare/
|
|
9
|
+
Project-URL: releasenotes, https://github.com/Josiah-Jarvis/MCMU/compare/v2.0.0.dev1...v2.0.0.dev2
|
|
10
10
|
Project-URL: documentation, https://github.com/Josiah-Jarvis/MCMU/blob/master/README.md
|
|
11
11
|
Project-URL: issues, https://github.com/Josiah-Jarvis/MCMU/issues
|
|
12
12
|
Author: Josiah Jarvis
|
|
@@ -25,7 +25,6 @@ Classifier: Natural Language :: English
|
|
|
25
25
|
Classifier: Operating System :: MacOS
|
|
26
26
|
Classifier: Operating System :: Microsoft
|
|
27
27
|
Classifier: Operating System :: Microsoft :: Windows
|
|
28
|
-
Classifier: Operating System :: Microsoft :: Windows :: Windows 10
|
|
29
28
|
Classifier: Operating System :: Microsoft :: Windows :: Windows 11
|
|
30
29
|
Classifier: Operating System :: POSIX
|
|
31
30
|
Classifier: Operating System :: POSIX :: Linux
|
|
@@ -126,3 +125,7 @@ mcmu -g game_version -i mod-name
|
|
|
126
125
|
### How does it work?
|
|
127
126
|
|
|
128
127
|
It works a lot like a package manager actually! It pulls the mods from a source (Modrinth) and installs them on the system. It keeps a list of the installed mods in a config file for easy access of the installed mods.
|
|
128
|
+
|
|
129
|
+
### What happened to v1.4.0?
|
|
130
|
+
|
|
131
|
+
It turned into v2.0.0.
|
|
@@ -82,3 +82,7 @@ mcmu -g game_version -i mod-name
|
|
|
82
82
|
### How does it work?
|
|
83
83
|
|
|
84
84
|
It works a lot like a package manager actually! It pulls the mods from a source (Modrinth) and installs them on the system. It keeps a list of the installed mods in a config file for easy access of the installed mods.
|
|
85
|
+
|
|
86
|
+
### What happened to v1.4.0?
|
|
87
|
+
|
|
88
|
+
It turned into v2.0.0.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Breaking changes between v1.3.0 and v2.0.0
|
|
2
|
+
|
|
3
|
+
This update breaks everything!
|
|
4
|
+
|
|
5
|
+
Why does it break everything? Because we are dropping the config file! Now the config is stored in the mods file name, now it is stored as {mod_name}_version_{mod_version}.jar.
|
|
6
|
+
|
|
7
|
+
## How to update safely
|
|
8
|
+
|
|
9
|
+
In v1.3.0 of MCMU do `mcmu -l` to get a list of all your mods. Keep this safe. One by one delete all your mods with `mcmu -r <modname>` then update MCMU with `pip install --upgrade mcmu`. Next reinstall all your mods with `mcmu -i <modname>`.
|
|
@@ -28,7 +28,6 @@ classifiers = [
|
|
|
28
28
|
"Operating System :: MacOS",
|
|
29
29
|
"Operating System :: Microsoft",
|
|
30
30
|
"Operating System :: Microsoft :: Windows",
|
|
31
|
-
"Operating System :: Microsoft :: Windows :: Windows 10",
|
|
32
31
|
"Operating System :: Microsoft :: Windows :: Windows 11",
|
|
33
32
|
"Operating System :: POSIX",
|
|
34
33
|
"Operating System :: POSIX :: Linux",
|
|
@@ -52,7 +51,7 @@ homepage = "https://github.com/Josiah-Jarvis/MCMU"
|
|
|
52
51
|
source = "https://github.com/Josiah-Jarvis/MCMU/"
|
|
53
52
|
download = "https://pypi.org/project/mcmu/#files"
|
|
54
53
|
changelog = "https://github.com/Josiah-Jarvis/MCMU/blob/master/CHANGELOG.md"
|
|
55
|
-
releasenotes = "https://github.com/Josiah-Jarvis/MCMU/compare/
|
|
54
|
+
releasenotes = "https://github.com/Josiah-Jarvis/MCMU/compare/v2.0.0.dev1...v2.0.0.dev2" # Change before every release
|
|
56
55
|
documentation = "https://github.com/Josiah-Jarvis/MCMU/blob/master/README.md"
|
|
57
56
|
issues = "https://github.com/Josiah-Jarvis/MCMU/issues"
|
|
58
57
|
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
from requests import get
|
|
8
8
|
|
|
9
|
+
|
|
9
10
|
class ModrinthAPI:
|
|
10
11
|
def __init__(self, UserAgent: str):
|
|
11
12
|
self.headers = {
|
|
@@ -27,7 +28,8 @@ class ModrinthAPI:
|
|
|
27
28
|
"""
|
|
28
29
|
parameters = {
|
|
29
30
|
'query': query,
|
|
30
|
-
'facets': facets
|
|
31
|
+
'facets': facets,
|
|
32
|
+
'limit': "100"
|
|
31
33
|
}
|
|
32
34
|
response = get(url="https://api.modrinth.com/v2/search", params=parameters, headers=self.headers)
|
|
33
35
|
if response.status_code != 200:
|
|
@@ -95,5 +97,3 @@ class ModrinthAPI:
|
|
|
95
97
|
return response.status_code
|
|
96
98
|
else:
|
|
97
99
|
return response.json()
|
|
98
|
-
|
|
99
|
-
|
|
@@ -1,38 +1,38 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
from
|
|
4
|
+
import sys
|
|
5
|
+
from re import match
|
|
6
|
+
from os import listdir
|
|
6
7
|
from pathlib import Path # Import for file functions
|
|
7
8
|
from logging import getLogger, basicConfig # Logging functionality
|
|
8
9
|
from requests import get # Get files from the CDN
|
|
9
10
|
from argparse import ArgumentParser # Command line arguments class
|
|
10
11
|
from .ModrinthAPI import ModrinthAPI # Modrinth API code (Local import)
|
|
11
12
|
|
|
12
|
-
__version__ = "
|
|
13
|
+
__version__ = "2.0.0.dev2"
|
|
13
14
|
__author__ = "Josiah Jarvis"
|
|
14
15
|
|
|
15
16
|
logger = getLogger(__name__)
|
|
16
17
|
basicConfig(format="%(levelname)s: %(message)s") # Set logging config
|
|
17
18
|
|
|
18
|
-
parser = ArgumentParser(prog=f"MCMU {__version__}", description="Downloads
|
|
19
|
+
parser = ArgumentParser(prog=f"MCMU {__version__}", description="Downloads Minecraft mods from Modrinth")
|
|
19
20
|
group = parser.add_mutually_exclusive_group() # Get mutually exclusive group set up
|
|
20
21
|
group.add_argument("-u", "--update", help="Updates installed mods", action="store_true")
|
|
21
22
|
group.add_argument("-r", "--remove", help="Removes an installed mod")
|
|
22
23
|
group.add_argument("-i", "--install", help="Installs a mod")
|
|
23
24
|
group.add_argument("-l", "--list", help="List installed mods", action="store_true")
|
|
24
25
|
group.add_argument("-s", "--search", help="Search packages on Modrinth")
|
|
25
|
-
group.add_argument("-v", "--version", action="version", version=f"MCMU version: {__version__}")
|
|
26
26
|
# Unix systems defaults to ~/.minecraft/ for the minecraft dir, I don't know about Windows or MacOS
|
|
27
27
|
parser.add_argument("-m", "--minecraft_dir", default=Path(Path.home(), ".minecraft/"), help="Path to the Minecraft folder, defaults to '~/.minecraft/'")
|
|
28
28
|
# Game version defaults to 1.21.11 as it is the latest Minecraft release
|
|
29
29
|
parser.add_argument("-g", "--game_version", default="26.1", help="The game version to use to install mods, defaults to '26.1'")
|
|
30
30
|
|
|
31
31
|
args = parser.parse_args() # Parser the arguments
|
|
32
|
-
config_file = Path(args.minecraft_dir, "config/mcmu.json") # Path to the config file
|
|
33
32
|
|
|
34
33
|
ModAPI = ModrinthAPI(f"Josiah-Jarvis/MCMU/{__version__} (https://github.com/Josiah-Jarvis/MCMU)")
|
|
35
34
|
|
|
35
|
+
|
|
36
36
|
def check_update(mod_name: str, current_version: str) -> [bool, dict]:
|
|
37
37
|
"""Checks for mod update from Modrinth
|
|
38
38
|
|
|
@@ -61,24 +61,20 @@ def check_update(mod_name: str, current_version: str) -> [bool, dict]:
|
|
|
61
61
|
return latest_version
|
|
62
62
|
return False # Return false for failure
|
|
63
63
|
|
|
64
|
-
def write_config_file(config_f: Path, config_d: dict):
|
|
65
|
-
"""Writes the config file
|
|
66
64
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
65
|
+
def list_mods(mod_path: Path):
|
|
66
|
+
mods = {}
|
|
67
|
+
for mod in listdir(mod_path):
|
|
68
|
+
pattern = r'^(.*?)_version_(.*)\.jar$'
|
|
69
|
+
m = match(pattern, mod)
|
|
70
|
+
mods[m.group(1)] = {
|
|
71
|
+
"name": m.group(1),
|
|
72
|
+
"version": m.group(2),
|
|
73
|
+
"file": mod
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return mods
|
|
70
77
|
|
|
71
|
-
Returns:
|
|
72
|
-
True: Success
|
|
73
|
-
False: Failure
|
|
74
|
-
"""
|
|
75
|
-
try:
|
|
76
|
-
with open(config_f, "w") as fp: # Open the config file
|
|
77
|
-
dump(config_d, fp, indent=4) # Write the config file
|
|
78
|
-
return True
|
|
79
|
-
except PermissionError: # Uh oh we do not have permission
|
|
80
|
-
logger.error("No permission to write to file.")
|
|
81
|
-
return False
|
|
82
78
|
|
|
83
79
|
def main():
|
|
84
80
|
"""Main function
|
|
@@ -87,30 +83,15 @@ def main():
|
|
|
87
83
|
1: Failure
|
|
88
84
|
0: Success
|
|
89
85
|
"""
|
|
90
|
-
try:
|
|
91
|
-
with open(config_file, "r") as fp: # Open the config file
|
|
92
|
-
config = load(fp) # Read the config file
|
|
93
|
-
except JSONDecodeError:
|
|
94
|
-
logger.critical("Config file not valid JSON.") # Well its not valid JSON
|
|
95
|
-
return 1
|
|
96
|
-
except FileNotFoundError: # Oops config file does not exist
|
|
97
|
-
logger.warn("Config file does not exist.")
|
|
98
|
-
with open(config_file, "w") as fp: # Create the file since it does not exist
|
|
99
|
-
logger.debug("Creating config file.")
|
|
100
|
-
dump({"mods":{}}, fp, indent=4)
|
|
101
|
-
config = {"mods":{}}
|
|
102
|
-
except PermissionError: # Can't we just have the permission :?
|
|
103
|
-
logger.error("No permission to write to file.")
|
|
104
|
-
return 1
|
|
105
|
-
mods = copy(config['mods']) # Get the mods data from the config file
|
|
106
86
|
mod_path = Path(args.minecraft_dir, "mods/") # Path to folder where the mod jar's are stored
|
|
87
|
+
mods = list_mods(mod_path)
|
|
107
88
|
if not mod_path.exists():
|
|
108
89
|
logger.critical(f"Mods folder: {mod_path} does not exist. Please create it.\nExiting...") # Fabric creates the mods/ folder on first run by they might not have run it yet
|
|
109
90
|
return 1
|
|
110
91
|
if args.update:
|
|
111
92
|
for mod_name in mods:
|
|
112
93
|
latest_version = check_update(mod_name, mods[mod_name]['version']) # Check for update
|
|
113
|
-
if latest_version == 404: # Thats weird
|
|
94
|
+
if latest_version == 404: # Thats weird
|
|
114
95
|
print("Mod does not exist on Modrinth.")
|
|
115
96
|
sys.exit(1)
|
|
116
97
|
elif latest_version is None: # If latest version is None no newer version was found
|
|
@@ -119,27 +100,24 @@ def main():
|
|
|
119
100
|
elif latest_version: # If latest version is a dict it should return True
|
|
120
101
|
old_file = Path(mod_path, mods[mod_name]['file']) # Path to the old mod file
|
|
121
102
|
additional_storage = latest_version['files'][0]['size'] - old_file.stat().st_size # Calculate how much more storage will be taken up
|
|
122
|
-
if input(f"{
|
|
103
|
+
if input(f"{mods[mod_name]['name']} will take up: {additional_storage} additional bytes, would you like to install? [Y/n]: ") is ("" or "Y"): # Ask them if they want to install it
|
|
123
104
|
old_file.unlink() # Delete old file
|
|
124
105
|
response = get(latest_version['files'][0]['url'], stream=True) # Get the new file
|
|
125
106
|
if response.status_code != 200: # If its not 200 fail
|
|
126
107
|
print(f"Failed to download the mod. Status code: {response.status_code}")
|
|
127
108
|
return 1
|
|
128
|
-
with open(f"{mod_path}/{latest_version['
|
|
109
|
+
with open(f"{mod_path}/{args.install}_version_{latest_version['version_number']}.jar", 'wb') as file: # IF everything good write to the file
|
|
129
110
|
for chunk in response.iter_content(chunk_size=1024):
|
|
130
111
|
if chunk:
|
|
131
112
|
file.write(chunk)
|
|
132
|
-
print(f"Downloaded {latest_version['
|
|
133
|
-
config['mods'][mod_name] = {'file': latest_version['files'][0]['filename'], 'version': latest_version['version_number'], 'name': mod_name}
|
|
134
|
-
if not write_config_file(config_file, config): # Write the config file
|
|
135
|
-
return 1 # Fail if writing failed
|
|
113
|
+
print(f"Downloaded mod at {mod_path}/{args.install}_version_{latest_version['version_number']}.jar successfully.") # Print the success
|
|
136
114
|
else:
|
|
137
115
|
print("Canceling.")
|
|
138
116
|
return 0
|
|
139
117
|
else:
|
|
140
118
|
print(f"Mod: {mod_name} at latest version!")
|
|
141
119
|
elif args.install: # If were installing the mod
|
|
142
|
-
if args.install in
|
|
120
|
+
if args.install in mods: # If mod already installed exit
|
|
143
121
|
print(f"{args.install} already installed.")
|
|
144
122
|
return 0
|
|
145
123
|
latest_version = check_update(args.install, "0") # Set the version to 0 so any version would be higher
|
|
@@ -152,14 +130,11 @@ def main():
|
|
|
152
130
|
if response.status_code != 200:
|
|
153
131
|
print(f"Failed to download the mod. Status code: {response.status_code}")
|
|
154
132
|
return False
|
|
155
|
-
with open(f"{mod_path}/{latest_version['
|
|
133
|
+
with open(f"{mod_path}/{args.install}_version_{latest_version['version_number']}.jar", 'wb') as file: # Write to the jar file
|
|
156
134
|
for chunk in response.iter_content(chunk_size=1024):
|
|
157
135
|
if chunk:
|
|
158
136
|
file.write(chunk)
|
|
159
|
-
print(f"Downloaded {latest_version['
|
|
160
|
-
config['mods'][args.install] = {'file': latest_version['files'][0]['filename'], 'version': latest_version['version_number'], 'name': args.install}
|
|
161
|
-
if not write_config_file(config_file, config): # Write to the config file
|
|
162
|
-
return 1
|
|
137
|
+
print(f"Downloaded mod at {mod_path}/{args.install}_version_{latest_version['version_number']}.jar successfully.") # Print the success
|
|
163
138
|
else:
|
|
164
139
|
print("Canceling.")
|
|
165
140
|
return 0
|
|
@@ -167,11 +142,11 @@ def main():
|
|
|
167
142
|
logger.error("Mod does not exist on Modrinth")
|
|
168
143
|
return 1
|
|
169
144
|
elif args.remove: # If were removing the mod
|
|
170
|
-
if args.remove not in
|
|
145
|
+
if args.remove not in mods: # If the mod is not installed
|
|
171
146
|
logger.error("Mod not installed")
|
|
172
147
|
return 1
|
|
173
148
|
try:
|
|
174
|
-
mod_file = Path(mod_path,
|
|
149
|
+
mod_file = Path(mod_path, mods[args.remove]['file']) # Path to the mod jar
|
|
175
150
|
if input(f"Would you like to remove {args.remove}? This operation will clear {mod_file.stat().st_size} bytes. [Y/n]: ") is ("" or "Y"): # Ask if they want to remove it
|
|
176
151
|
mod_file.unlink() # Remove the file
|
|
177
152
|
else:
|
|
@@ -182,24 +157,21 @@ def main():
|
|
|
182
157
|
except PermissionError: # No permission to delete the file
|
|
183
158
|
logger.critical("No permission to delete mod file.")
|
|
184
159
|
return 1
|
|
185
|
-
del config['mods'][args.remove] # Remove the mods entry in the config file
|
|
186
|
-
if not write_config_file(config_file, config): # Write to the config file
|
|
187
|
-
return 1
|
|
188
160
|
print(f"Mod: {args.remove}, successfully removed") # Print success
|
|
189
161
|
return 0
|
|
190
162
|
elif args.list: # List installed mod
|
|
191
|
-
for mod in
|
|
192
|
-
print(f"{
|
|
163
|
+
for mod in mods: # Iterate over all installed mods
|
|
164
|
+
print(f"{mods[mod]['name']}\n\tVersion: {mods[mod]['version']}\n\tFile: {mods[mod]['file']}")
|
|
193
165
|
elif args.search: # If we are searching for a mod
|
|
194
166
|
response = ModAPI.search(args.search, '[["categories:fabric"],["project_type:mod"]]')
|
|
195
167
|
if response == 410: # That means the API is deprecated: https://docs.modrinth.com/api/
|
|
196
168
|
logger.critical("API is deprecated, you probably have to update MCMU")
|
|
197
169
|
elif response == 400: # Response of 400 means request was invalid: https://docs.modrinth.com/api/operations/searchprojects/
|
|
198
|
-
logger.error(
|
|
170
|
+
logger.error("Request invalid") # Print error
|
|
199
171
|
else:
|
|
200
172
|
for mod in response['hits']: # Iterate over and list all the mods
|
|
201
173
|
print(f"{mod['title']}:\n\tDescription: {mod['description']}\n\tAuthor: {mod['author']}\n\tDownloads: {mod['downloads']}\n\tLatest Version: {mod['latest_version']}\n\n")
|
|
202
174
|
else:
|
|
203
175
|
parser.print_help() # Prints help message if there is nothing to do
|
|
204
176
|
|
|
205
|
-
return 0
|
|
177
|
+
return 0 # Return 0 if all good
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|