From be5362136f3d07e52e017b04da404148f799ea82 Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Sat, 9 Nov 2019 11:00:00 -0700 Subject: [PATCH] Shipping this --- .gcloudignore | 26 ++++++++ .gitignore | 5 ++ README.md | 22 +++++++ app.yaml | 6 ++ fetch-static.sh | 14 +++++ main.go | 70 +++++++++++++++++++++ static/foneworx.js | 154 +++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 297 insertions(+) create mode 100644 .gcloudignore create mode 100644 .gitignore create mode 100644 README.md create mode 100644 app.yaml create mode 100755 fetch-static.sh create mode 100644 main.go create mode 100644 static/foneworx.js diff --git a/.gcloudignore b/.gcloudignore new file mode 100644 index 0000000..26e18b8 --- /dev/null +++ b/.gcloudignore @@ -0,0 +1,26 @@ +# This file specifies files that are *not* uploaded to Google Cloud Platform +# using gcloud. It follows the same syntax as .gitignore, with the addition of +# "#!include" directives (which insert the entries of the given .gitignore-style +# file at that point). +# +# For more information, run: +# $ gcloud topic gcloudignore +# +fetch-static.sh +.gcloudignore +# If you would like to upload your .git directory, .gitignore file or files +# from your .gitignore file, remove the corresponding line +# below: +.git +.gitignore + +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib +# Test binary, build with `go test -c` +*.test +# Output of the go coverage tool, specifically when used with LiteIDE +*.out diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5e1f3b3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +static/FeisWorxLogo2.gif +static/bg8.jpg +static/cards.jpg +static/favicon.ico +static/feisworx.css diff --git a/README.md b/README.md new file mode 100644 index 0000000..8509ee1 --- /dev/null +++ b/README.md @@ -0,0 +1,22 @@ +This site adds a few simple tweaks to the feisworx web site, +in order to make it look better on a phone. + +The iPhone doesn't allow browser plugins. +So I had to create a whole app just to drop in some JavaScript. + +Hopefully one day feisworx integrates this and I can take my site down. + +Testing +------- + +First you should download static content, +so you're not hammering away at the feisworx site +for static resources. + + ./fetch-static.sh + + +Then you can test with + + go run . + diff --git a/app.yaml b/app.yaml new file mode 100644 index 0000000..2301d1d --- /dev/null +++ b/app.yaml @@ -0,0 +1,6 @@ +runtime: go113 +handlers: + - url: /images + static_dir: static + - url: /share + static_dir: static diff --git a/fetch-static.sh b/fetch-static.sh new file mode 100755 index 0000000..b5bbd10 --- /dev/null +++ b/fetch-static.sh @@ -0,0 +1,14 @@ +#! /bin/sh + +set -e + +cd $(dirname $0)/static +while read url; do + wget -c $url +done <") +const NewHead = ` + +` + +func Handler(w http.ResponseWriter, r *http.Request) { + r.URL.Scheme = "https" + r.URL.Host = "www.feisworx.com" + r.Host = "www.feisworx.com" + + resp, err := http.DefaultTransport.RoundTrip(r) + if err != nil { + http.Error(w, err.Error(), http.StatusServiceUnavailable) + return + } + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + http.Error(w, err.Error(), http.StatusServiceUnavailable) + return + } + + contentType := resp.Header.Get("Content-Type") + tamperBody := body + if strings.HasPrefix(contentType, "text/html") { + tamperBody = HeadTag.ReplaceAll(body, []byte(NewHead)) + } + + copyHeader(w.Header(), resp.Header) + w.Header().Set("Content-Length", fmt.Sprintf("%d", len(tamperBody))) + w.WriteHeader(resp.StatusCode) + w.Write(tamperBody) +} + +func main() { + http.HandleFunc("/", Handler) + http.Handle("/share/", http.StripPrefix("/share/", http.FileServer(http.Dir("static/")))) + http.Handle("/images/", http.StripPrefix("/images/", http.FileServer(http.Dir("static/")))) + + port := os.Getenv("PORT") + if port == "" { + port = "8080" + log.Printf("Defaulting to port %s", port) + } + + log.Printf("Listening on port %s", port) + log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil)) +} + diff --git a/static/foneworx.js b/static/foneworx.js new file mode 100644 index 0000000..820efde --- /dev/null +++ b/static/foneworx.js @@ -0,0 +1,154 @@ +// ==UserScript== +// @name PhoneWorx +// @namespace https://gist.githubusercontent.com/nealey/3af026cc34ddf502419aa16eee3a4caa/ +// @version 0.4 +// @description Subtly change Feisworks for narrow screens +// @author Neale Pickett +// @match http*://*.feisworx.com/* +// @match http*://feisworx.com/* +// @grant none +// ==/UserScript== + +// jshint asi:true + +// Most of what we're doing here is trying to make content flow. +// Quite a lot of pages are set up to do this pretty well already, +// they just need some hints removed. + +var foneworxCss = ` +body { + background: rgb(127,216,192); + background: linear-gradient(0deg, #1fc6f4 0%, #7fd8c0 100%); +} + +#foneworx-contact p { + float: right; + padding: 0 1em; + font-size: small; +} + +#foneworx-logo { + font-family: 'Uncial Antiqua', cursive; + font-size: 1.5em; +} +#foneworx-logo a:link { + text-decoration: none; + color: black; +} + +@media (max-width: 768px) { + body { + margin: 0; + } + h1, h2, h3, p { + margin: 0.5em; + } + #foneworx-title h1 { + margin: 0em 0.5em; + } + body > table:nth-of-type(1) tr { + display: flex; + flex-wrap: wrap; + } + #foneworx-nav tr { + display: flex; + } + a.sel { + padding: 0.5em; + margin: 0.1em; + } + form > table:nth-of-type(1) tr { + display: flex; + flex-wrap: wrap; + } + form > table:nth-of-type(1) td { + display: block; + } +} +` + +var foneworxNotice = ` +
+ +

