general fixes for future image gallery, and published ECM collection
This commit is contained in:
parent
00a7b0447f
commit
c916d71682
|
@ -1 +1,133 @@
|
||||||
[]
|
[
|
||||||
|
{
|
||||||
|
"title": "1 MeredithMonk 1972 Paris",
|
||||||
|
"parent_dir": "images",
|
||||||
|
"media": "1_MeredithMonk_1972_Paris",
|
||||||
|
"images": [
|
||||||
|
{
|
||||||
|
"title": "MeredithMonk 1972 ParisScore01",
|
||||||
|
"media": "MeredithMonk_1972_ParisScore01.jpg",
|
||||||
|
"thumb": "MeredithMonk_1972_ParisScore01.thumb.jpg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "MeredithMonk 1972 ParisScore02",
|
||||||
|
"media": "MeredithMonk_1972_ParisScore02.jpg",
|
||||||
|
"thumb": "MeredithMonk_1972_ParisScore02.thumb.jpg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "MeredithMonk 1972 ParisScore03",
|
||||||
|
"media": "MeredithMonk_1972_ParisScore03.jpg",
|
||||||
|
"thumb": "MeredithMonk_1972_ParisScore03.thumb.jpg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "MeredithMonk 1972 ParisScore04",
|
||||||
|
"media": "MeredithMonk_1972_ParisScore04.jpg",
|
||||||
|
"thumb": "MeredithMonk_1972_ParisScore04.thumb.jpg"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "2 Series of Watercolors (Untitled Studies), 1970-1986",
|
||||||
|
"parent_dir": "images",
|
||||||
|
"media": "2_Series of Watercolors (Untitled Studies), 1970-1986. (photographed 2007 Eileen Costa)",
|
||||||
|
"images": [
|
||||||
|
{
|
||||||
|
"title": "001",
|
||||||
|
"media": "001.jpg",
|
||||||
|
"thumb": "001.thumb.jpg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "002",
|
||||||
|
"media": "002.jpg",
|
||||||
|
"thumb": "002.thumb.jpg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "003",
|
||||||
|
"media": "003.jpg",
|
||||||
|
"thumb": "003.thumb.jpg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "004",
|
||||||
|
"media": "004.jpg",
|
||||||
|
"thumb": "004.thumb.jpg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "005",
|
||||||
|
"media": "005.jpg",
|
||||||
|
"thumb": "005.thumb.jpg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "006",
|
||||||
|
"media": "006.jpg",
|
||||||
|
"thumb": "006.thumb.jpg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "007",
|
||||||
|
"media": "007.jpg",
|
||||||
|
"thumb": "007.thumb.jpg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "008",
|
||||||
|
"media": "008.jpg",
|
||||||
|
"thumb": "008.thumb.jpg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "009",
|
||||||
|
"media": "009.jpg",
|
||||||
|
"thumb": "009.thumb.jpg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "010",
|
||||||
|
"media": "010.jpg",
|
||||||
|
"thumb": "010.thumb.jpg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "011",
|
||||||
|
"media": "011.jpg",
|
||||||
|
"thumb": "011.thumb.jpg"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "3 Posters",
|
||||||
|
"parent_dir": "images",
|
||||||
|
"media": "3_Posters",
|
||||||
|
"images": [
|
||||||
|
{
|
||||||
|
"title": "04 MERCY 2002",
|
||||||
|
"media": "04_MERCY_2002.jpg",
|
||||||
|
"thumb": "04_MERCY_2002.thumb.jpg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "122 THE GAMES",
|
||||||
|
"media": "122_THE_GAMES.jpg",
|
||||||
|
"thumb": "122_THE_GAMES.thumb.jpg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "146 Songs from the Hill Town Hall",
|
||||||
|
"media": "146_Songs_from_the_Hill_Town_Hall.jpg",
|
||||||
|
"thumb": "146_Songs_from_the_Hill_Town_Hall.thumb.jpg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "153 Vessel 2",
|
||||||
|
"media": "153_Vessel_2.jpg",
|
||||||
|
"thumb": "153_Vessel_2.thumb.jpg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "57 IMPERMENANCE MAP",
|
||||||
|
"media": "57_IMPERMENANCE_MAP.jpg",
|
||||||
|
"thumb": "57_IMPERMENANCE_MAP.thumb.jpg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "ATLAS world premiere flyer 1991",
|
||||||
|
"media": "ATLAS world premiere flyer 1991.jpg",
|
||||||
|
"thumb": "ATLAS world premiere flyer 1991.thumb.jpg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Quarry 1976 LaMama original poster",
|
||||||
|
"media": "Quarry_1976_LaMama_original poster.jpg",
|
||||||
|
"thumb": "Quarry_1976_LaMama_original poster.thumb.jpg"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
|
@ -23,6 +23,32 @@ async function generateWaveform(audioFile, outputDir) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function generateThumb(imgPath, outputDir) {
|
||||||
|
const { name, ext } = path.parse(imgPath)
|
||||||
|
|
||||||
|
if (!ext) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
const thumb = path.format({ name: `${name}.thumb`, ext })
|
||||||
|
const inputFile = path.join(outputDir, imgPath)
|
||||||
|
const outputFile = path.join(outputDir, thumb)
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
exec(
|
||||||
|
`magick "${inputFile}" -resize 250x250\\> "${outputFile}"`,
|
||||||
|
(error, stdout) => {
|
||||||
|
if (error) {
|
||||||
|
console.error(error)
|
||||||
|
reject(error)
|
||||||
|
} else {
|
||||||
|
resolve(thumb)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// MAIN FUNCTION
|
// MAIN FUNCTION
|
||||||
async function main() {
|
async function main() {
|
||||||
// variable for incoming variable
|
// variable for incoming variable
|
||||||
|
@ -35,9 +61,29 @@ async function main() {
|
||||||
let waveform = false
|
let waveform = false
|
||||||
let update = []
|
let update = []
|
||||||
|
|
||||||
|
if (process.argv.length < 3 || process.argv.includes('-h')) {
|
||||||
|
console.log(`
|
||||||
|
Files to Json converter
|
||||||
|
|
||||||
|
Commands :
|
||||||
|
-h : This message
|
||||||
|
-dir : The input directory to scan
|
||||||
|
-o : The output directory of the json file. If not set will default to current working directory
|
||||||
|
-u : [NOT IMPLEMENTED] List of comma separated feilds to update. Will only overwrite that which is set
|
||||||
|
-r : Recurse the directory (once) for sub-fields. Albums and image categories for example.
|
||||||
|
|
||||||
|
Other flags
|
||||||
|
--images-only : For a folder with only images, rather than media files with associated thumbs.
|
||||||
|
--dry-run : Output to the console
|
||||||
|
--formatted : Directory or file name, will format on the the undersore : "title_details".
|
||||||
|
This takes the arguments, parent, recurse or both. Defaults to both.
|
||||||
|
--gen-waveform : [may break if recursing] If going through audio files can generate waveform images for the file.
|
||||||
|
`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// get command line arguments
|
// get command line arguments
|
||||||
process.argv.forEach(function (val, index) {
|
process.argv.forEach((val, index) => {
|
||||||
// console.log(index + ': ' + val)
|
|
||||||
switch (val) {
|
switch (val) {
|
||||||
case '-dir':
|
case '-dir':
|
||||||
mediaDir = process.argv[index + 1] || ''
|
mediaDir = process.argv[index + 1] || ''
|
||||||
|
@ -69,7 +115,12 @@ async function main() {
|
||||||
dryRun = true
|
dryRun = true
|
||||||
break
|
break
|
||||||
case '--formatted':
|
case '--formatted':
|
||||||
formatted = ['parent', 'recurse', 'both' ].includes(process.argv[index + 1]) ? process.argv[index + 1] : 'both'
|
formatted = [
|
||||||
|
'parent',
|
||||||
|
'recurse',
|
||||||
|
'both' ].includes(
|
||||||
|
process.argv[index + 1]
|
||||||
|
) ? process.argv[index + 1] : 'both'
|
||||||
break
|
break
|
||||||
case '--gen-waveform':
|
case '--gen-waveform':
|
||||||
waveform = true
|
waveform = true
|
||||||
|
@ -93,11 +144,9 @@ async function main() {
|
||||||
let media = []
|
let media = []
|
||||||
let images = []
|
let images = []
|
||||||
|
|
||||||
|
|
||||||
// If recursing we are making the "media" the directories where we will find the
|
|
||||||
// acutal media to playback or see
|
// acutal media to playback or see
|
||||||
if (recurse) {
|
if (recurse) {
|
||||||
media = dirList.filter(i => !i.match(/\.[^/.]+$/))
|
media = dirList.filter(i => !i.match(/\.[^/.]{1,4}$/))
|
||||||
} else {
|
} else {
|
||||||
media = dirList.filter(i => i.match(/.(mp\d|m\d\w)$/i))
|
media = dirList.filter(i => i.match(/.(mp\d|m\d\w)$/i))
|
||||||
}
|
}
|
||||||
|
@ -158,13 +207,19 @@ async function main() {
|
||||||
// if images only
|
// if images only
|
||||||
if (imagesOnly) {
|
if (imagesOnly) {
|
||||||
// setup object per image in array
|
// setup object per image in array
|
||||||
_r.images = files
|
_r.images = files.filter(f => !f.media.match(/\.thumb\.[^/.]{1,4}$/i))
|
||||||
} else {
|
} else {
|
||||||
_r.album = true
|
_r.album = true
|
||||||
_r.tracks = files
|
_r.tracks = files
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (imagesOnly) {
|
||||||
|
_r.images = await Promise.all(_r.images.map(async i => {
|
||||||
|
return { ...i, thumb: await generateThumb(i.media, path.join(mediaDir, _r.media)) }
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
// return the result to the 'obj' variable
|
// return the result to the 'obj' variable
|
||||||
return _r
|
return _r
|
||||||
}))
|
}))
|
||||||
|
@ -203,7 +258,7 @@ function genMetadata(dir, formatted) {
|
||||||
details = d ? d.replace(/\.+(mp\d|m\dv)$/i, '') : ''
|
details = d ? d.replace(/\.+(mp\d|m\dv)$/i, '') : ''
|
||||||
} else {
|
} else {
|
||||||
// else just set title to filename without extensions
|
// else just set title to filename without extensions
|
||||||
title = dir.replace(/\.[^/.]+$/, '')
|
title = dir.replace(/\.[^/.]+$/, '').replace(/_/g, ' ')
|
||||||
}
|
}
|
||||||
|
|
||||||
return { title, details }
|
return { title, details }
|
||||||
|
|
|
@ -52,7 +52,6 @@ export default new Router({
|
||||||
short: 'ECM',
|
short: 'ECM',
|
||||||
icon: 'headphones',
|
icon: 'headphones',
|
||||||
group: 'Music & Sound',
|
group: 'Music & Sound',
|
||||||
disabled: true,
|
|
||||||
plugins: [
|
plugins: [
|
||||||
lazy(() => import('../views/audio.js'))
|
lazy(() => import('../views/audio.js'))
|
||||||
],
|
],
|
||||||
|
|
|
@ -31,7 +31,7 @@ class VerticalCard extends LitElement {
|
||||||
return html`
|
return html`
|
||||||
<div @click=${this.select} class=${this.selected ? 'selected' : ''}>
|
<div @click=${this.select} class=${this.selected ? 'selected' : ''}>
|
||||||
<picture>
|
<picture>
|
||||||
<img src="/media/${Router.route.path}/${this.details.image}">
|
<img src="/media${Router.route.path}/${this.details.image}">
|
||||||
</picture>
|
</picture>
|
||||||
<aside>
|
<aside>
|
||||||
<p class="title">${this.details?.title}</p>
|
<p class="title">${this.details?.title}</p>
|
||||||
|
@ -70,7 +70,6 @@ class VerticalCard extends LitElement {
|
||||||
picture {
|
picture {
|
||||||
display: block;
|
display: block;
|
||||||
background: var(--image-placeholder);
|
background: var(--image-placeholder);
|
||||||
/* aspect-ratio: 1 / 1; */
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,8 +27,11 @@ class ImageView extends LitElement {
|
||||||
const res = await fetch('/data/images.json')
|
const res = await fetch('/data/images.json')
|
||||||
const json = await res.json()
|
const json = await res.json()
|
||||||
|
|
||||||
|
|
||||||
json.forEach(i => i.path = `/media${Router.route.path}/${i.media}`)
|
json.forEach(i => i.path = `/media${Router.route.path}/${i.media}`)
|
||||||
|
|
||||||
|
console.log(json[0])
|
||||||
|
|
||||||
this.images = json
|
this.images = json
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
|
@ -64,7 +67,7 @@ class ImageView extends LitElement {
|
||||||
i => html`
|
i => html`
|
||||||
<mm-vcard
|
<mm-vcard
|
||||||
@click=${this.selectImage}
|
@click=${this.selectImage}
|
||||||
.details=${ { ...i, section: section.media } }
|
.details=${ { ...i, section: section.media, image: `${section.media}/${i.thumb}` } }
|
||||||
?selected=${i.title == this.selected?.title}
|
?selected=${i.title == this.selected?.title}
|
||||||
>
|
>
|
||||||
</mm-vcard>
|
</mm-vcard>
|
||||||
|
|
Loading…
Reference in New Issue