Last active
May 29, 2017 09:50
-
-
Save aclisp/e2c67622a9bdf6aaabf6d5c99ed1cca5 to your computer and use it in GitHub Desktop.
A golang app that list svn dirs...
This file contains 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
package main | |
import ( | |
"encoding/json" | |
"encoding/xml" | |
"fmt" | |
"net/http" | |
"strings" | |
) | |
const ( | |
svnServerAddr = "https://svn.xxxxxx.com" | |
svnUsername = "xxxxxx" | |
svnPassword = "xxxxxx" | |
) | |
var ( | |
client = &http.Client{} | |
) | |
// HTMLList is the container of svn returned items. | |
type HTMLList struct { | |
Items []string `xml:"body>ul>li>a"` | |
} | |
// DirList is the container of items for API | |
type DirList struct { | |
Path string | |
Items []string | |
} | |
// FileAttr is the container of file attributes for API | |
type FileAttr struct { | |
Path string | |
Exist bool | |
} | |
func getSVNContent(svnURL string) (*HTMLList, error) { | |
req, err := http.NewRequest("GET", svnURL, nil) | |
if err != nil { | |
return nil, fmt.Errorf("Couldn't create new http request: %v", err) | |
} | |
req.SetBasicAuth(svnUsername, svnPassword) | |
resp, err := client.Do(req) | |
if err != nil { | |
return nil, fmt.Errorf("Couldn't get svn path: %v", err) | |
} | |
defer resp.Body.Close() | |
// Parse html returned from svn. | |
decoder := xml.NewDecoder(resp.Body) | |
items := &HTMLList{} | |
err = decoder.Decode(items) | |
if err != nil { | |
return nil, fmt.Errorf("Couldn't parse svn resp body: %v", err) | |
} | |
return items, nil | |
} | |
func listDir(svnURL string) (string, error) { | |
items, err := getSVNContent(svnURL) | |
if err != nil { | |
return "", fmt.Errorf("Couldn't get svn content: %v", err) | |
} | |
// Filter non-dir items. | |
dirs := DirList{ | |
Path: svnURL, | |
} | |
for _, v := range items.Items { | |
if len(v) > 0 && v[0] != '.' && v[len(v)-1:] == "/" { | |
v = v[:len(v)-1] // Remove the last '/' | |
dirs.Items = append(dirs.Items, v) | |
} | |
} | |
// Encode result. | |
result, err := json.MarshalIndent(dirs, "", " ") | |
if err != nil { | |
return "", fmt.Errorf("Couldn't marshal result: %v", err) | |
} | |
return string(result), nil | |
} | |
func queryFile(svnURL string) (string, error) { | |
i := strings.LastIndex(svnURL, "/") | |
d := svnURL[:i+1] | |
f := svnURL[i+1:] | |
items, err := getSVNContent(d) | |
if err != nil { | |
return "", fmt.Errorf("Couldn't get svn content: %v", err) | |
} | |
attr := FileAttr{ | |
Path: svnURL, | |
} | |
for _, v := range items.Items { | |
if strings.EqualFold(f, v) { | |
attr.Exist = true | |
attr.Path = d + v | |
break | |
} | |
} | |
result, err := json.MarshalIndent(attr, "", " ") | |
if err != nil { | |
return "", fmt.Errorf("Couldn't marshal result: %v", err) | |
} | |
return string(result), nil | |
} | |
func handler(w http.ResponseWriter, r *http.Request) { | |
// allow cross domain AJAX requests | |
w.Header().Set("Access-Control-Allow-Origin", "*") | |
w.Header().Set("Content-Type", "application/json;charset=UTF-8") | |
svnPath := r.URL.Path | |
var result string | |
var err error | |
if svnPath[len(svnPath)-1:] == "/" { | |
result, err = listDir(svnServerAddr + svnPath) | |
} else { | |
result, err = queryFile(svnServerAddr + svnPath) | |
} | |
if err != nil { | |
http.Error(w, fmt.Sprintf("ERROR: %v", err), http.StatusInternalServerError) | |
return | |
} | |
fmt.Fprintf(w, "%s\n", result) | |
} | |
func main() { | |
http.HandleFunc("/", handler) | |
http.ListenAndServe(":8070", nil) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment