Stable APIs for Go. https://go.code.as
Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

page.go 7.0 KiB

há 10 anos
há 10 anos
há 10 anos
há 10 anos
há 10 anos
há 10 anos
há 10 anos
há 10 anos
há 10 anos
há 10 anos
há 10 anos
há 10 anos
há 10 anos
há 10 anos
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "html/template"
  6. "log"
  7. "net/http"
  8. "net/url"
  9. "os"
  10. "sort"
  11. "strings"
  12. )
  13. const packageTemplateString = `<!DOCTYPE html>
  14. <html >
  15. <head>
  16. <meta charset="utf-8">
  17. <title>{{.Repo.PackageName}}.{{.Repo.MajorVersion}}{{.Repo.SubPath}} - {{.Repo.GopkgPath}}</title>
  18. <link href='//fonts.googleapis.com/css?family=Ubuntu+Mono|Ubuntu' rel='stylesheet' >
  19. <link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet" >
  20. <link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet" >
  21. <style>
  22. html,
  23. body {
  24. height: 100%;
  25. }
  26. @media (min-width: 1200px) {
  27. .container {
  28. width: 970px;
  29. }
  30. }
  31. body {
  32. font-family: 'Ubuntu', sans-serif;
  33. }
  34. pre {
  35. font-family: 'Ubuntu Mono', sans-serif;
  36. }
  37. .main {
  38. padding-top: 20px;
  39. }
  40. .buttons a {
  41. width: 100%;
  42. text-align: left;
  43. margin-bottom: 5px;
  44. }
  45. .getting-started div {
  46. padding-top: 12px;
  47. }
  48. .getting-started p, .synopsis p {
  49. font-size: 1.3em;
  50. }
  51. .getting-started pre {
  52. font-size: 15px;
  53. }
  54. .versions {
  55. font-size: 1.3em;
  56. }
  57. .versions div {
  58. padding-top: 5px;
  59. }
  60. .versions a {
  61. font-weight: bold;
  62. }
  63. .versions a.current {
  64. color: black;
  65. font-decoration: none;
  66. }
  67. /* wrapper for page content to push down footer */
  68. #wrap {
  69. min-height: 100%;
  70. height: auto !important;
  71. height: 100%;
  72. /* negative indent footer by it's height */
  73. margin: 0 auto -40px;
  74. }
  75. /* footer styling */
  76. #footer {
  77. height: 40px;
  78. background-color: #eee;
  79. padding-top: 8px;
  80. text-align: center;
  81. }
  82. /* footer fixes for mobile devices */
  83. @media (max-width: 767px) {
  84. #footer {
  85. margin-left: -20px;
  86. margin-right: -20px;
  87. padding-left: 20px;
  88. padding-right: 20px;
  89. }
  90. }
  91. </style>
  92. </head>
  93. <body>
  94. <script type="text/javascript">
  95. // If there's a URL fragment, assume it's an attempt to read a specific documentation entry.
  96. if (window.location.hash.length > 1) {
  97. window.location = "http://godoc.org/{{.Repo.GopkgPath}}" + window.location.hash;
  98. }
  99. </script>
  100. <div id="wrap" >
  101. <div class="container" >
  102. <div class="row" >
  103. <div class="col-sm-12" >
  104. <div class="page-header">
  105. <h1>{{.Repo.GopkgPath}}</h1>
  106. {{.Synopsis}}
  107. </div>
  108. </div>
  109. </div>
  110. <div class="row" >
  111. <div class="col-sm-12" >
  112. <a class="btn btn-lg btn-info" href="https://{{.Repo.GitHubRoot}}/tree/{{if .Repo.AllVersions}}{{.FullVersion}}{{else}}master{{end}}{{.Repo.SubPath}}" ><i class="fa fa-github"></i> Source Code</a>
  113. <a class="btn btn-lg btn-info" href="http://godoc.org/{{.Repo.GopkgPath}}" ><i class="fa fa-info-circle"></i> API Documentation</a>
  114. </div>
  115. </div>
  116. <div class="row main" >
  117. <div class="col-sm-8 info" >
  118. <div class="getting-started" >
  119. <h2>Getting started</h2>
  120. <div>
  121. <p>To get the package, execute:</p>
  122. <pre>go get {{.Repo.GopkgPath}}</pre>
  123. </div>
  124. <div>
  125. <p>To import this package, add the following line to your code:</p>
  126. <pre>import "{{.Repo.GopkgPath}}"</pre>
  127. {{if .CleanPackageName}}<p>Refer to it as <i>{{.CleanPackageName}}</i>.{{end}}
  128. </div>
  129. <div>
  130. <p>For more details, see the API documentation.</p>
  131. </div>
  132. </div>
  133. </div>
  134. <div class="col-sm-3 col-sm-offset-1 versions" >
  135. <h2>Versions</h2>
  136. {{ if .LatestVersions }}
  137. {{ range .LatestVersions }}
  138. <div>
  139. <a href="//{{gopkgVersionRoot $.Repo .}}{{$.Repo.SubPath}}" {{if eq .Major $.Repo.MajorVersion.Major}}class="current"{{end}} >v{{.Major}}</a>
  140. &rarr;
  141. <span class="label label-default">{{.}}</span>
  142. </div>
  143. {{ end }}
  144. {{ else }}
  145. <div>
  146. <a href="//{{$.Repo.GopkgPath}}" class="current">v0</a>
  147. &rarr;
  148. <span class="label label-default">master</span>
  149. </div>
  150. {{ end }}
  151. </div>
  152. </div>
  153. </div>
  154. </div>
  155. <div id="footer">
  156. <div class="container">
  157. <div class="row">
  158. <div class="col-sm-12">
  159. <p class="text-muted credit"><a href="https://gopkg.in">gopkg.in<a></p>
  160. </div>
  161. </div>
  162. </div>
  163. </div>
  164. <!--<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>-->
  165. <!--<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>-->
  166. </body>
  167. </html>`
  168. var packageTemplate *template.Template
  169. func gopkgVersionRoot(repo *Repo, version Version) string {
  170. return repo.GopkgVersionRoot(version)
  171. }
  172. var packageFuncs = template.FuncMap{
  173. "gopkgVersionRoot": gopkgVersionRoot,
  174. }
  175. func init() {
  176. var err error
  177. packageTemplate, err = template.New("page").Funcs(packageFuncs).Parse(packageTemplateString)
  178. if err != nil {
  179. fmt.Fprintf(os.Stderr, "fatal: parsing package template failed: %s\n", err)
  180. os.Exit(1)
  181. }
  182. }
  183. type packageData struct {
  184. Repo *Repo
  185. LatestVersions VersionList // Contains only the latest version for each major
  186. FullVersion Version // Version that the major requested resolves to
  187. CleanPackageName string
  188. Synopsis string
  189. }
  190. type gddoApiSynopsisResult struct {
  191. Results []struct {
  192. Path string `json:"path"`
  193. Synopsis string `json:"synopsis"`
  194. } `json:"results"`
  195. }
  196. func renderPackagePage(resp http.ResponseWriter, req *http.Request, repo *Repo) {
  197. data := &packageData{
  198. Repo: repo,
  199. }
  200. // calculate version mapping
  201. latestVersionsMap := make(map[int]Version)
  202. for _, v := range repo.AllVersions {
  203. v2, exists := latestVersionsMap[v.Major]
  204. if !exists || v2.Less(v) {
  205. latestVersionsMap[v.Major] = v
  206. }
  207. }
  208. data.FullVersion = latestVersionsMap[repo.MajorVersion.Major]
  209. data.LatestVersions = make(VersionList, 0, len(latestVersionsMap))
  210. for _, v := range latestVersionsMap {
  211. data.LatestVersions = append(data.LatestVersions, v)
  212. }
  213. sort.Sort(sort.Reverse(data.LatestVersions))
  214. // find clean package name
  215. data.CleanPackageName = repo.PackageName
  216. if strings.HasPrefix(data.CleanPackageName, "go-") {
  217. data.CleanPackageName = data.CleanPackageName[3:]
  218. }
  219. if strings.HasSuffix(data.CleanPackageName, "-go") {
  220. data.CleanPackageName = data.CleanPackageName[:len(data.CleanPackageName)-3]
  221. }
  222. for i, c := range data.CleanPackageName {
  223. if c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' {
  224. continue
  225. }
  226. if i > 0 && (c == '_' || c >= '0' && c <= '9') {
  227. continue
  228. }
  229. data.CleanPackageName = ""
  230. break
  231. }
  232. // retrieve synopsis
  233. str := `http://api.godoc.org/search?q=` + url.QueryEscape(repo.GopkgPath())
  234. fmt.Println(str)
  235. gddoResp, err := http.Get(str)
  236. if err == nil {
  237. synopsisResult := &gddoApiSynopsisResult{}
  238. err = json.NewDecoder(gddoResp.Body).Decode(&synopsisResult)
  239. gddoResp.Body.Close()
  240. if err == nil {
  241. for _, apiPkg := range synopsisResult.Results {
  242. if apiPkg.Path == repo.GopkgPath() {
  243. data.Synopsis = apiPkg.Synopsis
  244. break
  245. }
  246. }
  247. }
  248. }
  249. err = packageTemplate.Execute(resp, data)
  250. if err != nil {
  251. log.Printf("error executing tmplPackage: %s\n", err)
  252. }
  253. }