#!/usr/bin/lua pcall(require, "luarocks.require") local socket = require ("socket") local ftp = require("socket.ftp") local http = require "socket.http" local ltn12 = require "ltn12" pcall(dofile,"luapaste.conf") local Services, Options, Files = {}, {}, {} local LP = { default_matcher = "", --function to process response from server for url service = DEFAULT_SERVICE or "", --service to use language = DEFAULT_LANGUAGE or "", --language to use services = {}, --available services (addService) options = {}, --available options (addOption) files = {}, --files to create textdata (fileList) textdata = "", --what to send (fData) description = "", --description of paste, filename or -d or stdin run = false, private = false, boundary = "##ThIs_iS_ThE_BoUnDaRy##", nick = DEFAULT_NICK or os.getenv("USER"), concat = false, } -- url = "http://codepad.org/"; -- url = "http://www.rafb.net/paste/paste.php"; -- url = "http://pastebin.ca/"; -- url = "http://dpaste.com/"; -- url = "http://pastebin.osuosl.org/"; function str__mod(lhs, rhs) if type(rhs) == "table" then return lhs:format(unpack(rhs)) else return lhs:gsub('%%', '%%%%'):gsub('%%%%', '%%', 1):format(rhs) end end getmetatable("").__mod = str__mod function createFormData(name, info) local t = { '--'..LP.boundary, 'Content-Disposition: form-data; name="%s"' % name, '', '%s' % info, } return table.concat(t, "\r\n") end function createEnd() local t = { '--'..LP.boundary..'--', '', } return table.concat(t, "\r\n") end function fdata(file) local fd = assert(io.open(file, "rb")) local buf = fd:read "*a" fd:close() -- return buf LP.textdata = buf end function fdataConcat() local fd local buf = "" for k, file in pairs(LP.files) do fd = assert(io.open(file, "rb")) buf = buf..file.."\n"..fd:read "*a" fd:close() end LP.textdata = buf -- return buf end function addService(tbl, service_name, service_url, languages_tbl, body_func, url_match) --tbl = LP tbl.services[service_name] = { url = service_url, languages = languages_tbl, -- body = "", matcher = url_match or nil, -- BODY = body_func, --function to create a body from LP.textdata (made with fData) } end CODEPAD_LANGUAGES = { "C", "C++", "D", "Haskell", "Lua", "OCaml", "PHP", "Perl", "Plain Text", "Python", "Ruby", "Scheme", "Tcl", } CA_LANGUAGES = { ["ASP"] = "22"; ["Action Script"] = "18"; ["Ada"] = "19"; ["Apache Configuration"] = "20"; ["Assembl (NASM)"] = "21"; ["Asterisk Configuration"] = "2"; ["BASH"] = "23"; ["C"] = "3"; ["C#"] = "9"; ["C++"] = "4"; ["CSS"] = "24"; ["Delphi"] = "25"; ["HTML 4.0 Strict"] = "26"; ["Java"] = "7"; ["JavaScript"] = "27"; ["LISP"] = "28"; ["Lua"] = "29"; ["Microprocessor ASM"] = "30"; ["Objective C"] = "31"; ["PHP"] = "5"; ["PL/I"] = "14"; ["Pascal"] = "12"; ["Perl"] = "6"; ["Python"] = "11"; ["Raw"] = "1"; ["Ruby"] = "10"; ["SQL Statement"] = "16"; ["Scheme"] = "17"; ["Visual Basic .NET"] = "32"; ["Visual Basic"] = "8"; ["XML Document"] = "15"; ["mIRC Script"] = "13"; } MYSTIC_LANGUAGES = { "as3", "bash", "csharp", "cpp", "css", "delphi", "diff", "groovy", "java", "js", "javafx", "perl", "php", "text", "powershell", "python", "ruby", "scala", "sql", "vb", "xml", } DPASTE_LANGUAGES = { "Python", "PythonConsole", "Sql", "DjangoTemplate", "JScript", "Css", "XmL", "Diff", "Ruby", "Rhtml", "Haskell", "Apache", "Bash", "Plain", } function CODEPAD_BODY() --passed to addService as body_func local run = LP.run local private = LP.private if run then run = "True" else run = "False" end if private then private = "True" else private = "False" end local body = { createFormData("client", "luapaste.lua"), createFormData("run", run), createFormData("lang", LP.language), createFormData("private", private), createFormData("submit", "Submit"), createFormData("code", LP.textdata), -- table.insert(body, createFormData("code", fdata(file))) createEnd(), } return table.concat(body, "\r\n") end function CA_BODY() --[[ local language = "Raw" if LP.services[LP.service].languages[LP.language] then language = LP.language else print("Invalid service, defaulting to Raw") end --]] local body = { createFormData("s", "Submit Post"), createFormData("name", LP.nick), createFormData("description", LP.description), createFormData("type", LP.language), createFormData("expiry", "15 minutes"), createFormData("content", LP.textdata), -- createFormData("api", "moFXXusXQpQ3zlOyYgsXuG74HzYErXkx"), createEnd(), } return table.concat(body, "\r\n") end function MYSTIC_BODY() local private = LP.private if private then private = "true" else private = "false" end local body = { createFormData("description", 'luapaste'), -- createFormData("", "hi"), -- createFormData("submit", "Paste"), -- createFormData("type", LP.language), -- createFormData("pasteForm1_hf_0", "Submit"), createFormData("fileExt", 'bash'), createFormData("name", 'kiwi'), createFormData("content", 'HI'), -- createFormData("paste_submit", "Paste"), createEnd(), } return table.concat(body, "\r\n") end local function DPASTE_BODY() local body = { -- createFormData("pasteform", ""), createFormData("content", LP.textdata), -- createFormData("language", LP.language), createFormData("title", LP.description), -- createFormData("poster", LP.nick), --createFormData("pasteform", "Paste it"), -- createFormData("pasteform", "post"), createEnd(), -- '--'..LP.boundary..'--', -- ' ', } return table.concat(body, "\r\n") end function CODEPAD_MATCHER(response) local url = response:match('The resource was found at (.*);') return "\nhttp://codepad.org"..url end function CA_MATCHER(response) local url = response:match('SUCCESS:(.*)') return "\nhttp://pastebin.ca/"..url --return response end local function MYSTIC_MATCHER(response) local url = response return "http://mysticpaste.com/view/"..url end function DPASTE_MATCHER(response) local url = response return url end addService(LP, "codepad", "http://codepad.org/", CODEPAD_LANGUAGES, CODEPAD_BODY, CODEPAD_MATCHER) --moFXXusXQpQ3zlOyYgsXuG74HzYErXkx addService(LP, "ca", "http://pastebin.ca/quiet-paste.php?api=moFXXusXQpQ3zlOyYgsXuG74HzYErXkx", CA_LANGUAGES, CA_BODY, CA_MATCHER) addService(LP, "mystic", "http://www.mysticpaste.com/servlet/plugin", MYSTIC_LANGUAGES, MYSTIC_BODY, MYSTIC_MATCHER) --addService(LP, "mystic", "http://www.mysticpaste.com/new", MYSTIC_LANGUAGES, MYSTIC_BODY, MYSTIC_MATCHER) addService(LP, "dpaste", "http://dpaste.com/api/v1", DPASTE_LANGUAGES, DPASTE_BODY, DPASTE_MATCHER) function addOption(option_name, func_name, secondary_name) LP.options[option_name] = {on = false, params = {}, func = func_name} if secondary_name and secondary_name ~= option_name then LP.options[secondary_name] = {on = false, params = LP.options[option_name].params, func = func_name} end end function getOptions(options) local function resetFlags() for k in pairs(options) do options[k].on = false end end local cur_opt local args_left = #arg for i = 1, #arg do if string.match(arg[i], "^%-%-") then s = string.gsub(arg[i], "^%-%-", "") --if options[s] and string.len(s) > 1 then if options[s] and #s > 1 then options[s].on = true cur_opt = s else print("--"..s.." is an invalid option") resetFlags() end elseif string.match(arg[i], "^%-%a+") then --for j = 1, arg[i]:len()-1 do for j = 1, #arg[i]-1 do s = string.sub(arg[i], j+1, j+1) if options[s] then options[s].on = true cur_opt = s else print("-"..s.." is an invalid option") resetFlags() end end elseif cur_opt then table.insert(options[cur_opt].params, arg[i]) else -- table.insert(files, arg[i]) end end end function fileList(tbl) for k, v in ipairs(tbl) do table.insert(LP.files, v) end end addOption("f", fileList, "file") function pickService(tbl) LP.service = tbl[1] end addOption("s", pickService, "service") function pickLanguage(tbl) LP.language = tbl[1] end addOption("l", pickLanguage, "language") function private(tbl) LP.private = true end addOption("p", private, "private") function run(tbl) LP.run = true end addOption("r", run, "run") function concat(tbl) LP.concat = true end addOption("concat", concat) function post(filename) local body = LP.services[LP.service].BODY() local s_url = LP.services[LP.service].url local matcher = LP.services[LP.service].matcher or LP.default_matcher local head = { -- ["content-type"] = 'application/x-www-form-urlencoded; boundary=%s' % LP.boundary; ["content-type"] = 'multipart/form-data; boundary=%s' % LP.boundary; ["content-length"] = tostring(#body); ["accept"] = "text/xml", "text/html", "text/plain"; } local response = {} local source = ltn12.source.string(body) local sent = 0 local function progress() local data = source() sent = sent + #(data or "") local progress = sent/#body * 100 io.stdout:write("\rUploading %s: %d%" % filename % progress) return data end local r, e = http.request { method = "POST"; url = s_url; headers = head; source = progress; sink = ltn12.sink.table(response); } print() if not r then return nil, tostring(e) end response = table.concat(response) local err = response:match('') if err then return nil, err end local response_url = matcher(response) return response_url end getOptions(LP.options) for k in pairs(LP.options) do if LP.options[k].on == true then LP.options[k].func(LP.options[k].params) end end --sanity checks to decide if the program should continue to upload --service if not LP.services[LP.service] then print("Invalid service") return end --language if not (function() ---[[ for k, v in ipairs(LP.services[LP.service].languages) do if v == LP.language then return true end end --]] if LP.services[LP.service].languages[LP.language] then return true end end)() then print("Invalid language") return end if LP.concat then fdataConcat() local filelist = "" for k, v in ipairs(LP.files) do filelist = filelist..v end print(post(filelist)) else for k, v in ipairs(LP.files) do fdata(v) print(post(v)) end end