UNPKG

3.35 kBJavaScriptView Raw
1/*jslint node: true, esversion: 6, maxlen: 180 */
2"use strict";
3
4const debug = require('debug')('upnpserver:contentHandlers:Exif');
5const Exif = require('exif');
6
7const ContentHandler = require('./contentHandler');
8
9const logger = require('../logger');
10
11class ExifContentHandler extends ContentHandler {
12
13 get name() {
14 return "exif";
15 }
16
17 /**
18 *
19 */
20 prepareMetas(contentInfos, context, callback) {
21 debug("Prepare metas of", contentInfos);
22
23 var contentURL = contentInfos.contentURL;
24
25 contentURL.readContent(null, (error, imageData) => {
26 if (error) {
27 logger.error("Can not get content of '" + contentURL + "'", error);
28 return callback(error);
29 }
30
31 new Exif.ExifImage({image: imageData, fixThumbnailOffset: true}, (error, exifData) => {
32 if (error) {
33 logger.error("Can not parse exif '" + contentURL + "'", error);
34 return callback(error);
35 }
36
37 filter(exifData);
38
39 var res;
40 var thumbnail = exifData.thumbnail;
41 if (thumbnail) {
42 delete exifData.thumbnail;
43
44 if (thumbnail.ThumbnailOffset && thumbnail.ThumbnailLength) {
45
46 var thumbnailMimeType;
47 if (isJPEG(imageData, thumbnail.ThumbnailOffset)) {
48 thumbnailMimeType = "image/jpeg";
49 }
50
51 if (thumbnailMimeType) {
52 res = res || [{}];
53
54 res.push({
55 contentHandlerKey: this.name,
56 key: "thumbnail",
57 mimeType: thumbnailMimeType,
58 size: thumbnail.ThumbnailLength,
59 _start: thumbnail.ThumbnailOffset
60 });
61 }
62 }
63 }
64 var exif = exifData;
65 if (exif) {
66 res = res || [{}];
67
68 if (exif.ExifImageWidth) {
69 res[0].width = exif.ExifImageWidth;
70 }
71 if (exif.ExifImageHeight) {
72 res[0].height = exif.ExifImageHeight;
73 }
74 if (exif.DateTimeOriginal) {
75 var ds = exif.DateTimeOriginal;
76 var reg = /^(\d{4}).(\d{2}).(\d{2}).(\d{2}).(\d{2}).(\d{2})/.exec(ds);
77 if (reg) {
78 exifData.dateTimeOriginal = new Date(parseInt(reg[1]), parseInt(reg[2]) - 1, parseInt(reg[3]),
79 parseInt(reg[4]), parseInt(reg[5]), parseInt(reg[6]));
80 exifData.date = exifData.dateTimeOriginal;
81 }
82 }
83 }
84
85 if (res) {
86 exifData.res = res;
87 }
88
89 callback(null, exifData);
90 });
91 });
92 }
93
94 /**
95 *
96 */
97 processRequest(node, request, response, path, parameters, callback) {
98
99 var resKey = parameters[0];
100 var res = this.getResourceByParameter(node, resKey);
101
102 debug("ProcessRequest", "resKey=", resKey, "=>", res);
103
104 if (!res) {
105 var error = new Error("Invalid resKey parameter (" + resKey + ")");
106 return callback(error, true);
107 }
108
109 this.sendResource(node.contentURL, res, request, response, callback);
110 }
111}
112
113module.exports = ExifContentHandler;
114
115function isJPEG(data, offset) {
116 debug("IsJPEG: offset=", offset, "data=", data[offset], data[offset + 1], data[offset + 2]);
117 return (data[offset] === 0xff) && (data[offset + 1] === 0xd8) && (data[offset + 2] === 0xff) && (data[offset + 3] === 0xdb);
118}
119
120function filter(json) {
121 for (var n in json) {
122 var v = json[n];
123 if (typeof(v) !== "object") {
124 continue;
125 }
126
127 if (v === null) {
128 continue;
129 }
130 if (v instanceof Array) {
131 continue;
132 }
133 if (Buffer.isBuffer(v)) {
134 delete json[n];
135 continue;
136 }
137 if (v instanceof Date) {
138 continue;
139 }
140 if (!Object.keys(v).length) {
141 delete json[n];
142 continue;
143 }
144
145 filter(v);
146 }
147}