瀏覽代碼

Library update

isundil 2 年之前
父節點
當前提交
485e2e9cee
共有 9 個文件被更改,包括 125 次插入17 次删除
  1. 4 1
      main.js
  2. 38 0
      model/mediaItem.js
  3. 15 7
      src/databaseHelper.js
  4. 12 0
      src/fileTypeManager.js
  5. 20 0
      src/filetype/cr2.js
  6. 5 0
      src/filetype/jpeg.js
  7. 15 0
      src/filetype/meta.js
  8. 14 7
      src/library.js
  9. 2 2
      src/libraryManager.js

+ 4 - 1
main.js

@@ -8,6 +8,8 @@ const CONFIG = require('./src/config.js');
 const Security = require('./src/security.js');
 const RouterUtils = require('./src/routerUtils.js').RouterUtils;
 
+const CR2Parser = require('./src/filetype/cr2.js').ExifParser;
+
 function App() {
     this.router = new Router({ static_route: __dirname+"/static/" });
     this.routerUtils = new RouterUtils(this);
@@ -22,9 +24,10 @@ App.prototype.init = async function() {
 
 App.prototype.run = function() {
     http.createServer(this.router).listen(CONFIG.port);
-    this.libraryManager.updateLibraries().then(() => process.exit());
+    this.libraryManager.updateLibraries(this.databaseHelper).then(() => process.exit());
 }
 
+console.info = () => {};
 let app = new App();
 app.init().then(() => app.run());
 

+ 38 - 0
model/mediaItem.js

@@ -0,0 +1,38 @@
+
+const DatabaseModel = require("./DatabaseModel.js").DatabaseModel;
+
+function MediaFileModel() {
+    DatabaseModel.call(this);
+    this.path = "";
+    this.md5sum = "";
+}
+
+MediaFileModel.prototype = Object.create(DatabaseModel.prototype);
+
+MediaFileModel.prototype.getTableName = function() {
+    return "mediaFile";
+}
+
+MediaFileModel.prototype.createOrUpdateBase = async function(dbHelper) {
+    await dbHelper.runSql(`CREATE TABLE IF NOT EXISTS 'mediaFile' (
+        path STRING NOT NULL,
+        md5sum varchar(32) NOT NULL,
+        PRIMARY KEY (path, md5sum))`);
+}
+
+MediaFileModel.prototype.describe = function() {
+    return {
+        "path": this.path,
+        "md5sum": this.md5sum
+    };
+}
+
+MediaFileModel.prototype.versionColumn = function() { return ""; }
+
+MediaFileModel.prototype.fromDb = function(dbObj) {
+    this.path = dbObj["path"];
+    this.md5sum = dbObj["md5sum"];
+}
+
+module.exports.MediaFileModel = MediaFileModel;
+

+ 15 - 7
src/databaseHelper.js

@@ -1,9 +1,10 @@
 
 const sqlite3 = require('sqlite3');
 const SessionModel = require('../model/session.js').SessionModel;
+const MediaFileModel = require('../model/mediaItem.js').MediaFileModel;
 const CONFIG = require('./config.js');
 
-let ALL_MODELS = [ SessionModel ];
+let ALL_MODELS = [ SessionModel, MediaFileModel ];
 
 function DatabaseHelper() {
     this.db = null;
@@ -28,7 +29,7 @@ DatabaseHelper.prototype.init = function() {
 }
 
 DatabaseHelper.prototype.runSql = function(sqlStatement, args) {
-    console.log("DatabaseHelper::runSql ", sqlStatement, args);
+    console.info("DatabaseHelper::runSql ", sqlStatement, args);
     return new Promise((ok, ko) => {
         if (sqlStatement.indexOf('--') >= 0) {
             console.error("Rejecting SQL request containing comments");
@@ -92,6 +93,9 @@ DatabaseHelper.prototype.buildWhere = function(whereObj, columns, args) {
         for (let [key, val] of Object.entries(whereObj)) {
             if (val === null) {
                 columns.push("`"+key+"` is null");
+            } else if (Array.isArray(val)) {
+                columns.push("`"+key+"` in (" +val.map(i => "?").join(",") + ")");
+                for (let i of val) args.push(i);
             } else {
                 columns.push("`"+key+"`=?");
                 args.push(val);
@@ -125,11 +129,7 @@ DatabaseHelper.prototype.versionFetch = async function(objectPrototype, minVersi
 }
 
 DatabaseHelper.prototype.fetch = async function(objectPrototype, where, orderBy) {
-    let whereArgs = this.buildWhere(where);
-    let query = "select * from `" +objectPrototype.prototype.getTableName.call(null) +"` where " +whereArgs.columns.join(" and ");
-    if (orderBy)
-        query += " ORDER BY " +Object.keys(orderBy || {}).map(i => "`"+i+"` " +(orderBy[i] === 'DESC' ? "DESC":"ASC")).join(",");
-    let result = await this.runSql(query, whereArgs.args);
+    let result = await this.fetchRaw("*", objectPrototype.prototype.getTableName.call(null), where, orderBy);
     let resultArr = [];
     for (let i of result)
     {
@@ -140,6 +140,14 @@ DatabaseHelper.prototype.fetch = async function(objectPrototype, where, orderBy)
     return resultArr;
 }
 
+DatabaseHelper.prototype.fetchRaw = async function(columns, tableName, where, orderBy) {
+    let whereArgs = this.buildWhere(where);
+    let query = "select " + (Array.isArray(columns) ? columns.join(","): columns) +" from `" +tableName +"` where " +whereArgs.columns.join(" and ");
+    if (orderBy)
+        query += " ORDER BY " +Object.keys(orderBy || {}).map(i => "`"+i+"` " +(orderBy[i] === 'DESC' ? "DESC":"ASC")).join(",");
+    return await this.runSql(query, whereArgs.args);
+}
+
 DatabaseHelper.prototype.findOne = async function(objectPrototype, where) {
     let whereArgs = this.buildWhere(where);
     let result = await this.runSql("select * from `" +objectPrototype.prototype.getTableName.call(null) +"` where " +whereArgs.columns.join(" and "), whereArgs.args);

+ 12 - 0
src/fileTypeManager.js

@@ -0,0 +1,12 @@
+
+const parsers = [
+    require ('./filetype/jpeg.js')
+];
+
+module.exports.createMeta = async function(path) {
+    let result = {};
+    for (let i of await Promise.all(parsers.map(i => i.parse(path))))
+        i && Object.assign(result, i);
+    return result;
+}
+

+ 20 - 0
src/filetype/cr2.js

@@ -0,0 +1,20 @@
+#!/bin/node
+
+const fs = require('fs');
+const Meta = require('./meta.js').Meta;
+
+function CR2Parser() {
+}
+
+CR2Parser.prototype.parse = async function(path) {
+    let result = new Meta();
+    return result;
+}
+
+if (module == require.main) {
+    (new CR2Parser()).parse().then(console.log);
+}
+
+module.exports.ExifParser = new CR2Parser();
+
+

+ 5 - 0
src/filetype/jpeg.js

@@ -0,0 +1,5 @@
+
+module.exports.parse = (path) => {
+    return {};
+}
+

+ 15 - 0
src/filetype/meta.js

@@ -0,0 +1,15 @@
+
+function Meta() {
+    this.height = 0;
+    this.width = 0;
+    this.snapTime = new Date(0);
+    this.cameraBrand = "";
+    this.cameraModel = "";
+    this.objBrand = "";
+    this.objModel = "";
+    this.fNumber = 0;
+    this.delay = 0;
+}
+
+module.exports.Meta = Meta;
+

+ 14 - 7
src/library.js

@@ -2,7 +2,9 @@ const fs = require('fs');
 const path = require('path');
 const mime = require("mime-types");
 const md5Stats = require('./md5sum.js').stats;
+const FileTypeManager = require('./fileTypeManager.js');
 
+const MediaFileModel = require("../model/mediaItem.js").MediaFileModel;
 const MANAGED_FILES = [ ".cr2" ]; // TODO
 const BUFFER_MAXSIZE = 100;
 
@@ -12,6 +14,7 @@ function File(fullPath, name) {
     this.checksum = null;
     this.mimeType = null;
     this.isMedia = null;
+    this.meta = {};
 }
 
 File.prototype.enrich = async function() {
@@ -19,11 +22,15 @@ File.prototype.enrich = async function() {
     const lowerName = this.name.toLowerCase();
     this.isMedia = this.mimeType.startsWith("image/") || this.mimeType.startsWith("video/") || !!MANAGED_FILES.find(i => lowerName.endsWith(i));
     this.checksum = this.isMedia ? await md5Stats(this.path) : "";
+    this.meta = await FileTypeManager.createMeta(this.path);
 }
 
-async function Library_doUpdate(lib) {
+async function Library_doUpdate(dbHelper, lib) {
     if (lib.buff.length === 0)
         return;
+    const dbItems = await dbHelper.fetchRaw("path", MediaFileModel.prototype.getTableName.call(null), { "path": lib.buff.map(i => i.path) });
+    lib.buff = lib.buff.filter(i => dbItems.indexOf(i.path) === -1);
+    console.log(lib.buff);
     await Promise.allSettled(lib.buff.map(i => i.enrich()));
     lib.buff = lib.buff.filter(i => !!i.checksum);
     // TODO update
@@ -31,15 +38,15 @@ async function Library_doUpdate(lib) {
     lib.buff = [];
 }
 
-async function Library_depthupdate(library, dir) {
+async function Library_depthupdate(dbHelper, library, dir) {
     for (let o of fs.readdirSync(dir, { withFileTypes: true })) {
         const fullPath = path.join(dir, o.name);
         if (o.isDirectory())
-            await Library_depthupdate(library, fullPath, library.buff);
+            await Library_depthupdate(dbHelper, library, fullPath);
         else if (o.isFile()) {
             library.buff.push(new File(fullPath, o.name));
             if (library.buff.length >= BUFFER_MAXSIZE)
-                await Library_doUpdate(library);
+                await Library_doUpdate(dbHelper, library);
         }
     }
 }
@@ -52,13 +59,13 @@ function Library(path) {
     this.path = path;
 }
 
-Library.prototype.updateLibrary = async function() {
+Library.prototype.updateLibrary = async function(dbHelper) {
     console.log(`Starting update of library ${this.path}`);
     this.foundMedias = [];
     this.buff = [];
     if (Library_isValid(this))
-        await Library_depthupdate(this, this.path);
-    await Library_doUpdate(this)
+        await Library_depthupdate(dbHelper, this, this.path);
+    await Library_doUpdate(dbHelper, this)
     console.log(`Done updating library ${this.path}. Managed ${this.foundMedias.length} media files.`);
 }
 

+ 2 - 2
src/libraryManager.js

@@ -13,8 +13,8 @@ LibraryManager.prototype.push = function(path) {
     this.libraries.push(new Library(path));
 }
 
-LibraryManager.prototype.updateLibraries = function() {
-    return Promise.allSettled(this.libraries.map(i => i.updateLibrary()));
+LibraryManager.prototype.updateLibraries = function(dbHelper) {
+    return Promise.allSettled(this.libraries.map(i => i.updateLibrary(dbHelper)));
 }
 
 module.exports.LibraryManager = new LibraryManager();