Skip to content

Instantly share code, notes, and snippets.

@dnicolson
dnicolson / xcode-missing-files.rb
Last active December 15, 2022 20:19
Script to find missing files in Xcode .xcodeproj files (they appear red in Xcode 12)
require 'xcodeproj'
project_path = ARGV[0]
project = Xcodeproj::Project.open(project_path)
xcodebuild = `xcodebuild -project '#{project_path}' -showBuildSettings`
build_settings = xcodebuild.scan(/([A-Z_]*) = (.*?)\n/).to_h
missing_files = []
project.files.to_a.each do |file|
absolute_path = file.real_path
@dnicolson
dnicolson / iOS-keyboard-issue.c
Last active December 3, 2020 14:34
Airoha (DuraGadet/OMOTON/etc.) iOS Bluetooth keyboards produce an HID value of 0x10101010101 instead of 1 when pressing Control-Command-Up or Control-Command-Space
// clang -framework IOKit -framework Carbon iOS-keyboard-issue.c -o iOS-keyboard-issue && ./iOS-keyboard-issue
#include <Carbon/Carbon.h>
#include <IOKit/hid/IOHIDManager.h>
#include <IOKit/hid/IOHIDValue.h>
CFMutableDictionaryRef CreateMatchingDictionary(UInt32 usage_page, UInt32 usage)
{
CFMutableDictionaryRef dictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
@dnicolson
dnicolson / itunes_pp.c
Last active September 16, 2020 21:22
Play/pause iTunes by double tapping the fn key
// clang -framework IOKit -framework Carbon itunes_pp.c -o itunes_pp && ./itunes_pp
#include <sys/time.h>
#include <Carbon/Carbon.h>
#include <IOKit/hid/IOHIDManager.h>
#include <IOKit/hid/IOHIDValue.h>
CFMutableDictionaryRef CreateMatchingDictionary(UInt32 usage_page, UInt32 usage)
{
CFMutableDictionaryRef dictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
@dnicolson
dnicolson / add-youtube-videos-to-playlist.js
Created August 24, 2020 20:51
Function that adds YouTube video IDs to a playlist using session information from window.ytcfg.data
async function addVideosToPlaylist(playlistId, videoIds) {
const sej = JSON.stringify({
commandMetadata: {
webCommandMetadata: {
url: '/service_ajax',
sendPost: true,
apiUrl: '/youtubei/v1/browse/edit_playlist'
}
},
playlistEditEndpoint: {
@dnicolson
dnicolson / add-grouping.js
Created August 6, 2020 22:18
Sets the grouping field of an iTunes/Music selection with artist MusicBrainz tags via Node.js with a couple of OSA calls
const osa = require('osa2');
const fetch = require('node-fetch');
const cliProgress = require('cli-progress');
// Return a list of unique artists based on the selection
const fetchArtists = osa(() =>
(Application('iTunes') || Application('Music'))
.selection()
.map((x) => x.artist())
.filter((v, i, a) => a.indexOf(v) === i),
@dnicolson
dnicolson / install-atomicparselygui.sh
Created May 4, 2020 19:09
Script to install AtomicParsleyGUI 0.3.5 (no longer available at https://github.com/x43x61x69/AtomicParsleyGUI)
#!/bin/bash
curl -O http://ftp-new-pc.pconline.com.cn/ffeffca671e6cf60507f8d3a6e8ed552/pub/download/201807/pconline1531017059128.zip
unzip pconline1531017059128.zip -d /Applications
chmod +x /Applications/AtomicParsleyGUI.app/Contents/MacOS/AtomicParsleyGUI
brew install atomicparsley
cp /usr/local/bin/AtomicParsley /Applications/AtomicParsleyGUI.app/Contents/Resources/AtomicParsley
chmod +x /Applications/AtomicParsleyGUI.app/Contents/Resources/AtomicParsley
xattr -r -d com.apple.quarantine /Applications/AtomicParsleyGUI.app
rm pconline1531017059128.zip
@dnicolson
dnicolson / bluetooth-connection.m
Created March 10, 2020 21:34
IOBluetooth code to log when devices are connected and disconnected
// clang -o bluetooth-connection bluetooth-connection.m -framework Foundation -framework IOBluetooth
#import <Foundation/Foundation.h>
#import <IOBluetooth/IOBluetooth.h>
@interface BluetoothConnection : NSObject {
}
@end
@implementation BluetoothConnection
@dnicolson
dnicolson / ihaper.js
Last active December 31, 2020 12:03
IFTTT solution to control an iHaper device from a Google Home Mini without the (false error) verbal confirmations
const shell = require('shelljs')
const express = require('express')
const app = express()
const port = 8000
app.get('/', (req, res) => {
shell.exec('bash /home/pi/ihaper.sh')
res.send('')
})
@dnicolson
dnicolson / switchbot.js
Created February 9, 2020 15:11
Script to a control a SwitchBot device without depending on gatttool
const noble = require('@abandonware/noble');
const address = '';
const uuidPrimary = 'cba20d00224d11e69fb80002a5d5c51b';
const uuidWrite = 'cba20002224d11e69fb80002a5d5c51b';
noble.on('stateChange', state => {
if (state === 'poweredOn') {
noble.startScanning([uuidPrimary], false);
} else {
@dnicolson
dnicolson / toggle-lightbulb.sh
Created January 18, 2020 16:30
Control a HomeKit lightbulb from the Touch Bar with this Quick Action (requires getting the pairing keys from the Keychain)
PYTHON=/Users/dave/.asdf/shims/python3
STATUS=`$PYTHON -m homekit.get_characteristic -f ~/.homekit_python/pairing.json -a iHaper -c 1.13`
if [[ "$STATUS" =~ "true" ]]; then
$PYTHON -m homekit.put_characteristic -f ~/.homekit_python/pairing.json -a iHaper -c 1.13 false
else
$PYTHON -m homekit.put_characteristic -f ~/.homekit_python/pairing.json -a iHaper -c 1.13 true
fi