Searching We.Love.Privacy.Club

Twts matching #doc
Sort by: Newest, Oldest, Most Relevant
In-reply-to » (#jldcvba) @shinyoukai yeah, that's the only reason why I use sub-domains when trying anything federated (I believe Matrix has the same problem), in case things didn't go as planned I can just migrate and take it down.

@prologic@twtxt.net Well, you can associate your identity to the apex domain with a bit of Webfinger wizardry, but I don’t. Mine are always attached to the sub-domains. I find it easier to migrate between instances that way without risking borking federation.

⤋ Read More
In-reply-to » I'm contemplating the idea of switching my activity pub instance from Gootosocial to a Pleroma one. While GTS is kinda cute (lightweight and easy to manage) of a software, the inability to fetch/scroll through people's past toots when visiting a profile or having access to a federated timeline and a proper search functionality ...etc felt like handicap for the past N months.

@bender@twtxt.net yeah, I’ve been reading through the documentation last night and it felt overwhelming for a minute… +1 point goes to GTS’s docs. but hey, I’ll be taking the easy route: podman-compose up -d they provide both a container image and an example compose file in a separate git repo but I’m wondering why that is not mentioned anywhere in the docs, (unless it is and I haven’t seen it yet)

⤋ Read More
In-reply-to » @prologic I'd say give crowdsec a try but I know for sure you prefer your own WAF ... šŸ˜…

@prologic@twtxt.net The main thing that I tought of is that whomever is abusing your services must be a well known actor (by range/set of IPs) that got reported by other Crowdsec users. So to my simpleton’s understanding, your reverse-proxy/web server passes the requests by crowdsec for processing, they get banned for $N hours if the source has already been blacklisted by the community or violates any of a set of behavior base rules (and even more hours for repeat offenders); otherwise the requests/responses go as per usual. Not sure if I got things right but this might help paint a better picture of the process.

⤋ Read More
In-reply-to » There are no really good GUI toolkits for Linux, are there?

FTR, I see one (two) issues with PyQt6, sadly:

  1. The PyQt6 docs appear to be mostly auto-generated from the C++ docs. And they contain many errors or broken examples (due to the auto-conversion). I found this relatively unpleasent to work with.
  2. (Until Python finally gets rid of the Global Interpreter Lock properly, it’s not really suited for GUI programs anyway – in my opinion. You can’t offload anything to a second thread, because the whole program is still single-threaded. This would have made my fractal rendering program impossible, for example.)

⤋ Read More

I used Gemini (the Google AI) twice at work today, asking about Google Workspace configuration and Google Cloud CLI usage (because we use those a lot). You’d think that it’d be well-suited for those topics. It answered very confidently, yet completely wrong. Just wrong. Made-up CLI arguments, whatever. It took me a while to notice, though, because it’s so convincing and, well, you implicitly and subconsciously trust the results of the Google AI when asking about Google topics, don’t you?

Will it get better over time? Maybe. But what I really want is this:

  • Good, well-structured, easy-to-read, proper documentation. Google isn’t doing too bad in this regard, actually, it’s just that they have so much stuff that it’s hard to find what you’re looking for. Hence …
  • … I want a good search function. Just give me a good fuzzy search for your docs. That’s it.

I just don’t have the time or energy to constantly second-guess this stuff. Give me something reliable. Something that is designed to do the right thing, not toy around with probabilities. ā€œAI for everythingā€ is just the wrong approach.

⤋ Read More
In-reply-to » There are no really good GUI toolkits for Linux, are there?

@movq@www.uninformativ.de Yeah, give it a shot. At worst you know that you have to continue your quest. :-)

Fun fact, during a semester break I was actually a little bored, so I just started reading the Qt documentation. I didn’t plan on using Qt for anything, though. I only looked at the docs because they were on my bucket list for some reason. Qt was probably recommended to me and coming from KDE myself, that was motivation enough to look at the docs just for fun.

