Const #LURK_LISTVIEW = "foundfeeds"
lurk = {PleaseStop=True}
;č jako v celé té appce i zde se pevně zavážeme
;č na struktury grafického rozhraní a jejich metody,
;č na MUI Royale.
;č předělávání nás tedy bude bolet...
Function lurk:set_status(s$)
mui.Set("lurkstatus", "Contents", s$)
EndFunction
Function lurk:Replay(err_code, msg$)
self:set_status(
IIf(err_code = #ERR_NONE, msg$, "\27b" .. GetErrorName(err_code)))
EndFunction
;č tohle nejde udělat jako method -
;č volající kód by asi musel ho i správně volat
Function lurk_callback(t)
If t.Action = #DOWNLOADFILE_STATUS
lurk:set_status(t.Count .. "/" .. t.Total .. " read from " .. t.UserData)
CheckEvents() ; keep MUI responsive
Return(lurk.PleaseStop)
EndIf
EndFunction
;č stáhnout soubor
Function lurk:Explore(url$)
self:Clear()
url$ = StripStr(url$)
self.PleaseStop = False
;č zjednodušená kontrola, pokud řetězec obsahuje procenta,
;č považujeme ho za "eskejpnutý".
;č Na případ, kdy uživatel strčí do URLu osamělý znak procenta vysereme
;FindStr(s$, "%") <> -1
Local err_code, html$, count = ?DownloadFile(url$,
{Adapter="hurl", Fail404=True, Encoded=FindStr(url$, "%", True) <> -1},
lurk_callback, url$)
If self.PleaseStop
self:set_status("interrupted")
Return()
EndIf
;č zde nepředpokládám, že by někdo jiný mohl spustit parser znovu.
;č O to je to jednodušší.
If err_code = #ERR_NONE
Local ok, n = ValidateStr(html$)
Local encoding = IIf(ok, #ENCODING_UTF8, #ENCODING_ISO8859_1)
Local headpos = FindStr(html$, "<head", False, 0, encoding)
If headpos < 0
self:set_status("\27bNothing found") ;č hlavně ta hlavička..
Return()
Else
self:set_status(count .. " bytes from " .. url$ .. " transmitted")
Local p = XMLParser.New({StartElement = lurkStartElement})
p:setbase(url$)
p:setencoding(IIf(ok, "UTF-8", "ISO-8859-1"))
;č ten parser trefí šlak, uvidí-li CO má zpracovat
p:Parse(UnrightStr(html$, headpos, encoding))
;č html-ko nemůže nezpůsobit chybu.
;č nemá cenu je hlídat
Local err_code = ?p:Close()
;Local err_code, status, msg, line, col, pos = ?p:Close()
;self:Replay(err_code, "Done.")
EndIf
Else
self:set_status("\27b" .. GetErrorName(err_code))
EndIf
EndFunction
Function lurk:Clear()
mui.DoMethod(#LURK_LISTVIEW, "Clear")
EndFunction
;č zoufalý pokus rekonstituce adresy
;č nikdy nemůže být 100% funkční
;č kvůli případným přesměrováním
Function p_reconstructURL(base$, href$)
;č Pro jistotu. Přece i webmaster může nahodit mezer do atributů!
href$ = StripStr(href$)
;č baseUrl je jíž dříve oříznuty
;č pokud href zdá být celou adresou, tak není co řešit
If StartsWith(href$, "http") Then Return(href$)
;č pokud href začína lomitkem, tak se vztahuje ke kořenu serveru
If StartsWith(href$, "/")
;č uživatel může zadat normální adresu na http://,
;č nebo bůhvíco, co může začínat jménem serveru...
Local hostpos = FindStr(base$, "//", True) + 2
Local hostend = FindStr(base$, "/", True, hostpos)
If hostend = -1
;č bez lomítka na konci.
Return(base$ .. href$)
Else
;č s dostatkem lomítek.
Return(LeftStr(base$, hostend) .. href$)
EndIf
EndIf
;č bez lomítka, pokud vůbec něčemu rozumím, vztahuje k aktuální složce?
;č Jenomže ani čert se nevyzná, co je to složka v moderním webu
;č (víz. poznámku ohledně přesměrování)
Local parampos = FindStr(base$, "?", True)
If parampos > 0
;č pokud ovšem adresa obsahuje otazník, nebo ampersand
;č tak část za nim můžeme zajistě vyhodit
Local drawerpos = ReverseFindStr(base$, "/", True, parampos)
Return(LeftStr(base$, drawerpos + 1) .. href$)
EndIf
;č Je to jedno. Nechť si to uživatel řeší sám!
Return(TrimStr(base$, "/", True) .. "/" .. href$)
EndFunction
Function _test_reconstruction()
Local testcases = {}
testcases["aninet.no"] = "feed"
testcases["gemini://aninet.no"] = "feed"
testcases["gemini://aninet.no/"] = "feed"
testcases["gemini://aninet.no/dfg/"] = "feed"
testcases["gemini://aninet.no/dfg/tgb"] = "feed"
testcases["gemini://aninet.no/dfg/tgb?"] = "feed"
testcases["gemini://aninet.no/dfg/tgb?atari=0&amiga=1"] = "feed"
testcases["gemini://aninet.no/dfg/?atari=0&amiga=1"] = "feed"
testcases["aninet.no/%34%20/?atari=0&amiga=1"] = "feed"
For i,v In Pairs(testcases)
DebugPrint(i, v, p_reconstructURL(i, v))
Next
EndFunction
Function lurkStartElement(p, name$, attrs)
CheckEvents()
If lurk.PleaseStop
p:Stop()
EndIf
Switch LowerStr(name$)
Case "body":
p:Stop()
Return()
Case "link":
If HaveItem(attrs, "type")
Switch LowerStr(attrs.type)
Case "application/atom+xml":
FallThrough
Case "application/rss+xml":
Local item = {href="", title="", rel=""}
For i,v In Pairs(item)
If HaveItem(attrs, i) Then item[i] = attrs[i]
Next
/*
<column title="CanHas"/>
<column title="Address"/>
<column title="Title"/>
<column title="Relationship"/>
<column title="Type"/>
<column title="URL constructed"/>
*/
Local url$ = p_reconstructURL(p:getbase(), item.href)
mui.DoMethod(#LURK_LISTVIEW, "Insert", "Bottom",
lurk:CanHas(url$),
item.href,
item.title,
item.rel,
attrs.type,
url$)
EndSwitch
EndIf
EndSwitch
EndFunction
Function lurk:CanHas(url$)
Return(IIf(p_HasItem(url$, "Root"), "added" , ""))
EndFunction
Function lurk:AddByDoubleClick()
self:AddFromlist(pos)
p_SaveFeeds()
EndFunction
Function lurk:AddSelected()
Local t = mui.DoMethod(#LURK_LISTVIEW, "GetSelection")
For i,v In IPairs(t) ;č tam jsou pouze číselné indexy. Možno.
lurk:AddFromlist(v)
Next
p_SaveFeeds()
EndFunction
Function lurk:AddFromlist(pos)
Local has$, href$, title$, rel$, type$, url$ = mui.DoMethod(
#LURK_LISTVIEW, "GetEntry", pos)
If Not has$
p_AddFeed(url$)
EndIf
mui.DoMethod(#LURK_LISTVIEW, "Rename", pos,
self:CanHas(url$), href$, title$, rel$, type$, url$)
EndFunction