// ==UserScript==
// @name 1024社区收藏夹
// @namespace http://tampermonkey.net/
// @version 1.43
// @description 为社区帖子添加一个本地收藏夹,支持导入导出功能。支持图片批量下载。该插件在手机端几乎可以用网页替代社区客户端。支持手机和电脑浏览器Tampermonkey、暴力猴。
// @author niuhe
// @include http://*/htm_data/*
// @match https://*/htm_data/*
// @match http://*/htm_mob/*
// @match https://*/htm_mob/*
// @match http://*/profile.php?action=favor
// @match https://*/profile.php?action=favor
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_listValues
// @grant GM_setClipboard
// @grant GM_download
// @grant GM_deleteValue
// @grant GM_info
// @license MIT
// ==/UserScript==
//为了和手机格式统一,url一律以http://**/htm_mob/格式保存
const DAT_EVENT_IMPORT = "dat_import";
const DAT_EVENT_RECORD = "dat_record";
const DAT_EVENT_STATUS = "dat_status";
const SEP_TAG = "<:separator;>"
var url_base = "http://**/htm_mob/"
var url = document.URL
var url_array = document.URL.split("/")
//CSS选择器
var biaoti_selector = ""
var bankuai_selector = ""
var image_selector = ""
var tag_loc = ""
//UA是否是手机端
var mobile = IsMob()
//用几个标识符来判断页面是收藏页/主题帖(手机)/主题帖(PC)
var is_collection_page = (document.URL.split("/").pop() == "profile.php?action=favor")
var is_htm_mob = (url_array[3] == "htm_mob")
var is_htm_data = (url_array[3] == "htm_data")
url_array[2] = "**"
url_array[3] = "htm_mob"
url = url_array.join("/")
var time1 = TimeFormat();
var biaoti = ""
var bankuai = ""
//获取主题帖标题和板块信息
if (is_collection_page == false)
{
console.log("I am getting bankuai info")
if (is_htm_mob)
{
biaoti_selector = "#main > div.f18"
bankuai_selector = "#header > table > tbody > tr > td > h3"
tag_loc = "h guide"
}
if (is_htm_data)
{
biaoti_selector = "#main > div:nth-child(4) > table > tbody > tr.tr1.do_not_catch > th:nth-child(2) > table > tbody > tr > td > h4"
bankuai_selector = "#main > div:nth-child(1) > table > tbody > tr:nth-child(1) > td > b > a:nth-child(2)"
tag_loc = 'tiptop'
}
biaoti = document.querySelector(biaoti_selector).textContent
if (is_htm_mob)
{
var a = document.querySelector(biaoti_selector).innerText
biaoti = a.substr(0,a.length-4)
}
bankuai = document.querySelector(bankuai_selector).textContent
console.log("biaoti" + biaoti)
}
var key = url_array.slice(4,7).join("/")
var content = biaoti + " " + bankuai + SEP_TAG + url + SEP_TAG + time1
//console.log(content)
document.addEventListener(DAT_EVENT_IMPORT, function (e) {
//Custom event after CSV import
alert("导入成功,刷新页面查看")
});
document.addEventListener(DAT_EVENT_STATUS, function (e) {
// Custom event on set status
alert("导入成功,已和本地收藏合并");
});
//默认设置cookie的path是根目录
function setCookie ( name, value, expdays, path="/" )
{
var expdate = new Date();
//设置Cookie过期日期
expdate.setDate(expdate.getDate() + expdays) ;
//添加Cookie
document.cookie = name + "=" + escape(value) + ";expires=" + expdate.toUTCString() + ";path=" + path;
console.log("set cookie success")
}
function getCookieValue(name) {
let result = document.cookie.match("(^|[^;]+)\\s*" + name + "\\s*=\\s*([^;]+)")
return result ? result.pop() : ""
}
//清除所有cookie函数
function clearAllCookie() {
var keys = document.cookie.match(/[^ =;]+(?=\=)/g);
if (keys) {
for (var i = keys.length; i--;)
document.cookie = keys[i] + '=0;expires=' + new Date(0).toUTCString()
}
}
function IsMob() {
var userAgentInfo = navigator.userAgent;
var Agents = ["Android", "iPhone",
"SymbianOS", "Windows Phone",
"iPad", "iPod"];
var flag = false;
for (var v = 0; v < Agents.length; v++) {
if (userAgentInfo.indexOf(Agents[v]) > 0) {
flag = true;
break;
}
}
return flag;
}
//手机和PC自适应,并重定向页面
function Set_Cookie()
{
if (mobile)
{
let is_mob= getCookieValue("ismob")
if (is_mob != "1")
{
setCookie("ismob","1",360)
console.log(" Mob cookie changed")
}
else
{
console.log(" Mob cookie not changed")
}
}
else
{
let is_mob= getCookieValue("ismob")
if (is_mob == "1")
{
setCookie("ismob","0",360)
console.log(" PC cookie changed,Redirect Page")
}
else
{
console.log(" PC cookie not changed")
}
}
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function TimeFormat() {
var fmt = "yyyy-MM-dd hh:mm:ss"
var myDate = new Date();
var o = {
"M+": myDate.getMonth() + 1, //月份
"d+": myDate.getDate(), //日
"h+": myDate.getHours(), //小时
"m+": myDate.getMinutes(), //分
"s+": myDate.getSeconds(), //秒
"q+": Math.floor((myDate.getMonth() + 3) / 3), //季度
"S": myDate.getMilliseconds() //毫秒
};
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (myDate.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o)
{
if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
}
return fmt;
}
function Collecte(){
if (mobile == true)
{
var tmp = document.createElement("text")
tmp.textContent = "|"
document.getElementsByClassName(tag_loc)[0].appendChild(tmp)
}
var a = document.createElement('a');
//a.href = 'data:application/dat;charset=utf-8,' + encodeURIComponent(data);
//supported by chrome 14+ and firefox 20+
//a.download = 'favorite.dat';
if ("none" == GM_getValue(key,"none"))
{
a.text = " 收藏 "
a.style = "color:#2F5FA1;"
}
else
{
a.text = " 已收藏 "
a.style = "color:#FF0000;"
}
document.getElementsByClassName(tag_loc)[0].appendChild(a);
a.addEventListener("click", function (value) {
if (a.text == " 收藏 ")
{
GM_setValue(key,content);
a.text = " 已收藏 "
a.style = "color:#FF0000;"
}
else
{
GM_deleteValue(key);
a.text = " 收藏 "
a.style = "color:#2F5FA1;"
}
//alert("添加收藏成功\n\n" + content)
});
}
function Export_Collection(data){
if (mobile == true)
{
var tmp = document.createElement("text")
tmp.textContent = "|"
document.getElementsByClassName(tag_loc)[0].appendChild(tmp)
}
var keys = GM_listValues()
var a = document.createElement('a');
//supported by chrome 14+ and firefox 20+
a.download = 'favorite.dat';
a.text = " 導出 "
//needed for firefox
document.getElementsByClassName(tag_loc)[0].appendChild(a);
a.addEventListener("click", function (value) {
var keys = GM_listValues()
var data = []
for(var i = 0, len = keys.length; i < len; i++){
data.push(GM_getValue(keys[i]))
}
data = data.join("\n")
a.href = 'data:application/dat;charset=utf-8,' + encodeURIComponent(data);
alert("导出成功")
});
}
function Gen_Input()
{
let input = document.createElement("input");
input.type = "file";
input.accept=".dat"
Object.assign(input.style, {
position: "relative"
});
input.addEventListener("input", function (value) {
let reader = new FileReader();
reader.readAsText(value.target.files[0]);
reader.onload = function () {
var dat_array = reader.result.split("\n")
for (var k = 0 ,len2 = dat_array.length; k < len2;k++)
{
GM_setValue(Gen_Key(dat_array[k]),dat_array[k])
}
document.dispatchEvent(new Event(DAT_EVENT_IMPORT))
};
});
return input
}
function Import_Collection(){
if (mobile == true)
{
var tmp = document.createElement("text")
tmp.textContent = "|"
document.getElementsByClassName(tag_loc)[0].appendChild(tmp)
}
var a = document.createElement('a');
//supported by chrome 14+ and firefox 20+
a.download = 'favorite.dat';
a.text = " 導入 "
//needed for firefox
document.getElementsByClassName(tag_loc)[0].appendChild(a);
var input = Gen_Input()
document.getElementsByClassName(tag_loc)[0].appendChild(input);
}
async function downloader(image_urls) {
console.log('start downloading');
// Sleep in loop
for(var img = 1, length1 = image_urls.length; img <= length1; img++){
var extension = image_urls[img-1].split(".").pop()
GM_download(image_urls[img-1], biaoti + "[" + img + "]." + extension)
console.log("Download Image" + img)
await sleep(2000)
}
await sleep(2000);
}
function Download_Pics()
{
if (mobile == true)
{
var tmp = document.createElement("text")
tmp.textContent = "|"
document.getElementsByClassName(tag_loc)[0].appendChild(tmp)
}
var a = document.createElement('a');
//supported by chrome 14+ and firefox 20+
a.text = " 下載 "
//needed for firefox
document.getElementsByClassName(tag_loc)[0].appendChild(a);
a.addEventListener("click", async function (value) {
var images = null
var image_urls = []
if (mobile == true)
{
images = document.querySelector(".tpc_cont").getElementsByTagName("img")
}
else
{
images = document.querySelector(".tpc_content").getElementsByTagName("img")
}
for(var i = 0, len = images.length; i < len; i++){
image_urls.push(images[i].src)
}
var result = image_urls.join("\n")
GM_setClipboard(result)
var info = confirm("已复制" + image_urls.length + "张图片链接到粘贴板,现在下载吗?")
if (info == true)
{
await downloader(image_urls)
}
});
}
function Gen_Key(value)
{
var url = value.split("<:separator;>")[1]
var url_array = url.split("/")
var key = url_array.slice(4,7).join("/")
return key
}
function Gen_Node(index,key,row_base,value) //
{
var tmp = value.split("<:separator;>")
var time = tmp[2]
var tmp_url = tmp[1]
tmp_url = tmp_url.replace(/\*\*/, document.URL.split("/")[2])
tmp_url = tmp_url.replace(/htm_mob/, "htm_data")
var tmp_str = tmp[0].split(" ")
var tmp_bankuai = tmp_str.pop()
var tmp_biaoti = tmp_str.join(" ")
var tmp_node = row_base.cloneNode(true)
tmp_node.className = "tr3"
tmp_node.children[0].innerText = index
tmp_node.children[1].innerText = tmp_biaoti
tmp_node.children[1].setAttribute("onclick","window.open('" + tmp_url + "');")
tmp_node.children[2].innerText = tmp_bankuai
tmp_node.children[3].innerText = time
tmp_node.children[4].innerText = "删除"
tmp_node.children[4].setAttribute("index",index)
tmp_node.children[4].setAttribute("align","center")
tmp_node.children[4].onclick = function()
{
if (tmp_node.children[4].innerText == "删除")
{
tmp_node.remove()
GM_deleteValue(key);
}
};
return tmp_node
}
//Gen node for mobile
function Gen_Mob_Node(index,key,row_base,value) //
{
var tmp = value.split("<:separator;>")
var time = tmp[2]
var tmp_url = tmp[1]
tmp_url = tmp_url.replace(/\*\*/, document.URL.split("/")[2])
tmp_url = tmp_url.replace(/htm_data/, "htm_mob")
var tmp_str = tmp[0].split(" ")
var tmp_bankuai = tmp_str.pop()
var tmp_biaoti = tmp_str.join(" ")
var tmp_node = row_base.cloneNode(true)
tmp_node.className = "tr3 tac"
tmp_node.children[0].innerText = tmp_biaoti
tmp_node.children[0].setAttribute("onclick","window.open('" + tmp_url + "');")
tmp_node.children[1].innerText = "删除"
tmp_node.children[1].setAttribute("index",index)
tmp_node.children[1].setAttribute("align","center")
tmp_node.children[1].onclick = function()
{
if (tmp_node.children[1].innerText == "删除")
{
GM_deleteValue(key);
tmp_node.children[1].innerText = "已删除"
}
};
return tmp_node
}
//time key
function extract_key_list()
{
var keys = GM_listValues()
var result = []
var tmps = []
for (var i=0 ,len1 = keys.length; i < len1; i++)
{
var tmp = []
var bar = GM_getValue(keys[i])
if (bar)
{
//time
tmp.push(bar.split("<:separator;>").pop())
}
tmp.push(keys[i])
tmps.push(tmp)
}
tmps.sort(function (a,b){return Date.parse(a[0]) < Date.parse(b[0]) ? 1 : -1;})
console.log(tmps)
for (var j=0 ,len2 = tmps.length; j < len2; j++)
{
result.push(tmps[j][1])
}
return result
}
function PC_Check_Collection()
{
console.log("打开收藏夹")
try
{
var father = document.getElementsByClassName("t")[2].getElementsByTagName("tr")
}
catch (err)
{
alert("需要登录才能查看/编辑收藏夹\n\n未登录状态只能进行添加/导入/导出操作\n\n收藏内容保存在本地,卸载脚本会丢失收藏夹,请及时导出备份!")
}
if (father.length > 2 )
{
for (var i= 2 ,len = father.length; i < len;i++)
{
father[i].remove()
}
}
father[1].getElementsByTagName("td")[3].innerText = "時間"
father[1].getElementsByTagName("td")[4].innerText = "操作"
document.querySelector("#main > div:nth-child(3) > table > tbody > tr > td:nth-child(2) > form > center").remove()
var row_base = father[1]
var keys = extract_key_list()
for(var j = 0, len1 = keys.length; j < len1; j++){
var tmp_node = Gen_Node(j+1,keys[j] ,row_base, GM_getValue(keys[j]))
father[1].parentElement.append(tmp_node)
}
var upload_entry = document.querySelector("#main > div:nth-child(3) > table > tbody > tr > td:nth-child(1) > form > div > table > tbody > tr:nth-child(4) > th")
upload_entry.innerText = " 導入 "
var input = Gen_Input()
upload_entry.appendChild(input)
}
function Mob_Check_Collection()
{
console.log("打开收藏夹")
try
{
document.querySelector("#main > div:nth-child(3) > table > tbody > tr:nth-child(2) > td > form > center").remove()
var father = document.getElementsByClassName("t")[2].getElementsByTagName("tr")
}
catch (err)
{
alert("需要登录才能查看/编辑收藏夹\n\n未登录状态只能进行添加/导入/导出操作\n\n收藏内容保存在本地,卸载脚本会丢失收藏夹,请及时导出备份!")
}
if (father.length > 1 )
{
for (var i= 1 ,len = father.length; i < len;i++)
{
father[i].remove()
}
}
father[0].children[1].width = "15%"
father[0].children[1].innerText = "操作"
father[0].children[1].innerText.align="right"
var row_base = father[0]
var keys = extract_key_list()
for(var j = 0, len1 = keys.length; j < len1; j++){
var tmp_node = Gen_Mob_Node(j+1,keys[j] ,row_base, GM_getValue(keys[j]))
father[0].parentElement.append(tmp_node)
}
document.getElementsByClassName("tr1")[0].parentNode.remove()
var upload_entry = document.getElementsByClassName("tr1")[0].children[0]
upload_entry.innerText = "導入 "
var input = Gen_Input()
upload_entry.appendChild(input)
}
(function() {
'use strict';
Set_Cookie()
if (is_collection_page == false)
{
Collecte()
if (bankuai == "新時代的我們" || bankuai == "達蓋爾的旗幟")
{
Download_Pics()
}
Export_Collection()
Import_Collection()
//Import_Collection()
}
else
{
if (mobile )
{
Mob_Check_Collection()
}
else
{
PC_Check_Collection()
}
}
})();