{"version": "https://jsonfeed.org/version/1.1", "title": "zerosleeps", "home_page_url": "https://zerosleeps.com/", "feed_url": "https://zerosleeps.com/feed.json", "description": "The 10 most recent blog posts on zerosleeps.com", "favicon": "https://zerosleeps.com/static/core/apple-touch-icon.703a48268c28.png", "authors": [{"name": "Scott Macpherson"}], "language": "en-AU", "items": [{"id": "/blog/2026/4/8/email/", "url": "https://zerosleeps.com/blog/2026/4/8/email/", "title": "Email?", "content_html": "<p>When did everyone decide to stop calling email addresses email addresses? I feel like everything I look at and everyone I talk to at the moment has started referring to the address as just &ldquo;email&rdquo;. &ldquo;What&rsquo;s your email?&rdquo; &ldquo;Enter your email.&rdquo;</p>\n<p>No. An email is an email, and you send an email to an email <strong>address</strong>. If we start calling the address an email, then we don&rsquo;t have any words left to refer to an <strong>actual</strong> email.</p>", "date_published": "2026-04-08T09:14:18Z"}, {"id": "/blog/2026/4/6/time-zone-abbreviations-suck/", "url": "https://zerosleeps.com/blog/2026/4/6/time-zone-abbreviations-suck/", "title": "Time zone abbreviations suck", "content_html": "<p>Yesterday morning a huge chunk of the east coast of Australia changed from AEDT (Australian Eastern Daylight Time) to AEST (Australian Eastern Standard Time) thanks to DST (Daylight Saving Time) ending.</p>\n<p>We went from <code>%DT</code> when <code>%ST</code> <em>was</em> in effect, to <code>%ST</code> where <code>%ST</code> is <em>not</em> in effect.</p>\n<p>These names and acronyms are crap. The whole concept of daylight saving time is crap. We, like every other household in the country, have a few things with clocks that need to be manually changed. It takes me 5 minutes.</p>\n<p>5 minutes \u00d7 twice a year \u00d7 10 million Australian households = 100,000,000 minutes = 69,444 human days. <strong>Every year</strong>.</p>\n<p>What <em>exactly</em> does it save?</p>", "date_published": "2026-04-06T05:00:29Z"}, {"id": "/blog/2026/4/5/log-database-queries-in-django/", "url": "https://zerosleeps.com/blog/2026/4/5/log-database-queries-in-django/", "title": "Log database queries in Django", "content_html": "<p>While <a href=\"/blog/2026/4/4/log-http-5xx-responses-in-django/\">I&rsquo;m on the topic</a> of logging in Django, it makes me sad and a little bit grumpy that when you take Django out of the box, it doesn&rsquo;t default to showing you what it&rsquo;s doing with your database.</p>\n<p>Here&rsquo;s a <code>LOGGING</code> configuration that takes care of that, and sends everything from <code>django.db.backends</code> to a file in the project&rsquo;s root directory during development:</p>\n<div class=\"codehilite\"><pre><span></span><code><span class=\"n\">LOGGING</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"s2\">&quot;version&quot;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">,</span>\n    <span class=\"s2\">&quot;disable_existing_loggers&quot;</span><span class=\"p\">:</span> <span class=\"kc\">False</span><span class=\"p\">,</span>\n    <span class=\"s2\">&quot;handlers&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s2\">&quot;db_backends_file&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n            <span class=\"s2\">&quot;class&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;logging.FileHandler&quot;</span><span class=\"p\">,</span>\n            <span class=\"s2\">&quot;filename&quot;</span><span class=\"p\">:</span> <span class=\"n\">BASE_DIR</span> <span class=\"o\">/</span> <span class=\"s2\">&quot;db_backends.log&quot;</span>\n        <span class=\"p\">}</span>\n    <span class=\"p\">},</span>\n    <span class=\"s2\">&quot;loggers&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s2\">&quot;django.db.backends&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n            <span class=\"s2\">&quot;level&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;DEBUG&quot;</span><span class=\"p\">,</span>\n            <span class=\"s2\">&quot;handlers&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"s2\">&quot;db_backends_file&quot;</span><span class=\"p\">]</span>\n        <span class=\"p\">}</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div>\n\n<p>It&rsquo;s important to note that <code>django.db.backends</code> <a href=\"https://docs.djangoproject.com/en/6.0/ref/logging/#django-db-backends\">only generates output</a> when the <code>DEBUG</code> setting is True.</p>", "date_published": "2026-04-05T06:08:56Z"}, {"id": "/blog/2026/4/4/log-http-5xx-responses-in-django/", "url": "https://zerosleeps.com/blog/2026/4/4/log-http-5xx-responses-in-django/", "title": "Log HTTP 5xx responses in Django", "content_html": "<p>By default, in a production environment where setting <code>DEBUG</code> is false, <a href=\"https://docs.djangoproject.com/en/6.0/ref/logging/#default-logging-conditions\">Django sends log messages</a> with ERROR or CRITICAL levels to <code>AdminEmailHandler</code>. This includes HTTP 5xx responses, which are handled by the <code>django.request</code> logger.</p>\n<p>If you don&rsquo;t have outbound email configured you lose these errors.</p>\n<p><a href=\"https://docs.python.org/3/library/logging.handlers.html#logging.StreamHandler\">Python&rsquo;s <code>logging.StreamHandler</code></a> defaults to sending output to stderr, and most of the time my Django applications are managed by systemd service units <a href=\"https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#StandardOutput=\">which default to</a> passing stdout and stderr to systemd&rsquo;s journal.</p>\n<p>Put all of that knowledge together and here&rsquo;s the delightfully simple <code>LOGGING</code> configuration I usually add to my production settings:</p>\n<div class=\"codehilite\"><pre><span></span><code><span class=\"n\">LOGGING</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"s2\">&quot;version&quot;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">,</span>\n    <span class=\"s2\">&quot;disable_existing_loggers&quot;</span><span class=\"p\">:</span> <span class=\"kc\">False</span><span class=\"p\">,</span>\n    <span class=\"s2\">&quot;handlers&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s2\">&quot;stderr&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n            <span class=\"s2\">&quot;class&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;logging.StreamHandler&quot;</span>\n        <span class=\"p\">}</span>\n    <span class=\"p\">},</span>\n    <span class=\"s2\">&quot;loggers&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s2\">&quot;django.request&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n            <span class=\"s2\">&quot;level&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;ERROR&quot;</span><span class=\"p\">,</span>\n            <span class=\"s2\">&quot;handlers&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"s2\">&quot;stderr&quot;</span><span class=\"p\">]</span>\n        <span class=\"p\">}</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div>\n\n<p>I can then fumble about with <a href=\"https://www.freedesktop.org/software/systemd/man/latest/journalctl.html\">journald</a> as required.</p>", "date_published": "2026-04-04T10:55:00Z"}, {"id": "/blog/2026/4/3/marco-arments-letter-to-john-ternus/", "url": "https://zerosleeps.com/blog/2026/4/3/marco-arments-letter-to-john-ternus/", "title": "Marco Arment's letter to John Ternus", "content_html": "<p>From <a href=\"https://marco.org/2026/04/01/letter-to-john-ternus\">Marco Arment&rsquo;s letter to John Ternus</a>:</p>\n<blockquote>\n<p>We are customers and owners \u2014 not resources to be harvested, annoyed, or badgered into ever more services and upsells.</p>\n</blockquote>\n<p>And:</p>\n<blockquote>\n<p>Making great computers must remain Apple\u2019s top responsibility, because if you don\u2019t do it, nobody will.</p>\n</blockquote>", "date_published": "2026-04-02T21:32:21Z"}, {"id": "/blog/2026/3/26/dogfooding/", "url": "https://zerosleeps.com/blog/2026/3/26/dogfooding/", "title": "Dogfooding", "content_html": "<p>Terence Eden in <a href=\"https://shkspr.mobi/blog/2026/03/bored-of-eating-your-own-dogfood-try-smelling-your-own-farts/\">a post titled &ldquo;Bored of eating your own dogfood? Try smelling your own farts!&rdquo;</a>:</p>\n<blockquote>\n<p>&ldquo;<a href=\"https://en.wikipedia.org/wiki/Eating_your_own_dog_food\">Dogfooding</a>&rdquo; is a sacred practice in the tech industry. Use your own products. That&rsquo;s it. That&rsquo;s all you have to do.</p>\n</blockquote>", "date_published": "2026-03-26T01:41:14Z"}, {"id": "/blog/2026/3/25/apple-continues-their-mission-to-drive-me-away/", "url": "https://zerosleeps.com/blog/2026/3/25/apple-continues-their-mission-to-drive-me-away/", "title": "Apple continues their mission to drive me away", "content_html": "<p>I used Pages to create a document a couple of weeks ago - something I <em>very</em> rarely do - and was presented with this advertisement for Apple Creator Studio when I selected a template:</p>\n<div class=\"columns\">\n<div class=\"column is-three-fifths is-offset-one-fifth\">\n<p><img alt=\"Screenshot of advertisement for Apple Creator Studio\" src=\"/uploads/2026-03-25-pages.png\" /></p>\n</div>\n</div>\n<p>Then at the weekend I got this advertisement on my iPhone&rsquo;s lock screen after paying for breakfast:</p>\n<div class=\"columns\">\n<div class=\"column is-three-fifths is-offset-one-fifth\">\n<p><img alt=\"Screenshot of notification to join rewards program\" src=\"/uploads/2026-03-25-notification.jpg\" /></p>\n</div>\n</div>\n<p>No idea how I turn that kind of crap off, because &ldquo;Offers &amp; Promotions&rdquo; is already disabled in my Apple Wallet notification settings:</p>\n<div class=\"columns\">\n<div class=\"column is-one-third is-offset-4\">\n<p><img alt=\"Screenshot of Apple Wallet notification settings\" src=\"/uploads/2026-03-25-notification-settings.jpg\" /></p>\n</div>\n</div>\n<p>Then a load of sloppiness this morning after updating my iPhone to iOS 26.4 when I was asked to double-click the side button to let stuff verify my age via Apple Wallet. That was the gist of it anyway. I don&rsquo;t want that shit so I dismissed the prompt without thinking too much about it.</p>\n<p>But then it threw up a dialogue with this content (I couldn&rsquo;t take screenshots):</p>\n<blockquote>\n<h3>Parental Consent</h3>\n<p>To provide parental consent to create this child account, you will need to verify your identity by confirming the password for your account.</p>\n</blockquote>\n<p>I&rsquo;m not creating a child account! I&rsquo;m not creating <em>any</em> account!</p>\n<p>I played the game, then got this message. I haven&rsquo;t replaced my actual email address - this is exactly what the message said, bold text and all:</p>\n<blockquote>\n<h3>Verification Code</h3>\n<p>To provide parental consent to create this child account, enter the verification code sent to this email address: <strong>email</strong></p>\n</blockquote>\n<p>Wealthiest company in the world. Thousands of employees. The premium Apple experience is a thing of the past.</p>", "date_published": "2026-03-24T23:34:36Z"}, {"id": "/blog/2026/3/23/the-weight-of-online-advertising/", "url": "https://zerosleeps.com/blog/2026/3/23/the-weight-of-online-advertising/", "title": "The weight of online advertising", "content_html": "<p>A couple of articles have been doing the rounds inside my circles over the last couple of weeks: <a href=\"https://thatshubham.com/blog/news-audit\">the first is titled &ldquo;The 49MB Web Page&rdquo; by Shubham Bose</a> and <a href=\"https://stuartbreckenridge.net/2026-03-19-pc-gamer-recommends-rss-readers-in-a-37mb-article/\">the other is by Stuart Breckenridge</a> about PC Gamer pages which download <em>gigabytes</em> of data if left alone.</p>\n<p>I&rsquo;ve never had to get really dirty with advertising, but on the few occasions that I have been in meetings with marketing departments, I&rsquo;ve never gotten the impression that online marketing/advertising people know whether their &ldquo;campaigns&rdquo; actually <em>do anything</em>. They just do the things they do because that&rsquo;s what they&rsquo;ve always done.</p>\n<p>I have testimony! (Kind of.) The application I work with generates and encrypts all URLs for all authenticated users (it was born before cookies were invented). Every link/button/form destination/GET/POST etc. has a unique URL, and a different URL every time a user loads the same page. Anything that attempts to count page visits by URL therefore fails miserably - all you end up with is an infinite list of URLs, all of which have exactly <strong>one</strong> page visit.</p>\n<p>I explained this to the marketing department at one of the larger universities I&rsquo;ve worked at, and they just didn&rsquo;t care. They &ldquo;needed&rdquo; the tracking code added to the application anyway. It gave them <em>utterly useless</em> data and a <em>lot</em> of it. But they were delighted because, I don&rsquo;t know, there was a number on a dashboard somewhere that kept going up?</p>\n<p>It wasn&rsquo;t to advertise to customers inside the application but I assume they wanted to track users to try and work out which &ldquo;campaigns&rdquo; had led to certain outcomes. It doesn&rsquo;t take a huge amount of creativity to imagine how that kind of desperation and cluelessness leads to pages that make hundreds of slimy network requests.</p>", "date_published": "2026-03-23T06:45:07Z"}, {"id": "/blog/2026/3/21/astral-to-join-openai/", "url": "https://zerosleeps.com/blog/2026/3/21/astral-to-join-openai/", "title": "Astral to join OpenAI", "content_html": "<p>Yikes. I&rsquo;ll be <a href=\"https://astral.sh/blog/openai\">keeping a close eye on this</a>.</p>\n<p>I went all-in on <a href=\"https://docs.astral.sh/uv/\">uv</a> a few months ago after watching the hype around it grow. It is indeed rather excellent, but it&rsquo;s not excellent enough that I couldn&rsquo;t/wouldn&rsquo;t dump it if OpenAI start taking it in a creepy direction.</p>\n<p>Python has always received <a href=\"https://xkcd.com/1987/\">a lot of shit</a> for environment management, but I&rsquo;ve never really had a problem with it. In fact, pre-uv I appreciated the explicitness of <a href=\"https://github.com/pyenv/pyenv\">building and invoking the required version</a> of Python, then using built-in tools and modules to <a href=\"https://docs.python.org/3/library/venv.html\">create virtual environments</a> and going from there.</p>", "date_published": "2026-03-20T23:24:28Z"}, {"id": "/blog/2026/3/20/background/", "url": "https://zerosleeps.com/blog/2026/3/20/background/", "title": "\"Background\"", "content_html": "<p>What the feckity feck is <em>this</em>?</p>\n<p><img alt=\"Screenshot of Background Security Improvements section of macOS System Settings\" src=\"/uploads/2026-03-20-background-security-improvements.png\" /></p>\n<p>What&rsquo;s &ldquo;background&rdquo; about it if I have to restart? And why is it in &ldquo;Privacy &amp; Security&rdquo;? Why is it not just a regular software update? It might be &ldquo;enhanced in a future software update&rdquo; anyway?</p>", "date_published": "2026-03-19T23:59:37Z"}]}