Advertisement
smallkan

Untitled

Feb 25th, 2016
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.54 KB | None | 0 0
  1. (function (App) {
  2. 'use strict';
  3. var querystring = require('querystring');
  4. var request = require('request');
  5. var Q = require('q');
  6. var inherits = require('util').inherits;
  7.  
  8.  
  9. var statusMap = {
  10. 0: 'Not Airing Yet',
  11. 1: 'Currently Airing',
  12. 2: 'Ended'
  13. };
  14.  
  15. var URL = 'http://ptp.haruhichan.com/';
  16.  
  17. var Haruhichan = function () {
  18. Haruhichan.super_.call(this);
  19. };
  20.  
  21. inherits(Haruhichan, App.Providers.Generic);
  22.  
  23. var queryTorrents = function (filters) {
  24. var deferred = Q.defer();
  25.  
  26. var params = {};
  27. params.sort = 'popularity';
  28. params.limit = '50';
  29. params.type = 'All';
  30. params.page = (filters.page ? filters.page - 1 : 0);
  31.  
  32. if (filters.keywords) {
  33. params.search = filters.keywords.replace(/\s/g, '% ');
  34. }
  35.  
  36. var genres = filters.genre;
  37. if (genres && (genres !== 'All')) {
  38. params.genres = genres;
  39. }
  40.  
  41. if (filters.sorter && filters.sorter !== 'popularity') {
  42. params.sort = filters.sorter;
  43. }
  44. if (filters.sort === 'name') {
  45. params.order * -1;
  46. }
  47.  
  48. switch (filters.order) {
  49. case 1:
  50. params.order = 'desc';
  51. break;
  52. case -1:
  53. /* falls through */
  54. default:
  55. params.order = 'asc';
  56. break;
  57. }
  58.  
  59. if (filters.type && filters.type !== 'All') {
  60. if (filters.type === 'Movies') {
  61. params.type = 'movie';
  62. } else {
  63. params.type = filters.type.toLowerCase();
  64. }
  65. }
  66.  
  67. // XXX(xaiki): haruchichan currently doesn't support filters
  68. var url = URL + 'list.php?' + querystring.stringify(params).replace(/%25%20/g, '%20');
  69. win.info('Request to Hurahican API', url);
  70. request({
  71. url: url,
  72. json: true
  73. }, function (error, response, data) {
  74. if (error || response.statusCode >= 400) {
  75. deferred.reject(error);
  76. } else if (!data || (data.error && data.error !== 'No movies found')) {
  77. var err = data ? data.error : 'No data returned';
  78. win.error('API error:', err);
  79. deferred.reject(err);
  80. } else {
  81. deferred.resolve(data);
  82. }
  83. });
  84.  
  85. return deferred.promise;
  86. };
  87.  
  88. var parseTime = function (duration) {
  89. var time = duration.match(/(?:([0-9]+) h)?.*?(?:([0-9]+) min)/);
  90. if (!time) {
  91. return win.error('couldn\'t parse time:', time);
  92. }
  93. return (time[1] ? time[1] : 0) * 60 + Number(time[2]);
  94. };
  95.  
  96. var formatForPopcorn = function (items) {
  97. var results = _.map(items, function (item) {
  98. var img = item.malimg;
  99. var type = (item.type === 'Movie') ? 'movie' : 'show';
  100. var aired = (item.aired.indexOf(', ') !== -1) ? item.aired.split(', ')[1] : item.aired;
  101.  
  102. var ret = {
  103. images: {
  104. poster: img,
  105. fanart: img,
  106. banner: img
  107. },
  108. mal_id: item.MAL,
  109. haru_id: item.id,
  110. tvdb_id: 'mal-' + item.id,
  111. imdb_id: 'mal-' + item.id,
  112. slug: item.name.toLowerCase().replace(/\s/g, '-'),
  113. title: item.name,
  114. year: aired.replace(/ to.*/, ''),
  115. type: type,
  116. item_data: item.type
  117. };
  118. return ret;
  119. });
  120.  
  121. return {
  122. results: Common.sanitize(results),
  123. hasMore: true
  124. };
  125. };
  126.  
  127. // Single element query
  128. var queryTorrent = function (torrent_id, prev_data) {
  129. return Q.Promise(function (resolve, reject) {
  130. var id = torrent_id.split('-')[1];
  131. var url = URL + 'anime.php?id=' + id;
  132.  
  133. win.info('Request to Hurahican API', url);
  134. request({
  135. url: url,
  136. json: true
  137. }, function (error, response, data) {
  138. var err;
  139. if (error || response.statusCode >= 400) {
  140. reject(error);
  141. } else if (!data || (data.error && data.error !== 'No data returned')) {
  142.  
  143. err = data ? data.error : 'No data returned';
  144. win.error('API error:', err);
  145. reject(err);
  146.  
  147. } else if (data.episodes.length === 0) {
  148.  
  149. err = 'No torrents returned';
  150. win.error('API error:', err);
  151. reject(err);
  152.  
  153. } else {
  154.  
  155. // we cache our new element
  156. resolve(formatDetailForPopcorn(data, prev_data));
  157. }
  158. });
  159. });
  160. };
  161.  
  162. var movieTorrents = function (id, dl) {
  163. var torrents = {};
  164. _.each(dl, function (item) {
  165. var qualityMatch = item.quality.match(/[0-9]+p/);
  166. var quality = qualityMatch ? qualityMatch[0] : null;
  167. var qualityNumber = quality.replace('p', '');
  168. if (qualityNumber > 480 && qualityNumber < 1000) {
  169. quality = '720p';
  170. } else if (qualityNumber >= 1000 && qualityNumber < 1800) {
  171. quality = '1080p';
  172. }
  173. torrents[quality] = {
  174. seeds: 0,
  175. peers: 0,
  176. magnet: item.magnet,
  177. health: 'good'
  178. };
  179. });
  180.  
  181. return torrents;
  182. };
  183.  
  184. var showTorrents = function (id, dl) {
  185. var torrents = {};
  186. var episodeNb = null;
  187. _.each(dl, function (item) {
  188. var qualityMatch = item.quality.match(/[0-9]+p/);
  189. var quality = qualityMatch ? qualityMatch[0] : null;
  190. var qualityNumber = quality.replace('p', '');
  191. if (qualityNumber > 200 && qualityNumber < 600) {
  192. quality = '480p';
  193. } else if (qualityNumber >= 600 && qualityNumber < 1000) {
  194. quality = '720p';
  195. } else if (qualityNumber >= 1000 && qualityNumber < 1800) {
  196. quality = '1080p';
  197. }
  198. var episode, tryName;
  199. var match = item.name.match(/[\s_]([0-9]+(-[0-9]+)?|CM|OVA)[\s_]/);
  200. if (!match) {
  201. tryName = item.name.split(/:?(\(|\[)/);
  202. if (tryName.length === 1) {
  203. return;
  204. }
  205. if (torrents[episodeNb] && torrents[episodeNb].title === tryName[0]) {
  206. episode = episodeNb;
  207. } else {
  208. episodeNb++;
  209. episode = episodeNb;
  210. }
  211. } else {
  212. episode = match[1];
  213. }
  214. if (!torrents[episode]) {
  215. torrents[episode] = {
  216. title: match ? item.name : tryName[0],
  217. ordered: match ? true : false
  218. };
  219. }
  220. torrents[episode][quality] = {
  221. seeds: 0,
  222. peers: 0,
  223. url: item.magnet,
  224. health: 'good'
  225. };
  226. });
  227. return _.map(torrents, function (torrents, s) {
  228. return {
  229. title: torrents.ordered ? 'Episode ' + s : torrents.title,
  230. torrents: torrents,
  231. season: 1,
  232. episode: Number(s.split('-')[0]),
  233. overview: i18n.__('We still don\'t have single episode overviews for anime… Sorry'),
  234. tvdb_id: id + '-1-' + s
  235. };
  236. });
  237. };
  238.  
  239. var formatDetailForPopcorn = function (item, prev) {
  240. var img = item.malimg;
  241. var type = prev.type;
  242. var genres = item.genres.split(', ');
  243.  
  244. var ret = _.extend(prev, {
  245. country: i18n.__('Japan'),
  246. genre: genres,
  247. genres: genres,
  248. num_seasons: 1,
  249. runtime: parseTime(item.duration),
  250. status: statusMap[item.status],
  251. synopsis: item.synopsis,
  252. network: item.producers, //FIXME
  253. rating: { // FIXME
  254. hated: 0,
  255. loved: 0,
  256. votes: 0,
  257. percentage: Math.round(item.score) * 10
  258. },
  259. images: {
  260. poster: img,
  261. fanart: img,
  262. banner: img
  263. },
  264. year: item.aired.split(', ')[1].replace(/ to.*/, ''),
  265. type: type
  266. });
  267.  
  268. if (type === 'movie') {
  269. ret = _.extend(ret, {
  270. cover: img,
  271. rating: item.score,
  272. subtitle: undefined,
  273. torrents: movieTorrents(item.id, item.episodes),
  274. });
  275. } else {
  276. ret = _.extend(ret, {
  277. episodes: showTorrents(item.id, item.episodes)
  278. });
  279. }
  280.  
  281. return Common.sanitize(ret);
  282. };
  283.  
  284. Haruhichan.prototype.extractIds = function (items) {
  285. return _.pluck(items.results, 'haru_id');
  286. };
  287.  
  288. Haruhichan.prototype.fetch = function (filters) {
  289. return queryTorrents(filters)
  290. .then(formatForPopcorn);
  291. };
  292.  
  293. Haruhichan.prototype.detail = function (torrent_id, prev_data) {
  294. return queryTorrent(torrent_id, prev_data);
  295. };
  296.  
  297. App.Providers.Haruhichan = Haruhichan;
  298.  
  299. })(window.App);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement