Help Bites
-
@hungrier said in Help Bites:
But is it Windows only?
Nah, it's Java so it'll run on MacOS or Linux.
@hungrier said in Help Bites:
extremely fiddly to work with token authentication redirects and json payloads
Depends what you need but probably. It's at least possible to script it with other stuff if needed.
-
@hungrier said in Help Bites:
weird cookie issues
Ah, yeah, if your API is fucking around with cookies, good luck. That shit is janky on web browsers as it is...
-
@loopback0 said in Help Bites:
@hungrier said in Help Bites:
What's the best HTTP API test software? It can't possibly be Postman
I use SoapUI or good ol'
curl
depending on what I need to do.Do you use the "free" version or the paid version ($600 a year)?
Main downsides is that pricing, the fact that it has been originally made for SOAP calls while REST got added in later (big surprise given the name) and the fact it's UI is stuck in the year 2003 (unless they rewrote that less than a year ago, but I'm not holding my breath).
However, my opinion might be somewhat colored by a test project setup by an external consultant. We asked for a way to quickly get multiple scenarios up and running without too much boilerplate, and we ended up with some inner-platform SoapUI thing driven by an Excel file.
-
@JBert said in Help Bites:
Do you use the "free" version or the paid version ($600 a year)?
Free.
@JBert said in Help Bites:
the fact that it has been originally made for SOAP calls while REST got added in later
The REST stuff works, although a lot of our stuff is still SOAP, so that's not really an issue.
@JBert said in Help Bites:
UI is stuck in the year 2003 (unless they rewrote that less than a year ago, but I'm not holding my breath).
Yeah the UI is the same.
-
So I'm working on my task using postman, when suddenly it stops working. I do the normal thing of quitting and restarting, and this is what I get:
Thanks Postman, very cool
-
@hungrier Much beige, such wow.
-
@hungrier said in Help Bites:
For my current purpose I need something that'll work in Linux
Curl may work for what I need but I think it would be extremely fiddly to work with token authentication redirects and json payloadsMaybe PowerShell Core?
Invoke-WebRequest
can deal with cookies, andConvertTo-JSON
/ConvertFrom-JSON
will handle the payloads. Not 100% sure on token authentication redirects.
-
@Unperverted-Vixen For now, at least when it works, I've got a setup working in postman that works for what I need. I don't really want to mess around with auth tokens on CLI tools
-
@loopback0 Cosmic Latte?
-
Linux file permissions and groups
Say I have a root
media
folder, with subfolders formusic
,tv
, andmovies
. Each of these has to be writable by some management app running under its own user with its own group, as I understand well-behaved Linux programs should do. They also all should be accessible and writable by Plex and preferably by a user logged into the desktop.Right now I'm thinking:
- add all the users to a media group
- media group owns the folder
- each app owns its own folder
- 775 permissions on everything
Does that make sense, and/or is there some horrible pitfall that I don't see?
-
@hungrier said in Help Bites:
Does that make sense, and/or is there some horrible pitfall that I don't see?
Seems fine to me.
Plex only needs read permission usually unless you want to make transcode versions of stuff.
-
@Tsaukpaetra I thought it also added some metadata, but maybe it doesn't put it next to the actual media. I don't know for sure
-
@hungrier said in Help Bites:
@Tsaukpaetra I thought it also added some metadata, but maybe it doesn't put it next to the actual media. I don't know for sure
No, the metadata is kept in Plex's own application data folder.
-
@Tsaukpaetra I've got metadata together with my media but that must all be from Sonarr if it's not Plex
-
@hungrier said in Help Bites:
@Tsaukpaetra I've got metadata together with my media but that must all be from Sonarr if it's not Plex
One easy trick is to see the owner of the files.
-
@Tsaukpaetra It would be if these files were created by their respective programs on the Linux machine, but they're all copied from my (Windows) desktop
-
@hungrier said in Help Bites:
@Tsaukpaetra It would be if these files were created by their respective programs on the Linux machine, but they're all copied from my (Windows) desktop
Whelp.
-
@hungrier said in Help Bites:
@Tsaukpaetra I've got metadata together with my media but that must all be from Sonarr if it's not Plex
It is.
-
re: Plex requiring write access
Something I hadn't thought of: If you need to pre-encode an H264 version for compatibility with things because the shitty computer can't convert 1080p VC1 on the fly, it needs to be somewhere that Plex has write access to. I ended up using another external "Plex versions" folder for now because I didn't feel like fiddling with Linux's shitty permission system any more for now.
-
Anyway the real reason I came back to this topic is something unrelated.
I got the idea into my head to convert an old computer PSU into a bench power supply, and most of the guides I've seen mention that it may or may not need a dummy load on 5V in order to work. However I haven't seen any of them mention how to tell if it does. If it's something simple like it won't turn on without it, then I think I'm fine. However I don't want to go ahead without it if it's something like "it'll work fine for 37 minutes, then explode into flaming shards"
Does anyone here have experience with this and/or know how to determine if my PSU requires the dummy load or not?
-
@hungrier As far as I know it boils down to testing it. I believe running without a load shouldn't do any damage, it's just that the PSU might shut down when it detects no load.
Anyway, I was thinking of doing the same until I read someone correctly mentioning that those power supplies have a good bunch of power, but no real configurable protection circuits. As a result it will make not shut down when it is frying your circuits. Only use it on something you can risk to fry, or learn / buy kits to add it yourself.
(In the end I splurged on a professional model bench power supply one late night, which I did regret the week after when I read that those too can burn up sometimes. Still, if I don't do reckless things with it then I guess it'll last me a lifetime. At least it's more likely that I'm doing something wrong in the circuit rather than the PSU failing to deliver. )
-
@hungrier Depends on what you mean by "old computer PSU". If it's not total no-name, check if there are any schematics available - HardwareSecrets and JonnyGuru, maybe even Tom's Hardware. The idea is: if it's DC-DC topology (that is, it converts first to 12V, then feeds minor rails from that), you're fine. If there's no schematics, only thing is to become good at electronicks to open it up and figure out what goes where.
-
@JBert said in Help Bites:
Anyway, I was thinking of doing the same until I read someone correctly mentioning that those power supplies have a good bunch of power, but no real configurable protection circuits. As a result it will make not shut down when it is frying your circuits. Only use it on something you can risk to fry, or learn / buy kits to add it yourself.
I'm not terribly concerned about that for now. I don't have any real plans, but I like tinkering with stuff like that in general. It'd be nice to have something to show for it at the end, especially if it can be useful later on for whatever else I want to do.
-
@Applied-Mediocrity I did a quick search on the brand name, and the first thing is a forum where someone mentioned that the only thing they can find searching for it is that very thread
-
@hungrier said in Help Bites:
However I haven't seen any of them mention how to tell if it does.
You bridge the power-supply-turn-on pin with ground (if memory serves) and if it turns on then it doesn't need anything more.
There's no way (visually) to tell, and it's not like it's listed on the box.
-
@Tsaukpaetra That's what it seems like from what I can see. I've seen the suggestion to verify that the voltages and PG are correct and steady, which sounds to me like they're saying "if it works, it's good"
-
@hungrier said in Help Bites:
"if it works, it's good"
Yeah. The alternative "If it doesn't work, it should definitely not have been in a PC because shit's sensitive, man!"
-
@Tsaukpaetra If it's in a PC it wouldn't need a dummy load anyway
-
@hungrier said in Help Bites:
@Tsaukpaetra If it's in a PC it wouldn't need a dummy load anyway
That's why it's not labeled or put on a spec or anything.
-
Status: I think I'm doing evil. Is this evil?
private: Client* m_client; void setClient(const Client& newClient) {m_client = const_cast<Client*>(&newClient);}; ... In receiver function.... template <class ServerT> void WebDuino::processConnection(ServerT &ServerInterface, char *buff, int *bufflen) { setClient(ServerInterface.available()); ... blah blah.... }
the
ServerT
type is expected to be a passed-by-value object ofServer
, which has a functionavailable()
that returns an object subclassing the abstract classClient
, but (as far as I can tell) I can't get it to make a copy constructor for it, so I'm doing the above.I don't care about the child class's shit, just the base class's methods (and being able to call them from the virtual table thingy of the sub-class whatever).
Is this really the way?
I also believe I'm going to have a memory leak before all is said and actually attempted to run, but I don't into C++ all that well and from the last conversation touting
const
I feel a little out of depth.Edit: Yeah, crashing hard.
02:11:41.351 -> Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled. 02:11:41.451 -> Core 1 register dump: 02:11:41.485 -> PC : 0x400d139e PS : 0x00060b30 A0 : 0x800d13fb A1 : 0x3ffb1e10 02:11:41.587 -> A2 : 0x00000000 A3 : 0x3ffb8718 A4 : 0x000020a6 A5 : 0x3ffc0910 02:11:41.655 -> A6 : 0x00000021 A7 : 0x3ffc0198 A8 : 0x800d1395 A9 : 0x3ffb1df0 02:11:41.755 -> A10 : 0x3ffb1e8c A11 : 0x3ffc0575 A12 : 0x67230001 A13 : 0x0000ff00 02:11:41.856 -> A14 : 0x00ff0000 A15 : 0xff000000 SAR : 0x0000000a EXCCAUSE: 0x0000001c 02:11:41.959 -> EXCVADDR: 0x0000003c LBEG : 0x4000c428 LEND : 0x4000c42d LCOUNT : 0x00000000 02:11:42.028 -> 02:11:42.028 -> Backtrace: 0x400d139e:0x3ffb1e10 0x400d13f8:0x3ffb1e30 0x400d14e5:0x3ffb1e50 0x400d2ec5:0x3ffb1e70 0x400d2f99:0x3ffb1ec0 0x400d2fb5:0x3ffb1f10 0x400d178d:0x3ffb1f30 0x400d19df:0x3ffb1f70 0x400d2e15:0x3ffb1f90 0x400d7fd1:0x3ffb1fb0 0x400889d9:0x3ffb1fd0 02:11:42.299 -> 02:11:42.299 -> Rebooting...
-
@Tsaukpaetra said in Help Bites:
object of Server, which has a function available() that returns an object subclassing the abstract class Client, but (as far as I can tell) I can't get it to make a copy constructor for it
So, the
Client
-subclassed object is returned by value, its type could be "anything derived fromClient
", but you want to takeWebDuino::processConnection
to take ownership of it? Can you use move semantics inside the templated method to put the object on the heap, then stuff that pointer intom_client
? Are you allowed to changeClient
if it turns out to forbid both copy-construction and move-construction?It would have been much easier if
ServerInterface.available()
returned a pointer. Or astd::unique_ptr<Client>
if they wanted the caller to take ownership.so I'm doing the above.
Yeah, you seem to be taking a pointer to a temporary object that only exists for the duration of the
setClient()
call.
-
@Tsaukpaetra
const_cast
is indeed evil. But also, as aitap said, it sounds like move semantics are what you want. Passing stuff by value goes well with move semantics, no need for copying anything since copying wouldn't make sense in this case.
-
@Tsaukpaetra what is
ServerInterface.available()
actually returning, a referenceClient&
or an actual objectSomeClientImplementation
?
If it’s the latter, it should have at least a move constructor (not technically required anymore, but would be unusual). You are definitely storing a stale pointer to a temporary, which is worse than leaking memory and will crash.
If it’s the former, it really depends on what the lifetime of the object is (are you taking ownership or not) how long that pointer is valid.As has been pointed out, your const cast is evil one way or another.
-
@aitap said in Help Bites:
Can you use move semantics
I have no idea what this is. Reading now.
@aitap said in Help Bites:
Are you allowed to change
Client
if it turns out to forbid both copy-construction and move-construction?This is the base Arduino api-thing, I'm already dealing with a breaking change the ESP32 devs decided to fuck up for some reason.
@LB_ said in Help Bites:
no need for copying anything since copying wouldn't make sense in this case.
Yeah I'm trying to avoid copying, but I'm no so good with this memory stuff. I'm not even sure how to figure out if I'm fucking up the heap with this.
@topspin said in Help Bites:
@Tsaukpaetra what is
ServerInterface.available()
actually returning, a referenceClient&
or an actual objectSomeClientImplementation
?In this case it's a
ServerInterface's Client object
. Specfically:EthernetClient EthernetServer::available() { //blah code to find sockindex, a uint8_t return EthernetClient(sockindex); }
If it’s the latter, it should have at least a move constructor (not technically required anymore, but would be unusual). You are definitely storing a stale pointer to a temporary, which is worse than leaking memory and will crash.
Yes, it's definitely crashing!
If it’s the former, it really depends on what the lifetime of the object is (are you taking ownership or not) how long that pointer is valid.
I suppose I'm completely missing what is meant by "taking ownership". But I would agree that the pointer seems definitely invalid by the time it's actually used.
As has been pointed out, your const cast is evil one way or another.
I've added another thingy to the template, it now looks like this:
template <class ClientT, class ServerT> void WebDuino::processConnection(ServerT &ServerInterface, char *buff, int *bufflen) { delete m_client; m_client = (Client*)new ClientT(ServerInterface.available()); }
But I'm sure this is also wrong in some way too, though it does seem to be working... (I'd have to spam the port with connections for some time to see if it fucks up, but my money is on
YES
).
-
@Tsaukpaetra said in Help Bites:
I've added another thingy to the template, it now looks like this:
template <class ClientT, class ServerT> void WebDuino::processConnection(ServerT &ServerInterface, char *buff, int *bufflen) { delete m_client; m_client = (Client*)new ClientT(ServerInterface.available()); }
But I'm sure this is also wrong in some way too, though it does seem to be working... (I'd have to spam the port with connections for some time to see if it fucks up, but my money is on
YES
).Looks better.
You should wrap yourm_client
in aunique_ptr
, then you can get rid of thedelete
.
Also, didn't you say there is no copy constructor?
-
@topspin said in Help Bites:
You should wrap your
m_client
in aunique_ptr
, then you can get rid of thedelete
.I don't know what that is. Researching....
Also, didn't you say there is no copy constructor?
I didn't see one defined? Is that one of the automagic ones? I just typed words until it seemed to work...
-
Is this the code you're having to use? https://github.com/arduino-libraries/Ethernet/blob/75a3c37b5e513305b82e926ca6a4f8190f536c9d/src/Ethernet.h#L214-L250
I can't find "Client.h", but I haven't spent more than a few minutes searching. So far though my impressions of this are... not good. It's a polymorphic class type, but they have left the copy and move ctors to be implicit, which means there is potential for slicing if you assign a more derived type to a less derived type.
But anyway, it looks like move semantics will not work for you after all due to the polymorphism. You do need to use a smart pointer. Pretty simple:
private: std::unique_ptr<Client> m_client; template<typename ClientT> void setClient(ClientT newClient) { m_client = std::make_unique<ClientT>(std::move(new_client)); }
This will take any client and move it into a smart pointer, then the
m_client
var will hold it as long asClientT
is derived fromClient
.template <class ServerT> void WebDuino::processConnection(ServerT &ServerInterface, char *buff, int *bufflen) { setClient(ServerInterface.available()); //... blah blah.... }
Then this original code you had can remain unchanged, it will just work with the new code above. We are using move semantics here, to move the return value of
ServerInterface.available()
from the stack to the heap (pointed to by theuniue_ptr
), but that's of the same type as the fully derived type that theavailable()
function returns by value (copy or move). You could avoid usingunique_ptr
and just move it into the class directly if you knew the fully derived type in advance, but since you want to accept anything that derives fromClient
you need to use a pointer here.The full chain of operations now is:
ServerInterface.available()
returns some concrete type by value that derives fromClient
- that return value gets passed into the parameter of
setClient
by value (copy or move, likely elided by the compiler) - a dynamic allocation happens to hold the
ClientT
- the parameter is given to the move constructor of the new dynamically allocated one, and thus from our perspective moved from the stack to the heap (this can also be elided by the compiler)
- the pointer is stored as a member variable, thanks to the
=
being overloaded to allow more-derivedunique_ptr
to be assigned to less-derivedunique_ptr
. Any previous value in the member variable is freed.
With compiler optimizations it can probably go straight from step 1 to the end of step 4, only needing to keep the dynamic memory allocation.
-
@LB_ said in Help Bites:
Is this the code you're having to use? https://github.com/arduino-libraries/Ethernet/blob/75a3c37b5e513305b82e926ca6a4f8190f536c9d/src/Ethernet.h#L214-L250
Yes.
I can't find "Client.h", but I haven't spent more than a few minutes searching. So far though my impressions of this are... not good. It's a polymorphic class type, but they have left the copy and move ctors to be implicit, which means there is potential for slicing if you assign a more derived type to a less derived type.
Yeah,
Client.h
is an almost completely-abstract class. (if I'm understanding how that works) consisting of all virtual methods and looks basically identical with exception of the ints there.But anyway, it looks like move semantics will not work for you after all due to the polymorphism. You do need to use a smart pointer. Pretty simple:
private: std::unique_ptr<Client> m_client; template<typename ClientT> void setClient(ClientT newClient) { m_client = std::make_unique<ClientT>(std::move(new_client)); }
This will take any client and move it into a smart pointer, then the
m_client
var will hold it as long asClientT
is derived fromClient
.template <class ServerT> void WebDuino::processConnection(ServerT &ServerInterface, char *buff, int *bufflen) { setClient(ServerInterface.available()); //... blah blah.... }
Then this original code you had can remain unchanged, it will just work with the new code above. We are using move semantics here, to move the return value of
ServerInterface.available()
from the stack to the heap (pointed to by theuniue_ptr
), but that's of the same type as the fully derived type that theavailable()
function returns by value (copy or move). You could avoid usingunique_ptr
and just move it into the class directly if you knew the fully derived type in advance, but since you want to accept anything that derives fromClient
you need to use a pointer here.Yeah, originally the Webduino code (that I'm shamelessly ripping from) explicitly called upon the EthernetClient and EthernetServer classes directly, but since I wanted it to be interchangable that's why I want it to be a pointer.
The full chain of operations now is:
ServerInterface.available()
returns some concrete type by value that derives fromClient
- that return value gets passed into the parameter of
setClient
by value (copy or move, likely elided by the compiler) - a dynamic allocation happens to hold the
ClientT
- the parameter is given to the move constructor of the new dynamically allocated one, and thus from our perspective moved from the stack to the heap (this can also be elided by the compiler)
- the pointer is stored as a member variable, thanks to the
=
being overloaded to allow more-derivedunique_ptr
to be assigned to less-derivedunique_ptr
. Any previous value in the member variable is freed.
With compiler optimizations it can probably go straight from step 1 to the end of step 4, only needing to keep the dynamic memory allocation.
Sounds like a plan. But, I'm assuming I missed a step somewhere, it's complaining weirdly...
error: 'unique_ptr' in namespace 'std' does not name a template type std::unique_ptr<Client> m_client;
-
@Tsaukpaetra add
#include <memory>
.
-
@topspin said in Help Bites:
@Tsaukpaetra add
#include <memory>
.Discoverable...
And for this then?
error: 'make_unique' is not a member of 'std' m_client = std::make_unique<ClientT>(std::move(ServerInterface.available())); ^ error: expected primary-expression before '>' token m_client = std::make_unique<ClientT>(std::move(ServerInterface.available())); ^
I kinda wish I could just stuff my head back into the sludge that is PHP. In fact, Imma do that now....
-
@Tsaukpaetra guessing (on the phone) you need to change your compiler flags. Increase to
-std=c++14
formake_unique
or go directly to 17.
If that’s not supported, you could skip themake_unique<ClientT>(...)
part and replace it withunique_ptr<ClientT>(new ClientT(...))
.
-
@topspin said in Help Bites:
@Tsaukpaetra guessing (on the phone) you need to change your compiler flags. Increase to
-std=c++14
formake_unique
or go directly to 17.
If that’s not supported, you could skip themake_unique<ClientT>(...)
part and replace it withunique_ptr<ClientT>(new ClientT(...))
.No, can't do c++ bigger than 11 without annoying hacks to the device definitions. Chaining the
unique_ptr
andnew
seems to work. I'm wondering why that makes me not need to delete it though? More reading is in store for me I guess...
-
@Tsaukpaetra said in Help Bites:
Chaining the
unique_ptr
andnew
seems to work. I'm wondering why that makes me not need to delete it though? More reading is in store for me I guess...That is exactly the point of
unique_ptr
. Its destructor calls delete, so you can’t forget it (even in the case of exceptions) or call it twice. One fewer source of common bugs (99infinitely many remaining).
-
@Tsaukpaetra said in Help Bites:
More reading is in store for me I guess...
cppreference is an always-useful resource for me: https://en.cppreference.com/w/cpp/memory/unique_ptr
std::unique_ptr
is a smart pointer that owns and manages another object through a pointer and disposes of that object when theunique_ptr
goes out of scope.The object is disposed of using the associated deleter when either of the following happens:
- the managing
unique_ptr
object is destroyed - the managing
unique_ptr
object is assigned another pointer viaoperator=
orreset()
.
The object is disposed of using a potentially user-supplied deleter by calling
get_deleter()(ptr)
. The default deleter uses thedelete
operator, which destroys the object and deallocates the memory.If you want to, for example, use
std::free
instead (e.g. when needing to manage something given by a C library that was allocated withstd::malloc
orstd::calloc
) you can do this:struct StdFreeDeleter final { void operator()(void *p) noexcept { std::free(p); } }; template<typename T> using c_unique_ptr = std::unique_ptr<T, StdFreeDeleter>; c_unique_ptr<some_c_struct> ptr (some_c_function()); use_some_c_struct(ptr.get()); ptr.reset(some_other_c_function());
- the managing
-
I've got some fucking obnoxious settings enforced on my work laptop by Group Policy (eg, screen lock with password after 5 minutes of idle). Is there any way that I, a user that has managed to obtain local admin rights, can override or disable GPOs?
-
-
So I was looking at my Linux machine in the basement again, trying to get5.1 channel audio working.
My janky Rube Goldberg setup has a bunch of HDMI sources plugged into an HDMI switcher with audio extraction, which connects with HDMI to my TV and with toslink to my (old, pre-HDMI) audio receiver. This works great for my Playstations that support the right format of digital audio over HDMI that can be extracted in this way. Not so great for my Nintendo consoles that apparently can only output 5.1 PCM. I've also got the computer hooked up to this thing with HDMI, and stereo works but 5.1 seems to be PCM only as well.
What I did find that works is connecting the optical output directly from my computer to the receiver. It's not immediately available but with some additional software I could enable AC3 5.1-channel output on the optical port, and my receiver is perfectly happy with that. However, it's kind of flaky when plugging it in and out, and I'd prefer to have everything going through the HDMI switcher.
Is there any way to enable the AC3 format for 5.1 over HDMI? I spent a bunch of time looking at (old, crappy) guides that I could find online, but none of them worked. The worst was trying to use Xplayer's AC3 passthrough with an AC3 encoded file, which seemed to work for 4 seconds then crashed the entire audio system so hard that the HDMI sound device was completely gone until I rebooted.
-
@hungrier said in Help Bites:
my Linux machine
Well first you're going to need the kernel sources...
-
Docking Station Status: I recently got an additional work laptop with a USBC docking station, and they work together great. Power, network, display, probably USB (haven't tried yet, ). But I've also got another work laptop with USBC, which I've verified can be powered over USBC, so I figured I would try replacing the (proprietary) dock that that one uses with this new dock, to make better use of my desk space.
Everything worked right off the bat, with one exception: power. For some reason, the laptop that's just fine being plugged into a USBC power brick rated for 65W, is unable to draw power from the dock that, according to the manual, should work with laptops that need up to 130W.
-
There's more to USB-C power than just wattage. It's actually a standard with plenty of variations and options. So compatibility problems are not rare.
I don't think there's much you can do to solve the problem while keeping your existing dock, unfortunately. A firmware update for the dock and/or the laptop, maybe?