The more I read, the more hooked I got. The documentation was extremely well written, something I’ve never seen before. The structure was very well thought out and I got the impression that I understood what the people thought when they actually designed Qt.

A few days in I decided to actually give it a real try. Having never done anything in C++ before, I quickly realized that this endeavor won’t succeed. I simply couldn’t get it going. But I found the Qt bindings for Python, so that was a new boost. And quickly after, I discovered that there were even KDE bindings for Python in my package manager, so I immediately switched to them as that integrated into my KDE desktop even nicer.

I used the Python KDE bindings for one larger project, a planning software for a summer camp that we used several years. It’s main feature was to see who is available to do an activity. In the past, that was done on a large sheet of paper, but people got assigned two activities at the same time or weren’t assigned at all. So, by showing people in yellow (free), green (one activity assigned) and red (overbooked), this sped up and improved the planning process.

Another core feature was to generate personalized time tables (just like back in school) and a dedicated view for the morning meeting on site.

It was extended over the years with all sorts of stuff. E.g. I then implemented a warning if all the custodians of an activitiy with kids were underage to satisfy new the guidelines that there should be somebody of age.

Just before the pandemic I started to even add support for personalized live views on phones or tablets during the planning process (with web sockets, though). This way, people could see their own schedule or independently check at which day an activity takes place etc. For these side quests, they don’t have to check the large matrix on the projector. But the project died there.

Here’s a screenshot from one of the main views: https://lyse.isobeef.org/tmp/k3man.png

This Python+Qt rewrite replaced and improved the Java+Swing predecessor.

⤋ Read More
In-reply-to » @lyse LOLz! Way to destroy @prologic's newest playground! :-P

Actually. Looking at the template and the BeerCSS docs, I think I’m just using the wrong elements and doing the wrong thing in the template/partial structure itself šŸ¤” Probably need to wrap text in something else other than a plain ā€˜ol <p>

⤋ Read More
⤋ Read More
In-reply-to » You can explicitly use colors in manpages. I saw this in the apt manpage of Ubuntu recently, which, for some reason, uses blue text in one place:

Ah, so apparently they don’t like writing manpages anymore and instead use XML:

https://salsa.debian.org/apt-team/apt/-/blob/main/doc/apt.8.xml

And then they use XSLT on top and what not:

https://salsa.debian.org/apt-team/apt/-/blob/main/doc/manpage-style.xsl.cmake.in

It’s not even explicitly blue:

https://salsa.debian.org/apt-team/apt/-/blob/main/doc/apt.ent?ref_type=heads#L17

Abstractions upon abstractions upon abstractions.

⤋ Read More

Here’s an example of X11/Xlib being old and archaic.

X11 knows the data type ā€œcardinalā€. For example, the window property _NET_WM_ICON (which holds image data for icons) is an array of ā€œcardinalā€. I am already not really familiar with that word and I’m assuming that it comes from mathematics:

https://en.wikipedia.org/wiki/Cardinal_number

