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: