@@ -142,10 +142,30 @@ func renderDirectory(ctx *context.Context, treeLink string) {
142142 return
143143 }
144144
145+ renderDirectoryDefaultFile (ctx , entries , treeLink )
146+ }
147+
148+ // renderDirectoryDefaultFile render the default file when render a root directory or a sub directory
149+ func renderDirectoryDefaultFile (ctx * context.Context , entries git.Entries , treeLink string ) {
145150 if ctx .Repo .TreePath != "" {
146151 ctx .Data ["Title" ] = ctx .Tr ("repo.file.title" , ctx .Repo .Repository .Name + "/" + path .Base (ctx .Repo .TreePath ), ctx .Repo .RefName )
147152 }
148153
154+ // Check permission to add or upload new file.
155+ if ctx .Repo .CanWrite (unit_model .TypeCode ) && ctx .Repo .IsViewBranch {
156+ ctx .Data ["CanAddFile" ] = ! ctx .Repo .Repository .IsArchived
157+ ctx .Data ["CanUploadFile" ] = setting .Repository .Upload .Enabled && ! ctx .Repo .Repository .IsArchived
158+ }
159+
160+ readmeFile , readmeTreelink := findReadmeFile (ctx , entries , treeLink )
161+ if ctx .Written () || readmeFile == nil {
162+ return
163+ }
164+
165+ renderReadmeFile (ctx , readmeFile , readmeTreelink )
166+ }
167+
168+ func findReadmeFile (ctx * context.Context , entries git.Entries , treeLink string ) (* namedBlob , string ) {
149169 // 3 for the extensions in exts[] in order
150170 // the last one is for a readme that doesn't
151171 // strictly match an extension
@@ -183,7 +203,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
183203 target , err = entry .FollowLinks ()
184204 if err != nil && ! git .IsErrBadLink (err ) {
185205 ctx .ServerError ("FollowLinks" , err )
186- return
206+ return nil , ""
187207 }
188208 }
189209 log .Debug ("%t" , target == nil )
@@ -205,7 +225,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
205225 entry , err = entry .FollowLinks ()
206226 if err != nil && ! git .IsErrBadLink (err ) {
207227 ctx .ServerError ("FollowLinks" , err )
208- return
228+ return nil , ""
209229 }
210230 }
211231 if entry != nil && (entry .IsExecutable () || entry .IsRegular ()) {
@@ -236,7 +256,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
236256 readmeFile , err = getReadmeFileFromPath (ctx .Repo .Commit , entry .GetSubJumpablePathName ())
237257 if err != nil {
238258 ctx .ServerError ("getReadmeFileFromPath" , err )
239- return
259+ return nil , ""
240260 }
241261 if readmeFile != nil {
242262 readmeFile .name = entry .Name () + "/" + readmeFile .name
@@ -245,129 +265,127 @@ func renderDirectory(ctx *context.Context, treeLink string) {
245265 }
246266 }
247267 }
268+ return readmeFile , readmeTreelink
269+ }
248270
249- if readmeFile != nil {
250- ctx .Data ["RawFileLink" ] = ""
251- ctx .Data ["ReadmeInList" ] = true
252- ctx .Data ["ReadmeExist" ] = true
253- ctx .Data ["FileIsSymlink" ] = readmeFile .isSymlink
271+ func renderReadmeFile ( ctx * context. Context , readmeFile * namedBlob , readmeTreelink string ) {
272+ ctx .Data ["RawFileLink" ] = ""
273+ ctx .Data ["ReadmeInList" ] = true
274+ ctx .Data ["ReadmeExist" ] = true
275+ ctx .Data ["FileIsSymlink" ] = readmeFile .isSymlink
254276
255- dataRc , err := readmeFile .blob .DataAsync ()
256- if err != nil {
257- ctx .ServerError ("Data" , err )
258- return
259- }
260- defer dataRc .Close ()
261-
262- buf := make ([]byte , 1024 )
263- n , _ := util .ReadAtMost (dataRc , buf )
264- buf = buf [:n ]
265-
266- st := typesniffer .DetectContentType (buf )
267- isTextFile := st .IsText ()
268-
269- ctx .Data ["FileIsText" ] = isTextFile
270- ctx .Data ["FileName" ] = readmeFile .name
271- fileSize := int64 (0 )
272- isLFSFile := false
273- ctx .Data ["IsLFSFile" ] = false
274-
275- // FIXME: what happens when README file is an image?
276- if isTextFile && setting .LFS .StartServer {
277- pointer , _ := lfs .ReadPointerFromBuffer (buf )
278- if pointer .IsValid () {
279- meta , err := models .GetLFSMetaObjectByOid (ctx .Repo .Repository .ID , pointer .Oid )
280- if err != nil && err != models .ErrLFSObjectNotExist {
281- ctx .ServerError ("GetLFSMetaObject" , err )
282- return
283- }
284- if meta != nil {
285- ctx .Data ["IsLFSFile" ] = true
286- isLFSFile = true
277+ dataRc , err := readmeFile .blob .DataAsync ()
278+ if err != nil {
279+ ctx .ServerError ("Data" , err )
280+ return
281+ }
282+ defer dataRc .Close ()
287283
288- // OK read the lfs object
289- var err error
290- dataRc , err = lfs .ReadMetaObject (pointer )
291- if err != nil {
292- ctx .ServerError ("ReadMetaObject" , err )
293- return
294- }
295- defer dataRc .Close ()
284+ buf := make ([]byte , 1024 )
285+ n , _ := util .ReadAtMost (dataRc , buf )
286+ buf = buf [:n ]
296287
297- buf = make ([]byte , 1024 )
298- n , err = util .ReadAtMost (dataRc , buf )
299- if err != nil {
300- ctx .ServerError ("Data" , err )
301- return
302- }
303- buf = buf [:n ]
288+ st := typesniffer .DetectContentType (buf )
289+ isTextFile := st .IsText ()
304290
305- st = typesniffer .DetectContentType (buf )
306- isTextFile = st .IsText ()
307- ctx .Data ["IsTextFile" ] = isTextFile
291+ ctx .Data ["FileIsText" ] = isTextFile
292+ ctx .Data ["FileName" ] = readmeFile .name
293+ fileSize := int64 (0 )
294+ isLFSFile := false
295+ ctx .Data ["IsLFSFile" ] = false
308296
309- fileSize = meta .Size
310- ctx .Data ["FileSize" ] = meta .Size
311- filenameBase64 := base64 .RawURLEncoding .EncodeToString ([]byte (readmeFile .name ))
312- ctx .Data ["RawFileLink" ] = fmt .Sprintf ("%s.git/info/lfs/objects/%s/%s" , ctx .Repo .Repository .HTMLURL (), url .PathEscape (meta .Oid ), url .PathEscape (filenameBase64 ))
313- }
297+ // FIXME: what happens when README file is an image?
298+ if isTextFile && setting .LFS .StartServer {
299+ pointer , _ := lfs .ReadPointerFromBuffer (buf )
300+ if pointer .IsValid () {
301+ meta , err := models .GetLFSMetaObjectByOid (ctx .Repo .Repository .ID , pointer .Oid )
302+ if err != nil && err != models .ErrLFSObjectNotExist {
303+ ctx .ServerError ("GetLFSMetaObject" , err )
304+ return
314305 }
315- }
316-
317- if ! isLFSFile {
318- fileSize = readmeFile .blob .Size ()
319- }
306+ if meta != nil {
307+ ctx .Data ["IsLFSFile" ] = true
308+ isLFSFile = true
320309
321- if isTextFile {
322- if fileSize >= setting .UI .MaxDisplayFileSize {
323- // Pretend that this is a normal text file to display 'This file is too large to be shown'
324- ctx .Data ["IsFileTooLarge" ] = true
325- ctx .Data ["IsTextFile" ] = true
326- ctx .Data ["FileSize" ] = fileSize
327- } else {
328- rd := charset .ToUTF8WithFallbackReader (io .MultiReader (bytes .NewReader (buf ), dataRc ))
329-
330- if markupType := markup .Type (readmeFile .name ); markupType != "" {
331- ctx .Data ["IsMarkup" ] = true
332- ctx .Data ["MarkupType" ] = string (markupType )
333- var result strings.Builder
334- err := markup .Render (& markup.RenderContext {
335- Ctx : ctx ,
336- Filename : readmeFile .name ,
337- URLPrefix : readmeTreelink ,
338- Metas : ctx .Repo .Repository .ComposeDocumentMetas (),
339- GitRepo : ctx .Repo .GitRepo ,
340- }, rd , & result )
341- if err != nil {
342- log .Error ("Render failed: %v then fallback" , err )
343- buf := & bytes.Buffer {}
344- ctx .Data ["EscapeStatus" ], _ = charset .EscapeControlReader (rd , buf )
345- ctx .Data ["FileContent" ] = strings .ReplaceAll (
346- gotemplate .HTMLEscapeString (buf .String ()), "\n " , `<br>` ,
347- )
348- } else {
349- ctx .Data ["EscapeStatus" ], ctx .Data ["FileContent" ] = charset .EscapeControlString (result .String ())
350- }
351- } else {
352- ctx .Data ["IsRenderedHTML" ] = true
353- buf := & bytes.Buffer {}
354- ctx .Data ["EscapeStatus" ], err = charset .EscapeControlReader (rd , buf )
355- if err != nil {
356- log .Error ("Read failed: %v" , err )
357- }
310+ // OK read the lfs object
311+ var err error
312+ dataRc , err = lfs .ReadMetaObject (pointer )
313+ if err != nil {
314+ ctx .ServerError ("ReadMetaObject" , err )
315+ return
316+ }
317+ defer dataRc .Close ()
358318
359- ctx .Data ["FileContent" ] = strings .ReplaceAll (
360- gotemplate .HTMLEscapeString (buf .String ()), "\n " , `<br>` ,
361- )
319+ buf = make ([]byte , 1024 )
320+ n , err = util .ReadAtMost (dataRc , buf )
321+ if err != nil {
322+ ctx .ServerError ("Data" , err )
323+ return
362324 }
325+ buf = buf [:n ]
326+
327+ st = typesniffer .DetectContentType (buf )
328+ isTextFile = st .IsText ()
329+ ctx .Data ["IsTextFile" ] = isTextFile
330+
331+ fileSize = meta .Size
332+ ctx .Data ["FileSize" ] = meta .Size
333+ filenameBase64 := base64 .RawURLEncoding .EncodeToString ([]byte (readmeFile .name ))
334+ ctx .Data ["RawFileLink" ] = fmt .Sprintf ("%s.git/info/lfs/objects/%s/%s" , ctx .Repo .Repository .HTMLURL (), url .PathEscape (meta .Oid ), url .PathEscape (filenameBase64 ))
363335 }
364336 }
365337 }
366338
367- // Check permission to add or upload new file.
368- if ctx .Repo .CanWrite (unit_model .TypeCode ) && ctx .Repo .IsViewBranch {
369- ctx .Data ["CanAddFile" ] = ! ctx .Repo .Repository .IsArchived
370- ctx .Data ["CanUploadFile" ] = setting .Repository .Upload .Enabled && ! ctx .Repo .Repository .IsArchived
339+ if ! isTextFile {
340+ return
341+ }
342+
343+ if ! isLFSFile {
344+ fileSize = readmeFile .blob .Size ()
345+ }
346+
347+ if fileSize >= setting .UI .MaxDisplayFileSize {
348+ // Pretend that this is a normal text file to display 'This file is too large to be shown'
349+ ctx .Data ["IsFileTooLarge" ] = true
350+ ctx .Data ["IsTextFile" ] = true
351+ ctx .Data ["FileSize" ] = fileSize
352+ return
353+ }
354+
355+ rd := charset .ToUTF8WithFallbackReader (io .MultiReader (bytes .NewReader (buf ), dataRc ))
356+
357+ if markupType := markup .Type (readmeFile .name ); markupType != "" {
358+ ctx .Data ["IsMarkup" ] = true
359+ ctx .Data ["MarkupType" ] = string (markupType )
360+ var result strings.Builder
361+ err := markup .Render (& markup.RenderContext {
362+ Ctx : ctx ,
363+ Filename : readmeFile .name ,
364+ URLPrefix : readmeTreelink ,
365+ Metas : ctx .Repo .Repository .ComposeDocumentMetas (),
366+ GitRepo : ctx .Repo .GitRepo ,
367+ }, rd , & result )
368+ if err != nil {
369+ log .Error ("Render failed: %v then fallback" , err )
370+ buf := & bytes.Buffer {}
371+ ctx .Data ["EscapeStatus" ], _ = charset .EscapeControlReader (rd , buf )
372+ ctx .Data ["FileContent" ] = strings .ReplaceAll (
373+ gotemplate .HTMLEscapeString (buf .String ()), "\n " , `<br>` ,
374+ )
375+ } else {
376+ ctx .Data ["EscapeStatus" ], ctx .Data ["FileContent" ] = charset .EscapeControlString (result .String ())
377+ }
378+ } else {
379+ ctx .Data ["IsRenderedHTML" ] = true
380+ buf := & bytes.Buffer {}
381+ ctx .Data ["EscapeStatus" ], err = charset .EscapeControlReader (rd , buf )
382+ if err != nil {
383+ log .Error ("Read failed: %v" , err )
384+ }
385+
386+ ctx .Data ["FileContent" ] = strings .ReplaceAll (
387+ gotemplate .HTMLEscapeString (buf .String ()), "\n " , `<br>` ,
388+ )
371389 }
372390}
373391
0 commit comments