Created
January 5, 2018 02:39
-
-
Save anonymous/22a76c1d02c3785b0d3989c9d38f0351 to your computer and use it in GitHub Desktop.
Gitlab Available Two-Character Names Script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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