GoPLS Viewer

Home|gopls/cmd/present/dir.go
1// Copyright 2012 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package main
6
7import (
8    "html/template"
9    "io"
10    "log"
11    "net"
12    "net/http"
13    "os"
14    "path/filepath"
15    "sort"
16    "strings"
17
18    "golang.org/x/tools/present"
19)
20
21func init() {
22    http.HandleFunc("/"dirHandler)
23}
24
25// dirHandler serves a directory listing for the requested path, rooted at *contentPath.
26func dirHandler(w http.ResponseWriterr *http.Request) {
27    if r.URL.Path == "/favicon.ico" {
28        http.NotFound(wr)
29        return
30    }
31    name := filepath.Join(*contentPathr.URL.Path)
32    if isDoc(name) {
33        err := renderDoc(wname)
34        if err != nil {
35            log.Println(err)
36            http.Error(werr.Error(), http.StatusInternalServerError)
37        }
38        return
39    }
40    if isDirerr := dirList(wname); err != nil {
41        addr_e := net.SplitHostPort(r.RemoteAddr)
42        if e != nil {
43            addr = r.RemoteAddr
44        }
45        log.Printf("request from %s: %s"addrerr)
46        http.Error(werr.Error(), http.StatusInternalServerError)
47        return
48    } else if isDir {
49        return
50    }
51    http.FileServer(http.Dir(*contentPath)).ServeHTTP(wr)
52}
53
54func isDoc(path stringbool {
55    _ok := contentTemplate[filepath.Ext(path)]
56    return ok
57}
58
59var (
60    // dirListTemplate holds the front page template.
61    dirListTemplate *template.Template
62
63    // contentTemplate maps the presentable file extensions to the
64    // template to be executed.
65    contentTemplate map[string]*template.Template
66)
67
68func initTemplates(base stringerror {
69    // Locate the template file.
70    actionTmpl := filepath.Join(base"templates/action.tmpl")
71
72    contentTemplate = make(map[string]*template.Template)
73
74    for extcontentTmpl := range map[string]string{
75        ".slide":   "slides.tmpl",
76        ".article""article.tmpl",
77    } {
78        contentTmpl = filepath.Join(base"templates"contentTmpl)
79
80        // Read and parse the input.
81        tmpl := present.Template()
82        tmpl = tmpl.Funcs(template.FuncMap{"playable"playable})
83        if _err := tmpl.ParseFiles(actionTmplcontentTmpl); err != nil {
84            return err
85        }
86        contentTemplate[ext] = tmpl
87    }
88
89    var err error
90    dirListTemplateerr = template.ParseFiles(filepath.Join(base"templates/dir.tmpl"))
91    return err
92}
93
94// renderDoc reads the present file, gets its template representation,
95// and executes the template, sending output to w.
96func renderDoc(w io.WriterdocFile stringerror {
97    // Read the input and build the doc structure.
98    docerr := parse(docFile0)
99    if err != nil {
100        return err
101    }
102
103    // Find which template should be executed.
104    tmpl := contentTemplate[filepath.Ext(docFile)]
105
106    // Execute the template.
107    return doc.Render(wtmpl)
108}
109
110func parse(name stringmode present.ParseMode) (*present.Docerror) {
111    ferr := os.Open(name)
112    if err != nil {
113        return nilerr
114    }
115    defer f.Close()
116    return present.Parse(fnamemode)
117}
118
119// dirList scans the given path and writes a directory listing to w.
120// It parses the first part of each .slide file it encounters to display the
121// presentation title in the listing.
122// If the given path is not a directory, it returns (isDir == false, err == nil)
123// and writes nothing to w.
124func dirList(w io.Writername string) (isDir boolerr error) {
125    ferr := os.Open(name)
126    if err != nil {
127        return falseerr
128    }
129    defer f.Close()
130    fierr := f.Stat()
131    if err != nil {
132        return falseerr
133    }
134    if isDir = fi.IsDir(); !isDir {
135        return falsenil
136    }
137    fiserr := f.Readdir(0)
138    if err != nil {
139        return falseerr
140    }
141    strippedPath := strings.TrimPrefix(namefilepath.Clean(*contentPath))
142    strippedPath = strings.TrimPrefix(strippedPath"/")
143    d := &dirListData{PathstrippedPath}
144    for _fi := range fis {
145        // skip the golang.org directory
146        if name == "." && fi.Name() == "golang.org" {
147            continue
148        }
149        e := dirEntry{
150            Namefi.Name(),
151            Pathfilepath.ToSlash(filepath.Join(strippedPathfi.Name())),
152        }
153        if fi.IsDir() && showDir(e.Name) {
154            d.Dirs = append(d.Dirse)
155            continue
156        }
157        if isDoc(e.Name) {
158            fn := filepath.ToSlash(filepath.Join(namefi.Name()))
159            if perr := parse(fnpresent.TitlesOnly); err != nil {
160                log.Printf("parse(%q, present.TitlesOnly): %v"fnerr)
161            } else {
162                e.Title = p.Title
163            }
164            switch filepath.Ext(e.Path) {
165            case ".article":
166                d.Articles = append(d.Articlese)
167            case ".slide":
168                d.Slides = append(d.Slidese)
169            }
170        } else if showFile(e.Name) {
171            d.Other = append(d.Othere)
172        }
173    }
174    if d.Path == "." {
175        d.Path = ""
176    }
177    sort.Sort(d.Dirs)
178    sort.Sort(d.Slides)
179    sort.Sort(d.Articles)
180    sort.Sort(d.Other)
181    return truedirListTemplate.Execute(wd)
182}
183
184// showFile reports whether the given file should be displayed in the list.
185func showFile(n stringbool {
186    switch filepath.Ext(n) {
187    case ".pdf":
188    case ".html":
189    case ".go":
190    default:
191        return isDoc(n)
192    }
193    return true
194}
195
196// showDir reports whether the given directory should be displayed in the list.
197func showDir(n stringbool {
198    if len(n) > 0 && (n[0] == '.' || n[0] == '_') || n == "present" {
199        return false
200    }
201    return true
202}
203
204type dirListData struct {
205    Path                          string
206    DirsSlidesArticlesOther dirEntrySlice
207}
208
209type dirEntry struct {
210    NamePathTitle string
211}
212
213type dirEntrySlice []dirEntry
214
215func (s dirEntrySliceLen() int           { return len(s) }
216func (s dirEntrySliceSwap(ij int)      { s[i], s[j] = s[j], s[i] }
217func (s dirEntrySliceLess(ij intbool { return s[i].Name < s[j].Name }
218
MembersX
dirEntrySlice.Swap
strings
dirHandler.BlockStmt.err
renderDoc.docFile
renderDoc.doc
dirEntrySlice.Less.i
template
dirHandler.isDir
isDoc.path
dirList.isDir
dirList.strippedPath
showFile.n
log
renderDoc.err
dirList.name
dirEntrySlice.Swap.j
dirHandler.name
parse
dirListData
init
dirHandler.BlockStmt._
dirEntry.Name
initTemplates.RangeStmt_1651.BlockStmt.err
dirList.RangeStmt_3604.BlockStmt.BlockStmt.fn
dirEntrySlice.Len.s
dirEntrySlice.Less.j
dirHandler.err
initTemplates.actionTmpl
initTemplates.RangeStmt_1651.BlockStmt.tmpl
dirListTemplate
parse.mode
dirListData.Slides
showDir.n
dirEntry
dirList.fi
dirList.d
showDir
dirListData.Path
dirListData.Dirs
dirEntry.Title
dirHandler.w
dirList.RangeStmt_3604.BlockStmt.BlockStmt.err
showFile
dirList.err
dirList.fis
dirList.RangeStmt_3604.fi
dirList.RangeStmt_3604.BlockStmt.e
os
initTemplates.base
initTemplates.RangeStmt_1651.BlockStmt._
dirListData.Other
dirEntrySlice.Len
dirEntrySlice.Swap.i
parse.name
dirList.w
dirList.f
dirList.RangeStmt_3604.BlockStmt.BlockStmt.p
dirEntrySlice.Swap.s
dirListData.Articles
contentTemplate
initTemplates.RangeStmt_1651.ext
renderDoc.w
dirHandler.BlockStmt.addr
initTemplates.err
parse.f
dirEntrySlice.Less.s
dirEntrySlice.Less
http
sort
dirHandler.r
isDoc
initTemplates
renderDoc
parse.err
dirEntrySlice
io
filepath
dirHandler.BlockStmt.e
initTemplates.RangeStmt_1651.contentTmpl
dirList
dirEntry.Path
net
present
dirHandler
Members
X