• How to Handle Pluralization and Internationalization in Django Templates

    This is written in the docs, but it was a first time for me to handle. Your templates can start to get very verbose when you really start supporting i18n support. 

    For strings directly in your templates you can use the blocktrans plural tag. ( Note this changes a bit with Django 3.2, blocktrans becomes blocktranslate ).

    {% load i18n %}
    {% blocktrans count counter=object_list|length %}
    {{ object_list }}件
    {% plural %}
    {{ object_list }}件
    {% endblocktrans %}

    For master data that has a dedicated DB column, you can use the get_language_code from the i18n package.

    {% get_current_language as LANGUAGE_CODE %}
    {% if LANGUAGE_CODE != "en" %}
        {{ my_model.foo }}
    {% else %}
        {{ my_model.foo_en }}
    {% endif %}
  • Bookmark of koaning.io: My New Home Setup

    Better Patterns for Development Work.
    Despite my undying love for my mid-2014, I've been itching for a new computer for the better part of a year. I really like this idea that Vincent has setup working: a beefy Intel NUC PC running Linux to handle Docker etc.. and uses VSCode to develop on it from his Mac.

    I've heard of people doing this before, but they're usually using a terminal for all of their development on a server in the cloud.

    While I'm reluctant to use VSCode (because I'm still not sure I trust Microsoft yet), it appears a similar can also be done with PyCharm. Maybe this is the solution to my building a PC/getting a PC itch.
  • Why I'm Joining Octopus Energy 🐙

    A bit over 4 years ago I moved back to Japan, without a stable job. I had been contracting for 3 or 4 years in the US, but a difference in time zones (GMT+9 vs GMT - 4) made that difficult to maintain. I had heard about a Python shop called BeProud and they were remote friendly.

    There weren't many remote friendly companies at the time in Japan, let alone companies that specialized in Python consulting. Being full-remote friendly signaled to me that they'd have a progressive company culture where I'd fit.

    It was a fun just over 4 years, my longest tenure to date. My co-workers were great, bosses nice, and the projects (mostly) fun. Work-life balance is taken seriously (I took 6-weeks of (paid) parental leave after my son was born without any issues – something that's still rare in Japan).

    If you can speak Japanese and sling Python, they're a great company filled with great people.

    So why leave?

    Climate change. Like many, for years I've worried about climate change. But I didn't know where to begin, beyond voting for people that take it seriously and reduce flights/driving where possible. But the challenge is bigger than any individual.

    The most important change society is going to need to make is is getting our emissions to net zero. As fast as we can. And the biggest leaver is changing how we power (⚡️) our society. Japan currently gets 69% of its electricity from fossil fuels. Any way I can help lower this number, beyond just changing my personal electricity, is something worth spending my time and effort doing.

    Per capita electricity from fossil fuels, nuclear, and renewables, 2020

    Like many, while I am worried about climate change and want to help, each time I looked for how I could get involved in non-superficial ways it either required engineering or chemistry expertise that I don't have or in the wrong location or some other  factor that didn't line up. Until now.

    Octopus Energy, one of Europe's largest investors in renewable energy, is a working to make a "green dent in the universe".  They do this in a number of ways:

    1. As an electricity provider, they offer dynamic tariffs that move with the wholesale price of electricity. Using data science and machine learning, they then help their customers take advantage of renewables by increasing electricity usage when there's an abundance of energy on the grid (which is usually when there's a lot of renewables producing  electricity) and reduce usage when there's less abundance (and usually dirtier, fossil fuels).
    2. They're generating their own green electricity that they put on the grid.
    3. They sell and service electric vehicles
    4. They're making green-Hydrogen as a service.

    The system that powers all of this is called Kraken and they're bringing it to the US, Australia, and Japan (in partnership with Tokyo Gas), allowing customers to take advantage of cheap green energy and reduce demand when it's mostly fossil fuels. 

    Starting in October, I'll  be working on the integrations that allow  Kraken to be used in Japan and helping de-carbonize Japan's electricity supply. Hopefully over the coming years this 69% will decrease.With any luck, my work will directly contribute to driving that number to 0% as quick as possible.

    While I'm sad to leave BeProud and co-workers I enjoyed working for and with, the opportunity to use my skills to fight climate change in a meaningful way is not one that I could pass up. To my new co-workers, I look forward to working together to make our green dent.
  • The Framework laptop, a laptop designed to be upgraded and repaired has shipped. I really want one as I love the idea of being able to fix my computer again. The two things that give me pause are the hot/loud mess that is Intel (compared to the M1) and jumping to desktop linux (which doesn't have the experience I'm used to on my Mac). 🤔
  • Bookmark of Free is a Lie (2014)

    Privacy is between me and myself. Privacy does not mean between me and Google. Privacy does not mean between me and Facebook...Violating privacy violates the United Nations of Human Rights.
    I don't have a specific quote, but I quite enjoyed this talk from Aral (of Small Tech). The premise of the talk is something that most people are familiar with, free (ala Google/Twitter/FB) silos aren't free, but you pay with your privacy. ( This blog respects your privacy and doesn't track you).

    But what really made me think was the chart quadrant chart comparing Open Systems and Closed Systems on Features and Experience. In the upper left Closed / Features you have the leader: Microsoft. Next to that is Closed / Experience, where Apple and Google lead.

    What's in the bottom half where open systems preside? Open source can compete with features, but they often can't compete on experience. Most people care about experience more than they care about features. An entire quadrant of the chart has no competition from open systems!

    And since there's no competition in from open systems on the experience front, the system is going to arch closed. In order to have an open future, open systems must compete not only on features, but also on experience as well. 

    Competing on experience is increasingly difficult as more systems have some kind of hosted server component. I think about this in regards to Tanzawa on a regular basis, but I haven't figured out a model that I think would work.
  • Response to Why self hosting is important

    Self hosting is about freedom, you can choose what server you want to run, which version, which features and which configuration you want. If you self host at home, You can also pick the hardware to match your needs (more Ram ? More Disk? RAID?).
    Excellent post about the importance of self-hosting. It also rightfully points out that buying new hardware isn't necessarily ecological to save 20 wants. ( As we learned in Frugal Computing the lifespan of a server needs to be  10 - 20 years to offset the energy used to manufacture the computer). 

    More people should self-host. I'm self-hosting where it makes sense (my blog) and paying for hosting where it doesn't (Fastmail).

    I have a strong opinion on the subject, hosting your own services is a fantastic way to learn new skills or perfect them, but it's also important for freedom.

    Amen. (Which reminds me, I was planning on moving my server to a BSD. I should really get around to doing that).
  • Bookmark of Django & Celery in production

    DjangoCon JP 2021 発表資料

    Some good tips about Celery Production tips from Django Congress 2021 in Nagano this year (I couldn't attend). Most of the information is in the docs in English, but it's handy to see it condensed, even if it's in Japanese. A couple key points:

    • Use **kwargs for your tasks input. This makes it easier to make updates to your tasks once they're already running in production if your input needs to change. 
    • Reminders about all of the handy kwargs you can pass to tasks in regards to retry. Especially handy autoretry_for where you can pass a tuple of exceptions that will cause the task to automatically retry
  • Gathering Requirements for Native Crossposting in Tanzawa

    Ru made a feature request for Tanzawa to be able to syndicate / cross post from Tanzawa to other sites natively. I think it's a great idea and spent some time to collect my thoughts about what that could look like.

    My thoughts were posted on GitHub, but I'm copying them here so I always have a copy and in case people who read my blog but don't follow  the Tanzawa GitHub have any input.


    Agreed – being able to syndicate content directly from Tanzawa would be ideal. All syndication is currently manual (it doesn't hurt enough to automate it, yet).

    Base Thoughts 

    If we can figure out what the workflow would look like, I think we can define some base requirements for the feature. A couple of general thoughts about syndication:

    • I don't think posting should be syndicated automatically on publish. There's a couple of reasons for this: 
      • Tanzawa doesn't support any kind of background tasks. Posts that have a bunch of links take a while to complete it tries to send webmentions. Adding more external requests could increase the response time to longer than the request timeout allows quite easily. This is especially true because webmentions require 2 requests per save (before content update and after content update). We could probably process webmentions concurrently to speed this up, but that feels like a bit much at this point? It may be easy with asyncio, but I'd need to research it.
      • When I was posting with Wordpress there was a syndication checkbox (via brid.gy) and found it you'd get errors if you saved twice as the post had already been syndicated. Because there also wasn't a preview, it was always a bit of a gamble for how it would post.
    • Syndication is a separate concern from authoring posts themselves. And as such warrants dedicated screens to make it _right_.  Initially I had thought it might work well to handle syndication via a modal on the edit post page, but the more I think about it, it would box us in.
    • Brid.gy is still super handy for backfeeding likes/replies as webmentions. I still think brid.gy is useful / "required" unless we were to build in some kind of polling mechanism, which is difficult without support for cron/background tasks. ( It could be done "easily" with a django management command, I'm hesitant to introduce undue complexity).
    • "Syndication" feels a bit jargony to me. Is "Cross post" (or something similar)  a better term to use in the interface?
    • Each syndication destination is going to require some kind of settings (API keys, mostly). These can / should be managed via the Django admin?


    Create of  Syndication/Cross Posts

    This is assuming that all syndication can be handled with the same form.

    • Creating a new syndication would happen from the edit post button. The button should be on the meta menu (on the right), below the publish  buttons and only display once the post is published (you can't syndicate a draft).
    • Clicking this button would take you to dedicated syndication page.
    • The top of the page would be a form. The form would display the syndication text and up to 4 photos (with the caption).

      The syndication text is free text and pre-filled with either the post title + link or the first 280 chars of the note. Above the text field itself would be a segmented control (tabs? radio button?) that when clicked would let you toggle between the different presets.

      You may not want to syndicate each photo, so perhaps a checkbox is warranted to let you select which photos will be sent.
    • Finally at the bottom there's some checkboxes for which networks to syndicate to. As you can only syndicate a post once per network, posts that have already been syndicated to would be disabled with text explaining that you've already syndicated to that network for this post.
    • Once syndicated they'd store the url of the syndication and create a TSyndication record.

    Syndication List

    I think we'd want a separate section for syndication, like we do with "Posts / Files" on the left for syndications / cross posts. 

    Clicking that would show you a list of your most recent syndication activity ( syndication destination (link to twitter etc..), syndicated text, link to the related post). 

    Selecting a crosspost would show you a (readonly?) version of the syndication Create form.


    Does that sound about right? Anything you'd change or we should consider (especially regards to Mastodon,  I don't have an account/haven't used it before).
  • TIL: English and GEOS Reference Points Opposite of Each Other

    This post is less a TIL and more of a I knew that and I don't want to forget it again and stems from a bugfix in Tanzawa.

    In English when we refer to a geo-coordinate we usually say it in latitude, longitude order. The reason why we say coordinates in this order is we could measure latitude accurately (via astronomical measurements) before longitude. Frontend mapping libraries like leaflet.js keep this familiar ordering. i.e. plotting points on a map takes a latitude/longitude array and events have a latlng property for referencing points.

    GEOS, the open source geometry library used in most GIS (include GeoDjango) applications doesn't think of points in those terms, but as a graph of x,y coordinates.  As such if you when you're working with data across these boundaries it's important to not mix up your ordering.

    When instantiating a Point it's tempting to just pass in floats directly. But if you do that it's easy to mix up the ordering , so I've started make sure I always use the keyword argument name to reduce mistakes.

    from django.contrib.gis.geos import Point
    # Keep our familiar lat/lon ordering without messing up the data point.
    point = Point(y=35.31593281000502, x=139.4700015160363)
  • How to Pipe Python stdout with xargs

    When writing instructions for getting started with Tanzawa, users needed a way to set a unique SECRET_KEY in their environment variable configuration file. Initially I had a secret key entry in the sample file with some instructions to "just modify it". But that felt like I was just passing the buck.

    What I wanted to do was to generate a unique secret_key and output it to the .env file. Outputting just the secret key is simple, you can just use >> and append output to an existing file. But I wanted to use my Python secret key output as an argument to another command.

    I did it as follows:

    python3 -c "import secrets; print(secrets.token_urlsafe())" | xargs -I{} -n1 echo SECRET_KEY={} >> .env

    1. Use the Python secrets module to generate a secure token.
    2. Pipe the output to xargs.
    3. -I is "replace string" and "{}" is the string we want xargs to replace. -n1 limits us to a single argument.
    4. xargs executes and takes our Python output as an argument and replaces the {} with it, giving us our desired string.

    Writing this now, I probably could have just used Python to include the SECRET_KEY= bit and forgone using xargs, but it was good practice anyways.
Previous 2 of 9 Next