1. lemoncurry 1.10.0: what's new and what's next?

    lots of stuff is new, since i haven't posted a changelog since 1.9.4! let's focus on the important things i guess?

    • all my html templates are jinja2 now instead of vanilla django - jinja2 is faster and also much more capable, since it supports pretty much arbitrary python expressions rather than a very strict specialised syntax
    • lemoncurry now natively serves avatars through the libravatar protocol, which is basically like an open distributed version of gravatar? sadly, the main libravatar server later announced that it's shutting down in october :( my implementation will still work at least, since it's distributed, but i expect fewer services will actually support libravatar after the main server's gone :( :(
    • micropub support is way better now - i have a micropub media endpoint, which lets you upload images and stuff for your post before you publish it, posts can be deleted over micropub, and additional properties work now too. neato
    • i use messagepack now for caching stuff in redis, since it's faster as well as more space-efficient than the other serialisation formats available
    • amp is no longer supported, because i decided amp sucks. you're welcome?
    • changed the layout of entries so they now have way less vertical overhead. i did this to encourage me to use notes more, since they're meant to be little status updates like toots and making them Big discouraged me from Doing That

    next, i think i might be planning to break backwards compatibility. yep :o

    specifically, i store entries internally using fairly typical relational database modeling: fields for single-valued stuff like name and content, many-to-many associations for stuff like cats and syndications, etc. etc.? and i'm running into a mismatch between that structure and what i need the site to handle

    specifically, while i can easily produce microformats2 html from that structure, micropub works by sending microformats2 items into the site, which means i need to convert back and forth between mf2 and my internal format. this ends up being a big hassle in some cases! what micropub really wants is for microformats2 to be the site's native format, since that eliminates the need for translation

    so basically: i'm planning to change lemoncurry's internal entry format from traditional entity-relationship modeling to native microformats2 json, just like the json i send to its micropub endpoint right now. then i can natively exchange microformats2 items with my site, without the translation mismatch

    that's a gigantic change, and i haven't even decided exactly how i wanna implement it. so i'm planning to make it a major version. that's right, lemoncurry 2.0 is on the roadmap!! :o

    lemoncurry facebook.com twitter.com vulpine.club
  2. got the new design looking pretty nice on my phone now c: woo! i think the next thing to figure out at this point is probably automatic syndication? i’ll look into doing it with mastodon first, and then maybe silos as well. maybe

  3. just added something i’ve been meaning to include!! yay! here it is, since you can’t actually see it unless you’re logged in as me 😉

    a screenshot of an admin panel in my site, which displays micropub tokens and allows me to revoke access

    yay! it can load the clients’ display names and logos as well, although quill is the only client i have in here that has those things

    another screenshot, showing that quill.p3k.io has its nice name and logo displayed. lovely

    so that’s cool!! yay

    lemoncurry micropub
  4. tbh what i really need to do next is get syndication going! with my entries automatically pushed to masto and maaaaaaybe the birdsite, posting here’ll be a way more reasonable choice

    lemoncurry roadmap
  5. yo i just signed into lemoncurry on my phone!! hopefully this will reduce posting friction and get me actually using my own site for stuff lmao

    also it’s been updated a lot since i last posted? lots of general polish, performance tweaks, type checking and such. delicious

    not really many new features honestly, just a lot of cleanup and paying off technical debt

    anyway yeah i’m feeling pretty good about it! yay 💖

  6. a tale of two releases

    hey friends! i haven’t released a lemoncurry update in about a month, but i have been working on it! since last time, i’ve made versions 1.9.3 and 1.9.4 (whoa!! i know, right?) so here’s what happened in both of them :o

    first up, lemoncurry 1.9.3!

    • bootstrap 4 came out of beta, so i switched from the beta to the final release!! woo
    • i set up continuous integration with gitlab ci! what that means is that the unit tests are automatically run every time i push a new commit, and a cute little checkmark is displayed on the commit when i view it on gitlab? unless the tests failed, in which case i get an unpleasant little cross instead? so at a glance i know if a commit Broke The Tests, which is handy info!
    • font awesome put out a few more releases, so now i’m on v5.0.8 instead! neat
    • lots of refactoring: i previously defined separate named routes in django for each kind of post, like entries:notes_index and entries:articles_index, but that makes figuring out whether a particular url points to an entry or something else way more of a hassle, since there are lots of different route names to match? and it turns out you need to know whether a given url on your site points at an entry to receive webmentions (!!!!!!!) for that entry, so i changed all that stuff around :o now there’s just a route called entries:index that takes a parameter for the entry kind, which is much easier to process c:
    • the permalink pages, like /notes/3 and such, weren’t checking whether the entry with id 3 actually existed. which meant it crashed and gave you a 500 server error. now, it checks upfront and returns the correct error if you ask for a nonexistent entry - 404, not found!

    and now, lemoncurry 1.9.4!!

    • i started writing code to receive webmentions!!!!!!!! it’s nowhere near finished yet, and i haven’t made it discoverable so other people’s sites won’t know to use it, but it can receive mentions, figure out which entry was being mentioned, and save that information to the database?? next, i need to use the job queue to test whether the webmention is valid (i.e., whether the source page really mentions the target page) and then if it’s valid to actually display it someplace :o really good start so far tho!
    • i decided to install the lovely highlight.js, for pretty code colours every time i post a code block :3
    • previously, the nya.as short urls were being generated by a third-party plugin called django-shorturls, but that plugin hasn’t been updated since 2016! since it doesn’t really do much anyway, i decided to spend a few hours reimplementing its functionality myself. easy peasy
    • the big advantage of dropping django-shorturls is that it wasn’t compatible with django 2 - since i’m not using it any more, i upgraded django to 2.0.3!! yay!! it seems pretty much the same as before but still!! yay!!

    so that’s what’s up! here’s a pretty little python code block to celebrate :o

    def is_cutie(person):
      Test whether the person provided is an absolute cutie pie.
      if person.is_reading_this:
        return True
      return True # yes, even people not reading this are cuties
    font awesome lemoncurry facebook.com octodon.social twitter.com
  7. yo i just published lemoncurry 1.9.2! there’s nothing new that you can actually see lol

    there are two new things behind the scenes though??

    1. i started writing automated tests?? i’m generally pretty bad at writing tests for my projects so this is kinda notable, i think?? currently the only things covered by my tests are a few utility functions and a couple of the /.well-known views, but it’s a good start and i’m proud ✨

      i’m using the lovely pytest?? the main reason i chose it is that it’s got super-smart assertion introspection: if you write tests using the standard python unittest module, then you have to write ugly things like self.assertEqual(result, 5) into your tests, whereas if you’re using pytest all you need to write is assert result == 5 and you still get the same information when the assertion fails! yay! 🐱

    2. i was hashing passwords with django’s default algorithm, pdkbf2, which is quite good! but it’s not the best password hasher out there, so i’ve now switched to the newer and stronger algorithm argon2 instead! 💖


    lemoncurry testing facebook.com octodon.social twitter.com
  8. whoa, it’s lemoncurry 1.9! yep!

    i bumped the minor version instead of the patch version, ‘cause lots of stuff happened!

    • i added rudimentary support for producing accelerated mobile pages versions of each entry!
      • it doesn’t always produce valid amp html, because i haven’t figured out how to convert the html i get out of my markdown parser into amp html?
      • but for simple entries, mostly entries that don’t have images in them, it works perfectly c:
    • lots of performance improvements
      • i cut down on the number of sql queries that lemoncurry needs to make to achieve various things?
      • most importantly, rendering an entry requires access to its author, its cats, its syndications, and so on. fetching all this took a lot of queries, but it turns out it could just make a few simpler queries up-front instead!
    • i bumped font awesome again!
      • it’s 5.0.6 now: i skipped 5.0.5 because 5.0.6 was actually released on the very same day?
      • i guess they made a mistake in 5.0.5 that needed urgent fixing or something like that :o
    • micropub is better again! specifically, i added support for GET /micropub, which lets micropub clients ask the server for information
      • there’s q=syndicate-to, which tells the client what syndication targets the server supports (currently none)
      • and q=config, which tells the client where the micropub media endpoint is (currently nowhere) and what the syndication targets are (still none)
      • and q=source, which tells the client the normalised microformats2 json for a particular entry! clients use this to retrieve entries in an editable format, as part of updating an existing entry. this part works perfectly so far, but because updating isn’t implemented it’s not too useful yet 😉
    • additionally, micropub
      • does scope checking now! your token must contain the ‘create’ scope if you want to create a new entry! there aren’t any other operations you can perform yet that require a scope, but you’ll need the ‘update’ scope when i implement updating existing entries
      • returns better error responses, when you do things like pass a token that’s missing the scope you need? it turns out the micropub spec actually describes the format the errors should be in, which i wasn’t following, oops :3 now i am!
    • i turned off google analytics!
      • i don’t care about getting that kind of information
      • i didn’t like subjecting visitors to google’s tracking
    • this isn’t actually part of the app itself, just the way i’ve set up my deployment, but: i realised i had gunicorn running just one lemoncurry worker, which meant i could only handle exactly one request at a time??
      • this causes problems if for example your micropub source query works simply by directly requesting the page you asked for, and then parsing it with mf2py! (yes, that’s what lemoncurry’s implementation does 😉 )
      • it also causes problems if you expect any decent amount of traffic to your site, since you can only handle one http request from anyone at a time?
      • so i fixed that, gunicorn has a couple of workers now c:

    you may be wondering why the version is already 1.9.1? the reason is that 1.9.0, while containing all of the above exciting features, was unfortunately broken! while optimising the system’s performance, i accidentally broke the django authentication :o i didn’t notice because i was focused on micropub, which always uses its own tokens rather than the usual session-based authentication? anyway 1.9.1 fixed that

    oh, by the way, it won’t roll over to 2.0 with the next minor release? unless i do something massive next, you can expect 1.10 to be the next minor version!

    lemoncurry micropub to quote william shakespeare: words words words facebook.com octodon.social twitter.com
  9. yoooo i forgot to work on lemoncurry! again! oops?? here’s 1.8.4

    the reason i forgot to work on the site this time is that i bought a new 3ds xl, which arrived the day after i last updated lemoncurry 😳 the last nintendo handheld i bought was a ds lite, so i’ve missed a lot of gaming in the meantime and i have a lot to catch up on :o

    i got a special samus edition 3ds, which i guess was released to commemorate the new metroid game released for the platform? it’s really cool, here’s what it looks like

    new 3ds xl - samus edition

    the best part is that it came with a download code for the aforementioned new metroid game, samus returns, which is fantastic???

    • it’s a remake of metroid ii: return of samus for the game boy, which apparently was poorly received since it was a lot more linear than the first metroid??
    • samus returns, however, is quite possibly the best side-scrolling metroid game. yes, it’s that good
    • to progress through the game’s areas you have to find and slay a certain number of metroids in each, thereby unlocking the path to the next area, which is what made metroid ii so linear
    • that hasn’t changed, but now each area is absolutely colossal and takes literal hours to explore? you head off down a side path thinking “i’ll just check here quickly before going back to the main path”, and then, you don’t return to that spot for like an hour?? so it’s like you’re playing eight non-linear exploration-focused metroid games in a row??? i love it 💖
    • it’s also using utterly gorgeous 3d graphics, despite being a sidescroller, since the 3ds is so very good at 3d graphics. the environments look amazing, samus looks really really cool especially after finding the suit upgrades, everything looks super great.
    • this is the first side-scrolling metroid for a dual-screen console, which means it can finally use those two screens in the best possible way: the map - not a minimap, a full-size map - is constantly visible on the touch screen, which makes exploring a delightful breeze. it’s the perfect arrangement for classic metroid gameplay, and it makes me wonder why the ds never got a classic metroid?? silly nintendo
    • samus can aim and fire in any direction with the circle pad, rather than only eight directions like every previous side-scrolling metroid - this makes for some really engaging combat, especially while fighting the metroids (which are like, minibosses, i guess?) since they’re flying all over the place and you gotta hit their weak point for massive damage
    • she’s also got a new attack, called the “melee counter” - when an enemy charges at her, tapping the x button with good timing will stun the enemy, dramatically weaken them, and automatically aim her gun at them. it doesn’t do a lot of damage, but it means you can wipe out enemies with just a few blasts once they’re stunned! many, many enemies charge at you, including the metroids, so you get to use the melee counter a lot. it makes combat faster and way more interesting than in previous metroids, it’s brilliant 💕
    • i love this game please play it ✨

    oh yeah, the lemoncurry update!! like last time, i made two little changes

    1. i enabled cross-origin request sharing for all pages! basically, cors support means that javascript, running in anyone’s browser, will be able to fetch pages directly from my site and inspect the contents? which is cool for things like js-based indieweb readers :3
    2. font awesome 5.0.4 was out, so i bumped my version again! yay! i also found a changelog, which i can’t link since it’s inside the private fa pro repository :o it looks like they fixed a lot of spacing issues with the previous versions? neato burrito 🌯
    gaming lemoncurry metroid samus is a trans lesbian icon facebook.com octodon.social twitter.com
  10. two little upgrades in 1.8.2!

    1. i put the aria-hidden="true" attribute on any icon elements that aren’t necessarily font awesome - fa automatically inserts that attribute for you, but only for its own icons? what it’s for is accessibility: aria-hidden indicates that an element is just for presentation and can safely be ignored by screen readers c:
    2. font awesome 5.0.2 is out so i upgraded again! there are no changelogs for fa 5.x yet so idk what the differences are but yeah
    font awesome lemoncurry facebook.com octodon.social twitter.com