683 lines
17 KiB
JavaScript
683 lines
17 KiB
JavaScript
'use strict'
|
|
|
|
const fs = require( 'fs' )
|
|
, md5 = require( 'md5' )
|
|
, path = require( 'path' )
|
|
, gm = require( 'gm' )
|
|
, url = require( 'url' )
|
|
, range = require( 'range-2018.js' )
|
|
|
|
, DB = require( './db.js' )
|
|
, GetID = require( './get-id.js' )
|
|
, Now = require( './readable-timestamp.js' )
|
|
, Config = require( '../config.js' )
|
|
|
|
const Sizes =
|
|
exports.Sizes =
|
|
{ S : 200
|
|
, N : 490
|
|
, M : 800
|
|
, L : 1600
|
|
}
|
|
|
|
|
|
const SortAccounts = arrAccounts =>
|
|
arrAccounts
|
|
.filter( a => a && a.trim( ) )
|
|
.sort( ( a,b ) => b[ 0 ] == a[ 0 ]
|
|
? 'i' == a[ 0xA ]
|
|
: 'r' == a[ 0 ]
|
|
)
|
|
|
|
const getHashFromPhotoURL =
|
|
exports.getHashFromPhotoURL = PhotoURL =>
|
|
PhotoURL.match( /([^\/_]+)_?L\.jpg$/ )[ 1 ]
|
|
|
|
const PhotoHashmapToSQL =
|
|
exports.PhotoHashmapToSQL = PhotoHashmap =>
|
|
Object.keys( PhotoHashmap )
|
|
.map( k => `Photo_${ k } = "${ PhotoHashmap[ k ] }"` )
|
|
.join( ',' )
|
|
|
|
const SmallerSizes =
|
|
exports.SmallerSizes =
|
|
Object.keys( Sizes )
|
|
.filter( k => 'L' != k )
|
|
|
|
const HashOrNr =
|
|
exports.HashOrNr = Hash =>
|
|
( Hash
|
|
&& Hash.length
|
|
&& ( Hash.length > 2 )
|
|
)
|
|
? Hash + '_'
|
|
: Hash
|
|
|
|
const getURL =
|
|
exports.getURL = ({ SKU, Hash, Size, EXT }) =>
|
|
url.resolve
|
|
( Config.Paths.imgGlobal
|
|
, path.join
|
|
( './'
|
|
, GetID( SKU )
|
|
, HashOrNr( Hash ) + Size + ( EXT || '.jpg' )
|
|
)
|
|
)
|
|
|
|
const getFilepath =
|
|
exports.getFilepath = ({ SKU, Hash, Size, EXT }) =>
|
|
path.join
|
|
( Config.Paths.imgLocal
|
|
, GetID( SKU )
|
|
, HashOrNr( Hash ) + Size + ( EXT || '.jpg' )
|
|
)
|
|
|
|
const Resize =
|
|
exports.Resize = ({ SKU, Hash }) =>
|
|
new Promise( ( resolve, reject ) =>
|
|
{ SmallerSizes.forEach( ( Size, i, a ) =>
|
|
{ gm( getFilepath({ SKU, Hash, Size : 'L' }) )
|
|
.resize( Sizes[ Size ], Sizes[ Size ] )
|
|
.write( getFilepath({ SKU, Hash, Size }), err =>
|
|
{ if( err )
|
|
{ reject( err ) }
|
|
if( i == a.length - 1 )
|
|
{ resolve( true ) }
|
|
})
|
|
})
|
|
}).catch( err => console.error
|
|
( Now( )
|
|
, 'error resizing'
|
|
, '(Photos.Resize)'
|
|
, err
|
|
) )
|
|
|
|
const Convert_toBW = path =>
|
|
new Promise( ( resolve, reject ) =>
|
|
{ gm( path )
|
|
.colorspace( 'GRAY' )
|
|
.write( path, err =>
|
|
{ if( err )
|
|
{ console.error
|
|
( Now( )
|
|
, 'error converting #10 to BW'
|
|
, path
|
|
, err
|
|
)
|
|
reject( false )
|
|
}
|
|
resolve( true )
|
|
})
|
|
|
|
}).catch( err => console.error
|
|
( Now( )
|
|
, 'error converting #10 to BW'
|
|
, '(Photos.Convert_toBW)'
|
|
, err
|
|
) )
|
|
|
|
const Process =
|
|
exports.Process = ({ FilePath, SKU, Variant, Nr }) =>
|
|
new Promise( async ( resolve, reject ) =>
|
|
{ if( 10 == Nr )
|
|
{ console.info( Now( ), 'converting to BW...\n' )
|
|
await Convert_toBW( FilePath )
|
|
}
|
|
|
|
const Hash = md5( fs.readFileSync( FilePath ) )
|
|
try
|
|
{ fs.mkdirSync( path.join( Config.Paths.imgLocal, GetID( SKU ) ) ) }
|
|
catch( err )
|
|
{ console.info( 'dir', path.join( Config.Paths.imgLocal, GetID( SKU ) ), 'exist' ) }
|
|
fs.renameSync( FilePath, getFilepath({ SKU, Hash, Size : 'L' }) )
|
|
|
|
const Varinat_Exist = await DB.read(
|
|
{ table : 'Photos'
|
|
, where : `( SKU = "${ SKU }"
|
|
AND Variant = "${ Variant }"
|
|
)`
|
|
})
|
|
|
|
if( !Varinat_Exist || !Varinat_Exist.length )
|
|
{ await createVariant({ SKU, Variant }) }
|
|
|
|
await DB.update(
|
|
{ table : 'Photos'
|
|
, set : ` Photo_${ Nr } = "${ getURL({ SKU, Hash, Size : 'L' }) }"
|
|
, Need_update = TRUE
|
|
`
|
|
, where : `( SKU = "${ SKU }"
|
|
AND Variant = "${ Variant }"
|
|
)`
|
|
})
|
|
|
|
await Resize({ SKU, Hash })
|
|
|
|
resolve( true )
|
|
|
|
}).catch( err => console.error
|
|
( Now( )
|
|
, 'error processing'
|
|
, '(Photos.Process)'
|
|
, err
|
|
) )
|
|
|
|
const Renumber =
|
|
exports.Renumber = ({ SKU, Variant, OldNr, NewNr }) =>
|
|
new Promise( async ( resolve, reject ) =>
|
|
{ const OldHashmap = await getHashmap(
|
|
{ SKU
|
|
, Variant
|
|
, arrNumbers : range( 1,10 )
|
|
})
|
|
const Photo_toShift = OldHashmap[ OldNr ]
|
|
|
|
let newArr = Object
|
|
.keys( OldHashmap )
|
|
.map( k => OldHashmap[ k ] )
|
|
newArr.unshift( null )
|
|
newArr.splice( OldNr, 1 )
|
|
newArr.splice( NewNr, 0, Photo_toShift )
|
|
|
|
let NewHashmap = { }
|
|
range( 1,10 ).map( Nr =>
|
|
{ NewHashmap[ Nr ] = newArr[ Nr ] })
|
|
|
|
console.info
|
|
( Now( )
|
|
, 'Renumbering\n from :'
|
|
, OldHashmap
|
|
, 'to :'
|
|
, NewHashmap
|
|
)
|
|
|
|
const _res = await DB.update(
|
|
{ table : 'Photos'
|
|
, set : PhotoHashmapToSQL( NewHashmap )
|
|
+ ', Need_update = TRUE'
|
|
, where : `( SKU = "${ SKU }"
|
|
AND Variant = "${ Variant }"
|
|
)`
|
|
})
|
|
|
|
if( _res && _res.length )
|
|
{ resolve( true ) }
|
|
else
|
|
{ reject( _res ) }
|
|
|
|
}).catch( err => console.error
|
|
( Now( )
|
|
, 'error renumbering'
|
|
, '(Photos.Renumber)'
|
|
, err
|
|
) )
|
|
|
|
|
|
const URLoccurrences =
|
|
exports.URLoccurrences = ({ SKU, PhotoURL }) =>
|
|
new Promise( async ( resolve, reject ) =>
|
|
{ const Photos_EQ_URL = range( 1,11 )
|
|
.map( Nr => `Photo_${ Nr } = "${ PhotoURL }"` )
|
|
.join( ' OR ' )
|
|
|
|
const _req = await DB.read(
|
|
{ table : 'Photos'
|
|
, where : `( SKU = "${ SKU }"
|
|
AND ( ${ Photos_EQ_URL } )
|
|
)`
|
|
})
|
|
|
|
if( typeof _req == 'object' )
|
|
{ let Occurrences = 0
|
|
_req.forEach( V =>
|
|
{ for( Param in V )
|
|
{ Occurrences += ( V[ Param ] == PhotoURL ) }
|
|
})
|
|
resolve( Occurrences )
|
|
}
|
|
reject( false )
|
|
|
|
}).catch( err => console.error
|
|
( Now( )
|
|
, 'error getting finding occurrences of an URL'
|
|
, '(Photos.URLoccurrences)'
|
|
, err
|
|
) )
|
|
|
|
const deletePhotoFiles =
|
|
exports.deletePhotoFiles = ({ SKU, Hash }) =>
|
|
new Promise( async ( resolve, reject ) =>
|
|
{ if( !Hash )
|
|
{ console.error
|
|
( Now( )
|
|
, 'cant delete file, no Hash in params:'
|
|
, { SKU, Hash }
|
|
)
|
|
resolve( false )
|
|
return false
|
|
}
|
|
// check if filename exist anywhere else
|
|
if( 1 < ( await URLoccurrences(
|
|
{ SKU
|
|
, PhotoURL : getURL({ SKU, Hash })
|
|
})
|
|
)
|
|
)
|
|
{ resolve( false )
|
|
return false
|
|
}
|
|
|
|
console.log( 'removing file:', SKU + '/' + Hash )
|
|
Object.keys( Sizes ).map
|
|
( Size => fs.unlinkSync( getFilepath({ SKU, Hash, Size }) ) )
|
|
|
|
resolve( true )
|
|
|
|
}).catch( err => console.error
|
|
( Now( )
|
|
, 'error deleting files'
|
|
, '(Photos.deletePhotoFiles)'
|
|
, err
|
|
) )
|
|
|
|
const removeOne =
|
|
exports.removeOne = ({ SKU, Variant, Nr }) =>
|
|
new Promise( async ( resolve, reject ) =>
|
|
{ const HashMap_req = await getHashmap(
|
|
{ SKU
|
|
, Variant
|
|
, arrNumbers : [ Nr ]
|
|
})
|
|
|
|
const PhotoURL = HashMap_req[ Nr ]
|
|
, Hash = getHashFromPhotoURL( PhotoURL )
|
|
|
|
console.log({ SKU, Variant, Nr, PhotoURL, Hash })
|
|
|
|
console.log
|
|
( Now( )
|
|
, 'removing photo'
|
|
, '(Photos.removeOne):\n'
|
|
, { SKU, Variant, Nr }
|
|
)
|
|
|
|
if( 10 === Number( Nr ) )
|
|
{ DB.update(
|
|
{ table : 'Photos'
|
|
, set : `Photo_10 = ""`
|
|
, where : `( SKU = "${SKU}"
|
|
AND Variant = "${Variant}"
|
|
)`
|
|
})
|
|
}
|
|
else
|
|
{ const OldHashmap = await getHashmap(
|
|
{ SKU
|
|
, Variant
|
|
, arrNumbers : range( 1,10 ).filter( _Nr => _Nr >= Nr )
|
|
})
|
|
|
|
let NewHashmap = { }
|
|
Object.keys( OldHashmap )
|
|
.filter( _Nr => OldHashmap[ _Nr ] )
|
|
.forEach( _Nr =>
|
|
{ NewHashmap[ _Nr ] =
|
|
OldHashmap[ Number( _Nr ) + 1 ] || ''
|
|
})
|
|
|
|
await DB.update(
|
|
{ table : 'Photos'
|
|
, set : PhotoHashmapToSQL( NewHashmap )
|
|
, where : `( SKU = "${SKU}"
|
|
AND Variant = "${Variant}"
|
|
)`
|
|
})
|
|
}
|
|
resolve( await deletePhotoFiles({ SKU, Hash }) )
|
|
|
|
}).catch( err => console.error
|
|
( Now( )
|
|
, 'error removing one'
|
|
, '(Photos.removeOne)'
|
|
, err
|
|
) )
|
|
|
|
const getHashmap =
|
|
exports.getHashmap = ({ SKU, Variant, arrNumbers }) =>
|
|
new Promise( async ( resolve, reject ) =>
|
|
{ const _req = await DB.read(
|
|
{ table : 'Photos'
|
|
, columns : ( arrNumbers || range( 1,11 ) )
|
|
.map( Nr => `Photo_${ Nr } AS "${ Nr }"` )
|
|
.join( ',' )
|
|
, where : `( SKU="${SKU}"
|
|
AND Variant="${Variant}"
|
|
)`
|
|
})
|
|
|
|
if( _req.length && typeof _req == 'object' )
|
|
{ resolve( _req[ 0 ] ) }
|
|
reject( false )
|
|
|
|
}).catch( err => console.error
|
|
( Now( )
|
|
, 'error getting hashmap'
|
|
, '(Photos.getHashmap)'
|
|
, err
|
|
) )
|
|
|
|
|
|
const setDefaultVariant =
|
|
exports.setDefaultVariant = async ({ SKU, Variant, oldVarinatRenamedTo }) =>
|
|
{ const _req = await DB.read(
|
|
{ table : 'Photos'
|
|
, columns : 'SKU, Variant, Accounts'
|
|
, where : `SKU = "${ SKU }"`
|
|
})
|
|
|
|
if( !_req.length )
|
|
{ console.error
|
|
( Now( )
|
|
, 'no records of SKU'
|
|
, SKU
|
|
)
|
|
return false
|
|
}
|
|
|
|
let oldDefault = { Accounts :'' }
|
|
, newDefault = { Accounts :'' }
|
|
|
|
_req.forEach( V =>
|
|
{ if( '_default' == V.Variant )
|
|
{ oldDefault = V }
|
|
if( Variant == V.Variant )
|
|
{ newDefault = V }
|
|
})
|
|
|
|
newDefault.Accounts =
|
|
[ ...newDefault.Accounts.split( /[\r\n]+/g )
|
|
, ...oldDefault.Accounts.split( /[\r\n]+/g )
|
|
]
|
|
|
|
newDefault.Accounts = SortAccounts( newDefault.Accounts )
|
|
|
|
if( oldDefault.SKU )
|
|
{ await DB.update(
|
|
{ table : 'Photos'
|
|
, set : ` Variant = "${ oldVarinatRenamedTo }"
|
|
, Accounts = ""
|
|
`
|
|
, where : `( SKU = "${ SKU }"
|
|
AND Variant = "_default"
|
|
)`
|
|
})
|
|
}
|
|
|
|
await DB.update(
|
|
{ table : 'Photos'
|
|
, set : ` Variant = "_default"
|
|
, Accounts = "${ newDefault.Accounts.join('\n') }"
|
|
, Need_update = TRUE
|
|
`
|
|
, where : `( SKU = "${ SKU }"
|
|
AND Variant = "${ Variant }"
|
|
)`
|
|
})
|
|
|
|
console.log
|
|
( Now( )
|
|
, `variant "${ Variant }"`
|
|
, `of "${ SKU }" is now the default`
|
|
, '(Photos.setDefaultVariant)'
|
|
)
|
|
|
|
return true
|
|
}
|
|
|
|
|
|
const createVariant =
|
|
exports.createVariant = ({ SKU, Variant, CopyOf }) =>
|
|
new Promise( async ( resolve, reject ) =>
|
|
{ const _test = await DB.read(
|
|
{ table : 'Photos'
|
|
, where : `( SKU = "${ SKU }"
|
|
AND Variant = "${ Variant }"
|
|
)`
|
|
})
|
|
if( _test.length )
|
|
{ resolve( true )
|
|
return true
|
|
}
|
|
|
|
const _req = await DB.read(
|
|
{ table : 'Photos'
|
|
, where : `( SKU = "${ SKU }"
|
|
AND Variant = "${ CopyOf || '_default' }"
|
|
)`
|
|
})
|
|
|
|
console.log( _req && _req.length && _req[ 0 ]
|
|
|| 'err DB.read [Photos.createVariant]'
|
|
)
|
|
|
|
const Accounts
|
|
= '_default' == Variant
|
|
? Config.Accounts.join( '\n' )
|
|
: ''
|
|
|
|
await DB.create(
|
|
{ table : 'Photos'
|
|
, set :
|
|
` SKU = "${ SKU }"
|
|
, Variant = "${ Variant }"
|
|
, Need_update = TRUE
|
|
, Accounts = "${ Accounts }"
|
|
`
|
|
+ ( _req && _req.length
|
|
? `, Photo_10 = "${ _req[ 0 ].Photo_10 }"`
|
|
+ ( CopyOf
|
|
? `
|
|
, Photo_1 = "${ _req[ 0 ].Photo_1 }"
|
|
, Photo_2 = "${ _req[ 0 ].Photo_2 }"
|
|
, Photo_3 = "${ _req[ 0 ].Photo_3 }"
|
|
, Photo_4 = "${ _req[ 0 ].Photo_4 }"
|
|
, Photo_5 = "${ _req[ 0 ].Photo_5 }"
|
|
, Photo_6 = "${ _req[ 0 ].Photo_6 }"
|
|
, Photo_7 = "${ _req[ 0 ].Photo_7 }"
|
|
, Photo_8 = "${ _req[ 0 ].Photo_8 }"
|
|
, Photo_9 = "${ _req[ 0 ].Photo_9 }"
|
|
`
|
|
: '' )
|
|
: '' )
|
|
})
|
|
|
|
resolve( true )
|
|
|
|
}).catch( err => console.error
|
|
( Now( )
|
|
, 'error creating Variant'
|
|
, '(Photos.createVariant)'
|
|
, err
|
|
) )
|
|
|
|
|
|
const assignVariantToAccount =
|
|
exports.assignVariantToAccount = ({ SKU, Account, Variant }) =>
|
|
new Promise( async ( resolve, reject ) =>
|
|
{ const AccountsBefore = await DB.read(
|
|
{ table : 'Photos'
|
|
, columns : 'Variant, Accounts'
|
|
, where : `( SKU = "${ SKU }"
|
|
AND Accounts LIKE "%${ Account }%"
|
|
)`
|
|
})
|
|
|
|
if( AccountsBefore && AccountsBefore.length )
|
|
{ const PrevVariant = AccountsBefore[ 0 ].Variant
|
|
let arrAccountsToStay = AccountsBefore[ 0 ].Accounts.split(/[\r\n]+/g)
|
|
arrAccountsToStay.splice( arrAccountsToStay.indexOf(Account), 1)
|
|
|
|
console.log({ PrevVariant, arrAccountsToStay })
|
|
|
|
await DB.update(
|
|
{ table : 'Photos'
|
|
, set : `Accounts = "${ arrAccountsToStay.join('\n') }"`
|
|
, where : `( SKU = "${ SKU }"
|
|
AND Variant = "${ PrevVariant }"
|
|
)`
|
|
})
|
|
}
|
|
else
|
|
{ console.warn(Account, 'was unset before') }
|
|
|
|
const AccountsInsertBefore = await DB.read(
|
|
{ table : 'Photos'
|
|
, columns : 'Accounts'
|
|
, set : `Accounts = "${ Account }"`
|
|
, where : `( SKU = "${ SKU }"
|
|
AND Variant = "${ Variant }"
|
|
)`
|
|
})
|
|
|
|
if( AccountsInsertBefore && AccountsInsertBefore.length )
|
|
{ let arrUpdatedAccountsInsert =
|
|
AccountsInsertBefore[ 0 ]
|
|
.Accounts
|
|
.split(/[\r\n]+/g)
|
|
|
|
arrUpdatedAccountsInsert.push(Account)
|
|
arrUpdatedAccountsInsert = SortAccounts( arrUpdatedAccountsInsert )
|
|
|
|
DB.update(
|
|
{ table : 'Photos'
|
|
, set : ` Accounts = "${ arrUpdatedAccountsInsert.join('\n') }"
|
|
, Need_update = TRUE
|
|
`
|
|
, where : `( SKU = "${ SKU }"
|
|
AND Variant = "${ Variant }"
|
|
)`
|
|
})
|
|
|
|
resolve( true )
|
|
}
|
|
else
|
|
{ reject( 'error getting AccountsInsertBefore' ) }
|
|
|
|
}).catch( err => console.error
|
|
( Now( )
|
|
, 'cant assign Variant to Account'
|
|
, '(Photos.assignVariantToAccount)'
|
|
, err
|
|
) )
|
|
|
|
const removeVariant =
|
|
exports.removeVariant = ({ SKU, Variant }) =>
|
|
new Promise( async ( resolve, reject ) =>
|
|
{ const VariantToDelete = await DB.read(
|
|
{ table : 'Photos'
|
|
, where : `( SKU = "${ SKU }"
|
|
AND Variant = "${ Variant }"
|
|
)`
|
|
})
|
|
if( !VariantToDelete.length )
|
|
{ resolve( 'variant does not exist' )
|
|
return true
|
|
}
|
|
|
|
if( VariantToDelete[ 0 ].Accounts.trim( ) )
|
|
{ const VariantsMigrateTo = await DB.read(
|
|
{ table : 'Photos'
|
|
, where : `( SKU = "${ SKU }"
|
|
AND Variant != "${ Variant }"
|
|
)`
|
|
})
|
|
if( VariantsMigrateTo.length )
|
|
{ let AccountsToMigrate = [...new Set
|
|
( [ ...VariantToDelete[ 0 ].Accounts.split( /[\r\n]+/g )
|
|
, ...VariantsMigrateTo[ 0 ].Accounts.split( /[\r\n]+/g )
|
|
]
|
|
)]
|
|
|
|
console.log(
|
|
{ VariantToDelete
|
|
, VariantsMigrateTo
|
|
, AccountsToMigrate
|
|
})
|
|
|
|
await DB.update(
|
|
{ table : 'Photos'
|
|
, set : `Accounts = "${ AccountsToMigrate.join('\n') }"`
|
|
, where : `( SKU = "${ SKU }"
|
|
AND Variant = "${ VariantsMigrateTo[ 0 ].Variant }"
|
|
)`
|
|
})
|
|
}
|
|
}
|
|
|
|
DB.delete(
|
|
{ table : 'Photos'
|
|
, where : `( SKU = "${ SKU }"
|
|
AND Variant = "${ Variant }"
|
|
)`
|
|
})
|
|
|
|
let Photos_toDelete = await getHashmap({ SKU, Variant })
|
|
if( Photos_toDelete )
|
|
{ for( let i=1; i<11; i++ )
|
|
{ if( Photos_toDelete[ i ] )
|
|
{ await deletePhotoFiles(
|
|
{ SKU
|
|
, Hash : Photos_toDelete[ i ]
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
resolve( true )
|
|
|
|
}).catch( err => console.error
|
|
( Now( )
|
|
, 'error removing variant'
|
|
, '(Photos.removeVariant)'
|
|
, err
|
|
) )
|
|
|
|
const readTable =
|
|
exports.readTable = table =>
|
|
new Promise( async ( resolve, reject ) =>
|
|
resolve( await DB.read({ table }) )
|
|
).catch( err => console.error
|
|
( Now( )
|
|
, 'error removing variant'
|
|
, '(Photos.readTable)'
|
|
, err
|
|
) )
|
|
|
|
|
|
const get_Photos_Since =
|
|
exports.get_Photos_Since = ( since = 0 ) =>
|
|
new Promise( async ( resolve, reject ) =>
|
|
{ const res = await DB.read(
|
|
{ table : 'Photos_Ordered'
|
|
, where : ( 0 != since )
|
|
&& `( Updated > "${ since }"
|
|
AND Updated IS NOT NULL
|
|
)`
|
|
|| '1'
|
|
, order_by : 'id'
|
|
}).catch( reject )
|
|
|
|
// console.log( 'get_Photos_Since:', since )
|
|
// console.log( 'res:', res )
|
|
resolve( res )
|
|
|
|
}).catch( err => console.error
|
|
( Now( )
|
|
, 'error removing variant'
|
|
, '(Photos.readTable)'
|
|
, err
|
|
) )
|
|
|
|
|
|
module.exports = exports
|