Skip to content

Commit

Permalink
titlecase root dirs; albums -> Albums etc.
Browse files Browse the repository at this point in the history
  • Loading branch information
azuline committed Oct 13, 2023
1 parent 87414b3 commit f3f5ea0
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 71 deletions.
11 changes: 5 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Rosé

_Work in Progress. See [Issue #1](https://github.com/azuline/rose/issues/1) for
the current state.
the current state._

A virtual filesystem music library and a music metadata manager.

Expand Down Expand Up @@ -33,15 +33,15 @@ The virtual filesystem constructed from the above source directory is:

```tree
.
├── albums
├── Albums
│   ├── BLACKPINK - 2016. SQUARE ONE - Single [K-Pop] {YG Entertainment}
│   ├── BLACKPINK - 2016. SQUARE TWO - Single [K-Pop] {YG Entertainment}
│   ├── LOOΠΔ 1_3 - 2017. Love & Evil [K-Pop] {BlockBerry Creative}
│   ├── LOOΠΔ - 2019. [X X] [K-Pop] {BlockBerry Creative}
│   ├── LOOΠΔ - 2020. [#] [K-Pop] {BlockBerry Creative}
│   ├── LOOΠΔ ODD EYE CIRCLE - 2017. Max & Match [K-Pop] {BlockBerry Creative}
│   └── YUZION - 2019. Young Trapper [Hip Hop] {No Label}
├── artists
├── Artists
│   ├── BLACKPINK
│   │   ├── BLACKPINK - 2016. SQUARE ONE - Single [K-Pop] {YG Entertainment}
│   │ └── BLACKPINK - 2016. SQUARE TWO - Single [K-Pop] {YG Entertainment}
Expand All @@ -54,7 +54,7 @@ The virtual filesystem constructed from the above source directory is:
│   │   └── LOOΠΔ ODD EYE CIRCLE - 2017. Max & Match [K-Pop] {BlockBerry Creative}
│   └── YUZION
│   └── YUZION - 2019. Young Trapper [Hip Hop] {No Label}
├── genres
├── Genres
│   ├── Hip-Hop
│   │   └── YUZION - 2019. Young Trapper [Hip Hop] {No Label}
│   └── K-Pop
Expand All @@ -64,7 +64,7 @@ The virtual filesystem constructed from the above source directory is:
│      ├── LOOΠΔ - 2019. [X X] [K-Pop] {BlockBerry Creative}
│      ├── LOOΠΔ - 2020. [#] [K-Pop] {BlockBerry Creative}
│      └── LOOΠΔ ODD EYE CIRCLE - 2017. Max & Match [K-Pop] {BlockBerry Creative}
└── labels
└── Labels
├── BlockBerry Creative
│   ├── LOOΠΔ 1_3 - 2017. Love & Evil [K-Pop] {BlockBerry Creative}
│   ├── LOOΠΔ - 2019. [X X] [K-Pop] {BlockBerry Creative}
Expand Down Expand Up @@ -243,7 +243,6 @@ flowchart BT
S[Source Files] -->|Populates| C
C[Read Cache] -->|Renders| V
V[Virtual Filesystem] -->|Updates| S
W[Watchdog (Optional)] -->|Refreshes| C
```

This architecture takes care to ensure that there is a single source of truth
Expand Down
62 changes: 31 additions & 31 deletions rose/virtualfs.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def _cached_getattr(config: Config, path: str) -> dict[str, Any]:
p = parse_virtual_path(path)
logger.debug(f"Parsed getattr path as {p}")

if p.view == "root":
if p.view == "Root":
return mkstat("dir")
elif p.album and p.file:
if tp := track_exists(config, p.album, p.file):
Expand Down Expand Up @@ -79,34 +79,34 @@ def readdir(self, path: str, _: int) -> Iterator[str]:

yield from [".", ".."]

if p.view == "root":
if p.view == "Root":
yield from [
"albums",
"artists",
"genres",
"labels",
"Albums",
"Artists",
"Genres",
"Labels",
]
elif p.album:
rf = get_release_files(self.config, p.album)
for track in rf.tracks:
yield track.virtual_filename
if rf.cover:
yield rf.cover.name
elif p.artist or p.genre or p.label or p.view == "albums":
elif p.artist or p.genre or p.label or p.view == "Albums":
for album in list_releases(
self.config,
sanitized_artist_filter=p.artist,
sanitized_genre_filter=p.genre,
sanitized_label_filter=p.label,
):
yield album.virtual_dirname
elif p.view == "artists":
elif p.view == "Artists":
for artist in list_artists(self.config):
yield sanitize_filename(artist)
elif p.view == "genres":
elif p.view == "Genres":
for genre in list_genres(self.config):
yield sanitize_filename(genre)
elif p.view == "labels":
elif p.view == "Labels":
for label in list_labels(self.config):
yield sanitize_filename(label)
else:
Expand Down Expand Up @@ -142,7 +142,7 @@ def read(self, path: str, length: int, offset: int, fh: int) -> bytes:

@dataclass
class ParsedPath:
view: Literal["root", "albums", "artists", "genres", "labels"] | None
view: Literal["Root", "Albums", "Artists", "Genres", "Labels"] | None
artist: str | None = None
genre: str | None = None
label: str | None = None
Expand All @@ -154,48 +154,48 @@ def parse_virtual_path(path: str) -> ParsedPath:
parts = path.split("/")[1:] # First part is always empty string.

if len(parts) == 1 and parts[0] == "":
return ParsedPath(view="root")
return ParsedPath(view="Root")

if parts[0] == "albums":
if parts[0] == "Albums":
if len(parts) == 1:
return ParsedPath(view="albums")
return ParsedPath(view="Albums")
if len(parts) == 2:
return ParsedPath(view="albums", album=parts[1])
return ParsedPath(view="Albums", album=parts[1])
if len(parts) == 3:
return ParsedPath(view="albums", album=parts[1], file=parts[2])
return ParsedPath(view="Albums", album=parts[1], file=parts[2])
raise fuse.FuseOSError(errno.ENOENT)

if parts[0] == "artists":
if parts[0] == "Artists":
if len(parts) == 1:
return ParsedPath(view="artists")
return ParsedPath(view="Artists")
if len(parts) == 2:
return ParsedPath(view="artists", artist=parts[1])
return ParsedPath(view="Artists", artist=parts[1])
if len(parts) == 3:
return ParsedPath(view="artists", artist=parts[1], album=parts[2])
return ParsedPath(view="Artists", artist=parts[1], album=parts[2])
if len(parts) == 4:
return ParsedPath(view="artists", artist=parts[1], album=parts[2], file=parts[3])
return ParsedPath(view="Artists", artist=parts[1], album=parts[2], file=parts[3])
raise fuse.FuseOSError(errno.ENOENT)

if parts[0] == "genres":
if parts[0] == "Genres":
if len(parts) == 1:
return ParsedPath(view="genres")
return ParsedPath(view="Genres")
if len(parts) == 2:
return ParsedPath(view="genres", genre=parts[1])
return ParsedPath(view="Genres", genre=parts[1])
if len(parts) == 3:
return ParsedPath(view="genres", genre=parts[1], album=parts[2])
return ParsedPath(view="Genres", genre=parts[1], album=parts[2])
if len(parts) == 4:
return ParsedPath(view="genres", genre=parts[1], album=parts[2], file=parts[3])
return ParsedPath(view="Genres", genre=parts[1], album=parts[2], file=parts[3])
raise fuse.FuseOSError(errno.ENOENT)

if parts[0] == "labels":
if parts[0] == "Labels":
if len(parts) == 1:
return ParsedPath(view="labels")
return ParsedPath(view="Labels")
if len(parts) == 2:
return ParsedPath(view="labels", label=parts[1])
return ParsedPath(view="Labels", label=parts[1])
if len(parts) == 3:
return ParsedPath(view="labels", label=parts[1], album=parts[2])
return ParsedPath(view="Labels", label=parts[1], album=parts[2])
if len(parts) == 4:
return ParsedPath(view="labels", label=parts[1], album=parts[2], file=parts[3])
return ParsedPath(view="Labels", label=parts[1], album=parts[2], file=parts[3])
raise fuse.FuseOSError(errno.ENOENT)

raise fuse.FuseOSError(errno.ENOENT)
Expand Down
68 changes: 34 additions & 34 deletions rose/virtualfs_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,43 +32,43 @@ def can_read(p: Path) -> bool:

with startfs(config):
root = config.fuse_mount_dir
assert (root / "albums").is_dir()
assert (root / "albums" / "r1").is_dir()
assert not (root / "albums" / "lalala").exists()
assert (root / "albums" / "r1" / "01.m4a").is_file()
assert not (root / "albums" / "r1" / "lala.m4a").exists()
assert can_read(root / "albums" / "r1" / "01.m4a")
assert (root / "Albums").is_dir()
assert (root / "Albums" / "r1").is_dir()
assert not (root / "Albums" / "lalala").exists()
assert (root / "Albums" / "r1" / "01.m4a").is_file()
assert not (root / "Albums" / "r1" / "lala.m4a").exists()
assert can_read(root / "Albums" / "r1" / "01.m4a")

assert (root / "albums" / "r2" / "cover.jpg").is_file()
assert can_read(root / "albums" / "r2" / "cover.jpg")
assert not (root / "albums" / "r1" / "cover.jpg").exists()
assert not (root / "albums" / "r2" / "cover.png").exists()
assert (root / "Albums" / "r2" / "cover.jpg").is_file()
assert can_read(root / "Albums" / "r2" / "cover.jpg")
assert not (root / "Albums" / "r1" / "cover.jpg").exists()
assert not (root / "Albums" / "r2" / "cover.png").exists()

assert (root / "artists").is_dir()
assert (root / "artists" / "Bass Man").is_dir()
assert not (root / "artists" / "lalala").exists()
assert (root / "artists" / "Bass Man" / "r1").is_dir()
assert not (root / "artists" / "Bass Man" / "lalala").exists()
assert (root / "artists" / "Bass Man" / "r1" / "01.m4a").is_file()
assert not (root / "artists" / "Bass Man" / "r1" / "lalala.m4a").exists()
assert can_read(root / "artists" / "Bass Man" / "r1" / "01.m4a")
assert (root / "Artists").is_dir()
assert (root / "Artists" / "Bass Man").is_dir()
assert not (root / "Artists" / "lalala").exists()
assert (root / "Artists" / "Bass Man" / "r1").is_dir()
assert not (root / "Artists" / "Bass Man" / "lalala").exists()
assert (root / "Artists" / "Bass Man" / "r1" / "01.m4a").is_file()
assert not (root / "Artists" / "Bass Man" / "r1" / "lalala.m4a").exists()
assert can_read(root / "Artists" / "Bass Man" / "r1" / "01.m4a")

assert (root / "genres").is_dir()
assert (root / "genres" / "Techno").is_dir()
assert not (root / "genres" / "lalala").exists()
assert (root / "genres" / "Techno" / "r1").is_dir()
assert not (root / "genres" / "Techno" / "lalala").exists()
assert (root / "genres" / "Techno" / "r1" / "01.m4a").is_file()
assert not (root / "genres" / "Techno" / "r1" / "lalala.m4a").exists()
assert can_read(root / "genres" / "Techno" / "r1" / "01.m4a")
assert (root / "Genres").is_dir()
assert (root / "Genres" / "Techno").is_dir()
assert not (root / "Genres" / "lalala").exists()
assert (root / "Genres" / "Techno" / "r1").is_dir()
assert not (root / "Genres" / "Techno" / "lalala").exists()
assert (root / "Genres" / "Techno" / "r1" / "01.m4a").is_file()
assert not (root / "Genres" / "Techno" / "r1" / "lalala.m4a").exists()
assert can_read(root / "Genres" / "Techno" / "r1" / "01.m4a")

assert (root / "labels").is_dir()
assert (root / "labels" / "Silk Music").is_dir()
assert not (root / "labels" / "lalala").exists()
assert (root / "labels" / "Silk Music" / "r1").is_dir()
assert not (root / "labels" / "Silk Music" / "lalala").exists()
assert (root / "labels" / "Silk Music" / "r1" / "01.m4a").is_file()
assert not (root / "labels" / "Silk Music" / "r1" / "lalala").exists()
assert can_read(root / "labels" / "Silk Music" / "r1" / "01.m4a")
assert (root / "Labels").is_dir()
assert (root / "Labels" / "Silk Music").is_dir()
assert not (root / "Labels" / "lalala").exists()
assert (root / "Labels" / "Silk Music" / "r1").is_dir()
assert not (root / "Labels" / "Silk Music" / "lalala").exists()
assert (root / "Labels" / "Silk Music" / "r1" / "01.m4a").is_file()
assert not (root / "Labels" / "Silk Music" / "r1" / "lalala").exists()
assert can_read(root / "Labels" / "Silk Music" / "r1" / "01.m4a")

assert not (root / "lalala").exists()

0 comments on commit f3f5ea0

Please sign in to comment.