Closed lrstanley closed 5 years ago
Hi @lrstanley, let me say up front, thank you very much for all the great feedback and the offer to help!
My apologies for the delay in getting back to you. I've had more priorities than I have time lately. :)
I will attempt to address all of your comments/suggestions in order:
& 2. & 3. All good suggestions. Much appreciated. Haven't had anyone mention accidentally deleting their library running the sample code before, but clearly it's not a great thing to have the potential for. I'm happy to accept a PR for them.
The device caching is necessary (imho) in this library because of the nature of the Arlo API. It's fundamentally an async API which uses a single EventStream for all the messages. The EventStream and all related HTTP requests to the /notify
endpoint share a single HTTP session, and only a single HTTP session is allowed. I also didn't want to have to pass that session around all over the place.
The basestations are the only ones that interact with the EventStream and the basestation must ping the EventStream every 30 seconds to keep it alive. (The ping request includes the basestation device id as well as the xCloudId, which is only found on devices.) So, to me, it made sense to tie the EventStream to the basestations and cache all the devices, but I'm open to having architectural discussions on this topic. If you can propose a better architecture, I'm happy to consider it.
The thing I was trying to avoid was forcing the programmer to cast the device to the specific type once they call FindDevice()
as that sort of requires the programmer to have explicit knowledge of the underlying, not documented at all, Arlo API and what device types there are. I want to remove as much of that as possible in this library. If you want to throw together a PR with your suggested changes here, I'm happy to consider/discussion it.
Again, I'm open to a proposal (or PR to talk about) here. I made this decision because the HTTP session is required for all of the API calls which are made by all of the devices (and the EventStream). It was an architectural decision, as I didn't want to have to injection the HTTP session/request object into every API method, and I wanted the individual API methods to be tied to their respective devices, so it was clear to the consumer of this library which APIs they could call on which objects.
I agree. Those functions are just there because it was late and I haven't gotten around to moving them into their own package. At the time, I was fighting with the go core team about getting those functions moved into the go standard library, and so, I just threw them in to get by. But I do like the suggestion of adding methods to those types. I will move them to an internal package soon.
Just haven't gotten around to it, but I definitely agree and will put it on the backlog. (I'm happy to accept a PR for this too.)
I have, just didn't feel like it was ready at the time, and dep has been working fine, so figured I'd wait until Go 2 or whatever and deal with that then. (This is also something I'm open to consider a PR for, but would want to discuss it a little bit first.)
Thanks again! Jeff
@lrstanley going to close this issue. I went ahead and filed proper issues for each of the items you suggested. Please feel free to take any of them you would like. All help is much appreciated!
Thanks again!
Hello! I recently wrote up a quick utility which streamlines the mirroring of recordings from Arlo, using this library: https://github.com/lrstanley/arlo-dl.
Per the readme, I wanted to share some feedback. Loving that I can interact with Arlo's API's in Go now, but I did notice some odd issues/quirks.
_examples
directory. This is the common location for most packages (example layout here).Arlo
struct.Devices.GetCameras()
, I would think would return a slice of cameras, not a custom-typed version of a slice of cameras. It's not clear unless the user reads your source, to know they can iterate over that returned type. returning[]Camera
is more much clear in my opinion.arlo.FindDevice(id string) (Device, error)
and having it callarlo.GetDevices()
under the covers, than callingarlo.GetDevices()
, thendevices.FindDevice()
. This way, the user wanting more control, can just iterate through the devices themselves, and a user wanting simplicity, gets it at the abstraction level.[]<type>
on top of another type, in most situations.Devices
,Cameras
,Basestations
, etc.arlo
) is a frowned upon thing in go from my experience, as it reduces simplicity, and can lead to very messy code.FromUnixMicro
style functions defined at package root, aren't things that should, in my opinion, live in this library. If these are needed, they might be better off as methods on the given type that needs them. I.e.Timestamp()
method on theRecording
type (and if there is a conflicting field, name thatTimestampUnix
, etc), rather than requiring the user to pass some field into these functions.Arlo
is provided to arbitrarily call a given API endpoint, the*Uri
constants that are exported here, I don't see why they would need to be exported, given the end user isn't going to use them. This would reduce the type footprint for users.I am willing to help with some of these points if you think they are valid.