Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow import on startup for sites other than pastebin #4042

Merged
merged 3 commits into from
Feb 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -200,37 +185,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 "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 @@ -244,10 +201,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 @@ -987,44 +954,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