Skip to content

Instantly share code, notes, and snippets.

View paulmwatson's full-sized avatar

Paul Watson paulmwatson

View GitHub Profile
@paulmwatson
paulmwatson / Dockerfile
Last active July 1, 2025 13:31
docker-metabase-duckdb
# Minor modification to https://github.com/motherduckdb/metabase_duckdb_driver?tab=readme-ov-file#docker
FROM openjdk:21-buster
ENV MB_VERSION=v0.55.5
ENV MB_PLUGINS_DIR=/home/plugins/
ADD https://downloads.metabase.com/${MB_VERSION}/metabase.jar /home
ADD https://github.com/motherduckdb/metabase_duckdb_driver/releases/download/0.3.1/duckdb.metabase-driver.jar /home/plugins/
RUN chmod 744 /home/plugins/duckdb.metabase-driver.jar
git clean -d -x -f -n
@paulmwatson
paulmwatson / cypress_test_404_spec.js
Created January 14, 2021 08:33
Testing a 404 page with Cypress
cy.visit('/404')
//=> Test fails
cy.visit('/404', {failOnStatusCode: false})
//=> Test passes but does not test the HTTP code was 404
cy.request({url: '/404', failOnStatusCode: false}).its('status').should('equal', 404)
cy.visit('/404', {failOnStatusCode: false})
//=> Test passes, tests that the HTTP code was 404, and tests page was visited
# Python to return the IAM details of an access key
import boto3
client = boto3.client('sts', aws_access_key_id="ACCESS_KEY_ID", aws_secret_access_key="SECRET")
client.get_caller_identity()
=> {'UserId': '...', 'Account': '...', 'Arn': 'arn:aws:iam::...:user/...', 'ResponseMetadata': {'RequestId': '...', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': '...', 'content-type': 'text/xml', 'content-length': '409', 'date': '...'}, 'RetryAttempts': 0}}
docker run -it --rm -v /dir/to/code:/app python:3.9 bash
@paulmwatson
paulmwatson / explode-geojson.rb
Created May 23, 2022 07:39
Convert multiple feature/layers in a geoJSON file to individual files
# Creates multiple files from one geojson file
require 'json'
file = File.read('data.geojson')
data_hash = JSON.parse(file)
data_hash['features'].each do |feature|
file_name = feature['properties']['OBJECTID']
File.open("#{file_name}.geojson", 'w') do |f|
f.write(feature.to_json)
end
import tweepy
import os 
API_KEY = os.getenv('API_KEY')
API_SECRET = os.getenv('API_SECRET') 
auth = tweepy.AppAuthHandler(API_KEY, API_SECRET)
api = tweepy.API(auth, wait_on_rate_limit=True) 
items = tweepy.Cursor(api.user_timeline, screen_name='NPATweets', count=200).items(3200)
@paulmwatson
paulmwatson / docker-compose.yml
Created January 3, 2022 13:50
Using PgBouncer with Django and Docker Compose
version: '3'
services:
app:
build: .
image: app
depends_on:
- db
environment:
- DATABASE_URL=postgresql://db:db@pgbouncer/db
@paulmwatson
paulmwatson / 302-redirect.js
Created December 23, 2021 14:31
302 redirect
'use strict';
exports.handler = (event, context, callback) => {
var response = {
"statusCode": 302,
"headers": {
"location": "https://new-domain.tld"
},
"body": "{}",
"isBase64Encoded": false
@paulmwatson
paulmwatson / search_before_you_tweet.js
Last active December 15, 2021 20:56
A simple bookmarklet that searches Twitter with the URL you are on.
// A simple bookmarklet that searches Twitter with the URL you are on.
// Before you Tweet your own hot-take see what others are saying and ReTweet them instead.
// Author: @paulmwatson
// License: MIT
// Notes: It first looks for the "canonical" URL before falling back to the window.location.
// It strips any URL parameters e.g. UTM and keeps just the protocol, host, and path.
// This broadens the search as often UTM or other identifiers are unique to your session
// and Twitter's search will return no results. However it can be inacurate on websites
// that use URL parameters to identify content to show.
// Usage: Visit an article on a website like Buzzfeed.com and click the bookmarklet. A new tab