pastebin rework round 3

This commit is contained in:
kepler155c@gmail.com 2019-04-12 08:33:41 -04:00
parent f011e7b14f
commit a77d55e33f
3 changed files with 157 additions and 135 deletions

View File

@ -1,150 +1,128 @@
--- Parse the pastebin code from the given code or URL
local function parseCode(paste)
local patterns = {
"^([%a%d]+)$",
"^https?://pastebin.com/([%a%d]+)$",
"^pastebin.com/([%a%d]+)$",
"^https?://pastebin.com/raw/([%a%d]+)$",
"^pastebin.com/raw/([%a%d]+)$",
}
--- Attempts to guess the pastebin ID from the given code or URL
local function extractId(paste)
local patterns = {
"^([%a%d]+)$",
"^https?://pastebin.com/([%a%d]+)$",
"^pastebin.com/([%a%d]+)$",
"^https?://pastebin.com/raw/([%a%d]+)$",
"^pastebin.com/raw/([%a%d]+)$",
}
for i = 1, #patterns do
local code = paste:match(patterns[i])
if code then
return code
end
end
for i = 1, #patterns do
local code = paste:match( patterns[i] )
if code then return code end
end
return nil
return nil
end
function download(url)
if type( url ) ~= "string" then
error( "bad argument #1 (expected string, got " .. type( url ) .. ")", 2 )
end
-- Download the contents of a paste
local function download(url)
if type(url) ~= "string" then
error("bad argument #1 (expected string, got " .. type(url) .. ")", 2)
end
if not http then
return false, "Pastebin requires http API"
end
if not http then
return false, "Pastebin requires http API"
end
local paste = extractId( url )
if not paste then
return false, "Invalid pastebin code. The code is the ID at the end of the pastebin.com URL."
end
-- Add a cache buster so that spam protection is re-checked
local cacheBuster = ("%x"):format(math.random(0, 2 ^ 30))
local response, err = http.get(
"https://pastebin.com/raw/" .. textutils.urlEncode(paste) .. "?cb=" .. cacheBuster
)
-- Add a cache buster so that spam protection is re-checked
local cacheBuster = ("%x"):format(math.random(0, 2^30))
local response, err = http.get(
"https://pastebin.com/raw/"..textutils.urlEncode( paste ).."?cb="..cacheBuster
)
if not response then
return response, err
end
if not response then
return response, err
end
-- If spam protection is activated, we get redirected to /paste with Content-Type: text/html
local headers = response.getResponseHeaders()
if not headers["Content-Type"] or not headers["Content-Type"]:find("^text/plain") then
return false, "Pastebin blocked due to spam protection"
end
-- If spam protection is activated, we get redirected to /paste with Content-Type: text/html
local headers = response.getResponseHeaders()
if not headers["Content-Type"] or not headers["Content-Type"]:find( "^text/plain" ) then
return false, "Pastebin blocked the download due to spam protection. Please complete the captcha in a web browser: https://pastebin.com/" .. textutils.urlEncode( paste )
end
local sResponse = response.readAll()
response.close()
return sResponse
local contents = response.readAll()
response.close()
return contents
end
local function put(sPath)
if type( sPath ) ~= "string" then
error( "bad argument #1 (expected string, got " .. type( sPath ) .. ")", 2 )
end
-- Upload text to pastebin
local function upload(name, text)
if not http then
return false, "Pastebin requires http API"
end
if not http then
return false, "Pastebin requires http API"
end
-- POST the contents to pastebin
local key = "0ec2eb25b6166c0c27a394ae118ad829"
local response = http.post(
"https://pastebin.com/api/api_post.php",
"api_option=paste&" ..
"api_dev_key=" .. key .. "&" ..
"api_paste_format=lua&" ..
"api_paste_name=" .. textutils.urlEncode(name) .. "&" ..
"api_paste_code=" .. textutils.urlEncode(text)
)
-- Upload a file to pastebin.com
-- Determine file to upload
if not fs.exists( sPath ) or fs.isDir( sPath ) then
return false, "No such file"
end
if not response then
return false, "Failed."
end
-- Read in the file
local sName = fs.getName( sPath )
local file = fs.open( sPath, "r" )
local sText = file.readAll()
file.close()
local contents = response.readAll()
response.close()
-- POST the contents to pastebin
local key = "0ec2eb25b6166c0c27a394ae118ad829"
local response = http.post(
"https://pastebin.com/api/api_post.php",
"api_option=paste&"..
"api_dev_key="..key.."&"..
"api_paste_format=lua&"..
"api_paste_name="..textutils.urlEncode(sName).."&"..
"api_paste_code="..textutils.urlEncode(sText)
)
if response then
local sResponse = response.readAll()
response.close()
return string.match( sResponse, "[^/]+$" )
end
return false, "Failed."
return string.match(contents, "[^/]+$")
end
local function get(sCode, sPath)
if type( sCode ) ~= "string" then
error( "bad argument #1 (expected string, got " .. type( sCode ) .. ")", 2 )
end
-- Download the contents to a file from pastebin
local function get(code, path)
if type(code) ~= "string" then
error( "bad argument #1 (expected string, got " .. type(code) .. ")", 2)
end
if type( sPath ) ~= "string" then
error( "bad argument #2 (expected string, got " .. type( sPath ) .. ")", 2 )
end
if type(path) ~= "string" then
error("bad argument #2 (expected string, got " .. type(path) .. ")", 2)
end
if not http then
return false, "Pastebin requires http API"
end
local res, msg = download(code)
if not res then
return res, msg
end
if fs.exists( sPath ) then
return false, "File already exists"
end
local file = fs.open(path, "w")
file.write(res)
file.close()
-- GET the contents from pastebin
local res, msg = download(sCode)
if not res then
return res, msg
end
local file = fs.open( sPath, "w" )
file.write( res )
file.close()
return sPath
return true
end
local function run(sCode, ...)
if not http then
return false, "Pastebin requires http API"
end
-- Upload a file to pastebin.com
local function put(path)
if type(path) ~= "string" then
error("bad argument #1 (expected string, got " .. type(path) .. ")", 2)
end
if type( sCode ) ~= "string" then
error( "bad argument #1 (expected string, got " .. type( sCode ) .. ")", 2 )
end
-- Determine file to upload
if not fs.exists(path) or fs.isDir(path) then
return false, "No such file"
end
local res, msg = download(sCode)
if not res then
return res, msg
end
local func, err = load(res, sCode, "t", _ENV)
if not func then
return func, err
end
return pcall(func, ...)
-- Read in the file
local name = fs.getName(path)
local file = fs.open(path, "r")
local text = file.readAll()
file.close()
return upload(name, text)
end
return {
get = get,
put = put,
run = run,
}
download = download,
upload = upload,
get = get,
put = put,
parseCode = parseCode,
}

