Zip R2 Objects in Memory with Cloudflare Workers

It seems like a super basic thing you’d want to do with Cloudflare Workers when you store files in R2, but I’ve googled far and wide and couldn’t find an example of this anywhere.

So here’s my take on this, after much trial and error:

import { z } from 'zod';
import { ZipWriter, BlobReader, configure } from '@zip.js/zip.js';
// Without this, we get uncaught error due to Workers runtime bug
// See: https://github.com/gildas-lormeau/zip.js/discussions/514
configure({
useCompressionStream: false,
});
// Payload schema that lists the files to be bundled, their filenames and the archive filename
const schema = z.object({
archive_filename: z.string().endsWith('.zip'),
files: z.array(
z.object({
r2key: z.string(),
filename: z.string(),
})
),
});
export default {
async fetch(request, env, ctx): Promise<Response> {
const body = await request.json();
const payload = schema.safeParse(body);
if (!payload.success) {
return new Response(JSON.stringify({ status: 'failed', error: payload.error }), {
status: 409,
headers: { 'Content-Type': 'application/json' },
});
}
let { readable, writable } = new IdentityTransformStream();
// Create a ZIP archive stream
const archive = new ZipWriter(writable);
// Store all the promises to catch any errors all together later
let promises: Promise<any>[] = [];
for (const receipt of payload.data.files) {
const { r2key, filename } = receipt;
// Fetch the receipt from the R2 bucket
const fileContent = await env.STORAGE_BUCKET.get(r2key);
if (!fileContent) {
return new Response(`Object not found: ${r2key}`, { status: 404 });
}
// Add the receipt to the ZIP archive
promises.push(archive.add(filename, new BlobReader(await fileContent.blob())));
}
promises.push(archive.close());
Promise.all(promises).catch((err) => {
console.log(err);
});
return new Response(readable, {
headers: {
'Content-Type': 'application/zip',
'Content-Disposition': `attachment; filename="${payload.data.archive_filename}"`,
},
});
},
} satisfies ExportedHandler<Env>;
view raw index.ts hosted with ❤ by GitHub

You can just POST to it a JSON object with the output filename for the zip file and a list of R2 object keys with a filename to set for each.

Don’t forget to set your bindings in the wrangler.toml.

Simple Japanese Inheritance Calculator

I made a thing again!

If you’re like me, a foreigner in your 40s living in Japan, the thought of dealing with inheritance taxes for your parents back home can be daunting. Understanding how these taxes might be applied is essential.

To help with this, I created an app: Japanese Inheritance Tax Calculator.

Here are a few insights:

  • It’s not as straightforward as you might think.
  • The calculation method actually offers some advantages for foreigners.
  • The base deduction is quite high, meaning many people won’t owe taxes on even fairly sizable inheritances.

Bear in mind that this is a super simplified calculator: it only works in the case of a standard family unit where a parent of the user passes away and the user is the only heir living in Japan. But that’s fits me and a lot of my friends in Japan, so #scratchyourownitch it is.

It’s a tiny single page app built on Vite + React with shadcn/ui components. You can check out the code in the GitHub repo.

Masters of the Universe

Recently I read an article sent in by a friend of mine: What price the new democracy? Goldman Sachs conquers Europe

This is The Goldman Sachs Project […] to create such a deep exchange of people and ideas and money that it is impossible to tell the difference between the public interest and the Goldman Sachs interest.

It’s an interesting article, a realistic conspiracy theory. It made me think there might actually be guys sitting right now in a board room having a conversation like this:

Mr. Pink: “So what are we gonna do today?”

Mr. Brain: “The same thing we do every day Mr. Pink, try to take over the world!”

Except Mr. Pink probably isn’t an idiot in this story…

Lady Homare of Greystoke

The other day as we were watching TV, my girlfriend was saying that 沢穂希 (Homare Sawa), captain of Nadeshiko Japan the national women soccer team, should really keep her hair tied up under all circumstance lest she look like an ape…

