local function escape(x) x=x:gsub("([%+%-%*%.%%%?%^%$%(%)%[%]])","%%%1") return x end local function sleep(x) if x>0 then os.execute("ping -n "..tostring(x+1).." localhost > NUL") end end local function fread(f) local h,x = io.open(f or "debug.bin","rb"),nil if h then x=h:read("*all"); io.close(h) end return x end local function fwrite(s,f) s = s or "" local h,x = io.open(f or "debug.bin","wb"),nil if h then x=h:write(s); io.close(h) end return x end local function fappend(s,f) s = s or "" local h,x = io.open(f or "debug.bin","ab"),nil if h then x=h:write(s); io.close(h) end return x end local function GetPage(x) local s0="" if x then s0=io.popen('curl.exe -g -k -L --location-trusted '..x,"rb"):read("*all") end return s0 end local function encURL(x) x=string.gsub(x,"[^0-9A-Za-z%.%-_~]",function(x) local x,s=string.byte(x),"0123456789ABCDEF" local z,y=math.floor(x/16)+1,math.mod(x,16)+1 return "%"..string.sub(s,z,z)..string.sub(s,y,y) end) return x end local function encPath(x) x=string.gsub(x,"[^0-9A-Za-z%.%-_~/]",function(x) local x,s=string.byte(x),"0123456789ABCDEF" local z,y=math.floor(x/16)+1,math.mod(x,16)+1 return "%"..string.sub(s,z,z)..string.sub(s,y,y) end) return x end local function fdebug(m,tdir) fappend(os.date("%d.%m.%y %H:%M:%S").." "..m.."\n",(tdir or "C:\\Lua5\\").."debug.txt") end local function Utf8ToOem(x) return win.WideCharToMultiByte(win.MultiByteToWideChar(x,65001),866) end local function Utf8ToAnsi(x) return win.WideCharToMultiByte(win.MultiByteToWideChar(x,65001),1251) end local ftask="C:\\Lua5\\flist.txt" local tdir0="H:\\Temp\\" local token="..." -- your token local urlh0='-H "Content-Type: application/json"' local urlh='-H "Authorization: OAuth '..token..'" '..urlh0 local fnflt='[%?%*"<>|:\\/#]' local dldir='disk%3A%2F%D0%97%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BA%D0%B8%2F' -- disk:/Загрузки/ local function TaskAdd(c,a,b) a,b,c = a or "",b or "",c or "" if a~="" then local r,s=false,fread(ftask) if s then for x in s:gmatch("purl: (%C-)[;%c]") or s:gmatch("purl: (%C-)$") do if x==a then r=true break end end end if not r then l="purl: "..a if b~="" then l=l.."; tdir: "..b end l=l.."\n" c=c:lower() if c=="ins" then print("MSG: Paste task to queue 1st") fwrite(l..s,ftask) elseif c=="add" then print("MSG: Paste task to queue last") fwrite(s..l,ftask) end end end end local function TaskRemove(purl) print("MSG: Delete task from queue") local s=fread(ftask) if s and s~="" and s:match("\n") then s=s:gsub("purl: "..escape(purl)..".-\n","") else s="" end fwrite(s,ftask) end local function TaskRead() print("MSG: Read task from queue") local s,a,b = fread(ftask) if s and s~="" then a=s:match("^purl: (%C-)[;%c]") or s:match("^purl: (%C-)$") b=s:match("^purl: %C-; tdir: (%C-)%c") or s:match("^purl: %C-; tdir: (%C-)$") end return a,b end local function PublishUrl(urlh,path) print("MSG: Get public URL...") local url='https://cloud-api.yandex.net/v1/disk/resources/publish?path='..encURL(path) print('url="'..url..'" path="'..win.Utf8ToOem(path)..'"') return GetPage(urlh..' -X PUT "'..url..'"'):match('"href"%s-:%s-"(.-)"') end local function UnPublishUrl(urlh,path) print("MSG: Close public URL...") local url='https://cloud-api.yandex.net/v1/disk/resources/unpublish?path='..encURL(path) print('url="'..url..'" path="'..win.Utf8ToOem(path)..'"') return GetPage(urlh..' -X PUT "'..url..'"'):match('"href"%s-:%s-"(.-)"') end local function GetUrlForUploadToDisk(urlh,path) print("MSG: Get URL for upload local file to my YADisk...") local url='https://cloud-api.yandex.net/v1/disk/resources/upload?path='..encURL(path) print('url="'..url..'" path="'..win.Utf8ToOem(path)..'"') return GetPage(urlh..' -X GET "'..url..'"'):match('"href"%s-:%s-"(.-)"') end local function GetMetaInfo(urlh,path) print("MSG: Get MetaInfo about object...") local url='https://cloud-api.yandex.net/v1/disk/resources?path='..encURL(path) print('url="'..url..'" path="'..win.Utf8ToOem(path)..'"') return GetPage(urlh..' -X GET "'..url..'"') end local function CreateDir(urlh,path) print("MSG: Create directory...") local url='https://cloud-api.yandex.net/v1/disk/resources?path='..encURL(path) print('url="'..url..'" path="'..win.Utf8ToOem(path)..'"') return GetPage(urlh..' -X PUT "'..url..'"'):match('"href"%s-:%s-"(.-)"') end local function DeleteObj(urlh,path) print("MSG: Delete object...") local url='https://cloud-api.yandex.net/v1/disk/resources?path='..encURL(path) print('url="'..url..'" path="'..win.Utf8ToOem(path)..'"') return GetPage(urlh..' -X DELETE "'..url..'&permanently=true"') end local function MoveObj(urlh,src,dst) print("MSG: Move object...") local url='https://cloud-api.yandex.net/v1/disk/resources/move?from='..encURL(src)..'&path='..encURL(dst) print('url="'..url..'" src="'..win.Utf8ToOem(src)..'" dst="'..win.Utf8ToOem(dst)..'"') return GetPage(urlh..' -X POST "'..url..'"'):match('"href"%s-:%s-"(.-)"') end local function CopyObj(urlh,src,dst) print("MSG: Copy object...") local url='https://cloud-api.yandex.net/v1/disk/resources/copy?from='..encURL(src)..'&path='..encURL(dst) print('url="'..url..'" src="'..win.Utf8ToOem(src)..'" dst="'..win.Utf8ToOem(dst)..'"') return GetPage(urlh..' -X POST "'..url..'"'):match('"href"%s-:%s-"(.-)"') end local function UploadLocalFileToDisk(urlh,url,f) print("MSG: Upload local file to my YADisk...") return GetPage(urlh..' -T "'..f..'" -X PUT "'..url..'"') end local function GetDirectURL(urlh,url) print("MSG: Get direct link...") return GetPage(urlh..' -X GET "'..url..'"'):match('"href"%s-:%s-"(.-)"') end local function GetStatusOp(urlh,idOp) print("MSG: Get status operation...") return GetPage(urlh..' -X GET "https://cloud-api.yandex.net/v1/disk/operations/'..idOp..'"') end local function SaveInetFileToDisk(urlh,url,path) print("MSG: Save inet file to my YADisk...") if not path then path=dldir end local s1,s2=url:match("([A-Za-z]-://.-/)(.+)$") url=s1..encPath(s2) local site,fname=url:match('^(.+/)(.-)$') local url='https://cloud-api.yandex.net/v1/disk/resources/upload?url='..encURL(url)..'&path='..path..fname local s=GetPage(urlh..' -X POST "'..url..'"') --fwrite("url: "..url.."\nanswer:\n"..s) return s:match('"href"%s-:%s-"https://cloud%-api%.yandex%.net/v1/disk/operations%?id=(.-)"') end local function SaveToDisk(urlh,key) print("MSG: Save public file to my YADisk...") local url='https://cloud-api.yandex.net/v1/disk/public/resources/save-to-disk/?public_key='..encURL(key) return GetPage(urlh..' -X POST "'..url..'"'):match('"href"%s-:%s-"(https://cloud%-api%.yandex%.net/v1/disk/resources%?path=.-)"') end local function fDelete(urlh,url) print("MSG: Deleting file from my YADisk...") print(GetPage(urlh..' -X DELETE "'..url..'&permanently=true"')) -- delete file from YADisk end local function CheckSize(x) local s,h = nil,io.open(x,"rb") if h then s=h:seek("end") h:close() end return s end local function fDownload(purl,urlh,url,tdir,fname,fpath,fsize,fResume) --print("MSG: File: "..win.Utf8ToOem(fname)) fpath=string.gsub(fpath,".",function(x) if string.byte(x)<32 then x="" end return x end) --fwrite(fpath) if url then local line=urlh..' -X GET "'..url..'" -o "'..fpath..'"' local dsize=CheckSize(fpath) if dsize==fsize then print("MSG: Complete file present in target directory") TaskRemove(purl) -- delete downloaded task else if dsize and fResume and dsize>0 and dsize<fsize then print("MSG: Downloaded "..dsize.."/"..fsize.." ("..(math.ceil(dsize/fsize*1000)/10).."%), resuming...") line=line..' -C -' else print("MSG: File is not exists in target directory, start new download...") line=line..' --create-dirs' end local res=GetPage(line.." -w %{http_code}") -- download file dsize=CheckSize(fpath) if dsize==fsize then print("MSG: Task done, code: "..res) TaskRemove(purl) -- delete finished task else print("MSG: Download error") end end else local m="Error: can't download - URL is nil" print("MSG: "..m) fdebug(m..", purl: "..purl,tdir) end end local function GetYAD(purl,tdir) if purl then if not tdir then tdir=tdir0 end local url=GetPage('"'..purl..'"') local patt='"mediatype"%s-:%s-".-",.-,"size"%s-:%s-(%d-)},"mtime"%s-:%s-(%d-),"utime"%s-:%s-%d-,"type"%s-:%s-"file","name"%s-:%s-"(.-)",.-,"hash"%s-:%s-"(.-)"' --fwrite(url) local fsize,ftime,fname,key=url:match(patt) if fsize and ftime and fname and key then fname=fname:gsub("\\u0026","&"):gsub("&#(%d-);",function(s) return s:char() end) print("MSG: File: "..win.Utf8ToOem(fname).." Size: "..fsize.." Date: "..os.date("%d.%m.%y %H:%M:%S",ftime)) local line1='fname: '..fname..'\nfsize: '..fsize..'\nftime: '..os.date("%d.%m.%y %H:%M:%S",ftime)..'\nkey: '..key..'\npurl: '..purl local fpath,fsize,fResume = tdir..fname,tonumber(fsize),false local line0=fread(fpath..'.txt') if line0 and line1:match("^(.-)\nkey:")==line0:match("^(.-)\nkey:") then fResume=true else fwrite(line1,fpath..'.txt') end local url0='https://cloud-api.yandex.net/v1/disk/resources?path='..dldir..encURL(fname) url=url0:gsub("(resources)(%?path)","%1/download%2") local res=GetDirectURL(urlh,url) -- the file exists on my YADisk? if not res then res=SaveToDisk(urlh,key) url=res:gsub("(resources)(%?path)","%1/download%2") res=GetDirectURL(urlh,url) -- the file exists on my YADisk? local i=0 while not res and i<12 do print("MSG: File is not saved yet, wait 5 seconds...") sleep(5) res=GetDirectURL(urlh,url) -- the file exists on my YADisk? i=i+1 end if res then print("MSG: File saved to my YADisk, direct URL received, downloading from my YAD...") url=res:gsub("%+","%%20"):gsub("(resources)(%?path)","%1/download%2") fDownload(purl,urlh,url,tdir,fname,fpath,fsize,fResume) local dsize=CheckSize(fpath) if dsize==fsize then fDelete(urlh,url0) end else print("MSG: Error save file to my YADisk, downloading from public resource...") url='https://cloud-api.yandex.net/v1/disk/public/resources/download?public_key='..encURL(key) res=GetDirectURL(urlh0,url) if res then url=res:gsub("%+","%%20") fDownload(purl,urlh0,url,tdir,fname,fpath,fsize,fResume) else m="Error: can't get direct URL for public resource" print("MSG: "..m) fdebug(m..", url: "..url,tdir) end end else print("MSG: File present on my YADisk") url=res:gsub("%+","%%20"):gsub("(resources)(%?path)","%1/download%2") fDownload(purl,urlh,url,tdir,fname,fpath,fsize,fResume) local dsize=CheckSize(fpath) if dsize==fsize then fDelete(urlh,url0) end end else local m="Error: answer is not recognized" print("MSG: "..m) fdebug(m..", purl: "..purl,tdir) end else print("MSG: Task list is clear") end end local function SaveInetFileToYAD(purl,tdir) SaveInetFileToDisk(urlh,purl,tdir) TaskRemove(purl) end local function UploadLocalFileToYAD(purl,tdir) if not tdir then tdir='/Temp/' end tdir=tdir..purl:gsub('^.+\\','') local i,url0=0,'https://cloud-api.yandex.net/v1/disk/resources/download?path=disk%3A'..encURL(tdir) local res=GetDirectURL(urlh,url0) while not res and i<12 do local url=GetUrlForUploadToDisk(urlh,tdir) print(UploadLocalFileToDisk(urlh.." --limit-rate 40k",url,purl)) res=GetDirectURL(urlh,url0) i=i+1 end if res then TaskRemove(purl) else local m="File is not uploaded, purl: "..purl..", encURL: "..encURL(tdir) print("MSG: "..m) fdebug(m) end end if arg[2] and (arg[2]:match("https?://") or arg[2]:match("[A-Za-z]:\\")) then TaskAdd(arg[1],arg[2],arg[3]) end while true do local purl,tdir=TaskRead() if purl then if purl:match("https?://yadi%.sk/") or purl:match("https?://narod%.ru/disk/") then GetYAD(purl,tdir) elseif purl:match("https?://") then SaveInetFileToYAD(purl,tdir) elseif purl:match("[A-Za-z]:\\") then UploadLocalFileToYAD(purl,tdir) end print("MSG: Wait 5 seconds before start next task...") sleep(5) else print("MSG: No more tasks") break end end |