Skip to content

Commit

Permalink
feat: add file and exclude-pattern arguments; fix link argument
Browse files Browse the repository at this point in the history
  • Loading branch information
MatteoGuadrini committed Nov 22, 2024
2 parents 743fd04 + 0ea2afd commit cd543c9
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 60 deletions.
8 changes: 8 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Release notes

## 1.11.0
Nov 22, 2024

- Add `exclude-pattern` cli argument
- Add `file` cli argument
- Add **human_size_to_byte** function
- Fix `link` argument if it is a valid http link

## 1.10.0
Jul 25, 2024

Expand Down
117 changes: 63 additions & 54 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,38 +19,40 @@ $ pip install . # for others

``mkpl`` have many command line arguments. They are explained in this table:

| short | long | description | args |
|-------|------------------|-----------------------------------------------|---------------------------|
| -d | --directories | Directories that contains multimedia file | Path of directories |
| -e | --exclude-dirs | Exclude directory paths | Path of directories |
| -i | --include | Include other file format | Format of file. ex. mp3 |
| -p | --pattern | Regular expression inclusion pattern | Regular expression string |
| -f | --format | Select only a file format | Format of file. ex. mp3 |
| -s | --size | Start size in bytes | Bytes number |
| -m | --max-tracks | Maximum number of tracks | Number |
| -t | --title | Playlist title | Title string |
| -g | --encoding | Text encoding | UTF-8,ASCII,UNICODE |
| -I | --image | Playlist image | Image path |
| -l | --link | Add local or remote files | Files |
| -j | --join | Join one or more other playlist files | Playlist files |
| -n | --cache | Cache playlist results | Seconds |
| -U | --url-chars | Substitute some chars with URL Encoding | |
| -r | --recursive | Recursive search | |
| -a | --absolute | Absolute file name | |
| -s | --shuffle | Casual order | |
| -u | --unique | The same files are not placed in the playlist | |
| -c | --append | Continue playlist instead of override it | |
| -w | --windows | Windows style folder separator | |
| -v | --verbose | Enable verbosity (debug mode) | |
| -S | --split | Split playlist by directories | |
| -R | --interactive | Asks each file for confirmation | |
| -C | --count | Count elements into playlist | |
| -o | --orderby-name | Order playlist files by name | |
| -O | --orderby-date | Order playlist files by creation date | |
| -T | --orderby-track | Order playlist files by track | |
| -y | --orderby-year | Order playlist files by year | |
| -Z | --orderby-size | Order playlist files by size | |
| -L | --orderby-length | Order playlist files by length | |
| short | long | description | args |
|-------|-------------------|-----------------------------------------------|---------------------------|
| -d | --directories | Directories that contains multimedia file | Path of directories |
| -e | --exclude-dirs | Exclude directory paths | Path of directories |
| -i | --include | Include other file format | Format of file. ex. mp3 |
| -p | --pattern | Regular expression inclusion pattern | Regular expression string |
| -P | --exclude-pattern | Regular expression exclusion pattern | Regular expression string |
| -f | --format | Select only a file format | Format of file. ex. mp3 |
| -s | --size | Minimum size (bytes, kb, mb, ...) | Bytes (kb, mb, gb, ...) |
| -m | --max-tracks | Maximum number of tracks | Number |
| -t | --title | Playlist title | Title string |
| -g | --encoding | Text encoding | UTF-8,ASCII,UNICODE |
| -I | --image | Playlist image | Image path |
| -l | --link | Add remote file links | Http links |
| -F | --file | Add files | Files |
| -j | --join | Join one or more other playlist files | Playlist files |
| -n | --cache | Cache playlist results | Seconds |
| -U | --url-chars | Substitute some chars with URL Encoding | |
| -r | --recursive | Recursive search | |
| -a | --absolute | Absolute file name | |
| -s | --shuffle | Casual order | |
| -u | --unique | The same files are not placed in the playlist | |
| -c | --append | Continue playlist instead of override it | |
| -w | --windows | Windows style folder separator | |
| -v | --verbose | Enable verbosity (debug mode) | |
| -S | --split | Split playlist by directories | |
| -R | --interactive | Asks each file for confirmation | |
| -C | --count | Count elements into playlist | |
| -o | --orderby-name | Order playlist files by name | |
| -O | --orderby-date | Order playlist files by creation date | |
| -T | --orderby-track | Order playlist files by track | |
| -y | --orderby-year | Order playlist files by year | |
| -Z | --orderby-size | Order playlist files by size | |
| -L | --orderby-length | Order playlist files by length | |

## Examples

