+
diff --git a/modules/about/server/controllers/makers.server.controller.js b/modules/about/server/controllers/makers.server.controller.js
index e267bc51..c23a03e8 100644
--- a/modules/about/server/controllers/makers.server.controller.js
+++ b/modules/about/server/controllers/makers.server.controller.js
@@ -153,8 +153,8 @@ exports.delete = function (req, res) {
exports.list = function (req, res) {
Maker.find()
.sort('-torrent_count')
- .populate('user', 'username displayName profileImageURL isVip')
- .populate('members', 'username displayName profileImageURL isVip')
+ .populate('user', 'username displayName profileImageURL isVip score uploaded downloaded')
+ .populate('members', 'username displayName profileImageURL isVip score uploaded downloaded')
.exec(function (err, makers) {
if (err) {
return res.status(422).send({
@@ -323,9 +323,9 @@ exports.makerByID = function (req, res, next, id) {
}
Maker.findById(id)
- .populate('user', 'username displayName profileImageURL isVip')
- .populate('members', 'username displayName profileImageURL isVip')
- .populate('_ratings.user', 'username displayName profileImageURL isVip uploaded downloaded')
+ .populate('user', 'username displayName profileImageURL isVip score uploaded downloaded')
+ .populate('members', 'username displayName profileImageURL isVip score uploaded downloaded')
+ .populate('_ratings.user', 'username displayName profileImageURL isVip score uploaded downloaded')
.exec(function (err, maker) {
if (err) {
return next(err);
diff --git a/modules/announce/server/controllers/announces.server.controller.js b/modules/announce/server/controllers/announces.server.controller.js
index 2d4de6c2..f3495bcd 100644
--- a/modules/announce/server/controllers/announces.server.controller.js
+++ b/modules/announce/server/controllers/announces.server.controller.js
@@ -22,10 +22,8 @@ var path = require('path'),
var traceConfig = config.meanTorrentConfig.trace;
var scoreConfig = config.meanTorrentConfig.score;
var hnrConfig = config.meanTorrentConfig.hitAndRun;
-var signConfig = config.meanTorrentConfig.sign;
var announceConfig = config.meanTorrentConfig.announce;
var globalSalesConfig = config.meanTorrentConfig.torrentGlobalSales;
-var examinationConfig = config.meanTorrentConfig.examination;
var appConfig = config.meanTorrentConfig.app;
@@ -166,8 +164,10 @@ exports.announce = function (req, res) {
req.selfpeer = [];
req.seeder = false;
- mtDebug.debugGreen('', 'ANNOUNCE', true, req.passkeyuser);
- mtDebug.debugGreen('============= Announce request =============', 'ANNOUNCE', true, req.passkeyuser);
+ mtDebug.debugGreen('\n\n', 'ANNOUNCE', true, req.passkeyuser);
+ mtDebug.debugGreen('================================================================================', 'ANNOUNCE', true, req.passkeyuser);
+ mtDebug.debugGreen(' ANNOUNCE REQUEST ', 'ANNOUNCE', true, req.passkeyuser);
+ mtDebug.debugGreen('================================================================================', 'ANNOUNCE', true, req.passkeyuser);
mtDebug.debugBlue(req.url, 'ANNOUNCE', true, req.passkeyuser);
var s = req.url.split('?');
@@ -277,6 +277,8 @@ exports.announce = function (req, res) {
torrent data include peers
---------------------------------------------------------------*/
function (done) {
+ mtDebug.debugRed('req.passkeyuser._id = ' + req.passkeyuser._id.toString(), 'ANNOUNCE', true, req.passkeyuser);
+ mtDebug.debugRed('req.torrent.info_hash = ' + query.info_hash, 'ANNOUNCE', true, req.passkeyuser);
Torrent.findOne({
info_hash: query.info_hash
})
@@ -334,7 +336,7 @@ exports.announce = function (req, res) {
---------------------------------------------------------------*/
function (done) {
mtDebug.debugGreen('---------------' + eventString(query.event) + '----------------', 'ANNOUNCE', true, req.passkeyuser);
- if (req.seeder && event(query.event) !== EVENT_COMPLETED) {
+ if (req.seeder && event(query.event) !== EVENT_COMPLETED && event(query.event) !== EVENT_STOPPED) {
if (announceConfig.seedingInFinishedCheck) {
if (!req.passkeyuser._id.equals(req.torrent.user._id)) {
Finished.findOne({
@@ -363,7 +365,7 @@ exports.announce = function (req, res) {
if not find and torrent is h&r and user isn`t vip, then create complete record
---------------------------------------------------------------*/
function (done) {
- if (req.torrent.torrent_hnr && !req.passkeyuser.isVip) {
+ if (hnrConfig.enable && req.torrent.torrent_hnr && !req.passkeyuser.isVip) {
Complete.findOne({
torrent: req.torrent._id,
user: req.passkeyuser._id
@@ -405,8 +407,6 @@ exports.announce = function (req, res) {
----------------------------------------------------------------*/
function (done) {
if (event(query.event) === EVENT_STARTED) {
- mtDebug.debugGreen('---------------EVENT_STARTED----------------', 'ANNOUNCE', true, req.passkeyuser);
-
Peer.remove({
torrent: req.torrent._id,
_id: {$nin: req.torrent._peers}
@@ -429,19 +429,23 @@ exports.announce = function (req, res) {
---------------------------------------------------------------*/
function (done) {
if (!req.seeder && !req.passkeyuser.isVip && event(query.event) === EVENT_STARTED) {
- if (req.passkeyuser.hnr_warning >= hnrConfig.forbiddenDownloadMinWarningNumber) {
- if (!req.torrent.torrent_hnr) {
- done(190);
- } else {
- if (!req.completeTorrent) {
- done(191);
+ if (hnrConfig.enable) {
+ if (req.passkeyuser.hnr_warning >= hnrConfig.forbiddenDownloadMinWarningNumber) {
+ if (!req.torrent.torrent_hnr) {
+ done(190);
} else {
- if (!req.completeTorrent.hnr_warning) {
- done(190);
+ if (!req.completeTorrent) {
+ done(191);
} else {
- done(null);
+ if (!req.completeTorrent.hnr_warning) {
+ done(190);
+ } else {
+ done(null);
+ }
}
}
+ } else {
+ done(null);
}
} else {
done(null);
@@ -457,7 +461,7 @@ exports.announce = function (req, res) {
vip user not checked
---------------------------------------------------------------*/
function (done) {
- if (!req.seeder && !req.passkeyuser.isVip && event(query.event) === EVENT_STARTED) {
+ if (!req.seeder && !req.passkeyuser.isVip && !req.passkeyuser.isOper && event(query.event) === EVENT_STARTED) {
if (req.passkeyuser.ratio !== -1 && req.passkeyuser.ratio < announceConfig.downloadCheck.ratio) {
var checkTimeBegin = moment(req.passkeyuser.created).add(announceConfig.downloadCheck.checkAfterSignupDays, 'd');
if (checkTimeBegin < moment(Date.now())) {
@@ -492,6 +496,9 @@ exports.announce = function (req, res) {
}
getCurrentPeer(function () {
+ mtDebug.debugRed('req.currentPeer.isNewCreated = ' + req.currentPeer.isNewCreated, 'ANNOUNCE', true, req.passkeyuser);
+ mtDebug.debugRed('req.currentPeer._id = ' + req.currentPeer._id.toString(), 'ANNOUNCE', true, req.passkeyuser);
+ mtDebug.debugRed('req.currentPeer.torrent._id = ' + req.currentPeer.torrent._id, 'ANNOUNCE', true, req.passkeyuser);
done(null);
});
},
@@ -503,15 +510,16 @@ exports.announce = function (req, res) {
numbers is in setting announceConfig.announceCheck
---------------------------------------------------------------*/
function (done) {
+ mtDebug.debugGreen('---------------CHECK USER SEED/LEECH COUNT----------------', 'ANNOUNCE', true, req.passkeyuser);
var lcount = getSelfLeecherCount();
var scount = getSelfSeederCount();
if (lcount > announceConfig.announceCheck.maxLeechNumberPerUserPerTorrent && !req.seeder) {
- mtDebug.debugYellow('getSelfLeecherCount = ' + lcount, 'ANNOUNCE', true, req.passkeyuser);
+ mtDebug.debugRed('getSelfLeecherCount = ' + lcount, 'ANNOUNCE', true, req.passkeyuser);
removeCurrPeer();
done(180);
} else if (scount > announceConfig.announceCheck.maxSeedNumberPerUserPerTorrent && req.seeder) {
- mtDebug.debugYellow('getSelfSeederCount = ' + scount, 'ANNOUNCE', true, req.passkeyuser);
+ mtDebug.debugRed('getSelfSeederCount = ' + scount, 'ANNOUNCE', true, req.passkeyuser);
removeCurrPeer();
done(181);
} else {
@@ -555,25 +563,24 @@ exports.announce = function (req, res) {
}
//write user uploaded and downloaded
- req.passkeyuser.uploaded += u;
- req.passkeyuser.downloaded += d;
- req.passkeyuser.true_uploaded += curru;
- req.passkeyuser.true_downloaded += currd;
- //write examination uploaded and downloaded
- if (common.examinationIsValid(req.passkeyuser)) {
- req.passkeyuser.examinationData.uploaded = req.passkeyuser.examinationData.uploaded || 0;
- req.passkeyuser.examinationData.uploaded += u;
- req.passkeyuser.examinationData.downloaded = req.passkeyuser.examinationData.downloaded || 0;
- req.passkeyuser.examinationData.downloaded += d;
+ var up_d = {
+ uploaded: u,
+ downloaded: d,
+ true_uploaded: curru,
+ true_downloaded: currd
+ };
+ mtDebug.debugRed(JSON.stringify(up_d), 'ANNOUNCE', true, req.passkeyuser);
- var uploadFinished = req.passkeyuser.examinationData.uploaded >= examinationConfig.incrementData.upload;
- var downloadFinished = req.passkeyuser.examinationData.downloaded >= examinationConfig.incrementData.download;
- var scoreFinished = req.passkeyuser.examinationData.score >= examinationConfig.incrementData.score;
- req.passkeyuser.examinationData.isFinished = uploadFinished && downloadFinished && scoreFinished;
- req.passkeyuser.examinationData.finishedTime = req.passkeyuser.examinationData.isFinished ? Date.now() : null;
- req.passkeyuser.markModified('examinationData');
+ if (common.examinationIsValid(req.passkeyuser)) {
+ up_d['examinationData.uploaded'] = u;
+ up_d['examinationData.downloaded'] = d;
+ mtDebug.debugGreen('---------------WRITE EXAMINATION DATA----------------', 'ANNOUNCE', true, req.passkeyuser);
+ mtDebug.debugRed('examinationData.uploaded: ' + u + ', examinationData.downloaded: ' + d, 'ANNOUNCE', true, req.passkeyuser);
}
- req.passkeyuser.save();
+
+ req.passkeyuser.update({
+ $inc: up_d
+ }).exec();
//write peer speed
var sp = {};
@@ -642,6 +649,7 @@ exports.announce = function (req, res) {
}
totalScore = Math.round(totalScore * 100) / 100;
scoreUpdate(req, req.passkeyuser, action, totalScore, false);
+ mtDebug.debugRed('announce score: ' + totalScore, 'ANNOUNCE', true, req.passkeyuser);
}
}
@@ -691,10 +699,13 @@ exports.announce = function (req, res) {
}
//write peer data
- req.currentPeer.peer_uploaded = query.uploaded;
- req.currentPeer.peer_downloaded = query.downloaded;
- req.currentPeer.peer_left = query.peer_left;
- req.currentPeer.save();
+ req.currentPeer.update({
+ $set: {
+ peer_uploaded: query.uploaded,
+ peer_downloaded: query.downloaded,
+ peer_left: query.left
+ }
+ }).exec();
done(null, curru, currd);
},
@@ -704,11 +715,14 @@ exports.announce = function (req, res) {
---------------------------------------------------------------*/
function (curru, currd, done) {
if (curru > 0 || currd > 0) {
- if (req.completeTorrent) {
+ if (hnrConfig.enable && req.completeTorrent) {
mtDebug.debugGreen('---------------WRITE COMPLETE DATA----------------', 'ANNOUNCE', true, req.passkeyuser);
- req.completeTorrent.total_uploaded += curru;
- req.completeTorrent.total_downloaded += currd;
- req.completeTorrent.save(function () {
+ req.completeTorrent.update({
+ $inc: {
+ total_uploaded: curru,
+ total_downloaded: currd
+ }
+ }, function () {
done(null);
});
} else {
@@ -725,10 +739,13 @@ exports.announce = function (req, res) {
---------------------------------------------------------------*/
function (done) {
if (!req.currentPeer.isNewCreated) {
- if (req.completeTorrent && req.completeTorrent.complete && event(query.event) !== EVENT_COMPLETED) {
+ if (hnrConfig.enable && req.completeTorrent && req.completeTorrent.complete && event(query.event) !== EVENT_COMPLETED) {
mtDebug.debugGreen('---------------UPDATE H&R COMPLETE TOTAL_SEED_TIME----------------', 'ANNOUNCE', true, req.passkeyuser);
- req.completeTorrent.total_seed_time += (Date.now() - req.currentPeer.last_announce_at);
- req.completeTorrent.save(function () {
+ req.completeTorrent.update({
+ $inc: {
+ total_seed_time: (Date.now() - req.currentPeer.last_announce_at)
+ }
+ }, function () {
done(null);
});
} else {
@@ -745,7 +762,7 @@ exports.announce = function (req, res) {
---------------------------------------------------------------*/
function (done) {
if (!req.currentPeer.isNewCreated) {
- if (req.seeder && event(query.event) !== EVENT_COMPLETED) {
+ if (req.seeder && event(query.event) !== EVENT_COMPLETED && event(query.event) !== EVENT_STARTED) {
mtDebug.debugGreen('---------------UPLOAD SCORE THROUGH SEED TIMED----------------', 'ANNOUNCE', true, req.passkeyuser);
var action = scoreConfig.action.seedTimed;
@@ -779,6 +796,7 @@ exports.announce = function (req, res) {
}
seedScore = Math.round(seedScore * 100) / 100;
scoreUpdate(req, req.passkeyuser, action, seedScore);
+ mtDebug.debugRed('seed timed score: ' + seedScore, 'ANNOUNCE', true, req.passkeyuser);
done(null);
} else {
@@ -803,12 +821,11 @@ exports.announce = function (req, res) {
mtDebug.debugGreen('---------------UPDATE LAST_ANNOUNCE_AT----------------', 'ANNOUNCE', true, req.passkeyuser);
if (!req.currentPeer.isNewCreated) {
- req.currentPeer.last_announce_at = Date.now();
- req.currentPeer.save();
- }
-
- if (req.completeTorrent) {
- req.completeTorrent.globalUpdateMethod();
+ req.currentPeer.update({
+ $set: {
+ last_announce_at: Date.now()
+ }
+ }).exec();
}
done(null);
@@ -820,22 +837,6 @@ exports.announce = function (req, res) {
function (done) {
if (event(query.event) === EVENT_COMPLETED) {
mtDebug.debugGreen('---------------EVENT_COMPLETED----------------', 'ANNOUNCE', true, req.passkeyuser);
- //write completed torrent data into finished
- var finished = new Finished();
- finished.user = req.passkeyuser;
- finished.torrent = req.torrent;
- finished.user_ip = req.cf_ip;
- finished.user_agent = req.get('User-Agent');
- finished.user_port = query.port;
- finished.save();
-
- traceLogCreate(req, traceConfig.action.userAnnounceFinished, {
- user: req.passkeyuser._id,
- torrent: req.torrent._id,
- agent: req.get('User-Agent'),
- ip: req.cf_ip,
- port: query.port
- });
doCompleteEvent(function () {
done(null);
@@ -850,7 +851,7 @@ exports.announce = function (req, res) {
---------------------------------------------------------------*/
function (done) {
if (!req.currentPeer.isNewCreated) {
- if (req.completeTorrent && event(query.event) !== EVENT_COMPLETED) {
+ if (hnrConfig.enable && req.completeTorrent && event(query.event) !== EVENT_COMPLETED) {
mtDebug.debugGreen('---------------COUNT H&R WARNING FOR USER----------------', 'ANNOUNCE', true, req.passkeyuser);
req.completeTorrent.countHnRWarning(false, true);
}
@@ -867,7 +868,7 @@ exports.announce = function (req, res) {
if (event(query.event) === EVENT_STOPPED) {
mtDebug.debugGreen('---------------EVENT_STOPPED----------------', 'ANNOUNCE', true, req.passkeyuser);
- if (req.completeTorrent) {
+ if (hnrConfig.enable && req.completeTorrent) {
req.completeTorrent.countHnRWarning(true, false);
}
removeCurrPeer(function () {
@@ -908,8 +909,9 @@ exports.announce = function (req, res) {
var len = writePeers(peerBuffer, want, req.torrent._peers);
peerBuffer = peerBuffer.slice(0, len);
+ mtDebug.debugGreen('---------------SEND RESPONSE TO USER----------------', 'ANNOUNCE', true, req.passkeyuser);
var resp = 'd8:intervali' + ANNOUNCE_INTERVAL + 'e8:completei' + req.torrent.torrent_seeds + 'e10:incompletei' + req.torrent.torrent_leechers + 'e10:downloadedi' + req.torrent.torrent_finished + 'e5:peers' + len + ':';
- mtDebug.debugGreen(resp, 'ANNOUNCE', true, req.passkeyuser);
+ mtDebug.debugRed(resp, 'ANNOUNCE', true, req.passkeyuser);
res.writeHead(200, {
'Content-Length': resp.length + peerBuffer.length + 1,
@@ -924,6 +926,25 @@ exports.announce = function (req, res) {
mtDebug.debug(peerBuffer, 'ANNOUNCE', true, req.passkeyuser);
}
+ done(null);
+ },
+
+ /**
+ * update user, torrent, peer, complete
+ * @param done
+ */
+ function (done) {
+ req.passkeyuser.globalUpdateMethod(true);
+ req.torrent.globalUpdateMethod(true);
+
+ if (req.currentPeer) {
+ req.currentPeer.globalUpdateMethod(true);
+ }
+
+ if (hnrConfig.enable && req.completeTorrent) {
+ req.completeTorrent.globalUpdateMethod(true);
+ }
+
done(null, 'done');
}
], function (err, reason) {
@@ -940,8 +961,22 @@ exports.announce = function (req, res) {
req.selfpeer.every(function (p) {
if (p.peer_id === query.peer_id) {
req.currentPeer = p;
+ req.currentPeer.torrent = req.torrent;
req.currentPeer.isNewCreated = false;
+ //if find peer_id, but some time some client (like qbittorrent 4.1.0) the ip or port is changed, update it
+ if ((req.currentPeer.peer_ip !== req.cf_ip || req.currentPeer.peer_port !== query.port) && query.port !== 0) {
+ req.currentPeer.peer_ip = req.cf_ip;
+ req.currentPeer.peer_port = query.port;
+
+ req.currentPeer.update({
+ $set: {
+ peer_ip: req.cf_ip,
+ peer_port: query.port
+ }
+ }).exec();
+ }
+
if (req.seeder && req.currentPeer.peer_status !== PEERSTATE_SEEDER && event(query.event) !== EVENT_COMPLETED) {
mtDebug.debugGreen('---------------PEER STATUS CHANGED: Seeder----------------', 'ANNOUNCE', true, req.passkeyuser);
doCompleteEvent(function () {
@@ -966,19 +1001,48 @@ exports.announce = function (req, res) {
* doCompleteEvent
*/
function doCompleteEvent(callback) {
- req.currentPeer.peer_status = PEERSTATE_SEEDER;
- req.currentPeer.save();
+ //write completed torrent data into finished
+ var finished = new Finished();
+ finished.user = req.passkeyuser;
+ finished.torrent = req.torrent;
+ finished.user_ip = req.cf_ip;
+ finished.user_agent = req.get('User-Agent');
+ finished.user_port = query.port;
+ finished.save();
- req.torrent.torrent_finished += 1;
- req.torrent.save();
+ traceLogCreate(req, traceConfig.action.userAnnounceFinished, {
+ user: req.passkeyuser._id,
+ torrent: req.torrent._id,
+ agent: req.get('User-Agent'),
+ ip: req.cf_ip,
+ port: query.port
+ });
- req.passkeyuser.finished += 1;
- req.passkeyuser.save();
+ req.currentPeer.update({
+ $set: {
+ peer_status: PEERSTATE_SEEDER
+ }
+ }).exec();
+
+ req.torrent.update({
+ $inc: {
+ torrent_finished: 1
+ }
+ }).exec();
+
+ req.passkeyuser.update({
+ $inc: {
+ finished: 1
+ }
+ }).exec();
//update completeTorrent complete status
- if (req.completeTorrent) {
- req.completeTorrent.complete = true;
- req.completeTorrent.save(function () {
+ if (hnrConfig.enable && req.completeTorrent) {
+ req.completeTorrent.update({
+ $set: {
+ complete: true
+ }
+ }, function () {
if (callback) callback();
});
} else {
@@ -1017,12 +1081,10 @@ exports.announce = function (req, res) {
req.passkeyuser.addLeechedIp(peer.peer_ip);
req.passkeyuser.addClientAgent(peer.user_agent);
- peer.save(function (err) {
- if (!err) {
- req.currentPeer = peer;
- mtDebug.debugGreen('---------------createCurrentPeer()----------------', 'ANNOUNCE', true, req.passkeyuser);
- if (callback) callback();
- }
+ peer.save(function () {
+ req.currentPeer = peer;
+ mtDebug.debugGreen('---------------createCurrentPeer()----------------', 'ANNOUNCE', true, req.passkeyuser);
+ if (callback) callback();
});
}
@@ -1032,13 +1094,23 @@ exports.announce = function (req, res) {
function removeCurrPeer(callback) {
req.selfpeer.splice(req.selfpeer.indexOf(req.currentPeer), 1);
- req.torrent.update({
- $pull: {_peers: req.currentPeer._id}
- }).exec();
+ req.torrent._peers.forEach(function (_p) {
+ if (_p._id.equals(req.currentPeer._id)) {
+ req.torrent._peers.pull(_p);
+ req.torrent.save();
+ }
+ });
- req.currentPeer.remove(function () {
- if (callback) callback();
- mtDebug.debugGreen('---------------removeCurrPeer()----------------', 'ANNOUNCE', true, req.passkeyuser);
+ Peer.findById(req.currentPeer._id, function (err, _p) {
+ _p.remove(function (err) {
+ if (err) {
+ mtDebug.debugGreen('---------------removeCurrPeer(): Error----------------', 'ANNOUNCE', true, req.passkeyuser);
+ } else {
+ mtDebug.debugGreen('---------------removeCurrPeer()----------------', 'ANNOUNCE', true, req.passkeyuser);
+ }
+ req.currentPeer = undefined;
+ if (callback) callback();
+ });
});
}
@@ -1090,13 +1162,15 @@ exports.announce = function (req, res) {
var udr = {};
var sale = req.torrent.torrent_sale_status;
- var start = moment(globalSalesConfig.global.startAt, globalSalesConfig.global.timeFormats).utc().valueOf();
+ var start = moment(globalSalesConfig.global.startAt, globalSalesConfig.global.timeFormats).valueOf();
var end = start + globalSalesConfig.global.expires;
var now = Date.now();
isGlobalSaleValid = (now > start && now < end && globalSalesConfig.global.value) ? true : false;
if (isGlobalSaleValid && globalSalesConfig.global.value) {
sale = globalSalesConfig.global.value;
+ mtDebug.debugRed('isGlobalSaleValid = ' + isGlobalSaleValid, 'ANNOUNCE', true, req.passkeyuser);
+ mtDebug.debugRed('global sale value = ' + sale, 'ANNOUNCE', true, req.passkeyuser);
}
switch (sale) {
@@ -1185,6 +1259,10 @@ exports.announce = function (req, res) {
var c = 0;
if (!req.seeder && event(query.event) !== EVENT_STOPPED && event(query.event) !== EVENT_COMPLETED) {
+ mtDebug.debugGreen('---------------GET PEERS LIST----------------', 'ANNOUNCE', true, req.passkeyuser);
+ mtDebug.debugRed('want.count = ' + count, 'ANNOUNCE', true, req.passkeyuser);
+ mtDebug.debugRed('peers.length = ' + peers.length, 'ANNOUNCE', true, req.passkeyuser);
+
var p;
var bc;
var m = Math.min(peers.length, count);
@@ -1201,14 +1279,14 @@ exports.announce = function (req, res) {
if (p.last_announce_at > (Date.now() - announceConfig.announceInterval - announceConfig.announceIdleTime)) { //do not send inactive peer
if (p.user.equals(req.passkeyuser._id)) {
if (announceConfig.peersCheck.peersSendListIncludeOwnSeed) {
- mtDebug.debug(p._id.toString(), 'ANNOUNCE', true, req.passkeyuser);
+ mtDebug.debug(p._id.toString() + ' IP:' + p.peer_ip + ' PORT:' + p.peer_port, 'ANNOUNCE', true, req.passkeyuser);
bc = compact(p);
if (bc) {
bc.copy(buf, c++ * PEER_COMPACT_SIZE);
}
}
} else {
- mtDebug.debug(p._id.toString(), 'ANNOUNCE', true, req.passkeyuser);
+ mtDebug.debug(p._id.toString() + ' IP:' + p.peer_ip + ' PORT:' + p.peer_port, 'ANNOUNCE', true, req.passkeyuser);
bc = compact(p);
if (bc) {
bc.copy(buf, c++ * PEER_COMPACT_SIZE);
diff --git a/modules/check/client/check.client.module.js b/modules/check/client/check.client.module.js
new file mode 100644
index 00000000..766781f8
--- /dev/null
+++ b/modules/check/client/check.client.module.js
@@ -0,0 +1,9 @@
+(function (app) {
+ 'use strict';
+
+ app.registerModule('check', ['core']);// The core module is required for special route handling; see /core/client/config/core.client.routes
+ app.registerModule('check.admin', ['core.admin']);
+ app.registerModule('check.admin.routes', ['core.admin.routes']);
+ app.registerModule('check.services');
+ app.registerModule('check.routes', ['ui.router', 'core.routes', 'check.services']);
+}(ApplicationConfiguration));
diff --git a/modules/check/client/services/check.client.service.js b/modules/check/client/services/check.client.service.js
new file mode 100644
index 00000000..b4577736
--- /dev/null
+++ b/modules/check/client/services/check.client.service.js
@@ -0,0 +1,24 @@
+(function () {
+ 'use strict';
+
+ // Users service used for communicating with the users REST endpoint
+ angular
+ .module('check.services')
+ .factory('CheckService', CheckService);
+
+ CheckService.$inject = ['$resource'];
+
+ function CheckService($resource) {
+ var Check = $resource('/api/check', {}, {
+ get: {
+ method: 'GET'
+ },
+ update: {
+ method: 'PUT'
+ }
+ });
+
+ return Check;
+ }
+
+}());
diff --git a/modules/check/server/config/check.server.config.js b/modules/check/server/config/check.server.config.js
new file mode 100644
index 00000000..629c3606
--- /dev/null
+++ b/modules/check/server/config/check.server.config.js
@@ -0,0 +1,14 @@
+'use strict';
+
+/**
+ * Module dependencies
+ */
+var path = require('path'),
+ config = require(path.resolve('./config/config'));
+
+/**
+ * Module init function.
+ */
+module.exports = function (app, db) {
+
+};
diff --git a/modules/check/server/controllers/check.server.controller.js b/modules/check/server/controllers/check.server.controller.js
new file mode 100644
index 00000000..92d93843
--- /dev/null
+++ b/modules/check/server/controllers/check.server.controller.js
@@ -0,0 +1,114 @@
+'use strict';
+
+/**
+ * Module dependencies
+ */
+var path = require('path'),
+ config = require(path.resolve('./config/config')),
+ mongoose = require('mongoose'),
+ errorHandler = require(path.resolve('./modules/core/server/controllers/errors.server.controller')),
+ moment = require('moment'),
+ User = mongoose.model('User'),
+ Check = mongoose.model('Check'),
+ scoreUpdate = require(path.resolve('./config/lib/score')).update;
+
+var mtDebug = require(path.resolve('./config/lib/debug'));
+var scoreConfig = config.meanTorrentConfig.score;
+var appConfig = config.meanTorrentConfig.app;
+
+/**
+ * Show the current collection
+ */
+exports.get = function (req, res) {
+ if (!req.user) {
+ return res.status(403).json({
+ message: 'SERVER.USER_IS_NOT_AUTHORIZED'
+ });
+ } else {
+ Check.findOne({user: req.user._id}, function (err, ck) {
+ if (err) {
+ return res.status(422).send({
+ message: errorHandler.getErrorMessage(err)
+ });
+ } else {
+ if (!ck) {
+ return res.status(422).send({
+ message: 'no check data founded'
+ });
+ } else {
+ var oldCheckDate = moment(moment(ck.lastCheckedAt).utcOffset(appConfig.dbTimeZone).format('YYYY-MM-DD'));
+ var now = moment(moment().utcOffset(appConfig.dbTimeZone).format('YYYY-MM-DD'));
+ var diff = now.diff(oldCheckDate, 'days');
+
+ var nck = ck.toJSON();
+ nck.todayIsDone = (diff === 0 ? true : false);
+ res.json(nck);
+ }
+ }
+ });
+ }
+
+};
+
+/**
+ * Update an collection
+ */
+exports.check = function (req, res) {
+ if (!req.user) {
+ return res.status(403).json({
+ message: 'SERVER.USER_IS_NOT_AUTHORIZED'
+ });
+ } else {
+ var score = 0;
+ Check.findOne({user: req.user._id}, function (err, ck) {
+ if (!ck) {
+ ck = new Check();
+ ck.user = req.user._id;
+ ck.keepDays = 1;
+ ck.save();
+
+ score = scoreConfig.action.dailyCheckIn.dailyBasicScore + (ck.keepDays - 1) * scoreConfig.action.dailyCheckIn.dailyStepScore;
+ score = Math.min(score, scoreConfig.action.dailyCheckIn.dailyMaxScore);
+ scoreUpdate(req, req.user, scoreConfig.action.dailyCheckIn, score);
+
+ ck = ck.toJSON();
+ ck.todayIsDone = true;
+ res.json(ck);
+ } else {
+ var oldCheckDate = moment(moment(ck.lastCheckedAt).utcOffset(appConfig.dbTimeZone).format('YYYY-MM-DD'));
+ var now = moment(moment().utcOffset(appConfig.dbTimeZone).format('YYYY-MM-DD'));
+ var diff = now.diff(oldCheckDate, 'days');
+
+ if (diff === 0) {
+ return res.status(422).json({
+ message: 'SERVER.YOU_ALREADY_CHECK_IN'
+ });
+ } else if (diff === 1) {
+ ck.keepDays += 1;
+ ck.lastCheckedAt = Date.now();
+ ck.save();
+
+ score = scoreConfig.action.dailyCheckIn.dailyBasicScore + (ck.keepDays - 1) * scoreConfig.action.dailyCheckIn.dailyStepScore;
+ score = Math.min(score, scoreConfig.action.dailyCheckIn.dailyMaxScore);
+ scoreUpdate(req, req.user, scoreConfig.action.dailyCheckIn, score);
+
+ ck = ck.toJSON();
+ ck.todayIsDone = true;
+ res.json(ck);
+ } else {
+ ck.keepDays = 1;
+ ck.lastCheckedAt = Date.now();
+ ck.save();
+
+ score = scoreConfig.action.dailyCheckIn.dailyBasicScore + (ck.keepDays - 1) * scoreConfig.action.dailyCheckIn.dailyStepScore;
+ score = Math.min(score, scoreConfig.action.dailyCheckIn.dailyMaxScore);
+ scoreUpdate(req, req.user, scoreConfig.action.dailyCheckIn, score);
+
+ ck = ck.toJSON();
+ ck.todayIsDone = true;
+ res.json(ck);
+ }
+ }
+ });
+ }
+};
diff --git a/modules/check/server/models/check.server.model.js b/modules/check/server/models/check.server.model.js
new file mode 100644
index 00000000..5db3e04f
--- /dev/null
+++ b/modules/check/server/models/check.server.model.js
@@ -0,0 +1,30 @@
+'use strict';
+
+/**
+ * Module dependencies
+ */
+var mongoose = require('mongoose'),
+ Schema = mongoose.Schema;
+
+/**
+ * Check in Schema
+ */
+var CheckSchema = new Schema({
+ user: {
+ type: Schema.Types.ObjectId,
+ ref: 'User'
+ },
+ keepDays: {
+ type: Number,
+ default: 0
+ },
+ lastCheckedAt: {
+ type: Date,
+ default: Date.now
+ }
+}, {usePushEach: true});
+
+
+CheckSchema.index({user: 1, createdAt: -1});
+
+mongoose.model('Check', CheckSchema);
diff --git a/modules/check/server/routes/check.server.routes.js b/modules/check/server/routes/check.server.routes.js
new file mode 100644
index 00000000..05691f65
--- /dev/null
+++ b/modules/check/server/routes/check.server.routes.js
@@ -0,0 +1,8 @@
+'use strict';
+
+module.exports = function (app) {
+ var check = require('../controllers/check.server.controller');
+
+ app.route('/api/check').get(check.get);
+ app.route('/api/check').put(check.check);
+};
diff --git a/modules/collections/client/views/collection-view.client.view.html b/modules/collections/client/views/collection-view.client.view.html
index a48ce0ab..e331929f 100644
--- a/modules/collections/client/views/collection-view.client.view.html
+++ b/modules/collections/client/views/collection-view.client.view.html
@@ -95,121 +95,7 @@
{{ 'TABLE_FIELDS.PUBLISHER' | translate}}
-
-
-
-
-
-
-
- {{vm.TGI.getVoteTitle(item)}} {{item.resource_detail_info.vote_average | number : 1}}
-
- {{item.createdat | life}}
- {{item.torrent_size | bytes:2}}
-
-
-
- {{item.torrent_seeds}}
-
-
-
-
- {{item.torrent_leechers}}
-
-
-
-
- {{item.torrent_finished}}
-
-
-
-
-
-
{{ 'ANONYMOUS' | translate }}
-
-
-
-
-
-
-
- {{'COLLECTIONS.BTN_REMOVE_FROM_COLLECTION' | translate}}
-
-
-
-
-
-
-
-
-
-
+
diff --git a/modules/collections/server/controllers/collections.server.controller.js b/modules/collections/server/controllers/collections.server.controller.js
index f01de5a4..aee77af3 100644
--- a/modules/collections/server/controllers/collections.server.controller.js
+++ b/modules/collections/server/controllers/collections.server.controller.js
@@ -279,7 +279,7 @@ exports.list = function (req, res) {
var findQuery = function (callback) {
Collection.find(condition)
.sort('-recommend_level -ordered_at -created_at')
- .populate('user', 'username displayName profileImageURL isVip')
+ .populate('user', 'username displayName profileImageURL isVip score uploaded downloaded')
.populate('torrents')
.skip(skip)
.limit(limit)
@@ -312,12 +312,12 @@ exports.collectionByID = function (req, res, next, id) {
}
Collection.findById(id)
- .populate('user', 'username displayName profileImageURL isVip')
+ .populate('user', 'username displayName profileImageURL isVip score uploaded downloaded')
.populate({
path: 'torrents',
populate: [{
path: 'user',
- select: 'username displayName profileImageURL isVip'
+ select: 'username displayName profileImageURL isVip score uploaded downloaded'
}, {
path: 'maker',
select: 'name'
diff --git a/modules/core/client/app/trans-string-en.js b/modules/core/client/app/trans-string-en.js
index 920a609d..3e359c98 100644
--- a/modules/core/client/app/trans-string-en.js
+++ b/modules/core/client/app/trans-string-en.js
@@ -23,6 +23,7 @@
VALUE_CUSTOM: 'CUSTOM',
VALUE_SELECT_ALL: 'Select All',
BTN_REMOVE: 'Remove',
+ BTN_CONTINUE: 'Continue',
//Support
SUPPORT_GROUP_NAME_DESC: 'Management group',
@@ -131,6 +132,15 @@
}
},
+ CHECK: {
+ BTN_CHECK_IN: 'Check In',
+ CHECK_TOOLTIP: '#### `mine.pt` invites you to participate in the daily check in. Now check in to get `{{todayScore}}` scores and renew tomorrow to get `{{tomorrowScore}}` scores!',
+ CHECK_TODAY_NOT: '#### You have not checked in yet. Last check in at: `{{checkTime | date: "yyyy-MM-dd HH:mm"}}`. Now check in to get `{{todayScore}}` scores and renew tomorrow to get `{{tomorrowScore}}` scores!',
+ CHECK_TODAY_DONE: '#### You have checked in to `{{keepDays}}` days in a row, today check in at: `{{checkTime | date: "yyyy-MM-dd HH:mm"}}`, you have got `{{todayScore}}` scores and renew tomorrow to get `{{tomorrowScore}}` scores, please be careful not to interrupt!',
+ CHECK_SUCCESSFULLY: 'Check in successfully',
+ CHECK_ERROR: 'Check in failed'
+ },
+
//element title/alt
TITLE_ALT: {
SEEDS: 'Seeds users',
@@ -162,16 +172,12 @@
TITLE_LIFE: 'orderBy life',
//status
- UPLOADED_SPEED: 'U/S',
- DOWNLOADED_RATIO: 'D/R',
- DOWNLOADED_SPEED: 'D/S',
- UPLOADED_RATIO_PERCENT: 'U/R/P',
+ UPLOADED_SPEED: 'U/S/R',
+ DOWNLOADED_SPEED: 'D/S/P',
UP_DOWN_RATIO_TIME: 'U/D/R/T',
- ABBR_UPLOADED_SPEED: 'uploaded/speed',
- ABBR_DOWNLOADED_RATIO: 'downloaded/ratio',
- ABBR_DOWNLOADED_SPEED: 'downloaded/speed',
- ABBR_UPLOADED_RATIO_PERCENT: 'uploaded/ratio/percent',
+ ABBR_UPLOADED_SPEED: 'uploaded/speed/ratio',
+ ABBR_DOWNLOADED_SPEED: 'downloaded/speed/percent',
ABBR_UP_DOWN_RATIO_TIME: 'uploaded/downloaded/ratio/seeding time',
//peer
@@ -336,17 +342,20 @@
TAGS_SEARCH_GLOBAL: 'Tags Search - Global',
CA_KEYWORD: 'Keyword',
CA_TORRENT_STATUS: 'Torrent status',
+ CA_TORRENT_ATTR: 'Torrent attribute',
CA_TORRENT_HNR: 'Hit and Run',
CA_TORRENT_SALE_STATUS: 'Sale Status',
CA_TORRENT_SALE_NOW: 'Saling',
CA_TORRENT_VIP: 'VIP resources',
+ CA_TORRENT_TOP: 'Top Status',
+ CA_TORRENT_UNIQUE: 'Unique Status',
CA_RESOURCE_TYPE: 'Resource type',
- CA_MAKE_RSS_URL: 'Rss Url',
- DESC_MAKE_RSS_URL: 'This RSS url is make with above filter conditions, you can used it in the BT client (such as uTorrent) that supports the RSS subscription function to download torrent and resources automatic.',
+ DESC_MAKE_RSS_URL: 'Based on the RSS address generated by the current search conditions, click Copy to clipboard.',
COPY_TO_CLIPBOARD: 'Copy to clipboard',
COPY_LINK_TO_CLIPBOARD: 'Copy torrent file download link to clipboard',
COPY_LINK_TEXT: 'Copy torrent file link',
COPY_TO_CLIPBOARD_SUCCESSFULLY: 'Copy data to clipboard successfully!',
+ TORRENT_LABEL_LINK: 'Torrent Link',
PH_KEYWORD: 'Search keyword',
CLEAR_ALL_CONDITION: 'Clear All Condition',
MORE_TAGS: 'More Tags',
@@ -371,7 +380,13 @@
TORRENT_THUMBS_FAILED: 'Thumbs-up for torrent failed',
TORRENT_RATING_SUCCESSFULLY: 'Rating torrent successfully',
TORRENT_RATING_FAILED: 'Rating torrent failed',
- EDIT_THIS_OVERVIEW: 'Edit this Overview',
+ EDIT_THIS_OVERVIEW: 'Edit this overview',
+ VIEW_ORIGINAL_MEDIA_INFO: 'View original media info',
+ VIEW_FORMATTED_MEDIA_INFO: 'View formatted media info',
+ EDIT_THIS_MEDIA_INFO: 'Edit media info',
+ SAVE_THIS_MEDIA_INFO: 'Save media info',
+ EDIT_TORRENT_NFO_SUCCESSFULLY: 'Torrent media info edited successfully',
+ EDIT_TORRENT_NFO_FAILED: 'Torrent media info edited failed',
IMG_PAGE_INFO: 'Current: {{index}} / {{total}}',
ANNOUNCE_URL: 'Announce Url',
@@ -382,10 +397,12 @@
ALL_FILES_LIST: 'Files List',
VIDEO_SIZE: 'Video Size',
UPLOAD_TIME: 'Upload Time',
- VIDEO_SALE_INFO: 'Video Sale Info',
SALE_EXPIRES_TIME: 'expires',
TORRENT_STATUS_TOP_TITLE: 'Top Level',
+ TORRENT_STATUS_UNIQUE: 'Unique resource',
+ TORRENT_STATUS_UNIQUE_TITLE: 'Unique resource, no transfer',
STATUS_TOP_KEY: 'TOP',
+ STATUS_UNIQUE_KEY: 'UNIQUE',
UPLOAD_SUBTITLE: 'Upload Subtitle file',
SUBTITLE_LIST: 'Subtitle list',
SUBTITLE_RULES: {
@@ -422,6 +439,8 @@
ADMIN_BASIC_UNSET_VIP: 'UnsetVIP',
ADMIN_BASIC_SET_TOP: 'SetTop',
ADMIN_BASIC_UNSET_TOP: 'UnsetTop',
+ ADMIN_BASIC_SET_UNIQUE: 'SetUnique',
+ ADMIN_BASIC_UNSET_UNIQUE: 'UnsetUnique',
ADMIN_BASIC_TYPE_SET: 'Sale Type',
ADMIN_SALE_TYPE_SET: 'Sale Type Set',
ADMIN_BASIC_RLEVEL_SET: 'Recommend Level',
@@ -465,6 +484,8 @@
TORRENT_TOGGLE_VIP_FAILED: 'Torrent toggle VIP tag failed',
TORRENT_TOGGLE_TOP_SUCCESSFULLY: 'Torrent toggle TOP tag successfully',
TORRENT_TOGGLE_TOP_FAILED: 'Torrent toggle TOP tag failed',
+ TORRENT_TOGGLE_UNIQUE_SUCCESSFULLY: 'Torrent toggle Unique tag successfully',
+ TORRENT_TOGGLE_UNIQUE_FAILED: 'Torrent toggle Unique tag failed',
TORRENT_SETTAGS_SUCCESSFULLY: 'Torrent tags set successfully',
TORRENT_SETTAGS_ERROR: 'Torrent tags set failed',
@@ -510,7 +531,7 @@
SELECT_TORRENT_FILE: '1. Please select the torrent file',
SELECT_FILE: 'Select file',
DO_UPLOAD: 'Upload',
- ENTER_TMDB_ID: '3. Please enter theMovieDB id',
+ ENTER_TMDB_ID: '3 Please enter theMovieDB id',
LOAD_TMDB_INFO: 'Load info',
SEARCH_FROM_TMDB: 'Search From TMDB',
TMDB_ID: 'TMDB ID',
@@ -553,8 +574,8 @@
ERROR_ONLY_IMAGE: 'Only image files support(gif, png, bmp, jpg, jpeg)',
FILE_TYPE_ERROR: 'File type that is not accepted',
- ENTER_RESOURCE_TITLE: '3. Please enter the resource title and desc',
- RESOURCE_TITLE: 'resource title',
+ ENTER_RESOURCE_TITLE: '4.1 Please enter the resource main title and sub title',
+ RESOURCE_TITLE: 'resource main title',
RESOURCE_SUB_TITLE: 'resource sub title',
SELECT_RESOURCE_IMAGE: '3.1 Please select resource cover image',
ENTER_RESOURCE_DETAIL_INFO: '4. Please enter the resource detail info',
@@ -848,9 +869,10 @@
COMMENT_REMOVE_ERROR: 'Comment removed failed!',
DESC_LIST: '### NOTE: \n - The list contains only the last `{{days}}` days of the requests. \n - If your response is accepted, the requestor\'s reward score will be automatically transferred to your account. \n - Only the torrents reviewed by the administrator can be accepted by the requestor. \n - The requester can only accept one of the responses. \n - If your response is complains, your account may be punished, Please respond to the user\'s request carefully.',
DESC_MY: '### NOTE: \n - If you accept a response, your reward score will be transferred to the respondent\'s account that you accept. \n - Only the torrents reviewed by the administrator can be accepted by you. \n - You can only accept one of the responses. \n - The request over `{{days}}` days has expired and cannot accept the response, you can only post the request again. \n - If your score is maliciously damaged, Please contact our {{sNameDesc | translate}} by **[Message](/messages/send?to={{sName}})** or **[Email](mailto:{{sMail}})** to complaints.',
- DESC_ADD: '### NOTE: \n - Each request will be automatically deducted from `{{add_score}}` points, but your reward score will only be transferred to the responder\'s account that you eventually accept. \n - Only the torrents reviewed by the administrator can be accepted by you. \n - Each request is only valid for `{{days}}` days. After expiry, you can only post the request again. \n - Please give a clear resources description of your request when you post the request.',
+ DESC_ADD: '### NOTE: \n - Each request will be automatically deducted from `{{add_score}}` points, and your reward score will only be transferred to the responder\'s account that you eventually accept. \n - Only the torrents reviewed by the administrator can be accepted by you. \n - Each request is only valid for `{{days}}` days. After expiry, you can only post the request again. \n - Please give a clear resources description of your request when you post the request.',
DESC_RES: '### NOTE: \n - If requestor accept your response, the reward score will be transferred to your account. \n - Only the torrents reviewed by the administrator can be accepted by requestor. \n - Requestor can only accept one of the responses.',
- DESC_VIEW: '### NOTE: \n - If you want to response a request, please upload the torrent file and seed, Please respond to the user\'s request carefully. \n - If you are a requestor, you can choose a responder and accept it, and only the torrents reviewed by the administrator can be accepted. \n - If you accept a response, your reward score will be transferred to the respondent\'s account that you accept. \n - The request over `{{days}}` days has expired and cannot accept or response(upload).'
+ DESC_VIEW: '### NOTE: \n - If you want to response a request, please upload the torrent file and seed, Please respond to the user\'s request carefully. \n - If you are a requestor, you can choose a responder and accept it, and only the torrents reviewed by the administrator can be accepted. \n - If you accept a response, your reward score will be transferred to the respondent\'s account that you accept. \n - The request over `{{days}}` days has expired and cannot accept or response(upload).',
+ CAN_NTO_TO_ADD: 'Each request will be automatically deducted from `{{add_score}}` points,your scores are too small, please try again later ...'
},
//user status
@@ -1060,13 +1082,12 @@
MESSAGE_TYPE_USER: 'User message',
MESSAGE_TYPE_SYSTEM: 'System message',
MESSAGE_TYPE_ADVERT: 'Advert message',
- MESSAGE_TYPE_NOTICE: 'Notice message',
MESSAGE_TYPE_SERVER: 'Server notice',
MESSAGE_SEND_SUCCESSFULLY: 'Message send successfully',
MESSAGE_SEND_FAILED: 'Message send failed',
MESSAGE_DELETED_SUCCESSFULLY: 'Message deleted successfully',
MESSAGE_DELETED_ERROR: 'Message deleted failed',
- MESSAGE_SERVER_TOOLTIP: '
Server message Server message is send to you by server automatic when you do some operations or your account status make some change or some important things about you, There may be a lot of messages, so you need to check and delete them in time. The system only keeps the last {{count}} messages.',
+ MESSAGE_SERVER_TOOLTIP: '
Server message Server message is send to you by server automatic when you do some operations or your account status make some change or some important things about you, There may be a lot of messages, so you need to check and delete them in time. The system keeps only the messages of the last {{days}} days.',
MESSAGE_DELETE_CONFIRM_OK: 'Delete',
MESSAGE_DELETE_CONFIRM_CANCEL: 'Cancel',
@@ -1438,7 +1459,7 @@
TYPE: {
SELF: 'Medium',
BLU_RAY: 'Blu-ray',
- WEB: 'Web',
+ WEB: 'WEB',
REMUX: 'Remux',
ENCODE: 'Encode',
HDTV: 'HDTV'
@@ -1460,14 +1481,23 @@
X265: 'x265'
},
+ VISION: {
+ SELF: 'Video Vision',
+ DOLBY: 'DolbyVision',
+ HDR10PLUS: 'HDR10+',
+ HDR10: 'HDR10',
+ HDR: 'HDR',
+ SDR: 'SDR'
+ },
+
AUDIO: {
SELF: 'Audio Codec',
DTS_X: 'DTS:X',
ATMOS: 'Atmos',
DTS_HD: 'DTS-HD',
- TRUE_HD: 'TRUE-HD',
+ TRUE_HD: 'True-HD',
DTS: 'DTS',
- AC3: 'AC3',
+ AC3: 'AC-3',
AAC: 'AAC'
},
@@ -1572,6 +1602,45 @@
}
},
+ MEDIAINFO: {
+ GENERAL: {
+ SELF: 'General Info',
+ FILESIZE: 'File Size',
+ RUNTIME: 'Runtime',
+ DURATION: 'Duration',
+ OVERALLBITRATE: 'Overall Bit Rate'
+ },
+ VIDEO: {
+ SELF: 'Video Info',
+ FORMAT: 'Format',
+ DURATION: 'Duration',
+ BITRATE: 'Bit Rate',
+ WIDTH: 'Width',
+ HEIGHT: 'Height',
+ FRAMERATEMODE: 'Frame Rate Mode',
+ FRAMERATE: 'Frame Rate',
+ BITDEPTH: 'Bit Depth',
+ STREAMSIZE: 'Stream Size',
+ WRITINGLIBRARY: 'Writing Library',
+ RESOLUTION: 'Resolution',
+ CODEC: 'Video Codec'
+ },
+ AUDIO: {
+ SELF: 'Audio Info',
+ FORMAT: 'Format',
+ BITRATEMODE: 'Bit Rate Mode',
+ BITRATE: 'Bit Rate',
+ CHANNEL: 'Channel',
+ LANGUAGE: 'Language',
+ INFO: 'Audio Info',
+ CODEC: 'Codec'
+ },
+ TEXT: {
+ SELF: 'Subtitle Info',
+ LANGUAGE: 'Language'
+ }
+ },
+
//server returned string
SERVER: {
USER_IS_NOT_AUTHORIZED: 'User is not authorized',
@@ -1606,10 +1675,12 @@
INVITE_MAIL_SEND_FAILED: 'Invitation mail send failed (SERVER)',
EMAIL_ADDRESS_IS_NOT_ALLOW: 'The domain of this email address is not allowable from server',
INFO_HASH_IS_EMPTY: 'Info hash field of torrent file is empty',
- INFO_HASH_ALREADY_EXISTS: 'This info hash value is already exists',
+ INFO_HASH_ALREADY_EXISTS: 'This info hash value is already exists, {{hash}}',
+ FILE_ALREADY_EXISTS: 'This torrent file name already exists, {{filename}}',
UPLOAD_ACCESS_DENY: 'System only accepts resources group to upload torrents',
READ_TORRENT_FILE_FAILD: 'The torrent file parsing error. Please check your torrent file to check if some of the necessary information is missing',
- MOVE_TORRENT_FILE_ERROR: 'The torrent file was moved incorrectly. Please do not repeat the submit operation quickly or the uploaded torrent file is missing.'
+ MOVE_TORRENT_FILE_ERROR: 'The torrent file was moved incorrectly. Please do not repeat the submit operation quickly or the uploaded torrent file is missing.',
+ YOU_ALREADY_CHECK_IN: 'You already checked in today'
},
//server message string, content string support markdown and emoji
@@ -1682,6 +1753,9 @@
TITLE_TORRENT_TOP_CHANGED: 'Torrent TOP status changed',
CONTENT_TORRENT_TOP_CHANGED: '### TOP status changed! \n You uploaded torrent [{{torrent_file_name}}](/torrents/{{torrent_id}}) TOP status was changed by user [{{by_name}}](/userinfo/{{by_id}}), current status is **{{top_status}}**.',
+ TITLE_TORRENT_UNIQUE_CHANGED: 'Torrent Unique status changed',
+ CONTENT_TORRENT_UNIQUE_CHANGED: '### Unique status changed! \n You uploaded torrent [{{torrent_file_name}}](/torrents/{{torrent_id}}) Unique status was changed by user [{{by_name}}](/userinfo/{{by_id}}), current status is **{{unique_status}}**.',
+
TITLE_TORRENT_SALE_CHANGED: 'Torrent sale status changed',
CONTENT_TORRENT_SALE_CHANGED: '### Sale status changed! \n You uploaded torrent [{{torrent_file_name}}](/torrents/{{torrent_id}}) sale status was changed by user [{{by_name}}](/userinfo/{{by_id}}), current status is **{{sale_status}}**.',
@@ -1710,7 +1784,7 @@
SITE_NOTICE: {
GLOBAL_SALES_NOTICE: '### IMPORTANT NOTICE: \n :radio: **Happy new year 2018**, **{{site_name}}** global sale is coming, sales value is
**{{sale_value}}** , sales start at **{{sale_start_at | date: "yyyy-MM-dd HH:mm"}}** and continued
**{{sale_days}}** days and end at **{{sale_end_at | date: "yyyy-MM-dd HH:mm"}}**, Thank you for all the help and support you have been giving us all the time!',
EXAMINATION_NOTICE: '### IMPORTANT NOTICE: \n :radio: **{{site_name}}** will take a new incremental examination from **{{examination_start_at | date: "yyyy-MM-dd HH:mm"}}** to **{{examination_end_at | date: "yyyy-MM-dd HH:mm"}}**, Incremental data requirements: upload **{{data_upload | bytes:2}}**, download **{{data_download | bytes:2}}**, score **{{data_score}}**, Please arrange your own time and hope to pass the exam smoothly. All **VIP** users and registered new users within **{{join_days}}** days are exempt, The unfinished user account will be banned.
[Get more detail at here]({{detail_url}}). ',
- EXAMINATION_STATUS: '### EXAMINATION STATUS: \n
Examination time: {{examination_start_at | date: "yyyy-MM-dd HH:mm"}} - {{examination_end_at | date: "yyyy-MM-dd HH:mm"}} Incremental data of upload: {{data_upload | bytes:2}}, finished {{finished_upload | bytes:2}} Incremental data of download: {{data_download | bytes:2}}, finished {{finished_download | bytes:2}} Incremental data of score: {{data_score | number: 2}}, finished {{finished_score | number: 2}} Examination status: {{data_status | translate}} [more detail]({{detail_url}}) ',
+ EXAMINATION_STATUS: '### EXAMINATION STATUS: \n
Examination time: {{examination_start_at | date: "yyyy-MM-dd HH:mm"}} - {{examination_end_at | date: "yyyy-MM-dd HH:mm"}} Incremental data of upload: {{data_upload | bytes:2}}, finished {{finished_upload | bytes:2}} Incremental data of download: {{data_download | bytes:2}}, finished {{finished_download | bytes:2}} Incremental data of score: {{data_score | score: 2}}, finished {{finished_score | score: 2}} Examination status: {{data_status | translate}} [more detail]({{detail_url}}) ',
EXAMINATION_FINISHED: 'Finished',
EXAMINATION_UNFINISHED: 'Unfinished'
}
diff --git a/modules/core/client/app/trans-string-zh-tw.js b/modules/core/client/app/trans-string-zh-tw.js
index dee65660..dbfe7cbf 100644
--- a/modules/core/client/app/trans-string-zh-tw.js
+++ b/modules/core/client/app/trans-string-zh-tw.js
@@ -1466,7 +1466,7 @@
},
RESOLUTION: {
- SELF: '解析度',
+ SELF: '分辨率',
S4K: '4K',
S1080P: '1080p',
S1080I: '1080i',
@@ -1756,6 +1756,9 @@
TITLE_TORRENT_UNIQUE_CHANGED: '上傳的種子 禁轉 狀態改變',
CONTENT_TORRENT_UNIQUE_CHANGED: '### 禁轉 狀態改變! \n 您上傳的種子 [{{torrent_file_name}}](/torrents/{{torrent_id}}) 禁轉 狀態已經由管理員用戶 [{{by_name}}](/userinfo/{{by_id}}) 修改, 當前狀態為: **{{unique_status}}**.',
+ TITLE_TORRENT_UNIQUE_CHANGED: '上傳的種子 禁轉 狀態改變',
+ CONTENT_TORRENT_UNIQUE_CHANGED: '### 禁轉狀態改變! \n 您上傳的種子[{{torrent_file_name}}](/torrents/{{torrent_id}}) 禁轉狀態已經由管理員用戶[{{by_name}}]( /userinfo/{{by_id}}) 修改, 當前狀態為: **{{unique_status}}**.',
+
TITLE_TORRENT_SALE_CHANGED: '上傳的種子促銷狀態改變',
CONTENT_TORRENT_SALE_CHANGED: '### 促銷狀態改變! \n 您上傳的種子 [{{torrent_file_name}}](/torrents/{{torrent_id}}) 促銷狀態已經由管理員用戶 [{{by_name}}](/userinfo/{{by_id}}) 修改, 當前狀態為: **{{sale_status}}**.',
diff --git a/modules/core/client/app/trans-string-zh.js b/modules/core/client/app/trans-string-zh.js
index 1e73dee7..5caf3ecb 100644
--- a/modules/core/client/app/trans-string-zh.js
+++ b/modules/core/client/app/trans-string-zh.js
@@ -23,6 +23,7 @@
VALUE_CUSTOM: '自定义',
VALUE_SELECT_ALL: '全选',
BTN_REMOVE: '删除',
+ BTN_CONTINUE: '继续',
//Support
SUPPORT_GROUP_NAME_DESC: '管理组',
@@ -131,6 +132,15 @@
}
},
+ CHECK: {
+ BTN_CHECK_IN: '我要签到',
+ CHECK_TOOLTIP: '#### `mine.pt` 邀请您参加每日签到,现在签到可获得 `{{todayScore}}` 积分,明日续签可获得 `{{tomorrowScore}}` 积分哦!',
+ CHECK_TODAY_NOT: '#### 您今日还未签到,上次签到:`{{checkTime | date: "yyyy-MM-dd HH:mm"}}`,现在签到可获得 `{{todayScore}}` 积分,明日续签到可获得 `{{tomorrowScore}}` 积分哦!',
+ CHECK_TODAY_DONE: '#### 您已连续签到 `{{keepDays}}` 天,今日签到时间:`{{checkTime | date: "yyyy-MM-dd HH:mm"}}`,已经获得 `{{todayScore}}` 积分,明日续签到可获得 `{{tomorrowScore}}` 积分,请注意不要中断哦!',
+ CHECK_SUCCESSFULLY: '签到成功',
+ CHECK_ERROR: '签到失败'
+ },
+
//element title/alt
TITLE_ALT: {
SEEDS: '做种用户数',
@@ -162,16 +172,12 @@
TITLE_LIFE: '按上传时间排序',
//status
- UPLOADED_SPEED: '上/速',
- DOWNLOADED_RATIO: '下/比',
- DOWNLOADED_SPEED: '下/速',
- UPLOADED_RATIO_PERCENT: '上/比/进度',
+ UPLOADED_SPEED: '上/速/分享',
+ DOWNLOADED_SPEED: '下/速/进度',
UP_DOWN_RATIO_TIME: '上/下/比/时',
- ABBR_UPLOADED_SPEED: '上传量/速度',
- ABBR_DOWNLOADED_RATIO: '下载量/分享率',
- ABBR_DOWNLOADED_SPEED: '下载量/速度',
- ABBR_UPLOADED_RATIO_PERCENT: '上传量/分享率/完成百分比',
+ ABBR_UPLOADED_SPEED: '上传量/速度/分享率',
+ ABBR_DOWNLOADED_SPEED: '下载量/速度/完成进度',
ABBR_UP_DOWN_RATIO_TIME: '上传量/下载量/分享率/做种时间',
//peer
@@ -336,20 +342,23 @@
TAGS_SEARCH_GLOBAL: '种子搜索 - 全局',
CA_KEYWORD: '关键字',
CA_TORRENT_STATUS: '种子状态',
+ CA_TORRENT_ATTR: '种子属性',
CA_TORRENT_HNR: 'H&R 黑种',
CA_TORRENT_SALE_STATUS: '促销状态',
CA_TORRENT_SALE_NOW: '正在促销',
CA_TORRENT_VIP: 'VIP 资源',
+ CA_TORRENT_TOP: '置顶状态',
+ CA_TORRENT_UNIQUE: '禁转状态',
CA_RESOURCE_TYPE: '资源类型',
- CA_MAKE_RSS_URL: 'RSS连接',
- DESC_MAKE_RSS_URL: '这个 RSS 地址是通过上面的过滤条件生成的,您可以使用支持 RSS 订阅功能的BT客户端(如uTorrent)来自动下载您想要的这些种子和资源文件.',
+ DESC_MAKE_RSS_URL: '根据当前检索条件生成的 RSS 地址, 点击复制到粘贴版.',
COPY_TO_CLIPBOARD: '复制到剪切板',
COPY_LINK_TO_CLIPBOARD: '复制种子文件下载连接到剪切板',
COPY_LINK_TEXT: '复制种子文件地址',
COPY_TO_CLIPBOARD_SUCCESSFULLY: '内容已复制到剪切板!',
+ TORRENT_LABEL_LINK: '种子连接',
PH_KEYWORD: '搜索关键字',
CLEAR_ALL_CONDITION: '清空所有条件',
- MORE_TAGS: '显示更多标签',
+ MORE_TAGS: '更多标签',
CA_RESET: '重置条件',
TORRENT_DOWNLOAD_ERROR: '种子文件下载失败',
TORRENTS_DOWNLOAD_SUCCESSFULLY: '种子文件下载成功',
@@ -372,6 +381,12 @@
TORRENT_RATING_SUCCESSFULLY: '为种子投票成功',
TORRENT_RATING_FAILED: '为种子投票失败',
EDIT_THIS_OVERVIEW: '编辑详情介绍',
+ VIEW_ORIGINAL_MEDIA_INFO: '查看原始的媒体信息',
+ VIEW_FORMATTED_MEDIA_INFO: '查看格式化的媒体信息',
+ EDIT_THIS_MEDIA_INFO: '编辑媒体信息',
+ SAVE_THIS_MEDIA_INFO: '保存媒体信息',
+ EDIT_TORRENT_NFO_SUCCESSFULLY: '种子媒体信息编辑成功',
+ EDIT_TORRENT_NFO_FAILED: '种子媒体信息编辑失败',
IMG_PAGE_INFO: '当前页: {{index}} / {{total}}',
ANNOUNCE_URL: 'Tracker 地址',
@@ -382,10 +397,12 @@
ALL_FILES_LIST: '文件清单',
VIDEO_SIZE: '视频文件大小',
UPLOAD_TIME: '上传时间',
- VIDEO_SALE_INFO: '视频促销信息',
SALE_EXPIRES_TIME: '过期',
TORRENT_STATUS_TOP_TITLE: '置顶推荐',
+ TORRENT_STATUS_UNIQUE: '禁转资源',
+ TORRENT_STATUS_UNIQUE_TITLE: '禁转资源,禁止转发',
STATUS_TOP_KEY: '置顶',
+ STATUS_UNIQUE_KEY: '禁转',
UPLOAD_SUBTITLE: '上传字幕文件',
SUBTITLE_LIST: '字幕列表',
SUBTITLE_RULES: {
@@ -422,6 +439,8 @@
ADMIN_BASIC_UNSET_VIP: '取消VIP',
ADMIN_BASIC_SET_TOP: '设为置顶',
ADMIN_BASIC_UNSET_TOP: '取消置顶',
+ ADMIN_BASIC_SET_UNIQUE: '设为禁转',
+ ADMIN_BASIC_UNSET_UNIQUE: '取消禁转',
ADMIN_BASIC_TYPE_SET: '设置促销',
ADMIN_SALE_TYPE_SET: '种子促销类型',
ADMIN_BASIC_RLEVEL_SET: '推荐级别',
@@ -465,6 +484,8 @@
TORRENT_TOGGLE_VIP_FAILED: '改变种子VIP标签失败',
TORRENT_TOGGLE_TOP_SUCCESSFULLY: '改变种子置顶状态成功',
TORRENT_TOGGLE_TOP_FAILED: '改变种子置顶状态失败',
+ TORRENT_TOGGLE_UNIQUE_SUCCESSFULLY: '改变种子禁转状态成功',
+ TORRENT_TOGGLE_UNIQUE_FAILED: '改变种子禁转状态失败',
TORRENT_SETTAGS_SUCCESSFULLY: '种子属性标签设置成功',
TORRENT_SETTAGS_ERROR: '种子属性标签设置失败',
@@ -510,7 +531,7 @@
SELECT_TORRENT_FILE: '1. 请选择种子文件',
SELECT_FILE: '选择文件',
DO_UPLOAD: '上传',
- ENTER_TMDB_ID: '3. 请输入TMDB_ID',
+ ENTER_TMDB_ID: '3 请输入TMDB_ID',
LOAD_TMDB_INFO: '检索信息',
TMDB_ID: 'TMDB ID',
SEARCH_FROM_TMDB: '从 TMDB 搜索',
@@ -553,8 +574,8 @@
ERROR_ONLY_IMAGE: '此处只支持图片文件上传(gif, png, bmp, jpg, jpeg)',
FILE_TYPE_ERROR: '文件类型不被接受',
- ENTER_RESOURCE_TITLE: '3. 请输入资源标题与描述',
- RESOURCE_TITLE: '资源标题',
+ ENTER_RESOURCE_TITLE: '4.1 请输入资源主副标题',
+ RESOURCE_TITLE: '资源主标题',
RESOURCE_SUB_TITLE: '资源副标题',
SELECT_RESOURCE_IMAGE: '3.1 请选择资源封面图片',
ENTER_RESOURCE_DETAIL_INFO: '4. 请输入资源详细信息',
@@ -850,7 +871,8 @@
DESC_MY: '### 提示: \n - 如果您接受一个响应, 您的悬赏积分就会转入您接受的响应者的帐户. \n - 只有被管理员审核通过的种子才能被您接受. \n - 您只能接受多个响应中的一个. \n - 超过 `{{days}}` 天的请求已经过期且不能接受响应, 如果需要您只能再次发起请求. \n - 如果您的积分受到恶意损害, 请给{{sNameDesc | translate}}发送 **[消息](/messages/send?to={{sName}})** 或 **[邮件](mailto:{{sMail}})** 进行投诉.',
DESC_ADD: '### 提示: \n - 每发布一个请求会被自动扣除 `{{add_score}}` 积分, 而您的悬赏积分会转入您最终接受的响应者的帐户. \n - 只有被管理员审核通过的种子才能被您接受. \n - 每一个发布的请求只有 `{{days}}` 天的有效期, 过期后您只能再次发起请求. \n - 请在发布请求时明确描述您对资源的要求.',
DESC_RES: '### NOTE: \n - 如果请求者接受了您的响应, 悬赏积分将自动转入您的帐户. \n - 只有被管理员审核通过的种子才能被请求者接受. \n - 请求者只会接受多个响应中的一个.',
- DESC_VIEW: '### NOTE: \n - 如果您是一个响应者, 请上传您的种子文件并开始做种, 请认真响应用户的请求. \n - 如果您是一个请求者, 您可以选择一个响应并接受它, 只有被管理员审核通过的种子才能被您接受. \n - 如果您接受一个响应, 您的悬赏积分就会转入您接受的响应者的帐户. \n - 超过 `{{days}}` 天的请求已经过期且不能接受响应或上传种子.'
+ DESC_VIEW: '### NOTE: \n - 如果您是一个响应者, 请上传您的种子文件并开始做种, 请认真响应用户的请求. \n - 如果您是一个请求者, 您可以选择一个响应并接受它, 只有被管理员审核通过的种子才能被您接受. \n - 如果您接受一个响应, 您的悬赏积分就会转入您接受的响应者的帐户. \n - 超过 `{{days}}` 天的请求已经过期且不能接受响应或上传种子.',
+ CAN_NTO_TO_ADD: '每发布一个请求会被自动扣除 `{{add_score}}` 积分,您的积分太少,请稍候再试 ...'
},
//user status
@@ -1058,15 +1080,14 @@
BUTTON_MESSAGE_REPLY: '回复',
MESSAGE_TYPE_USER: '用户消息',
- MESSAGE_TYPE_SYSTEM: '全局系统消息',
- MESSAGE_TYPE_ADVERT: '全局广告推送',
- MESSAGE_TYPE_NOTICE: '全局系统通知',
+ MESSAGE_TYPE_SYSTEM: '系统消息',
+ MESSAGE_TYPE_ADVERT: '广告推送',
MESSAGE_TYPE_SERVER: '服务器事件通知',
MESSAGE_SEND_SUCCESSFULLY: '消息发送成功',
MESSAGE_SEND_FAILED: '消息发送失败',
MESSAGE_DELETED_SUCCESSFULLY: '消息删除成功',
MESSAGE_DELETED_ERROR: '消息删除失败',
- MESSAGE_SERVER_TOOLTIP: '
服务器事件通知 当您做了一些重要的操作或者您的帐户状态发生变化以及某些重要事情与您有关时,服务器会自动发送消息给您,这种消息可能会很多,所以请及时查看及删除,服务器只保留最后的 {{count}} 条消息.',
+ MESSAGE_SERVER_TOOLTIP: '
服务器事件通知 当您做了一些重要的操作或者您的帐户状态发生变化以及某些重要事情与您有关时,服务器会自动发送消息给您,这种消息可能会很多,所以请及时查看及删除,系统只保留最近 {{days}} 天的消息。',
MESSAGE_DELETE_CONFIRM_OK: '删除',
MESSAGE_DELETE_CONFIRM_CANCEL: '取消',
@@ -1438,7 +1459,7 @@
TYPE: {
SELF: '媒介',
BLU_RAY: 'Blu-ray',
- WEB: 'Web',
+ WEB: 'WEB',
REMUX: 'Remux',
ENCODE: 'Encode',
HDTV: 'HDTV'
@@ -1460,14 +1481,23 @@
X265: 'x265'
},
+ VISION: {
+ SELF: '视频色彩',
+ DOLBY: 'DolbyVision',
+ HDR10PLUS: 'HDR10+',
+ HDR10: 'HDR10',
+ HDR: 'HDR',
+ SDR: 'SDR'
+ },
+
AUDIO: {
SELF: '音频编码',
DTS_X: 'DTS:X',
ATMOS: 'Atmos',
DTS_HD: 'DTS-HD',
- TRUE_HD: 'TRUE-HD',
+ TRUE_HD: 'True-HD',
DTS: 'DTS',
- AC3: 'AC3',
+ AC3: 'AC-3',
AAC: 'AAC'
},
@@ -1572,6 +1602,45 @@
}
},
+ MEDIAINFO: {
+ GENERAL: {
+ SELF: '资源通用信息',
+ FILESIZE: '总体积',
+ RUNTIME: '总时长',
+ DURATION: '总时长',
+ OVERALLBITRATE: '总码率'
+ },
+ VIDEO: {
+ SELF: '视频信息',
+ FORMAT: '格式',
+ DURATION: '时长',
+ BITRATE: '码率',
+ WIDTH: '分辨率.宽',
+ HEIGHT: '分辨率.高',
+ FRAMERATEMODE: '帧率模式',
+ FRAMERATE: '帧率',
+ BITDEPTH: '位深',
+ STREAMSIZE: '体积',
+ WRITINGLIBRARY: '编码方式',
+ RESOLUTION: '分辨率',
+ CODEC: '编码'
+ },
+ AUDIO: {
+ SELF: '音频信息',
+ FORMAT: '格式',
+ BITRATEMODE: '码率模式',
+ BITRATE: '码率',
+ CHANNEL: '声道',
+ LANGUAGE: '音轨',
+ INFO: '音轨信息',
+ CODEC: '编码'
+ },
+ TEXT: {
+ SELF: '字幕信息',
+ LANGUAGE: '语言'
+ }
+ },
+
//server returned string
SERVER: {
USER_IS_NOT_AUTHORIZED: '用户身份验证未通过',
@@ -1606,10 +1675,12 @@
INVITE_MAIL_SEND_FAILED: '邀请邮件发送失败(SERVER)',
EMAIL_ADDRESS_IS_NOT_ALLOW: '该邮件地址不允许被邀请或注册',
INFO_HASH_IS_EMPTY: 'Info hash 字段值不能为空',
- INFO_HASH_ALREADY_EXISTS: '该 info hash 值已经存在,不能重复提交',
+ INFO_HASH_ALREADY_EXISTS: '该 info hash 值已经存在,不能重复提交, {{hash}}',
+ FILE_ALREADY_EXISTS: '该种子文件名已经存在, {{filename}}',
UPLOAD_ACCESS_DENY: '当前系统只接受资源制作小组上传种子',
READ_TORRENT_FILE_FAILD: '种子文件解析错误,请检查您的种子文件,看是否缺少某些必要信息',
- MOVE_TORRENT_FILE_ERROR: '种子文件移动错误,请不要快速重复进行提交操作或者上传的种子文件已丢失'
+ MOVE_TORRENT_FILE_ERROR: '种子文件移动错误,请不要快速重复进行提交操作或者上传的种子文件已丢失',
+ YOU_ALREADY_CHECK_IN: '您今天已经签过到了,不能重复签到'
},
//server message string, content string support markdown and emoji
@@ -1682,6 +1753,9 @@
TITLE_TORRENT_TOP_CHANGED: '上传的种子 置顶 状态改变',
CONTENT_TORRENT_TOP_CHANGED: '### 置顶 状态改变! \n 您上传的种子 [{{torrent_file_name}}](/torrents/{{torrent_id}}) 置顶 状态已经由管理员用户 [{{by_name}}](/userinfo/{{by_id}}) 修改, 当前状态为: **{{top_status}}**.',
+ TITLE_TORRENT_UNIQUE_CHANGED: '上传的种子 禁转 状态改变',
+ CONTENT_TORRENT_UNIQUE_CHANGED: '### 禁转 状态改变! \n 您上传的种子 [{{torrent_file_name}}](/torrents/{{torrent_id}}) 禁转 状态已经由管理员用户 [{{by_name}}](/userinfo/{{by_id}}) 修改, 当前状态为: **{{unique_status}}**.',
+
TITLE_TORRENT_SALE_CHANGED: '上传的种子促销状态改变',
CONTENT_TORRENT_SALE_CHANGED: '### 促销状态改变! \n 您上传的种子 [{{torrent_file_name}}](/torrents/{{torrent_id}}) 促销状态已经由管理员用户 [{{by_name}}](/userinfo/{{by_id}}) 修改, 当前状态为: **{{sale_status}}**.',
@@ -1710,7 +1784,7 @@
SITE_NOTICE: {
GLOBAL_SALES_NOTICE: '### 重要通知! \n :radio: **新年快乐 2018**, **{{site_name}}** 新年促销活动已准备就绪, 促销活动类型为
**{{sale_value}}** , 活动将开始于 **{{sale_start_at | date: "yyyy-MM-dd HH:mm"}}** 并持续
**{{sale_days}}** 天, 结束于 **{{sale_end_at | date: "yyyy-MM-dd HH:mm"}}**, 并感谢所有会员用户一直以来给予我们的帮助与支持!',
EXAMINATION_NOTICE: '### 重要通知! \n :radio: **{{site_name}}** 将从 **{{examination_start_at | date: "yyyy-MM-dd HH:mm"}}** 到 **{{examination_end_at | date: "yyyy-MM-dd HH:mm"}}** 进行一次新的增量考核, 增量数据要求: 上传 **{{data_upload | bytes:2}}**, 下载 **{{data_download | bytes:2}}**, 积分 **{{data_score}}**, 请各位会员安排好自已的时间,并祝您顺利通过这次考核. 所有 **vip** 用户以及最近 **{{join_days}}** 天内注册的新用户免考, 考核未达标的用户帐号将会被禁止.
[更多详情请看这里]({{detail_url}}). ',
- EXAMINATION_STATUS: '### 考核状态信息: \n
考核时间区间: {{examination_start_at | date: "yyyy-MM-dd HH:mm"}} - {{examination_end_at | date: "yyyy-MM-dd HH:mm"}} 增量上传数据: {{data_upload | bytes:2}}, 已完成 {{finished_upload | bytes:2}} 增量下载数据: {{data_download | bytes:2}}, 已完成 {{finished_download | bytes:2}} 增量积分: {{data_score | number: 2}}, 已完成 {{finished_score | number: 2}} 当前考核状态: {{data_status | translate}} [更多详情]({{detail_url}}) ',
+ EXAMINATION_STATUS: '### 考核状态信息: \n
考核时间区间: {{examination_start_at | date: "yyyy-MM-dd HH:mm"}} - {{examination_end_at | date: "yyyy-MM-dd HH:mm"}} 增量上传数据: {{data_upload | bytes:2}}, 已完成 {{finished_upload | bytes:2}} 增量下载数据: {{data_download | bytes:2}}, 已完成 {{finished_download | bytes:2}} 增量积分: {{data_score | score: 2}}, 已完成 {{finished_score | score: 2}} 当前考核状态: {{data_status | translate}} [更多详情]({{detail_url}}) ',
EXAMINATION_FINISHED: '已通过',
EXAMINATION_UNFINISHED: '未通过'
}
diff --git a/modules/core/client/controllers/header.client.controller.js b/modules/core/client/controllers/header.client.controller.js
index f519a558..3647e687 100644
--- a/modules/core/client/controllers/header.client.controller.js
+++ b/modules/core/client/controllers/header.client.controller.js
@@ -6,13 +6,14 @@
.controller('HeaderController', HeaderController);
HeaderController.$inject = ['$scope', '$state', '$timeout', '$translate', 'Authentication', 'menuService', 'MeanTorrentConfig', 'localStorageService',
- 'ScoreLevelService', 'InvitationsService', '$interval', 'MessagesService', 'TorrentsService', 'UsersService', 'DebugConsoleService'];
+ 'ScoreLevelService', 'InvitationsService', '$interval', 'MessagesService', 'TorrentsService', 'UsersService', 'DebugConsoleService', 'getStorageLangService'];
function HeaderController($scope, $state, $timeout, $translate, Authentication, menuService, MeanTorrentConfig, localStorageService, ScoreLevelService,
- InvitationsService, $interval, MessagesService, TorrentsService, UsersService, mtDebug) {
+ InvitationsService, $interval, MessagesService, TorrentsService, UsersService, mtDebug, getStorageLangService) {
$scope.$state = $state;
var vm = this;
vm.user = Authentication.user;
+ vm.langService = getStorageLangService;
vm.language = MeanTorrentConfig.meanTorrentConfig.language;
vm.announceConfig = MeanTorrentConfig.meanTorrentConfig.announce;
vm.messageConfig = MeanTorrentConfig.meanTorrentConfig.messages;
@@ -46,12 +47,50 @@
});
});
+ /**
+ * bindHoverToMenuItem
+ */
+ vm.bindHoverToMenuItem = function () {
+ //set menu bar opened when hover
+ $timeout(function () {
+ $('div.navbar-mt ul.nav li.dropdown').off('mouseenter mouseleave').hover(function (evt) {
+ if (!$(this).hasClass('open')) {
+ $(this).find('.dropdown-toggle', this).trigger('click');
+ bindClick($(this));
+ } else {
+ bindClick($(this));
+ }
+ }, function (evt) {
+ $(this).off('click');
+ if ($(this).hasClass('open')) {
+ $(this).find('.dropdown-toggle', this).trigger('click');
+ }
+ });
+
+ $('div.navbar-mt ul.nav li.dropdown ul.dropdown-menu').off('mouseenter mouseleave').hover(function (evt) {
+ $(this).parent().off('click');
+ }, function (evt) {
+ bindClick($(this).parent());
+ });
+ }, 0);
+
+ function bindClick(ele) {
+ ele.off('click').on('click', function (e) {
+ var sta = ele.find('.dropdown-toggle', ele).attr('alt');
+ if (sta) {
+ $state.go(sta);
+ }
+ });
+ }
+ };
+
/**
* auth-user-changed
*/
$scope.$on('auth-user-changed', function (event, args) {
vm.user = Authentication.user;
vm.scoreLevelData = vm.user ? ScoreLevelService.getScoreLevelJson(vm.user.score) : undefined;
+ vm.bindHoverToMenuItem();
vm.getInvitationsCount();
vm.getWarning();
vm.getCountUnread();
@@ -149,12 +188,14 @@
* checkHnRWarning
*/
vm.checkHnRWarning = function () {
- vm.getWarning();
- $interval(vm.getWarning, vm.hnrConfig.checkWaringInterval);
+ if (vm.hnrConfig.enable) {
+ vm.getWarning();
+ $interval(vm.getWarning, vm.hnrConfig.checkWaringInterval);
+ }
};
vm.getWarning = function () {
- if (Authentication.user) {
+ if (Authentication.user && vm.hnrConfig.enable) {
UsersService.getUserWarningNumber()
.then(function (data) {
vm.user.hnr_warning = Authentication.user.hnr_warning = data.hnr_warning;
diff --git a/modules/core/client/controllers/home.client.controller.js b/modules/core/client/controllers/home.client.controller.js
index 5981f1bf..4ec46805 100644
--- a/modules/core/client/controllers/home.client.controller.js
+++ b/modules/core/client/controllers/home.client.controller.js
@@ -5,13 +5,13 @@
.module('core')
.controller('HomeController', HomeController);
- HomeController.$inject = ['$scope', '$state', '$translate', 'Authentication', 'TorrentsService', 'Notification', 'MeanTorrentConfig',
+ HomeController.$inject = ['$scope', '$state', '$translate', 'Authentication', 'TorrentsService', 'NotifycationService', 'MeanTorrentConfig',
'getStorageLangService', 'ForumsService', '$timeout', 'localStorageService', 'TopicsService', 'TorrentGetInfoServices', 'DebugConsoleService',
- 'marked'];
+ 'marked', 'CheckService'];
- function HomeController($scope, $state, $translate, Authentication, TorrentsService, Notification, MeanTorrentConfig, getStorageLangService,
+ function HomeController($scope, $state, $translate, Authentication, TorrentsService, NotifycationService, MeanTorrentConfig, getStorageLangService,
ForumsService, $timeout, localStorageService, TopicsService, TorrentGetInfoServices, mtDebug,
- marked) {
+ marked, CheckService) {
var vm = this;
vm.user = Authentication.user;
vm.appConfig = MeanTorrentConfig.meanTorrentConfig.app;
@@ -23,8 +23,10 @@
vm.announceConfig = MeanTorrentConfig.meanTorrentConfig.announce;
vm.homeConfig = MeanTorrentConfig.meanTorrentConfig.home;
vm.supportConfig = MeanTorrentConfig.meanTorrentConfig.support;
+ vm.scoreConfig = MeanTorrentConfig.meanTorrentConfig.score;
vm.searchType = 'torrents';
+ vm.checkData = undefined;
/**
* initBodyBackground
@@ -89,7 +91,7 @@
$state.go('forums.search', {forumId: fid, keys: vm.searchKeys});
} else { //search from torrents
- $state.go('torrents.search', {keys: vm.searchKeys});
+ $state.go('torrents.aggregate', {keys: vm.searchKeys});
}
}
};
@@ -146,9 +148,9 @@
var e = $('.sales_notice');
$timeout(function () {
- e.slideDown(800);
+ e.slideDown(500);
e.removeClass('panel-collapsed');
- }, 1000);
+ }, 300);
};
/**
@@ -195,9 +197,9 @@
var e = $('.examination_notice');
$timeout(function () {
- e.slideDown(800);
+ e.slideDown(500);
e.removeClass('panel-collapsed');
- }, 1000);
+ }, 300);
};
/**
@@ -247,9 +249,9 @@
var e = $('.examination_status');
$timeout(function () {
- e.slideDown(800);
+ e.slideDown(500);
e.removeClass('panel-collapsed');
- }, 1000);
+ }, 300);
};
/**
@@ -323,5 +325,86 @@
return marked(ts, {sanitize: true});
};
+ /**
+ * getMyCheckData
+ */
+ vm.getMyCheckData = function () {
+ CheckService.get(function (res) {
+ mtDebug.info(res);
+ vm.checkData = res;
+ vm.openCheckTooltip();
+ }, function (err) {
+ vm.checkData = false;
+ vm.openCheckTooltip();
+ });
+ };
+
+ /**
+ * checkIn
+ */
+ vm.checkIn = function () {
+ CheckService.update(function (res) {
+ mtDebug.info(res);
+ vm.checkData = res;
+ NotifycationService.showSuccessNotify('CHECK.CHECK_SUCCESSFULLY');
+ }, function (err) {
+ NotifycationService.showErrorNotify(err.data.message, 'CHECK.CHECK_ERROR');
+ });
+ };
+
+ /**
+ * getCheckTodayDoneMessage
+ * @returns {*}
+ */
+ vm.getCheckTodayDoneMessage = function () {
+ var ts = $translate.instant('CHECK.CHECK_TODAY_DONE', {
+ keepDays: vm.checkData.keepDays,
+ checkTime: vm.checkData.lastCheckedAt,
+ todayScore: vm.scoreConfig.action.dailyCheckIn.dailyBasicScore + (vm.checkData.keepDays - 1) * vm.scoreConfig.action.dailyCheckIn.dailyStepScore,
+ tomorrowScore: vm.scoreConfig.action.dailyCheckIn.dailyBasicScore + vm.checkData.keepDays * vm.scoreConfig.action.dailyCheckIn.dailyStepScore
+ });
+
+ return marked(ts, {sanitize: false});
+ };
+
+ /**
+ * getCheckTodayNotMessage
+ * @returns {*}
+ */
+ vm.getCheckTodayNotMessage = function () {
+ var ts = $translate.instant('CHECK.CHECK_TODAY_NOT', {
+ checkTime: vm.checkData.lastCheckedAt,
+ todayScore: vm.scoreConfig.action.dailyCheckIn.dailyBasicScore + vm.checkData.keepDays * vm.scoreConfig.action.dailyCheckIn.dailyStepScore,
+ tomorrowScore: vm.scoreConfig.action.dailyCheckIn.dailyBasicScore + (vm.checkData.keepDays + 1) * vm.scoreConfig.action.dailyCheckIn.dailyStepScore
+ });
+
+ return marked(ts, {sanitize: false});
+ };
+
+ /**
+ * getCheckTooltipMessage
+ * @returns {*}
+ */
+ vm.getCheckTooltipMessage = function () {
+ var ts = $translate.instant('CHECK.CHECK_TOOLTIP', {
+ todayScore: vm.scoreConfig.action.dailyCheckIn.dailyBasicScore,
+ tomorrowScore: vm.scoreConfig.action.dailyCheckIn.dailyBasicScore + vm.scoreConfig.action.dailyCheckIn.dailyStepScore
+ });
+
+ return marked(ts, {sanitize: false});
+ };
+
+ /**
+ * openCheckTooltip
+ */
+ vm.openCheckTooltip = function () {
+ var e = $('.home-check-in');
+
+ $timeout(function () {
+ e.slideDown(500);
+ e.removeClass('panel-collapsed');
+ }, 300);
+ };
+
}
}());
diff --git a/modules/core/client/directives/editable-line.client.directive.js b/modules/core/client/directives/editable-line.client.directive.js
index 22496fb8..37a80fce 100644
--- a/modules/core/client/directives/editable-line.client.directive.js
+++ b/modules/core/client/directives/editable-line.client.directive.js
@@ -27,11 +27,13 @@
$scope.input = jQuery($element).find('.editable-line-input');
$scope.originalDivBackground = $scope.div.css('background-color');
- $scope.div.awesomeCursor('wrench', {
- color: '#ff6000',
- flip: 'horizontal',
- outline: '#ff3e00'
- });
+ if (!$scope.readonly) {
+ $scope.div.awesomeCursor('pencil', {
+ color: '#ff6000',
+ flip: 'vertical',
+ outline: '#ff3e00'
+ });
+ }
var originalValue;
$scope.div.bind('click', function () {
diff --git a/modules/core/client/directives/torrent-list-item.client.directive.js b/modules/core/client/directives/torrent-list-item.client.directive.js
new file mode 100644
index 00000000..664c6fad
--- /dev/null
+++ b/modules/core/client/directives/torrent-list-item.client.directive.js
@@ -0,0 +1,377 @@
+(function () {
+ 'use strict';
+
+ angular.module('core')
+ .directive('torrentListItem', torrentListItem);
+
+ function torrentListItem() {
+ var TorrentsItemController = ['$scope', '$state', 'TorrentGetInfoServices', 'ResourcesTagsServices', '$timeout', 'DownloadService', 'MeanTorrentConfig',
+ 'TorrentsService', 'Authentication', 'NotifycationService', 'ModalConfirmService', '$translate', 'moment',
+ function ($scope, $state, TorrentGetInfoServices, ResourcesTagsServices, $timeout, DownloadService, MeanTorrentConfig, TorrentsService, Authentication,
+ NotifycationService, ModalConfirmService, $translate, moment) {
+ var vm = this;
+
+ vm.user = Authentication.user;
+ vm.state = $state;
+ vm.TGI = TorrentGetInfoServices;
+ vm.RTS = ResourcesTagsServices;
+ vm.DLS = DownloadService;
+ vm.torrentSalesType = MeanTorrentConfig.meanTorrentConfig.torrentSalesType;
+ vm.torrentRLevels = MeanTorrentConfig.meanTorrentConfig.torrentRecommendLevel;
+ vm.salesGlobalConfig = MeanTorrentConfig.meanTorrentConfig.torrentGlobalSales;
+ vm.hnrConfig = MeanTorrentConfig.meanTorrentConfig.hitAndRun;
+
+ /**
+ * buildPager
+ */
+ function buildPager() {
+ if (typeof $scope.parent.torrentBuildPager === 'function') {
+ $scope.parent.torrentBuildPager();
+ } else if (typeof $scope.parent.buildPager === 'function') {
+ $scope.parent.buildPager();
+ }
+ }
+
+ /**
+ * getTagUsedStatus
+ * @param t
+ * @returns {boolean}
+ */
+ vm.getTagUsedStatus = function (t) {
+ return $scope.parent.searchTags.indexOf(t) !== -1;
+ };
+
+ /**
+ * onTagClicked
+ * @param tag: tag name
+ */
+ vm.onTagClicked = function (tag) {
+ if ($('#tag_' + tag) && $('#tag_' + tag).val()) {
+ $timeout(function () {
+ angular.element('#tag_' + tag).trigger('click');
+ }, 10);
+ } else {
+ if ($scope.parent.searchTags.includes(tag)) {
+ $scope.parent.searchTags.splice($scope.parent.searchTags.indexOf(tag), 1);
+ } else {
+ $scope.parent.searchTags.push(tag);
+ }
+ buildPager();
+ }
+ };
+
+ /**
+ * onReleaseClicked
+ * @param y
+ */
+ vm.onReleaseClicked = function (y) {
+ if ($scope.parent.releaseYear === y) {
+ $scope.parent.releaseYear = undefined;
+ } else {
+ $scope.parent.releaseYear = y;
+ }
+
+ buildPager();
+ };
+
+ /**
+ * onTorrentTypeClicked
+ * @param t
+ */
+ vm.onTorrentTypeClicked = function (t) {
+ if ($state.current.name.startsWith('admin.torrents')) {
+ if ($scope.parent.torrentType === t) {
+ $scope.parent.torrentType = 'aggregate';
+ } else {
+ $scope.parent.torrentType = t;
+ }
+ } else {
+ if ($scope.parent.filterType === t) {
+ $scope.parent.filterType = $scope.parent.torrentType;
+ } else {
+ $scope.parent.filterType = t;
+ }
+ }
+
+ buildPager();
+ };
+
+ /**
+ * onRLevelClicked
+ * @param y
+ */
+ vm.onRLevelClicked = function (l) {
+ if ($scope.parent.torrentRLevel === l) {
+ $scope.parent.torrentRLevel = 'level0';
+ } else {
+ $scope.parent.torrentRLevel = l;
+ }
+
+ buildPager();
+ };
+
+ /**
+ * onHnRClicked
+ */
+ vm.onHnRClicked = function () {
+ $scope.parent.filterHnR = !$scope.parent.filterHnR;
+
+ buildPager();
+ };
+
+ /**
+ * onSaleChanged
+ */
+ vm.onSaleClicked = function () {
+ $scope.parent.filterSale = !$scope.parent.filterSale;
+
+ buildPager();
+ };
+
+ /**
+ * onVIPClicked
+ */
+ vm.onVIPClicked = function () {
+ $scope.parent.filterVIP = !$scope.parent.filterVIP;
+
+ buildPager();
+ };
+
+ /**
+ * onTopClicked
+ */
+ vm.onTopClicked = function () {
+ $scope.parent.filterTop = !$scope.parent.filterTop;
+ buildPager();
+ };
+
+ /**
+ * onUniqueClicked
+ */
+ vm.onUniqueClicked = function () {
+ $scope.parent.filterUnique = !$scope.parent.filterUnique;
+ buildPager();
+ };
+
+ /**
+ * toggleTop
+ */
+ vm.toggleTop = function (item) {
+ var dt = new TorrentsService(item);
+ dt.$toggleTopStatus(function (res) {
+ $scope.list[$scope.list.indexOf(item)] = res;
+ NotifycationService.showSuccessNotify('TORRENT_TOGGLE_TOP_SUCCESSFULLY');
+ }, function (res) {
+ NotifycationService.showErrorNotify(res.data.message, 'TORRENT_TOGGLE_TOP_FAILED');
+ });
+ };
+
+ /**
+ * toggleTop
+ */
+ vm.toggleUnique = function (item) {
+ var dt = new TorrentsService(item);
+ dt.$toggleUniqueStatus(function (res) {
+ $scope.list[$scope.list.indexOf(item)] = res;
+ NotifycationService.showSuccessNotify('TORRENT_TOGGLE_UNIQUE_SUCCESSFULLY');
+ }, function (res) {
+ NotifycationService.showErrorNotify(res.data.message, 'TORRENT_TOGGLE_UNIQUE_FAILED');
+ });
+ };
+
+ /**
+ * toggleHnR
+ */
+ vm.toggleHnR = function (item) {
+ var dt = new TorrentsService(item);
+ dt.$toggleHnRStatus(function (res) {
+ $scope.list[$scope.list.indexOf(item)] = res;
+ NotifycationService.showSuccessNotify('TORRENT_TOGGLE_HNR_SUCCESSFULLY');
+ }, function (res) {
+ NotifycationService.showErrorNotify(res.data.message, 'TORRENT_TOGGLE_HNR_FAILED');
+ });
+ };
+
+ /**
+ * toggleVIP
+ */
+ vm.toggleVIP = function (item) {
+ var dt = new TorrentsService(item);
+ dt.$toggleVIPStatus(function (res) {
+ $scope.list[$scope.list.indexOf(item)] = res;
+ NotifycationService.showSuccessNotify('TORRENT_TOGGLE_VIP_SUCCESSFULLY');
+ }, function (res) {
+ NotifycationService.showErrorNotify(res.data.message, 'TORRENT_TOGGLE_VIP_FAILED');
+ });
+ };
+
+ /**
+ * vm.setRecommendLevel
+ */
+ vm.setRecommendLevel = function (item, rl) {
+ TorrentsService.setRecommendLevel({
+ _torrentId: item._id,
+ _rlevel: rl.value
+ }, function (res) {
+ $scope.list[$scope.list.indexOf(item)] = res;
+ NotifycationService.showSuccessNotify('TORRENT_SETRLEVEL_SUCCESSFULLY');
+ }, function (res) {
+ NotifycationService.showErrorNotify(res.data.message, 'TORRENT_SETRLEVEL_ERROR');
+ });
+ };
+
+ /**
+ * setSaleType
+ */
+ vm.setSaleType = function (item, st) {
+ TorrentsService.setSaleType({
+ _torrentId: item._id,
+ _saleType: st.name
+ }, function (res) {
+ $scope.list[$scope.list.indexOf(item)] = res;
+ NotifycationService.showSuccessNotify('TORRENT_SETSALETYPE_SUCCESSFULLY');
+ }, function (res) {
+ NotifycationService.showErrorNotify(res.data.message, 'TORRENT_SETSALETYPE_ERROR');
+ });
+ };
+
+ /**
+ * deleteTorrent
+ */
+ vm.deleteTorrent = function (item) {
+ var modalOptions = {
+ closeButtonText: $translate.instant('TORRENT_DELETE_CONFIRM_CANCEL'),
+ actionButtonText: $translate.instant('TORRENT_DELETE_CONFIRM_OK'),
+ headerText: $translate.instant('TORRENT_DELETE_CONFIRM_HEADER_TEXT'),
+ bodyText: $translate.instant('TORRENT_DELETE_CONFIRM_BODY_TEXT'),
+ bodyParams: item.torrent_filename,
+
+ selectOptions: {
+ enable: true,
+ title: 'TORRENT_DELETE_REASON',
+ options: [
+ 'TORRENT_DELETE_REASON_OVERVIEW',
+ 'TORRENT_DELETE_REASON_NFO',
+ 'TORRENT_DELETE_REASON_QUALITY',
+ 'TORRENT_DELETE_REASON_ILLEGAL'
+ ]
+ }
+ };
+
+ ModalConfirmService.showModal({}, modalOptions)
+ .then(function (result) {
+ var reason = result.reason;
+ if (reason === 'CUSTOM') reason = result.custom;
+
+ var dt = new TorrentsService(item);
+ dt.$remove({
+ reason: reason
+ }, function (response) {
+ successCallback(response);
+ }, function (errorResponse) {
+ errorCallback(errorResponse);
+ });
+
+ function successCallback(res) {
+ $scope.list.splice($scope.list.indexOf(item), 1);
+ NotifycationService.showSuccessNotify('TORRENT_DELETE_SUCCESSFULLY');
+ }
+
+ function errorCallback(res) {
+ NotifycationService.showErrorNotify(res.data.message, 'TORRENT_DELETE_ERROR');
+ }
+ });
+ };
+
+ /**
+ * reviewedTorrentStatus
+ * @param item
+ */
+ vm.reviewedTorrentStatus = function (item) {
+ TorrentsService.setReviewedStatus({
+ _torrentId: item._id
+ }, function (res) {
+ $scope.list[$scope.list.indexOf(item)] = res;
+ NotifycationService.showSuccessNotify('TORRENT_SETREVIEWED_SUCCESSFULLY');
+ }, function (res) {
+ NotifycationService.showErrorNotify(res.data.message, 'TORRENT_SETREVIEWED_ERROR');
+ });
+ };
+
+ /**
+ * showByLabel
+ * @returns {boolean}
+ */
+ vm.showByLabel = function () {
+ if (vm.state.current.name.startsWith('admin.torrents')) {
+ return true;
+ } else if (vm.state.current.name.indexOf('seeding') > 0) {
+ return true;
+ } else if (vm.state.current.name.indexOf('leeching') > 0) {
+ return true;
+ } else if (vm.state.current.name.indexOf('warning') > 0) {
+ return true;
+ } else if (vm.state.current.name.indexOf('downloading') > 0) {
+ return true;
+ } else {
+ return false;
+ }
+ };
+
+ /**
+ * showByUser
+ * @returns {boolean}
+ */
+ vm.showByUser = function () {
+ if (vm.state.current.name.startsWith('admin.torrents')) {
+ return false;
+ } else if (vm.state.current.name.indexOf('seeding') > 0) {
+ return false;
+ } else if (vm.state.current.name.indexOf('leeching') > 0) {
+ return false;
+ } else if (vm.state.current.name.indexOf('warning') > 0) {
+ return false;
+ } else if (vm.state.current.name.indexOf('downloading') > 0) {
+ return false;
+ } else if (vm.state.current.name.startsWith('collections')) {
+ return false;
+ } else if (vm.state.current.name.startsWith('requests')) {
+ return false;
+ } else {
+ return true;
+ }
+ };
+
+ /**
+ * isGlobalSaleNow
+ * @returns {boolean}
+ */
+ vm.isGlobalSaleNow = function () {
+ var start = moment(vm.salesGlobalConfig.global.startAt, vm.salesGlobalConfig.global.timeFormats).valueOf();
+ var end = start + vm.salesGlobalConfig.global.expires;
+ var now = Date.now();
+
+ if (now > start && now < end && vm.salesGlobalConfig.global.value) {
+ return true;
+ } else {
+ return false;
+ }
+ };
+
+ }];
+
+ return {
+ restrict: 'AE',
+ templateUrl: '/modules/torrents/client/templates/torrent-item.client.view.html',
+ controller: TorrentsItemController,
+ controllerAs: 'vm',
+ scope: {
+ item: '=',
+ list: '=',
+ peer: '=',
+ warning: '=',
+ parent: '='
+ }
+ };
+ }
+}());
diff --git a/modules/core/client/directives/torrent-progress.client.directive.js b/modules/core/client/directives/torrent-progress.client.directive.js
index b542558e..b81c46e3 100644
--- a/modules/core/client/directives/torrent-progress.client.directive.js
+++ b/modules/core/client/directives/torrent-progress.client.directive.js
@@ -20,10 +20,8 @@
function link(scope, element, attrs) {
scope.$watch(attrs.torrentProgress, function (p) {
- if (p && p.length > 0) {
- var pt = p[0];
- //mtDebug.info(pt);
-
+ var pt = Array.isArray(p) ? (p.length > 0 ? p[0] : undefined) : p;
+ if (pt) {
var t_progressbar = ngProgressFactory.createInstance();
t_progressbar.setParent(element[0]);
t_progressbar.setAbsolute();
@@ -69,8 +67,6 @@
scope.$watch(attrs.cardProgress, function (p) {
if (p && p.length > 0) {
var pt = p[0];
- //mtDebug.info(pt);
-
var t_progressbar = ngProgressFactory.createInstance();
t_progressbar.setParent(element[0]);
t_progressbar.setAbsolute();
diff --git a/modules/core/client/filter/bytes.client.filter.js b/modules/core/client/filter/bytes.client.filter.js
index ea06792a..9986abf5 100644
--- a/modules/core/client/filter/bytes.client.filter.js
+++ b/modules/core/client/filter/bytes.client.filter.js
@@ -9,7 +9,7 @@
function bytes() {
return function (bytes, precision) {
- if (bytes === 0 || isNaN(parseFloat(bytes)) || !isFinite(bytes)) return '-';
+ if (bytes === 0 || isNaN(parseFloat(bytes)) || !isFinite(bytes)) return '0';
if (typeof precision === 'undefined') precision = 1;
//var units = ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'],
var units = ['b', 'K', 'M', 'G', 'T', 'P'],
diff --git a/modules/core/client/filter/dollar.client.filter.js b/modules/core/client/filter/dollar.client.filter.js
index 38e78fc8..223d9deb 100644
--- a/modules/core/client/filter/dollar.client.filter.js
+++ b/modules/core/client/filter/dollar.client.filter.js
@@ -11,7 +11,7 @@
function dollar($translate) {
return function (number, precision) {
- if (number === 0 || isNaN(parseFloat(number)) || !isFinite(number)) return '-';
+ if (number === 0 || isNaN(parseFloat(number)) || !isFinite(number)) return '0';
if (typeof precision === 'undefined') precision = 1;
return '$' + (number / 1000000).toFixed(precision) + ' ' + $translate.instant('UNIT_MILLION');
};
diff --git a/modules/core/client/filter/score.client.filter.js b/modules/core/client/filter/score.client.filter.js
new file mode 100644
index 00000000..6280379d
--- /dev/null
+++ b/modules/core/client/filter/score.client.filter.js
@@ -0,0 +1,18 @@
+(function () {
+ 'use strict';
+
+ // Focus the element on page load
+ // Unless the user is on a small device, because this could obscure the page with a keyboard
+
+ angular.module('core')
+ .filter('score', score);
+
+ score.$inject = ['$filter'];
+
+ function score($filter) {
+ return function (input, decimals) {
+ if (input === 0 || isNaN(parseFloat(input)) || !isFinite(input)) return '0';
+ return $filter('number')(input, decimals);
+ };
+ }
+}());
diff --git a/modules/core/client/less/btn-size.less b/modules/core/client/less/btn-size.less
index 1de14495..d495eef3 100644
--- a/modules/core/client/less/btn-size.less
+++ b/modules/core/client/less/btn-size.less
@@ -108,6 +108,46 @@
min-width: 500px !important;
}
+.max-width-10 {
+ max-width: 10px !important;
+}
+
+.max-width-20 {
+ max-width: 20px !important;
+}
+
+.max-width-30 {
+ max-width: 30px !important;
+}
+
+.max-width-40 {
+ max-width: 40px !important;
+}
+
+.max-width-50 {
+ max-width: 50px !important;
+}
+
+.max-width-60 {
+ max-width: 60px !important;
+}
+
+.max-width-70 {
+ max-width: 70px !important;
+}
+
+.max-width-80 {
+ max-width: 80px !important;
+}
+
+.max-width-90 {
+ max-width: 90px !important;
+}
+
+.max-width-100 {
+ max-width: 100px !important;
+}
+
.max-width-300 {
max-width: 300px !important;
}
@@ -134,9 +174,19 @@
}
}
+.btn-mt-o-default-dark {
+ color: #666;
+ border: solid 1px #666;
+ &:focus {
+ color: #666;
+ border-color: #666;
+ }
+}
+
.btn-mt-o-success {
color: @state-success-text;
border: solid 1px @state-success-text;
+ &:hover,
&:focus {
color: @state-success-text;
border-color: @state-success-text;
diff --git a/modules/core/client/less/home.less b/modules/core/client/less/home.less
index c9bf80cb..bdac4200 100644
--- a/modules/core/client/less/home.less
+++ b/modules/core/client/less/home.less
@@ -113,6 +113,30 @@
}
}
+.col-valign-middle {
+ @media (min-width: @screen-sm-min) {
+ display: table-cell;
+ vertical-align: middle;
+ float: none;
+ }
+}
+
+.home-check-in {
+ padding: 10px 0;
+ h4, .h4 {
+ line-height: 1.8;
+ }
+ .check-in-btn {
+ margin-top: 10px;
+ @media(max-width: @screen-sm-max){
+ margin-top: 20px;
+ }
+ @media(max-width: @screen-xs-max){
+ margin-top: 15px;
+ }
+ }
+}
+
.home-button-list {
padding: 50px 0;
@media (max-width: @screen-xs-max) {
@@ -316,6 +340,18 @@
}
}
+.filter-check-in {
+ position: relative;
+ margin-top: 2px;
+ background-color: @mt-body-background-color;
+ background-color: rgba(255, 255, 255, .85);
+ transition: background-color .2s ease-in;
+ &:hover {
+ background-color: @mt-body-background-color;
+ background-color: rgba(255, 255, 255, .95);
+ }
+}
+
.filter-copy {
position: relative;
line-height: 2;
@@ -378,71 +414,73 @@
vertical-align: middle;
}
}
- .search-panel {
+ .top-panel {
min-height: 120px;
padding: 20px 0;
text-shadow: 0 0 0.1em #000,-0 -0 0.1em #000;
- .search-title {
- color: #fff;
- font-size: 2em;
- font-weight: 400;
- margin-bottom: 0 !important;
- }
- .search-sub-title {
- margin-top: 10px;
- color: #aaa;
- text-shadow: 0 0 0.1em #000, 0 0 0.1em #000;
- }
- .search-group {
- max-width: 50em;
- margin-right: auto;
- margin-left: auto;
- display: block;
- input {
- color: #eee;
- background-color: #ccc;
- background-color: rgba(255, 255, 255, 0.2);
- border-radius: 17px;
- position: inherit;
- z-index: 2;
- float: none;
- width: 100%;
- margin-bottom: 0;
- padding-right: 105px;
+ .home-search {
+ .search-title {
+ color: #fff;
+ font-size: 2em;
+ font-weight: 400;
+ margin-bottom: 0 !important;
}
- .btn-search {
- border-top-right-radius: 17px;
- border-bottom-right-radius: 17px;
- position: absolute;
- right: 1px;
- top: 1px;
- bottom: 1px;
- opacity: 0.6;
- z-index: 3;
- &:hover,
- &:focus {
- outline: none;
- opacity: 1;
+ .search-sub-title {
+ margin-top: 10px;
+ color: #aaa;
+ text-shadow: 0 0 0.1em #000, 0 0 0.1em #000;
+ }
+ .search-group {
+ max-width: 50em;
+ margin-right: auto;
+ margin-left: auto;
+ display: block;
+ input {
+ color: #eee;
+ background-color: #ccc;
+ background-color: rgba(255, 255, 255, 0.2);
+ border-radius: 17px;
+ position: inherit;
+ z-index: 2;
+ float: none;
+ width: 100%;
+ margin-bottom: 0;
+ padding-right: 105px;
+ }
+ .btn-search {
+ border-top-right-radius: 17px;
+ border-bottom-right-radius: 17px;
+ position: absolute;
+ right: 1px;
+ top: 1px;
+ bottom: 1px;
+ opacity: 0.6;
+ z-index: 3;
+ &:hover,
+ &:focus {
+ outline: none;
+ opacity: 1;
+ }
}
}
- }
- .search-type {
- color: #aaa;
- text-shadow: 0 0 0.1em #000, 0 0 0.1em #000;
- input {
- opacity: 0.6;
- &:hover,
- &:checked,
- &:focus {
- opacity: 1;
+ .search-type {
+ color: #aaa;
+ text-shadow: 0 0 0.1em #000, 0 0 0.1em #000;
+ input {
+ opacity: 0.6;
+ &:hover,
+ &:checked,
+ &:focus {
+ opacity: 1;
+ }
+ }
+ .radio-inline + .radio-inline,
+ .checkbox-inline + .checkbox-inline {
+ margin-top: 0;
+ margin-left: 50px; // space out consecutive inline controls
}
- }
- .radio-inline + .radio-inline,
- .checkbox-inline + .checkbox-inline {
- margin-top: 0;
- margin-left: 50px; // space out consecutive inline controls
- }
+ }
}
}
}
diff --git a/modules/core/client/less/media-margin.less b/modules/core/client/less/media-margin.less
new file mode 100644
index 00000000..5ba962dc
--- /dev/null
+++ b/modules/core/client/less/media-margin.less
@@ -0,0 +1,7 @@
+@import (reference) "../../../core/client/less/mt-var.less";
+
+.xs-margin-top-10 {
+ @media (max-width: @screen-xs-max) {
+ margin-top: 10px;
+ }
+}
diff --git a/modules/core/client/less/mt.less b/modules/core/client/less/mt.less
index 258b2f7a..800198f3 100644
--- a/modules/core/client/less/mt.less
+++ b/modules/core/client/less/mt.less
@@ -14,6 +14,10 @@ body {
background-color: @mt-body-background-color;
}
+.ui-notification{
+ width: 400px;
+}
+
.social-list {
img {
border-radius: 12px;
@@ -438,6 +442,7 @@ body {
color: #FF6600;
> kbd {
background-color: #FF6600;
+ font-size: 12px;
}
}
@@ -908,6 +913,12 @@ body {
.coll-item-remove {
display: block;
}
+ .warning-btn {
+ display: block;
+ }
+ .warning-data {
+ display: none;
+ }
}
.media-left {
position: relative;
@@ -918,8 +929,8 @@ body {
> .td-text-overflow {
.text-long {
@media (min-width: @screen-lg-min) {
- max-width: 570px;
- min-width: 560px;
+ max-width: 550px;
+ min-width: 540px;
}
@media (max-width: @screen-md-max) {
max-width: 420px;
@@ -1064,14 +1075,15 @@ body {
position: relative;
.torrent-filename {
margin-top: 2px;
- font-size: 12px;
+ font-size: 13px;
color: @gray-light;
}
.list-all-tags {
- position: absolute;
- bottom: 1px;
+ min-height: 52px;
+ margin-top: 8px;
+ width: 100%;
.label {
- margin-top: 3px;
+ margin-top: 5px;
}
span {
position: relative;
@@ -1089,10 +1101,25 @@ body {
border: solid 1px #fff;
}
}
+ .label-torrent-link {
+ color: #8a8a8a;
+ border: solid 1px #dedede;
+ background-color: #fafafa;
+ &:hover {
+ color: #f00;
+ }
+ }
}
.media-heading {
+ line-height: 1.2;
margin-bottom: 5px;
}
+ .list-all-genres {
+ font-size: 12px;
+ .genres-item {
+ color: @gray-light;
+ }
+ }
}
.td-imdb {
min-width: 90px;
@@ -1111,7 +1138,10 @@ body {
}
.td-admin-cmd {
min-width: 143px;
- padding: 0 !important;
+ padding: 5px !important;
+ }
+ .warning-btn {
+ display: none;
}
}
@@ -1133,10 +1163,7 @@ body {
}
.list-all-genres {
- font-size: 12px;
.genres-item {
- color: @gray-light;
- font-size: 12px;
&:not(:first-child) {
&::before {
content: " | ";
@@ -1215,6 +1242,7 @@ body {
.label-tag {
color: #0366d6;
background-color: #f1f8ff;
+ border: solid 1px #ddeeff;
&:hover {
cursor: pointer;
color: #f00;
@@ -1225,6 +1253,7 @@ body {
}
.label-rlevel {
+ border: solid 1px darken(@brand-info, 2%);
&:hover {
cursor: pointer;
color: #f00;
@@ -1234,6 +1263,7 @@ body {
.label-hnr-info {
color: #eee;
background-color: #333;
+ border: solid 1px #000;
&:hover {
cursor: pointer;
color: #f00;
@@ -1242,9 +1272,9 @@ body {
}
.label-vip-info {
- color: @mt-base-color;
- font-weight: bold;
- background-color: #f1f8ff;
+ color: #fff;
+ background-color: @mt-base-color;
+ border: solid 1px darken(@mt-base-color, 2%);
&:hover {
cursor: pointer;
color: #f00;
@@ -1254,9 +1284,29 @@ body {
}
}
+.label-unique-info {
+ color: #fff;
+ background-color: @brand-danger;
+ border: solid 1px darken(@brand-danger, 2%);
+ &:hover {
+ cursor: pointer;
+ color: #f00;
+ }
+ &:active {
+ color: #0366d6;
+ }
+}
+
+.upload-by {
+ color: #888;
+ background-color: #efefef;
+ border: solid 1px #dedede;
+}
+
.label-se-info {
color: @mt-base-color;
background-color: #f1f8ff;
+ border: solid 1px #ddeeff;
&:hover {
cursor: pointer;
color: #f00;
@@ -1264,6 +1314,7 @@ body {
}
.label-ttype {
+ border: solid 1px darken(@brand-primary, 2%);
&:hover {
cursor: pointer;
color: #f00;
@@ -1278,6 +1329,7 @@ body {
}
.label-sale {
+ border: solid 1px darken(@brand-success, 2%);
&:hover {
cursor: pointer;
color: #f00;
@@ -1285,6 +1337,17 @@ body {
}
.label-release {
+ border: solid 1px darken(@brand-warning, 2%);
+ &:hover {
+ cursor: pointer;
+ color: #f00;
+ }
+}
+
+.torrent-top {
+ color: @mt-base-color;
+ border: solid 1px darken(@mt-base-color, 2%);
+ background-color: #fafafa;
&:hover {
cursor: pointer;
color: #f00;
@@ -1305,6 +1368,15 @@ body {
}
}
+.radio-type {
+ margin-top: 0;
+ margin-bottom: 0;
+ line-height: 1.6;
+ input[type="radio"] {
+ margin-top: 5px;
+ }
+}
+
.checkbox-hnr {
margin-top: 0;
margin-bottom: 0;
@@ -1658,6 +1730,9 @@ body {
padding: 15px 8px;
}
}
+ + tbody {
+ border-top: none;
+ }
}
}
}
@@ -1724,16 +1799,38 @@ body {
}
.lang-list {
- margin-left: 10px;
+ margin-top: 5px;
+ padding-left: 5px;
line-height: 2;
.flag-icon {
font-size: 18px;
margin-left: 10px;
&,
- &:hover,
&:focus {
cursor: pointer;
}
+ &:hover {
+ &:after {
+ content: '';
+ background-color: #c0c0c0;
+ position: absolute;
+ width: 100%;
+ height: 3px;
+ top: -5px;
+ right: 0;
+ }
+ }
+ &.curr-language {
+ &:after {
+ content: '';
+ background-color: @brand-primary;
+ position: absolute;
+ width: 100%;
+ height: 3px;
+ top: -5px;
+ right: 0;
+ }
+ }
}
}
@@ -1760,11 +1857,6 @@ body {
padding-top: 5px;
}
-.upload-by {
- color: #888;
- font-size: 12px;
-}
-
.status-avatar {
border-radius: 3px;
height: 44px;
diff --git a/modules/core/client/services/menu.client.service.js b/modules/core/client/services/menu.client.service.js
index 20f90d72..f0419915 100644
--- a/modules/core/client/services/menu.client.service.js
+++ b/modules/core/client/services/menu.client.service.js
@@ -61,7 +61,8 @@
target: options.target || undefined,
divider: options.divider || false,
faClass: options.faClass || null,
- faIcon: options.faIcon || null
+ faIcon: options.faIcon || null,
+ linkState: options.linkState || undefined
});
// Add submenu items
@@ -96,7 +97,8 @@
target: options.target || undefined,
divider: options.divider || false,
faClass: options.faClass || null,
- faIcon: options.faIcon || null
+ faIcon: options.faIcon || null,
+ linkState: options.linkState || undefined
});
});
diff --git a/modules/core/client/views/footer.client.view.html b/modules/core/client/views/footer.client.view.html
index fae498d4..e835ab8d 100644
--- a/modules/core/client/views/footer.client.view.html
+++ b/modules/core/client/views/footer.client.view.html
@@ -36,7 +36,7 @@
diff --git a/modules/core/client/views/header.client.view.html b/modules/core/client/views/header.client.view.html
index 9cbed53e..7ff27125 100644
--- a/modules/core/client/views/header.client.view.html
+++ b/modules/core/client/views/header.client.view.html
@@ -1,4 +1,5 @@
-