Skip to content

Commit 8f018ad

Browse files
Merge pull request #11 from HenestrosaDev/dev
Add support for multiple files and directories input
2 parents db6f173 + 9289cef commit 8f018ad

File tree

3 files changed

+160
-44
lines changed

3 files changed

+160
-44
lines changed

README.md

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ In addition to being able to run this script on its own, it can also be installe
125125
### Project Structure
126126

127127
<details>
128-
<summary>ASCII folder structure</summary>
128+
<summary>ASCII directory structure</summary>
129129

130130
```
131131
│ .gitignore
@@ -289,29 +289,51 @@ Install the PyPI package by running `pip install mobile-strings-converter`.
289289

290290
### Running the Program
291291

292-
For basic use, you can run the following command:
292+
To convert one file to another file:
293293

294-
```bash
295-
python path/to/mobile_strings_converter.py *.[SUPPORTED_FILE_TYPE] -o *.[SUPPORTED_FILE_TYPE]
294+
```
295+
python path/to/mobile_strings_converter.py *.[SUPPORTED_FILE_TYPE] -f *.[SUPPORTED_FILE_TYPE]
296+
```
297+
298+
To include the comments of the `.xml`/`.strings` input file in the output file, add the `-p` (also `--print-comments`) flag. Note that it will be ignored for other input file types.
299+
300+
```
301+
python path/to/mobile_strings_converter.py *.[SUPPORTED_FILE_TYPE] -f *.[SUPPORTED_FILE_TYPE] -p
302+
```
303+
304+
To convert multiple files at once and save them to the specified directory passed in the `-d` flag, use the`-t` flag followed by the desired file type extension (e.g., `.json`). Note that the program will create the directory if it doesn't exist.
305+
306+
```
307+
python path/to/mobile_strings_converter.py *.[SUPPORTED_FILE_TYPE] *.[SUPPORTED_FILE_TYPE] *.[SUPPORTED_FILE_TYPE] -d [DIR_PATH] -t [TARGET_TYPE]
296308
```
297309

298-
To include the comments of the `.xml`/`.strings` file in the output file, add the `-p` (also `--print-comments`) flag:
310+
To convert supported files in a directory and its subdirectories and save them to a directory:
299311

300-
```bash
301-
python path/to/mobile_strings_converter.py *.[SUPPORTED_FILE_TYPE] -o *.[SUPPORTED_FILE_TYPE] -p
312+
```
313+
python path/to/mobile_strings_converter.py [INPUT_DIR_PATH] -d [OUTPUT_DIR_PATH] -t [TARGET_TYPE]
314+
```
315+
316+
To convert supported files in multiple directories and their subdirectories and save them to a directory:
317+
318+
```
319+
python path/to/mobile_strings_converter.py [INPUT_DIR_PATH_1] [INPUT_DIR_PATH_2] [INPUT_DIR_PATH_3] -d [OUTPUT_DIR_PATH] -t [TARGET_TYPE]
302320
```
303321

322+
For multiple file inputs and directories, the name of the files will be the same as the input file. For example, if there is a file named `spanish.xml` in a directory, the output file name will be `spanish.[TARGET_TYPE]`
323+
304324
See the [Generating a Spreadsheet in Google Sheets](#generating-a-spreadsheet-in-google-sheets) section to create a spreadsheet in your Google account.
305325

306326
#### Script Flags
307327

308-
| Flag | Description |
309-
|:----------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
310-
| `-h` or `--help` | Displays help text for the program |
311-
| `-o` or `--output-filepath` | Specifies the filepath for storing the converted file. The file extension can be chosen from the list of supported file types mentioned [here](#about-the-project). |
312-
| `-g` or `--google-sheets` | Followed by the name of the sheet, creates a new Google Sheets spreadsheet with the specified name. |
313-
| `-c` or `--credentials` | Followed by the path to your `service_account.json` file is mandatory if you want to generate a spreadsheet in your Google account. |
314-
| `-p` or `--print-comments` | The output file will contain all commented strings that were present in the original file (only applicable if the input file is a `.xml` or `.strings` file). Otherwise it will be ignored. |
328+
| Flag | Description |
329+
|:----------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
330+
| `-h` or `--help` | Displays help text for the program. |
331+
| `-f` or `--output-filepath` | Path to save the converted file. Only works if only one input file is provided. The file extension can be chosen from [the list of supported file types](#file-types-supported). |
332+
| `-d` or `--output-dir` | Directory where the converted files will be saved. Compatible with single and multiple input files as well as directories. The specified directory will be created if it does not already exist. |
333+
| `-t` or `--target-type` | Target file type to convert the files (e.g., .pdf, .json). Required if multiple file paths or the `--output-dir` is specified. |
334+
| `-g` or `--google-sheets` | If provided, a Google spreadsheet will be created in your Google account. You must pass the `service_account.json` with the `-c` flag. |
335+
| `-c` or `--credentials` | `service_account.json` filepath. Mandatory if you want to generate a spreadsheet in your Google account. You can learn how to generate it in the [Generating a Spreadsheet in Google Sheets](#generating-a-spreadsheet-in-google-sheets) section. |
336+
| `-p` or `--print-comments` | If provided, the commented strings will be printed in the output file. Only valid for input files of type `.xml` or `.strings`. Otherwise it is ignored. |
315337

316338
<p align="right">(<a href="#top">back to top</a>)</p>
317339

@@ -348,15 +370,17 @@ Alternatively, you can create an `.xlsx` file and open it in Google Sheets if yo
348370

349371
Once you have the `service_account.json` file, you can create a spreadsheet in Google Sheets by running the following command:
350372

351-
```bash
352-
python path/to/mobile_strings_converter.py *.[SUPPORTED_FILE_TYPE] -g [SHEET_NAME] -c path/to/service_account.json
373+
```
374+
python path/to/mobile_strings_converter.py *.[SUPPORTED_FILE_TYPE] -g -c path/to/service_account.json
353375
```
354376

355377
If you want to generate an output file along with the spreadsheet, run this:
356378

357-
```bash
358-
python path/to/mobile_strings_converter.py *.[SUPPORTED_FILE_TYPE] -g [SHEET_NAME] -c path/to/service_account.json -o *.[SUPPORTED_FILE_TYPE]
359379
```
380+
python path/to/mobile_strings_converter.py *.[SUPPORTED_FILE_TYPE] -g -c path/to/service_account.json -o *.[SUPPORTED_FILE_TYPE]
381+
```
382+
383+
The name of the sheet will be the same as the name of the input file.
360384

361385
#### Using the `to_google_sheets` Function in Your Project
362386

@@ -407,8 +431,9 @@ to_google_sheets(
407431
## Roadmap
408432

409433
- [x] Add support for converting a file (not `.xml` or `.strings`) into a strings resource file (`.xml` or `.strings`).
410-
- [ ] Add support for multiple files input.
411-
- [ ] Add support for accepting the path to a folder as input.
434+
- [x] Add support for multiple files input.
435+
- [x] Add support for accepting the path to a directory as input.
436+
- [x] Add support for accepting the path to a directory as output.
412437
- [ ] Make a web version.
413438

414439
You can propose a new feature creating an [issue](https://github.com/HenestrosaDev/mobile-strings-converter/new/choose).

src/mobile_strings_converter/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from .converter import convert_strings, to_google_sheets
88

99
# Constants
10-
__version__ = "0.1.3"
10+
__version__ = "0.1.4"
1111

1212
__author__ = "José Carlos López Henestrosa"
1313
__license = "MIT"

src/mobile_strings_converter/__main__.py

Lines changed: 114 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,64 @@
11
import argparse
2+
import os
23
from pathlib import Path
34

45
from console_style import ConsoleStyle
56
from converter import convert_strings, to_google_sheets
67

78

9+
def get_filepaths_from_dir(directory, extensions):
10+
"""Return a list of filepaths in the directory matching the given extensions."""
11+
matched_files = []
12+
for root, _, files in os.walk(directory):
13+
for file in files:
14+
if file.endswith(tuple(extensions)):
15+
matched_files.append(Path(root) / file)
16+
17+
return matched_files
18+
19+
820
def main():
921
parser = argparse.ArgumentParser(
1022
description="Takes input and output files from console."
1123
)
1224
parser.add_argument(
13-
"input_filepath",
25+
"input_paths",
1426
type=str,
15-
help=".xml or .strings filepath that contains the strings.",
27+
nargs="+", # Accept one or more values
28+
help="File paths or directories containing supported file types to be "
29+
"converted.",
1630
)
1731
parser.add_argument(
18-
"-o",
32+
"-f",
1933
"--output-filepath",
2034
required=False,
2135
type=str,
22-
help="Output filepath where you want to store the converted file. It can be a "
23-
"CSV, HTML, iOS strings file, MD, JSON, ODS, PDF, XLSX, XML or YAML file.",
36+
help="Path to save the converted file. Only works if only one input file "
37+
"is provided. See the README for a list of supported file types.",
38+
)
39+
parser.add_argument(
40+
"-d",
41+
"--output-dir",
42+
required=False,
43+
type=str,
44+
help="Directory where the converted files will be saved. Compatible with "
45+
"single and multiple input files as well as directories. The specified "
46+
"directory will be created if it does not already exist.",
47+
)
48+
parser.add_argument(
49+
"-t",
50+
"--target-type",
51+
type=str,
52+
help="Target file type to convert the files (e.g., .pdf, .json). Required if "
53+
"multiple file paths or the `--output-dir` is specified.",
2454
)
2555
parser.add_argument(
2656
"-g",
2757
"--google-sheets",
2858
required=False,
29-
type=str,
30-
help="Creates a spreadsheet in Google Sheets with the name passed as argument.",
59+
action="store_true",
60+
help="If provided, a Google spreadsheet will be created in your Google "
61+
"account. You must pass the `service_account.json` with the -c flag.",
3162
)
3263
parser.add_argument(
3364
"-c",
@@ -43,34 +74,94 @@ def main():
4374
"--print-comments",
4475
required=False,
4576
action="store_true",
46-
help="If called, indicates that commented strings will be printed in the "
47-
"output file.",
77+
help="If provided, the commented strings will be printed in the output file. "
78+
"Only valid for input files of type `.xml` or `.strings`. Otherwise it is "
79+
"ignored.",
4880
)
81+
4982
args = parser.parse_args()
5083

51-
input_filepath = Path(args.input_filepath)
84+
# Check if the output-extension argument is provided when output-dir is specified
85+
if args.output_dir and not args.target_type:
86+
raise ValueError(
87+
f"{ConsoleStyle.RED}--output-dir requires --output-extension."
88+
f"{ConsoleStyle.END}"
89+
)
90+
91+
allowed_extensions = [
92+
".csv",
93+
".xlsx",
94+
".ods",
95+
".md",
96+
".json",
97+
".yaml",
98+
".html",
99+
".strings",
100+
".xml",
101+
".pdf",
102+
]
103+
104+
input_filepaths = []
105+
output_dir = None
106+
107+
for path in args.input_paths:
108+
if os.path.isdir(path):
109+
# If it's a directory, get all matching files
110+
input_filepaths.extend(get_filepaths_from_dir(path, allowed_extensions))
111+
elif os.path.isfile(path) and path.endswith(tuple(allowed_extensions)):
112+
# If it's a file with an allowed extension, add it to the list
113+
input_filepaths.append(Path(path))
114+
else:
115+
print(
116+
f"{ConsoleStyle.YELLOW}Skipping unsupported file or path: {path}"
117+
f"{ConsoleStyle.END}"
118+
)
119+
120+
# Ensure the correct output options are used
121+
if args.output_filepath:
122+
if len(input_filepaths) > 1:
123+
raise ValueError(
124+
"Cannot use --output-filepath with multiple input files. Use "
125+
"--output-dir instead."
126+
)
127+
output_path = Path(args.output_filepath)
128+
output_path.parent.mkdir(parents=True, exist_ok=True)
129+
elif args.output_dir:
130+
output_dir = Path(args.output_dir)
131+
output_dir.mkdir(parents=True, exist_ok=True)
132+
else:
133+
raise ValueError(
134+
f"{ConsoleStyle.RED}You must specify an output path with the "
135+
f"-f or -d flag.{ConsoleStyle.END}"
136+
)
52137

53138
if args.google_sheets and not args.credentials:
54-
print(
55-
f"{ConsoleStyle.RED}Error: You need to pass the path of the "
139+
raise ValueError(
140+
f"{ConsoleStyle.RED}You need to pass the path of the "
56141
f"`service_account.json` file to generate a Sheet.{ConsoleStyle.END}"
57142
)
58-
return
59143
elif not args.google_sheets and args.credentials:
60-
print(
61-
f"{ConsoleStyle.RED}Error: You need to pass the name of the Sheet to be "
144+
raise ValueError(
145+
f"{ConsoleStyle.RED}You need to pass the name of the Sheet to be "
62146
f"generated.{ConsoleStyle.END}"
63147
)
64-
return
65148
elif args.google_sheets and args.credentials:
66-
to_google_sheets(
67-
input_filepath,
68-
sheet_name=args.google_sheets,
69-
credentials_filepath=Path(args.credentials),
70-
with_comments=args.print_comments,
71-
)
149+
for input_filepath in input_filepaths:
150+
to_google_sheets(
151+
args.input_filepath,
152+
sheet_name=Path(input_filepath).stem,
153+
credentials_filepath=Path(args.credentials),
154+
with_comments=args.print_comments,
155+
)
156+
157+
for input_filepath in input_filepaths:
158+
if args.output_filepath:
159+
output_filepath = Path(args.output_filepath)
160+
else:
161+
output_filename = Path(input_filepath).stem + args.target_type
162+
output_filepath = output_dir / output_filename
72163

73-
convert_strings(input_filepath, Path(args.output_filepath), args.print_comments)
164+
convert_strings(input_filepath, output_filepath, args.print_comments)
74165

75166

76167
if __name__ == "__main__":

0 commit comments

Comments
 (0)