'use strict'; const Transmission = require('transmission-promise'); const conf = require('>/conf'); const tr_client = new Transmission(conf.transmission) const statusMap = [ 'STOPPED', // 0 'CHECK_WAIT', // 1 'CHECK', // 2 'DOWNLOAD_WAIT', // 3 'DOWNLOAD', // 4 'SEED_WAIT', // 5 'SEED', // 6 'ISOLATED', // 7 ]; module.exports = (sequelize, DataTypes, Model) => { class Torrent extends Model { /** * Helper method for defining associations. * This method is not a part of Sequelize lifecycle. * The `models/index` file will call this method automatically. */ static associate(models) { // define association here } static trClient = tr_client; static async create(data, ...args){ try{ // let instance = this.build(data); // console.log('instance', instance) await this.build(data).validate(); // console.log('validate', val); let res = await tr_client.addUrl(data.magnetLink); return await super.create({ magnetLink: data.magnetLink, hashString: res.hashString, name: res.name, added_by: data.added_by, status: 0, percentDone: 0, }, args); }catch (error){ console.log('Torrent create error', error); throw error; } } static async migrate(hashString, username){ try{ let exists = await this.findByPk(hashString); if(exists){ console.log('torrent in DB, skipping') return {} } let res = ( await tr_client.get(hashString, [ "eta", "percentDone", "status", "rateDownload", "errorString", "hashString", 'name', 'downloadDir', 'addedDate', 'magnetLink', 'files', //array of files 'filesStats', // array of files with status 'isFinished', 'isStalled', 'peers', 'peersConnected', // array of peers, 'sizeWhenDone', ]) ).torrents[0]; // console.log('date:', res.addedDate, new Date(res.addedDate*1000), 'res:', res) let instance = await this.build({createdAt: new Date(res.addedDate*1000), ...res, added_by: username}); await instance.save(); return {...res, ...instance.dataValues}; }catch(error){ console.error('migrate error', error); } } async getTorrentData(noUpdate){ try{ if(this.percentDone === 1) return this.dataValues let res = ( await tr_client.get(this.hashString, [ "eta", "percentDone", "status", "rateDownload", "errorString", "hashString", 'name', 'downloadDir', 'dateCreated', 'files', //array of files 'filesStats', // array of files with status 'isFinished', 'isStalled', 'peers', 'peersConnected', // array of peers, 'sizeWhenDone', ]) ).torrents[0]; await this.update(res); if(noUpdate) await this.save(); return {...res, ...this.dataValues}; }catch(error){ if(error.code === 'ECONNREFUSED'){ let e = new Error('TorrentGatewayDown') e.status = 555 throw e } // console.error(`Torrent ${this.hashString} getTorrentData error`, error); throw error; } } async stop(){ return await this.constructor.trClient.stop(this.hashString); } async start(force){ if(force) return await this.constructor.trClient.startNow(this.hashString); let res = await this.constructor.trClient.start(this.hashString); console.log('start', res); return res; } async destroy(){ await await this.constructor.trClient.remove(this.hashString, true); return await super.destroy() } } Torrent.init({ hashString: { type: DataTypes.STRING, allowNull: false, primaryKey: true }, magnetLink: { type: DataTypes.STRING, allowNull: false, validate:{ notNull: true, notEmpty: true, }, }, isPrivate: { type: DataTypes.BOOLEAN, defaultValue: false, }, name: DataTypes.STRING, added_by: { type: DataTypes.STRING, ldapModel: 'User', allowNull: false, validate:{ notNull: true, notEmpty: true, }, }, status: DataTypes.NUMBER, percentDone: DataTypes.FLOAT, downloadDir: { type: DataTypes.STRING, allowNull: true, }, errorString: { type: DataTypes.STRING, allowNull: true, }, sizeWhenDone: { type: DataTypes.NUMBER, allowNull: true, }, createdAt: { type: DataTypes.DATE }, }, { sequelize, modelName: 'Torrent', logging: false, }); return Torrent; };