package api import ( "fmt" "net/http" "github.com/photoprism/photoprism/internal/photoprism" "github.com/photoprism/photoprism/internal/query" "github.com/photoprism/photoprism/pkg/fs" "github.com/photoprism/photoprism/pkg/txt" "github.com/gin-gonic/gin" ) // TODO: GET /api/v1/dl/file/:hash // TODO: GET /api/v1/dl/photo/:uid // TODO: GET /api/v1/dl/album/:uid // GET /api/v1/dl/:hash // // Parameters: // hash: string The file hash as returned by the search API func GetDownload(router *gin.RouterGroup) { router.GET("/dl/:hash", func(c *gin.Context) { if InvalidDownloadToken(c) { c.Data(http.StatusForbidden, "image/svg+xml", brokenIconSvg) return } fileHash := c.Param("hash") f, err := query.FileByHash(fileHash) if err != nil { c.AbortWithStatusJSON(404, gin.H{"error": err.Error()}) return } fileName := photoprism.FileName(f.FileRoot, f.FileName) if !fs.FileExists(fileName) { log.Errorf("download: file %s is missing", txt.Quote(f.FileName)) c.Data(404, "image/svg+xml", brokenIconSvg) // Set missing flag so that the file doesn't show up in search results anymore. logError("download", f.Update("FileMissing", true)) return } downloadFileName := f.ShareFileName() c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", downloadFileName)) c.File(fileName) }) }