Skip to content

Commit

Permalink
feat: add orderby-size, orderby-length, count and interactive arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
MatteoGuadrini committed May 9, 2024
2 parents e92deea + ccca986 commit 2ede958
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 64 deletions.
9 changes: 9 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Release notes

## 1.9.0
May 09, 2024

- Add `orderby-size` cli argument
- Add `orderby-length` cli argument
- Add `interactive` cli argument
- Add `count` cli argument
- Add **confirm** function for _interactive_ mode

## 1.8.0
Aug 03, 2023

Expand Down
78 changes: 51 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,32 +22,36 @@ $ 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 |
| -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 | |
| -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 | |
| 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 |
| -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 Down Expand Up @@ -146,19 +150,39 @@ $ pip install . # for others
...
```
15. Sort playlist files by name (`-o`), by creation date (`-O`), by track number (`-T`) or by year (`-y`):
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`):
```bash
mkpl -d "new_collection" -r "my music.m3u" -o
mkpl -d "new_collection" -r "my music.m3u" -O
mkpl -d "new_collection" -r "my music.m3u" -T
mkpl -d "new_collection" -r "my music.m3u" -y
mkpl -d "new_collection" -r "my music.m3u" -Z
mkpl -d "new_collection" -r "my music.m3u" -L
```
16. 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:
```console
mkpl -d "new_collection" -r "My new collection" -C
4023
```
18. Asks confirmation for every file into folders:
```console
mkpl -d "new_collection" -r "My new collection" -R
Add file new_collection/sample1.mp3 to playlist? [Y/n]:y
Add file new_collection/sample2.mp3 to playlist? [Y/n]:Y
Add file new_collection/sample3.mp3 to playlist? [Y/n]:n
Add file new_collection/sample4.mp3 to playlist? [Y/n]:N
```
## Use it like Python module
Expand Down
139 changes: 104 additions & 35 deletions mkpl.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# created by: matteo.guadrini
# mkpl -- mkpl
#
# Copyright (C) 2023 Matteo Guadrini <matteo.guadrini@hotmail.it>
# Copyright (C) 2024 Matteo Guadrini <matteo.guadrini@hotmail.it>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -71,7 +71,7 @@
"f4a",
}
FILE_FORMAT = AUDIO_FORMAT.union(VIDEO_FORMAT)
__version__ = "1.8.0"
__version__ = "1.9.0"


# endregion
Expand Down Expand Up @@ -151,15 +151,15 @@ def get_args():
"--link",
help="Add local or remote file links",
nargs=argparse.ONE_OR_MORE,
metavar='FILES',
metavar="FILES",
default=[],
)
parser.add_argument(
"-j",
"--join",
help="Join one or more other playlist files",
nargs=argparse.ONE_OR_MORE,
metavar='PLAYLISTS',
metavar="PLAYLISTS",
default=[],
)
parser.add_argument(
Expand All @@ -186,6 +186,15 @@ def get_args():
parser.add_argument(
"-S", "--split", help="Split playlist by directories", action="store_true"
)
parser.add_argument(
"-R",
"--interactive",
help="Asks each file for confirmation",
action="store_true",
)
parser.add_argument(
"-C", "--count", help="Count elements into playlist", action="store_true"
)
orderby_group.add_argument(
"-s", "--shuffle", help="Casual order", action="store_true"
)
Expand All @@ -207,6 +216,18 @@ def get_args():
help="Order playlist files by year",
action="store_true",
)
orderby_group.add_argument(
"-Z",
"--orderby-size",
help="Order playlist files by size",
action="store_true",
)
orderby_group.add_argument(
"-L",
"--orderby-length",
help="Order playlist files by length",
action="store_true",
)

args = parser.parse_args()

Expand Down Expand Up @@ -265,6 +286,28 @@ def get_args():
return args


def confirm(file, default="y"):
"""Ask user to enter Y or N (case-insensitive)
:file: file to add into playlist
:default: default answer
:return: True if the answer is Y.
:rtype: bool
"""
while (
answer := input(
"Add file {0} to playlist? {1}:".format(
file, "[Y/n]" if default == "y" else "[y/N]"
)
).lower()
) not in ("y", "n"):
# Check if default
if not answer:
answer = default
break
return answer == "y"


