/lurk.hws (f39265cc944ed3be89260bc28f32c3805794fb0d) (6412 bytes) (mode 100755) (type blob)


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$)

	self:set_status(count .. " bytes from " .. url$ .. " transmitted") 

	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 
		self:set_status("\27b" .. GetErrorName(err_code)) 
		Return()
	EndIf
		
	Local ok, n = ValidateStr(html$, #ENCODING_UTF8)
	Local encoding = IIf(ok, #ENCODING_UTF8, #ENCODING_ISO8859_1)
	Local headpos = FindStr(html$, "<head", False, 0, encoding)
	If headpos < 0
		self:set_status("Nothing found") ;č hlavně ta hlavička..
		Return()
	EndIf 
	
	Local headend = ReverseFindStr(html$, "</head>", False, 
								StrLen(html$, encoding)-1, encoding)
	Local len = headend-headpos
	If len < 0
		self:set_status("Something wrong on page")
		Return()
	EndIf 
	
	html$ = MidStr(html$, headpos, len, encoding)
	Local p = XMLParser.New({StartElement = lurkStartElement})
	p:setbase(url$)
	p:setencoding(IIf(ok, "UTF-8", "ISO-8859-1"))
	;č ten parser trefí šlak, až uvidí CO má zpracovat 
	p:Parse(html$)
	Local lin, col, pos = p:pos()
	
	;č html-ko nemůže nezpůsobit chybu.
	;č nemá cenu je hlídat
	Local err_code = ?p:Close()
	If len > pos
		self:set_status("("..pos .."/"..len .. ") It's too hard. Parser lost.")
	Else 
		self:set_status("Parser done.")
	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 

Mode Type Size Ref File
100755 blob 7473 1ab45355102d3c454b8d83e05e4af10b0447dee3 128px-Feed-icon.png
100755 blob 5559 b4b21e48b891dd64eb9d1bc4a2897ce50bb139ac AppWindow.xml
100755 blob 3296 87f34b200c7e6abd9235c437a1927c745832e729 IvoR.hws
100755 blob 8539 5fb3546290c06f2b7077fbedb85cef583a60e574 IvoRSS.hws
100755 blob 7191 6291191cf3b1e9b7dd44493a09e26918f2c6e3d1 IvoRSS.png
100755 blob 4405 6f1fc460afb31e6e38cd78dd01c0debaae6f5343 feeds.hws
100755 blob 1694 83e47eb86860331dfe771f49029c00559a2f687e feedsdata.hws
100755 blob 8773 a1ac5af9c9ebafc5b2a012753079ee9602fbb98f feedtree.hws
100755 blob 6412 f39265cc944ed3be89260bc28f32c3805794fb0d lurk.hws
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/iam-git/IvoRSS

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/iam-git/IvoRSS

Clone this repository using git:
git clone git://git.rocketgit.com/user/iam-git/IvoRSS

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main