<commit_before>// ==UserScript==
// @name            TruyenYY downloader
// @name:vi         TruyenYY downloader
// @namespace       http://devs.forumvi.com/
// @description     Tải truyện từ TruyenYY định dạng EPUB.
// @description:vi  Tải truyện từ TruyenYY định dạng EPUB.
// @version         4.8.0
// @icon            https://i.imgur.com/1HkQv2b.png
// @author          Zzbaivong
// @oujs:author     baivong
// @license         MIT; https://baivong.mit-license.org/license.txt
// @match           https://truyenyy.com/truyen/*/
// @match           https://truyenyy.vn/truyen/*/
// @require         https://code.jquery.com/jquery-3.5.1.min.js
// @require         https://unpkg.com/jszip@3.1.5/dist/jszip.min.js
// @require         https://unpkg.com/file-saver@2.0.2/dist/FileSaver.min.js
// @require         https://unpkg.com/ejs@2.7.4/ejs.min.js
// @require         https://unpkg.com/jepub@2.1.4/dist/jepub.min.js
// @require         https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js?v=a834d46
// @noframes
// @connect         vnvl.net
// @supportURL      https://github.com/lelinhtinh/Userscript/issues
// @run-at          document-end
// @grant           GM_xmlhttpRequest
// @grant           GM.xmlHttpRequest
// ==/UserScript==

(function ($, window, document) {
  'use strict';

  /**
   * Nhận cảnh báo khi có chương bị lỗi
   */
  var errorAlert = true;

  /**
   * Những đoạn ghi chú nguồn truyện
   * Toàn bộ nội dung ghi chú, có phân biệt hoa thường
   * Ngăn cách các đoạn bằng dấu |
   */
  var citeSources =
    'Text được lấy tại truyenyy[.c]om|truyện được lấy tại t.r.u.y.ệ.n.y-y|Đọc Truyện Online mới nhất ở truyen/y/y/com|Truyện được copy tại TruyệnYY.com|nguồn t r u y ệ n y_y|Bạn đang xem truyện được sao chép tại: t.r.u.y.e.n.y.y chấm c.o.m|Nguồn tại http://truyenyy[.c]om|xem tại tr.u.y.ệ.n.yy|Bạn đang đọc chuyện tại Truyện.YY';

  citeSources = citeSources.split('|');

  function cleanHtml(str) {
    citeSources.forEach(function (source) {
      if (str.indexOf(source) !== -1) {
        str = str.replace(source, '');
        return false;
      }
    });
    str = str.replace(/[^\x09\x0A\x0D\x20-\uD7FF\uE000-\uFFFD\u10000-\u10FFFF]+/gm, ''); // eslint-disable-line
    return str;
  }

  function downloadError(mess, err) {
    downloadStatus('danger');
    if (err) console.error(mess);
    if (!chapTitle) return;

    titleError.push(chapTitle);
    if (errorAlert) errorAlert = confirm('Lỗi! ' + mess + '\nBạn có muốn tiếp tục nhận cảnh báo?');

    return '<p class="no-indent"><a href="' + referrer + chapId + '">' + mess + '</a></p>';
  }

  function downloadVip($chapter) {
    var parts = $chapter.find('#vip-content-placeholder').siblings('script').first().text(),
      vipContent = '';

    parts = parts.match(/\/web-api\/novel\/chapter-content-get\/\?chap_id=\w+&part=\d+/g);
    if (!parts.length) return downloadError('Lỗi tải chương VIP');

    return new Promise(function (resolve, reject) {
      (function getVipContent() {
        if (!parts.length) {
          resolve(vipContent);
          return;
        }

        var partUrl = parts.shift();
        $.getJSON(partUrl)
          .done(function (data) {
            if (!data.ok) {
              reject(downloadError('Lỗi lấy nội dung chương VIP'));
              return;
            }

            var $content = $(data.content);
            $content.find('style, [style]').remove();
            $content.each(function (i, v) {
              vipContent += '<p>' + v.textContent + '</p>';
            });

            getVipContent();
          })
          .fail(function (err) {
            reject(downloadError('Lỗi kết nối chương VIP', err));
          });
      })();
    });
  }

  function genEbook() {
    jepub
      .generate('blob', function (metadata) {
        $download.html(
          '<i class="iconfont icon-book"></i> Đang nén <strong>' + metadata.percent.toFixed(2) + '%</strong>'
        );
      })
      .then(function (epubZipContent) {
        document.title = '[⇓] ' + ebookTitle;
        $win.off('beforeunload');

        $download
          .attr({
            href: window.URL.createObjectURL(epubZipContent),
            download: ebookFilename,
          })
          .html('<i class="iconfont icon-save"></i> Hoàn thành')
          .off('click');
        if (!$download.hasClass('btn-danger')) downloadStatus('success');

        saveAs(epubZipContent, ebookFilename);
      })
      .catch(function (err) {
        downloadStatus('danger');
        console.error(err);
      });
  }

  function saveEbook() {
    if (endDownload) return;
    endDownload = true;
    $download.html('<i class="iconfont icon-layer"></i> Bắt đầu tạo EPUB');

    if (titleError.length) {
      titleError = '<p class="no-indent"><strong>Các chương lỗi: </strong>' + titleError.join(', ') + '</p>';
    } else {
      titleError = '';
    }
    beginEnd = '<p class="no-indent">Nội dung từ <strong>' + begin + '</strong> đến <strong>' + end + '</strong></p>';

    jepub.notes(beginEnd + titleError + '<br /><br />' + credits);

    GM.xmlHttpRequest({
      method: 'GET',
      url: ebookCover,
      responseType: 'arraybuffer',
      onload: function (response) {
        try {
          jepub.cover(response.response);
        } catch (err) {
          console.error(err);
        }
        genEbook();
      },
      onerror: function (err) {
        console.error(err);
        genEbook();
      },
    });
  }

  function getContent(pageId) {
    if (endDownload) return;
    chapId = pageId;

    $.get(pathname + chapId)
      .done(function (response) {
        var $data = $(response),
          $chapter = $data.find('#id_chap_content'),
          $notContent = $chapter.find('iframe, script, style, a'),
          $referrer = $chapter.find('[style]').filter(function () {
            return this.style.fontSize === '1px' || this.style.fontSize === '0px' || this.style.color === 'white';
          }),
          chapContent,
          $next = $data.find('.buttons .btn-primary');

        if (endDownload) return;

        chapTitle = $data.find('h1.chapter-title').text().trim();
        if (chapTitle === '') chapTitle = 'Chương ' + chapId.match(/\d+/)[0];

        if (!$chapter.length) {
          chapContent = downloadError('Không có nội dung');
        } else {
          if ($chapter.find('#btn_buy').length) {
            chapContent = downloadError('Chương VIP');
          } else if ($chapter.find('a[href="/register/"]').length) {
            chapContent = downloadError('Chương yêu cầu đăng nhập');
          } else if ($chapter.find('#vip-content-placeholder').length) {
            downloadVip($chapter).then(function (chapContent) {
              handle(cleanHtml(chapContent), $next);
            });
            return;<commit_msg>Refactor downloadVip function<commit_after>// ==UserScript==
// @name            TruyenYY downloader
// @name:vi         TruyenYY downloader
// @namespace       http://devs.forumvi.com/
// @description     Tải truyện từ TruyenYY định dạng EPUB.
// @description:vi  Tải truyện từ TruyenYY định dạng EPUB.
// @version         4.8.1
// @icon            https://i.imgur.com/1HkQv2b.png
// @author          Zzbaivong
// @oujs:author     baivong
// @license         MIT; https://baivong.mit-license.org/license.txt
// @match           https://truyenyy.com/truyen/*/
// @match           https://truyenyy.vn/truyen/*/
// @require         https://code.jquery.com/jquery-3.5.1.min.js
// @require         https://unpkg.com/jszip@3.1.5/dist/jszip.min.js
// @require         https://unpkg.com/file-saver@2.0.2/dist/FileSaver.min.js
// @require         https://unpkg.com/ejs@2.7.4/ejs.min.js
// @require         https://unpkg.com/jepub@2.1.4/dist/jepub.min.js
// @require         https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js?v=a834d46
// @noframes
// @connect         vnvl.net
// @supportURL      https://github.com/lelinhtinh/Userscript/issues
// @run-at          document-end
// @grant           GM_xmlhttpRequest
// @grant           GM.xmlHttpRequest
// ==/UserScript==

(function ($, window, document) {
  'use strict';

  /**
   * Nhận cảnh báo khi có chương bị lỗi
   */
  var errorAlert = true;

  /**
   * Những đoạn ghi chú nguồn truyện
   * Toàn bộ nội dung ghi chú, có phân biệt hoa thường
   * Ngăn cách các đoạn bằng dấu |
   */
  var citeSources =
    'Text được lấy tại truyenyy[.c]om|truyện được lấy tại t.r.u.y.ệ.n.y-y|Đọc Truyện Online mới nhất ở truyen/y/y/com|Truyện được copy tại TruyệnYY.com|nguồn t r u y ệ n y_y|Bạn đang xem truyện được sao chép tại: t.r.u.y.e.n.y.y chấm c.o.m|Nguồn tại http://truyenyy[.c]om|xem tại tr.u.y.ệ.n.yy|Bạn đang đọc chuyện tại Truyện.YY';

  citeSources = citeSources.split('|');

  function cleanHtml(str) {
    citeSources.forEach(function (source) {
      if (str.indexOf(source) !== -1) {
        str = str.replace(source, '');
        return false;
      }
    });
    str = str.replace(/[^\x09\x0A\x0D\x20-\uD7FF\uE000-\uFFFD\u10000-\u10FFFF]+/gm, ''); // eslint-disable-line
    return str;
  }

  function downloadError(mess, err) {
    downloadStatus('danger');
    if (err) console.error(mess);
    if (!chapTitle) return;

    titleError.push(chapTitle);
    if (errorAlert) errorAlert = confirm('Lỗi! ' + mess + '\nBạn có muốn tiếp tục nhận cảnh báo?');

    return '<p class="no-indent"><a href="' + referrer + chapId + '">' + mess + '</a></p>';
  }

  function downloadVip($chapter) {
    var parts = $chapter.find('#vip-content-placeholder').siblings('script').first().text();
    parts = parts.match(/\/web-api\/novel\/chapter-content-get\/\?chap_id=\w+&part=\d+/g);

    return new Promise(function (resolve, reject) {
      if (!parts.length) {
        reject('Lỗi truy vấn chương VIP');
        return;
      }

      var vipContent = '';
      (function getVipContent() {
        if (!parts.length) {
          resolve(vipContent);
          return;
        }

        var partUrl = parts.shift();
        $.getJSON(partUrl)
          .done(function (data) {
            if (!data.ok) {
              reject('Lỗi lấy nội dung chương VIP');
              return;
            }

            var $content = $(data.content);
            $content.find('style, [style]').remove();
            $content.each(function (i, v) {
              vipContent += '<p>' + v.textContent + '</p>';
            });

            getVipContent();
          })
          .fail(function () {
            reject('Lỗi kết nối chương VIP');
          });
      })();
    });
  }

  function genEbook() {
    jepub
      .generate('blob', function (metadata) {
        $download.html(
          '<i class="iconfont icon-book"></i> Đang nén <strong>' + metadata.percent.toFixed(2) + '%</strong>'
        );
      })
      .then(function (epubZipContent) {
        document.title = '[⇓] ' + ebookTitle;
        $win.off('beforeunload');

        $download
          .attr({
            href: window.URL.createObjectURL(epubZipContent),
            download: ebookFilename,
          })
          .html('<i class="iconfont icon-save"></i> Hoàn thành')
          .off('click');
        if (!$download.hasClass('btn-danger')) downloadStatus('success');

        saveAs(epubZipContent, ebookFilename);
      })
      .catch(function (err) {
        downloadStatus('danger');
        console.error(err);
      });
  }

  function saveEbook() {
    if (endDownload) return;
    endDownload = true;
    $download.html('<i class="iconfont icon-layer"></i> Bắt đầu tạo EPUB');

    if (titleError.length) {
      titleError = '<p class="no-indent"><strong>Các chương lỗi: </strong>' + titleError.join(', ') + '</p>';
    } else {
      titleError = '';
    }
    beginEnd = '<p class="no-indent">Nội dung từ <strong>' + begin + '</strong> đến <strong>' + end + '</strong></p>';

    jepub.notes(beginEnd + titleError + '<br /><br />' + credits);

    GM.xmlHttpRequest({
      method: 'GET',
      url: ebookCover,
      responseType: 'arraybuffer',
      onload: function (response) {
        try {
          jepub.cover(response.response);
        } catch (err) {
          console.error(err);
        }
        genEbook();
      },
      onerror: function (err) {
        console.error(err);
        genEbook();
      },
    });
  }

  function getContent(pageId) {
    if (endDownload) return;
    chapId = pageId;

    $.get(pathname + chapId)
      .done(function (response) {
        var $data = $(response),
          $chapter = $data.find('#id_chap_content'),
          $notContent = $chapter.find('iframe, script, style, a'),
          $referrer = $chapter.find('[style]').filter(function () {
            return this.style.fontSize === '1px' || this.style.fontSize === '0px' || this.style.color === 'white';
          }),
          chapContent,
          $next = $data.find('.buttons .btn-primary');

        if (endDownload) return;

        chapTitle = $data.find('h1.chapter-title').text().trim();
        if (chapTitle === '') chapTitle = 'Chương ' + chapId.match(/\d+/)[0];

        if (!$chapter.length) {
          chapContent = downloadError('Không có nội dung');
        } else {
          if ($chapter.find('#btn_buy').length) {
            chapContent = downloadError('Chương VIP');
          } else if ($chapter.find('a[href="/register/"]').length) {
            chapContent = downloadError('Chương yêu cầu đăng nhập');
          } else if ($chapter.find('#vip-content-placeholder').length) {
            downloadVip($chapter)
              .then(function (chapContent) {
                handle(cleanHtml(chapContent), $next);
              })
              .catch(function (err) {
                handle(downloadError(err));
              });
            return;
{'fraction_non_alphanumeric': 0.16842872767043382, 'fraction_numerical': 0.007291286912139993, 'mean_word_length': 2.126510143606109, 'pattern_counts': {'":': 0, '<': 55, '<?xml version=': 0, '>': 55, 'https://': 22, 'lorem ipsum': 0, 'www.': 0, 'xml': 6}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 45, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2394823', 'n_tokens_mistral': 5008, 'n_tokens_neox': 4894, 'n_words': 891}