1. 6

    I’ve been using Hugo as of late due to ox-hugo, which allows me to write blog posts in Emacs’ Org mode. It’s pretty wonderful for tracking WIP posts and what else to write with Org.

    1. 4

      The other day I was digging into someone’s personal wiki’s implementation and found that they’re using ox-hugo to generate the wiki from their org-roam notes 👏

      1. 5

        That’s not just anyone - that’s actually the maintainer of org-roam, so it makes sense that they’d use it on a personal wiki as well. Cool find.

    1. 1

      I’ve always considered IRC bouncers a cludge. For the longest time I ran irssi in screen on a shell. There was lag typing. Then came mosh, which helped. Quassel has a nice model, where you can run the IRC client on a server and the interface locally. But I haven’t tried that. These days I just use matrix and the irc bridges offered by matrix.org (freenode) and SNT (ircnet).

      1. 2

        I’ve been using screen + irssi for years. Works well enough for me.

        When I got a job again I might consider paying up for IRCCloud. It’s quite slick.

        1. 2

          I’ve always considered IRC bouncers a cludge.

          May I ask why? It’s always seemed fairly elegant to me - have a server act as a client to an IRC server and have virtual channels, exporting an IRC connection out the other side.

          Quassel has a nice model, where you can run the IRC client on a server and the interface locally.

          Isn’t this pretty much what a bouncer does? The client runs on a server somewhere and you pick your own IRC client as the interface?

          These days I just use matrix and the irc bridges offered by matrix.org (freenode) and SNT (ircnet).

          Am I misunderstanding something, or isn’t this essentially a bouncer as well? It sits on a server somewhere and you connect to it with your own client. In this case, it’s something like riot rather than an IRC client, but it’s the same concept with an additional protocol to act as the bridge.

          1. 4

            The difference between an IRC bouncer and the other solutions mentioned (here I’m guessing at how Quassel works though) is that there’s tighter integration between the client and server.

            Here’s an example: when you connect to an IRC bouncer, you get playback of the messages you missed. But all of those messages have the wrong timestamp, because from your client’s perspective, they all came in within a minute or two of when you connected to the bouncer. You can set your bouncer to send timestamps to the client (this is what I do), but there’s no way for the bouncer to “correct” the client’s timestamp, so all it can do is add the timestamp as part of the message. So what you get is two timestamps. E.g. let’s say you connect to the bouncer at 12:30:

            12:30 <someuser> [09:45:00] luser: you around?
            12:30 <luser> [09:53:00] someuser: yes let's discuss the foobars
            12:31 <you> I just connected with my bouncer. it's 1 minute after I actually connected because there was such a flood of IRC playback messages that it took a while to settle and this message wouldn't send until it did.
            12:35 <you> cool, I've been connected with my bouncer for about 5 minutes now
            

            IRCv3 is supposed to help fix this, but it’s not here yet. At least not in my out-of-the-box ZNC + ERC combo, although I will admit that I’m sure IRCv3 is not high on ERC’s priority list 🙄

            Contrast this with Matrix where no matter when you connect, your client always gets the right timestamps because what the client is doing is properly synchronizing with the server. The details from the origin IRC server’s message - like timestamps - are preserved and sent down to the Matrix client.

            I’m picking on timestamps here, but there are a few other problems like this too. For example, it’s annoying when your IRC bouncer disconnects but your client thinks you’re still connected just fine, so the UI desynchronizes with reality. Not sure if Matrix fixes that, although it could. I’m just not familiar enough with it to say.

            1. 2

              IRCv3 is supposed to help fix this, but it’s not here yet.

              I can’t remember if they’re on the standard version of the protocol yet, but Hexchat knows how to get the correct timestamps out of ZNC, so it’s there for at least some clients.

              For example, it’s annoying when your IRC bouncer disconnects but your client thinks you’re still connected just fine, so the UI desynchronizes with reality. Not sure if Matrix fixes that, although it could.

              It couldn’t. I could rant for days about this, but I’ll try to keep it specific. Matrix bridging works by creating a room on the Matrix side and trying to keep it in sync with the IRC side; individual bridged IRC users are a protocol-level fiction in some sense. It tries to monitor what’s happening to them and effect the equivalent changes on the other side, but it doesn’t always know how. The failure modes of this are generally worse than the bouncer model because the latter treats IRC connections individually. For example, if ZNC fails to join a channel for a reason it doesn’t understand, it just won’t join the channel; if a Matrix bridged user tries to do the same they’ll think they’re in the channel (and receive messages from it) until they try to speak. Until about a year ago, you could part channels with !cmd and the bridge wouldn’t notice, setting up the same condition. This will still occur if the bridge doesn’t have enough power level in the Matrix room.

              There remain dozens of outstanding issues that could be described as desyncs on the matrix-appservice-irc tracker. Whatever other benefits of the model might exist, I don’t think maintaining synchronization with reality is one of them.

              1. 1

                Exactly. And matrix also allows requesting more history from the home server to the client. And connecting several clients to the same account.

          1. 1

            Closing on our first house! That’s the biggest thing.

            For personal projects, I’ve been working on my personal chat bot framework and have finished up the IRC and Discord backends… Minecraft as a chat backend is getting finished this week (along with the release of 1.16) and then I just need to build a proxy plugin so people in linked channels can see messages from other platforms.

            1. 6

              Working on my painfully over-engineered chat bot and adding support for more platforms. It currently supports IRC, but I’d like to add Discord and Minecraft. I’m halfway done with the Minecraft plugin, but the backend service needs to be expanded to work with multiple chat services (and multiple chat platforms).

              1. 10

                Why waste such a thorough article with a stupid clickbait title? At least someone edit the lobste.rs title to something else?

                1. 4

                  You have the power to suggest title edits. Click the ‘suggest’ link button at the top under the title.

                  1. 4

                    We’re generally against changing the title of a submission away form what it actually is, except to remove authors and such.

                    1. 2

                      Sure, but anyone can suggest anything. I was just informing them that they don’t have to ask someone to change it, they can suggest changes themselves. I wasn’t arguing that the existing title is/isn’t wrong.

                  2. 1

                    I don’t think it’s worth subverting the author (Who’s a lobster user!)’s intent and changing the title of the post, but I agree that it’s definitely not indicative of the quality of the content within.

                    1. 3

                      I made a suggestion with the subtitle of the post “Practical Dependency Injection in Python” because it seems to be much more descriptive of the containing content and doesn’t subvert the author, as that’s really a secondary title. Still, it can be approved or denied.

                  1. 8

                    Like every other problem in Python, there are libraries that provide a solution. Two libraries that stand out are freezegun and libfaketime. Both provide the ability to mock time at different levels. However, resorting to external libraries is a luxury only developers of legacy system can afford. For new projects, or projects that are small enough to change, there are other alternatives that can keep the project free of these dependencies.

                    The article only touches on libraries like freezegun, using a rather dismissive argument that “only developers of legacy systems can afford” them, but I tend to disagree - libraries like these are designed as conveniences rather than crutches. One example I have is testing token validation (in our case JWTs) - you can test the same token right before it’s supposed to be valid, during the valid period and after, without having to dig into the internals of the PyJWT library. With freezegun, this was trivial. When you don’t control the code actually calling datetime.now(), this method of mocking out dates is quite a bit easier to control.

                    Note that there are plenty of good examples here… in particular some of the stuff around designing Protocols is super useful, but similar to the clickbait-style title, the datetime portion seems to brush past a valid answer because it doesn’t fit the narrative of the post.

                    1. 2

                      I agree that if you use an external library with an API like the one you are describing, may force you to use libraries such as libfaketime. Not because it’s the best, or the right way, but because you have to.

                      Point of the article is that the library API can possibly be changed so that you won’t have to use libfaketime. Instead, the library can provide you with a simpler way of testing the token. For example, provide an argument that sets the time the token is validated at, like the article suggests.

                    1. 2

                      There was a very interesting design decision in the Bitbucket.org codebase back when I worked there - they pushed for function-based-views rather than class-based-views in Django. The reasoning was that writing a decorator called with_repo which attaches the repository to the request is much simpler than writing a class mixin to set self.repository. With functional views, it’s clear what order “mixin” decorators are called in - top to bottom, but with class-based views you might need to understand the resolution order of the mixins, which gets to be a nightmare.

                      This is not to say either method is better or worse, but there are times that things get overcomplicated simply to maintain “purity”, to the point that they can be an antipattern.

                      1. 3

                        I have a self-hosted instance of Miniflux which I use with Reeder on iOS and macOS. I just recently switched back to Linux for my personal dev machine, so I haven’t found anything for that yet.

                        1. 3

                          Nice post, there’s some great stuff here!

                          I’ve got a few random things that might be interesting that I’ve learned in my time maintaining prezto and zsh-utils.

                          Exists could also be written with the plus operator, the commands array, and the arithmetic parens. This should be slightly faster as it doesn’t have to match the given arg against a pattern - it just uses the associative array that’s already there. Note that there are also arrays for $functions and I thought there was one that was a combined array of functions, commands, and aliases but I can’t seem to find it.

                          _exists() { (( $+commands[$1] )) }
                          

                          This is a modification to _postpath which uses a zsh builtin to handle the readlink portion which allows it to work on more platforms (it’s especially nice because it should work with both macOS, BSD, and Linux). It could obviously be used for _prepath as well.

                          http://zsh.sourceforge.net/Doc/Release/Expansion.html#Modifiers

                          _postpath() {
                              for dir in "$@"; do
                                  dir=${dir:A}
                                  [[ ! -d "$dir" ]] && return
                                  path=($path[@] "$dir")
                              done
                          }
                          

                          One really good example of where ZLE can be useful is prepending sudo on a keybind. https://github.com/sorin-ionescu/prezto/blob/master/modules/editor/init.zsh#L232

                          I assume you could do this with zle -U, but the nice thing about this is that it doesn’t move the cursor.

                          prepend-sudo() {
                            if [[ "$BUFFER" != su(do|)\ * ]]; then
                              BUFFER="sudo $BUFFER"
                              (( CURSOR += 5 ))
                            fi
                          }
                          zle -N prepend-sudo
                          
                          1. 3

                            Ah, thanks; I’ll update the _exists and _{pre,post}path functions.

                            To be honest I never really looked much at zle, and always found it a bit confusing. I need to sit down and properly look at it one day. There’s some other useful stuff in that zshrc as well btw (like using terminfo instead of bindkey '^[OA').

                            1. 2

                              Yeah there’s a ton in zle. It’s super powerful but there are also a lot of pitfalls. If you’re looking for something simpler than presto or oh-my-zsh take a look at zsh-utils or zsh4humans. They’re both really solid places to start.

                              1. 1

                                I love zsh and all but confused why you made the _exists function? Is command -v not enough? Thats also portable to any bourne shell as well.

                                1. 1

                                  It’s just so much work to type!

                                  command -v vim >/dev/null || alias vi=vim
                                  
                              2. 1

                                For sudo, I am using this version:

                                # Meta-S will toggle sudo
                                function vbe-sudo-command-line() {
                                    [[ -z $BUFFER ]] && zle up-history
                                    if [[ $BUFFER == sudo\ * ]]; then
                                        LBUFFER="${LBUFFER#sudo }"
                                    else
                                        LBUFFER="sudo $LBUFFER"
                                    fi
                                }
                                zle -N vbe-sudo-command-line
                                bindkey "\es" vbe-sudo-command-line
                                

                                For _postpath, it could be further simplified to (relying on Zsh not doing word-splitting by default and arrays are not nested:

                                _postpath() {
                                    for dir in "$@"; do
                                        dir=${dir:A}
                                        [[ ! -d $dir ]] && return
                                        path=($path $dir)
                                    done
                                }
                                

                                I don’t rely on typeset -U myself as it can be fooled with symlinks (and I want to keep symlinks in path, notably for the path to Nix profile). So, I do the dupe checks manually: https://github.com/vincentbernat/zshrc/blob/master/zshenv#L28

                              1. 3

                                After trying logfmt at my current job, we actually ended up giving up and moving back to json logging. Writing logfmt logs is supported fairly well, but parsing it is not. When we tried a year ago SumoLogic doesn’t have a good way of parsing logs formatted like this and it’s particularly challenging to approximate something using a regex because fields can be quoted or not (and quotes can be escaped).

                                On the other hand, json works out of the box and is fairly standard. We lose some of the human readability, but as we’re using python it’s fairly trivial to simply use a different log formatter.

                                1. 1

                                  That’s a bit sad, it seems to me it’d be quite easy to write a parser for this format by hand. Not with a single regex, but really, the delimiters are =, , and ", right? Tokenizing and unquoting strings doesn’t seem infeasible. Of course if all you have is a custom regex in a tool, yes, that’s a pity.

                                  1. 2

                                    It definitely would be fairly easy to write a parser by hand. Unfortunately (and with good reason) you can’t do this with most hosted logging platforms. So we went with the least common denominator so it should work everywhere. I generally prefer interoperability anyway.

                                1. 12

                                  I’ve ranted against JWT before, and that rant includes a few links and citations.

                                  Here’s a three-year-old discussion on this site against JWT.

                                  Here’s another anti-JWT article that goes into some detail.

                                  Here are a couple of articles explaining why JWTs as a “replacement” for session cookies are a bad idea.

                                  1. 2

                                    I would second the comment at the bottom of the email thread, would love your rant as a blog post.

                                    1. 1

                                      How do you feel about solutions like Cognito?

                                      1. 1

                                        Mixed feelings. On the one hand, I generally push people to use someone else’s battle-tested auth system rather than rolling their own. On the other hand, I dislike ones that use JWTs since they inevitably mean using a JWT-parsing library with all the attendant risks.

                                      2. 1

                                        I mostly agree with this - I think for 99% of people, using JWTs is dangerous because it’s easy to miss one small thing and mess up the security of the implementation. And most people do it because it’s easy - when you’re writing a flask service nobody wants to handle setting up sessions because that involves a whole bunch of other components that aren’t built-in.

                                        I’ve seen one implementation do it well: short-lived JWT access tokens, long lived session refresh tokens.

                                        The access tokens are signed by an auth server and can be verified by microservices while the long lived refresh tokens are just session tokens - you can get an updated JWT by talking to the auth server again. This has the advantage that auth is centralized but any microservices only need to see the short lived token to verify the user’s identity. There are limitations (you can’t immediately expire all auth tokens - you can only expire the refresh tokens, so you may have living sessions until the latest auth token expires) but when done correctly it can be a useful technology.

                                        1. 3

                                          I’ll refer you back to my “rant” – this scheme is literally just one of (signed cookies | bearer tokens) but with extra work and less safety. JWT isn’t offering anything you wouldn’t get from one of those other options, except for the “feature” of people sometimes being able to literally Jedi-mind-trick their way into your services by waving their hand and saying “You don’t require me to have a valid signature” and your servers agreeing.

                                          Or for a more comprehensive reply, read any of the “don’t use JWT for session tokens” articles. They tend to cover this scheme and debunk its usefulness.

                                          1. 2

                                            I think for 99% of people, using JWTs is dangerous because it’s easy to miss one small thing and mess up the security of the implementation.

                                            I think it’s also worth contrasting between consuming JWTs and creating them. Lots of identity providers create them and those JWTs should be pretty bullet proof (no none algos, supporting good encryption protocols). It’s their job, after all.

                                            Rolling your own JWT seems far more problematic to me.

                                            There are limitations (you can’t immediately expire all auth tokens - you can only expire the refresh tokens, so you may have living sessions until the latest auth token expires) but when done correctly it can be a useful technology.

                                            This post (full disclosure, written the CEO of my company) talks about JWT revocation options. May be of interest to you: https://fusionauth.io/learn/expert-advice/tokens/revoking-jwts

                                        1. 1

                                          I don’t post much, but I’ve got a ton of ideas. Right now it’s just an intro to a package I wrote and a rambling about Go and Rust.

                                          https://coded.io

                                          Future ideas:

                                          • Intro to the SSH protocol (And implementing an SSH server in go)
                                          • Vim vs Emacs (and why I use both)
                                          • My personal Django Project Template
                                          • My personal Docker Setup
                                          • “Too Many Buttons” Rant (think about how painfully configurable JIRA/Confluence are)

                                          If anyone is interested in any of these, feel free to reach out and I may be able to prioritize them.

                                          1. 1

                                            In terms of editor, it depends on what I’m doing

                                            • Emacs (using doom-emacs with some of my own tweaks) for most usage
                                            • VSCode when I just need completion for a language to work perfectly - I’d love to phase this out once my emacs setup gets a little better
                                            • vim when I’m on a server - it’s just ubiquitous

                                            Other tools:

                                            • zsh with zsh-utils to keep a fairly minimal setup.
                                            • tmux
                                            • ripgrep for searching
                                            • iTerm2, though I’ve been playing with alacritty

                                            Essential tools between editors:

                                            • editorconfig - pretty much every editor has a plugin for this - it’s nice to set indentation up once and forget about it
                                            • git - in emacs, this is through magit, otherwise just through the command line. After working at Bitbucket for a few years, you tend to get used to the oddities in the command line interface.

                                            I really like emacs and wish I could just use that for everything, but I’ve had some issues with plugin stability, especially around lsp/completion support.

                                            If anyone’s interested, I maintain a number of themes for emacs:

                                            I also maintain zsh-utils, and use that in place of prezto (which I also work on a bit).

                                            1. 1

                                              VSCode when I just need completion for a language to work perfectly - I’d love to phase this out once my emacs setup gets a little better

                                              What environments are you struggling with? Or are you talking about completion frameworks?

                                              1. 2

                                                In particular, I’ve had some issues with rust (either rls or the connection keeps crashing - I haven’t had the time to debug it yet) and JS/TS just isn’t on par with VSCode. I haven’t tried python recently, but at least in my personal config I’ve had it stable-ish for a while, so I’m not as worried about that one.

                                              2. 1

                                                Does vscode gets slower. I think vscode is basically like modern day emacs

                                                1. 1

                                                  I think vscode is basically like modern day emacs?

                                                  Why? They seems like two projects with different goals to me.

                                              1. 14

                                                So looking at their pricing page, it looks like a number of features will only be available on public repos, and you still need to get a plan to get those features on your private repos (draft PRs, code owners, protected branches; scroll down a bit on that page for a table).

                                                Also looks like GitHub actions and the package storage is a big part of their pricing strategy now, whereas before (up to a year ago or so) it was mostly about charging for private repos.

                                                1. 2

                                                  It’s interesting to me that GitHub seems to be aligning with Bitbucket on this one (https://bitbucket.org/product/pricing) rather than Bitbucket playing catch up.

                                                  I have to admit this makes me less likely to want to work on my personal open source git hosting project because moves like this make users less likely to move over… because a small open source solution will never have the same feature set something like GitHub does.

                                                  1. 20

                                                    I have to admit this makes me less likely to want to work on my personal open source git hosting project

                                                    So I started working on my own analytics project last year, with the plan to make this a sustainable source of income, and every time someone announces a “we’ve built a new analytics product” here or on HN I’m a little bit discouraged. When I started last year, there were very few alternatives; now: many more.

                                                    Then I look at the new products, and many are neat and seem well-built but … they’re also different than what I’m building in various ways (technical, UI, business), so then I’m like “this is okay, no problem!”

                                                    This is also the value stuff like Sourcehut gives us. For me, personally, I think sourcehut is a terrible product, I would not enjoy using it at all because the workflow just doesn’t jibe with me. But clearly it is useful for many people, and it’s certainly offering something different than the GitHub and clones of the world, so I think it’s a cool project just for that, regardless of my personal opinion of it.

                                                    If you’re working on a “GitHub clone”, then yeah, it may not be worth it to continue (which was already the case before, since there are a whole bunch of them already). But if you’re working on something that solves the same problem in a different way: then there’s certainly value in that, and if you do it well enough you should get users/customers regardless of what GitHub is doing.

                                                    That’s just my 2c on that anyway; focus on your own story and don’t be too distracted on other people’s stories.

                                                    1. 5

                                                      So I started working on my own analytics project last year, with the plan to make this a sustainable source of income, and every time someone announces a “we’ve built a new analytics product” here or on HN I’m a little bit discouraged. When I started last year, there were very few alternatives; now: many more.

                                                      Usually you should be happy when this happens. Competition showing up is validation that the area you are investing in or the project you are building actually has a market. Don’t get discouraged, the pie is often big enough to feed everyone at the table and it’s better to eat a pie in company than stare at an empty plate alone.

                                                      1. 2

                                                        Yeah, agreed, and I’m happy there are alternatives people can choose from. Also helps keep me sharp.

                                                      2. 3

                                                        Wow, thanks for the quality response. I’ve been feeling a bit down lately and I think a bit of it just came out in my original post… I wasn’t expecting such a well thought out response.

                                                        At least as far as I can tell, there seems to be a bunch of missing tools that stick to simplicity. Goatcounter does a fantastic job of this in the analytics space. That was one of the original goals of my project as well - a simple way to securely deploy git repos, definitely not a GitHub clone, The original plan was mostly for personal use but after taking a closer look at Goatcounter, maybe I’ll have to see if I can come up with some small enterprise focused features as well.

                                                        In any sense, thanks for the encouragement, I really do appreciate it.

                                                      3. 2

                                                        this makes me less likely to want to work on my personal open source git hosting project

                                                        I get what you are saying, but on the other hand this is the best time to push for such solutions. I think there is room for more of these types of projects.

                                                        1. 1

                                                          I don’t know, Github should catch up to others at this point, imo. Paid private repos was always a negative thing to me and when they sold to Microsoft, a lot of peoples trust in Github was betrayed. Its a good move for them right now and should have been done sooner in my opinion. I do find myself using alternatives for private projects and Github is sort of a portfolio for me. I don’t really see myself migrating all my private repos to GH in the future though.

                                                      1. 1

                                                        I don’t know for sure… I’ve been going a bit stir-crazy lately and I have a ton of project ideas but can’t seem to focus on any of them…

                                                        • An experimental wiki, sort of based on an idea someone showed me with a “script” page type that can dynamically generate page output
                                                        • Updating/bulletproofing gitdir
                                                        • Some form of cross-platform document storage (similar to Keep It)
                                                        • A cbr/cbz reader, hopefully something that works on macOS/iOS and maybe other platforms
                                                        • A replacement for rcm - something even easier to install and use
                                                        • An alternative to prezto/oh-my-zsh and friends (maybe taking zsh-utils and extending it or cleaning it up)
                                                        • Yet another emacs config framework… I’m a huge fan of doom, but I’m interested to see what would happen if I cleaned up my own config and focused on making it a little faster.
                                                        • Play around with/start learning rails - I use Python/Django normally, but Ruby/Rails has always been interesting to me.

                                                        Who knows, maybe I’ll get to one of them, maybe none of them.

                                                        1. 4

                                                          For my personal servers, I use Final Fantasy characters. I figure if I ever need to expand, I can broaden that to video game characters, but FF has quite a few options.

                                                          1. 3

                                                            The question becomes: what OS does sephiroth or kefka run?

                                                            You don’t have to answer. It’s more about the ludotechnical dissonance. :)

                                                            1. 3

                                                              I think right now kefka is an experimental single-node kubernetes machine I was using to try and learn kubernetes.

                                                          1. 4

                                                            If smol doesn’t depend on mio, then how does it do the actual non-blocking I/O? Do we still have to use async-std and/or tokio for that part?

                                                            1. 1

                                                              It wraps the stdlib’s TcpStream and friends with epoll (on Linux) and other platform specific APIs to determine when to wake up waiting tasks.

                                                              1. 1

                                                                Isn’t that what mio does? Was mio’s API just not the right API for what you needed?

                                                                1. 3

                                                                  So, I’m not the creator, but stjepang was nice enough to let me take a look early.

                                                                  It does look like mio uses epoll under the hood (though it’s abstracted a ton), however there’s a lot of code there. As far as I can tell, a major reason for wanting to write this async runtime was to show how simple a full feature-complete runtime can be. The entire implementation of smol (including documentation and newlines, excluding external dependencies) is under 2000 lines. mio itself is over 7500.

                                                                  1. 1

                                                                    Looking forward to trying it out!

                                                            1. 2

                                                              This looks awesome! I’ve got a few toy projects I’m interested in using this in - mostly as a markdown editor.

                                                              1. 11

                                                                This is really frustrating. Are there any good alternative APIs? I was using this for my IRC bot, but it sounds like they’re phasing out support for that eventually, so I’ll have to replace it with something else.

                                                                Weather Underground shut down a while back, Yahoo Weather no longer exists, api.weather.gov is US only (and a massive pain to deal with).

                                                                It looks like Carrot Weather has the options for Foreca, ClimaCell, AccuWeather, Aeris Weather, and MeteoGroup… that app has luckily spent the last year or so adding more data sources… but as far as I can tell, most of those don’t really have a hobby-level tier. There’s also weather.com, weather.gov, NOAA, and WMO. However, some of those are limited to the US.

                                                                Does anyone have experience with any of these and how they are to work with or how their pricing is?

                                                                1. 3

                                                                  Are there any good alternative APIs? I was using this for my IRC bot

                                                                  It’s somewhat gimmicky, but I have curl http://wttr.in/Cambridge?n0 in my .profile. When I log in now, I see (with colours that weren’t copied over):

                                                                  Weather report: Cambridge
                                                                  
                                                                      \  /       Partly cloudy
                                                                    _ /"".-.     6..8 °C        
                                                                      \_(   ).   → 13 km/h      
                                                                      /(___(__)  10 km          
                                                                                 0.1 mm         
                                                                  

                                                                  For an IRC bot, that might be sufficient…

                                                                  1. 2

                                                                    Thanks for the tip with weather.gov! I just swapped a simple call from Darksky to National Weather Service with minimal fuss.

                                                                    1. 2

                                                                      After a while rewriting it, finally switched over my IRC bot from the Go version I’ve been running for almost 7 years to a Rust version I’ve been using to learn the language. There’s still a lot to clean up, but it’s passable.

                                                                      Additionally, I’d like to jump back in and clean up gitdir a bit more if I can find the time after work.

                                                                      1. 1

                                                                        Why switch to Rust?

                                                                        1. 1

                                                                          Whenever I’m trying to learn a new language, I generally try and implement an IRC bot. It involves text parsing, network IO, potentially DB access and API calls. A pretty broad set of technologies. Whenever I find a language I enjoy using more than the previous version I start seriously looking at taking a subset of the features in the previous bot and porting them to the version in the new language.

                                                                          I had a post a few weeks ago that sort of outlines some of the strengths of Rust over Go (and vice versa) at https://coded.io/2020/02/early-impressions-of-rust-from-a-go-programmer/.

                                                                          My main complaint in that article was around async not being as easy to use as Go… which is still true (complete reversals don’t often happen in a month) but a large portion of the bot doesn’t need async. I think after a little more learning and experimenting, it became clearer how async fits in and how to use it effectively which made me enjoy it more.

                                                                          Also, I stopped trying to use external libraries to talk to APIs. I cannot begin to describe how much this helped - removing one library which doesn’t seem to get updates any more and replacing it with a custom solution cleaned up the code a ton and dropped about 100 external dependencies. Because of serde, the hardest part of writing API clients for my use cases has been writing the data types for responses. I’m about half way through planning a blog post around API clients in rust as a result of that work.