To which I replied that comparing her to a monkey is a bit harsh, but she does look a bit like the Earl of Greystoke, Lord of the Apes. As she looked at me dumbfounded, I realized she had never heard of the original Tarzan apart from the Disney adaptation. So I dug out a torrent of the movie Greystoke and we watched it together.

The movie is just as good as I remember it from my childhood. It was Christophe Lambert‘s first major movie role. It was also Andie McDowell‘s first role so next up on the movie list is “Four Weddings and a Funeral”.

VIE for Valeo in Kohnan / Kumagaya

valeo logoI get a lot of Google traffic from French people whenever a job posting comes up for a VIE contract (special government high-profile trainee contract for European citizens in French companies abroad) at the place I work.

All this traffic goes to a much outdated post I wrote over 4 years ago just before coming here and I thought I’d make an update for the new arrivals or just people researching the living conditions here before accepting the job.

So if you are considering coming to work for VALEO in Kohnan – or Kounan, or Kōnan depending how you romanize 江南 – you must be asking yourself 3 questions:

Where is it?

Kohnan is in northern Saitama prefecture, some 55km north-north-west of Tokyo proper – see map below. It used to be a town by itself but has since been absorbed by the bigger city of Kumagaya which explains the dual Kohnan / Kumagaya naming conundrum. The factory itself is pretty much in the middle of the countryside with not much around, meaning: you will not go out for lunch or coffee break unless you have a car, the closest Starbucks being 15km away anyways…

View VIE for Valeo in Kohnan in a larger map

Where can you live and how to get there?

Tokyo – First out, do not expect to live in Tokyo and commute by car. Unless you are an expatriate with all expenses covered by the company, the cost of parking in Tokyo and highway tolls everyday is way way out of your budget. You can live in Tokyo and commute by train though, like I do now, preferably in northern Tokyo close to Ikebukuro station. Commute time from Ikebukuro station: 1 hour train + 20 minutes company bus.

Kumagaya – The most popular place to live among VIEs here. A bigger country town with a respectable number of restaurants and bars which will keep you entertained at least on weekday nights. Relatively good train connections to Tokyo with the Takasaki/Shonan-Shinjuku line taking you direct to Shinjuku/Shibuya in 1 hour 20 minutes. The town is 7-8km so you can come by bicycle when the weather is good. Commute time: 20 minutes by public bus + 5 minutes walk.

Higashimatsuyama – Second popular spot, I lived there for 2 years while I was myself a VIE. Small country town, not many restaurants, almost no standard bars although there are plenty of hostess clubs… The Tobu-Tojo line will take you straight to Ikebukuro in 55 minutes and with a painless train change to Shibuya in 1 hour 35 minutes. Only good point is it is cheaper than Kumagaya so you can have a bigger apartment and there is a company bus that picks you up from there and drops you inside the factory. I would not recommend it though unless you are the quiet type… (note: the area around the station is being renovated with a cinema complex and new apartment buildings as write this post, so there might be a little bit more animation in the near future) Commute time: 20min by company bus.

Kawagoe – The new frontier, only 1 or 2 Valeo VIEs live there. Big lively country town halfway from Tokyo and the company. There are tons of places to party and the place is culturally active (nicknamed “The little Edo”, there is a whole neighborhood that still has traditional buildings from the lat 1800’s, a rare sight in Japan). The Tobu-Tojo line will get you to Ikebukuro in 30 minutes and a change with the Fukutoshin line to Shibuya in under 1 hour. I would argue that this is the best compromise between commute time, cost of living and closeness to Tokyo for partying in the weekends. Commute time: 30 minutes train + 20 minutes company bus.

Additional points

One thing to keep in mind is that Kumagaya/Higashimatsuyama is 1h30 away from the ski stations which are open from mid-December through May. Bring your snow gear with you or plan to buy some here because there are snowboarding trips organized every weekend of the season.

If I could hit a big reset button and do it all again, I would probably choose to live in Kawagoe. Kumagaya is good if you hate living more than half an hour away from work. There is very little point to living in Higashimatsuyama…

If you have any questions, leave a comment and I’ll be sure to reply to you.

