Zazama /
node-id3
| 1 | const fs = require('fs')
|
||
| 2 | const ID3Definitions = require("./src/ID3Definitions")
|
||
| 3 | const ID3Frames = require('./src/ID3Frames')
|
||
| 4 | const ID3Util = require('./src/ID3Util')
|
||
| 5 | const zlib = require('zlib')
|
||
| 6 | |||
| 7 | /* |
||
| 8 | ** Used specification: http://id3.org/id3v2.3.0 |
||
| 9 | */ |
||
| 10 | |||
| 11 | /** |
||
| 12 | * @param {any} value
|
||
| 13 | * @returns {boolean} true if value is a function
|
||
| 14 | */ |
||
| 15 | const isFunction = (value) => value && typeof value === 'function' |
||
| 16 | |||
| 17 | /** |
||
| 18 | * Write passed tags to a file/buffer |
||
| 19 | * @param tags - Object containing tags to be written |
||
| 20 | * @param filebuffer - Can contain a filepath string or buffer |
||
| 21 | * @param fn - (optional) Function for async version |
||
| 22 | * @returns {boolean|Buffer|Error}
|
||
| 23 | */ |
||
| 24 | module.exports.write = function(tags, filebuffer, fn) {
|
||
| 25 | let completeTag = this.create(tags) |
||
| 26 | if(filebuffer instanceof Buffer) {
|
||
| 27 | filebuffer = this.removeTagsFromBuffer(filebuffer) || filebuffer |
||
| 28 | let completeBuffer = Buffer.concat([completeTag, filebuffer]) |
||
| 29 | if(isFunction(fn)) {
|
||
| 30 | fn(null, completeBuffer) |
||
| 31 | return undefined |
||
| 32 | } else {
|
||
|
0 ignored issues
–
show
Comprehensibility
introduced
by
Loading history...
|
|||
| 33 | return completeBuffer |
||
| 34 | } |
||
| 35 | } |
||
| 36 | |||
| 37 | if(isFunction(fn)) {
|
||
| 38 | try {
|
||
| 39 | fs.readFile(filebuffer, function(err, data) {
|
||
| 40 | if(err) {
|
||
| 41 | fn(err) |
||
| 42 | return |
||
| 43 | } |
||
| 44 | data = this.removeTagsFromBuffer(data) || data |
||
| 45 | let rewriteFile = Buffer.concat([completeTag, data]) |
||
| 46 | fs.writeFile(filebuffer, rewriteFile, 'binary', (err) => {
|
||
| 47 | fn(err) |
||
| 48 | }) |
||
| 49 | }.bind(this)) |
||
| 50 | } catch(err) {
|
||
|
0 ignored issues
–
show
|
|||
| 51 | fn(err) |
||
| 52 | } |
||
|
0 ignored issues
–
show
|
|||
| 53 | } else {
|
||
| 54 | try {
|
||
| 55 | let data = fs.readFileSync(filebuffer) |
||
| 56 | data = this.removeTagsFromBuffer(data) || data |
||
| 57 | let rewriteFile = Buffer.concat([completeTag, data]) |
||
| 58 | fs.writeFileSync(filebuffer, rewriteFile, 'binary') |
||
| 59 | return true |
||
| 60 | } catch(err) {
|
||
| 61 | return err |
||
| 62 | } |
||
| 63 | } |
||
| 64 | } |
||
| 65 | |||
| 66 | /** |
||
| 67 | * Creates a buffer containing the ID3 Tag |
||
| 68 | * @param tags - Object containing tags to be written |
||
| 69 | * @param fn fn - (optional) Function for async version |
||
| 70 | * @returns {Buffer}
|
||
| 71 | */ |
||
| 72 | module.exports.create = function(tags, fn) {
|
||
| 73 | let frames = [] |
||
| 74 | |||
| 75 | // Create & push a header for the ID3-Frame |
||
| 76 | const header = Buffer.alloc(10) |
||
| 77 | header.fill(0) |
||
| 78 | header.write("ID3", 0) //File identifier
|
||
| 79 | header.writeUInt16BE(0x0300, 3) //Version 2.3.0 -- 03 00 |
||
| 80 | header.writeUInt16BE(0x0000, 5) //Flags 00 |
||
| 81 | |||
| 82 | //Last 4 bytes are used for header size, but have to be inserted later, because at this point, its size is not clear. |
||
| 83 | frames.push(header) |
||
| 84 | |||
| 85 | frames = frames.concat(this.createBuffersFromTags(tags)) |
||
| 86 | |||
| 87 | // Calculate frame size of ID3 body to insert into header |
||
| 88 | |||
| 89 | let totalSize = 0 |
||
| 90 | frames.forEach((frame) => {
|
||
| 91 | totalSize += frame.length |
||
| 92 | }) |
||
| 93 | |||
| 94 | // Don't count ID3 header itself |
||
| 95 | totalSize -= 10 |
||
| 96 | // ID3 header size uses only 7 bits of a byte, bit shift is needed |
||
| 97 | let size = ID3Util.encodeSize(totalSize) |
||
| 98 | |||
| 99 | // Write bytes to ID3 frame header, which is the first frame |
||
| 100 | frames[0].writeUInt8(size[0], 6) |
||
| 101 | frames[0].writeUInt8(size[1], 7) |
||
| 102 | frames[0].writeUInt8(size[2], 8) |
||
| 103 | frames[0].writeUInt8(size[3], 9) |
||
| 104 | |||
| 105 | if(isFunction(fn)) {
|
||
| 106 | fn(Buffer.concat(frames)) |
||
| 107 | } else {
|
||
|
0 ignored issues
–
show
|
|||
| 108 | return Buffer.concat(frames) |
||
| 109 | } |
||
| 110 | } |
||
| 111 | |||
| 112 | /** |
||
| 113 | * Returns array of buffers created by tags specified in the tags argument |
||
| 114 | * @param tags - Object containing tags to be written |
||
| 115 | * @returns {Array}
|
||
| 116 | */ |
||
| 117 | module.exports.createBuffersFromTags = function(tags) {
|
||
| 118 | let frames = [] |
||
| 119 | if(!tags) {
|
||
| 120 | return frames |
||
| 121 | } |
||
| 122 | const rawObject = Object.keys(tags).reduce((acc, val) => {
|
||
| 123 | if(ID3Definitions.FRAME_IDENTIFIERS.v3[val] !== undefined) {
|
||
| 124 | acc[ID3Definitions.FRAME_IDENTIFIERS.v3[val]] = tags[val] |
||
| 125 | } else {
|
||
| 126 | acc[val] = tags[val] |
||
| 127 | } |
||
| 128 | return acc |
||
| 129 | }, {})
|
||
| 130 | |||
| 131 | Object.keys(rawObject).forEach((specName) => {
|
||
| 132 | let frame |
||
| 133 | // Check if invalid specName |
||
| 134 | if(specName.length !== 4) {
|
||
| 135 | return |
||
| 136 | } |
||
| 137 | if(ID3Frames[specName] !== undefined) {
|
||
| 138 | frame = ID3Frames[specName].create(rawObject[specName], 3, this) |
||
| 139 | } else if(specName.startsWith('T')) {
|
||
| 140 | frame = ID3Frames.GENERIC_TEXT.create(specName, rawObject[specName], 3) |
||
| 141 | } else if(specName.startsWith('W')) {
|
||
| 142 | if(ID3Util.getSpecOptions(specName, 3).multiple && rawObject[specName] instanceof Array && rawObject[specName].length > 0) {
|
||
| 143 | frame = Buffer.alloc(0) |
||
| 144 | // deduplicate array |
||
| 145 | for(let url of [...new Set(rawObject[specName])]) {
|
||
| 146 | frame = Buffer.concat([frame, ID3Frames.GENERIC_URL.create(specName, url, 3)]) |
||
| 147 | } |
||
| 148 | } else {
|
||
| 149 | frame = ID3Frames.GENERIC_URL.create(specName, rawObject[specName], 3) |
||
| 150 | } |
||
| 151 | } |
||
| 152 | |||
| 153 | if (frame && frame instanceof Buffer) {
|
||
| 154 | frames.push(frame) |
||
| 155 | } |
||
| 156 | }) |
||
| 157 | |||
| 158 | return frames |
||
| 159 | } |
||
| 160 | |||
| 161 | /** |
||
| 162 | * Read ID3-Tags from passed buffer/filepath |
||
| 163 | * @param filebuffer - Can contain a filepath string or buffer |
||
| 164 | * @param options - (optional) Object containing options |
||
| 165 | * @param fn - (optional) Function for async version |
||
| 166 | * @returns {boolean}
|
||
| 167 | */ |
||
| 168 | module.exports.read = function(filebuffer, options, fn) {
|
||
| 169 | if(!options || typeof options === 'function') {
|
||
| 170 | fn = fn || options |
||
| 171 | options = {}
|
||
| 172 | } |
||
| 173 | if(!fn || typeof fn !== 'function') {
|
||
| 174 | if(typeof filebuffer === "string" || filebuffer instanceof String) {
|
||
| 175 | filebuffer = fs.readFileSync(filebuffer) |
||
| 176 | } |
||
| 177 | return this.getTagsFromBuffer(filebuffer, options) |
||
| 178 | } else {
|
||
|
0 ignored issues
–
show
|
|||
| 179 | if(typeof filebuffer === "string" || filebuffer instanceof String) {
|
||
| 180 | fs.readFile(filebuffer, function(err, data) {
|
||
| 181 | if(err) {
|
||
| 182 | fn(err, null) |
||
| 183 | } else {
|
||
| 184 | fn(null, this.getTagsFromBuffer(data, options)) |
||
| 185 | } |
||
| 186 | }.bind(this)) |
||
| 187 | } else {
|
||
|
0 ignored issues
–
show
|
|||
| 188 | fn(null, this.getTagsFromBuffer(filebuffer, options)) |
||
| 189 | } |
||
|
0 ignored issues
–
show
|
|||
| 190 | } |
||
| 191 | } |
||
| 192 | |||
| 193 | /** |
||
| 194 | * Update ID3-Tags from passed buffer/filepath |
||
| 195 | * @param tags - Object containing tags to be written |
||
| 196 | * @param filebuffer - Can contain a filepath string or buffer |
||
| 197 | * @param options - (optional) Object containing options |
||
| 198 | * @param fn - (optional) Function for async version |
||
| 199 | * @returns {boolean|Buffer|Error}
|
||
| 200 | */ |
||
| 201 | module.exports.update = function(tags, filebuffer, options, fn) {
|
||
| 202 | if(!options || typeof options === 'function') {
|
||
| 203 | fn = fn || options |
||
| 204 | options = {}
|
||
| 205 | } |
||
| 206 | |||
| 207 | const rawTags = Object.keys(tags).reduce((acc, val) => {
|
||
| 208 | if(ID3Definitions.FRAME_IDENTIFIERS.v3[val] !== undefined) {
|
||
| 209 | acc[ID3Definitions.FRAME_IDENTIFIERS.v3[val]] = tags[val] |
||
| 210 | } else {
|
||
| 211 | acc[val] = tags[val] |
||
| 212 | } |
||
| 213 | return acc |
||
| 214 | }, {})
|
||
| 215 | |||
| 216 | const updateFn = (currentTags) => {
|
||
| 217 | currentTags = currentTags.raw || {}
|
||
| 218 | Object.keys(rawTags).map((specName) => {
|
||
| 219 | const options = ID3Util.getSpecOptions(specName, 3) |
||
| 220 | const cCompare = {}
|
||
| 221 | if(options.multiple && currentTags[specName] && rawTags[specName]) {
|
||
| 222 | if(options.updateCompareKey) {
|
||
| 223 | currentTags[specName].forEach((cTag, index) => {
|
||
| 224 | cCompare[cTag[options.updateCompareKey]] = index |
||
| 225 | }) |
||
| 226 | |||
| 227 | } |
||
| 228 | if (!(rawTags[specName] instanceof Array)) {
|
||
| 229 | rawTags[specName] = [rawTags[specName]] |
||
| 230 | } |
||
| 231 | rawTags[specName].forEach((rTag) => {
|
||
| 232 | const comparison = cCompare[rTag[options.updateCompareKey]] |
||
| 233 | if (comparison !== undefined) {
|
||
| 234 | currentTags[specName][comparison] = rTag |
||
| 235 | } else {
|
||
| 236 | currentTags[specName].push(rTag) |
||
| 237 | } |
||
| 238 | }) |
||
| 239 | } else {
|
||
| 240 | currentTags[specName] = rawTags[specName] |
||
| 241 | } |
||
| 242 | }) |
||
| 243 | |||
| 244 | return currentTags |
||
| 245 | } |
||
| 246 | |||
| 247 | if(!fn || typeof fn !== 'function') {
|
||
| 248 | return this.write(updateFn(this.read(filebuffer, options)), filebuffer) |
||
| 249 | } |
||
| 250 | |||
| 251 | this.write(updateFn(this.read(filebuffer, options)), filebuffer, fn) |
||
| 252 | } |
||
|
0 ignored issues
–
show
|
|||
| 253 | |||
| 254 | module.exports.getTagsFromBuffer = function(filebuffer, options) {
|
||
| 255 | let framePosition = ID3Util.getFramePosition(filebuffer) |
||
| 256 | if(framePosition === -1) {
|
||
| 257 | return this.getTagsFromFrames([], 3, options) |
||
| 258 | } |
||
| 259 | const frameSize = ID3Util.decodeSize(filebuffer.slice(framePosition + 6, framePosition + 10)) + 10 |
||
| 260 | let ID3Frame = Buffer.alloc(frameSize + 1) |
||
| 261 | filebuffer.copy(ID3Frame, 0, framePosition) |
||
| 262 | //ID3 version e.g. 3 if ID3v2.3.0 |
||
| 263 | let ID3Version = ID3Frame[3] |
||
| 264 | const tagFlags = ID3Util.parseTagHeaderFlags(ID3Frame) |
||
| 265 | let extendedHeaderOffset = 0 |
||
| 266 | if(tagFlags.extendedHeader) {
|
||
| 267 | if(ID3Version === 3) {
|
||
| 268 | extendedHeaderOffset = 4 + filebuffer.readUInt32BE(10) |
||
| 269 | } else if(ID3Version === 4) {
|
||
| 270 | extendedHeaderOffset = ID3Util.decodeSize(filebuffer.slice(10, 14)) |
||
| 271 | } |
||
| 272 | } |
||
| 273 | let ID3FrameBody = Buffer.alloc(frameSize - 10 - extendedHeaderOffset) |
||
| 274 | filebuffer.copy(ID3FrameBody, 0, framePosition + 10 + extendedHeaderOffset) |
||
| 275 | |||
| 276 | let frames = this.getFramesFromID3Body(ID3FrameBody, ID3Version, options) |
||
| 277 | |||
| 278 | return this.getTagsFromFrames(frames, ID3Version, options) |
||
| 279 | } |
||
| 280 | |||
| 281 | module.exports.getFramesFromID3Body = function(ID3FrameBody, ID3Version, options = {}) {
|
||
| 282 | let currentPosition = 0 |
||
| 283 | let frames = [] |
||
| 284 | if(!ID3FrameBody || !(ID3FrameBody instanceof Buffer)) {
|
||
| 285 | return frames |
||
| 286 | } |
||
| 287 | |||
| 288 | let identifierSize = 4 |
||
| 289 | let textframeHeaderSize = 10 |
||
| 290 | if(ID3Version === 2) {
|
||
| 291 | identifierSize = 3 |
||
| 292 | textframeHeaderSize = 6 |
||
| 293 | } |
||
| 294 | |||
| 295 | while(currentPosition < ID3FrameBody.length && ID3FrameBody[currentPosition] !== 0x00) {
|
||
| 296 | let bodyFrameHeader = Buffer.alloc(textframeHeaderSize) |
||
| 297 | ID3FrameBody.copy(bodyFrameHeader, 0, currentPosition) |
||
| 298 | |||
| 299 | let decodeSize = false |
||
| 300 | if(ID3Version === 4) {
|
||
| 301 | decodeSize = true |
||
| 302 | } |
||
| 303 | let bodyFrameSize = ID3Util.getFrameSize(bodyFrameHeader, decodeSize, ID3Version) |
||
| 304 | if(bodyFrameSize + 10 > (ID3FrameBody.length - currentPosition)) {
|
||
| 305 | break |
||
| 306 | } |
||
| 307 | const specName = bodyFrameHeader.toString('utf8', 0, identifierSize)
|
||
| 308 | if(options.exclude instanceof Array && options.exclude.includes(specName) || options.include instanceof Array && !options.include.includes(specName)) {
|
||
| 309 | currentPosition += bodyFrameSize + textframeHeaderSize |
||
| 310 | continue |
||
| 311 | } |
||
| 312 | const frameHeaderFlags = ID3Util.parseFrameHeaderFlags(bodyFrameHeader, ID3Version) |
||
| 313 | let bodyFrameBuffer = Buffer.alloc(bodyFrameSize) |
||
| 314 | ID3FrameBody.copy(bodyFrameBuffer, 0, currentPosition + textframeHeaderSize + (frameHeaderFlags.dataLengthIndicator ? 4 : 0)) |
||
| 315 | // Size of sub frame + its header |
||
| 316 | currentPosition += bodyFrameSize + textframeHeaderSize |
||
| 317 | frames.push({
|
||
| 318 | name: specName, |
||
| 319 | flags: frameHeaderFlags, |
||
| 320 | body: frameHeaderFlags.unsynchronisation ? ID3Util.processUnsynchronisedBuffer(bodyFrameBuffer) : bodyFrameBuffer |
||
| 321 | }) |
||
| 322 | } |
||
| 323 | |||
| 324 | return frames |
||
| 325 | } |
||
| 326 | |||
| 327 | module.exports.getTagsFromFrames = function(frames, ID3Version, options = {}) {
|
||
| 328 | let tags = { }
|
||
| 329 | let raw = { }
|
||
| 330 | |||
| 331 | frames.forEach((frame) => {
|
||
| 332 | const specName = ID3Version === 2 ? ID3Definitions.FRAME_IDENTIFIERS.v3[ID3Definitions.FRAME_INTERNAL_IDENTIFIERS.v2[frame.name]] : frame.name |
||
| 333 | const identifier = ID3Version === 2 ? ID3Definitions.FRAME_INTERNAL_IDENTIFIERS.v2[frame.name] : ID3Definitions.FRAME_INTERNAL_IDENTIFIERS.v3[frame.name] |
||
| 334 | |||
| 335 | if(!specName || !identifier || frame.flags.encryption) {
|
||
| 336 | return |
||
| 337 | } |
||
| 338 | |||
| 339 | if(frame.flags.compression) {
|
||
| 340 | if(frame.body.length < 5) {
|
||
| 341 | return |
||
| 342 | } |
||
| 343 | const inflatedSize = frame.body.readInt32BE() |
||
| 344 | /* |
||
| 345 | * ID3 spec defines that compression is stored in ZLIB format, but doesn't specify if header is present or not. |
||
| 346 | * ZLIB has a 2-byte header. |
||
| 347 | * 1. try if header + body decompression |
||
| 348 | * 2. else try if header is not stored (assume that all content is deflated "body") |
||
| 349 | * 3. else try if inflation works if the header is omitted (implementation dependent) |
||
| 350 | * */ |
||
| 351 | try {
|
||
| 352 | frame.body = zlib.inflateSync(frame.body.slice(4)) |
||
| 353 | } catch (e) {
|
||
| 354 | try {
|
||
| 355 | frame.body = zlib.inflateRawSync(frame.body.slice(4)) |
||
| 356 | } catch (e) {
|
||
| 357 | try {
|
||
| 358 | frame.body = zlib.inflateRawSync(frame.body.slice(6)) |
||
| 359 | } catch (e) {
|
||
| 360 | return |
||
| 361 | } |
||
| 362 | } |
||
| 363 | } |
||
| 364 | if(frame.body.length !== inflatedSize) {
|
||
| 365 | return |
||
| 366 | } |
||
| 367 | } |
||
| 368 | |||
| 369 | let decoded |
||
| 370 | if(ID3Frames[specName]) {
|
||
| 371 | decoded = ID3Frames[specName].read(frame.body, ID3Version, this) |
||
| 372 | } else if(specName.startsWith('T')) {
|
||
| 373 | decoded = ID3Frames.GENERIC_TEXT.read(frame.body, ID3Version) |
||
| 374 | } else if(specName.startsWith('W')) {
|
||
| 375 | decoded = ID3Frames.GENERIC_URL.read(frame.body, ID3Version) |
||
| 376 | } |
||
| 377 | |||
| 378 | if(decoded) {
|
||
| 379 | if(ID3Util.getSpecOptions(specName, ID3Version).multiple) {
|
||
| 380 | if(!options.onlyRaw) {
|
||
| 381 | if(!tags[identifier]) {
|
||
| 382 | tags[identifier] = [] |
||
| 383 | } |
||
| 384 | tags[identifier].push(decoded) |
||
| 385 | } |
||
| 386 | if(!options.noRaw) {
|
||
| 387 | if(!raw[specName]) {
|
||
| 388 | raw[specName] = [] |
||
| 389 | } |
||
| 390 | raw[specName].push(decoded) |
||
| 391 | } |
||
| 392 | } else {
|
||
| 393 | if(!options.onlyRaw) {
|
||
| 394 | tags[identifier] = decoded |
||
| 395 | } |
||
| 396 | if(!options.noRaw) {
|
||
| 397 | raw[specName] = decoded |
||
| 398 | } |
||
| 399 | } |
||
| 400 | } |
||
| 401 | }) |
||
| 402 | |||
| 403 | if(options.onlyRaw) {
|
||
| 404 | return raw |
||
| 405 | } |
||
| 406 | if(options.noRaw) {
|
||
| 407 | return tags |
||
| 408 | } |
||
| 409 | |||
| 410 | tags.raw = raw |
||
| 411 | return tags |
||
| 412 | } |
||
| 413 | |||
| 414 | /** |
||
| 415 | * Checks and removes already written ID3-Frames from a buffer |
||
| 416 | * @param data - Buffer |
||
| 417 | * @returns {boolean|Buffer}
|
||
| 418 | */ |
||
| 419 | module.exports.removeTagsFromBuffer = function(data) {
|
||
| 420 | let framePosition = ID3Util.getFramePosition(data) |
||
| 421 | |||
| 422 | if (framePosition === -1) {
|
||
| 423 | return data |
||
| 424 | } |
||
| 425 | |||
| 426 | let hSize = Buffer.from([data[framePosition + 6], data[framePosition + 7], data[framePosition + 8], data[framePosition + 9]]) |
||
| 427 | |||
| 428 | const isMsbSet = !!((hSize[0] | hSize[1] | hSize[2] | hSize[3]) & 0x80) |
||
| 429 | if (isMsbSet) {
|
||
| 430 | // Invalid tag size (msb not 0) |
||
| 431 | return false |
||
| 432 | } |
||
| 433 | |||
| 434 | if (data.length >= framePosition + 10) {
|
||
| 435 | const size = ID3Util.decodeSize(data.slice(framePosition + 6, framePosition + 10)) |
||
| 436 | return Buffer.concat([data.slice(0, framePosition), data.slice(framePosition + size + 10)]) |
||
| 437 | } |
||
| 438 | |||
| 439 | return data |
||
| 440 | } |
||
| 441 | |||
| 442 | /** |
||
| 443 | * Checks and removes already written ID3-Frames from a file |
||
| 444 | * @param filepath - Filepath to file |
||
| 445 | * @param fn - (optional) Function for async usage |
||
| 446 | * @returns {boolean|Error}
|
||
| 447 | */ |
||
| 448 | module.exports.removeTags = function(filepath, fn) {
|
||
| 449 | if(!fn || typeof fn !== 'function') {
|
||
| 450 | let data |
||
| 451 | try {
|
||
| 452 | data = fs.readFileSync(filepath) |
||
| 453 | } catch(e) {
|
||
| 454 | return e |
||
| 455 | } |
||
| 456 | |||
| 457 | let newData = this.removeTagsFromBuffer(data) |
||
| 458 | if(!newData) {
|
||
| 459 | return false |
||
| 460 | } |
||
| 461 | |||
| 462 | try {
|
||
| 463 | fs.writeFileSync(filepath, newData, 'binary') |
||
| 464 | } catch(e) {
|
||
| 465 | return e |
||
| 466 | } |
||
| 467 | |||
| 468 | return true |
||
| 469 | } |
||
| 470 | |||
| 471 | fs.readFile(filepath, function(err, data) {
|
||
| 472 | if(err) {
|
||
| 473 | fn(err) |
||
| 474 | } |
||
| 475 | |||
| 476 | let newData = this.removeTagsFromBuffer(data) |
||
| 477 | if(!newData) {
|
||
| 478 | fn(err) |
||
| 479 | return |
||
| 480 | } |
||
| 481 | |||
| 482 | fs.writeFile(filepath, newData, 'binary', function(err) {
|
||
| 483 | if(err) {
|
||
| 484 | fn(err) |
||
| 485 | } else {
|
||
| 486 | fn(false) |
||
| 487 | } |
||
| 488 | }) |
||
| 489 | }.bind(this)) |
||
| 490 | } |
||
|
0 ignored issues
–
show
|
|||
| 491 | |||
| 492 | module.exports.Promise = {
|
||
| 493 | write: (tags, file) => {
|
||
| 494 | return new Promise((resolve, reject) => {
|
||
| 495 | this.write(tags, file, (err, ret) => {
|
||
| 496 | if(err) {
|
||
| 497 | reject(err) |
||
| 498 | } else {
|
||
| 499 | resolve(ret) |
||
| 500 | } |
||
| 501 | }) |
||
| 502 | }) |
||
| 503 | }, |
||
| 504 | update: (tags, file) => {
|
||
| 505 | return new Promise((resolve, reject) => {
|
||
| 506 | this.update(tags, file, (err, ret) => {
|
||
| 507 | if(err) {
|
||
| 508 | reject(err) |
||
| 509 | } else {
|
||
| 510 | resolve(ret) |
||
| 511 | } |
||
| 512 | }) |
||
| 513 | }) |
||
| 514 | }, |
||
| 515 | create: (tags) => {
|
||
| 516 | return new Promise((resolve) => {
|
||
| 517 | this.create(tags, (buffer) => {
|
||
| 518 | resolve(buffer) |
||
| 519 | }) |
||
| 520 | }) |
||
| 521 | }, |
||
| 522 | read: (file, options) => {
|
||
| 523 | return new Promise((resolve, reject) => {
|
||
| 524 | this.read(file, options, (err, ret) => {
|
||
| 525 | if(err) {
|
||
| 526 | reject(err) |
||
| 527 | } else {
|
||
| 528 | resolve(ret) |
||
| 529 | } |
||
| 530 | }) |
||
| 531 | }) |
||
| 532 | }, |
||
| 533 | removeTags: (filepath) => {
|
||
| 534 | return new Promise((resolve, reject) => {
|
||
| 535 | this.removeTags(filepath, (err) => {
|
||
| 536 | if(err) {
|
||
| 537 | reject(err) |
||
| 538 | } else {
|
||
| 539 | resolve() |
||
| 540 | } |
||
| 541 | }) |
||
| 542 | }) |
||
| 543 | } |
||
| 544 | } |
||
| 545 |