From 43f1a1dd1b44065663a797603012394c52a9baea Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Sat, 13 May 2023 13:31:58 -0300 Subject: use ESM module syntax & update tui-lib Exciting update! This doesn't make any substantial changes exactly but does update the most quickly-archaic parts of older Node code. --- playlist-utils.js | 137 ++++++++++++++++++------------------------------------ 1 file changed, 44 insertions(+), 93 deletions(-) (limited to 'playlist-utils.js') diff --git a/playlist-utils.js b/playlist-utils.js index 227c985..0fe26df 100644 --- a/playlist-utils.js +++ b/playlist-utils.js @@ -1,16 +1,12 @@ 'use strict' -const path = require('path') -const fs = require('fs') +import path from 'node:path' -const { promisify } = require('util') -const unlink = promisify(fs.unlink) +import {shuffleArray} from './general-util.js' -const { shuffleArray } = require('./general-util') +export const parentSymbol = Symbol('Parent group') -const parentSymbol = Symbol('Parent group') - -function updatePlaylistFormat(playlist) { +export function updatePlaylistFormat(playlist) { const defaultPlaylist = { options: [], items: [] @@ -43,7 +39,7 @@ function updatePlaylistFormat(playlist) { return updateGroupFormat(fullPlaylistObj) } -function updateGroupFormat(group) { +export function updateGroupFormat(group) { const defaultGroup = { name: '', items: [] @@ -61,7 +57,7 @@ function updateGroupFormat(group) { groupObj.items = groupObj.items.map(item => { // Check if it's a group; if not, it's probably a track. - if (typeof item[1] === 'array' || item.items) { + if (Array.isArray(item[1]) || item.items) { item = updateGroupFormat(item) } else { item = updateTrackFormat(item) @@ -85,7 +81,7 @@ function updateGroupFormat(group) { return groupObj } -function updateTrackFormat(track) { +export function updateTrackFormat(track) { const defaultTrack = { name: '', downloaderArg: '' @@ -106,7 +102,7 @@ function updateTrackFormat(track) { return Object.assign(defaultTrack, trackObj) } -function cloneGrouplike(grouplike) { +export function cloneGrouplike(grouplike) { const newGrouplike = { name: grouplike.name, items: grouplike.items.map(item => { @@ -128,7 +124,7 @@ function cloneGrouplike(grouplike) { return newGrouplike } -function filterTracks(grouplike, handleTrack) { +export function filterTracks(grouplike, handleTrack) { // Recursively filters every track in the passed grouplike. The track-handler // function passed should either return true (to keep a track) or false (to // remove the track). After tracks are filtered, groups which contain no @@ -161,7 +157,7 @@ function filterTracks(grouplike, handleTrack) { }) } -function flattenGrouplike(grouplike) { +export function flattenGrouplike(grouplike) { // Flattens a group-like, taking all of the non-group items (tracks) at all // levels in the group tree and returns them as a new group containing those // tracks. @@ -177,7 +173,7 @@ function flattenGrouplike(grouplike) { } } -function countTotalTracks(item) { +export function countTotalTracks(item) { // Returns the total number of tracks in a grouplike, including tracks in any // descendant groups. Basically the same as flattenGrouplike().items.length. @@ -191,7 +187,7 @@ function countTotalTracks(item) { } } -function shuffleOrderOfGroups(grouplike) { +export function shuffleOrderOfGroups(grouplike) { // OK, this is opinionated on how it should work, but I think it Makes Sense. // Also sorry functional-programming friends, I'm sure this is a horror. // (FYI, this is the same as how http-music used to work with shuffle-groups, @@ -209,12 +205,12 @@ function shuffleOrderOfGroups(grouplike) { return {items: shuffleArray(items)} } -function reverseOrderOfGroups(grouplike) { +export function reverseOrderOfGroups(grouplike) { const { items } = collapseGrouplike(grouplike) return {items: items.reverse()} } -function collectGrouplikeChildren(grouplike, filter = null) { +export function collectGrouplikeChildren(grouplike, filter = null) { // Collects all descendants of a grouplike into a single flat array. // Can be passed a filter function, which will decide whether or not to add // an item to the return array. However, note that all descendants will be @@ -237,7 +233,7 @@ function collectGrouplikeChildren(grouplike, filter = null) { return items } -function partiallyFlattenGrouplike(grouplike, resultDepth) { +export function partiallyFlattenGrouplike(grouplike, resultDepth) { // Flattens a grouplike so that it is never more than a given number of // groups deep, INCLUDING the "top" group -- e.g. a resultDepth of 2 // means that there can be one level of groups remaining in the resulting @@ -258,7 +254,7 @@ function partiallyFlattenGrouplike(grouplike, resultDepth) { return {items} } -function collapseGrouplike(grouplike) { +export function collapseGrouplike(grouplike) { // Similar to partiallyFlattenGrouplike, but doesn't discard the individual // ordering of tracks; rather, it just collapses them all to one level. @@ -284,7 +280,7 @@ function collapseGrouplike(grouplike) { return {items: ret} } -function filterGrouplikeByProperty(grouplike, property, value) { +export function filterGrouplikeByProperty(grouplike, property, value) { // Returns a copy of the original grouplike, only keeping tracks with the // given property-value pair. (If the track's value for the given property // is an array, this will check if that array includes the given value.) @@ -314,13 +310,13 @@ function filterGrouplikeByProperty(grouplike, property, value) { }) } -function filterPlaylistByPathString(playlist, pathString) { +export function filterPlaylistByPathString(playlist, pathString) { // Calls filterGroupContentsByPath, taking an unparsed path string. return filterGrouplikeByPath(playlist, parsePathString(pathString)) } -function filterGrouplikeByPath(grouplike, pathParts) { +export function filterGrouplikeByPath(grouplike, pathParts) { // Finds a group by following the given group path and returns it. If the // function encounters an item in the group path that is not found, it logs // a warning message and returns the group found up to that point. If the @@ -371,13 +367,13 @@ function filterGrouplikeByPath(grouplike, pathParts) { } } -function removeGroupByPathString(playlist, pathString) { +export function removeGroupByPathString(playlist, pathString) { // Calls removeGroupByPath, taking a path string, rather than a parsed path. return removeGroupByPath(playlist, parsePathString(pathString)) } -function removeGroupByPath(playlist, pathParts) { +export function removeGroupByPath(playlist, pathParts) { // Removes the group at the given path from the given playlist. const groupToRemove = filterGrouplikeByPath(playlist, pathParts) @@ -418,7 +414,7 @@ function removeGroupByPath(playlist, pathParts) { } } -function getPlaylistTreeString(playlist, showTracks = false) { +export function getPlaylistTreeString(playlist, showTracks = false) { function recursive(group) { const groups = group.items.filter(x => isGroup(x)) const nonGroups = group.items.filter(x => !isGroup(x)) @@ -454,7 +450,7 @@ function getPlaylistTreeString(playlist, showTracks = false) { return recursive(playlist) } -function getItemPath(item) { +export function getItemPath(item) { if (item[parentSymbol]) { return [...getItemPath(item[parentSymbol]), item] } else { @@ -462,7 +458,7 @@ function getItemPath(item) { } } -function getItemPathString(item) { +export function getItemPathString(item) { // Gets the playlist path of an item by following its parent chain. // // Returns a string in format Foo/Bar/Baz, where Foo and Bar are group @@ -489,12 +485,12 @@ function getItemPathString(item) { } } -function parsePathString(pathString) { +export function parsePathString(pathString) { const pathParts = pathString.split('/').filter(item => item.length) return pathParts } -function getTrackIndexInParent(track) { +export function getTrackIndexInParent(track) { if (parentSymbol in track === false) { throw new Error( 'getTrackIndexInParent called with a track that has no parent!' @@ -505,6 +501,11 @@ function getTrackIndexInParent(track) { let i = 0, foundTrack = false; for (; i < parent.items.length; i++) { + // TODO: Port isSameTrack from http-music, if it makes sense - doing + // so involves porting the [oldSymbol] property on all tracks and groups, + // so may or may not be the right call. This function isn't used anywhere + // in mtui so it'll take a little extra investigation. + /* eslint-disable-next-line no-undef */ if (isSameTrack(track, parent.items[i])) { foundTrack = true break @@ -519,14 +520,14 @@ function getTrackIndexInParent(track) { } const nameWithoutTrackNumberSymbol = Symbol('Cached name without track number') -function getNameWithoutTrackNumber(track) { +export function getNameWithoutTrackNumber(track) { // A "part" is a series of numeric digits, separated from other parts by // whitespace, dashes, and dots, always preceding either the first non- // numeric/separator character or (if there are no such characters) the // first word (i.e. last whitespace). const getNumberOfParts = ({ name }) => { - name = name.replace(/^[\-\s.]+$/, '') - const match = name.match(/[^0-9\-\s.]/) + name = name.replace(/^[-\s.]+$/, '') + const match = name.match(/[^0-9-\s.]/) if (match) { if (match.index === 0) { return 0 @@ -538,12 +539,12 @@ function getNameWithoutTrackNumber(track) { } else { return 0 } - name = name.replace(/[\-\s.]+$/, '') - return name.split(/[\-\s.]+/g).length + name = name.replace(/[-\s.]+$/, '') + return name.split(/[-\s.]+/g).length } const removeParts = (name, numParts) => { - const regex = new RegExp(String.raw`[\-\s.]{0,}([0-9]+[\-\s.]+){${numParts},${numParts}}`) + const regex = new RegExp(String.raw`[-\s.]{0,}([0-9]+[-\s.]+){${numParts},${numParts}}`) return track.name.replace(regex, '') } @@ -591,24 +592,24 @@ function getNameWithoutTrackNumber(track) { } } -function isGroup(obj) { +export function isGroup(obj) { return !!(obj && obj.items) } -function isTrack(obj) { +export function isTrack(obj) { return !!(obj && obj.downloaderArg) } -function isPlayable(obj) { +export function isPlayable(obj) { return isGroup(obj) || isTrack(obj) } -function isOpenable(obj) { +export function isOpenable(obj) { return !!(obj && obj.url) } -function searchForItem(grouplike, value, preferredStartIndex = -1) { +export function searchForItem(grouplike, value, preferredStartIndex = -1) { if (value.length) { // We prioritize searching past the index that the user opened the jump // element from (oldFocusedIndex). This is so that it's more practical @@ -648,7 +649,7 @@ function searchForItem(grouplike, value, preferredStartIndex = -1) { return null } -function getCorrespondingFileForItem(item, extension) { +export function getCorrespondingFileForItem(item, extension) { if (!(item && item.url)) { return null } @@ -673,7 +674,7 @@ function getCorrespondingFileForItem(item, extension) { return null } -function getCorrespondingPlayableForFile(item) { +export function getCorrespondingPlayableForFile(item) { if (!(item && item.url)) { return null } @@ -691,53 +692,3 @@ function getCorrespondingPlayableForFile(item) { const basename = path.basename(item.url, path.extname(item.url)) return parent.items.find(item => isPlayable(item) && path.basename(item.url, path.extname(item.url)) === basename) } - -module.exports = { - parentSymbol, - updatePlaylistFormat, updateGroupFormat, updateTrackFormat, - cloneGrouplike, - filterTracks, - flattenGrouplike, countTotalTracks, - shuffleOrderOfGroups, - reverseOrderOfGroups, - partiallyFlattenGrouplike, collapseGrouplike, - filterGrouplikeByProperty, - filterPlaylistByPathString, filterGrouplikeByPath, - removeGroupByPathString, removeGroupByPath, - getPlaylistTreeString, - getItemPath, getItemPathString, - parsePathString, - getTrackIndexInParent, - getNameWithoutTrackNumber, - searchForItem, - getCorrespondingFileForItem, - getCorrespondingPlayableForFile, - isGroup, isTrack, - isOpenable, isPlayable -} - -if (require.main === module) { - { - const group = updateGroupFormat({items: [ - {name: '- 1.01 Hello World 425', downloaderArg: 'x'}, - {name: '1.02 Aww Yeah 371', downloaderArg: 'x'}, - {name: ' 1.03 Here Goes 472', downloaderArg: 'x'} - ]}) - - for (let i = 0; i < group.items.length; i++) { - console.log(group.items[i].name, '->', getNameWithoutTrackNumber(group.items[i])) - } - } - - { - const group = updateGroupFormat({items: [ - {name: 'BAM #1', downloaderArg: 'x'}, - {name: 'BAM #2', downloaderArg: 'x'}, - {name: 'BAM #3.1 - no', downloaderArg: 'x'} - ]}) - - for (let i = 0; i < group.items.length; i++) { - console.log(group.items[i].name, '->', getNameWithoutTrackNumber(group.items[i])) - } - } -} -- cgit 1.3.0-6-gf8a5