View File

@ -1,4 +1,3 @@
local function printUsage()
print( "Usages:" )
print( "pastebin put <filename>" )
@ -6,12 +5,6 @@ local function printUsage()
print( "pastebin run <code> <arguments>" )
end
local tArgs = { ... }
if #tArgs < 2 then
printUsage()
return
end
if not http then
printError( "Pastebin requires http API" )
printError( "Set http_enable to true in ComputerCraft.cfg" )
@ -20,9 +13,17 @@ end
local pastebin = require('http.pastebin')
local tArgs = { ... }
local sCommand = tArgs[1]
if sCommand == "put" then
-- Upload a file to pastebin.com
if #tArgs < 2 then
printUsage()
return
end
-- Determine file to upload
local sFile = tArgs[2]
local sPath = shell.resolve( sFile )
@ -45,15 +46,18 @@ if sCommand == "put" then
elseif sCommand == "get" then
-- Download a file from pastebin.com
if #tArgs < 3 then
printUsage()
return
end
print( "Connecting to pastebin.com... " )
local sCode = pastebin.parseCode(tArgs[2])
if not sCode then
return false, "Invalid pastebin code. The code is the ID at the end of the pastebin.com URL."
end
-- Determine file to download
local sCode = tArgs[2]
local sFile = tArgs[3]
local sPath = shell.resolve( sFile )
if fs.exists( sPath ) then
@ -61,21 +65,45 @@ elseif sCommand == "get" then
return
end
print( "Connecting to pastebin.com... " )
local resp, msg = pastebin.get(sCode, sPath)
if resp then
print( "Downloaded as "..resp )
print( "Downloaded as " .. sPath )
else
printError( msg )
end
elseif sCommand == "run" then
local sCode = tArgs[2]
-- Download and run a file from pastebin.com
if #tArgs < 2 then
printUsage()
return
end
local sCode = pastebin.parseCode(tArgs[2])
if not sCode then
return false, "Invalid pastebin code. The code is the ID at the end of the pastebin.com URL."
end
print( "Connecting to pastebin.com... " )
local resp, msg = pastebin.run(sCode, table.unpack(tArgs, 3))
if not resp then
local res, msg = pastebin.download(sCode)
if not res then
printError( msg )
return res, msg
end
res, msg = load(res, sCode, "t", _ENV)
if not res then
printError( msg )
return res, msg
end
res, msg = pcall(res, table.unpack(tArgs, 3))
if not res then
printError( msg )
end
else
@ -83,3 +111,4 @@ else
printUsage()
return
end

15
sys/help/pastebin Normal file
View File

@ -0,0 +1,15 @@
pastebin is a program for uploading files to and downloading files from pastebin.com. This is useful for sharing programs with other players.
The HTTP API must be enabled in ComputerCraft.cfg to use this program.
ex:
"pastebin put foo" will upload the file "foo" to pastebin.com, and print the URL.
"pastebin get xq5gc7LB foo" will download the file from the URL http://pastebin.com/xq5gc7LB, and save it as "foo".
"pastebin run CxaWmPrX" will download the file from the URL http://pastebin.com/CxaWmPrX, and immediately run it.
Functions in the pastebin API:
pastebin.get( code, filepath )
pastebin.put( filepath )
pastebin.download( code )
pastebin.upload( pastename, text )
pastebin.parseCode( code )