DiscogsDataProcessorCLI 1.5.0__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.
- discogsdataprocessorcli-1.5.0/DiscogsDataProcessorCLI.egg-info/PKG-INFO +119 -0
- discogsdataprocessorcli-1.5.0/DiscogsDataProcessorCLI.egg-info/SOURCES.txt +20 -0
- discogsdataprocessorcli-1.5.0/DiscogsDataProcessorCLI.egg-info/dependency_links.txt +1 -0
- discogsdataprocessorcli-1.5.0/DiscogsDataProcessorCLI.egg-info/entry_points.txt +2 -0
- discogsdataprocessorcli-1.5.0/DiscogsDataProcessorCLI.egg-info/requires.txt +3 -0
- discogsdataprocessorcli-1.5.0/DiscogsDataProcessorCLI.egg-info/top_level.txt +1 -0
- discogsdataprocessorcli-1.5.0/PKG-INFO +119 -0
- discogsdataprocessorcli-1.5.0/README.md +102 -0
- discogsdataprocessorcli-1.5.0/discogs/__init__.py +0 -0
- discogsdataprocessorcli-1.5.0/discogs/chunker.py +95 -0
- discogsdataprocessorcli-1.5.0/discogs/config.py +75 -0
- discogsdataprocessorcli-1.5.0/discogs/converter.py +190 -0
- discogsdataprocessorcli-1.5.0/discogs/deleter.py +51 -0
- discogsdataprocessorcli-1.5.0/discogs/downloader.py +120 -0
- discogsdataprocessorcli-1.5.0/discogs/extractor.py +92 -0
- discogsdataprocessorcli-1.5.0/discogs/main.py +170 -0
- discogsdataprocessorcli-1.5.0/discogs/scraper.py +125 -0
- discogsdataprocessorcli-1.5.0/discogs/selector.py +197 -0
- discogsdataprocessorcli-1.5.0/discogs/utils.py +96 -0
- discogsdataprocessorcli-1.5.0/pyproject.toml +3 -0
- discogsdataprocessorcli-1.5.0/setup.cfg +32 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: DiscogsDataProcessorCLI
|
|
3
|
+
Version: 1.5.0
|
|
4
|
+
Summary: A CLI to download, extract and convert Discogs data dumps
|
|
5
|
+
Home-page: https://github.com/ofurkancoban/DiscogsCLI
|
|
6
|
+
Author: Furkan Γoban
|
|
7
|
+
Author-email: ofurkancoban@gmail.com
|
|
8
|
+
License: MIT
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Requires-Python: >=3.8
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
Requires-Dist: rich
|
|
15
|
+
Requires-Dist: pandas
|
|
16
|
+
Requires-Dist: typer
|
|
17
|
+
|
|
18
|
+
# π§ Discogs CLI β Data Processor Tool πΏ
|
|
19
|
+
<p align="center">
|
|
20
|
+
<img src="img/logo.png" alt="Discogs Logo" width="200"/>
|
|
21
|
+
</p>
|
|
22
|
+
A modern command-line tool to **download**, **extract**, and **convert** Discogs data dumps into structured CSV files.
|
|
23
|
+
<p align="center">
|
|
24
|
+
<img src="img/preview.gif" />
|
|
25
|
+
</p>
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## π Features
|
|
30
|
+
|
|
31
|
+
- π§ Scrape latest available data dump list from Discogs S3
|
|
32
|
+
- β¬οΈ Download `.gz` files for artists, labels, releases, masters
|
|
33
|
+
- π¦ Extract `.gz` files to raw XML
|
|
34
|
+
- βοΈ Chunk large XML into smaller files
|
|
35
|
+
- π Convert XML to clean, flat CSV files
|
|
36
|
+
- π Delete selected or all files
|
|
37
|
+
- βοΈ Set custom download folder
|
|
38
|
+
- π§ͺ Easy to use from terminal with friendly UI
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## π§© Installation
|
|
43
|
+
|
|
44
|
+
### π» Install with Homebrew
|
|
45
|
+
```bash
|
|
46
|
+
brew tap ofurkancoban/discogs
|
|
47
|
+
brew install discogs
|
|
48
|
+
```
|
|
49
|
+
### or
|
|
50
|
+
```bash
|
|
51
|
+
git clone https://github.com/ofurkancoban/DiscogsCLI.git
|
|
52
|
+
cd DiscogsCLI
|
|
53
|
+
pip install -e .
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## π» Usage
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
discogs run # Auto: download β extract β convert
|
|
62
|
+
discogs show # List available Discogs data
|
|
63
|
+
discogs download # Just download selected files
|
|
64
|
+
discogs extract # Extract downloaded .gz files
|
|
65
|
+
discogs convert # Convert extracted XML to CSV
|
|
66
|
+
discogs delete # Delete files by selection or --all
|
|
67
|
+
discogs config # Set download folder
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## π Folder Structure
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
~/Downloads/Discogs/
|
|
76
|
+
βββ .discogs_config.json
|
|
77
|
+
βββ Datasets/
|
|
78
|
+
βββ 2025-04/
|
|
79
|
+
βββ discogs_20250401_artists.gz
|
|
80
|
+
βββ discogs_20250401_artists β .xml
|
|
81
|
+
βββ discogs_20250401_artists.csv β converted
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## π§ Example Workflow
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
discogs show
|
|
90
|
+
# [1] 2025-04 | releases | 950 MB
|
|
91
|
+
# [2] 2025-04 | artists | 320 MB
|
|
92
|
+
|
|
93
|
+
discogs download
|
|
94
|
+
# Select 1,2
|
|
95
|
+
# Downloads only
|
|
96
|
+
|
|
97
|
+
discogs extract
|
|
98
|
+
# Select file to extract
|
|
99
|
+
|
|
100
|
+
discogs convert
|
|
101
|
+
# Select XML to convert
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## π§βπ» Author
|
|
107
|
+
|
|
108
|
+
- GitHub: [github.com/ofurkancoban](https://github.com/ofurkancoban)
|
|
109
|
+
- LinkedIn: [linkedin.com/in/ofurkancoban](https://linkedin.com/in/ofurkancoban)
|
|
110
|
+
- Kaggle: [kaggle.com/ofurkancoban](https://www.kaggle.com/ofurkancoban)
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## π License
|
|
115
|
+
|
|
116
|
+
MIT β use freely, mention when you do something cool π
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
Built with β€οΈ by [@ofurkancoban](https://github.com/ofurkancoban)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
setup.cfg
|
|
4
|
+
DiscogsDataProcessorCLI.egg-info/PKG-INFO
|
|
5
|
+
DiscogsDataProcessorCLI.egg-info/SOURCES.txt
|
|
6
|
+
DiscogsDataProcessorCLI.egg-info/dependency_links.txt
|
|
7
|
+
DiscogsDataProcessorCLI.egg-info/entry_points.txt
|
|
8
|
+
DiscogsDataProcessorCLI.egg-info/requires.txt
|
|
9
|
+
DiscogsDataProcessorCLI.egg-info/top_level.txt
|
|
10
|
+
discogs/__init__.py
|
|
11
|
+
discogs/chunker.py
|
|
12
|
+
discogs/config.py
|
|
13
|
+
discogs/converter.py
|
|
14
|
+
discogs/deleter.py
|
|
15
|
+
discogs/downloader.py
|
|
16
|
+
discogs/extractor.py
|
|
17
|
+
discogs/main.py
|
|
18
|
+
discogs/scraper.py
|
|
19
|
+
discogs/selector.py
|
|
20
|
+
discogs/utils.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
discogs
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: DiscogsDataProcessorCLI
|
|
3
|
+
Version: 1.5.0
|
|
4
|
+
Summary: A CLI to download, extract and convert Discogs data dumps
|
|
5
|
+
Home-page: https://github.com/ofurkancoban/DiscogsCLI
|
|
6
|
+
Author: Furkan Γoban
|
|
7
|
+
Author-email: ofurkancoban@gmail.com
|
|
8
|
+
License: MIT
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Requires-Python: >=3.8
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
Requires-Dist: rich
|
|
15
|
+
Requires-Dist: pandas
|
|
16
|
+
Requires-Dist: typer
|
|
17
|
+
|
|
18
|
+
# π§ Discogs CLI β Data Processor Tool πΏ
|
|
19
|
+
<p align="center">
|
|
20
|
+
<img src="img/logo.png" alt="Discogs Logo" width="200"/>
|
|
21
|
+
</p>
|
|
22
|
+
A modern command-line tool to **download**, **extract**, and **convert** Discogs data dumps into structured CSV files.
|
|
23
|
+
<p align="center">
|
|
24
|
+
<img src="img/preview.gif" />
|
|
25
|
+
</p>
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## π Features
|
|
30
|
+
|
|
31
|
+
- π§ Scrape latest available data dump list from Discogs S3
|
|
32
|
+
- β¬οΈ Download `.gz` files for artists, labels, releases, masters
|
|
33
|
+
- π¦ Extract `.gz` files to raw XML
|
|
34
|
+
- βοΈ Chunk large XML into smaller files
|
|
35
|
+
- π Convert XML to clean, flat CSV files
|
|
36
|
+
- π Delete selected or all files
|
|
37
|
+
- βοΈ Set custom download folder
|
|
38
|
+
- π§ͺ Easy to use from terminal with friendly UI
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## π§© Installation
|
|
43
|
+
|
|
44
|
+
### π» Install with Homebrew
|
|
45
|
+
```bash
|
|
46
|
+
brew tap ofurkancoban/discogs
|
|
47
|
+
brew install discogs
|
|
48
|
+
```
|
|
49
|
+
### or
|
|
50
|
+
```bash
|
|
51
|
+
git clone https://github.com/ofurkancoban/DiscogsCLI.git
|
|
52
|
+
cd DiscogsCLI
|
|
53
|
+
pip install -e .
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## π» Usage
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
discogs run # Auto: download β extract β convert
|
|
62
|
+
discogs show # List available Discogs data
|
|
63
|
+
discogs download # Just download selected files
|
|
64
|
+
discogs extract # Extract downloaded .gz files
|
|
65
|
+
discogs convert # Convert extracted XML to CSV
|
|
66
|
+
discogs delete # Delete files by selection or --all
|
|
67
|
+
discogs config # Set download folder
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## π Folder Structure
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
~/Downloads/Discogs/
|
|
76
|
+
βββ .discogs_config.json
|
|
77
|
+
βββ Datasets/
|
|
78
|
+
βββ 2025-04/
|
|
79
|
+
βββ discogs_20250401_artists.gz
|
|
80
|
+
βββ discogs_20250401_artists β .xml
|
|
81
|
+
βββ discogs_20250401_artists.csv β converted
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## π§ Example Workflow
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
discogs show
|
|
90
|
+
# [1] 2025-04 | releases | 950 MB
|
|
91
|
+
# [2] 2025-04 | artists | 320 MB
|
|
92
|
+
|
|
93
|
+
discogs download
|
|
94
|
+
# Select 1,2
|
|
95
|
+
# Downloads only
|
|
96
|
+
|
|
97
|
+
discogs extract
|
|
98
|
+
# Select file to extract
|
|
99
|
+
|
|
100
|
+
discogs convert
|
|
101
|
+
# Select XML to convert
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## π§βπ» Author
|
|
107
|
+
|
|
108
|
+
- GitHub: [github.com/ofurkancoban](https://github.com/ofurkancoban)
|
|
109
|
+
- LinkedIn: [linkedin.com/in/ofurkancoban](https://linkedin.com/in/ofurkancoban)
|
|
110
|
+
- Kaggle: [kaggle.com/ofurkancoban](https://www.kaggle.com/ofurkancoban)
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## π License
|
|
115
|
+
|
|
116
|
+
MIT β use freely, mention when you do something cool π
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
Built with β€οΈ by [@ofurkancoban](https://github.com/ofurkancoban)
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# π§ Discogs CLI β Data Processor Tool πΏ
|
|
2
|
+
<p align="center">
|
|
3
|
+
<img src="img/logo.png" alt="Discogs Logo" width="200"/>
|
|
4
|
+
</p>
|
|
5
|
+
A modern command-line tool to **download**, **extract**, and **convert** Discogs data dumps into structured CSV files.
|
|
6
|
+
<p align="center">
|
|
7
|
+
<img src="img/preview.gif" />
|
|
8
|
+
</p>
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## π Features
|
|
13
|
+
|
|
14
|
+
- π§ Scrape latest available data dump list from Discogs S3
|
|
15
|
+
- β¬οΈ Download `.gz` files for artists, labels, releases, masters
|
|
16
|
+
- π¦ Extract `.gz` files to raw XML
|
|
17
|
+
- βοΈ Chunk large XML into smaller files
|
|
18
|
+
- π Convert XML to clean, flat CSV files
|
|
19
|
+
- π Delete selected or all files
|
|
20
|
+
- βοΈ Set custom download folder
|
|
21
|
+
- π§ͺ Easy to use from terminal with friendly UI
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## π§© Installation
|
|
26
|
+
|
|
27
|
+
### π» Install with Homebrew
|
|
28
|
+
```bash
|
|
29
|
+
brew tap ofurkancoban/discogs
|
|
30
|
+
brew install discogs
|
|
31
|
+
```
|
|
32
|
+
### or
|
|
33
|
+
```bash
|
|
34
|
+
git clone https://github.com/ofurkancoban/DiscogsCLI.git
|
|
35
|
+
cd DiscogsCLI
|
|
36
|
+
pip install -e .
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## π» Usage
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
discogs run # Auto: download β extract β convert
|
|
45
|
+
discogs show # List available Discogs data
|
|
46
|
+
discogs download # Just download selected files
|
|
47
|
+
discogs extract # Extract downloaded .gz files
|
|
48
|
+
discogs convert # Convert extracted XML to CSV
|
|
49
|
+
discogs delete # Delete files by selection or --all
|
|
50
|
+
discogs config # Set download folder
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## π Folder Structure
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
~/Downloads/Discogs/
|
|
59
|
+
βββ .discogs_config.json
|
|
60
|
+
βββ Datasets/
|
|
61
|
+
βββ 2025-04/
|
|
62
|
+
βββ discogs_20250401_artists.gz
|
|
63
|
+
βββ discogs_20250401_artists β .xml
|
|
64
|
+
βββ discogs_20250401_artists.csv β converted
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## π§ Example Workflow
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
discogs show
|
|
73
|
+
# [1] 2025-04 | releases | 950 MB
|
|
74
|
+
# [2] 2025-04 | artists | 320 MB
|
|
75
|
+
|
|
76
|
+
discogs download
|
|
77
|
+
# Select 1,2
|
|
78
|
+
# Downloads only
|
|
79
|
+
|
|
80
|
+
discogs extract
|
|
81
|
+
# Select file to extract
|
|
82
|
+
|
|
83
|
+
discogs convert
|
|
84
|
+
# Select XML to convert
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## π§βπ» Author
|
|
90
|
+
|
|
91
|
+
- GitHub: [github.com/ofurkancoban](https://github.com/ofurkancoban)
|
|
92
|
+
- LinkedIn: [linkedin.com/in/ofurkancoban](https://linkedin.com/in/ofurkancoban)
|
|
93
|
+
- Kaggle: [kaggle.com/ofurkancoban](https://www.kaggle.com/ofurkancoban)
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## π License
|
|
98
|
+
|
|
99
|
+
MIT β use freely, mention when you do something cool π
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
Built with β€οΈ by [@ofurkancoban](https://github.com/ofurkancoban)
|
|
File without changes
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# discogs/chunker.py
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from rich.console import Console
|
|
6
|
+
from rich.progress import Progress, BarColumn, TimeElapsedColumn, TextColumn
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def sanitize_line(line: str) -> str:
|
|
10
|
+
"""
|
|
11
|
+
Removes invalid XML characters and fixes unescaped ampersands.
|
|
12
|
+
This helps ensure the XML is well-formed before processing.
|
|
13
|
+
"""
|
|
14
|
+
line = re.sub(r'[^\x09\x0A\x0D\x20-\uD7FF\uE000-\uFFFD]', '', line) # Remove illegal XML characters
|
|
15
|
+
line = re.sub(r'&(?![a-zA-Z0-9#]+;)', '&', line) # Escape unescaped '&' characters
|
|
16
|
+
return line
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def chunk_xml_by_type(xml_file: Path, content_type: str, records_per_file: int = 10000) -> Path:
|
|
20
|
+
"""
|
|
21
|
+
Splits a large XML file into smaller, valid XML files (chunks).
|
|
22
|
+
Each chunk contains up to `records_per_file` XML records.
|
|
23
|
+
Returns the folder path where chunked files are stored.
|
|
24
|
+
"""
|
|
25
|
+
record_tag = content_type[:-1].lower() # e.g., "releases" β "release"
|
|
26
|
+
start_pat = re.compile(fr'<{record_tag}\b', re.IGNORECASE) # Match opening tag
|
|
27
|
+
end_pat = re.compile(fr'</{record_tag}>', re.IGNORECASE) # Match closing tag
|
|
28
|
+
|
|
29
|
+
chunk_folder = xml_file.parent / f"chunked_{content_type}" # Output folder
|
|
30
|
+
chunk_folder.mkdir(parents=True, exist_ok=True)
|
|
31
|
+
|
|
32
|
+
console = Console()
|
|
33
|
+
chunk_count = 0
|
|
34
|
+
record_count = 0
|
|
35
|
+
inside_record = False
|
|
36
|
+
buffer_lines = [] # Stores lines of current XML record
|
|
37
|
+
current_chunk_file = None
|
|
38
|
+
|
|
39
|
+
# Helper function to open a new chunk file
|
|
40
|
+
def open_new_chunk():
|
|
41
|
+
nonlocal chunk_count, current_chunk_file, record_count
|
|
42
|
+
chunk_count += 1
|
|
43
|
+
chunk_path = chunk_folder / f"chunk_{chunk_count:05}.xml"
|
|
44
|
+
current_chunk_file = open(chunk_path, "w", encoding="utf-8")
|
|
45
|
+
current_chunk_file.write(f'<?xml version="1.0" encoding="utf-8"?>\n<{content_type}>\n')
|
|
46
|
+
record_count = 0
|
|
47
|
+
|
|
48
|
+
# Helper function to close the current chunk file
|
|
49
|
+
def close_chunk():
|
|
50
|
+
nonlocal current_chunk_file
|
|
51
|
+
if current_chunk_file:
|
|
52
|
+
current_chunk_file.write(f"</{content_type}>")
|
|
53
|
+
current_chunk_file.close()
|
|
54
|
+
current_chunk_file = None
|
|
55
|
+
|
|
56
|
+
open_new_chunk()
|
|
57
|
+
|
|
58
|
+
# Setup progress bar for visual feedback
|
|
59
|
+
with Progress(
|
|
60
|
+
TextColumn("[progress.description]{task.description}"),
|
|
61
|
+
BarColumn(),
|
|
62
|
+
"[progress.percentage]{task.percentage:.1f}%",
|
|
63
|
+
"β’",
|
|
64
|
+
TimeElapsedColumn()
|
|
65
|
+
) as progress:
|
|
66
|
+
task = progress.add_task(f"Chunking {xml_file.name}", total=xml_file.stat().st_size)
|
|
67
|
+
|
|
68
|
+
# Read and process XML file line by line
|
|
69
|
+
with xml_file.open("r", encoding="utf-8", errors="ignore") as f:
|
|
70
|
+
for raw_line in f:
|
|
71
|
+
line = sanitize_line(raw_line)
|
|
72
|
+
progress.update(task, advance=len(raw_line))
|
|
73
|
+
|
|
74
|
+
if not inside_record:
|
|
75
|
+
# Detect start of a record
|
|
76
|
+
if start_pat.search(line):
|
|
77
|
+
inside_record = True
|
|
78
|
+
buffer_lines = [line]
|
|
79
|
+
else:
|
|
80
|
+
buffer_lines.append(line)
|
|
81
|
+
if end_pat.search(line):
|
|
82
|
+
# Write complete record to current chunk
|
|
83
|
+
current_chunk_file.write("".join(buffer_lines) + "\n")
|
|
84
|
+
record_count += 1
|
|
85
|
+
inside_record = False
|
|
86
|
+
buffer_lines = []
|
|
87
|
+
|
|
88
|
+
# If chunk is full, start a new one
|
|
89
|
+
if record_count >= records_per_file:
|
|
90
|
+
close_chunk()
|
|
91
|
+
open_new_chunk()
|
|
92
|
+
|
|
93
|
+
close_chunk()
|
|
94
|
+
console.print(f"[green]β Chunked into {chunk_count} file(s): {chunk_folder}")
|
|
95
|
+
return chunk_folder
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# discogs/config.py
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from rich.console import Console
|
|
6
|
+
from rich.prompt import Prompt
|
|
7
|
+
|
|
8
|
+
CONFIG_PATH = Path.home() / ".discogs_config.json" # Path to the user's config file
|
|
9
|
+
DEFAULT_DOWNLOAD_PATH = Path.home() / "Downloads" / "Discogs" # Default download location
|
|
10
|
+
|
|
11
|
+
console = Console()
|
|
12
|
+
|
|
13
|
+
def get_download_dir() -> Path:
|
|
14
|
+
"""
|
|
15
|
+
Returns the download directory from the config file if it exists,
|
|
16
|
+
otherwise returns the default download path.
|
|
17
|
+
"""
|
|
18
|
+
if CONFIG_PATH.exists():
|
|
19
|
+
path = CONFIG_PATH.read_text().strip()
|
|
20
|
+
if path:
|
|
21
|
+
return Path(path)
|
|
22
|
+
return DEFAULT_DOWNLOAD_PATH
|
|
23
|
+
|
|
24
|
+
def set_download_dir(path: str) -> None:
|
|
25
|
+
"""
|
|
26
|
+
Sets (writes) the download directory path to the config file.
|
|
27
|
+
"""
|
|
28
|
+
CONFIG_PATH.write_text(path.strip())
|
|
29
|
+
|
|
30
|
+
def load_config() -> dict:
|
|
31
|
+
"""
|
|
32
|
+
Loads configuration data from the config file.
|
|
33
|
+
If the config cannot be read, it returns a dictionary with default values.
|
|
34
|
+
"""
|
|
35
|
+
if CONFIG_PATH.exists():
|
|
36
|
+
try:
|
|
37
|
+
with CONFIG_PATH.open("r") as f:
|
|
38
|
+
return json.load(f)
|
|
39
|
+
except Exception as e:
|
|
40
|
+
console.print(f"[red]Error reading config:[/] {e}")
|
|
41
|
+
return {"download_dir": str(DEFAULT_DOWNLOAD_PATH)}
|
|
42
|
+
|
|
43
|
+
def save_config(config: dict) -> None:
|
|
44
|
+
"""
|
|
45
|
+
Saves the given configuration dictionary to the config file.
|
|
46
|
+
Creates the parent directory if it doesn't exist.
|
|
47
|
+
"""
|
|
48
|
+
CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True)
|
|
49
|
+
with CONFIG_PATH.open("w") as f:
|
|
50
|
+
json.dump(config, f, indent=4)
|
|
51
|
+
|
|
52
|
+
def get_download_dir() -> Path:
|
|
53
|
+
"""
|
|
54
|
+
Gets the download directory from config, falling back to default if missing.
|
|
55
|
+
"""
|
|
56
|
+
config = load_config()
|
|
57
|
+
return Path(config.get("download_dir", str(DEFAULT_DOWNLOAD_PATH)))
|
|
58
|
+
|
|
59
|
+
def configure_download_folder() -> None:
|
|
60
|
+
"""
|
|
61
|
+
Prompts the user to configure the download folder via CLI.
|
|
62
|
+
Updates the config if a new folder is provided.
|
|
63
|
+
"""
|
|
64
|
+
console.print("[bold]Configure Discogs download folder[/bold]")
|
|
65
|
+
current = get_download_dir()
|
|
66
|
+
console.print(f"Current folder: [green]{current}[/green]")
|
|
67
|
+
|
|
68
|
+
new_path = Prompt.ask("Enter new folder path or leave empty to keep current", default=str(current)).strip()
|
|
69
|
+
if new_path:
|
|
70
|
+
new_path = Path(new_path).expanduser()
|
|
71
|
+
new_path.mkdir(parents=True, exist_ok=True)
|
|
72
|
+
save_config({"download_dir": str(new_path)})
|
|
73
|
+
console.print(f"[green]β
Download folder updated to:[/] {new_path}")
|
|
74
|
+
else:
|
|
75
|
+
console.print("[yellow]No changes made.[/yellow]")
|