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
HttpInspector: new plugin for developpers to inspect KOReader #11457
Conversation
Impressive! |
I also see strange stuff with Microsoft Edge (Chrome based): even just getting on home and click on list of dispatcher event, it just waits, I see a request sent and just waiting for answer in Dev tools, I see in KOReader output that the request went in and the response is printed, so probably sent. If I reclick on that link, the page displays, and there's no 2nd request in the output....
With "strings first", you mean everything else not a function ? Properties (number or string), tables and object all first but alpha sorted - and then just all the functions alpha-sorted?
I thought you'd find that useful. |
Maybe combined by the groups, each group alpha-sorted:
Example with many items from groups 1 - 3: http://192.168.0.131:8080/koreader/ui/file_chooser/ |
No usb mount. Wifi + SSH server on Kindle give full access to its file system from my PC. |
return { | ||
name = "httpinspector", | ||
fullname = _("HTTP KOReader Inspector"), | ||
description = _([[Allow browsing KOReader internal objects over HTTP. This is aimed at developpers, and may pose some security risks. Only enable this on networks you can trust.]]), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
description = _([[Allow browsing KOReader internal objects over HTTP. This is aimed at developpers, and may pose some security risks. Only enable this on networks you can trust.]]), | |
description = _([[Allow browsing KOReader internal objects over HTTP. This is aimed at developers, and may pose some security risks. Only enable this on networks you can trust.]]), |
<pre wrap> | ||
<big>Welcome to KOReader inspector HTTP server!</big> | ||
|
||
This service is aimed at developpers, <mark>use at your own risk</mark>. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This service is aimed at developpers, <mark>use at your own risk</mark>. | |
This service is aimed at developers, <mark>use at your own risk</mark>. |
Looks good to me! I tried it on the Kindle and my remote thingy, no issues other than the lack of wakelock when using it for reading, so my Kindle will go to sleep after a while, even though I am still reading. Should we add some sort of wakelock, or handle it by device? This was what I used to keep the Kindle awake while I am reading (from #10223)
|
I have no idea what this resetT1Timeout does. You mean you need it after dispatching the event ? Don't you need any kind of stuff like that before, so http requests are accepted and processed ?
I was assuming that devices never go into standby, except when explicitely managed by our AutoSuspend (which does autostandby too) plugin, and that other code that want to prevent standby in some section wrap that section or period with I'm not really familiar with all that (and don't want to be :)), so pinging @NiLuJe . |
Wifi in and of itself doesn't prevent standby, but otoh the minimal traffic of an open SSH connection should. |
The second click is sometimes required not only on sending an event, but on viewing an object too. Besides that, all features work as expected, encountered no issues. To show notifications on the reader when sending an event, notifications "From all other sources" must be enabled. |
"beforeSuspend", | ||
"initNetworkManager", | ||
"free", | ||
"clear", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding "onResume" allows detecting DeviceListener and NetworkListener.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But gives garbage in BackgroundRunner entry in FileManager ui.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We get such garbage elsewhere for all plugins onXYZ methods, as they are wrapped by pluginloader :/
koreader/frontend/pluginloader.lua
Lines 28 to 32 in bdd475f
local function sandboxPluginEventHandlers(plugin) | |
for key, value in pairs(plugin) do | |
if key:sub(1, 2) == "on" and type(value) == "function" then | |
plugin[key] = function(self, ...) | |
local ok, re = pcall(value, self, ...) |
(I tried to keep the original method with another name, but it got messy with multiple plugin instantiations :) anyway, I ended up thinking this plugin should may be not do to many adjustments, and just keep telling the truth - even if the truth is ugly sometimes :))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are also other modules that have only unique methods, not shared with anything else, ie. ReaderUserHyph.
If we're annoyed with not seeing their name, we could just plug some dummy methods in the classes that need it, ie function ReaderUserHyph:_forClassIdentification() return
Not exactly sure what it does, but I believe its used to reset the Kindle's own sleep timer. I suspect without this KOReader actually still runs, but as there is no touch input when HTTP requests are sent after ~10 mins the timer will trigger the Kindle to go to sleep. |
Can be used to inspect the state of the objects in a running KOReader. It can also be used to execute actions (like the ones available to associate to a gesture) with HTTP requests from a remote computer/devices/gadgets. The TCP server side is implemented with a new ZeroMQ StreamMessageQueueServer (thanks bneo99). Minor UIManager tweak to avoid uneeded inputevent when such a ZeroMQ module is running.
760c3dc
to
d418337
Compare
I still can't figure what's happeninng.
When I hit again the link in Edge, there is no other request/connection, and that content received on the 2nd connection is displayed ... :/ |
I tried rewriting the tcpserver part without ZMQ, but keeping the same API (so, it can be a drop-in replacement). @hius07 : can you try with your Chrome how it behaves, if you replace |
@bneo99 : where would you insert that in the code of this PR? |
Please disregard this code. I tested this part and found that it might be the cause of the random crashes I encountered previously. I will look for another way to keep the Kindle awake, you can proceed to merge this PR without this part. |
Yeah, this server is good. |
Oh, right, our devices over wifi are probably slower :) |
The CI "docs" stuff is failing:
It does not mention any of this PR files at the start, but only at the end :) so probably cause by this PR... |
I don't know if there is a "usual" problem. ;-) But note that all plugins explicitly define a name
Though in this case it might make more sense to just not make it a docstring? There isn't anything else in that file anyway. |
I see this was resolved later on, but, for completeness' sake: this simply "pings" the native system so as not to let it enter standby on its own, in order for everything to behave as on other platforms (i.e., AutoSuspend decides when to standby). Nobody should ever be calling this, AutoSuspend already does it as-needed ;). |
if self._zeromqs[1] then | ||
self.event_hook:execute("InputEvent") | ||
end | ||
local sent_InputEvent = false | ||
for _, zeromq in ipairs(self._zeromqs) do | ||
for input_event in zeromq.waitEvent, zeromq do | ||
if not sent_InputEvent then | ||
self.event_hook:execute("InputEvent") | ||
sent_InputEvent = true | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Umm, this chunk doesn't make sense to me?
AFAICT, it does the exact same thing as before, but.... uglier? ^^.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the intent to only send an InputEvent
in case waitEvent
actually returns something?
Because that raises an interesting conundrum: AFAICT, none of our (ZMQ) waitEvent implementations actually ever return anything... ^^.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may happen when the cat let the mice dance :)
Haven't reread what I wrote to explain the issue and this solution, but will if needed :) It's the 2nd bullet point in the first link, solution detailed in the 2nd link.
#10223 (comment)
#10223 (comment)
As you're back, there's still the Ctrl-C and the "not painting 1 covered widget" that you may have some thoughts about.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In no particular order:
- I can kill stuff just fine via SIGTERM (before this PR, at least ;p) on Kobo, so not quite sure what this was about? (But signals are hell, so I'd rather not have to deal with signals ourselves).
- The double ^C is the expected behavior for SIGQUIT.
- Re: CRe partial renderings and this chunk: I guess it was spamming InputEvent because of the active ZMQ, which means it never went "idle" ;).
The issue, right now, is that since no waitEvent implementations ever return anything, is that: first, this becomes dead code; but more importantly, we no longer send an InputEvent when a ZMQ is active. That's potentially a problem for Calibre Wireless. The main use-case for these is for AutoSuspend's sake, to make it aware that we're actually active and do not want to enter suspend/standby.
So, while the spam every 50ms is a bit overkill, we do need a way to periodically send those when a ZMQ is in play...
(And, ideally, at a delay higher than the CRe "idle" threshold, but lower than the lowest AutoSuspend timer... And that gets tricky, because standby can go as low as 2s ^^). - Re: the _repaint stuff. This is sort of an artifact of the ZMQ being integrated inside the main/render loop, I don't really have a better way to deal with this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- The main use-case for these is for AutoSuspend's sake, to make it aware that we're actually active and do not want to enter suspend/standby.
We might instead want to tackle this the other way around:
- Extend AutoSuspend to provide a way to stop/resume its timers (a pair of events?), and simply call that whenever it makes sense?
(The framework is already in place because we already do something similar on suspend/resume anyway).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have UIManager:preventStandby() / UIManager:allowStandby() - isn't that what you wish for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's for standby only, not suspend ;).
And, now that I think about it, standby is already skipped if wifi is enabled, which is almost guaranteed for these use-cases ;).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm? A server can happily run locally on the device without any wifi.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hence my "almost guaranteed" comment ^^
Use case: https://www.mobileread.com/forums/showthread.php?t=359837. |
I noted this plugin for adding in the upcoming guide update. I was going to ask for an example what it can be used for. You read my mind hius07 👍 |
Can be used to inspect the state of the objects in a running KOReader.
It can also be used to execute actions (like the ones available to associate to a gesture) with HTTP requests from a remote computer/device/gadget.
The TCP server side is implemented with a new ZeroMQ StreamMessageQueueServer (thanks @bneo99). A small interesting writting about ZeroMQ and doing a small HTTP server that way at http://hintjens.com/blog:42.
Minor UIManager tweak to avoid uneeded inputevent when such a ZeroMQ module is running.
Based on (and supercedes) #10223 by @bneo99 , who did all the groundwork (I just had fun with building simple and pretty HTML and using Lua introspection
facilitieshacks to present all the objects we developpers are familiar with in a new light :)).@bneo99: I did some small reworks on the start/stop and menu stuff, please review.
Tell me if there are some other "core objects" I didn't think about, stuff not immediately reachable through these 4 ones.
Other but older screenshots available in #10223 (comment) #10223 (comment)
The plugin is enabled by default, but the server is not started by default.
This is to be run only on trusted networks, as it is highly insecure (no httpS, no access restriction, no authentication, all this is out of scope and some additional access checks could be implemented via user patches I think): your wife can see what you read, and you can see what your children read :)
I previously wondered if this kind of plugin (not strictly reading related) should be shipped or better left be a user-plugin, and was ok having it in core if made generic enough (like I think this finally got), and it's probably more interesting for us developpers, and so good to have it handy present by default in our working tree when git clone, without having to download another user-plugin.
Oh, and yes, the HTML content is left untranslatable, it was painful enough :)
This change is