Skip to content

Instantly share code, notes, and snippets.

View mikker's full-sized avatar
👋

Mikkel Malmberg mikker

👋
View GitHub Profile
@mikker
mikker / application.html.erb
Last active September 5, 2024 20:58
Using Bucket.co with Rails (+Stimulus)
<!doctype html>
<html>
<head>
<script>
window.BUCKET_OPTIONS = <%= bucket_options.to_json.html_safe %>
</script>
<%= javascript_include_tag :application %>
</head>
<body>
<!-- ... -->
@mikker
mikker / account_updated.rb
Created December 18, 2023 08:48
Homegrown StripeEvents handling
# app/models/stripe_events/account_updated.rb
module StripeEvents
class AccountUpdated
def call(event)
# do your thing
Rails.logger.debug(event.data.object)
end
end
end
@mikker
mikker / normalize_slim_class_names.rb
Last active January 3, 2024 07:45
Script to normalize Slim template class names into their attribute form. This more regular form works better with Tailwind, both the parser and the sorting formatters.
#!/usr/bin/env ruby
class SlimLine
KNOWN_TAGS = "div|header|footer|aside|section|article|nav|main|ul|ol|li|a|p|h1|h2|h3|h4|h5|h6|span|button|form|input|textarea|select|option|label|fieldset|legend|table|thead|tbody|tr|td|th"
RE = %r{^(?<whitespace>\s*)(?<tag>(#{KNOWN_TAGS})\b)?(?<id>#[a-z\-]+)?(?<class_list>(\.[-a-z][a-z0-9\-:\/]*)+)?(?<rest>.*)?}
def initialize(line)
@line = line.dup
end
@mikker
mikker / action.json
Created November 4, 2023 13:53
Add to Newsletters for Scriptable
{
"always_run_in_app" : false,
"icon" : {
"color" : "deep-purple",
"glyph" : "magic"
},
"name" : "Add to Newsletters",
"script" : "const input = args.plainTexts[0] || \"[email protected]\";\nconst emails = input.match(\/([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\\.[a-zA-Z0-9._-]+)\/gi);\nconst email = emails[0];\n\n\nconst containers = await ContactsContainer.all();\n\nlet container, group;\nfor (const c of containers) {\n const groups = await ContactsGroup.all([c]);\n const newsletters = groups.find(g => g.name === \"Newsletters\");\n if (!newsletters) continue;\n container = c;\n group = newsletters;\n}\n\nconst contact = new Contact();\ncontact.emailAddresses =[{ value: email }];\nContact.add(contact, container.identifier);\ngroup.addMember(contact);\n\nawait Contact.persistChanges();\n\nconst alert = new Alert();\nalert.title = email;\nalert.addAction(\"OK\")\nalert.present();\n\n",
"share_sheet_inputs" : [
"plain-text"
@mikker
mikker / 0_sort.rb
Created February 23, 2022 14:06
Sorting the Invisible Friends
require_relative "sheet.rb"
require 'digest'
CURRENT_BLOCK = 12345
COMMUNITY_REACTIONS = 54321
def main
sheet = Sheet.new('Metadata/InvisibleFriends_Metadata.csv')
sheet.headers.concat(['Seed', 'Filename', 'SHA256'])
@mikker
mikker / ensure_docker_is_ready.bash
Created June 25, 2021 09:16
Wait for Docker.app to be ready
#!/bin/bash
# Usage:
# $ ensure_docker_is_ready && docker-compose up
docker ps &> /dev/null
if [ $? -ne 0 ]; then
open -a Docker.app
else
exit 0
@mikker
mikker / 00 README.md
Created May 13, 2020 20:59
Open Reading List in Tabs.app

Open Reading List in tabs

  1. Make a new Automator document of type "App"
  2. Add these three steps in order
  3. Remember to replace mikker with your own username in the AppleScript scripts
@mikker
mikker / something_system_spec.rb
Created September 9, 2019 06:55
Receive and expect Stripe webhook events in your Rails system tests
require 'system_helper'
RSpec.describe 'Something', type: :system do
it 'receives an event', :with_stripe_events do
make_request_at_stripe
wait_for_stripe_event { |e| e.type == 'charge.succeeded' }
expect(...)
end
end
@mikker
mikker / action_controller_media_type_hack.rb
Created August 5, 2019 07:11
Monkey patch action controller in Rails 6.0.0.rc2 to avoid deprecation warning
# Require this in config/application.rb after require "action_controller/railtie"
module ActionController
module Renderers
remove :json
remove :js
remove :xml
add :json do |json, options|
json = json.to_json(options) unless json.kind_of?(String)
@mikker
mikker / twitter.com.js
Created July 31, 2019 08:24
Automatically switch (back) to Latest Tweets timeline
function main() {
console.log("tick");
// Find the header signifying current timeline mode
const title = document.querySelector(
'[data-testid="primaryColumn"] h2[role="heading"]'
);
// If it isn't loaded yet, try again in 0.5 secs
if (!title) {