├── LICENSE ├── README.md ├── app ├── .gitignore ├── Dockerfile ├── Package.swift └── Sources │ └── main.swift ├── docker-compose.yml ├── proxy ├── Dockerfile └── nginx.conf ├── script └── run └── web ├── Dockerfile └── index.html /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Thomas Catterall 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #Fucking Fuck Mailman 2 | 3 | A web application written in Swift that will take the first path component of the URL and redirect you to a Google search of that query on the Swift mailing list. 4 | 5 | Try it out: 6 | 7 | ``` 8 | fuckfuckingmailman.com/query+goes+here 9 | ``` 10 | 11 | # How it works 12 | 13 | Fucking Fuck Mailman (or Fuck Fucking Mailman) is built on the excellent [Curassow web server](https://github.com/kylef/Curassow) and my very own [Underwood](https://github.com/swizzlr/Underwood), a Sinatra-like DSL for Swift web applications that conforms to the [Nest](https://github.com/nestproject/Nest) web server interface. 14 | 15 | Standing on the shoulders of the above giants, Fuck Fucking Mailman weighs in at a paltry 10 (yes, 10) [lines of code](https://github.com/swizzlr/ffmailman/blob/master/app/Sources/main.swift). 16 | 17 | Most of this repo is in fact the configuration of the Docker container and the nginx reverse proxy server. 18 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | .build/ 2 | Packages/ 3 | -------------------------------------------------------------------------------- /app/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM swiftdocker/swift:latest 2 | 3 | WORKDIR /code 4 | 5 | COPY Package.swift ./ 6 | # Using older version, manually patch its little "problem". 7 | RUN swift build || \ 8 | rm Packages/Curassow-0.2.0/example.swift && \ 9 | swift build --configuration release 10 | 11 | COPY ./Sources ./Sources/ 12 | RUN swift build --configuration release 13 | 14 | CMD .build/release/ffmailman --workers 4 --bind 0.0.0.0:8000 15 | -------------------------------------------------------------------------------- /app/Package.swift: -------------------------------------------------------------------------------- 1 | import PackageDescription 2 | 3 | let package = Package(name: "ffmailman", dependencies: [ 4 | .Package(url: "https://github.com/nestproject/Nest.git", majorVersion: 0), 5 | .Package(url: "https://github.com/swizzlr/Underwood.git", majorVersion: 0), 6 | .Package(url: "https://github.com/kylef/Curassow.git", Version("0.2.0")!) 7 | ]) 8 | -------------------------------------------------------------------------------- /app/Sources/main.swift: -------------------------------------------------------------------------------- 1 | import Curassow 2 | import Inquiline 3 | import Underwood 4 | import Foundation 5 | 6 | final class FuckFuckingMailman: 🇺🇸 { 7 | override init() { 8 | super.init() 9 | get("/fuckit/searchit") { _, query in 10 | let query = NSString(string: query["search"] ?? "You gotta give me a search term mate") 11 | return redirectForQuery(query) 12 | } 13 | 14 | get("/:query") { params, _ in 15 | let query = NSString(string: params["query"]!) 16 | return redirectForQuery(query) 17 | } 18 | } 19 | } 20 | 21 | private func redirectForQuery(query: NSString) -> Response { 22 | let url = NSString(string: "https://encrypted.google.com/search?as_sitesearch=lists.swift.org&q=") 23 | let escapedQuery = query 24 | .stringByAddingPercentEncodingWithAllowedCharacters( 25 | NSCharacterSet.URLQueryAllowedCharacterSet() 26 | )! 27 | let redirectURL = url.stringByAppendingString(escapedQuery) 28 | return Response(.Found, headers: [("Location", redirectURL)]) 29 | } 30 | 31 | serve(FuckFuckingMailman().application) 32 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | app: 2 | build: ./app/ 3 | tty: true 4 | ports: 5 | - "8000" 6 | 7 | nginx: 8 | build: ./proxy/ 9 | tty: true 10 | ports: 11 | - "80:80" 12 | - "443:443" 13 | volumes_from: 14 | - web 15 | links: 16 | - app 17 | 18 | web: 19 | build: ./web/ 20 | -------------------------------------------------------------------------------- /proxy/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx 2 | 3 | COPY nginx.conf /etc/nginx/nginx.conf 4 | -------------------------------------------------------------------------------- /proxy/nginx.conf: -------------------------------------------------------------------------------- 1 | worker_processes 1; 2 | 3 | events { 4 | worker_connections 1024; 5 | } 6 | 7 | http { 8 | upstream curassow { 9 | # Change IP and port for your Curassow server 10 | server app:8000 fail_timeout=30s; 11 | } 12 | 13 | server { 14 | listen 80; 15 | root /www/data; 16 | index index.html index.htm; 17 | 18 | location / { 19 | try_files $uri $uri/ @proxy; 20 | } 21 | 22 | location @proxy { 23 | proxy_http_version 1.1; 24 | proxy_set_header Upgrade $http_upgrade; 25 | proxy_set_header Connection 'upgrade'; 26 | proxy_set_header Host $host; 27 | proxy_cache_bypass $http_upgrade; 28 | 29 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 30 | proxy_set_header Host $http_host; 31 | proxy_set_header X-Forwarded-Proto $scheme; 32 | proxy_redirect off; 33 | proxy_pass http://curassow; 34 | } 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /script/run: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | docker-compose build && docker-compose up 4 | -------------------------------------------------------------------------------- /web/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:14.04 2 | 3 | WORKDIR /www/data 4 | COPY ./index.html ./ 5 | VOLUME /www/data 6 | -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |

Fuck Fucking Mailman

6 | 7 |
8 | 9 |
10 | 11 | 12 | 13 | --------------------------------------------------------------------------------