Oddbean new post about | logout

Notes by Terence Eden’s Blog | export

 Safelinks are a fragile foundation for publishing
https://shkspr.mobi/blog/2024/02/safelinks-are-a-fragile-foundation-for-publishing/

Microsoft loves you and wants to protect you. So every time you receive an email with a link in it, Microsoft Outlook helpfully rewrites it so that it goes through their "safelinks" system.

Safelinks allow your administrator, or someone at Microsoft, to stop you visiting a link which is malicious or suspicious.  Rather than going to example.com, your link now goes to safelinks.protection.outlook.com/?url=example.com.

Hurrah! If you accidentally click on a naughty link you won't cause chaos and ructions.

Except, there's a tiny problem.  People like to copy and paste links that they receive. Someone sends an email which says "here's the link to that report you asked for" which then gets copied into a document or a web page.

For example, I was reading this official document from the UK's Department of Health and Social Care. Slap bang in the middle is a link to another report:



That forces everyone who visits that link to go through Microsoft's proxy. That might protect users if a link later becomes suspicious. But, more likely, it will be used in analytics to further profile users who click on links. It also undermines a user's ability to see the final destination of a link unless they can manually URl-decode content in their head.

It appears that every large organisation which uses Microsoft is prone to this failure.  Lots of UK Government departments publish content with safelinks:


The US Military too:


It's all over Twitter:


And there are hundreds of academic works infested:


Look, I get why people do this. They copy a link from an email, paste it in, click it, and it works. No one writes raw HTML by hand, nor should they have to. Our WYSIWYG tools work really well and hide all the mumbo-jumbo. Copy editors look at text; not hypertext.  It's only nerds like me who hover over a link before clicking on it.

Perhaps I should stop worrying? Perhaps it is OK that Microsoft intercepts the clicks from people all around the world? Perhaps they can competently run a proxy which detects and blocks inappropriate content? Perhaps they won't ever abuse that facility?

Here's my prediction. In the next five or so years, Microsoft is going to accidentally shut off *.safelinks.protection.outlook.com and a million copy-and-pasted links across the web are going to break.

Think I'm over-reacting?  A decade ago, Microsoft got rid of their MS Tag product and, shortly after, all their proxy links were shut off.  Similarly, other proxies like McAfee have shut down with little warning.

Or maybe Microsoft's sub-domains will be hijacked?

Either way, if you work in digital publishing, please make sure that your links point directly to the content that you want; not to Microsoft's safelinks service.

https://shkspr.mobi/blog/2024/02/safelinks-are-a-fragile-foundation-for-publishing/

#microsoft #privacy #web 
 You can't paste enter into a Linux terminal
https://shkspr.mobi/blog/2023/10/you-cant-paste-enter-into-a-linux-terminal/

I love my Linux laptop. But, once in a while, it forgets it has a keyboard. I wake it from a little nap and it's all like "no, sir! no keyboards here! just use a mouse please!"

Logging in is pretty simple. Pop_OS has an on-screen keyboard which lets me hunt-n-peck P4ssW0rd123! into the box.


But then I'm stuck. I can launch apps - but I can't type into them.

The on-screen keyboard only seems to work on certain OS elements. It didn't pop up for the Terminal app.

I could have plugged in a USB keyboard. Or even a Yubikey. But where's the fun in that? Similarly, I could have rebooted and manually changed Bash's behaviour. Or done some weird config which turns a middle click into an enter. Or SSH'd in from another machine. But I like a challenge!

So I opened up my browser, clicked to a news story, and then laboriously copied and pasted the letters l s u s b into the terminal. That would show me if my keyboard was stolen by goblins.

But how to run the command? I found a newline on the web page and c&p'd that.



Nothing.

And that's how I learned that most modern terminals don't let you paste in an enter. It becomes a newline to stop you automatically running code you shouldn't. This is the default behaviour on Bash since 5.1.

Anyway, there's a long running bug about this intermittently glitchy keyboard behaviour. In future, I'll just reboot.

https://shkspr.mobi/blog/2023/10/you-cant-paste-enter-into-a-linux-terminal/

#linux 
 Why is there no OpenBanking API for personal use?
https://shkspr.mobi/blog/2023/10/why-is-there-no-openbanking-api-for-personal-use/

The recent news that MoneyDashboard is suddenly shutting down has exposed a gap in the way OpenBanking works. It is simply impossible for a user to get read-only access to their own data without using an aggregator. And there are very few aggregators around.

Why is it impossible for me to get programmatic access to my own data?

There are two interlinked reasons which I'd like to discuss.Background

OpenBanking is a brilliant idea encoded in an excellent standard wrapped in some very complex processes and with some rather unfair limitations.

OpenBanking presents a standardised API to allow read and write access to a financial account. So I could give a smartphone app read-only access to my credit card and let it automatically tell me when I've spent more than £50 on sausage rolls this week. Or I could add all my bank accounts to one service which would let me see my net worth. Or any of a hundred ideas.

I could also connect my accounts in such a way that when Bank Account A drop below £100, an OpenBanking API request is sent to Bank Account B to transfer some money to A.

Nifty!Access

But here's the first problem. The only way you can get access to a bank's API is if you have a licence. And you only get a licence if you're a financial institution who can prove that they have robust security controls.  Which means that individuals have to go through an aggregator. Or, in OpenBanking terms, an "Account Information Service Provider".

Some OpenBanking providers will let individuals play in a "sandbox" to test out the API. There are no real accounts and no real money, it's just a way to test how the API works.

I can see why that makes sense for write access. You don't want a user's unpatched Raspberry Pi suddenly sending all their money to Russia.

And I can see why that makes sense for organisations which deal with data from multiple people. One leak and everyone is exposed.

But I'm not convinced that it makes sense to deny an individual read-only API access to their own account. Sure, I might accidentally leak my own data - but the same risk exists if I download a PDF statement from my bank.Coverage

The second problem is that not every OpenBanking consumer will talk to every OpenBanking provider.

For example, I have an account with Coventry Building society. They have an OpenBanking API which no one uses! They're not the largest financial institution in the UK, but have a fair few customers. And yet all the OpenBanking apps refuse to work with it.

So even if I did find an aggregator with an API, it may not work with all my financial institutions.What's next?

As much as I love using someone else's website or app, sometimes there's nothing better than writing something bespoke.

I was using MoneyDashboard as an unofficial API. I gave them read-only access to my accounts and then piggybacked off their API. But that's now closed.

Similarly, I was using Moneyed - which offered a personal OpenBanking API - but that shut down as well.

And now I can't find anything.

If you know of an Account Information Service Provider which provides read-only API access to connected accounts, please let me know!

https://shkspr.mobi/blog/2023/10/why-is-there-no-openbanking-api-for-personal-use/

#api #money #openbanking 
 Improving the WordPress Comments Form with Client-Side Validation
https://shkspr.mobi/blog/2023/10/improving-the-wordpress-comments-form/

If you use WordPress's HTML5 comments, there's an annoying little gotcha. There's a four year old bug which prevents client-side form validation.

HTML allows <input> elements to have a required attribute. In theory, that means the form shouldn't submit until the input is filled in. Sadly, WordPress uses novalidate on the form - as the name suggests it stops any validation.

But! WordPress is very hackable. Here's how to make a comment form which does client-side validation and as a bonus checks that the commentor's URl starts with http:// or https://

In your theme, there should be a file called comments.php - that's what we'll be editing.

We're looking for the part which generates the comments form. It will probably be comment_form( $comments_args ); or comment_form();

We're going to need to create a $comments_args array full of the options we want to set.

The most important is "format" => "xhtml" - that prevents the dreaded novalidate from appearing.if ( comments_open() || pings_open() ) :    $comments_args = array(        //  Force client side validation         "format" => "xhtml",        "comment_field" => '<label for="comment">Comment:</label>'.                '<textarea required id="comment" name="comment" cols="45" rows="8" maxlength="65525" placeholder="Write something interesting here…"></textarea>',        'fields' => array(            'author' => '<label for="author">Your Name (required):</label>'.                '<input type="text" required id="author" name="author" value="" size="30" maxlength="245" autocomplete="name" placeholder="Dr. Winston O\'Boogie">',            'email' => '<label for="email">Your Email (required):</label>'.                '<input type="email" required id="email" name="email" placeholder="me@example.com">',            'url' => '<label for="url">Your Website (optional):</label>'.                '<input type="url" id="url" name="url" pattern="^https?:\/\/(.*)" placeholder="https://example.com">'        )    );    comment_form( $comments_args );

Save that and upload it to your theme and - hopefully - it will work. You can test it out by leaving me a comment below.

https://shkspr.mobi/blog/2023/10/improving-the-wordpress-comments-form/

#HowTo #HTML #php #wordpress 
 It has never been cheaper to commit a crime
https://shkspr.mobi/blog/2023/10/it-has-never-been-cheaper-to-commit-a-crime/

The UK has what is known as a "Standard Scale" of fines for criminal acts. For example, breaking the law may incur "a fine not exceeding level 4 on the standard scale".

Part of the reasoning behind this, so I understand, is to make it simpler for the Government to update the value of those fines. Rather than having to change every law in the land - and have tedious votes on them - it's possible to change one law and have its provisions cascade down to all others. Efficient!

The modern Standard Scale was brought in by the Criminal Justice Act 1991.  The fines are:

Level on the scale
Offence committed
11 April 1983 - 1 October 1992
Offence committed
 after 1 October 1992

1
£25
£200

2
£50
£500

3
£200
£1,000

4
£500
£2,500

5
£1,000
£5,000

(Source: Sentencing Act 2020)

As you can see,  the fines increased quite dramatically from their old value.

And, since 1992 the fines have increased by... nothing!

The Bank of England's Inflation calculator estimates that a £5,000 fine in 1992 should be approximately £10,000 in 2023.

As I understand it, the Standard Scale can be increased via a Statutory Instrument. With the stroke of a pen (and a lot of behind the scenes work) the Justice Secretary could increase these fines so they kept up with inflation.

And that nearly happened! In 2014, a Draft statutory Instrument was published. It proposed increasing the Levels 1-4 fines by 400% - so Level 4 would go from £2,500 to £10,0001.

Quite why it was never published, I was not able to find out.

All I know is that during this time of rapid inflation, it appears that the Government are doing nothing to make sure crime doesn't pay.

It is estimated that in 2021, 77% of all offenders received a fine.  That's approximately 737,000 offenders who are paying less than they would have thirty years ago.

The very least the Government could do is ensure that the criminals who do get caught, charged, and convicted have to pay a fine which reflects the severity of their crime.

The Level 5 fine had already become a potentially unlimited fine due to Legal Aid, Sentencing and Punishment of Offenders Act 2012 - Section 85. ↩

https://shkspr.mobi/blog/2023/10/it-has-never-been-cheaper-to-commit-a-crime/

#crime #government #politics 
 The minimal-div minimal-span philosophy of this blog
https://shkspr.mobi/blog/2023/10/the-minimal-div-minimal-span-philosophy-of-this-blog/

If you've ever leaned Mandarin Chinese, you'll know about "measure words". They're the sort of thing that trip up all new learners of the language.  While 个 (gè) can be used as a generic measure word, using it everywhere makes you sound like an idiot (according to my old teacher). So you learn to use 个 for people, 包 for packets, and 根 for things which are long and thin.

English has a similar construct. You might say "one bunch of flowers" or "two glasses of wine" or "three bowls of soup".

You could say "one thing of flowers" or "two things of wines" or "three things of soups" but the measure words give much needed context and semantics.

If you get it wrong and said to a publican "four mugs of beer please" they'd probably know what you meant but it could be a bit confusing.

And isn't that very much like HTML?

The language of the web gives us semantic elements for our markup. When you use <button> to draw a button on screen, the browser knows exactly what to expect, how to display the content, and what it should do.  A search engine can extract meaning from the page. Users of assistive technology can be told that they're on a button. Everything is lovely!

You don't have to do that, of course. You could use <div class="button" onclick="something()"> - with enough CSS and JS you'll have something which looks and acts more-or-less like a button. But you'll lose all the semantics which make life easier for browsers, search engines, assistive technologies, and anything else that a user uses to interact with your site.

HTML has dozens of semantic elements. There's <address> for contact details, <time> for dates and times, <nav> for navigation elements.

There are two main "generic" elements. <div> for blocks of stuff, and <span> for a short run of text.  I find that most modern websites over-use these elements. I want to reiterate, there's nothing illegal or immoral about doing so; the web police aren't going to take you to gaol.  I personally think that writing semantic HTML is easier to maintain, easier to understand, easier for accessibility, and easier for automatically extracting meaning.

So, for a while now, I've been slowly working on my blog's theme in order to remove as many <div>s and <span>s as possible. I started out with a couple of hundred of each. I'm now down to about 35 of each - depending on which page you're on.

Here are some of the problems I found.

Semantic wrapping is complicated

I use Schema.org microdata in my HTML. For example, when a user has left a comment, I might indicate their name by using <span itemprop="name">Juliet Capulet</span>

Or, in the heading of a post I might useThis post has<span itemprop="https://schema.org/commentCount">3</span> comments and is<span itemprop="https://schema.org/wordCount">400</span> words long

Because there's no HTML element like <commentcount> or <wordcount>, I have to wrap those numbers in something if I want to indicate the semantic content behind them.  I could "cheat" and use something like <var> or <output> but they're as semantically irrelevant as <span>.

Similarly, it's hard to do semantic comments for WordPress.

Some things are just things

I have a large calendar at the bottom of every page showing my archives. Each calendar is its own "thing" and so is wrapped in a <div> which controls its style and layout. That group of calendars is also its own thing - because <details> elements are weird.

They're inside a widget - which itself is inside of an <aside>.

I was using a <table> layout for them, but it wasn't flexible and it ballooned the size of the DOM. Perhaps I should treat them as lists? At least then they'd be easier to skip?

WordPress defaults

All built in widgets in WordPress take the following form:<h2 class="widget-title">...</h2><div>   ...</div>

I don't think they need that extra <div>, although I can see why it might be necessary for styling.

Similarly, wp_nav_menu() is encased in a <div> by default - although that can be removed.

What's Next?

I'm going to continue hacking away out of a sense of masochism. Perhaps the only person who will notice (other than me) is someone accidentally viewing the source of this page.



But I think it's worth it. There's that story about how the original Mac circuit board was laid out so that, despite never being seen by normal people, it was part of the overall æsthetic.  And I think that's what I'm going for - something that I can be satisfied with.

https://shkspr.mobi/blog/2023/10/the-minimal-div-minimal-span-philosophy-of-this-blog/

#blogging #HTML 
 Who said "Brits think 100 miles is a long distance - Americans think 100 years is a long time"?
https://shkspr.mobi/blog/2023/09/who-said-brits-think-100-miles-is-a-long-distance-americans-think-100-years-is-a-long-time/

It's one of those pithy little quotes which reveals so much about our two cultures. The average Briton considers anything more than a 45 minute trip a bit of a schelp, whereas Americans will seemingly drive half a day just to get some ribs from that one place they like. Conversely, I went to school opposite a church which pre-dated Columbus's invasion of North America - and I doubt that was the oldest church in the town!

But who said it first?  Oh, there are a variety of sites online which will swear that it's a modern author. But let's see if we can find a quote from the last century.

Back in 1999, Neil Gaiman was interviewed in Locus Magazine and said:

  England has history; Americans have geography. Which goes back to that joke, ‘America is a country where 100 years is a long time, and England is a country where 100 miles is a long way.’ Both of those things are true on many levels. There really isn’t a great English road trip tradition, because in three or four days, you’ve done it all. Whereas in America, the idea of the road trip is this magnificent long slog.

So it was already an establish trope by the tail-end of the millennium - as can be seen in Billboard Magazine's October 1998 edition.

Diana Gabaldon published "Drums of Autumn" in 1996. She's often cited as the origin of the quote.

[Image:  She smiled, but with a wry edge to it. 'My father always said that was the difference between an American and an Englishman. An Englishman thinks a hundred miles is a long way; an American thinks a hundred years is a long time.' Roger laughed, taken by surprise. 'Too right You'll be an American, then, I suppose?' ]

Travelling back a bit further, there's a Usenet post from 1995 where 'Mike "from the US, but my wife is from Scotland" Bartman' says:

  It appears that the difference between the US and the UK is that in the UK 100 miles is a long way, and in the US 100 years is a long time... ;^)

There's quite a few Usenet posts with that phrase, but I couldn't find any before the mid 90s.

In 1992, Benjamin Jones wrote a column in "EUROPE, The Magazine of the European Community" (ISSN 0191-4545)

[Image:  There's a saying that the difference between the two nations is that the British think 100 miles is a long way, while the Americans think 100 years is a long time.]

(60MB PDF Source)

But the earliest I can reliably trace it back is a book from 1991 called "The Changing context of social-health care : its implications for providers and consumers". It in, Emily Friedman wrote a paper called "Patients as Partners: The Changing Health Care Environment" which talks, in part, about the litigious nature of American consumers of health services. She writes:

[Image:  Unfortunately or fortunately, this situation will prevail for some time to come, because the United States, as a nation, is going through a delayed adolescence, and we are questioning everything. We are a very new country, even if we are an old democracy, and we don't have it all down yet. As my friend Simon, an Englishman, says, "The British think a hundred miles is a long way; Americans think a hundred years is a long time." ]

You can read the original at the Internet Archive or on Google Books.

Who was this "Simon"? Is he a real or imagined interlocutor? Did he originate this mot juste? Given the passage of time, it's probably impossible to find out.

Sadly, Emily died in 2016. It sounds like she fought tirelessly for justice - may she rest in power.

As for unreliable sources?  There's this page from Jan Kučera which catalogues jokes posted to HUMOR@UGA.CC.UGA.EDU. It appears to have gone live around 1996:

[Image:  From: hcate.OSBU_North@XEROX.COM
Subject: Life 3.S A collection of clean humor gathered on: 21 Nov 88. "Give me a place to sit, and I'll watch."
-- friend of Archimedes "Great leaders are rare, so I'm following myself." Guy walks into a restaurant. Orders eggs. The waitress asks "How would you like those eggs cooked?" The guy says "Hey, that would be great."
"No job too big; no fee too big!" --Dr. Peter Venkman, "Ghost-busters" Difference between US & UK... UK - 100 miles is a long distance. US - 100 years is a long time.]

That claims to be from 1988 - but there doesn't appear to be an archive of the HUMOR@UGA.CC.UGA.EDU listserve that I can find.

However, it does turn up in the venerable TextFiles:

[Image:  From: fraser@engine.dec.com (Product Acoustics Group*MLO6-2/T13*223-8744). Subject: Difference between US & UK... Keywords: rec_humor_cull, smirk. Date: 22 Nov 88 16:30:06 GMT. Organization: Digital Equipment Corporation. UK - 100 miles is a long distance. US - 100 years is a long time. Edited by Brad Templeton.  MAIL, yes MAIL your jokes to watmath!looking!funny . Attribute the joke's source if at all possible.  I will reply, mailers willing. If you MUST reply to a rejection, include a description of your joke because there is 0 chance I will remember which one it was.]

It looks like "Fraser" at DEC sent that via UUCP to (for those of you not familiar with the now obsolete "Bang Path Notation) funny at looking via University of Waterloo's math department. Whereupon Brad Templeton probably re-circulated it to Usenet's "rec.humor.funny".

And that's as far back as I can trace it. Early Internet history is either mouldering on a set of tapes somewhere or completely lost. Google Books and Archive.org don't show the phrase appearing any earlier. But perhaps your research skills are better than mine?

Can you find an earlier reference? If so, please stick a comment in the usual box.

https://shkspr.mobi/blog/2023/09/who-said-brits-think-100-miles-is-a-long-distance-americans-think-100-years-is-a-long-time/

#history #language 
 How far did my post go on the Fediverse?
https://shkspr.mobi/blog/2023/09/how-far-did-my-post-go-on-the-fediverse/

I wrote a moderately popular post on Mastodon. Lots of people shared it. Is it possible to find out how many different ActivityPub servers it went to?

Yes!

As we all know, the Fediverse is one big chain mail.  I don't mean that in a derogatory way.

When I write a post, it appears on my server (called an "instance" in Mastodon-speak).

Everyone on my instance can see my post.

My instance looks at all my followers - some of whom are on completely different instances - and sends my post to their instances.

As an example:

I am on mastodon.social
John is on eggman_social.com
Paul is on penny_lane.co.uk
Both John and Paul follow me. So my post gets syndicated to their servers.

With me so far?

What happens when someone shares (reposts) my status?

John is on eggman_social.com
Ringo is on liverpool.drums
Ringo follows John
John reposts my status.
eggman_social.com syndicates my post to liverpool.drums

And so my post goes around the Fediverse!  But can I see where it has gone?  Well... sort of! Let's look at how.

A note on privacy

People on Mastodon and the Fediverse tend to be privacy conscious. So there are limits - both in the API and the culture - as to what is acceptable.

Some people don't share their "social graph". That is, it is impossible to see who follows them or who they follow.

Users can choose to opt-in or -out of publicly sharing their social graph. They remain in control of their privacy.

In the example above, if Ringo were to reshare John's reshare of my status - John doesn't know about it. Only the original poster (me) gets notified. If John doesn't share his social graph, it might be possible to work out where Ringo saw the status - but that's rather unlikely.

Mastodon has an API rate limit which only allows 80 results per request and 1 request per second. That makes it long and tedious to crawl thousands of results.

Similarly, some instances do not share their social data or expose anything of significance. Some servers may no longer exist, or might have changed names. It's impossible to get a comprehensive view of the entire Fediverse network.

And that's OK! People should be able to set limits on what others can do with their data.  The code you're about to see doesn't attempt to breach anyone's privacy. All it does is show me which servers picked up my post. This is information which is already shown to me - but this makes it slightly easier to see.

The Result

I looked at this post of mine which was reposted over 100 times.

It eventually found its way to… 2,547 instances!

Ranging from 0ab.uk to թութ.հայ via godforsaken.website and many more!

And that's one of the things which makes me hopeful this rebellion will succeed. There are a thousand points of light out there - each a shining beacon to doing things differently. And, the more the social media giants tighten their grip, the more these systems will slip through their fingers.

The Code

This is not very efficient code - nor well written. It was designed to scratch an itch.  It uses Mastodon.py to interact with the API.

It gets the instance names of all my followers. Then the instance names of everyone who reposted one of my posts.

But it cannot get the instance names of everyone who follows the users who reposted me - because:
[Image:  Followers from other servers are not displayed. Browse more on the original profile.]

The only way to get a list of followers from a user on a different instance is to apply for an API key for that instance. Which seems a bit impractical.

But I can get the instance name of the followers of accounts on my instance who reposted me. Clear?

I can also get a list of everyone who favourited my post. If they aren't on my instance, or one of my reposter's follower's instances, they're probably from a reposter who isn't on my instance.

My head hurts.

Got it? Here we go!import configfrom mastodon import Mastodonfrom rich.pretty import pprint#  Set up accessmastodon = Mastodon( api_base_url=config.instance, access_token=config.access_token, ratelimit_method='pace' )#  Status to check forstatus_id = 111040801202691232print("Looking up status: " + str(status_id))#  Get my datame = mastodon.me()my_id = me["id"]print("You have User ID: " + str(my_id))#  Empty setsinstances_all        = set()instances_followers  = set()instances_reposters  = set()instances_reposters_followers  = set()instances_favourites = set()#  My Followersfollowers = mastodon.account_followers( my_id )print( "Getting all followers" )followers_all = mastodon.fetch_remaining( followers )print("Total followers = " + str( len(followers_all) ) )#  Get the server names of all my followersfor follower in followers_all:    if ( "@" in follower["acct"]) :        f = follower["acct"].split("@")[1]        instances_all.add( f )        if ( f not in instances_followers):            print( "Follower: " + f )            instances_followers.add( f )    else :        instances_all.add( "mastodon.social" )        instances_followers.add( "mastodon.social" )total_followers  = len(instances_followers)print( "Total Unique Followers Instances = " + str(total_followers)  )#  Reposters#  Find the accounts which reposted my statusreposters     = mastodon.status_reblogged_by( status_id )reposters_all = mastodon.fetch_remaining(reposters)#  Get all the instance names of my repostersfor reposter in reposters_all:    if ( "@" in reposter["acct"]) :        r = reposter["acct"].split("@")[1]        instances_all.add( r )        if ( r not in instances_followers ) :            print( "Reposter: " + r )            instances_reposters.add( r )total_reposters  = len(instances_reposters)print( "Total Unique Reposters Instances = " + str(total_reposters)  )# Followers of reposters     # This can take a *long* time!   for reposter in reposters_all:       if ( "@" not in reposter["acct"]) :          reposter_id = reposter["id"]        print( "Getting followers of reposter " + reposter["acct"] + " with ID " + str(reposter_id) )        reposter_followers = mastodon.account_followers( reposter_id )           reposter_followers_all = mastodon.fetch_remaining( reposter_followers )          for reposter_follower in reposter_followers_all:                if ( "@" in reposter_follower["acct"]) :                 f = reposter_follower["acct"].split("@")[1]                instances_all.add( f )                if (f not in instances_reposters_followers) :                    print( "   Adding " + f + " from " + reposter["acct"] )                    instances_reposters_followers.add( f )   total_instances_reposters_followers  = len(instances_reposters_followers)print( "Total Unique Reposters' Followers Instances = " + str(total_instances_reposters_followers)  )#  Favourites#  Find the accounts which favourited my statusfavourites     = mastodon.status_favourited_by( status_id )favourites_all = mastodon.fetch_remaining(favourites)#  Get all the instance names of my favouritesfor favourite in favourites_all:    if ( "@" in favourite["acct"]) :        f = favourite["acct"].split("@")[1]        instances_all.add( f )        if ( f not in instances_favourites ) :            print( "Favourite: " + f )            instances_favourites.add( r )total_favourites = len(instances_favourites)print( "Total Unique Favourites Instances  = " + str(total_favourites) )print( "Total Unique Reposters Instances = " + str(total_reposters)  )print( "Total Unique Followers Instances = " + str(total_followers)  )print( "Total Unique Reposters' Followers Instances = " + str( len(instances_reposters_followers) ) )print( "Total Unique Instances = " + str( len(instances_all) ) )

https://shkspr.mobi/blog/2023/09/how-far-did-my-post-go-on-the-fediverse/

#mastodon #MastodonAPI #python 
 A love letter to electric power tools
https://shkspr.mobi/blog/2023/09/a-love-letter-to-electric-power-tools/

When I was seven or eight, I asked Santa to bring me a set of screwdrivers for Christmas. I wanted to take apart my toys to see how they worked1. I also thought they might be useful on our upcoming holiday; if the aeroplane needed repairing mid-flight I'd be able to help2!

Santa heard my plea and delivered a set of screwdrivers3. I used them for years. A few decades later and they're still in use4 - in fact, they're used a little too often.

For years I resisted the idea of an electric screwdriver. I don't know if it was pride, stubbornness, or a misplaced sense of machismo. I had two working hands, why shouldn't I exert my raw manly power and transform them into torque? Electric screwdrivers were for wimps!

And then, one day, I saw a USB-powered electric screwdriver and though "fuck it, why not?"

It was a revelation!

All of a sudden the little jobs I'd been putting off for ages were easy to accomplish. When I was tired from a day of DIY, it was a breeze to screw things back together. My hands didn't hurt after grappling with a stuck screw. I became a full convert.

Last week I had to saw some fence panels to length. "No worries!" I thought, "I've got a hacksaw!"

Two hours of sweating in the hot sun, and with only half the panels cut, I gave in and got an electric jigsaw5.  This weekend I did the rest in about 15 minutes with minimum sweating, swearing, and injury.

Why am I like this? Why do I struggle with the hard, manual way and only then reluctantly let tools help me?

I'm like this with computers as well. When I started programming in university, I was strictly a "type it in notepad" kinda guy. I couldn't afford an IDE6. What did I need "syntax highlighting" for? Auto-complete was just for lazy programmers.

And then, one day, after banging my head against my desk once too often a class-mate induced me to switch.

The same happened with PHP. I spent ages hand-crafting things. Learning the hard way what worked and what didn't. Coming up with my own bespoke solutions until it was just too much for me to manage. And then I switched to the Symfony framework.

In one sense, it is useful to do things manually. To learn what works and what doesn't. To understand where the limits of usefulness are. To be equipped to manage if you're stuck without tools.

And, it's helpful not to prematurely optimise. The British phrase "all the gear, no idea" perfectly describes someone who grabs all the (expensive) tools without the faintest idea how they work and what to do with them7.

I'm getting better, mind you. During my MSc, I asked for advice and started using Zotero before getting too far down the manual route. That saved me a huge amount of time and heartache.

So, my plea to you - and to future me - remember that's it is OK to use tools. It isn't cheating. It isn't unseemly. Sometimes, it isn't about they journey you take, it is about the destination.

Sadly, I never quite mastered the art of putting them back together again. So many R.A.T.S. never worked properly again after I'd finished with them. ↩
To this day I've never heard a plane's Captain announce over the tannoy "Is there any one on board who has a screwdriver?" ↩
It is also possible that my parents thought that screwdrivers were cheaper than whatever plastic junk was currently being advertised on TV. ↩
I honestly think they're the only birthday present from my pre-teen years I still have. All the He-Man toys8 slowly went to jumble-sales. ↩
I also got a battery, extra blades, new gloves, eye protection, some masks, clamps, and a new drill. Oh, and a battery + charger. Because I am weak-willed and need all the toys. ↩
Yes, that's how old I am. We had to pay for our C++ IDEs. And the compiler cost extra. ↩
Of course, I have the opposite problem. I spend months reading reviews and micro-optimising for the perfect cost/value ratio. ↩
THEY'RE NOT DOLLS! THEY'RE ACTION FIGURES! ↩

https://shkspr.mobi/blog/2023/09/a-love-letter-to-electric-power-tools/

#tools 
 Book Review: The Internet Con - How to Seize the Means of Computation by Cory Doctorow
https://shkspr.mobi/blog/2023/09/book-review-the-internet-con-how-to-seize-the-means-of-computation-by-cory-doctorow/

This is beloved firebrand Cory doing what he does best. Rallying the rebellion with righteous indignation and a no-nonsense approach to fixing technology's ills.

If you've read any of his fiction, or listened to him talk, you'll know what to expect. An overview of how big tech has screwed us over and the consequences of those machinations. Unlike other writers, Doctorow provides eminently practical solutions.

Now, some of the solutions you'll be unable to implement unless you're an elected official. So now's a great time to write to your representative and ask them to take action.

He is relentless at pointing out the hypocrisy of big tech - fighting to carve out exceptions for themselves which they then deny to others. We get a full-on historical lesson about the VCR and how the fight for the right to party infringe copyright was won and lost several times.

I spent many years working inside the UK Government pushing the agenda of open standards and interoperability. So it was particularly gratifying to read:

  Governments can—and should—have rules about interoperability in their procurement policies. They should require companies hoping to receive public money to supply the schematics, error codes, keys and other technical matter needed to maintain and improve the things they sell and provide to our public institutions.

That's what I did! It is getting better - but it is work that will never be finished.

Similarly, he accurately describes the problems with Standards Development Organisations:

  standardization meetings and forensic examinations of firewall errors—is supremely dull. It combines the thrill of bookkeeping with the excitement of Robert’s Rules of Order.

I've been a member of many and - yes - that's exactly what it is like. But, I take slight issue at some of his suggestions on this topic. The ideal SDO has to be a compromise. No one gets to walk away entirely happy. This is the eternal "Devil's Bargain" - we all exchange a little bit of what we want in order to get closer to what we need. I'm not sure there's any way around that without centrally mandating specific technical choices.

Indeed, he goes on to say:

  We won’t fix anything by demanding the impossible and shouting “nerd harder!” when tech companies fail to produce it. Nor will we fix anything by taking the tech industry at its word when it tells us that effective policies are flat-out impossible.

I'm a boring practicalist. At some point we need to do what works, even if it is ideologically unpleasant.

One of the things that Cory does well is "steelman" his opponents' arguments. He's excellent at taking on some big topics (CSAM and Blockchain, for example) and giving their proponents the benefit of the doubt1. And then he forensically takes them apart.

Cory's writing style is like his spoken style. The poetic rhythm is almost palpable - as is his love for sarcastic asides. It makes this - admittedly short - book supremely quick to read.  I feel greedy asking for more - but the book does end rather abruptly.

If you work in tech, or go anywhere near tech-policy, this is a must read. It gives you the history of how we got here, explains the problems happening now, and warns about an uncertain future.

The eBook is currently on sale for £4.50 from the publishers.
You can follow Cory Doctorow on Mastodon @b92dcc07

OK, he does say "It’s an established fact that 99.83 percent of all conversations about blockchain are nonconsensual." Which is a bit uncharitable. It's, like, 99.73% max! ↩

https://shkspr.mobi/blog/2023/09/book-review-the-internet-con-how-to-seize-the-means-of-computation-by-cory-doctorow/

#BookReview #CoryDoctorow #internet #politics