├── .gitignore ├── .gometalinter.json ├── FEBEA35B-0996-4DFB-9F9A-4049E7F5D678.png ├── LICENSE ├── Makefile ├── README.md ├── README.png ├── README2.png ├── README3.png ├── README4.png ├── VERSION ├── docker-hub.alfredworkflow ├── glide.lock ├── glide.yaml ├── hub.png ├── icon.png ├── images ├── docker-pixelmator-pro.pxd │ ├── QuickLook │ │ ├── Icon.tiff │ │ ├── Preview.tiff │ │ └── Thumbnail.tiff │ └── metadata.info └── docker.svg ├── info.plist ├── main.go ├── not-verified.png └── verified.png /.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | docker-hub/ 3 | vendor/ 4 | -------------------------------------------------------------------------------- /.gometalinter.json: -------------------------------------------------------------------------------- 1 | { 2 | "Aggregate": true, 3 | "Concurrency": 4, 4 | "CycloOver": 10, 5 | "Deadline": "2m", 6 | "Debug": false, 7 | "DisableAll": true, 8 | "DuplThreshold": 50, 9 | "Enable": [ 10 | "deadcode", 11 | "dupl", 12 | "errcheck", 13 | "gas", 14 | "goconst", 15 | "gocyclo", 16 | "gofmt", 17 | "goimports", 18 | "golint", 19 | "gotype", 20 | "gotypex", 21 | "ineffassign", 22 | "interfacer", 23 | "lll", 24 | "maligned", 25 | "megacheck", 26 | "misspell", 27 | "nakedret", 28 | "structcheck", 29 | "test", 30 | "testify", 31 | "unconvert", 32 | "unparam", 33 | "varcheck", 34 | "vet", 35 | "vetshadow" 36 | ], 37 | "EnableGC": true, 38 | "Exclude": ["^/.*", "vendor/.*", ".*_test.go$"], 39 | "LineLength": 120, 40 | "MinConfidence": 80, 41 | "MinConstLength": 3, 42 | "MinOccurrences": 3, 43 | "MisspellLocale": "US", 44 | "Skip": ["vendor"], 45 | "Sort": ["linter", "severity", "path", "line"], 46 | "Test": true, 47 | "Vendor": true, 48 | "VendoredLinters": true 49 | } 50 | -------------------------------------------------------------------------------- /FEBEA35B-0996-4DFB-9F9A-4049E7F5D678.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyzyx/docker-hub.alfredworkflow/239fa4535ece1ee659ed8b3a5c8c4ddcf3c73f7a/FEBEA35B-0996-4DFB-9F9A-4049E7F5D678.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 Ryan Parman 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 17 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | @cat Makefile | grep : | grep -v PHONY | grep -v @ | sed 's/:/ /' | awk '{print $$1}' | sort 3 | 4 | #------------------------------------------------------------------------------- 5 | 6 | .PHONY: install-deps 7 | install-deps: 8 | glide install && gometalinter.v2 --install 9 | 10 | .PHONY: build 11 | build: 12 | go build -ldflags="-s -w" -o bin/dockerhub main.go 13 | 14 | .PHONY: lint 15 | lint: 16 | gometalinter.v2 ./main.go 17 | 18 | .PHONY: package 19 | package: build 20 | upx --brute bin/dockerhub 21 | mkdir -p docker-hub 22 | rm -Rf docker-hub 23 | mkdir -p docker-hub 24 | cp -rv bin docker-hub/ 25 | cp -v *.png docker-hub/ 26 | cp -v *.plist docker-hub/ 27 | cd docker-hub/ && \ 28 | zip -r docker-hub.zip * && \ 29 | mv -v docker-hub.zip ../docker-hub.alfredworkflow 30 | 31 | #------------------------------------------------------------------------------- 32 | 33 | .PHONY: tag 34 | tag: 35 | @ if [ $$(git status -s -uall | wc -l) != 1 ]; then echo 'ERROR: Git workspace must be clean.'; exit 1; fi; 36 | 37 | @echo "This release will be tagged as: $$(cat ./VERSION)" 38 | @echo "This version should match your release. If it doesn't, re-run 'make version'." 39 | @echo "---------------------------------------------------------------------" 40 | @read -p "Press any key to continue, or press Control+C to cancel. " x; 41 | 42 | @echo " " 43 | @chag update $$(cat ./VERSION) 44 | @echo " " 45 | 46 | @echo "These are the contents of the CHANGELOG for this release. Are these correct?" 47 | @echo "---------------------------------------------------------------------" 48 | @chag contents 49 | @echo "---------------------------------------------------------------------" 50 | @echo "Are these release notes correct? If not, cancel and update CHANGELOG.md." 51 | @read -p "Press any key to continue, or press Control+C to cancel. " x; 52 | 53 | @echo " " 54 | 55 | git add . 56 | git commit -a -m "Preparing the $$(cat ./VERSION) release." 57 | chag tag --sign 58 | 59 | #------------------------------------------------------------------------------- 60 | 61 | .PHONY: version 62 | version: 63 | @echo "Current version: $$(cat ./VERSION)" 64 | @read -p "Enter new version number: " nv; \ 65 | printf "$$nv" > ./VERSION 66 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # docker-hub.alfredworkflow 2 | 3 | An Alfred PowerPack Workflow for searching Docker Hub for public Docker images. 4 | 5 | ## Usage 6 | 7 | `dockerhub {query}` — Search for an image. 8 | 9 | ### Actions 10 | 11 | `↩` — Open the module in the Docker Hub UI. 12 | `⇧/⌘Y` — Quicklook details 13 | 14 | ### Screenshots 15 | 16 | ![](README.png) 17 | ![](README2.png) 18 | ![](README3.png) 19 | ![](README4.png) 20 | 21 | **[Download!](docker-hub.alfredworkflow?raw=true)** Requires [Alfred 3 and the PowerPack](https://www.alfredapp.com/powerpack/). 22 | 23 | ## Developing/Deploying 24 | 25 | ### Golang 26 | 27 | Go (when spoken) or [Golang] (when written) is a strongly-typed language from Google that "blends the simplicity of Python with the performance of C". Static binaries can be compiled for all major platforms, and many minor ones. 28 | 29 | It is recommended that you install Golang using your system's package manager. If you don't have one (or if the version is too old), you can [install Golang from its website](https://golang.org/doc/install). Reading the [Getting Started](https://golang.org/doc/) documentation is a valuable exercise. 30 | 31 | ```bash 32 | brew update && brew install golang 33 | ``` 34 | 35 | ### Glide 36 | 37 | Golang dependencies are managed with [Glide]. You should install them before compiling this project. 38 | 39 | ```bash 40 | curl https://glide.sh/get | sh 41 | glide install 42 | ``` 43 | 44 | ### GoMetaLinter 45 | 46 | [GoMetaLinter] pulls together many popular linting tools, and can run them on a project. 47 | 48 | ```bash 49 | gometalinter.v2 --install 50 | ``` 51 | 52 | ### Developing 53 | 54 | ```bash 55 | make build 56 | bin/dockerhub "golang" 57 | ``` 58 | 59 | Make sure that you run the linter to catch any issues. 60 | 61 | ```bash 62 | make lint 63 | ``` 64 | 65 | [Glide]: https://glide.sh 66 | [Golang]: https://golang.org 67 | [GoMetaLinter]: https://github.com/alecthomas/gometalinter 68 | -------------------------------------------------------------------------------- /README.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyzyx/docker-hub.alfredworkflow/239fa4535ece1ee659ed8b3a5c8c4ddcf3c73f7a/README.png -------------------------------------------------------------------------------- /README2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyzyx/docker-hub.alfredworkflow/239fa4535ece1ee659ed8b3a5c8c4ddcf3c73f7a/README2.png -------------------------------------------------------------------------------- /README3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyzyx/docker-hub.alfredworkflow/239fa4535ece1ee659ed8b3a5c8c4ddcf3c73f7a/README3.png -------------------------------------------------------------------------------- /README4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyzyx/docker-hub.alfredworkflow/239fa4535ece1ee659ed8b3a5c8c4ddcf3c73f7a/README4.png -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | 1.0.0 -------------------------------------------------------------------------------- /docker-hub.alfredworkflow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyzyx/docker-hub.alfredworkflow/239fa4535ece1ee659ed8b3a5c8c4ddcf3c73f7a/docker-hub.alfredworkflow -------------------------------------------------------------------------------- /glide.lock: -------------------------------------------------------------------------------- 1 | hash: 84f0685dccae014c18b5b1bf064dd0b1e7d8230b24bcfd1217dde3fdf2a2b62e 2 | updated: 2019-05-26T12:18:57.583866-07:00 3 | imports: 4 | - name: github.com/davecgh/go-spew 5 | version: 8991bc29aa16c548c550c7ff78260e27b9ab7c73 6 | subpackages: 7 | - spew 8 | - name: github.com/moul/http2curl 9 | version: e4e02a27abe7e3d0352874f6c0b92581c5d5a6f7 10 | - name: github.com/parnurzeal/gorequest 11 | version: a578a48e8d6ca8b01a3b18314c43c6716bb5f5a3 12 | - name: github.com/pkg/errors 13 | version: 27936f6d90f9c8e1145f11ed52ffffbfdb9e0af7 14 | - name: golang.org/x/net 15 | version: f3200d17e092c607f615320ecaad13d87ad9a2b3 16 | subpackages: 17 | - publicsuffix 18 | - name: gopkg.in/alecthomas/gometalinter.v2 19 | version: 102ac984005d45456a7e3ae6dc94ebcd95c2bb19 20 | testImports: [] 21 | -------------------------------------------------------------------------------- /glide.yaml: -------------------------------------------------------------------------------- 1 | package: github.com/skyzyx/docker-hub.alfredworkflow 2 | import: 3 | - package: gopkg.in/alecthomas/gometalinter.v2 4 | version: ^2.0.5 5 | - package: github.com/parnurzeal/gorequest 6 | version: ~0.2.15 7 | - package: github.com/moul/http2curl 8 | - package: github.com/davecgh/go-spew 9 | version: ^1.1.0 10 | subpackages: 11 | - spew 12 | -------------------------------------------------------------------------------- /hub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyzyx/docker-hub.alfredworkflow/239fa4535ece1ee659ed8b3a5c8c4ddcf3c73f7a/hub.png -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyzyx/docker-hub.alfredworkflow/239fa4535ece1ee659ed8b3a5c8c4ddcf3c73f7a/icon.png -------------------------------------------------------------------------------- /images/docker-pixelmator-pro.pxd/QuickLook/Icon.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyzyx/docker-hub.alfredworkflow/239fa4535ece1ee659ed8b3a5c8c4ddcf3c73f7a/images/docker-pixelmator-pro.pxd/QuickLook/Icon.tiff -------------------------------------------------------------------------------- /images/docker-pixelmator-pro.pxd/QuickLook/Preview.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyzyx/docker-hub.alfredworkflow/239fa4535ece1ee659ed8b3a5c8c4ddcf3c73f7a/images/docker-pixelmator-pro.pxd/QuickLook/Preview.tiff -------------------------------------------------------------------------------- /images/docker-pixelmator-pro.pxd/QuickLook/Thumbnail.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyzyx/docker-hub.alfredworkflow/239fa4535ece1ee659ed8b3a5c8c4ddcf3c73f7a/images/docker-pixelmator-pro.pxd/QuickLook/Thumbnail.tiff -------------------------------------------------------------------------------- /images/docker-pixelmator-pro.pxd/metadata.info: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyzyx/docker-hub.alfredworkflow/239fa4535ece1ee659ed8b3a5c8c4ddcf3c73f7a/images/docker-pixelmator-pro.pxd/metadata.info -------------------------------------------------------------------------------- /images/docker.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | bundleid 6 | com.ryanparman.docker-hub 7 | category 8 | Internet 9 | connections 10 | 11 | FEBEA35B-0996-4DFB-9F9A-4049E7F5D678 12 | 13 | 14 | destinationuid 15 | BBDB1AC3-89E8-41A4-BB7F-F196DF8EE7A3 16 | modifiers 17 | 0 18 | modifiersubtext 19 | 20 | vitoclose 21 | 22 | 23 | 24 | 25 | createdby 26 | Ryan Parman 27 | description 28 | Search the Docker Hub API for Docker images. 29 | disabled 30 | 31 | name 32 | Docker Hub 33 | objects 34 | 35 | 36 | config 37 | 38 | alfredfiltersresults 39 | 40 | alfredfiltersresultsmatchmode 41 | 0 42 | argumenttrimmode 43 | 0 44 | argumenttype 45 | 0 46 | escaping 47 | 63 48 | keyword 49 | hub 50 | queuedelaycustom 51 | 3 52 | queuedelayimmediatelyinitially 53 | 54 | queuedelaymode 55 | 0 56 | queuemode 57 | 1 58 | runningsubtext 59 | Retrieving search suggestions… 60 | script 61 | bin/dockerhub "{query}" 62 | 63 | scriptargtype 64 | 0 65 | scriptfile 66 | 67 | subtext 68 | Search Docker Hub for "{query}"… 69 | title 70 | Docker Hub 71 | type 72 | 0 73 | withspace 74 | 75 | 76 | type 77 | alfred.workflow.input.scriptfilter 78 | uid 79 | FEBEA35B-0996-4DFB-9F9A-4049E7F5D678 80 | version 81 | 2 82 | 83 | 84 | config 85 | 86 | browser 87 | 88 | spaces 89 | 90 | url 91 | {query} 92 | utf8 93 | 94 | 95 | type 96 | alfred.workflow.action.openurl 97 | uid 98 | BBDB1AC3-89E8-41A4-BB7F-F196DF8EE7A3 99 | version 100 | 1 101 | 102 | 103 | readme 104 | README 105 | uidata 106 | 107 | BBDB1AC3-89E8-41A4-BB7F-F196DF8EE7A3 108 | 109 | xpos 110 | 300 111 | ypos 112 | 140 113 | 114 | FEBEA35B-0996-4DFB-9F9A-4049E7F5D678 115 | 116 | xpos 117 | 150 118 | ypos 119 | 140 120 | 121 | 122 | webaddress 123 | https://ryanparman.com 124 | 125 | 126 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 Ryan Parman 2 | // Copyright (c) 2019 Contributors 3 | // 4 | // https://www.alfredapp.com/help/workflows/inputs/script-filter/json/ 5 | 6 | package main 7 | 8 | import ( 9 | "encoding/json" 10 | "fmt" 11 | "net/url" 12 | "os" 13 | 14 | // "github.com/davecgh/go-spew/spew" 15 | "github.com/parnurzeal/gorequest" 16 | ) 17 | 18 | var ( 19 | doc InputDocument 20 | querystring string 21 | ) 22 | 23 | type InputDocument struct { 24 | Count int64 `json:"count"` 25 | Next string `json:"next"` 26 | Previous string `json:"previous"` 27 | Results []InputResult `json:"results"` 28 | } 29 | 30 | type InputResult struct { 31 | RepoName string `json:"repo_name"` 32 | ShortDescription string `json:"short_description"` 33 | StarCount int64 `json:"star_count"` 34 | PullCount int64 `json:"pull_count"` 35 | RepoOwner string `json:"repo_owner"` 36 | IsAutomated bool `json:"is_automated"` 37 | IsOfficial bool `json:"is_official"` 38 | } 39 | 40 | type AlfredDocument struct { 41 | Items []AlfredItem `json:"items,omitempty"` 42 | } 43 | 44 | type AlfredItem struct { 45 | // Simple objects 46 | Arg string `json:"arg,omitempty"` 47 | Autocomplete string `json:"autocomplete,omitempty"` 48 | Match string `json:"match,omitempty"` 49 | QuicklookUrl string `json:"quicklookurl,omitempty"` 50 | Subtitle string `json:"subtitle,omitempty"` 51 | Title string `json:"title,omitempty"` 52 | Type string `json:"type,omitempty"` 53 | UID string `json:"uid,omitempty"` 54 | Valid bool `json:"valid,omitempty"` 55 | 56 | // Complex objects 57 | Icon AlfredIcon `json:"icon,omitempty"` 58 | Mods AlfredModifierKeys `json:"mods,omitempty"` 59 | Text AlfredText `json:"text,omitempty"` 60 | } 61 | 62 | type AlfredIcon struct { 63 | Path string `json:"path,omitempty"` 64 | Type string `json:"type,omitempty"` 65 | } 66 | 67 | type AlfredText struct { 68 | Copy string `json:"copy,omitempty"` 69 | LargeType string `json:"largetype,omitempty"` 70 | } 71 | 72 | type AlfredModifierKeys struct { 73 | Alt AlfredModifierKey `json:"alt,omitempty"` 74 | Command AlfredModifierKey `json:"cmd,omitempty"` 75 | } 76 | 77 | type AlfredModifierKey struct { 78 | Arg string `json:"arg,omitempty"` 79 | Subtitle string `json:"subtitle,omitempty"` 80 | QuicklookUrl string `json:"quicklookurl,omitempty"` 81 | Valid bool `json:"valid,omitempty"` 82 | } 83 | 84 | // The core function 85 | func main() { 86 | alfred := new(AlfredDocument) 87 | querystring = url.QueryEscape(os.Args[1]) 88 | 89 | _, body, _ := gorequest.New().Get("https://hub.docker.com/v2/search/repositories?query=" + querystring).End() 90 | err := json.Unmarshal([]byte(body), &doc) 91 | 92 | if err != nil { 93 | fmt.Println(err) 94 | os.Exit(1) 95 | } 96 | 97 | // spew.Dump(doc) 98 | 99 | // No results 100 | if doc.Count == 0 { 101 | alfred.Items = append(alfred.Items, AlfredItem{ 102 | Title: "No results found.", 103 | Valid: false, 104 | Type: "default", 105 | Icon: AlfredIcon{ 106 | Path: "hub.png", 107 | }, 108 | }) 109 | } 110 | 111 | // Results 112 | for _, result := range doc.Results { 113 | regUrl := fmt.Sprintf( 114 | "https://hub.docker.com/%s", 115 | map[bool]string{ 116 | true: fmt.Sprintf("_/%s", result.RepoName), 117 | false: fmt.Sprintf("r/%s", result.RepoName), 118 | }[result.IsOfficial], 119 | ) 120 | 121 | alfred.Items = append(alfred.Items, AlfredItem{ 122 | UID: result.RepoName, 123 | Title: result.RepoName, 124 | Subtitle: result.ShortDescription, 125 | Arg: regUrl, 126 | QuicklookUrl: regUrl, 127 | Valid: true, 128 | Type: "default", 129 | // Autocomplete string `json:"autocomplete,omitempty"` 130 | // Match string `json:"match,omitempty"` 131 | Icon: AlfredIcon{ 132 | // Type: "fileicon", 133 | Path: map[bool]string{true: "verified.png", false: "not-verified.png"}[result.IsOfficial], 134 | }, 135 | Text: AlfredText{ 136 | Copy: result.RepoName, 137 | LargeType: result.RepoName, 138 | }, 139 | Mods: AlfredModifierKeys{ 140 | Alt: AlfredModifierKey{ 141 | Arg: regUrl, 142 | Subtitle: fmt.Sprintf( 143 | "%d %s • %d %s • %s", 144 | result.StarCount, 145 | map[bool]string{true: "star", false: "stars"}[result.StarCount == 1], 146 | result.PullCount, 147 | map[bool]string{true: "pull", false: "pulls"}[result.PullCount == 1], 148 | map[bool]string{true: "Automated", false: "Not Automated"}[result.IsAutomated], 149 | ), 150 | QuicklookUrl: regUrl, 151 | Valid: true, 152 | }, 153 | }, 154 | }) 155 | } 156 | 157 | // output, err := json.Marshal(alfred) 158 | output, err := json.MarshalIndent(alfred, "", " ") 159 | 160 | if err != nil { 161 | fmt.Println(err) 162 | os.Exit(1) 163 | } 164 | 165 | fmt.Println(string(output)) 166 | } 167 | -------------------------------------------------------------------------------- /not-verified.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyzyx/docker-hub.alfredworkflow/239fa4535ece1ee659ed8b3a5c8c4ddcf3c73f7a/not-verified.png -------------------------------------------------------------------------------- /verified.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyzyx/docker-hub.alfredworkflow/239fa4535ece1ee659ed8b3a5c8c4ddcf3c73f7a/verified.png --------------------------------------------------------------------------------