Skip to content

Instantly share code, notes, and snippets.

Created January 5, 2018 02:39
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/22a76c1d02c3785b0d3989c9d38f0351 to your computer and use it in GitHub Desktop.
Save anonymous/22a76c1d02c3785b0d3989c9d38f0351 to your computer and use it in GitHub Desktop.
Gitlab Available Two-Character Names Script
// This code is published under GNU GPL v3+. For more information, visit http://www.gnu.org/licenses/gpl.html
package main
import (
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"os"
"sync"
"time"
)
const (
url = "https://gitlab.com/users/"
)
var (
chars = []string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"} //Used to generate character from number
)
// GitlabResp is meant for unmarshalling a JSON response from the GitLab users
// API.
type GitlabResp struct {
Exists bool
}
func main() {
count, total := 0, len(chars)*len(chars)
// Open file to output usernames.
f, _ := os.Create("/tmp/usernm.txt")
defer f.Close()
// Limit ourselves to four API calls a second.
throttle := time.Tick(250 * time.Millisecond)
availChan, done := make(chan string), make(chan struct{})
// Have a routine for listening to available names coming in, and write them
// to our file.
go func() {
for {
name, ok := <-availChan
if !ok {
break
}
if _, err := io.WriteString(f, name+"\n"); err != nil {
log.Println("Failed to write %q to file", name)
}
}
close(done)
}()
var wg sync.WaitGroup
for _, c1 := range chars {
for _, c2 := range chars {
wg.Add(1)
go func(u string) {
defer wg.Done()
// Rate-limit ourselves, to be courteous.
<-throttle
av, err := usernameAvailable(u)
if err != nil {
log.Printf("Failed to get availability from Gitlab: %v", err)
return
}
if av {
count++
availChan <- u
} else {
log.Printf("%q is not available", u)
}
}(c1 + c2)
}
}
// Wait until we check all of the names.
wg.Wait()
// Signal our file-writer that we're done sending names.
close(availChan)
// Wait until our file-writer is done.
<-done
fmt.Println("Total:", total, "Available:", count)
}
func usernameAvailable(u string) (bool, error) {
// Call to Gitlab API to check for user.
resp, err := http.Get(url + u + "/exists")
if err != nil {
return false, err
}
defer resp.Body.Close()
var gr GitlabResp
if err := json.NewDecoder(resp.Body).Decode(&gr); err != nil {
return false, err
}
return !gr.Exists, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment