diff --git a/package/ctcgfw/luci-app-jd-dailybonus/Makefile b/package/ctcgfw/luci-app-jd-dailybonus/Makefile index b8a76bbd41..406342eeed 100644 --- a/package/ctcgfw/luci-app-jd-dailybonus/Makefile +++ b/package/ctcgfw/luci-app-jd-dailybonus/Makefile @@ -8,12 +8,13 @@ include $(TOPDIR)/rules.mk LUCI_TITLE:=Luci for JD dailybonus Script -LUCI_DEPENDS:=+node +node-request +coreutils +coreutils-nohup +wget +LUCI_DEPENDS:=+coreutils +coreutils-nohup +node +node-request \ + +lua +luasocket +lua-cjson +lua-md5 +luasec +wget-ssl LUCI_PKGARCH:=all PKG_NAME:=luci-app-jd-dailybonus -PKG_VERSION:=0.8.9 -PKG_RELEASE:=20201230 +PKG_VERSION:=1.0.1 +PKG_RELEASE:=20210123 include $(TOPDIR)/feeds/luci/luci.mk diff --git a/package/ctcgfw/luci-app-jd-dailybonus/htdocs/jd-dailybonus/JDCookie.zip b/package/ctcgfw/luci-app-jd-dailybonus/htdocs/jd-dailybonus/JDCookie.zip deleted file mode 100644 index 54bcf0cd5c..0000000000 Binary files a/package/ctcgfw/luci-app-jd-dailybonus/htdocs/jd-dailybonus/JDCookie.zip and /dev/null differ diff --git a/package/ctcgfw/luci-app-jd-dailybonus/htdocs/jd-dailybonus/qrcode.min.js b/package/ctcgfw/luci-app-jd-dailybonus/htdocs/jd-dailybonus/qrcode.min.js new file mode 100644 index 0000000000..993e88f396 --- /dev/null +++ b/package/ctcgfw/luci-app-jd-dailybonus/htdocs/jd-dailybonus/qrcode.min.js @@ -0,0 +1 @@ +var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this.parsedData=[];for(var b=[],d=0,e=this.data.length;e>d;d++){var f=this.data.charCodeAt(d);f>65536?(b[0]=240|(1835008&f)>>>18,b[1]=128|(258048&f)>>>12,b[2]=128|(4032&f)>>>6,b[3]=128|63&f):f>2048?(b[0]=224|(61440&f)>>>12,b[1]=128|(4032&f)>>>6,b[2]=128|63&f):f>128?(b[0]=192|(1984&f)>>>6,b[1]=128|63&f):b[0]=f,this.parsedData=this.parsedData.concat(b)}this.parsedData.length!=this.data.length&&(this.parsedData.unshift(191),this.parsedData.unshift(187),this.parsedData.unshift(239))}function b(a,b){this.typeNumber=a,this.errorCorrectLevel=b,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=[]}function i(a,b){if(void 0==a.length)throw new Error(a.length+"/"+b);for(var c=0;c=f;f++){var h=0;switch(b){case d.L:h=l[f][0];break;case d.M:h=l[f][1];break;case d.Q:h=l[f][2];break;case d.H:h=l[f][3]}if(h>=e)break;c++}if(c>l.length)throw new Error("Too long data");return c}function s(a){var b=encodeURI(a).toString().replace(/\%[0-9a-fA-F]{2}/g,"a");return b.length+(b.length!=a?3:0)}a.prototype={getLength:function(){return this.parsedData.length},write:function(a){for(var b=0,c=this.parsedData.length;c>b;b++)a.put(this.parsedData[b],8)}},b.prototype={addData:function(b){var c=new a(b);this.dataList.push(c),this.dataCache=null},isDark:function(a,b){if(0>a||this.moduleCount<=a||0>b||this.moduleCount<=b)throw new Error(a+","+b);return this.modules[a][b]},getModuleCount:function(){return this.moduleCount},make:function(){this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(a,c){this.moduleCount=4*this.typeNumber+17,this.modules=new Array(this.moduleCount);for(var d=0;d=7&&this.setupTypeNumber(a),null==this.dataCache&&(this.dataCache=b.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,c)},setupPositionProbePattern:function(a,b){for(var c=-1;7>=c;c++)if(!(-1>=a+c||this.moduleCount<=a+c))for(var d=-1;7>=d;d++)-1>=b+d||this.moduleCount<=b+d||(this.modules[a+c][b+d]=c>=0&&6>=c&&(0==d||6==d)||d>=0&&6>=d&&(0==c||6==c)||c>=2&&4>=c&&d>=2&&4>=d?!0:!1)},getBestMaskPattern:function(){for(var a=0,b=0,c=0;8>c;c++){this.makeImpl(!0,c);var d=f.getLostPoint(this);(0==c||a>d)&&(a=d,b=c)}return b},createMovieClip:function(a,b,c){var d=a.createEmptyMovieClip(b,c),e=1;this.make();for(var f=0;f=g;g++)for(var h=-2;2>=h;h++)this.modules[d+g][e+h]=-2==g||2==g||-2==h||2==h||0==g&&0==h?!0:!1}},setupTypeNumber:function(a){for(var b=f.getBCHTypeNumber(this.typeNumber),c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[Math.floor(c/3)][c%3+this.moduleCount-8-3]=d}for(var c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[c%3+this.moduleCount-8-3][Math.floor(c/3)]=d}},setupTypeInfo:function(a,b){for(var c=this.errorCorrectLevel<<3|b,d=f.getBCHTypeInfo(c),e=0;15>e;e++){var g=!a&&1==(1&d>>e);6>e?this.modules[e][8]=g:8>e?this.modules[e+1][8]=g:this.modules[this.moduleCount-15+e][8]=g}for(var e=0;15>e;e++){var g=!a&&1==(1&d>>e);8>e?this.modules[8][this.moduleCount-e-1]=g:9>e?this.modules[8][15-e-1+1]=g:this.modules[8][15-e-1]=g}this.modules[this.moduleCount-8][8]=!a},mapData:function(a,b){for(var c=-1,d=this.moduleCount-1,e=7,g=0,h=this.moduleCount-1;h>0;h-=2)for(6==h&&h--;;){for(var i=0;2>i;i++)if(null==this.modules[d][h-i]){var j=!1;g>>e));var k=f.getMask(b,d,h-i);k&&(j=!j),this.modules[d][h-i]=j,e--,-1==e&&(g++,e=7)}if(d+=c,0>d||this.moduleCount<=d){d-=c,c=-c;break}}}},b.PAD0=236,b.PAD1=17,b.createData=function(a,c,d){for(var e=j.getRSBlocks(a,c),g=new k,h=0;h8*l)throw new Error("code length overflow. ("+g.getLengthInBits()+">"+8*l+")");for(g.getLengthInBits()+4<=8*l&&g.put(0,4);0!=g.getLengthInBits()%8;)g.putBit(!1);for(;;){if(g.getLengthInBits()>=8*l)break;if(g.put(b.PAD0,8),g.getLengthInBits()>=8*l)break;g.put(b.PAD1,8)}return b.createBytes(g,e)},b.createBytes=function(a,b){for(var c=0,d=0,e=0,g=new Array(b.length),h=new Array(b.length),j=0;j=0?p.get(q):0}}for(var r=0,m=0;mm;m++)for(var j=0;jm;m++)for(var j=0;j=0;)b^=f.G15<=0;)b^=f.G18<>>=1;return b},getPatternPosition:function(a){return f.PATTERN_POSITION_TABLE[a-1]},getMask:function(a,b,c){switch(a){case e.PATTERN000:return 0==(b+c)%2;case e.PATTERN001:return 0==b%2;case e.PATTERN010:return 0==c%3;case e.PATTERN011:return 0==(b+c)%3;case e.PATTERN100:return 0==(Math.floor(b/2)+Math.floor(c/3))%2;case e.PATTERN101:return 0==b*c%2+b*c%3;case e.PATTERN110:return 0==(b*c%2+b*c%3)%2;case e.PATTERN111:return 0==(b*c%3+(b+c)%2)%2;default:throw new Error("bad maskPattern:"+a)}},getErrorCorrectPolynomial:function(a){for(var b=new i([1],0),c=0;a>c;c++)b=b.multiply(new i([1,g.gexp(c)],0));return b},getLengthInBits:function(a,b){if(b>=1&&10>b)switch(a){case c.MODE_NUMBER:return 10;case c.MODE_ALPHA_NUM:return 9;case c.MODE_8BIT_BYTE:return 8;case c.MODE_KANJI:return 8;default:throw new Error("mode:"+a)}else if(27>b)switch(a){case c.MODE_NUMBER:return 12;case c.MODE_ALPHA_NUM:return 11;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 10;default:throw new Error("mode:"+a)}else{if(!(41>b))throw new Error("type:"+b);switch(a){case c.MODE_NUMBER:return 14;case c.MODE_ALPHA_NUM:return 13;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 12;default:throw new Error("mode:"+a)}}},getLostPoint:function(a){for(var b=a.getModuleCount(),c=0,d=0;b>d;d++)for(var e=0;b>e;e++){for(var f=0,g=a.isDark(d,e),h=-1;1>=h;h++)if(!(0>d+h||d+h>=b))for(var i=-1;1>=i;i++)0>e+i||e+i>=b||(0!=h||0!=i)&&g==a.isDark(d+h,e+i)&&f++;f>5&&(c+=3+f-5)}for(var d=0;b-1>d;d++)for(var e=0;b-1>e;e++){var j=0;a.isDark(d,e)&&j++,a.isDark(d+1,e)&&j++,a.isDark(d,e+1)&&j++,a.isDark(d+1,e+1)&&j++,(0==j||4==j)&&(c+=3)}for(var d=0;b>d;d++)for(var e=0;b-6>e;e++)a.isDark(d,e)&&!a.isDark(d,e+1)&&a.isDark(d,e+2)&&a.isDark(d,e+3)&&a.isDark(d,e+4)&&!a.isDark(d,e+5)&&a.isDark(d,e+6)&&(c+=40);for(var e=0;b>e;e++)for(var d=0;b-6>d;d++)a.isDark(d,e)&&!a.isDark(d+1,e)&&a.isDark(d+2,e)&&a.isDark(d+3,e)&&a.isDark(d+4,e)&&!a.isDark(d+5,e)&&a.isDark(d+6,e)&&(c+=40);for(var k=0,e=0;b>e;e++)for(var d=0;b>d;d++)a.isDark(d,e)&&k++;var l=Math.abs(100*k/b/b-50)/5;return c+=10*l}},g={glog:function(a){if(1>a)throw new Error("glog("+a+")");return g.LOG_TABLE[a]},gexp:function(a){for(;0>a;)a+=255;for(;a>=256;)a-=255;return g.EXP_TABLE[a]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},h=0;8>h;h++)g.EXP_TABLE[h]=1<h;h++)g.EXP_TABLE[h]=g.EXP_TABLE[h-4]^g.EXP_TABLE[h-5]^g.EXP_TABLE[h-6]^g.EXP_TABLE[h-8];for(var h=0;255>h;h++)g.LOG_TABLE[g.EXP_TABLE[h]]=h;i.prototype={get:function(a){return this.num[a]},getLength:function(){return this.num.length},multiply:function(a){for(var b=new Array(this.getLength()+a.getLength()-1),c=0;cf;f++)for(var g=c[3*f+0],h=c[3*f+1],i=c[3*f+2],k=0;g>k;k++)e.push(new j(h,i));return e},j.getRsBlockTable=function(a,b){switch(b){case d.L:return j.RS_BLOCK_TABLE[4*(a-1)+0];case d.M:return j.RS_BLOCK_TABLE[4*(a-1)+1];case d.Q:return j.RS_BLOCK_TABLE[4*(a-1)+2];case d.H:return j.RS_BLOCK_TABLE[4*(a-1)+3];default:return void 0}},k.prototype={get:function(a){var b=Math.floor(a/8);return 1==(1&this.buffer[b]>>>7-a%8)},put:function(a,b){for(var c=0;b>c;c++)this.putBit(1==(1&a>>>b-c-1))},getLengthInBits:function(){return this.length},putBit:function(a){var b=Math.floor(this.length/8);this.buffer.length<=b&&this.buffer.push(0),a&&(this.buffer[b]|=128>>>this.length%8),this.length++}};var l=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]],o=function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){function g(a,b){var c=document.createElementNS("http://www.w3.org/2000/svg",a);for(var d in b)b.hasOwnProperty(d)&&c.setAttribute(d,b[d]);return c}var b=this._htOption,c=this._el,d=a.getModuleCount();Math.floor(b.width/d),Math.floor(b.height/d),this.clear();var h=g("svg",{viewBox:"0 0 "+String(d)+" "+String(d),width:"100%",height:"100%",fill:b.colorLight});h.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink","http://www.w3.org/1999/xlink"),c.appendChild(h),h.appendChild(g("rect",{fill:b.colorDark,width:"1",height:"1",id:"template"}));for(var i=0;d>i;i++)for(var j=0;d>j;j++)if(a.isDark(i,j)){var k=g("use",{x:String(i),y:String(j)});k.setAttributeNS("http://www.w3.org/1999/xlink","href","#template"),h.appendChild(k)}},a.prototype.clear=function(){for(;this._el.hasChildNodes();)this._el.removeChild(this._el.lastChild)},a}(),p="svg"===document.documentElement.tagName.toLowerCase(),q=p?o:m()?function(){function a(){this._elImage.src=this._elCanvas.toDataURL("image/png"),this._elImage.style.display="block",this._elCanvas.style.display="none"}function d(a,b){var c=this;if(c._fFail=b,c._fSuccess=a,null===c._bSupportDataURI){var d=document.createElement("img"),e=function(){c._bSupportDataURI=!1,c._fFail&&_fFail.call(c)},f=function(){c._bSupportDataURI=!0,c._fSuccess&&c._fSuccess.call(c)};return d.onabort=e,d.onerror=e,d.onload=f,d.src="data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==",void 0}c._bSupportDataURI===!0&&c._fSuccess?c._fSuccess.call(c):c._bSupportDataURI===!1&&c._fFail&&c._fFail.call(c)}if(this._android&&this._android<=2.1){var b=1/window.devicePixelRatio,c=CanvasRenderingContext2D.prototype.drawImage;CanvasRenderingContext2D.prototype.drawImage=function(a,d,e,f,g,h,i,j){if("nodeName"in a&&/img/i.test(a.nodeName))for(var l=arguments.length-1;l>=1;l--)arguments[l]=arguments[l]*b;else"undefined"==typeof j&&(arguments[1]*=b,arguments[2]*=b,arguments[3]*=b,arguments[4]*=b);c.apply(this,arguments)}}var e=function(a,b){this._bIsPainted=!1,this._android=n(),this._htOption=b,this._elCanvas=document.createElement("canvas"),this._elCanvas.width=b.width,this._elCanvas.height=b.height,a.appendChild(this._elCanvas),this._el=a,this._oContext=this._elCanvas.getContext("2d"),this._bIsPainted=!1,this._elImage=document.createElement("img"),this._elImage.style.display="none",this._el.appendChild(this._elImage),this._bSupportDataURI=null};return e.prototype.draw=function(a){var b=this._elImage,c=this._oContext,d=this._htOption,e=a.getModuleCount(),f=d.width/e,g=d.height/e,h=Math.round(f),i=Math.round(g);b.style.display="none",this.clear();for(var j=0;e>j;j++)for(var k=0;e>k;k++){var l=a.isDark(j,k),m=k*f,n=j*g;c.strokeStyle=l?d.colorDark:d.colorLight,c.lineWidth=1,c.fillStyle=l?d.colorDark:d.colorLight,c.fillRect(m,n,f,g),c.strokeRect(Math.floor(m)+.5,Math.floor(n)+.5,h,i),c.strokeRect(Math.ceil(m)-.5,Math.ceil(n)-.5,h,i)}this._bIsPainted=!0},e.prototype.makeImage=function(){this._bIsPainted&&d.call(this,a)},e.prototype.isPainted=function(){return this._bIsPainted},e.prototype.clear=function(){this._oContext.clearRect(0,0,this._elCanvas.width,this._elCanvas.height),this._bIsPainted=!1},e.prototype.round=function(a){return a?Math.floor(1e3*a)/1e3:a},e}():function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){for(var b=this._htOption,c=this._el,d=a.getModuleCount(),e=Math.floor(b.width/d),f=Math.floor(b.height/d),g=[''],h=0;d>h;h++){g.push("");for(var i=0;d>i;i++)g.push('');g.push("")}g.push("
"),c.innerHTML=g.join("");var j=c.childNodes[0],k=(b.width-j.offsetWidth)/2,l=(b.height-j.offsetHeight)/2;k>0&&l>0&&(j.style.margin=l+"px "+k+"px")},a.prototype.clear=function(){this._el.innerHTML=""},a}();QRCode=function(a,b){if(this._htOption={width:256,height:256,typeNumber:4,colorDark:"#000000",colorLight:"#ffffff",correctLevel:d.H},"string"==typeof b&&(b={text:b}),b)for(var c in b)this._htOption[c]=b[c];"string"==typeof a&&(a=document.getElementById(a)),this._android=n(),this._el=a,this._oQRCode=null,this._oDrawing=new q(this._el,this._htOption),this._htOption.text&&this.makeCode(this._htOption.text)},QRCode.prototype.makeCode=function(a){this._oQRCode=new b(r(a,this._htOption.correctLevel),this._htOption.correctLevel),this._oQRCode.addData(a),this._oQRCode.make(),this._el.title=a,this._oDrawing.draw(this._oQRCode),this.makeImage()},QRCode.prototype.makeImage=function(){"function"==typeof this._oDrawing.makeImage&&(!this._android||this._android>=3)&&this._oDrawing.makeImage()},QRCode.prototype.clear=function(){this._oDrawing.clear()},QRCode.CorrectLevel=d}(); \ No newline at end of file diff --git a/package/ctcgfw/luci-app-jd-dailybonus/luasrc/controller/jd-dailybonus.lua b/package/ctcgfw/luci-app-jd-dailybonus/luasrc/controller/jd-dailybonus.lua index 38914fe751..f284836d32 100644 --- a/package/ctcgfw/luci-app-jd-dailybonus/luasrc/controller/jd-dailybonus.lua +++ b/package/ctcgfw/luci-app-jd-dailybonus/luasrc/controller/jd-dailybonus.lua @@ -1,82 +1,112 @@ -- Copyright (C) 2020 jerrykuku -- Licensed to the public under the GNU General Public License v3. -module("luci.controller.jd-dailybonus", package.seeall) -function index() - if not nixio.fs.access("/etc/config/jd-dailybonus") then - return +module('luci.controller.jd-dailybonus', package.seeall) +package.path = package.path .. ';/usr/share/jd-dailybonus/?.lua' +function index() + if not nixio.fs.access('/etc/config/jd-dailybonus') then + return end - entry({"admin", "services", "jd-dailybonus"}, alias("admin", "services", "jd-dailybonus", "client"), _("JD-DailyBonus"), 10).dependent = true -- 首页 - entry({"admin", "services", "jd-dailybonus", "client"}, cbi("jd-dailybonus/client"),_("Client"), 10).leaf = true -- 基本设置 - entry({"admin", "services", "jd-dailybonus", "log"},form("jd-dailybonus/log"),_("Log"), 30).leaf = true -- 日志页面 - entry({"admin", "services", "jd-dailybonus", "script"},form("jd-dailybonus/script"),_("Script"), 20).leaf = true -- 直接配置脚本 - entry({"admin", "services", "jd-dailybonus", "run"}, call("run")) -- 执行程序 - entry({"admin", "services", "jd-dailybonus", "update"}, call("update")) -- 执行更新 - entry({"admin", "services", "jd-dailybonus", "check_update"}, call("check_update")) -- 检查更新 + entry({'admin', 'services', 'jd-dailybonus'}, alias('admin', 'services', 'jd-dailybonus', 'client'), _('京东签到服务'), 10).dependent = true -- 首页 + entry({'admin', 'services', 'jd-dailybonus', 'client'}, cbi('jd-dailybonus/client', {hidesavebtn = true, hideresetbtn = true}), _('客户端'), 10).leaf = true -- 基本设置 + entry({'admin', 'services', 'jd-dailybonus', 'log'}, form('jd-dailybonus/log'), _('日志'), 30).leaf = true -- 日志页面 + entry({'admin', 'services', 'jd-dailybonus', 'script'}, form('jd-dailybonus/script'), _('脚本查看'), 20).leaf = true -- 直接配置脚本 + entry({'admin', 'services', 'jd-dailybonus', 'run'}, call('run')) -- 执行程序 + entry({'admin', 'services', 'jd-dailybonus', 'update'}, call('update')) -- 执行更新 + entry({'admin', 'services', 'jd-dailybonus', 'check_update'}, call('check_update')) -- 检查更新 + entry({'admin', 'services', 'jd-dailybonus', 'qrcode'}, call('qrcode')) -- 获取二维码 + entry({'admin', 'services', 'jd-dailybonus', 'check_login'}, call('check_login')) -- 获取二维码 end - +-- 写入配置 +function write_json(file, content) + local json = require 'luci.jsonc' + local f = assert(io.open(file, 'w')) + f:write(json.stringify(content, 1)) + f:close() +end -- 执行程序 - function run() local e = {} local uci = luci.model.uci.cursor() - local cookie = luci.http.formvalue("cookies") - local cookie2 = luci.http.formvalue("cookies2") - local auto_update = luci.http.formvalue("auto_update") - local auto_update_time = luci.http.formvalue("auto_update_time") - local auto_run = luci.http.formvalue("auto_run") - local auto_run_time = luci.http.formvalue("auto_run_time") - local stop = luci.http.formvalue("stop") - local serverchan = luci.http.formvalue("serverchan") - local failed = luci.http.formvalue("failed") - local name = "" - uci:foreach("vssr", "global", function(s) name = s[".name"] end) + local data = luci.http.formvalue() - if cookie ~= " " then - uci:set("jd-dailybonus", '@global[0]', 'auto_update', auto_update) - uci:set("jd-dailybonus", '@global[0]', 'auto_update_time', auto_update_time) - uci:set("jd-dailybonus", '@global[0]', 'auto_run', auto_run) - uci:set("jd-dailybonus", '@global[0]', 'auto_run_time', auto_run_time) - uci:set("jd-dailybonus", '@global[0]', 'stop', stop) - uci:set("jd-dailybonus", '@global[0]', 'cookie', cookie) - uci:set("jd-dailybonus", '@global[0]', 'cookie2', cookie2) - uci:set("jd-dailybonus", '@global[0]', 'serverchan', serverchan) - uci:set("jd-dailybonus", '@global[0]', 'failed', failed) - uci:save("jd-dailybonus") - uci:commit("jd-dailybonus") - luci.sys.call("/usr/share/jd-dailybonus/newapp.sh -r") - luci.sys.call("/usr/share/jd-dailybonus/newapp.sh -a") - e.error = 0 - else - e.error = 1 - end + data.auto_run = data.auto_run ~= nil and data.auto_run or 0 + data.auto_update = data.auto_update ~= nil and data.auto_update or 0 + uci:tset('jd-dailybonus', '@global[0]', data) + uci:commit('jd-dailybonus') + local json_data = { + CookieJD = data.cookie, + CookieJD2 = data.cookie2:len() == 0 and nil or data.cookie2, + JD_DailyBonusDelay = data.stop, + JD_DailyBonusTimeOut = data.out + } + write_json('/root/CookieSet.json', json_data) + write_json('/www/CookieSet.json', json_data) + luci.sys.call('/usr/share/jd-dailybonus/newapp.sh -r') + luci.sys.call('/usr/share/jd-dailybonus/newapp.sh -a') + e.error = 0 - luci.http.prepare_content("application/json") + luci.http.prepare_content('application/json') luci.http.write_json(e) - end --检查更新 function check_update() - local jd = "jd-dailybonus" + local jd = 'jd-dailybonus' local e = {} - local new_version = luci.sys.exec("/usr/share/jd-dailybonus/newapp.sh -n") + local new_version = luci.sys.exec('/usr/share/jd-dailybonus/newapp.sh -n') e.new_version = new_version e.error = 0 - luci.http.prepare_content("application/json") + luci.http.prepare_content('application/json') luci.http.write_json(e) end --执行更新 function update() - local jd = "jd-dailybonus" + local jd = 'jd-dailybonus' local e = {} local uci = luci.model.uci.cursor() - local version = luci.http.formvalue("version") + local version = luci.http.formvalue('version') --下载脚本 - local code = luci.sys.exec("/usr/share/jd-dailybonus/newapp.sh -u") + local code = luci.sys.exec('/usr/share/jd-dailybonus/newapp.sh -u') e.error = code - luci.http.prepare_content("application/json") + luci.http.prepare_content('application/json') luci.http.write_json(e) -end \ No newline at end of file +end + +--获取二维码 +function qrcode() + local jd_cookie = require 'jd_cookie' + local e = {} + e.error = 0 + e.data = jd_cookie.get_qrcode() + luci.http.prepare_content('application/json') + luci.http.write_json(e) +end + +--检测登录 +function check_login() + local jd_cookie = require 'jd_cookie' + local uci = luci.model.uci.cursor() + local data = luci.http.formvalue() + local id = data.id + local e = jd_cookie.checkLogin(data.check_url, data.cookies) + if e.error == 0 then + local cookieStr = 'pt_key=' .. e.cookie.pt_key .. ';pt_pin=' .. e.cookie.pt_pin .. ';' + uci:set('jd-dailybonus', '@global[0]', id, cookieStr) + local json_data = { + CookieJD = uci:get('jd-dailybonus', '@global[0]', 'cookie'), + CookieJD2 = uci:get('jd-dailybonus', '@global[0]', 'cookie2'), + JD_DailyBonusDelay = uci:get('jd-dailybonus', '@global[0]', 'stop'), + JD_DailyBonusTimeOut = uci:get('jd-dailybonus', '@global[0]', 'out') + } + write_json('/root/CookieSet.json', json_data) + write_json('/www/CookieSet.json', json_data) + uci:commit('jd-dailybonus') + e.cstr = cookieStr + end + + luci.http.prepare_content('application/json') + luci.http.write_json(e) +end diff --git a/package/ctcgfw/luci-app-jd-dailybonus/luasrc/model/cbi/jd-dailybonus/client.lua b/package/ctcgfw/luci-app-jd-dailybonus/luasrc/model/cbi/jd-dailybonus/client.lua index 72a252472f..d1cf607662 100644 --- a/package/ctcgfw/luci-app-jd-dailybonus/luasrc/model/cbi/jd-dailybonus/client.lua +++ b/package/ctcgfw/luci-app-jd-dailybonus/luasrc/model/cbi/jd-dailybonus/client.lua @@ -1,75 +1,101 @@ -local jd = "jd-dailybonus" +local jd = 'jd-dailybonus' local uci = luci.model.uci.cursor() -local sys = require "luci.sys" +local sys = require 'luci.sys' m = Map(jd) -- [[ 基本设置 ]]-- -s = m:section(TypedSection, "global", - translate("Base Config")) +s = m:section(TypedSection, 'global', translate('基本设置')) s.anonymous = true -o = s:option(DummyValue, "", "") +o = s:option(DummyValue, '', '') o.rawhtml = true -o.template = "jd-dailybonus/cookie_tools" +o.template = 'jd-dailybonus/cookie_tools' -o = s:option(ListValue, "remote_url", translate("Source Update Url")) -o:value("https://cdn.jsdelivr.net/gh/NobyDa/Script/JD-DailyBonus/JD_DailyBonus.js", translate("GitHub")) -o:value("https://gitee.com/jerrykuku/staff/raw/master/JD_DailyBonus.js", translate("Gitee")) -o.default = "nil" -o.rmempty = false -o.description = translate('当GitHub源无法更新时,可以选择使用国内Gitee源') - -o = s:option(Value, "cookie", translate("First Cookie")) +o = s:option(Value, 'cookie', translate('第一账号Cookie')) o.rmempty = false -o = s:option(Value, "cookie2", translate("Second Cookie")) +o = s:option(Value, 'cookie2', translate('第二账号Cookie')) o.rmempty = true -o.description = translate('双账号用户抓取"账号1"Cookie后, 请勿点击退出账号(可能会导致Cookie失效), 需清除浏览器资料或更换浏览器登录"账号2"抓取.') -o = s:option(Value, "stop", translate("Execute Delay")) +o = s:option(Value, 'stop', translate('延迟签到')) o.rmempty = false o.default = 0 o.datatype = integer -o.description = translate("自定义延迟签到,单位毫秒. 默认分批并发无延迟. (延迟作用于每个签到接口, 如填入延迟则切换顺序签到. ) ") +o.description = translate('自定义延迟签到,单位毫秒. 默认分批并发无延迟. (延迟作用于每个签到接口, 如填入延迟则切换顺序签到. ) ') -o = s:option(ListValue, "serverurl", translate("ServerURL")) -o:value("scu", translate("SCU")) -o:value("sct", translate("SCT")) -o.default = "scu" +o = s:option(Value, 'out', translate('接口超时')) +o.rmempty = false +o.default = 0 +o.datatype = integer +o.description = translate('接口超时退出,单位毫秒 用于可能发生的网络不稳定, 0则关闭.') + +-- server chan +o = s:option(ListValue, 'serverurl', translate('Server酱的推送接口地址')) +o:value('scu', translate('SCU')) +o:value('sct', translate('SCT')) +o.default = 'scu' o.rmempty = false o.description = translate('选择Server酱的推送接口') -o = s:option(Value, "serverchan", translate("ServerChan SCKEY")) +o = s:option(Value, 'serverchan', translate('Server酱 SCKEY')) o.rmempty = true -o.description = translate("微信推送,基于Server酱服务,请自行登录 http://sc.ftqq.com/ 绑定并获取 SCKEY (仅在自动签到时推送)") +o.description = translate('微信推送,基于Server酱服务,请自行登录 http://sc.ftqq.com/ 绑定并获取 SCKEY。') -o = s:option(Flag, "failed", translate("Failed Push")) +-- telegram + +o = s:option(Value, 'tg_token', translate('Telegram Bot Token')) +o.rmempty = true +o.description = translate('首先在Telegram上搜索BotFather机器人,创建一个属于自己的通知机器人,并获取Token。') + +o = s:option(Value, 'tg_userid', translate('Telegram UserID')) +o.rmempty = true +o.description = translate('在Telegram上搜索getuserIDbot机器人,获取UserID。') + +--Auto Run Script Service + +o = s:option(Flag, 'auto_run', translate('自动签到')) o.rmempty = false -o.description = translate("仅当cookie失效时推送") -o = s:option(Flag, "auto_update", translate("Auto Update")) -o.rmempty = false -o.description = translate("Auto Update Script Service") - -o =s:option(ListValue, "auto_update_time", translate("Update time (every day)")) -for t = 0, 23 do o:value(t, t .. ":01") end +o = s:option(ListValue, 'auto_run_time_h', translate('每天签到时间(小时)')) +for t = 0, 23 do + o:value(t, t) +end o.default = 1 o.rmempty = true -o:depends("auto_update", "1") - -o = s:option(Flag, "auto_run", translate("Auto Run")) -o.rmempty = false -o.description = translate("Auto Run Script Service") - -o =s:option(ListValue, "auto_run_time", translate("Run time (every day)")) -for t = 0, 23 do o:value(t, t .. ":05") end +o:depends('auto_run', '1') +o = s:option(ListValue, 'auto_run_time_m', translate('每天签到时间(分钟)')) +for t = 0, 59 do + o:value(t, t) +end o.default = 1 o.rmempty = true -o:depends("auto_run", "1") +o:depends('auto_run', '1') -o = s:option(DummyValue, "", "") +-- Auto Update Script Service + +o = s:option(Flag, 'auto_update', translate('自动更新')) +o.rmempty = false + +o = s:option(ListValue, 'auto_update_time', translate('每天更新时间')) +for t = 0, 23 do + o:value(t, t .. ':01') +end +o.default = 1 +o.rmempty = true +o:depends('auto_update', '1') + +o = s:option(Value, 'remote_url', translate('更新源地址')) +o:value('https://raw.githubusercontent.com/NobyDa/Script/master/JD-DailyBonus/JD_DailyBonus.js', translate('GitHub')) +o:value('https://cdn.jsdelivr.net/gh/NobyDa/Script/JD-DailyBonus/JD_DailyBonus.js', translate('GitHub CDN')) +o:value('https://gitee.com/jerrykuku/staff/raw/master/JD_DailyBonus.js', translate('Gitee')) +o.default = 'nil' +o.rmempty = false +o.description = translate('当GitHub源无法更新时,可以选择使用国内Gitee源,GitHub CDN可能比原地址更晚更新,但速度快') + +o = s:option(DummyValue, '', '') o.rawhtml = true o.version = sys.exec('uci get jd-dailybonus.@global[0].version') -o.template = "jd-dailybonus/update_service" +o.template = 'jd-dailybonus/update_service' + return m diff --git a/package/ctcgfw/luci-app-jd-dailybonus/luasrc/view/jd-dailybonus/cookie_tools.htm b/package/ctcgfw/luci-app-jd-dailybonus/luasrc/view/jd-dailybonus/cookie_tools.htm index a88d8248be..bb00927d86 100644 --- a/package/ctcgfw/luci-app-jd-dailybonus/luasrc/view/jd-dailybonus/cookie_tools.htm +++ b/package/ctcgfw/luci-app-jd-dailybonus/luasrc/view/jd-dailybonus/cookie_tools.htm @@ -1,25 +1,13 @@ <%+cbi/valueheader%> - +
- + +
帮助 - <%= translate("Click to download the JDCookie.zip,unzip it,and use load Unpacked extensions to install.link:[chrome://extensions/]")%> -
-
- -<%+cbi/valuefooter%> -<%+cbi/valueheader%> - - -
- -
-
- 帮助 - <%= translate("Sign in ,then click JDCookie button.you will copy JD cookies, paste the cookie below.")%> + <%= translate("点击上面按钮使用京东手机app扫码获取Cookie")%>
diff --git a/package/ctcgfw/luci-app-jd-dailybonus/luasrc/view/jd-dailybonus/update_service.htm b/package/ctcgfw/luci-app-jd-dailybonus/luasrc/view/jd-dailybonus/update_service.htm index 947f9d5057..6ef9b0ff9c 100644 --- a/package/ctcgfw/luci-app-jd-dailybonus/luasrc/view/jd-dailybonus/update_service.htm +++ b/package/ctcgfw/luci-app-jd-dailybonus/luasrc/view/jd-dailybonus/update_service.htm @@ -1,5 +1,9 @@ <%+cbi/valueheader%> + + - +
"> + value="<%= translate("保存Cookie,并马上进行签到") %>">
-<%+cbi/valuefooter%> -<%+cbi/valueheader%> - -
-
- v<%=self.version%> -
- -
<%+cbi/valuefooter%> <%+cbi/valueheader%> - +
"> - + value="<%= translate("手动检查脚本更新,当前版本:v")..self.version %>">
<%+cbi/valuefooter%> + + diff --git a/package/ctcgfw/luci-app-jd-dailybonus/po/zh-cn/jd-dailybonus.po b/package/ctcgfw/luci-app-jd-dailybonus/po/zh-cn/jd-dailybonus.po deleted file mode 100644 index 22daa12df6..0000000000 --- a/package/ctcgfw/luci-app-jd-dailybonus/po/zh-cn/jd-dailybonus.po +++ /dev/null @@ -1,111 +0,0 @@ -msgid "" -msgstr "Content-Type: text/plain; charset=UTF-8\n" - -msgid "JD-DailyBonus" -msgstr "京东签到服务" - -msgid "Enable" -msgstr "启用" - -msgid "Disable" -msgstr "停用" - -msgid "Log" -msgstr "日志" - -msgid "Script" -msgstr "脚本" - -msgid "Base Config" -msgstr "基本设置" - -msgid "Cookie Tools" -msgstr "Cookie 工具" - -msgid "JDCookie Tools" -msgstr "获取京东cookie扩展工具" - -msgid "Source Update Url" -msgstr "更新源地址" - -msgid "First Cookie" -msgstr "主账号Cookie" - -msgid "Second Cookie" -msgstr "第二账号Cookie" - -msgid "Click to download the JDCookie.zip,unzip it,and use load Unpacked extensions to install.link:[chrome://extensions/]")" -msgstr "点击上面的按钮安装下载JDCookie.zip(获取京东cookie扩展工具),解压后在[chrome://extensions/]中使用加载已解压的扩展程序进行安装。 " - -msgid "JD Url" -msgstr "京东链接" - -msgid "Sign in ,then click JDCookie button.you will copy JD cookies, paste the cookie below." -msgstr "登录后点击JDCookie 扩展工具复制cookie,然后粘贴到下面输入框中。(请使用F12调试工具,进入模拟手机浏览器模式)" - -msgid "Auto Update Script Service" -msgstr "自动更新脚本服务" - -msgid "Update time (every day)" -msgstr "更新时间 (每天)" - -msgid "Update Script" -msgstr "更新脚本" - -msgid "Execute Delay" -msgstr "延迟签到" - -msgid "ServerChan SCKEY" -msgstr "Server酱 SCKEY" - -msgid "ServerURL" -msgstr "Server酱的推送接口地址" - -msgid "SCT" -msgstr "测试版推送接口地址" - -msgid "SCU" -msgstr "原版推送接口地址" - -msgid "Failed Push" -msgstr "失效时推送" - -msgid "Auto Run" -msgstr "自动签到" - -msgid "Run" -msgstr "执行" - -msgid "Auto Run Script Service" -msgstr "自动签到服务" - -msgid "Run time (every day)" -msgstr "签到时间 (每天)" - -msgid "Save Cookies And Run Service" -msgstr "保存Cookie并签到" - -msgid "Sign in info" -msgstr "签到信息" - -msgid "Service is running,Please do not refresh!" -msgstr "服务正在执行中,请勿刷新!" - -msgid "Updating script,please wait ..." -msgstr "正在更新脚本,请稍候 ..." - -msgid "Is currently the latest version" -msgstr "当前已是最新版本。" - -msgid "There is a new version, click to update" -msgstr "有新的版本,请点击更新" - -msgid "Checking the New Version ..." -msgstr "正在检查是否存在新的版本 ..." - -msgid "Check Script Version" -msgstr "手动检查脚本更新" - -msgid "Current Script Version" -msgstr "当前脚本版本" - diff --git a/package/ctcgfw/luci-app-jd-dailybonus/root/etc/config/jd-dailybonus b/package/ctcgfw/luci-app-jd-dailybonus/root/etc/config/jd-dailybonus index 14a038cb7c..8002200ac1 100644 --- a/package/ctcgfw/luci-app-jd-dailybonus/root/etc/config/jd-dailybonus +++ b/package/ctcgfw/luci-app-jd-dailybonus/root/etc/config/jd-dailybonus @@ -1,9 +1,14 @@ config global - option version '1.87' - option auto_run_time '1' - option auto_run '1' - option auto_update_time '1' + option version '1.90' + option out '0' + option stop '100' + option serverchan '' + option remote_url 'https://raw.githubusercontent.com/NobyDa/Script/master/JD-DailyBonus/JD_DailyBonus.js' + option serverurl 'scu' option auto_update '1' - option stop '0' - option failed '0' - option remote_url 'https://cdn.jsdelivr.net/gh/NobyDa/Script/JD-DailyBonus/JD_DailyBonus.js' \ No newline at end of file + option auto_update_time '23' + option auto_run '1' + option auto_run_time '0' + option auto_run_time_m '1' + option auto_run_time_h '1' + option cookie '' \ No newline at end of file diff --git a/package/ctcgfw/luci-app-jd-dailybonus/root/usr/share/jd-dailybonus/JD_DailyBonus.js b/package/ctcgfw/luci-app-jd-dailybonus/root/usr/share/jd-dailybonus/JD_DailyBonus.js index c6d411f1fc..467ff87d1b 100644 --- a/package/ctcgfw/luci-app-jd-dailybonus/root/usr/share/jd-dailybonus/JD_DailyBonus.js +++ b/package/ctcgfw/luci-app-jd-dailybonus/root/usr/share/jd-dailybonus/JD_DailyBonus.js @@ -2,7 +2,7 @@ 京东多合一签到脚本 -更新时间: 2020.12.25 17:50 v1.89 +更新时间: 2021.01.07 17:00 v1.90 有效接口: 40+ 脚本兼容: QuantumultX, Surge, Loon, JSBox, Node.js 电报频道: @NobyDa @@ -13,7 +13,7 @@ 【 JSbox, Node.js 说明 】 : ************************* -开启抓包app后, Safari浏览器登录 https://bean.m.jd.com 点击签到并且出现签到日历后, 返回抓包app搜索关键字 functionId=signBean 复制请求头Cookie填入以下Key处的单引号内即可 */ +开启抓包app后, Safari浏览器登录 https://bean.m.jd.com/bean/signIndex.action 点击签到并且出现签到日历后, 返回抓包app搜索关键字 functionId=signBean 复制请求头Cookie填入以下Key处的单引号内即可 */ var Key = ''; //单引号内自行填写您抓取的Cookie @@ -30,7 +30,7 @@ var DualKey = ''; //如需双账号签到,此处单引号内填写抓取的"账 【 QX, Surge, Loon 说明 】 : ************************* -初次使用时, app配置文件添加脚本配置,并启用Mitm后, Safari浏览器打开登录 https://bean.m.jd.com ,点击签到并且出现签到日历后, 如果通知获得cookie成功, 则可以使用此签到脚本。 注: 请勿在京东APP内获取!!! +初次使用时, app配置文件添加脚本配置,并启用Mitm后, Safari浏览器打开登录 https://bean.m.jd.com/bean/signIndex.action ,点击签到并且出现签到日历后, 如果通知获得cookie成功, 则可以使用此签到脚本。 注: 请勿在京东APP内获取!!! 由于cookie的有效性(经测试网页Cookie有效周期最长31天),如果脚本后续弹出cookie无效的通知,则需要重复上述步骤。 签到脚本将在每天的凌晨0:05执行, 您可以修改执行时间。 因部分接口京豆限量领取, 建议调整为凌晨签到。 @@ -108,14 +108,12 @@ async function all() { case 0: await Promise.all([ JingDongBean(stop), //京东京豆 - JDTakeaLook(stop), //京东发现-看一看 JingDongStore(stop), //京东超市 JingDongWebcasts(stop), //京东直播 JingRongBean(stop), //金融简单赚钱 JingRongSteel(stop), //金融钢镚 JingDongTurn(stop), //京东转盘 JDFlashSale(stop), //京东闪购 - JDOverseas(stop), //京东国际 JingDongCash(stop), //京东现金红包 JDMagicCube(stop, 2), //京东小魔方 JingDongSubsidy(stop), //京东金贴 @@ -131,15 +129,13 @@ async function all() { JingRongDoll(stop, 'JRFiveDoll', '京东金融-签伍', '1D06AA3B0F') ]); await Promise.all([ - JDUserSignPre(stop, 'JDClothing', '京东商城-服饰', '4RBT3H9jmgYg1k2kBnHF8NAHm7m8'), //京东服饰 - JDUserSignPre(stop, 'JDUnderwear', '京东商城-内衣', '4PgpL1xqPSW1sVXCJ3xopDbB1f69'), //京东内衣馆 JDUserSignPre(stop, 'JDShoes', '京东商城-鞋靴', '4RXyb1W4Y986LJW8ToqMK14BdTD'), //京东鞋靴 JDUserSignPre(stop, 'JDCalendar', '京东日历-翻牌', '36V2Qw59VPNsuLxY84vCFtxFzrFs'), //京东日历翻牌 JDUserSignPre(stop, 'JDChild', '京东商城-童装', '3Af6mZNcf5m795T8dtDVfDwWVNhJ'), //京东童装馆 JDUserSignPre(stop, 'JDBaby', '京东商城-母婴', '3BbAVGQPDd6vTyHYjmAutXrKAos6'), //京东母婴馆 JDUserSignPre(stop, 'JD3C', '京东商城-数码', '4SWjnZSCTHPYjE5T7j35rxxuMTb6'), //京东数码电器馆 - JDUserSignPre(stop, 'JDSubsidy', '京东晚市-补贴', 'xK148m4kWj5hBcTPuJUNNXH3AkJ'), //京东晚市补贴金 - JDUserSignPre(stop, 'JDDrug', '京东商城-医药', '3tqTG5sF1xCUyC6vgEF5CLCxGn7w'), //京东医药馆 + // JDUserSignPre(stop, 'JDSubsidy', '京东晚市-补贴', 'xK148m4kWj5hBcTPuJUNNXH3AkJ'), //京东晚市补贴金 + // JDUserSignPre(stop, 'JDDrug', '京东商城-医药', '3tqTG5sF1xCUyC6vgEF5CLCxGn7w'), //京东医药馆 JDUserSignPre(stop, 'JDWomen', '京东商城-女装', 'DpSh7ma8JV7QAxSE2gJNro8Q2h9'), //京东女装馆 JDUserSignPre(stop, 'JDFineWine', '京东商城-酒饮', 'zGwAUzL3pVGjptBBGeYfpKjYdtX'), //京东酒饮馆 JDUserSignPre(stop, 'JDBook', '京东商城-图书', '3SC6rw5iBg66qrXPGmZMqFDwcyXi'), //京东图书 @@ -147,15 +143,17 @@ async function all() { JingRongDoll(stop, 'XJDouble', '金融现金-双签', 'F68B2C3E71', '', '', '', 'xianjin') //京东金融 现金双签 ]); await Promise.all([ + JDUserSignPre(stop, 'JDClothing', '京东商城-服饰', '4RBT3H9jmgYg1k2kBnHF8NAHm7m8'), //京东服饰 + JDUserSignPre(stop, 'JDUnderwear', '京东商城-内衣', '4PgpL1xqPSW1sVXCJ3xopDbB1f69'), //京东内衣馆 JDUserSignPre(stop, 'JDSuitcase', '京东商城-箱包', 'ZrH7gGAcEkY2gH8wXqyAPoQgk6t'), //京东箱包馆 JDUserSignPre(stop, 'JDSchool', '京东商城-校园', '4812pn2PAcUyfNdWr7Cvpww5MCyW'), //京东校园 JDUserSignPre(stop, 'JDHealth', '京东商城-健康', 'w2oeK5yLdHqHvwef7SMMy4PL8LF'), //京东健康 - JDUserSignPre(stop, 'JDPet', '京东商城-宠物', '37ta5sh5ocrMZF3Fz5UMJbTsL42'), //京东宠物馆 - JDUserSignPre(stop, 'JDShand', '京东拍拍-二手', '3S28janPLYmtFxypu37AYAGgivfp'), //京东拍拍二手 + // JDUserSignPre(stop, 'JDPet', '京东商城-宠物', '37ta5sh5ocrMZF3Fz5UMJbTsL42'), //京东宠物馆 + // JDUserSignPre(stop, 'JDShand', '京东拍拍-二手', '3S28janPLYmtFxypu37AYAGgivfp'), //京东拍拍二手 JDUserSignPre(stop, 'JDClean', '京东商城-清洁', '2Tjm6ay1ZbZ3v7UbriTj6kHy9dn6'), //京东清洁馆 JDUserSignPre(stop, 'JDCare', '京东商城-个护', 'NJ1kd1PJWhwvhtim73VPsD1HwY3'), //京东个人护理馆 JDUserSignPre(stop, 'JDJewels', '京东商城-珠宝', 'zHUHpTHNTaztSRfNBFNVZscyFZU'), //京东珠宝馆 - JDUserSignPre(stop, 'JDClocks', '京东商城-钟表', '2BcJPCVVzMEtMUynXkPscCSsx68W'), //京东钟表馆 + // JDUserSignPre(stop, 'JDClocks', '京东商城-钟表', '2BcJPCVVzMEtMUynXkPscCSsx68W'), //京东钟表馆 JDUserSignPre(stop, 'JDMakeup', '京东商城-美妆', '2smCxzLNuam5L14zNJHYu43ovbAP'), //京东美妆馆 JDUserSignPre(stop, 'JDVege', '京东商城-菜场', 'Wcu2LVCFMkBP3HraRvb7pgSpt64') //京东菜场 ]); @@ -164,14 +162,12 @@ async function all() { break; default: await JingDongBean(stop); //京东京豆 - await JDTakeaLook(stop); //京东发现-看一看 await JingDongStore(stop); //京东超市 await JingDongWebcasts(stop); //京东直播 await JingRongBean(stop); //金融简单赚钱 await JingRongSteel(stop); //金融钢镚 await JingDongTurn(stop); //京东转盘 await JDFlashSale(stop); //京东闪购 - await JDOverseas(stop); //京东国际 await JingDongCash(stop); //京东现金红包 await JDMagicCube(stop, 2); //京东小魔方 await JingDongGetCash(stop); //京东领现金 @@ -197,13 +193,13 @@ async function all() { await JDUserSignPre(stop, 'JDChild', '京东商城-童装', '3Af6mZNcf5m795T8dtDVfDwWVNhJ'); //京东童装馆 await JDUserSignPre(stop, 'JDBaby', '京东商城-母婴', '3BbAVGQPDd6vTyHYjmAutXrKAos6'); //京东母婴馆 await JDUserSignPre(stop, 'JD3C', '京东商城-数码', '4SWjnZSCTHPYjE5T7j35rxxuMTb6'); //京东数码电器馆 - await JDUserSignPre(stop, 'JDSubsidy', '京东晚市-补贴', 'xK148m4kWj5hBcTPuJUNNXH3AkJ'); //京东晚市补贴金 - await JDUserSignPre(stop, 'JDClocks', '京东商城-钟表', '2BcJPCVVzMEtMUynXkPscCSsx68W'); //京东钟表馆 - await JDUserSignPre(stop, 'JDDrug', '京东商城-医药', '3tqTG5sF1xCUyC6vgEF5CLCxGn7w'); //京东医药馆 + // await JDUserSignPre(stop, 'JDSubsidy', '京东晚市-补贴', 'xK148m4kWj5hBcTPuJUNNXH3AkJ'); //京东晚市补贴金 + // await JDUserSignPre(stop, 'JDClocks', '京东商城-钟表', '2BcJPCVVzMEtMUynXkPscCSsx68W'); //京东钟表馆 + // await JDUserSignPre(stop, 'JDDrug', '京东商城-医药', '3tqTG5sF1xCUyC6vgEF5CLCxGn7w'); //京东医药馆 await JDUserSignPre(stop, 'JDWomen', '京东商城-女装', 'DpSh7ma8JV7QAxSE2gJNro8Q2h9'); //京东女装馆 - await JDUserSignPre(stop, 'JDPet', '京东商城-宠物', '37ta5sh5ocrMZF3Fz5UMJbTsL42'); //京东宠物馆 + // await JDUserSignPre(stop, 'JDPet', '京东商城-宠物', '37ta5sh5ocrMZF3Fz5UMJbTsL42'); //京东宠物馆 await JDUserSignPre(stop, 'JDBook', '京东商城-图书', '3SC6rw5iBg66qrXPGmZMqFDwcyXi'); //京东图书 - await JDUserSignPre(stop, 'JDShand', '京东拍拍-二手', '3S28janPLYmtFxypu37AYAGgivfp'); //京东拍拍二手 + // await JDUserSignPre(stop, 'JDShand', '京东拍拍-二手', '3S28janPLYmtFxypu37AYAGgivfp'); //京东拍拍二手 await JDUserSignPre(stop, 'JDMakeup', '京东商城-美妆', '2smCxzLNuam5L14zNJHYu43ovbAP'); //京东美妆馆 await JDUserSignPre(stop, 'JDFineWine', '京东商城-酒饮', 'zGwAUzL3pVGjptBBGeYfpKjYdtX'); //京东酒饮馆 await JDUserSignPre(stop, 'JDVege', '京东商城-菜场', 'Wcu2LVCFMkBP3HraRvb7pgSpt64'); //京东菜场 @@ -1700,56 +1696,6 @@ function JingRongDoll(s, key, title, code, type, num, award, belong) { }); } -function JDOverseas(s) { - merge.Overseas = {}; - return new Promise(resolve => { - if (disable("Overseas")) return resolve() - setTimeout(() => { - const OverseasUrl = { - url: 'https://api.m.jd.com/client.action?functionId=checkin', - headers: { - Cookie: KEY - }, - body: "body=%7B%7D&build=167237&client=apple&clientVersion=9.0.0&openudid=1fce88cd05c42fe2b054e846f11bdf33f016d676&partner=apple&scope=11&sign=e27f8b904040a0e3c99b87fc27e09c87&st=1591730990449&sv=101" - }; - $nobyda.post(OverseasUrl, function(error, response, data) { - try { - if (error) { - throw new Error(error) - } else { - const Details = LogDetails ? "response:\n" + data : ''; - if (data.match(/\"type\":\d+?,/)) { - console.log("\n" + "京东商城-国际签到成功 " + Details) - merge.Overseas.success = 1 - if (data.match(/\"jdBeanAmount\":[1-9]+/)) { - merge.Overseas.bean = data.match(/\"jdBeanAmount\":(\d+)/)[1] - merge.Overseas.notify = "京东商城-国际: 成功, 明细: " + merge.Overseas.bean + "京豆 🐶" - } else { - merge.Overseas.notify = "京东商城-国际: 成功, 明细: 无京豆 🐶" - } - } else { - console.log("\n" + "京东商城-国际签到失败 " + Details) - merge.Overseas.fail = 1 - if (data.match(/(\"code\":\"13\"|重复签到)/)) { - merge.Overseas.notify = "京东商城-国际: 失败, 原因: 已签过 ⚠️" - } else if (data.match(/\"code\":\"(-1|3)\"/)) { - merge.Overseas.notify = "京东商城-国际: 失败, 原因: Cookie失效‼️" - } else { - merge.Overseas.notify = "京东商城-国际: 失败, 原因: 未知 ⚠️" - } - } - } - } catch (eor) { - $nobyda.AnError("京东商城-国际", "Overseas", eor, response, data) - } finally { - resolve() - } - }) - }, s) - if (out) setTimeout(resolve, out + s) - }); -} - function JingDongGetCash(s) { merge.JDGetCash = {}; return new Promise(resolve => { @@ -1834,45 +1780,6 @@ function JingDongWebcasts(s) { }); } -function JDTakeaLook(s) { - merge.TakeaLook = {}; - return new Promise(resolve => { - if (disable("TakeaLook")) return resolve() - setTimeout(() => { - $nobyda.get({ - url: 'https://api.m.jd.com/client.action?functionId=discTaskList&body=%7B%22bizType%22%3A1%2C%22referPageId%22%3A%22discRecommend%22%7D&client=apple&clientVersion=9.1.6&openudid=1fce88cd05c42fe2b054e846f11bdf33f016d676&sign=17061147fe8e0eb10edfe8d9968b6d66&st=1601138337675&sv=102', - headers: { - Cookie: KEY - } - }, (error, response, data) => { - try { - if (error) throw new Error(error); - const cc = JSON.parse(data); - const Details = LogDetails ? "response:\n" + data : ''; - const tm = parseInt((Date.now() + 28800000) / 86400000) * 86400000 - 28800000 - if (data.match(/签到成功/) && !data.match(tm)) { - console.log(`\n京东发现-看看签到成功 ${Details}`) - const aw = data.match(/\"签到成功,获得(\d+)京豆\"/) - merge.TakeaLook.success = 1 - merge.TakeaLook.bean = aw ? aw[1] : 0 - merge.TakeaLook.notify = `京东发现-看看: 成功, 明细: ${merge.TakeaLook.bean||`无`}京豆 🐶` - } else { - console.log(`\n京东发现-看看签到失败 ${Details}`) - const tp = data.match(tm) ? `已签过` : cc.busiCode == 2001 ? `Cookie失效` : `${cc.message||`未知`}` - merge.TakeaLook.notify = `京东发现-看看: 失败, 原因: ${tp}${cc.busiCode==2001?`‼️`:` ⚠️`}` - merge.TakeaLook.fail = 1 - } - } catch (eor) { - $nobyda.AnError("京东发现-看看", "TakeaLook", eor, response, data) - } finally { - resolve() - } - }) - }, s) - if (out) setTimeout(resolve, out + s) - }); -} - function JingDongStore(s) { merge.JDGStore = {}; return new Promise(resolve => { diff --git a/package/ctcgfw/luci-app-jd-dailybonus/root/usr/share/jd-dailybonus/jd_cookie.lua b/package/ctcgfw/luci-app-jd-dailybonus/root/usr/share/jd-dailybonus/jd_cookie.lua new file mode 100644 index 0000000000..a1ddffac18 --- /dev/null +++ b/package/ctcgfw/luci-app-jd-dailybonus/root/usr/share/jd-dailybonus/jd_cookie.lua @@ -0,0 +1,168 @@ +-- Copyright (C) 2021 jerrykuku +-- Licensed to the public under the GNU General Public License v3. + +local uci = require 'luci.model.uci'.cursor() +local config = 'jd-dailybonus' +package.path = package.path .. ';/usr/share/jd-dailybonus/?.lua' +local requests = require 'requests' +local socket = require 'socket' +local tinsert = table.insert +local ssub, slen, schar, sbyte, sformat, sgsub = string.sub, string.len, string.char, string.byte, string.format, string.gsub +local User_Agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36' +local Host = 'plogin.m.jd.com' +local jd_cookie = {} + +--打印table +function print_r(t) + local print_r_cache = {} + local function sub_print_r(t, indent) + if (print_r_cache[tostring(t)]) then + print(indent .. '*' .. tostring(t)) + else + print_r_cache[tostring(t)] = true + if (type(t) == 'table') then + for pos, val in pairs(t) do + if (type(val) == 'table') then + print(indent .. '[' .. pos .. '] => ' .. tostring(t) .. ' {') + sub_print_r(val, indent .. string.rep(' ', string.len(pos) + 8)) + print(indent .. string.rep(' ', string.len(pos) + 6) .. '}') + elseif (type(val) == 'string') then + print(indent .. '[' .. pos .. '] => "' .. val .. '"') + else + print(indent .. '[' .. pos .. '] => ' .. tostring(val)) + end + end + else + print(indent .. tostring(t)) + end + end + end + if (type(t) == 'table') then + print(tostring(t) .. ' {') + sub_print_r(t, ' ') + print('}') + else + sub_print_r(t, ' ') + end + print() +end + +-- 分割字符串 +local function split(full, sep) + full = full:gsub('%z', '') -- 这里不是很清楚 有时候结尾带个\0 + local off, result = 1, {} + while true do + local nStart, nEnd = full:find(sep, off) + if not nEnd then + local res = ssub(full, off, slen(full)) + if #res > 0 then -- 过滤掉 \0 + tinsert(result, res) + end + break + else + tinsert(result, ssub(full, off, nStart - 1)) + off = nEnd + 1 + end + end + return result +end + +--获取unix时间戳 +function jd_cookie.timestamp() + return math.floor(socket.gettime() * 1000) +end + +--延时函数 +function sleep(n) + os.execute('sleep ' .. n) +end + +--解析cookie +function praseSetCookies(rcookie) + local tbl = {} + for k, v in rcookie:gmatch('([^;%s]+)=([^;]+)') do + tbl[k] = v + end + return tbl +end + +--获取二维码链接和检测URL +function jd_cookie.get_qrcode() + local timeStamp = jd_cookie.timestamp() + local url = + 'https://plogin.m.jd.com/cgi-bin/mm/new_login_entrance?lang=chs&appid=300&returnurl=https://wq.jd.com/passport/LoginRedirect?state=' .. + timeStamp .. '&returnurl=https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action&source=wq_passport' + local xformHeaders = { + ['Content-Type'] = 'application/x-www-form-urlencoded', + ['Connection'] = 'Keep-Alive', + ['Accept'] = 'application/json, text/plain, */*', + ['Accept-Language'] = 'zh-cn', + ['Referer'] = 'https://plogin.m.jd.com/login/login?appid=300&returnurl=https://wq.jd.com/passport/LoginRedirect?state=' .. + timeStamp .. '&returnurl=https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action&source=wq_passport', + ['User-Agent'] = User_Agent, + ['Host'] = Host + } + local response = requests.get {url, headers = xformHeaders} + local s_token = response.json().s_token + local dat = split(string.gsub(response.headers['set-cookie'], ' DOMAIN=.plogin.m.jd.com', ''), ';') + local cookies = string.gsub(dat[1] .. dat[4] .. dat[6] .. dat[8], ',', ';') .. ';' + + local timeStamp = jd_cookie.timestamp() + local url = 'https://plogin.m.jd.com/cgi-bin/m/tmauthreflogurl?s_token=' .. s_token .. '&v=' .. timeStamp .. '&remember=true' + local xformHeaders = { + ['Content-Type'] = 'application/x-www-form-urlencoded', + ['Connection'] = 'Keep-Alive', + ['Accept'] = 'application/json, text/plain, */*', + ['Accept-Language'] = 'zh-cn', + ['Referer'] = 'https://plogin.m.jd.com/login/login?appid=300&returnurl=https://wq.jd.com/passport/LoginRedirect?state=' .. + timeStamp .. '&returnurl=https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action&source=wq_passport', + ['User-Agent'] = User_Agent, + ['Host'] = Host + } + local response = requests.post {url, cookies = cookies, headers = xformHeaders} + local json_body, error = response.json() + local token = json_body['token'] + local ou_state = json_body['ou_state'] + local okl_token = praseSetCookies(response.headers['set-cookie']).okl_token + local return_json = { + qrcode_url = 'https://plogin.m.jd.com/cgi-bin/m/tmauth?appid=300&client_type=m&token=' .. token, + check_url = 'https://plogin.m.jd.com/cgi-bin/m/tmauthchecktoken?&token=' .. token .. '&ou_state=' .. ou_state .. '&okl_token=' .. okl_token, + cookies = cookies + } + return return_json +end + +--检测扫码状态 并返回cookie +function jd_cookie.checkLogin(url, cookies) + local xformHeaders = { + ['Content-Type'] = 'application/x-www-form-urlencoded', + ['Connection'] = 'Keep-Alive', + ['Accept'] = 'application/json, text/plain, */*', + ['Accept-Language'] = 'zh-cn', + ['Referer'] = 'https://plogin.m.jd.com/login/login?appid=300&returnurl=https://wqlogin2.jd.com/passport/LoginRedirect?state=', + ['User-Agent'] = User_Agent, + ['Host'] = Host + } + local data = + 'lang=chs&appid=300&source=wq_passport&returnurl=https://wqlogin2.jd.com/passport/LoginRedirect?state=1100399130787&returnurl=//home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action' + local response = requests.post {url, data = data, cookies = cookies, headers = xformHeaders} + --local cookie = jd_cookie.praseSetCookies(response.headers['set-cookie']) + local json = response.json() + local return_json = {} + if json.errcode == 0 then + local ucookie = praseSetCookies(response.headers['set-cookie']) + return_json = { + error = 0, + cookie = ucookie + } + else + return_json = { + error = json.errcode, + msg = json.message + } + end + + return return_json +end + +return jd_cookie diff --git a/package/ctcgfw/luci-app-jd-dailybonus/root/usr/share/jd-dailybonus/newapp.sh b/package/ctcgfw/luci-app-jd-dailybonus/root/usr/share/jd-dailybonus/newapp.sh index 938461c032..c91e838b4d 100755 --- a/package/ctcgfw/luci-app-jd-dailybonus/root/usr/share/jd-dailybonus/newapp.sh +++ b/package/ctcgfw/luci-app-jd-dailybonus/root/usr/share/jd-dailybonus/newapp.sh @@ -49,78 +49,58 @@ cancel() { exit 1 } -fill_cookie() { - cookie1=$(uci_get_by_type global cookie) - if [ ! "$cookie1" = "" ]; then - varb="var Key = '$cookie1';" - a=$(sed -n '/var Key =/=' $JD_SCRIPT) - b=$((a-1)) - sed -i "${a}d" $JD_SCRIPT - sed -i "${b}a ${varb}" $JD_SCRIPT - fi - - cookie2=$(uci_get_by_type global cookie2) - if [ ! "$cookie2" = "" ]; then - varb2="var DualKey = '$cookie2';" - aa=$(sed -n '/var DualKey =/=' $JD_SCRIPT) - bb=$((aa-1)) - sed -i "${aa}d" $JD_SCRIPT - sed -i "${bb}a ${varb2}" $JD_SCRIPT - fi - - stop=$(uci_get_by_type global stop) - if [ ! "$stop" = "" ]; then - varb3="var stop = $stop;" - sed -i "s/^var stop =.*/$varb3/g" $JD_SCRIPT - fi -} - add_cron() { sed -i '/jd-dailybonus/d' $CRON_FILE - [ $(uci_get_by_type global auto_run 0) -eq 1 ] && echo '5 '$(uci_get_by_type global auto_run_time)' * * * sleep '$(expr $(head -n 128 /dev/urandom | tr -dc "0123456789" | head -c4) % 180)'s; /usr/share/jd-dailybonus/newapp.sh -w' >>$CRON_FILE + [ $(uci_get_by_type global auto_run 0) -eq 1 ] && echo $(uci_get_by_type global auto_run_time_m)' '$(uci_get_by_type global auto_run_time_h)' * * * /usr/share/jd-dailybonus/newapp.sh -w' >>$CRON_FILE [ $(uci_get_by_type global auto_update 0) -eq 1 ] && echo '1 '$(uci_get_by_type global auto_update_time)' * * * /usr/share/jd-dailybonus/newapp.sh -u' >>$CRON_FILE crontab $CRON_FILE + /etc/init.d/cron restart } # Run Script -serverchan() { - sckey=$(uci_get_by_type global serverchan) - failed=$(uci_get_by_type global failed) - desc=$(cat /www/JD_DailyBonus.htm | grep -E '签到号|签到概览|签到奖励|其他奖励|账号总计|其他总计' | sed 's/$/&\n/g') - serverurlflag=$(uci_get_by_type global serverurl) - serverurl=https://sc.ftqq.com/ - if [ "$serverurlflag" = "sct" ]; then - serverurl=https://sctapi.ftqq.com/ - fi - if [ $failed -eq 1 ]; then - grep "Cookie失效" /www/JD_DailyBonus.htm > /dev/null - if [ $? -eq 0 ]; then - title="$(date '+%Y年%m月%d日') 京东签到 Cookie 失效" - wget-ssl -q --output-document=/dev/null --post-data="text=$title~&desp=$desc" $serverurl$sckey.send - fi +notify() { + grep "Cookie失效" /www/JD_DailyBonus.htm >/dev/null + if [ $? -eq 0 ]; then + title="$(date '+%Y年%m月%d日') 京东签到 Cookie 失效" else title="$(date '+%Y年%m月%d日') 京东签到" + fi + desc=$(cat /www/JD_DailyBonus.htm | grep -E '签到号|签到概览|签到奖励|其他奖励|账号总计|其他总计' | sed 's/$/&\n/g') + #serverchan + sckey=$(uci_get_by_type global serverchan) + if [ ! -z $sckey ]; then + serverurlflag=$(uci_get_by_type global serverurl) + serverurl=https://sc.ftqq.com/ + if [ "$serverurlflag" = "sct" ]; then + serverurl=https://sctapi.ftqq.com/ + fi wget-ssl -q --output-document=/dev/null --post-data="text=$title~&desp=$desc" $serverurl$sckey.send fi + #telegram + TG_BOT_TOKEN=$(uci_get_by_type global tg_token) + TG_USER_ID=$(uci_get_by_type global tg_userid) + API_URL="https://api.telegram.org/bot${TG_BOT_TOKEN}/sendMessage" + if [ ! -z $TG_BOT_TOKEN ] && [ ! -z $TG_USER_ID ]; then + text="*$title* + +\`\`\` +"$desc" +==================================== +本消息来自京东签到插件 jd-dailybonus +\`\`\`" + wget-ssl -q --output-document=/dev/null --post-data="chat_id=$TG_USER_ID&text=$text&parse_mode=markdownv2" $API_URL + fi } run() { - fill_cookie echo -e $(date '+%Y-%m-%d %H:%M:%S %A') >$LOG_HTM 2>/dev/null - [ ! -f "/usr/bin/node" ] && echo -e "未安装node.js,请安装后再试!\nNode.js is not installed, please try again after installation!">>$LOG_HTM && exit 1 - node $JD_SCRIPT >>$LOG_HTM 2>/dev/null -} - -back_run() { - run - sleep 1s - serverchan + [ ! -f "/usr/bin/node" ] && echo -e "未安装node.js,请安装后再试!\nNode.js is not installed, please try again after installation!" >>$LOG_HTM && exit 1 + node $JD_SCRIPT >>$LOG_HTM 2>/dev/null && notify & } save() { - fill_cookie add_cron } @@ -156,7 +136,6 @@ update() { fi remote_ver=$(get_ver $TEMP_SCRIPT) cp -r $TEMP_SCRIPT $JD_SCRIPT - fill_cookie uci set jd-dailybonus.@global[0].version=$remote_ver uci commit jd-dailybonus cancel "0" @@ -169,7 +148,7 @@ while getopts ":alnruswh" arg; do exit 0 ;; l) - serverchan + notify exit 0 ;; n) @@ -189,7 +168,7 @@ while getopts ":alnruswh" arg; do exit 0 ;; w) - back_run + run exit 0 ;; h) diff --git a/package/ctcgfw/luci-app-jd-dailybonus/root/usr/share/jd-dailybonus/requests.lua b/package/ctcgfw/luci-app-jd-dailybonus/root/usr/share/jd-dailybonus/requests.lua new file mode 100644 index 0000000000..c2fc4d702e --- /dev/null +++ b/package/ctcgfw/luci-app-jd-dailybonus/root/usr/share/jd-dailybonus/requests.lua @@ -0,0 +1,303 @@ +-- Lua Requests library for http ease + +local http_socket = require('socket.http') +local https_socket = require('ssl.https') +local url_parser = require('socket.url') +local ltn12 = require('ltn12') +local json = require('cjson.safe') +local md5sum = require('md5') -- TODO: Make modular? +local mime = require('mime') + +local requests = { + _DESCRIPTION = 'Http requests made simpler', + http_socket = http_socket, + https_socket = https_socket +} + +local _requests = {} + +--User facing function the make a request use Digest Authentication +--TODO: Determine what else should live in authentication +function requests.HTTPDigestAuth(user, password) + return { _type = 'digest', user = user, password = password} +end + +--User facing function the make a request use Basic Authentication +--TODO: Determine what else should live in authentication +function requests.HTTPBasicAuth(user, password) + return { _type = 'basic', user = user, password = password} +end + +function requests.post(url, args) + return requests.request("POST", url, args) +end + +function requests.get(url, args) + return requests.request("GET", url, args) +end + +function requests.delete(url, args) + return requests.request("DELETE", url, args) +end + +function requests.patch(url, args) + return requests.request("PATCH", url, args) +end + +function requests.put(url, args) + return requests.request("PUT", url, args) +end + +function requests.options(url, args) + return requests.request("OPTIONS", url, args) +end + +function requests.head(url, args) + return requests.request("HEAD", url, args) +end + +function requests.trace(url, args) + return requests.request("TRACE", url, args) +end + +--Sets up all the data for a request and makes the request +function requests.request(method, url, args) + local request + + if type(url) == "table" then + request = url + if not request.url and request[1] then + request.url = table.remove(request, 1) + end + else + request = args or {} + request.url = url + end + + request.method = method + _requests.parse_args(request) + + -- TODO: Find a better way to do this + if request.auth and request.auth._type == 'digest' then + local response = _requests.make_request(request) + return _requests.use_digest(response, request) + else + return _requests.make_request(request) + end +end + +--Makes a request +function _requests.make_request(request) + local response_body = {} + local full_request = { + method = request.method, + url = request.url, + headers = request.headers, + sink = ltn12.sink.table(response_body), + redirect = request.allow_redirects, + proxy = request.proxy + } + if request.data then + full_request.source = ltn12.source.string(request.data) + end + + local response = {} + local ok + local socket = string.find(full_request.url, '^https:') and not request.proxy and https_socket or http_socket + + ok, response.status_code, response.headers, response.status = socket.request(full_request) + + assert(ok, 'error in '..request.method..' request: '..response.status_code) + response.text = table.concat(response_body) + response.json = function () return json.decode(response.text) end + + return response +end + +--Parses through all the possible arguments for a request +function _requests.parse_args(request) + _requests.check_url(request) + _requests.check_data(request) + _requests.create_header(request) + _requests.check_timeout(request.timeout) + _requests.check_redirect(request.allow_redirects) +end + +--Format the the url based on the params argument +function _requests.format_params(url, params) -- TODO: Clean + if not params or next(params) == nil then return url end + + url = url..'?' + for key, value in pairs(params) do + if tostring(value) then + url = url..tostring(key)..'=' + + if type(value) == 'table' then + local val_string = '' + + for _, val in ipairs(value) do + val_string = val_string..tostring(val)..',' + end + + url = url..val_string:sub(0, -2) + else + url = url..tostring(value) + end + + url = url..'&' + end + end + + return url:sub(0, -2) +end + +--Check that there is a URL given and append to it if params are passed in. +function _requests.check_url(request) + assert(request.url, 'No url specified for request') + request.url = _requests.format_params(request.url, request.params) +end + +-- Add to the HTTP header +function _requests.create_header(request) + request.headers = request.headers or {} + if request.data then + request.headers['Content-Length'] = request.data:len() + end + + if request.cookies then + if request.headers.cookie then + request.headers.cookie = request.headers.cookie..'; '..request.cookies + else + request.headers.cookie = request.cookies + end + end + + if request.auth then + _requests.add_auth_headers(request) + end +end + +--Makes sure that the data is in a format that can be sent +function _requests.check_data(request) + if type(request.data) == "table" then + request.data = json.encode(request.data) + elseif request.data then + request.data = tostring(request.data) + end +end + +--Set the timeout +function _requests.check_timeout(timeout) + http_socket.TIMEOUT = timeout or 5 + https_socket.TIMEOUT = timeout or 5 +end + +--Checks is allow_redirects parameter is set correctly +function _requests.check_redirect(allow_redirects) + if allow_redirects and type(allow_redirects) ~= "boolean" then + error("allow_redirects expects a boolean value. received type = "..type(allow_redirects)) + end +end + +--Create the Authorization header for Basic Auth +function _requests.basic_auth_header(request) + local encoded = mime.b64(request.auth.user..':'..request.auth.password) + request.headers.Authorization = 'Basic '..encoded +end + +-- Create digest authorization string for request header TODO: Could be better, but it should work +function _requests.digest_create_header_string(auth) + local authorization = 'Digest username="'..auth.user..'", realm="'..auth.realm..'", nonce="'..auth.nonce + authorization = authorization..'", uri="'..auth.uri..'", qop='..auth.qop..', nc='..auth.nc + authorization = authorization..', cnonce="'..auth.cnonce..'", response="'..auth.response..'"' + + if auth.opaque then + authorization = authorization..', opaque="'..auth.opaque..'"' + end + + return authorization +end + +--MD5 hash all parameters +local function md5_hash(...) + return md5sum.sumhexa(table.concat({...}, ":")) +end + +-- Creates response hash TODO: Add functionality +function _requests.digest_hash_response(auth_table) + return md5_hash( + md5_hash(auth_table.user, auth_table.realm, auth_table.password), + auth_table.nonce, + auth_table.nc, + auth_table.cnonce, + auth_table.qop, + md5_hash(auth_table.method, auth_table.uri) + ) +end + +-- Add digest authentication to the request header +function _requests.digest_auth_header(request) + if not request.auth.nonce then return end + + request.auth.cnonce = request.auth.cnonce or string.format("%08x", os.time()) + + request.auth.nc_count = request.auth.nc_count or 0 + request.auth.nc_count = request.auth.nc_count + 1 + + request.auth.nc = string.format("%08x", request.auth.nc_count) + + local url = url_parser.parse(request.url) + request.auth.uri = url_parser.build{path = url.path, query = url.query} + request.auth.method = request.method + request.auth.qop = 'auth' + + request.auth.response = _requests.digest_hash_response(request.auth) + + request.headers.Authorization = _requests.digest_create_header_string(request.auth) +end + +--Checks the resonse code and adds additional headers for Digest Auth +-- TODO: Rename this +function _requests.use_digest(response, request) + if response.status_code == 401 then + _requests.parse_digest_response_header(response,request) + _requests.create_header(request) + response = _requests.make_request(request) + response.auth = request.auth + response.cookies = request.headers.cookie + return response + else + response.auth = request.auth + response.cookies = request.headers.cookie + return response + end +end + +--Parse the first response from the host to make the Authorization header +function _requests.parse_digest_response_header(response, request) + for key, value in response.headers['www-authenticate']:gmatch('(%w+)="(%S+)"') do + request.auth[key] = value + end + + if request.headers.cookie then + request.headers.cookie = request.headers.cookie..'; '..response.headers['set-cookie'] + else + request.headers.cookie = response.headers['set-cookie'] + end + + request.auth.nc_count = 0 +end + +-- Call the correct authentication header function +function _requests.add_auth_headers(request) + local auth_func = { + basic = _requests.basic_auth_header, + digest = _requests.digest_auth_header + } + + auth_func[request.auth._type](request) +end + +--Return public functions +requests._private = _requests +return requests