+FoneWorx is an unofficial wrapper around FeisWorx. +We have reached out to the FeisWorx people +about integrating this functionality, +and remain hopeful that something like this can make it to the +official site. +

+ +

+If you have problems with FoneWorx, +try the FeisWorx Site +instead. +

+ +

+ FoneWorx Contact + | + Source +

+` + +function foneworxTag(path, id) { + let e = document.querySelector(path) + if (e) { + e.id = id + } +} + +function foneworxInit() { + let viewport = document.createElement("meta") + viewport.name = "viewport" + viewport.content = "width=device-width, initial-scale=1" + document.head.appendChild(viewport) + + let fontlink = document.createElement("link") + fontlink.href="https://fonts.googleapis.com/css?family=Uncial+Antiqua&display=swap" + fontlink.rel="stylesheet" + document.head.appendChild(fontlink) + + // Remove forced width on anything that forces it + for (let e of document.querySelectorAll("[width]")) { + e.width = undefined + } + + // Tag some things to make CSS more readable + foneworxTag("body > table:first-child [align='left']", "foneworx-logo") + foneworxTag("body > table:first-child [align='center']", "foneworx-title") + foneworxTag("body > table:first-child [align='right']", "foneworx-contact") + foneworxTag("table[align='center']", "foneworx-nav") + + // Do a lot of things to prevent people from pestering FeisWorx. + // If you are the FeisWorx people, I would love to + // give you whatever support you need to integrate this code, + // absolutely free of charge. neale@woozle.org + + // Change out the logo so it's clear this isn't FeisWorx + let logo = document.querySelector("#foneworx-logo") + if (logo) { + logo.innerHTML = "FoneWorx" + } + + // Tamper heavily with "contact us" + // so the feisworx people don't get a ton of mail + // about something they didn't make. + let contact = document.querySelector("#foneworx-contact") + if (contact) { + // Move it to the bottom + document.querySelector(".copyright").insertAdjacentElement("beforebegin", contact) + contact.innerHTML = foneworxNotice + } + + let style = document.createElement("style") + style.textContent = foneworxCss + document.head.appendChild(style) +} + + +if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", foneworxInit) +} else { + foneworxInit() +}