| 287 | } |
| 288 | |
| 289 | func getTweaks(c echo.Context, app storage.App) error { |
| 290 | tweaks, err := app.ReadDir(storage.TweaksDir) |
| 291 | if os.IsNotExist(err) { |
| 292 | return c.NoContent(404) |
| 293 | } else if err != nil { |
| 294 | return err |
| 295 | } |
| 296 | if len(tweaks) < 1 { |
| 297 | return c.NoContent(404) |
| 298 | } |
| 299 | appName, err := app.GetString(storage.AppName) |
| 300 | if err != nil { |
| 301 | return err |
| 302 | } |
| 303 | c.Response().Header().Set("Content-Type", mime.TypeByExtension(".tar")) |
| 304 | c.Response().Header().Add("Content-Disposition", fmt.Sprintf(`attachment; filename="%s-tweaks.tar"`, appName)) |
| 305 | writer := tar.NewWriter(c.Response().Writer) |
| 306 | defer writer.Close() |
| 307 | for _, tweak := range tweaks { |
| 308 | tweakPath := storage.FSName(filepath.Join(string(storage.TweaksDir), tweak.Name())) |
| 309 | file, err := app.GetFile(tweakPath) |
| 310 | if err != nil { |
| 311 | return err |
| 312 | } |
| 313 | defer file.Close() |
| 314 | stat, err := app.Stat(tweakPath) |
| 315 | if err != nil { |
| 316 | return err |
| 317 | } |
| 318 | if err := writer.WriteHeader(&tar.Header{ |
| 319 | Name: tweak.Name(), |
| 320 | Mode: 0600, |
| 321 | Size: stat.Size(), |
| 322 | }); err != nil { |
| 323 | return err |
| 324 | } |
| 325 | if _, err := io.Copy(writer, file); err != nil { |
| 326 | return err |
| 327 | } |
| 328 | } |
| 329 | return nil |
| 330 | } |
| 331 | |
| 332 | func renderRenameApp(c echo.Context, app storage.App) error { |
| 333 | appName, err := app.GetString(storage.AppName) |