Skip to content

Commit

Permalink
Allow import on startup for sites other than pastebin (#4042)
Browse files Browse the repository at this point in the history
* feat: Allow import on startup for sites other than pastebin

* feat: add upload support for PoE.ninja

* fix: properly disabled buttons for all sites
  • Loading branch information
Wires77 authored Feb 4, 2022
1 parent 73fd196 commit e138e5d
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 88 deletions.
3 changes: 2 additions & 1 deletion manifest.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version='1.0' encoding='UTF-8'?>
<PoBVersion>
<Version number="2.13.0" />
<Version number="2.14.0" />
<Source part="default" url="https://raw.githubusercontent.com/PathOfBuildingCommunity/PathOfBuilding/{branch}/" />
<Source part="program" url="https://raw.githubusercontent.com/PathOfBuildingCommunity/PathOfBuilding/{branch}/src/" />
<Source part="tree" url="https://raw.githubusercontent.com/PathOfBuildingCommunity/PathOfBuilding/{branch}/src/" />
Expand Down Expand Up @@ -187,6 +187,7 @@
<File name="Data/StatDescriptions/variable_duration_skill_stat_descriptions.lua" part="program" sha1="fbf3309032bb7288b085b9e001b962827218d4e6" />
<File name="Modules/Build.lua" part="program" sha1="e1e9f2aea182d9cf3063ce7b1fc815d47f592634" />
<File name="Modules/BuildList.lua" part="program" sha1="5c5ee46b6dee4feb5bbfc2f5ef753073fa9303a9" />
<File name="Modules/BuildSiteTools.lua" part="program" sha1="7c3fe60cec98601f10f2261d45a2a177ebb56d26" />
<File name="Modules/CalcActiveSkill.lua" part="program" sha1="3f182fc3132033f9a21b8a709b24b130cb5d0175" />
<File name="Modules/CalcBreakdown.lua" part="program" sha1="b90cd2cd732249f95b0d1d42bc809f6c0d679e20" />
<File name="Modules/CalcDefence.lua" part="program" sha1="099667258dd13d162bfd11751df28715e23540a1" />
Expand Down
87 changes: 27 additions & 60 deletions src/Classes/ImportTab.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,6 @@ local realmList = {
{ label = "Tencent", id = "PC", realmCode = "pc", hostName = "https://poe.game.qq.com/", profileURL = "account/view-profile/" },
}

-- Import/Export websites list used in dropdowns
local importWebsiteList = {
{
label = "Pastebin.com", id = "Pastebin", matchURL = "pastebin%.com/%w+", regexURL = "pastebin%.com/(%w+)%s*$", downloadURL = "pastebin.com/raw/%1",
codeOut = "", postUrl = "https://pastebin.com/api/api_post.php", postFields = "api_dev_key=c4757f22e50e65e21c53892fd8e0a9ff&api_paste_private=1&api_option=paste&api_paste_code="
},
{ label = "PastebinP.com", id = "PastebinProxy", matchURL = "pastebinp%.com/%w+", regexURL = "pastebinp%.com/(%w+)%s*$", downloadURL = "pastebinp.com/raw/%1" },
{ label = "Rentry.co", id = "Rentry", matchURL = "rentry%.co/%w+", regexURL = "rentry%.co/(%w+)%s*$", downloadURL = "rentry.co/paste/%1/raw" },
{ label = "PoeNinja", id = "PoeNinja", matchURL = "poe%.ninja/pob/%w+", regexURL = "poe%.ninja/pob/(%w+)%s*$", downloadURL = "poe.ninja/pob/raw/%1" },
{
label = "pobb.in", id = "POBBin", matchURL = "pobb%.in/%w+", regexURL = "pobb%.in/([%w-_]+)%s*$", downloadURL = "pobb.in/pob/%1",
codeOut = "https://pobb.in/", postUrl = "https://pobb.in/pob/", postFields = ""
},
}

local influenceInfo = itemLib.influenceInfo

local ImportTabClass = newClass("ImportTab", "ControlHost", "Control", function(self, build)
Expand Down Expand Up @@ -185,9 +170,9 @@ You can get this from your web browser's cookies while logged into the Path of E

local getExportSitesFromImportList = function()
local exportWebsites = { }
for k,v in pairs(importWebsiteList) do
for k,v in pairs(buildSites.websiteList) do
-- if entry has fields needed for Export
if importWebsiteList[k].postUrl and importWebsiteList[k].postFields and importWebsiteList[k].codeOut then
if buildSites.websiteList[k].postUrl and buildSites.websiteList[k].postFields and buildSites.websiteList[k].codeOut then
table.insert(exportWebsites, v)
end
end
Expand All @@ -201,37 +186,9 @@ You can get this from your web browser's cookies while logged into the Path of E
end)
self.controls.exportFrom:SelByValue(self.exportWebsiteSelected or main.lastExportWebsite or "Pastebin", "id")
self.controls.generateCodeByLink = new("ButtonControl", { "LEFT", self.controls.exportFrom, "RIGHT"}, 8, 0, 100, 20, "Share", function()
local response = ""
local exportWebsite = { }
if self.controls.exportFrom.selIndex then
exportWebsite = exportWebsitesList[self.controls.exportFrom.selIndex]
response = LaunchSubScript([[
local code, proxyURL = ...
local curl = require("lcurl.safe")
local page = ""
local easy = curl.easy()
easy:setopt_url(']]..exportWebsite.postUrl..[[')
easy:setopt(curl.OPT_POST, true)
easy:setopt(curl.OPT_POSTFIELDS, ']]..exportWebsite.postFields..[['..code)
easy:setopt(curl.OPT_ACCEPT_ENCODING, "")
if proxyURL then
easy:setopt(curl.OPT_PROXY, proxyURL)
end
easy:setopt_writefunction(function(data)
page = page..data
return true
end)
easy:perform()
local res = easy:getinfo_response_code()
easy:close()
if (res == 200) then
return page
else
return nil, page
end
]], "", "", self.controls.generateCodeOut.buf, launch.proxyURL)
end
if response ~= "" then
local exportWebsite = exportWebsitesList[self.controls.exportFrom.selIndex]
local response = buildSites.UploadBuild(self.controls.generateCodeOut.buf, exportWebsite)
if response then
self.controls.generateCodeOut:SetText("")
self.controls.generateCodeByLink.label = "Creating link..."
launch:RegisterSubScript(response, function(pasteLink, errMsg)
Expand All @@ -245,10 +202,20 @@ You can get this from your web browser's cookies while logged into the Path of E
end
end)
self.controls.generateCodeByLink.enabled = function()
return #self.controls.generateCodeOut.buf > 0 and not self.controls.generateCodeOut.buf:match("pastebin%.com") and not self.controls.generateCodeOut.buf:match("pobb%.in")
for _, exportSite in ipairs(exportWebsitesList) do
if #self.controls.generateCodeOut.buf > 0 and self.controls.generateCodeOut.buf:match(exportSite.matchURL) then
return false
end
end
return #self.controls.generateCodeOut.buf > 0
end
self.controls.exportFrom.enabled = function()
return #self.controls.generateCodeOut.buf > 0 and not self.controls.generateCodeOut.buf:match("pastebin%.com") and not self.controls.generateCodeOut.buf:match("pobb%.in")
for _, exportSite in ipairs(exportWebsitesList) do
if #self.controls.generateCodeOut.buf > 0 and self.controls.generateCodeOut.buf:match(exportSite.matchURL) then
return false
end
end
return #self.controls.generateCodeOut.buf > 0
end
self.controls.generateCodeNote = new("LabelControl", {"TOPLEFT",self.controls.generateCodeOut,"BOTTOMLEFT"}, 0, 4, 0, 14, "^7Note: this code can be very long; you can use 'Share' to shrink it.")
self.controls.importCodeHeader = new("LabelControl", {"TOPLEFT",self.controls.generateCodeNote,"BOTTOMLEFT"}, 0, 26, 0, 16, "^7To import a build, enter the code here:")
Expand Down Expand Up @@ -988,44 +955,44 @@ function ImportTabClass:OpenImportFromWebsitePopup()

controls.importAnchorPoint = new("Control", nil, 0, 0, 280, 0)
controls.importFromLabel = new("LabelControl", { "TOPLEFT", controls.importAnchorPoint, "BOTTOMLEFT"}, 15, 20, 0, 16, "Import from:")
controls.importFrom = new("DropDownControl", {"LEFT",controls.importFromLabel,"RIGHT"}, 8, 0, 140, 20, importWebsiteList, function(_, selectedWebsite)
controls.importFrom = new("DropDownControl", {"LEFT",controls.importFromLabel,"RIGHT"}, 8, 0, 140, 20, buildSites.websiteList, function(_, selectedWebsite)
self.importWebsiteSelected = selectedWebsite.id
end)
controls.importFrom:SelByValue( self.importWebsiteSelected or "Pastebin", "id" )
controls.editLabel = new("LabelControl", { "TOPLEFT", controls.importAnchorPoint, "BOTTOMLEFT"}, 15, 44, 0, 16, "Enter website link:")
controls.edit = new("EditControl", nil, 0, 64, 250, 18, "", nil, "^%w%p%s", nil, function(buf)
controls.msg.label = ""
if #controls.edit.buf > 0 then
for j=1,#importWebsiteList do
if controls.edit.buf:match(importWebsiteList[j].matchURL) then
controls.importFrom:SelByValue(importWebsiteList[j].id, "id")
for j=1,#buildSites.websiteList do
if controls.edit.buf:match(buildSites.websiteList[j].matchURL) then
controls.importFrom:SelByValue(buildSites.websiteList[j].id, "id")
end
end
end
end)
controls.msg = new("LabelControl", nil, 0, 82, 0, 16, "")
controls.import = new("ButtonControl", nil, -45, 104, 80, 20, "Import", function()
local selectedWebsite = importWebsiteList[controls.importFrom.selIndex]
local selectedWebsite = buildSites.websiteList[controls.importFrom.selIndex]
controls.import.enabled = false
controls.msg.label = "Retrieving paste..."
controls.edit.buf = controls.edit.buf:gsub("^[%s?]+", ""):gsub("[%s?]+$", "") -- Quick Trim
if controls.edit.buf:match("youtube%.com/redirect%?") then
local nested_url = controls.edit.buf:gsub(".*[?&]q=([^&]+).*", "%1")
controls.edit.buf = UrlDecode(nested_url)
end
launch:DownloadPage(controls.edit.buf:gsub(selectedWebsite.regexURL,selectedWebsite.downloadURL), function(page, errMsg)
if errMsg then
controls.msg.label = "^1"..errMsg
buildSites.DownloadBuild(controls.edit.buf, selectedWebsite, function(isSuccess, data)
if not isSuccess then
controls.msg.label = "^1"..data
controls.import.enabled = true
else
self.controls.importCodeIn:SetText(page, true)
self.controls.importCodeIn:SetText(data, true)
main:ClosePopup()
main:SelectControl(self.controls.importCodeIn)
end
end)
end)
controls.import.enabled = function()
local selectedWebsite = importWebsiteList[controls.importFrom.selIndex]
local selectedWebsite = buildSites.websiteList[controls.importFrom.selIndex]
return #controls.edit.buf > 0 and (controls.edit.buf:match(selectedWebsite.matchURL) or controls.edit.buf:match("youtube%.com/redirect%?"))
end
controls.cancel = new("ButtonControl", nil, 45, 104, 80, 20, "Cancel", function()
Expand Down
92 changes: 92 additions & 0 deletions src/Modules/BuildSiteTools.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
-- Path of Building
--
-- Module: Build Site Tools
-- Functions used to import and export PoB build codes from external websites
--

buildSites = { }

-- Import/Export websites list used in dropdowns
buildSites.websiteList = {
{
label = "Pastebin.com", id = "Pastebin", matchURL = "pastebin%.com/%w+", regexURL = "pastebin%.com/(%w+)%s*$", downloadURL = "pastebin.com/raw/%1",
codeOut = "", postUrl = "https://pastebin.com/api/api_post.php", postFields = "api_dev_key=c4757f22e50e65e21c53892fd8e0a9ff&api_paste_private=1&api_option=paste&api_paste_code="
},
{ label = "PastebinP.com", id = "PastebinProxy", matchURL = "pastebinp%.com/%w+", regexURL = "pastebinp%.com/(%w+)%s*$", downloadURL = "pastebinp.com/raw/%1" },
{ label = "Rentry.co", id = "Rentry", matchURL = "rentry%.co/%w+", regexURL = "rentry%.co/(%w+)%s*$", downloadURL = "rentry.co/paste/%1/raw" },
{
label = "PoeNinja", id = "PoeNinja", matchURL = "poe%.ninja/pob/%w+", regexURL = "poe%.ninja/pob/(%w+)%s*$", downloadURL = "poe.ninja/pob/raw/%1",
codeOut = "", postUrl = "https://poe.ninja/pob/api/api_post.php", postFields = "api_paste_code="
},
{
label = "pobb.in", id = "POBBin", matchURL = "pobb%.in/%w+", regexURL = "pobb%.in/([%w-_]+)%s*$", downloadURL = "pobb.in/pob/%1",
codeOut = "https://pobb.in/", postUrl = "https://pobb.in/pob/", postFields = ""
},
}

--- Uploads a PoB build code to a website
--- @param websiteInfo Table Contains the postUrl, any postParams, and a prefix to add to the response
--- @param buildCode String The build code that will be uploaded
function buildSites.UploadBuild(buildCode, websiteInfo)
local response
if websiteInfo then
response = LaunchSubScript([[
local code, proxyURL = ...
local curl = require("lcurl.safe")
local page = ""
local easy = curl.easy()
easy:setopt_url(']]..websiteInfo.postUrl..[[')
easy:setopt(curl.OPT_POST, true)
easy:setopt(curl.OPT_USERAGENT, "Path of Building/]]..launch.versionNumber..[[")
easy:setopt(curl.OPT_POSTFIELDS, ']]..websiteInfo.postFields..[['..code)
easy:setopt(curl.OPT_ACCEPT_ENCODING, "")
if proxyURL then
easy:setopt(curl.OPT_PROXY, proxyURL)
end
easy:setopt_writefunction(function(data)
page = page..data
return true
end)
easy:perform()
local res = easy:getinfo_response_code()
easy:close()
if (res == 200) then
return page
else
return nil, page
end
]], "", "", buildCode, launch.proxyURL)
end
return response
end

--- Downloads a PoB build code from a website
--- @param link String A link to the site that contains the link to the raw build code
--- @param websiteInfo Table Contains the downloadUrl
--- @param callback Function The function to call when the download is complete
function buildSites.DownloadBuild(link, websiteInfo, callback)
local siteCodeURL
-- Only called on program start via protocol handler
if not websiteInfo then
for _, siteInfo in ipairs(buildSites.websiteList) do
if link:match("^pob:[/\\]*" .. siteInfo.id:lower() .. "[/\\]+(%w+)") then
siteCodeURL = link:gsub("^pob:[/\\]*" .. siteInfo.id:lower() .. "[/\\]+(%w+)", "https://" .. siteInfo.downloadURL)
websiteInfo = siteInfo
break
end
end
else -- called via the ImportTab
siteCodeURL = link:gsub(websiteInfo.regexURL, websiteInfo.downloadURL)
end
if websiteInfo then
launch:DownloadPage(siteCodeURL, function(page, errMsg)
if errMsg then
callback(false, errMsg)
else
callback(true, page)
end
end)
else
callback(false, "Download information not found")
end
end
43 changes: 16 additions & 27 deletions src/Modules/Main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ LoadModule("Modules/ModTools")
LoadModule("Modules/ItemTools")
LoadModule("Modules/CalcTools")
LoadModule("Modules/PantheonTools")
LoadModule("Modules/BuildSiteTools")

--[[if launch.devMode then
for skillName, skill in pairs(data.enchantments.Helmet) do
Expand Down Expand Up @@ -202,7 +203,21 @@ the "Releases" section of the GitHub page.]])
self.decimalSeparator = "."
self.showTitlebarName = true

local ignoreBuild = self:LoadPastebinBuild()
local ignoreBuild
if arg[1] then
buildSites.DownloadBuild(arg[1], nil, function(isSuccess, data)
if not isSuccess then
self:SetMode("BUILD", false, data)
else
local xmlText = Inflate(common.base64.decode(data:gsub("-","+"):gsub("_","/")))
self:SetMode("BUILD", false, "Imported Build", xmlText)
self.newModeChangeToTree = true
end
end)
arg[1] = nil -- Protect against downloading again this session.
ignoreBuild = true
end

if not ignoreBuild then
self:SetMode("BUILD", false, "Unnamed build")
end
Expand Down Expand Up @@ -394,32 +409,6 @@ function main:CallMode(func, ...)
end
end

function main:LoadPastebinBuild()
local fullUri = arg[1]
if not fullUri then
return false
end
arg[1] = nil -- Protect against downloading again this session.
local pastebinCode = string.match(fullUri, "^pob:[/\\]*pastebin[/\\]+(%w+)[/\\]*")
if pastebinCode then
launch:DownloadPage("https://pastebin.com/raw/" .. pastebinCode, function(page, errMsg)
if errMsg then
self:SetMode("BUILD", false, "Failed Build Import (Download failed " .. pastebinCode .. ")")
else
local xmlText = Inflate(common.base64.decode(page:gsub("-","+"):gsub("_","/")))
if xmlText then
self:SetMode("BUILD", false, "Imported Build", xmlText)
self.newModeChangeToTree = true
else
self:SetMode("BUILD", false, "Failed Build Import (Decompress failed)")
end
end
end)
return true
end
return false
end

function main:LoadSettings(ignoreBuild)
local setXML, errMsg = common.xml.LoadXMLFile(self.userPath.."Settings.xml")
if not setXML then
Expand Down

0 comments on commit e138e5d

Please sign in to comment.