|
Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
-- fbkinds.lua: tools to handle the various kinds of Facebook URLs
-- This file:
-- http://angg.twu.net/fbcache/fbkinds.lua
-- http://angg.twu.net/fbcache/fbkinds.lua.html
-- (find-angg "fbcache/fbkinds.lua")
--
-- (find-fbcache "fbcache2.lua" "fbkinds")
-- «.fbkinds_bigstr» (to "fbkinds_bigstr")
-- «.fbpatexpand» (to "fbpatexpand")
-- «.fbpatexpand-tests» (to "fbpatexpand-tests")
-- «.Fbkind-class» (to "Fbkind-class")
-- «.Fbkind-tests» (to "Fbkind-tests")
-- «.Fbkinds-class» (to "Fbkinds-class")
-- «.fbkinds» (to "fbkinds")
-- «.fbdl» (to "fbdl")
-- «.fbdl-tests» (to "fbdl-tests")
require "lpeg" -- (find-es "lua-intro" "lpeg-quickref")
-- require "re" -- (find-es "lua-intro" "lpeg-re-1")
require "fbcache3" -- (find-fbcache "fbcache3.lua")
-- __ _ _ _ _ _ _ _
-- / _| |__ | | _(_)_ __ __| |___ | |__ (_) __ _ ___| |_ _ __
-- | |_| '_ \| |/ / | '_ \ / _` / __| | '_ \| |/ _` / __| __| '__|
-- | _| |_) | <| | | | | (_| \__ \ | |_) | | (_| \__ \ |_| |
-- |_| |_.__/|_|\_\_|_| |_|\__,_|___/___|_.__/|_|\__, |___/\__|_|
-- |_____| |___/
--
-- «fbkinds_bigstr» (to ".fbkinds_bigstr")
-- This table, stored as a big string, represent in a VERY ompact form
-- all the kinds of Facebook URLs that we support. For example, the
-- pattern "groupwpn", which is
--
-- /groups/W/permalink/N/R
--
-- matches:
--
-- https://www.facebook.com/groups/contatimprovbra/permalink/947586865274406/
--
-- the "W" matches the "contatimprovbra" (a word),
-- the "N" matches the "947586865274406" (a number), and
-- the "R" matches the empty string at the end (the rest).
fbkinds_bigstr = [[
eventnpn /events/N/permalink/N/R 21_ok
eventnn /events/N/N/R 21_ok
eventn /events/N/R 1_ok
groupnpn /groups/N/permalink/N/R 21_ok
groupwpn /groups/W/permalink/N/R 0_nothingworks
groupnn /groups/N/NR 1_whydoesnt2work
groupwn /groups/W/NR 2_ok
groupn /groups/NR 1_ok
groupw /groups/WR 0_how_to_convert_name->id?
mediawannn /W/media_set?set=a.N.N.NR 0_nothingworks
mediawnnn /media/set/?set=W.N.N.NR 0_nothingworks
mediawn /media/set/?set=W.NR 0_nothingworks
noteswwn /notes/W/W/NR 0_3shouldworkbutdeprecated
notesn /notes/N/R 0_1shouldworkbutdeprecated
pageswn /pages/W/NR 2_ok
storynn /permalink.php?story_fbid=N&id=NR 12_ok
photonn /photo.php?fbid=N&set=t.NR 0_nothingworks
photonnnn /photo.php?fbid=N&set=a.N.N.NR 0_nothingworks
photono /photo.php?fbid=N&set=OR 1
photot /N/photos/t.N/N/R 13
photogm /N/photos/gm.N/N/R 123
photona /N/photos/a.N.N.N/N/R 1245
photowa /W/photos/a.N.N.N/N/R 0_untested
photovs /photo.php?v=N&set=OR 1
photov /photo.php?v=NR 1
postwn /W/posts/NR 2
videon /video.php?v=NR 1
]]
-- __ _ _ _
-- / _| |__ _ __ __ _| |_ _____ ___ __ __ _ _ __ __| |
-- | |_| '_ \| '_ \ / _` | __/ _ \ \/ / '_ \ / _` | '_ \ / _` |
-- | _| |_) | |_) | (_| | || __/> <| |_) | (_| | | | | (_| |
-- |_| |_.__/| .__/ \__,_|\__\___/_/\_\ .__/ \__,_|_| |_|\__,_|
-- |_| |_|
--
-- «fbpatexpand» (to ".fbpatexpand")
-- (find-fbcache "fbcache2.lua" "fbpatcompile")
-- Convert patterns like the above ones into lpeg patterns.
-- For example,
--
-- "/events/N/permalink/N/R"
--
-- becomes this (as a string, to be compiled later):
--
-- lpeg.P"/events/" * PatN * lpeg.P"/permalink/" * PatN * lpeg.P"/" * PatR
--
-- and this:
--
-- (lpeg.Cp():Cg("bpos") *
-- lpeg.P"/events/" * PatN * lpeg.P"/permalink/" * PatN * lpeg.P"/" * PatR *
-- lpeg.Cc("eventnpn"):Cg("kind") * lpeg.Cc(1):Cg("kindn")
-- ):Ct()
--
PatN = (lpeg.R("09")^1):C()
PatO = ((lpeg.R("09") + lpeg.S(" "))^1):C()
PatW = ((lpeg.R("09") + lpeg.R("AZ") + lpeg.R("az") + lpeg.S("."))^1):C()
PatR = (lpeg.P(1)^0):C()
PatR = lpeg.Cp():Cg("rpos") * (lpeg.P(1)^0):C()
PatR = lpeg.Cp():Cg("rpos") * (lpeg.R("!~")^0):C()
fbpatexpand0 = function (pat)
local mkp = function (s) return "Pat"..s end
local mks = function (s) return 'lpeg.P"'..s..'"' end
local mka = function (...) return table.concat({...}, " * ") end
local Upcase = lpeg.R("AZ")
local NonUpcase = (1 - Upcase)^1
local Parts = ((NonUpcase/mks) * (Upcase/mkp))^1
return lpeg.match(Parts/mka, pat)
end
fbpatexpand = function (n, name, pat)
local patexp = fbpatexpand0(pat)
local ppos = 'lpeg.Cp():Cg("bpos")'
local pname = 'lpeg.Cc("' ..name..'"):Cg("name")'
local pn = 'lpeg.Cc(' ..n.. '):Cg("n")'
return format("(%s *\n %s *\n %s * %s\n):Ct()", ppos, patexp, pname, pn)
end
-- «fbpatexpand-tests» (to ".fbpatexpand-tests")
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "fbkinds.lua"
pat = "/events/N/permalink/N/R"
pat0 = fbpatexpand0(pat)
pate = fbpatexpand (1, "eventnpn", pat)
= pat0
= pate
url = "https://www.facebook.com/events/1397247553878845/permalink/1412951502308450/"
u = "/events/1397247553878845/permalink/1412951502308450/"
patc = expr(pate)
PP(patc:match(u))
--> {1="1397247553878845", 2="1412951502308450", 3="", "bpos"=1, "kind"="eventp", "rpos"=53}
--]]
-- _____ _ _ _ _
-- | ___| |__ | | _(_)_ __ __| |
-- | |_ | '_ \| |/ / | '_ \ / _` |
-- | _| | |_) | <| | | | | (_| |
-- |_| |_.__/|_|\_\_|_| |_|\__,_|
--
-- «Fbkind-class» (to ".Fbkind-class")
Fbkind = Class {
type = "Fbkind",
new = function (n, name, pat, comment)
return Fbkind {n=n, name=name, pat=pat, comment=comment}
end,
__tostring = function (fbk) return fbk:tostring() end,
__index = {
tostring = function (fbk)
return format("%2s %-12s %-40s %s",
tostring(fbk.n), fbk.name, fbk.pat, fbk.comment or "")
end,
patexpand = function (fbk)
return fbpatexpand(fbk.n, fbk.name, fbk.pat)
end,
match = function (fbk, u)
local pat = fbk:patexpand()
return expr(pat):match(u)
end,
},
}
-- «Fbkind-tests» (to ".Fbkind-tests")
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "fbkinds.lua"
fbk = Fbkind.new(1, "eventnpn", "/events/N/permalink/N/R", "c")
= fbk
--> 1 eventnpn /events/N/permalink/N/R c
PP(fbk)
--> {"comment"="c", "n"=1, "name"="eventnpn", "pat"="/events/N/permalink/N/R"}
= fbk:patexpand()
--> (lpeg.Cp():Cg("bpos") *
-- lpeg.P"/events/" * PatN * lpeg.P"/permalink/" * PatN * lpeg.P"/" * PatR *
-- lpeg.Cc("eventnpn"):Cg("name") * lpeg.Cc(1):Cg("n")
-- ):Ct()
url = "https://www.facebook.com/events/1397247553878845/permalink/1412951502308450/"
u = "/events/1397247553878845/permalink/1412951502308450/"
PP(fbk:match(u))
--> {1="1397247553878845", 2="1412951502308450", 3="", "bpos"=1, "n"=1, "name"="eventnpn", "rpos"=53}
--]]
-- _____ _ _ _ _
-- | ___| |__ | | _(_)_ __ __| |___
-- | |_ | '_ \| |/ / | '_ \ / _` / __|
-- | _| | |_) | <| | | | | (_| \__ \
-- |_| |_.__/|_|\_\_|_| |_|\__,_|___/
--
-- «Fbkinds-class» (to ".Fbkinds-class")
Fbkinds = Class {
type = "Fbkinds",
new = function () return Fbkinds {} end,
from = function (bigstr)
return Fbkinds.new():addlines(bigstr):patcompile()
end,
__tostring = function (fbks) return fbks:tostring() end,
__index = {
add = function (fbks, name, pat, comment)
local n = #fbks+1
local fbk = Fbkind.new(n, name, pat, comment)
fbks[n] = fbk
fbks[name] = fbk
return fbks
end,
addline = function (fbks, line)
local name, pat, comment = line:match("^%s*(%S+)%s+(%S+)%s*(.*)$")
if name then fbks:add(name, pat, comment) end
return fbks
end,
addlines = function (fbks, bigstr)
for line in bigstr:gmatch("[^\n]+") do fbks:addline(line) end
return fbks
end,
--
tostring = function (fbks)
local f = function (n) return tostring(fbks[n]) end
return mapconcat(f, seq(1, #fbks), "\n")
end,
--
patexpand0 = function (fbks)
local f = function (n) return fbks[n]:patexpand() end
return mapconcat(f, seq(1, #fbks), " +\n\n")
end,
patexpand = function (fbks)
return 'lpeg.P"https://www.facebook.com" * (\n\n' ..
fbks:patexpand0() .. '\n\n)'
end,
patcompile = function (fbks)
fbks.pat = expr(fbks:patexpand())
return fbks
end,
--
match = function (fbks, str) return fbks.pat:match(str) end,
in_string = function (fbks, bigstr)
return cow(function ()
for _,url in ipairs(split(bigstr)) do
local tbl = fbks:match(url)
if tbl then coy(tbl.name, tbl, url) end
end
end)
end,
in_file = function (fbks, fname)
return fbks:in_string(ee_readfile(fname))
end,
},
}
--[==[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "fbkinds.lua"
bigstr = [=[
eventnpn /events/N/permalink/N/R 21_ok
eventnn /events/N/N/R 21_ok
eventn /events/N/R 1_ok
]=]
fbkinds = Fbkinds.from(bigstr)
= fbkinds
= fbkinds:patexpand()
-- fbkinds:patcompile()
= fbkinds.pat
url = "https://www.facebook.com/events/1397247553878845/permalink/1412951502308450/"
u = "/events/1397247553878845/permalink/1412951502308450/"
PP(fbkinds:match(url))
= fbkinds.eventn
= fbkinds[1]
PP(fbkinds[1]:match(u))
PP(fbkinds:match(url))
for name,tbl,url in fbkinds:in_file "~/TODO" do print(url) end
--]==]
-- __ _ _ _ _
-- / _| |__ | | _(_)_ __ __| |___
-- | |_| '_ \| |/ / | '_ \ / _` / __|
-- | _| |_) | <| | | | | (_| \__ \
-- |_| |_.__/|_|\_\_|_| |_|\__,_|___/
--
-- «fbkinds» (to ".fbkinds")
-- The default value for fbkinds is the table from fbkinds_bigstr, compiled.
fbkinds = Fbkinds.from(fbkinds_bigstr)
-- (find-es "facebook" "eventnpn")
fbkinds.eventnpn.ex = "https://www.facebook.com/events/1397247553878845/permalink/1412951502308450/"
fbkinds.eventnpn.dl = 'g(f(1)); g(f(2)); g(f(1).."_"..f(2))'
-- (find-es "facebook" "eventnn")
fbkinds.eventnn.ex = "https://www.facebook.com/events/1553809231523002/1563468630557062/"
fbkinds.eventnn.dl = 'g(f(1)); g(f(2)); g(f(1).."_"..f(2))'
-- (find-es "facebook" "eventn")
fbkinds.eventn.ex = "https://www.facebook.com/events/1006218776073768/"
fbkinds.eventn.dl = "g(f(1))"
-- (find-es "facebook" "groupnpn")
fbkinds.groupnpn.ex = "https://www.facebook.com/groups/249360678448319/permalink/621939097857140/"
fbkinds.groupnpn.dl = "g(f(1)); g(f(2)); g(f(1)..'_'..f(2))"
-- (find-es "facebook" "groupwpn")
fbkinds.groupwpn.ex = "https://www.facebook.com/groups/contatimprovbra/permalink/947586865274406/"
fbkinds.groupwpn.dl = "g(nid(f(1))); g(f(2)); g(nid(f(1))..'_'..f(2))"
-- (find-es "facebook" "groupnn")
fbkinds.groupnn.ex = "https://www.facebook.com/groups/105487286280461/240851649410690/"
fbkinds.groupnn.dl = "g(f(1)); g(f(2)); g(f(1)..'_'..f(2))"
-- (find-es "facebook" "groupwn")
fbkinds.groupwn.ex = "https://www.facebook.com/groups/transgente/639092892836474/"
fbkinds.groupwn.dl = "g(nid(f(1))); g(f(2)); g(nid(f(1))..'_'..f(2))"
-- (find-es "facebook" "groupn")
fbkinds.groupn.ex = "https://www.facebook.com/groups/1398505100440487/"
fbkinds.groupn.dl = "g(f(1))"
-- (find-es "facebook" "groupw")
fbkinds.groupw.ex = "https://www.facebook.com/groups/transgente"
fbkinds.groupw.dl = "g(nid(f(1)))"
-- (find-es "facebook" "mediawannn")
fbkinds.mediawannn.ex = "https://www.facebook.com/paulakossatz/media_set?set=a.10202222226170686.1073741844.1040842293&type=1"
fbkinds.mediawannn.dl = "g(f(4))"
-- (find-es "facebook" "mediawnnn")
fbkinds.mediawnnn.err = "I don't have urls of this kind"
-- (find-es "facebook" "mediawn")
fbkinds.mediawn.err = "I don't have urls of this kind"
-- (find-es "facebook" "noteswwn")
fbkinds.noteswwn.err = "I don't have urls of this kind"
-- (find-es "facebook" "notesn")
fbkinds.notesn.ex = "https://www.facebook.com/notes/320469381448610/"
fbkinds.notesn.err = "(#12) notes API is deprecated for versions v2.0 and higher"
-- (find-es "facebook" "pageswn")
fbkinds.pageswn.ex = "https://www.facebook.com/pages/Viomundo/109725279084911"
fbkinds.pageswn.dl = "g(f(2))"
-- (find-es "facebook" "storynn")
fbkinds.storynn.ex = "https://www.facebook.com/permalink.php?story_fbid=10152640860900894&id=696685893&fref=nf"
fbkinds.storynn.dl = "g(f(2))"
fbkinds.storynn.err = "(#12) singular statuses API is deprecated for versions v2.4 and higher"
-- (find-es "facebook" "photonn")
fbkinds.photonn.ex = "https://www.facebook.com/photo.php?fbid=10151256245188625&set=t.100002233344951"
fbkinds.photonn.dl = "g(f(1)); g(f(2))"
fbkinds.photonn.err = "I don't know how to retrieve the photo"
-- (find-es "facebook" "photonnnn")
fbkinds.photonnnn.ex = "https://www.facebook.com/photo.php?fbid=10201336092313990&set=a.1569106477271.73917.1523735650&type=1&permPage=1"
fbkinds.photonnnn.dl = "g(f(1))"
-- (find-es "facebook" "photono")
fbkinds.photono.err = "I don't have urls of this kind"
-- (find-es "facebook" "photot")
fbkinds.photot.ex = "https://www.facebook.com/102015223300293/photos/t.100000842030889/317158085119338/"
fbkinds.photot.dl = "g(f(1)); g(f(2)); g(f(3))"
-- (find-es "facebook" "photogm")
fbkinds.photogm.ex = "https://www.facebook.com/1442002182737691/photos/gm.1466213243643988/1471817019756207/?type=1"
fbkinds.photogm.dl = "g(f(1)); g(f(2)); g(f(3))"
-- (find-es "facebook" "photona")
fbkinds.photona.ex = "https://www.facebook.com/21038112178/photos/a.441569537178.245171.21038112178/10152790891782179/?type=1&fref=nf"
fbkinds.photona.dl = "g(f(1)); g(f(2)); g(f(4))"
-- (find-es "facebook" "photowa")
fbkinds.photowa.ex = "https://www.facebook.com/AKPress/photos/a.215376115248.261941.205965845248/10154741098510249/?type=1"
fbkinds.photowa.dl = "g(f(1)); g(f(4)); g(f(5))"
-- (find-es "facebook" "photovs")
fbkinds.photovs.err = "I don't have urls of this kind"
-- (find-es "facebook" "photov")
fbkinds.photov.ex = "https://www.facebook.com/photo.php?v=10152413352959175"
fbkinds.photov.dl = "g(f(1))"
-- (find-es "facebook" "postwn")
fbkinds.postwn.ex = "https://www.facebook.com/CopBlock/posts/10152706679833189"
fbkinds.postwn.dl = "g(nid(f(1))); g(nid(f(1))..'_'..f(2))"
-- (find-es "facebook" "videon")
fbkinds.videon.ex = "https://www.facebook.com/video.php?v=823660551012161"
fbkinds.videon.dl = "g(f(1))"
--[==[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "fbkinds.lua"
= fbkinds
for name,tbl,url in fbkinds:in_file "~/TODO" do print(url) end
name = "eventnpn"
fbk = fbkinds[name]
= fbk.ex
tbl = PP(fbkinds:match(fbk.ex))
= tbl.name == name
--]==]
-- __ _ _ _
-- / _| |__ __| | |
-- | |_| '_ \ / _` | |
-- | _| |_) | (_| | |
-- |_| |_.__/ \__,_|_|
--
-- «fbdl» (to ".fbdl")
-- See: (find-fbcache "fbnameid.lua" "nameid_maybe")
-- and: (find-fbcache "fbnameid.lua" "fbget_maybe")
--
-- Experimental & messy
isfbid = function (str) return not str:match"%?" end
fbdl_f = function (n) return (tbl and tbl[n]) or "?" end
fbdl_g = function (fbid) if isfbid(fbid) then fbget(fbid) end; return fbid end
fbdl_g = function (fbid) if isfbid(fbid) then fbget(fbid) end; return PP(fbid) end
fbdl_nid = function (fbid) return isfbid(fbid) and nameid_maybe(fbid) or "?" end
fbdl_preamble = [[
tbl = ...
local f, g, nid = fbdl_f, fbdl_g, fbdl_nid
]]
fbdl_eval = function (url, tbl, dlcode)
return loadstring(fbdl_preamble .. dlcode, "fdbl:"..tbl.name)(tbl)
end
fbdl = function (url, tbl)
local tbl = tbl or fbkinds:match(url)
if not tbl then return "Not a Facebook URL" end
local dlcode = fbkinds[tbl.name].dl
if not dlcode then return "No download code" end
return fbdl_eval(url, tbl, dlcode)
end
-- «fbdl-tests» (to ".fbdl-tests")
--[==[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
require "fbkinds" -- (find-fbcache "fbcache3.lua")
name = "eventnpn"
= fbkinds[name].ex
= fbkinds[name].dl
= fbdl(fbkinds[name].ex)
name = "eventnpn"
url = fbkinds[name].ex
tbl = fbkinds:match(url)
f, g, nid = fbdl_f, fbdl_g, fbdl_nid
= fbkinds[name].dl
g(f(1)); g(f(2)); g(f(1).."_"..f(2))
--]==]
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "fbkinds.lua"
PP(fbkinds:match "https://www.facebook.com/photo.php?fbid=10205742030739697&set=pb.1523735650.-2207520000.1453614397.&type=3&theater")
-- new
--]]
-- Local Variables:
-- coding: raw-text-unix
-- End: