فهرست منبع

Media service

isundil 2 سال پیش
والد
کامیت
6021e7e0a5
6فایلهای تغییر یافته به همراه103 افزوده شده و 8 حذف شده
  1. 1 1
      main.js
  2. 13 3
      model/access.js
  3. 5 1
      model/mediaItem.js
  4. 81 0
      model/mediaService.js
  5. 2 3
      router/api.js
  6. 1 0
      src/library.js

+ 1 - 1
main.js

@@ -25,7 +25,7 @@ App.prototype.init = async function() {
     await this.databaseHelper.init();
     await this.databaseHelper.init();
 }
 }
 
 
-App.prototype.run = function() {
+App.prototype.run = async function() {
     http.createServer(this.router).listen(CONFIG.port);
     http.createServer(this.router).listen(CONFIG.port);
     this.libraryManager.updateLibraries(this.databaseHelper);
     this.libraryManager.updateLibraries(this.databaseHelper);
 }
 }

+ 13 - 3
model/access.js

@@ -15,6 +15,12 @@ const ACCESS_TO = {
     meta: 3
     meta: 3
 };
 };
 
 
+const GRANT = {
+    none: 0,
+    read: 1,
+    write: 2
+};
+
 function AccessModel() {
 function AccessModel() {
     DatabaseModel.call(this);
     DatabaseModel.call(this);
     this.id = null;
     this.id = null;
@@ -22,6 +28,7 @@ function AccessModel() {
     this.typeData = "";
     this.typeData = "";
     this.accessTo = ACCESS_TO.unknown;
     this.accessTo = ACCESS_TO.unknown;
     this.accessToData = "";
     this.accessToData = "";
+    this.grant = GRANT.none;
 }
 }
 
 
 AccessModel.prototype = Object.create(DatabaseModel.prototype);
 AccessModel.prototype = Object.create(DatabaseModel.prototype);
@@ -36,7 +43,8 @@ AccessModel.prototype.createOrUpdateBase = async function(dbHelper) {
         type TINYINT NOT NULL,
         type TINYINT NOT NULL,
         typeData STRING NOT NULL,
         typeData STRING NOT NULL,
         accessTo TINYINT NOT NULL,
         accessTo TINYINT NOT NULL,
-        accessToData STRING NOT NULL
+        accessToData STRING NOT NULL,
+        grant TINYINT NOT NULL
         )`);
         )`);
 }
 }
 
 
@@ -46,11 +54,12 @@ AccessModel.prototype.describe = function() {
         "type": this.type,
         "type": this.type,
         "typeData": this.typeData,
         "typeData": this.typeData,
         "accessTo": this.accessTo,
         "accessTo": this.accessTo,
-        "accessToData": this.accessToData
+        "accessToData": this.accessToData,
+        "grant": this.grant
     };
     };
 }
 }
 
 
-AccessModel.prototype.versionColumn = function() { return "loginDateTime"; }
+AccessModel.prototype.versionColumn = function() { return ""; }
 
 
 AccessModel.prototype.fromDb = function(dbObj) {
 AccessModel.prototype.fromDb = function(dbObj) {
     this.id = dbObj["sessionId"];
     this.id = dbObj["sessionId"];
@@ -58,6 +67,7 @@ AccessModel.prototype.fromDb = function(dbObj) {
     this.typeData = dbObj["typeData"];
     this.typeData = dbObj["typeData"];
     this.accessTo = dbObj["accessTo"];
     this.accessTo = dbObj["accessTo"];
     this.accessToData = dbObj["accessToData"];
     this.accessToData = dbObj["accessToData"];
+    this.grant = dbObj["grant"];
 }
 }
 
 
 module.exports.AccessModel = AccessModel;
 module.exports.AccessModel = AccessModel;

+ 5 - 1
model/mediaItem.js

@@ -5,6 +5,7 @@ function MediaFileModel() {
     DatabaseModel.call(this);
     DatabaseModel.call(this);
     this.path = "";
     this.path = "";
     this.md5sum = "";
     this.md5sum = "";
+    this.date = null;
 }
 }
 
 
 MediaFileModel.prototype = Object.create(DatabaseModel.prototype);
 MediaFileModel.prototype = Object.create(DatabaseModel.prototype);
@@ -17,13 +18,15 @@ MediaFileModel.prototype.createOrUpdateBase = async function(dbHelper) {
     await dbHelper.runSql(`CREATE TABLE IF NOT EXISTS 'mediaFile' (
     await dbHelper.runSql(`CREATE TABLE IF NOT EXISTS 'mediaFile' (
         path STRING NOT NULL,
         path STRING NOT NULL,
         md5sum varchar(32) NOT NULL,
         md5sum varchar(32) NOT NULL,
+        date DateTime NOT NULL,
         PRIMARY KEY (path, md5sum))`);
         PRIMARY KEY (path, md5sum))`);
 }
 }
 
 
 MediaFileModel.prototype.describe = function() {
 MediaFileModel.prototype.describe = function() {
     return {
     return {
         "path": this.path,
         "path": this.path,
-        "md5sum": this.md5sum
+        "md5sum": this.md5sum,
+        "date": this.date?.getTime()
     };
     };
 }
 }
 
 