Update: As of May 2011, I no longer work for Valeo.

Driving school and discrimination awarenesss

As I said in a previous post, I do not have a driving license it every now and then I get itchy and think about getting one. So the other day, feeling itchy, I scanned the web to find driving schools close to my new home in Ikebukuro and found the Koyama driving school.

Interestingly, they claim to be the only driving school in Tokyo to cater to the gaijin population by offering a curriculum entirely in english. So I checked out the prices on the English and Japanese versions of the site for basic manual license:

  • Japanese: ¥302,950
  • English: ¥398,630

Wow, those bilingual driving teachers sure come at a big premium don’t they? Well if you compare the detail of the prices here’s what you find:

koyama-japanese

koyama-english

So if you actually compare the detailed split-up, the english textbooks cost ¥18,900 compared to ¥5,250 which I can understand. All the lesson/test fees are the same. The only other difference is that the entry fee is ¥83.000 more expensive if you sign up in english…

Now the interesting thing is not that it’s more expensive, I would consider it normal to have higher lecture/training fees in english language in Tokyo. What’s shocking is that there is so little awareness of “discrimination being bad” in this country that no-one thought it a bad idea to write down the price hike for this special service (which could be justifiable) as a random meaningless admission fee.

Suffice to say, I will not be bringing my business to this shop…

Softbank’s “summer scam” campaign

Softbank is launching a fun summer campaign with its cute mascot お父さん:

Use your Softbank 3G phone overseas this summer and get a chance to win one of 100 flower-necklace-wearing-お父さん straps!

softbank-summer-campaign

Way to go Softbank! It’s a classy move, trying to lure customers into using their cellphone overseas at ¥200/min and potentially incurring ginormous phone bills, all for a chance of winning a ¥150 keitai-strap…

MOSDO – MOS Burger x Mister Donuts

mosdo! - donut burgers

Mister Donuts x MOS Burger = MOSDO!

Starting May 12, MOS Burger and Mister Donut will start a joint marketing operation mixing their respective products:

  • MOS will have burgers with a hole in the middle of the patty
  • Mister Donuts will sell  burger shaped donuts – reminiscent of Mamido burger I reported about a while back (sorry, I still blogged in French at that time)

mosdo-box

At first I thought they were doing a horrible frankenstein-esque combination of donut buns and meat patties… Gross…

Business cards and QRcodes

Still on the same line of thought as my previous post, I was designing my 名刺 – well, more of outsourcing the design to my brother – and had a hard time with QRcodes that might be interesting to some people.

my meishi

So I wanted my business card to have the classic human readable info on one side, and machine readable on the other. Not so impressive in Japan where QRcodes are everywhere but I like it.

So I did a little reasearch and hit a pot-hole: there is no universal QRcode vCard equivalent standard. As explained here, DoCoMo and SoftBank/au each have their format which are not cross-compatible. So you have 2 solutions:

  1. Make your code a URL link to a .vcf file on your website. Has the advantage that you can change the data without reprinting the cards, adapt the file format to the phone via referer checking and log access (I’d love to see business card conversions in my Google Analytics stats). Downside is conversion is not as easy and you’re not sure if the phone will be able to read the vCard file.
  2. Combine the 2 vCard-like formats in a single QRcode. No stats, but this will work in all phones if you follow my instructions.

I’ve looked into the second solutions and found out by testing that you can combine the 2 formats in one QRcode but only if you put the Softbank/au type first. I guess it cannot have any characters (even a linefeed) before the MEMORY: tag. Then you can use a line of dashes to separate the 2 and make it more easily readable. The end result should look like that:

MEMORY:
NAME1:Doe John
MAIL1:[email protected]
MAIL2:[email protected]
TEL1:+818036542234
------------------
MECARD:N:Doe John;TEL:+818036542234;EMAIL:[email protected];EMAIL:[email protected];;

Paste that into a QRcode generator and you will get a nice PNG image like this:

QRcode vCard for John Doe

I’ve tested it in 3-4 keitais and it worked nicely. Try it with your phone and tell me the results.