this post was submitted on 16 Jun 2025
225 points (93.8% liked)

linuxmemes

25668 readers
925 users here now

Hint: :q!


Sister communities:


Community rules (click to expand)

1. Follow the site-wide rules

2. Be civil
  • Understand the difference between a joke and an insult.
  • Do not harrass or attack users for any reason. This includes using blanket terms, like "every user of thing".
  • Don't get baited into back-and-forth insults. We are not animals.
  • Leave remarks of "peasantry" to the PCMR community. If you dislike an OS/service/application, attack the thing you dislike, not the individuals who use it. Some people may not have a choice.
  • Bigotry will not be tolerated.
  • 3. Post Linux-related content
  • Including Unix and BSD.
  • Non-Linux content is acceptable as long as it makes a reference to Linux. For example, the poorly made mockery of sudo in Windows.
  • No porn, no politics, no trolling or ragebaiting.
  • 4. No recent reposts
  • Everybody uses Arch btw, can't quit Vim, <loves/tolerates/hates> systemd, and wants to interject for a moment. You can stop now.
  • 5. πŸ‡¬πŸ‡§ Language/язык/Sprache
  • This is primarily an English-speaking community. πŸ‡¬πŸ‡§πŸ‡¦πŸ‡ΊπŸ‡ΊπŸ‡Έ
  • Comments written in other languages are allowed.
  • The substance of a post should be comprehensible for people who only speak English.
  • Titles and post bodies written in other languages will be allowed, but only as long as the above rule is observed.
  • 6. (NEW!) Regarding public figuresWe all have our opinions, and certain public figures can be divisive. Keep in mind that this is a community for memes and light-hearted fun, not for airing grievances or leveling accusations.
  • Keep discussions polite and free of disparagement.
  • We are never in possession of all of the facts. Defamatory comments will not be tolerated.
  • Discussions that get too heated will be locked and offending comments removed.
  • Β 

    Please report posts and comments that break these rules!


    Important: never execute code or follow advice that you don't understand or can't verify, especially here. The word of the day is credibility. This is a meme community -- even the most helpful comments might just be shitposts that can damage your system. Be aware, be smart, don't remove France.

    founded 2 years ago
    MODERATORS
     

    Has my motd gone too far? It loads a random ANSI catgirl from a folder. I use arch btw, server runs minimized Ubuntu Server.

    all 30 comments
    sorted by: hot top controversial new old
    [–] unrealMinotaur@sh.itjust.works 37 points 23 hours ago

    Catgirls aren't cringe, but ubuntu is.

    [–] rtxn@lemmy.world 47 points 1 day ago (2 children)

    You could double the vertical resolution by using half-height blocks (U+2584) and using the background color for the upper half.

    [–] Finadil@lemmy.world 15 points 1 day ago (1 children)

    Thanks for the suggestion, gonna look into this. I didn't want to use real images even though kitty supports them because I like the retro look and wanted it terminal agnostic for when I use termux on my phone.

    [–] TwilightKiddy@programming.dev 15 points 1 day ago* (last edited 1 day ago) (2 children)

    I gladly present you this jank.

    You might need these to compile:

    cargo add image
    cargo add clap --features derive
    

    And the jank itself:

    Some Rust code

    use std::path::PathBuf;
    
    use clap::Parser;
    use image::{ imageops::{self, FilterType}, ImageReader };
    
    #[derive(Parser)]
    struct Cli {
        path: PathBuf,
        #[arg(short = 'H', long, default_value_t = 30)]
        height: u32,
        #[arg(short, long, default_value_t = 0.4)]
        ratio: f32,
        #[arg(short, long, default_value_t, value_enum)]
        filter: Filter,
    }
    
    #[derive(clap::ValueEnum, Clone, Default)]
    enum Filter {
        Nearest,
        Triangle,
        Gaussian,
        CatmullRom,
        #[default]
        Lanczos3,
    }
    
    fn main() -> Result<(), Box<dyn std::error::Error>> {
        let args = Cli::parse();
        let filter = match args.filter {
            Filter::Nearest    => { FilterType::Nearest },
            Filter::Triangle   => { FilterType::Triangle },
            Filter::CatmullRom => { FilterType::CatmullRom },
            Filter::Gaussian   => { FilterType::Gaussian },
            Filter::Lanczos3   => { FilterType::Lanczos3 },
        };
        let img = ImageReader::open(args.path)?.decode()?;
        let original_ratio = img.width() as f32 / img.height() as f32;
        let width = ( args.height as f32 / args.ratio ) * original_ratio;
        let out = imageops::resize(&img, width as u32, args.height * 2, filter);
        let mut iter = out.enumerate_rows();
        while let Some((_, top)) = iter.next() {
            let (_, bottom) = iter.next().unwrap();
            top.zip(bottom)
                .for_each(|((_, _, t), (_, _, b))| {
                    print!("\x1B[38;2;{};{};{};48;2;{};{};{}m\u{2584}", b[0], b[1], b[2], t[0], t[1], t[2])
                });
            println!("\x1B[0m");
        }
        Ok(())
    }
    

    [–] Finadil@lemmy.world 7 points 1 day ago (1 children)

    It's beautiful! I actually adjusted my python code to your method and just for optimization checked if the current two pixel colors match the previous two and if so leave out the color info. Much more fidelity in the images now!

    [–] TwilightKiddy@programming.dev 1 points 15 hours ago

    As an extra optimization, if top and bottom colors of a pixel match, you can just output space and only set background color. Implemented correctly, this can save a lot of memory. Didn't want to make the code more complex in fear of people being scared of running it.

    [–] rtxn@lemmy.world 4 points 1 day ago* (last edited 1 day ago) (2 children)

    I've been learning Rust by going through The Book... there's some wack-ass syntax in that language. I've mostly used C# and Python so most of it just looks weird... I can more or less understand what while let Some((_, top)) = iter.next() { ... } is doing, but .for_each(|((_, _, t), (_, _, b))| { ... } just looks like an abomination. And I mean the syntax in general, not this code in particular.

    [–] TwilightKiddy@programming.dev 2 points 15 hours ago* (last edited 13 hours ago)
    .for_each(|((_, _, t), (_, _, b))| { ... }
    

    This is actually fairly similar to what C# has.

    This is a closure syntax:

    | arguments | { calls }
    

    In C#, the closest is lambda expressions, declared like this:

    ( arguments ) => { calls }
    

    Parentheses are tuple deconstructors. In C# you have exactly the same thing. Imagine you have a method that returns a two element tuple. If you do this:

    var (one, two) = MethodThatReturnsATuple();
    

    You'll get your tuple broken down automatically and variables one and two declared for you.

    First of all, I'm using .zip() to pair the rows of the picture by two, that returns a tuple, so, I have to deconstruct that. That's what the outer parentheses are for. The pixel enumeration stuff I'm using returns a tuple (u32, u32, &Rgba<u8>) first two values are x and y of the pixel, the third one is a reference to a structure with color data. I deconstruct those and just discard the position of the pixel, you do that with an underscore, same as C#.

    I'm not that far into learning myself, but I'm not a textbook learner at all. Poking around opensource projects and wrestling with the compiler prooved to educate me a lot more.

    [–] __dev@lemmy.world 5 points 1 day ago (1 children)

    but .for_each(|((_, , t), (, _, b))| { ... } just looks like an abomination

    It's not so different in python: for ((_, _, t), (_, _, b)) in zip(top, bottom):

    Or in C#: .ForEach(((_, _, t), (_, _, b)) => Console.Write(...));

    [–] rtxn@lemmy.world 2 points 1 day ago (1 children)

    Is | (...) | { ... } a lambda expression then?

    [–] ignotum@lemmy.world 1 points 22 hours ago

    Yep, lambda or closure (it's an anonymous function but it can also capture state from the enclosing function, i think pure lambdas can't do that?)

    [–] 30p87@feddit.org 4 points 1 day ago

    Or using sixels. For example foot supports them, and you can display one with chafa.

    [–] scrion@lemmy.world 39 points 1 day ago

    The real cringe is using passwords instead of keys to login.

    [–] NateNate60@lemmy.world 35 points 1 day ago

    It would be cringe if you were using a shared server and set this as a default for everyone or if it was interfering with something. But if you're just minding your own business I could not care less what customisations you put on your terminal as long as it isn't using excessive resources

    [–] Igilq@szmer.info 9 points 1 day ago (1 children)

    Never too far, also can you share how you did that?

    [–] Finadil@lemmy.world 11 points 1 day ago* (last edited 1 day ago)

    /etc/update-motd.d/01-random-art don't forget to chmod +x it and put 'art' in /usr/share/motd-art. MOTDs are limited to 80 characters wide, so don't over do it. I made image_to_ansi.py to resize and convert the images.

    [–] db2@lemmy.world 14 points 1 day ago

    I can't hate on ANSI art even if I'm not in to what the art is of. 🀷

    [–] ipkpjersi@lemmy.ml 2 points 22 hours ago

    Okaerinasaimase, goshujinsama

    [–] phantomwise@lemmy.ml 2 points 23 hours ago

    How??? Asking for a friend...

    [–] tuckerm@feddit.online 11 points 1 day ago

    Nah, I don't think so. I mean, sure, arch is a little cringe, but it's not that bad. Cool terminal, btw.

    [–] imouto@lemmy.world 7 points 1 day ago (1 children)

    Needs more pixels. You use Kitty, try something like https://github.com/hpjansson/chafa to render a proper picture?

    [–] Finadil@lemmy.world 7 points 1 day ago

    I considered using kitty's built-in ssh kitten to display real images, but I ended up liking the retro look more.

    [–] Agility0971@lemmy.world 3 points 1 day ago (3 children)

    I thought motd could not be scripted hmmm...

    [–] Finadil@lemmy.world 3 points 1 day ago

    /etc/motd no, but it runs the scripts in /etc/update-motd.d/

    [–] elvith@feddit.org 3 points 1 day ago (1 children)

    Never tried it, and IIRC, motd is just a text file - but does that stop you from running a systemd timer to update it every few minutes? Or, if it's your own server and there's only a single user (logging in), put a script in your profile that changes the motd for the next login?

    [–] 30p87@feddit.org 3 points 1 day ago

    For multiple users: /etc/profile or /etc/bash.bashrc

    Some shells (e.g. fish) allow you to easily customize this.