// Get implemented Get method for HomeRouter. func (this *HomeRouter) Get() { // Get argument(s). q := strings.TrimRight( strings.TrimSpace(this.Input().Get("q")), "/") if path, ok := utils.IsBrowseURL(q); ok { q = path } // Get pure URL. reqUrl := this.Ctx.Request.RequestURI[1:] if i := strings.Index(reqUrl, "?"); i > -1 { reqUrl = reqUrl[:i] if path, ok := utils.IsBrowseURL(reqUrl); ok { reqUrl = path } } // Redirect to query string. if len(reqUrl) == 0 && len(q) > 0 { reqUrl = q this.Redirect("/"+reqUrl, 302) return } // User History. urpids, _ := this.Ctx.Request.Cookie("UserHistory") urpts, _ := this.Ctx.Request.Cookie("UHTimestamps") if len(reqUrl) == 0 && len(q) == 0 { serveHome(this, urpids, urpts) return } // Documentation page. broPath := reqUrl // Browse path. // Check if it's the standard library. if utils.IsGoRepoPath(broPath) { broPath = "code.google.com/p/go/source/browse/src/pkg/" + broPath } else if utils.IsGoSubrepoPath(broPath) { this.Redirect("/code.google.com/p/"+broPath, 301) return } else if strings.Index(broPath, "source/browse/") > -1 { broPath = strings.Replace(broPath, "source/browse/", "", 1) } // Check if it's a remote path that can be used for 'go get', if not means it's a keyword. if !utils.IsValidRemotePath(broPath) { // Search. this.Redirect("/search?q="+reqUrl, 302) return } // Get tag field. tag := strings.TrimSpace(this.Input().Get("tag")) if tag == "master" || tag == "default" { tag = "" } // Check documentation of current import path, update automatically as needed. pdoc, err := doc.CheckDoc(reqUrl, tag, doc.RT_Human) if err == nil { // errNoMatch leads to pdoc == nil. if pdoc != nil { // Generate documentation page. if generatePage(this, pdoc, broPath, tag) { ps, ts := updateCacheInfo(pdoc, urpids, urpts) this.Ctx.SetCookie("UserHistory", ps, 9999999999, "/") this.Ctx.SetCookie("UHTimestamps", ts, 9999999999, "/") return } } this.Redirect("/search?q="+reqUrl, 302) return } // Error. this.Data["IsHasError"] = true this.Data["ErrMsg"] = strings.Replace(err.Error(), doc.GetGithubCredentials(), "<githubCred>", 1) if !strings.Contains(err.Error(), "Cannot find Go files") { beego.Error("HomeRouter.Get ->", err) } serveHome(this, urpids, urpts) }
func getGoogleDoc(client *http.Client, match map[string]string, tag, ptag string) (*hv.Package, error) { setupGoogleMatch(match) if m := googleEtagRe.FindStringSubmatch(ptag); m != nil { match["vcs"] = m[1] } else if err := getGoogleVCS(match); err != nil { return nil, err } match["tag"] = tag // Scrape the repo browser to find the project revision and individual Go files. stdout, _, err := com.ExecCmd("curl", com.Expand("http://{subrepo}{dot}{repo}.googlecode.com/{vcs}{dir}/?r={tag}", match)) if err != nil { return nil, errors.New("doc.getGoogleDoc(" + match["importPath"] + ") -> " + err.Error()) } p := []byte(stdout) // Check revision tag. var etag string if m := googleRevisionRe.FindSubmatch(p); m == nil { return nil, errors.New("doc.getGoogleDoc(" + match["importPath"] + ") -> Could not find revision") } else { etag = string(m[1]) if etag == ptag { return nil, errNotModified } } match["browserUrlTpl"] = "code.google.com/p/{repo}/source/browse{dir}/{0}?repo={subrepo}&r={tag}" match["rawSrcUrlTpl"] = "http://{subrepo}{dot}{repo}.googlecode.com/{vcs}{dir}/{0}?r={tag}" var isGoPro bool var files []com.RawFile var dirs []string // Unrecord and non-SVN project can download archive. if len(ptag) == 0 || match["vcs"] == "svn" { tmpTag := match["tag"] if len(tmpTag) == 0 { tmpTag = defaultTags[match["vcs"]] } isGoPro, _, files, dirs, err = getRepoByArchive(match, com.Expand("http://{subrepo}{dot}{repo}.googlecode.com/archive/{0}.zip", match, tmpTag)) if err != nil { return nil, errors.New("doc.getGoogleDoc(" + match["importPath"] + ") -> Fail to download archive: " + err.Error()) } } else { // Get source file data. ms := googleFileRe.FindAllSubmatch(p, -1) files = make([]com.RawFile, 0, len(ms)) for _, m := range ms { fname := strings.Split(string(m[1]), "?")[0] if utils.IsDocFile(fname) { isGoPro = true files = append(files, &hv.Source{ SrcName: fname, BrowseUrl: com.Expand(match["browserUrlTpl"], match, fname), RawSrcUrl: com.Expand(match["rawSrcUrlTpl"], match, fname), }) } } // Get subdirectories. ms = googleDirRe.FindAllSubmatch(p, -1) dirs = make([]string, 0, len(ms)) for _, m := range ms { dirName := strings.Split(string(m[1]), "?")[0] // Make sure we get directories. if strings.HasSuffix(dirName, "/") && utils.FilterDirName(dirName) { dirs = append(dirs, strings.Replace(dirName, "/", "", -1)) } } } if !isGoPro { return nil, com.NotFoundError{"Cannot find Go files, it's not a Go project."} } if len(files) == 0 && len(dirs) == 0 { return nil, com.NotFoundError{"Directory tree does not contain Go files and subdirs."} } // Fetch file from VCS. if err := fetchGoogleFiles(client, files); err != nil { return nil, err } // Get all tags. tags := getGoogleTags(match["importPath"], defaultTags[match["vcs"]], false) // Start generating data. w := &hv.Walker{ LineFmt: "#%d", Pdoc: &hv.Package{ PkgInfo: &hv.PkgInfo{ ImportPath: match["importPath"], IsGoSubrepo: utils.IsGoSubrepoPath(strings.TrimPrefix( match["importPath"], "code.google.com/p/")), ProjectName: com.Expand("{repo}{dot}{subrepo}", match), ProjectPath: com.Expand("code.google.com/p/{repo}/source/browse/?repo={subrepo}&r={tag}", match), ViewDirPath: com.Expand("code.google.com/p/{repo}/source/browse{dir}?repo={subrepo}&r={tag}", match), Tags: strings.Join(tags, "|||"), Ptag: etag, Vcs: "Google Code", }, PkgDecl: &hv.PkgDecl{ Tag: tag, Dirs: dirs, }, }, } srcs := make([]*hv.Source, 0, len(files)) srcMap := make(map[string]*hv.Source) for _, f := range files { s, _ := f.(*hv.Source) srcs = append(srcs, s) if len(tag) == 0 && (w.Pdoc.IsGoSubrepo || w.Pdoc.IsCmd) && !strings.HasSuffix(f.Name(), "_test.go") { srcMap[f.Name()] = s } } pdoc, err := w.Build(&hv.WalkRes{ WalkDepth: hv.WD_All, WalkType: hv.WT_Memory, WalkMode: hv.WM_All, Srcs: srcs, }) if err != nil { return nil, errors.New("doc.getGoogleDoc(" + match["importPath"] + ") -> Fail to build: " + err.Error()) } if len(tag) == 0 && (w.Pdoc.IsGoSubrepo || w.Pdoc.IsCmd) { err = generateHv(match["importPath"], srcMap) } return pdoc, err }