Expand All @@ -60,81 +62,88 @@ $ pip install . # for others
cd myalbum
mkpl myalbum.m3u
```

2. Create a playlist for one music album and add other multimedia files (`-F` option):

```bash
cd myalbum_special
mkpl myalbum_special.m3u -F music_video.mp4 other_stuff/song1.mp3 other_stuff/song2.mp3
```

2. Create a playlist of a film saga
3. Create a playlist of a film saga

```bash
mkpl -d HarryPotter -f mkv HP_saga.m3u
```

3. Create a shuffled playlist with my music collection
4. Create a shuffled playlist with my music collection; include only files with minimum size of 2 Megabyte

```bash
mkpl -d "my_mp3_collection" "my_mp4_collection" -rs "my music.m3u"
mkpl -d "my_mp3_collection" "my_mp4_collection" -rs -z 2mb "my music.m3u"
```

4. Create a shuffled playlist with my music collection and exclude dirs
5. Create a shuffled playlist with my music collection and exclude dirs

```bash
mkpl -d "my_mp3_collection" "my_mp4_collection" -r -s -e "my_mp3_collection/metallica" "my_mp3_collection/dk" -- "my music.m3u"
```

5. Create a TV series playlist with max 15 tracks
6. Create a TV series playlist with max 15 tracks

```bash
mkpl -d "my_series/GOT" -m 15 "got_first_15.m3u"
```

6. Add into _my music_ playlist new songs and don't add same file
7. Add into _my music_ playlist new songs and don't add same file
```bash
mkpl -d "new_collection" -rsu "my music.m3u" -a
```
7. Create playlist with music and video files if files is greater then 10MB
8. Create playlist with music and video files if files is greater then 10MB
```bash
mkpl -d "my_files" -r -z 10485760 "multimedia.m3u"
```
8. Create playlist with only number one and two tracks with regular expression
9. Create playlist with only number one and two tracks with regular expression
```bash
mkpl -d "my_mp3_collection" -r -p "^[12]|[012]{2}" "my music.m3u"
```
9. Create a playlist for one music album and set the title:
10. Create a playlist for one music album and set the title:
```bash
cd myalbum
mkpl myalbum.m3u -t "My Album"
```
```bash
cd myalbum
mkpl myalbum.m3u -t "My Album"
```
10. Create a playlist and add _UTF-8_ encoding
11. Create a playlist and add _UTF-8_ encoding
```bash
mkpl -d "new_collection" -r "my music.m3u" -g "UTF-8"
```
11. Create a playlist and set image
12. Create a playlist and set image
```bash
mkpl -d "new_collection" -r "my music.m3u" -I "new_collection/playlist_cover.jpg"
```
12. Create a playlist and add remote file links
13. Create a playlist and add remote file links
```bash
mkpl -d "new_collection" -r "my music.m3u" -l http://192.168.1.123/mp3/song1.mp3, http://192.168.1.123/mp3/song2.mp4
```
13. Create a playlist and set Windows backslash (\\) folder separator (for Windows OS)
14. Create a playlist and set Windows backslash (\\) folder separator (for Windows OS)
```bash
mkpl -d "new_collection" -r "my music.m3u" -w
```
14. Split playlist into _N_ playlists fon _N_ directories
15. Split playlist into _N_ playlists fon _N_ directories
```bash
mkpl -d "folder1" "folder2" "folder3" -r "my_music.m3u" -S
Expand All @@ -149,7 +158,7 @@ $ pip install . # for others
...
```
15. Sort playlist files by name (`-o`), by creation date (`-O`), by track number (`-T`), by year (`-y`), by size (`-Z`) or by length (`-L`):
16. Sort playlist files by name (`-o`), by creation date (`-O`), by track number (`-T`), by year (`-y`), by size (`-Z`) or by length (`-L`):
```bash
mkpl -d "new_collection" -r "my music.m3u" -o
Expand All @@ -160,20 +169,20 @@ $ pip install . # for others
mkpl -d "new_collection" -r "my music.m3u" -L
```
16. Join the _"First playlist.m3u"_ and _"Second playlist.m3u8"_ with new **"Third playlist.m3u"**:
17. Join the _"First playlist.m3u"_ and _"Second playlist.m3u8"_ with new **"Third playlist.m3u"**:
```bash
mkpl -d "new_collection" -r "Third playlist" -j "First playlist.m3u" "Second playlist.m3u8"
```
17. Counts the multimedia files:
18. Counts the multimedia files:
```console
mkpl -d "new_collection" -r "My new collection" -C
4023
```
18. Asks confirmation for every file into folders:
19. Asks confirmation for every file into folders:
```console
mkpl -d "new_collection" -r "My new collection" -R
Expand Down
69 changes: 64 additions & 5 deletions mkpl.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
"f4a",
}
FILE_FORMAT = AUDIO_FORMAT.union(VIDEO_FORMAT)
__version__ = "1.10.0"
__version__ = "1.11.0"


# endregion
Expand All @@ -87,7 +87,6 @@ def get_args():

parser = argparse.ArgumentParser(
description="Command line tool to creates playlist file in M3U format.",
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
epilog="See latest release from https://github.com/MatteoGuadrini/mkpl",
)
orderby_group = parser.add_mutually_exclusive_group()
Expand Down Expand Up @@ -121,6 +120,12 @@ def get_args():
parser.add_argument(
"-p", "--pattern", help="Regular expression inclusion pattern", default=None
)
parser.add_argument(
"-P",
"--exclude-pattern",
help="Regular expression exclusion pattern",
default=None,
)
parser.add_argument(
"-f",
"--format",
Expand All @@ -129,7 +134,11 @@ def get_args():
choices=FILE_FORMAT,
)
parser.add_argument(
"-z", "--size", help="Start size in bytes", type=int, default=1, metavar="BYTES"
"-z",
"--size",
help="Minimum size (bytes, kb, mb, ...)",
default="1",
metavar="BYTES",
)
parser.add_argument(
"-m",
Expand All @@ -151,9 +160,16 @@ def get_args():
parser.add_argument(
"-l",
"--link",
help="Add local or remote file links",
help="Add remote file links",
nargs=argparse.ONE_OR_MORE,
metavar="HTTP_LINK",
default=[],
)
parser.add_argument(
"-F",
"--file",
help="Add file",
nargs=argparse.ONE_OR_MORE,
metavar="FILES",
default=[],
)
parser.add_argument(
Expand Down Expand Up @@ -298,9 +314,41 @@ def get_args():
if args.format:
FILE_FORMAT = {args.format.strip("*").strip(".")}

# Convert size string into number
if args.size:
args.size = human_size_to_byte(args.size)

# Check link argument if it is a valid link
if args.link:
args.link = [link for link in args.link if re.match("https?://", link)]

# Check if other files exists
if args.file:
args.file = [f for f in args.file if os.path.exists(f)]

return args


def human_size_to_byte(size):
"""Convert human size into bytes
:param size: size string
:return: int
"""
size_name = ("b", "kb", "mb", "gb", "tb", "pb", "eb", "zb", "yb")
size_parts = re.search("([0-9]+) ?([a-zA-Z]+)?", size)
num, unit = int(size_parts[1]), size_parts[2]
if unit:
unit = unit.lower()
unit = unit if "b" in unit else unit + "b"
idx = size_name.index(unit)
factor = 1024**idx
size_bytes = num * factor
else:
size_bytes = num
return size_bytes


def confirm(file, default="y"):
"""Ask user to enter Y or N (case-insensitive)
Expand Down Expand Up @@ -528,6 +576,7 @@ def make_playlist(
directory,
file_formats,
pattern=None,
exclude_pattern=None,
sortby_name=False,
sortby_date=False,
sortby_track=False,
Expand Down Expand Up @@ -573,6 +622,11 @@ def make_playlist(
compiled_pattern = re.compile(pattern)
if not find_pattern(compiled_pattern, file):
continue
if exclude_pattern:
# Check re pattern
compiled_pattern = re.compile(exclude_pattern)
if find_pattern(compiled_pattern, file):
continue
# Check if in exclude dirs
if any([e_path in file for e_path in exclude_dirs]):
continue
Expand Down Expand Up @@ -656,6 +710,9 @@ def _process_playlist(files, cli_args, other_playlist=None):
# Add link
files.extend(cli_args.link)

# Add other files
files.extend(cli_args.file)

# Build a playlist
if files:
# Check shuffle
Expand Down Expand Up @@ -713,6 +770,7 @@ def main():
directory,
FILE_FORMAT,
args.pattern,
args.exclude_pattern,
sortby_name=args.orderby_name,
sortby_date=args.orderby_date,
sortby_track=args.orderby_track,
Expand All @@ -733,6 +791,7 @@ def main():
directory,
FILE_FORMAT,
args.pattern,
args.exclude_pattern,
sortby_name=args.orderby_name,
sortby_date=args.orderby_date,
sortby_track=args.orderby_track,
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ py-modules = ["mkpl"]

[project]
name = "make_playlist"
version = "1.10.0"
version = "1.11.0"
readme = "README.md"
keywords = ["playlist", "multimedia", "file", "maker", "make", "m3u", "m3u8"]

authors = [{ name = "Matteo Guadrini", email = "[email protected]" }]
maintainers = [
Expand Down

0 comments on commit cd543c9

Please sign in to comment.