@@ -32,6 +35,7 @@ MediaFileModel.prototype.versionColumn = function() { return ""; }
 MediaFileModel.prototype.fromDb = function(dbObj) {
 MediaFileModel.prototype.fromDb = function(dbObj) {
     this.path = dbObj["path"];
     this.path = dbObj["path"];
     this.md5sum = dbObj["md5sum"];
     this.md5sum = dbObj["md5sum"];
+    this.date = new Date(dbObj["date"]);
 }
 }
 
 
 module.exports.MediaFileModel = MediaFileModel;
 module.exports.MediaFileModel = MediaFileModel;

+ 81 - 0
model/mediaService.js

@@ -0,0 +1,81 @@
+
+function Media()
+{
+}
+
+function MediaStruct(i) {
+    this.path = i.path;
+    this.md5sum = i.md5sum;
+    this.date = i.date;
+    this.meta = {};
+    this.tags = [];
+}
+
+MediaStruct.prototype.pushMeta = function(key, value) {
+    if (key && value && !this.meta[key])
+        this.meta[key] = value;
+}
+
+MediaStruct.prototype.pushTag = function(tag) {
+    if (tag && this.tags.indexOf(tag) === -1)
+        this.tags.push(tag);
+}
+
+MediaStruct.prototype.HaveAccess = function(accessList) {
+    // FIXME
+    return false;
+}
+
+function reduceReqToMediaStruct(acc, i) {
+    let obj = acc[i.md5sum] = acc[i.md5sum] || new MediaStruct(i);
+    obj.pushMeta(i.metaKey, i.metaValue);
+    obj.pushTag(i.mediaTag);
+    return acc;
+}
+
+module.exports.fetchOne = async function(app, md5sum) {
+    let result = ((await app.databaseHelper.runSql(`
+        select mediaFile.path, mediaFile.md5sum, mediaFile.date,
+        mediaMeta.key as metaKey, mediaMeta.value as metaValue,
+        mediaTag.tag as mediaTag
+        from mediaFile
+        left join mediaMeta on mediaMeta.md5sum=mediaFile.md5sum
+        left join mediaTag on mediaTag.md5sum=mediaFile.md5sum
+        where mediaFile.md5sum=?`, md5sum)) || []).reduce(reduceReqToMediaStruct, {})[md5sum] || null;
+    return result;
+}
+
+module.exports.fetchMedias = async function(app, startTs, count) {
+    let result = ((await app.databaseHelper.runSql(`
+        select mediaFile.path, mediaFile.md5sum, mediaFile.date,
+        mediaMeta.key as metaKey, mediaMeta.value as metaValue,
+        mediaTag.tag as mediaTag
+        from mediaFile
+        left join mediaMeta on mediaMeta.md5sum=mediaFile.md5sum
+        left join mediaTag on mediaTag.md5sum=mediaFile.md5sum
+        where mediaFile.md5sum in
+            (select md5sum from mediaFile `
+            +(startTs ? "where date <? " : "")
+            +"order by date desc limit ?)", startTs ? [startTs, count] : [count])) || [])
+    .reduce(reduceReqToMediaStruct, {});
+
+    result = Object.keys(result).map(i => result[i]).sort((a, b) => b.date-a.date);
+    return result;
+};
+
+module.exports.fetchMediasWithAccess = async function(app, startTs, count, access) {
+    let result = [];
+    let lastTs = startTs;
+
+    while (result.length < count) {
+        let tmp = await module.exports.fetchMedias(app, lastTs, 25);
+        if (!tmp.length)
+            return result;
+        lastTs = tmp[tmp.length-1].date;
+        tmp = tmp.filter(i => i.HaveAccess(access));
+        if (tmp.length)
+            result = result.concat(tmp);
+    }
+    return result;
+};
+

+ 2 - 3
router/api.js

@@ -1,5 +1,6 @@
 
 
 const Security = require('../src/security.js');
 const Security = require('../src/security.js');
+const MediaService = require('../model/mediaService.js');
 
 
 module.exports = { register: app => {
 module.exports = { register: app => {
     app.router.get("/api/access/list", (req, res) => {
     app.router.get("/api/access/list", (req, res) => {
@@ -22,9 +23,7 @@ module.exports = { register: app => {
     app.router.get("/api/media/list", async (req, res) => {
     app.router.get("/api/media/list", async (req, res) => {
         app.routerUtils.onApiRequest(req, res);
         app.routerUtils.onApiRequest(req, res);
         app.routerUtils.jsonResponse(res, {
         app.routerUtils.jsonResponse(res, {
-            start: 0,
-            end: 0,
-            data: []
+            data: await MediaService.fetchMediasWithAccess(app, 0, 50, req.accessList)
         });
         });
     });
     });
 }};
 }};

+ 1 - 0
src/library.js

@@ -37,6 +37,7 @@ File.prototype.saveDb = async function(db, libraryHash) {
     let _this = this;
     let _this = this;
     entity.path = this.path;
     entity.path = this.path;
     entity.md5sum = this.checksum;
     entity.md5sum = this.checksum;
+    entity.date = this.meta.dateTime || new Date(fs.statsSync(this.path)?.birthtimeMs || Date.now());
     await db.insertOne(entity);
     await db.insertOne(entity);
     this.meta.photochamberImport = new Date();
     this.meta.photochamberImport = new Date();
     this.meta.libraryPath = libraryHash;
     this.meta.libraryPath = libraryHash;