Skip to content

Instantly share code, notes, and snippets.

View duanebester's full-sized avatar

Duane Bester duanebester

View GitHub Profile
@duanebester
duanebester / GPIOSysfs.dart
Created April 22, 2024 20:44
A class to control GPIO pins using the sysfs interface
import 'dart:io';
const String _gpioExport = '/sys/class/gpio/export';
const String _gpioUnexport = '/sys/class/gpio/unexport';
const String _gpioPath = '/sys/class/gpio/gpio%d';
const String _gpioDirection = '/sys/class/gpio/gpio%d/direction';
const String _gpioValue = '/sys/class/gpio/gpio%d/value';
const String _gpioActiveLow = '/sys/class/gpio/gpio%d/active_low';
enum Direction { input, output, low, high }
@duanebester
duanebester / gcs-api-example.ts
Created August 16, 2023 16:05
Example of how to save files in a db and gcs
import { GetSignedUrlConfig, Storage, File, Bucket } from '@google-cloud/storage';
const storage = new Storage({
keyFilename: './config/creds.json',
});
type UploadedFile = {
url: string;
bucketId: string;
bucketName: string;
@duanebester
duanebester / postgres_socket.u
Created June 3, 2022 17:58
Talk to Postgres w/ Unison
use .base
-- SQL password message: concat('md5', md5(concat(md5(concat(password, username)), random-salt)))
-- "md58393de45eea6f814e37f41f02540710c"
calculatePassword: Text -> Text -> Bytes -> Text
calculatePassword username password salt =
use md5 md5EncodeAscii md5Encode
userpassMd5 = md5EncodeAscii (password ++ username)
use Text toUtf8
userpassMd5Bytes = (toUtf8 userpassMd5)
@duanebester
duanebester / scraper-add-to-mongo.clj
Created November 16, 2021 23:34
Web Scraping w/ Clojure add products to Mongo
;; Mongo
(require '[somnium.congomongo :as m])
;; Products database
(def mongo-conn
(m/make-connection
"products"
:instances [{:host "127.0.0.1" :port 27017}]))
;; Set global connection
@duanebester
duanebester / driver-example.clj
Last active November 16, 2021 23:32
Web Scraping Driver example
(require '[etaoin.api :as d])
;; Start firefox driver
(def driver (d/firefox {:headless false}))
;; Navigate to product url (loc key)
(d/go driver (:loc (cache->product "bellroy")))
;; Query <script type="application/ld+json"> tags
(def ld-json-query {:tag :script :type "application/ld+json"})
@duanebester
duanebester / ld-json.html
Last active November 2, 2021 14:56
Example LD+JSON tag
<script type="application/ld+json">
{
"@context":"https://schema.org/",
"@type":"product",
"brand":"Bellroy",
"image":[...],
"name":"Lite Daypack",
"offers":[
{
"@type":"offer",
@duanebester
duanebester / products-cache.clj
Last active October 28, 2021 19:58
Web Scraping w/ Clojure adding product links to cache
(clear-site "bellroy") ;; Clear cache first
(find-products "bellroy" "https://bellroy.com/sitemap.xml" product->cache)
(get-count "bellroy")
;; => 158
;; Popping product links example:
(cache->product "bellroy")
;; => {:loc "https://bellroy.com/products/pod-jacket", ...}
(cache->product "bellroy")
@duanebester
duanebester / cache.clj
Created October 28, 2021 19:50
Web Scraping w/ Clojure Cache
(require '[taoensso.carmine :as car])
;; Redis Setup
(def redis-conn {:pool {} :spec {:uri "redis://localhost:6379/"}})
(defmacro wcar* [& body] `(car/wcar redis-conn ~@body))
(defn clear-site
[^String site]
(wcar* (car/del site)))
@duanebester
duanebester / scraper.docker-compose.yml
Created October 28, 2021 14:57
Web Scraping w/ Clojure Docker Compose
version: '3'
services:
redis:
image: 'bitnami/redis:latest'
container_name: redis
environment:
- ALLOW_EMPTY_PASSWORD=yes
ports:
- 6379:6379
@duanebester
duanebester / find-products.clj
Last active October 28, 2021 19:41
Scraping - find-products
(defn get-content
[content]
(into {} (map (fn [c] [(:tag c) (first (:content c))]) (:content content))))
(defn find-products
"Crawls the url's sitemap and for each product, will call f with the site and the product"
[site url f]
(let [p (parse-xml url)
tag (:tag p)]
(println (str "Parsing URL: " url " for site " site))