def file_in_playlist(playlist, file, root=None):
"""Check if file is in the playlist"""
for f in playlist:
Expand All @@ -287,7 +330,9 @@ def join_playlist(playlist, *others):
try:
# open playlist, remove extensions and extend current playlist file
lines = open(file).readlines()
playlist.extend([line.rstrip() for line in lines if not line.startswith('#')])
playlist.extend(
[line.rstrip() for line in lines if not line.startswith("#")]
)
except FileNotFoundError:
print(f"warning: {file} file not found")
except OSError as err:
Expand Down Expand Up @@ -333,6 +378,13 @@ def get_year(file):
return file.tags.get("TDOR", default)[0]


def get_length(file):
"""Get file by length for sort"""
file = open_multimedia_file(file)
if file and hasattr(file, "info"):
return file.info.length if hasattr(file.info, "length") else 0.0


def find_pattern(pattern, path):
"""Find patter in a file and tags"""
global AUDIO_FORMAT
Expand All @@ -344,10 +396,10 @@ def find_pattern(pattern, path):
if pattern.findall(path):
return True
# Check type of file
ext = os.path.splitext(path)[1].replace('.', '').lower()
ext = os.path.splitext(path)[1].replace(".", "").lower()
if ext in AUDIO_FORMAT:
file = open_multimedia_file(path)
# Check supports of ID3 tagsadd compiled pattern
# Check supports of ID3 tags add compiled pattern
if file and hasattr(file, "ID3"):
# Check pattern into title
if file.tags.get("TIT2"):
Expand Down Expand Up @@ -381,23 +433,23 @@ def unix_to_dos(path, viceversa=False):


def write_playlist(
playlist,
open_mode,
files,
encoding,
enabled_extensions=False,
image=None,
ext_part=None,
max_tracks=None,
verbose=False,
playlist,
open_mode,
files,
encoding,
enabled_extensions=False,
image=None,
ext_part=None,
max_tracks=None,
verbose=False,
):
"""Write playlist into file"""
if playlist:
with open(
playlist,
mode=open_mode,
encoding="UTF-8" if encoding == "UNICODE" else encoding,
errors="ignore",
playlist,
mode=open_mode,
encoding="UTF-8" if encoding == "UNICODE" else encoding,
errors="ignore",
) as pl:
if image and enabled_extensions:
vprint(verbose, f"set image {image}")
Expand All @@ -414,20 +466,23 @@ def write_playlist(


def make_playlist(
directory,
file_formats,
pattern=None,
sortby_name=False,
sortby_date=False,
sortby_track=False,
sortby_year=False,
recursive=False,
exclude_dirs=None,
unique=False,
absolute=False,
min_size=1,
windows=False,
verbose=False,
directory,
file_formats,
pattern=None,
sortby_name=False,
sortby_date=False,
sortby_track=False,
sortby_year=False,
sortby_size=False,
sortby_length=False,
recursive=False,
exclude_dirs=None,
unique=False,
absolute=False,
min_size=1,
windows=False,
interactive=False,
verbose=False,
):
"""Make playlist list"""
filelist = list()
Expand Down Expand Up @@ -465,12 +520,15 @@ def make_playlist(
# Check if file is in playlist
if unique:
if file_in_playlist(
filelist, file, root=root if not absolute else None
filelist, file, root=root if not absolute else None
):
continue
# Check file size
if size <= min_size:
continue
if interactive:
if not confirm(file):
continue
vprint(verbose, f"add multimedia file {file}")
filelist.append(unix_to_dos(file) if windows else file)
# Check sort
Expand All @@ -482,6 +540,10 @@ def make_playlist(
filelist = sorted(filelist, key=get_track)
elif sortby_year:
filelist = sorted(filelist, key=get_year)
elif sortby_size:
filelist = sorted(filelist, key=os.path.getsize)
elif sortby_length:
filelist = sorted(filelist, key=get_length)
return filelist


Expand Down Expand Up @@ -585,12 +647,15 @@ def main():
sortby_date=args.orderby_date,
sortby_track=args.orderby_track,
sortby_year=args.orderby_year,
sortby_size=args.orderby_size,
sortby_length=args.orderby_length,
recursive=args.recursive,
exclude_dirs=args.exclude_dirs,
unique=args.unique,
absolute=args.absolute,
min_size=args.size,
windows=args.windows,
interactive=args.interactive,
verbose=args.verbose,
)

Expand All @@ -608,6 +673,10 @@ def main():

_process_playlist(multimedia_files, args)

# Count files into playlist
if args.count:
print(len([file for file in multimedia_files if not file.startswith("#")]))

except Exception as err:
report_issue(err)

Expand Down
Loading

0 comments on commit 2ede958

Please sign in to comment.