(It could also be a bird, but probably not: https://en.wikipedia.org/wiki/Cardinalidae)

We would probably call this an ā€œintegerā€ today.

EWMH says that icons are arrays of cardinals and that they’re 32-bit numbers:

https://specifications.freedesktop.org/wm-spec/latest-single/#id-1.6.13

So it’s something like 0x11223344 with 0x11 being the alpha channel, 0x22 is red, and so on.

You would assume that, when you retrieve such an array from the X11 server, you’d get an array of uint32_t, right?

Nope.

Xlib is so old, they use char for 8-bit stuff, short int for 16-bit, and long int for 32-bit:

https://x.org/releases/current/doc/libX11/libX11/libX11.html#Obtaining_and_Changing_Window_Properties

That is congruent with the general C data types, so it does make sense:

https://en.wikipedia.org/wiki/C_data_types

Now the funny thing is, on modern x86_64, the type long int is actually 64 bits wide.

The result is that every pixel in a Pixmap, for example, is twice as large in memory as it would need to be. Just because Xlib uses long int, because uint32_t didn’t exist, yet.

And this is something that I wouldn’t know how to fix without breaking clients.

⤋ Read More
In-reply-to » Xfce does one thing very right: It stores its settings in plain-text XML files. This allows me to easily read, track, and maybe even distribute these settings to other machines.

@lyse@lyse.isobeef.org @kat@yarn.girlonthemoon.xyz I spent so much time in the past figuring out if something is a dict or a list in YAML, for example.

What are the types in this example?

items:
- part_no:   A4786
  descrip:   Water Bucket (Filled)
  price:     1.47
  quantity:  4
- part_no:   E1628
  descrip:   High Heeled "Ruby" Slippers
  size:      8
  price:     133.7
  quantity:  1

items is a dict containing … a list of two other dicts? Right?

It is quite hard for me to grasp the structure of YAML docs. 😢

The big advantage of YAML (and JSON and TOML) is that it’s much easier to write code for those formats, than it is with XML. json.loads() and you’re done.

⤋ Read More

I did a ā€œlectureā€/ā€œworkshopā€ about this at work today. 16-bit DOS, real mode. šŸ’¾ Pretty cool and the audience (devs and sysadmins) seemed quite interested. 🄳

  • People used the Intel docs to figure out the instruction encodings.
  • Then they wrote a little DOS program that exits with a return code and they used uhex in DOSBox to do that. Yes, we wrote a COM file manually, no Assembler involved. (Many of them had never used DOS before.)
  • DEBUG from FreeDOS was used to single-step through the program, showing what it does.
  • This gets tedious rather quickly, so we switched to SVED from SvarDOS for writing the rest of the program in Assembly language. nasm worked great for us.
  • At the end, we switched to BIOS calls instead of DOS syscalls to demonstrate that the same binary COM file works on another OS. Also a good opportunity to talk about bootloaders a little bit.
  • (I think they even understood the basics of segmentation in the end.)

The 8086 / 16-bit real-mode DOS is a great platform to explain a lot of the fundamentals without having to deal with OS semantics or executable file formats.

Now that was a lot of fun. 🄳 It’s very rare that we do something like this, sadly. I love doing this kind of low-level stuff.

⤋ Read More

Okay, here’s a thing I like about Rust: Returning things as Option and error handling. (Or the more complex Result, but it’s easier to explain with Option.)

fn mydiv(num: f64, denom: f64) -> Option<f64> {
    // (Let’s ignore precision issues for a second.)
    if denom == 0.0 {
        return None;
    } else {
        return Some(num / denom);
    }
}

fn main() {
    // Explicit, verbose version:
    let num: f64 = 123.0;
    let denom: f64 = 456.0;
    let wrapped_res = mydiv(num, denom);
    if wrapped_res.is_some() {
        println!("Unwrapped result: {}", wrapped_res.unwrap());
    }

    // Shorter version using "if let":
    if let Some(res) = mydiv(123.0, 456.0) {
        println!("Here’s a result: {}", res);
    }

    if let Some(res) = mydiv(123.0, 0.0) {
        println!("Huh, we divided by zero? This never happens. {}", res);
    }
}

You can’t divide by zero, so the function returns an ā€œerrorā€ in that case. (Option isn’t really used for errors, IIUC, but the basic idea is the same for Result.)

Option is an enum. It can have the value Some or None. In the case of Some, you can attach additional data to the enum. In this case, we are attaching a floating point value.

The caller then has to decide: Is the value None or Some? Did the function succeed or not? If it is Some, the caller can do .unwrap() on this enum to get the inner value (the floating point value). If you do .unwrap() on a None value, the program will panic and die.

The if let version using destructuring is much shorter and, once you got used to it, actually quite nice.

Now the trick is that you must somehow handle these two cases. You must either call something like .unwrap() or do destructuring or something, otherwise you can’t access the attached value at all. As I understand it, it is impossible to just completely ignore error cases. And the compiler enforces it.

(In case of Result, the compiler would warn you if you ignore the return value entirely. So something like doing write() and then ignoring the return value would be caught as well.)

⤋ Read More
In-reply-to » Fuck me sideways, Rust is so hard. Will we ever be friends?

@prologic@twtxt.net I’m trying to call some libc functions (because the Rust stdlib does not have an equivalent for getpeername(), for example, so I don’t have a choice), so I have to do some FFI stuff and deal with raw pointers and all that, which is very gnarly in Rust – because you’re not supposed to do this. Things like that are trivial in C or even Assembler, but I have not yet understood what Rust does under the hood. How and when does it allocate or free memory … is the pointer that I get even still valid by the time I do the libc call? Stuff like that.

I hope that I eventually learn this over time … but I get slapped in the face at every step. It’s very frustrating and I’m always this šŸ¤ close to giving up (only to try again a year later).

Oh, yeah, yeah, I guess I could ā€œjustā€ use some 3rd party library for this. socket2 gets mentioned a lot in this context. But I don’t want to. I literally need one getpeername() call during the lifetime of my program, I don’t even do the socket(), bind(), listen(), accept() dance, I already have a fully functional file descriptor. Using a library for that is total overkill and I’d rather do it myself. (And look at the version number: 0.5.10. The library is 6 years old but they’re still saying: ā€œNah, we’re not 1.0 yet, we reserve the right to make breaking changes with every new release.ā€ So many Rust libs are still unstable …)

… and I could go on and on and on … 🤣

⤋ Read More

fn sub(foo: &String) {
    println!("We got this string: [{}]", foo);
}

fn main() {
    // "Hello", 0x00, 0x00, "!"
    let buf: [u8; 8] = [0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x00, 0x00, 0x21];

    // Create a string from the byte array above, interpret as UTF-8, ignore decoding errors.
    let lossy_unicode = String::from_utf8_lossy(&buf).to_string();

    sub(&lossy_unicode);
}

Create a string from a byte array, but the result isn’t a string, it’s a cow 🐮, so you need another to_string() to convert your ā€œstringā€ into a string.

I still have a lot to learn.

(into_owned() instead of to_string() also works and makes more sense to me, it’s just that the compiler suggested to_string() first, which led to this funny example.)

⤋ Read More
In-reply-to » So I was using this function in Rust:

@lyse@lyse.isobeef.org Rust is so different and, at the same time, so complex – it’s not far fetched to assume that I simply don’t understand what’s going on here. The docs appear to be clear, but alas … is it a bugs in the docs? Is it a lack of experience on my part? Who knows.

By the way, looks like there was a bit of a discussion regarding that name:

https://github.com/rust-lang/rust/issues/120048

⤋ Read More

So I was using this function in Rust:

https://doc.rust-lang.org/std/path/struct.Path.html#method.display

Note the little 1.0.0 in the top right corner, which means that this function has been ā€œstable since Rust version 1.0.0ā€. We’re at 1.87 now, so we’re good.

Then I compiled my program on OpenBSD with Rust 1.86, i.e. just one version behind, but well ahead of 1.0.0.

The compiler said that I was using an unstable library feature.

Turns out, that function internally uses this:

https://doc.rust-lang.org/std/ffi/struct.OsStr.html#method.display

And that is only available since Rust 1.87.

How was I supposed to know this? 🤨🫩

⤋ Read More
In-reply-to » I wanted to port this to Rust as an excercise, but they still have no random number generator in the core library: https://github.com/rust-lang/rust/issues/130703

@prologic@twtxt.net Yeah, it’s difficult, you often don’t get what you’d expect. They also make heavy use of 3rd party libraries. IIUC, for random numbers, they refer to this library. I’ve read many times that the Rust stdlib is intentionally minimalistic (to make it easier to maintain and port and all that).

I’m struggling with this, using 3rd party libs for so many things isn’t really my cup of tea. I’ll probably make my own tiny little ā€œstandard libraryā€. It’s silly, but I don’t see any other options. 🤷

⤋ Read More