|
1 | 1 | package http |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "bufio" |
4 | 5 | "fmt" |
| 6 | + "musicboxapi/configuration" |
5 | 7 | "musicboxapi/database" |
6 | 8 | "musicboxapi/models" |
7 | 9 | "net/http" |
| 10 | + "os" |
8 | 11 | "strconv" |
| 12 | + "strings" |
9 | 13 |
|
10 | 14 | "github.com/gin-gonic/gin" |
11 | 15 | ) |
12 | 16 |
|
13 | 17 | type PlaylistSongHandler struct { |
14 | | - PlaylistsongTable database.IPlaylistsongTable |
| 18 | + PlaylistsongTable database.IPlaylistSongTable |
15 | 19 | } |
16 | 20 |
|
| 21 | +const DefaultPlaylistId = 1 |
| 22 | + |
17 | 23 | // @Produce json |
18 | 24 | // @Param playlistId path int true "Id of playlist" |
19 | 25 | // @Param lastKnowSongPosition path int false "Last song that is know by the client, pass this in to only get the latest songs" |
@@ -99,5 +105,74 @@ func (handler *PlaylistSongHandler) DeletePlaylistSong(ctx *gin.Context) { |
99 | 105 | ctx.JSON(http.StatusInternalServerError, models.ErrorResponse(err)) |
100 | 106 | return |
101 | 107 | } |
| 108 | + |
| 109 | + // Thumbnail and .opus file will be deleted only if you delete a song via the main playlist containing all the songs |
| 110 | + if playlistId == DefaultPlaylistId { |
| 111 | + |
| 112 | + songTable := database.NewSongTableInstance() |
| 113 | + song, err := songTable.FetchSongById(songId) |
| 114 | + |
| 115 | + if err != nil { |
| 116 | + ctx.JSON(http.StatusInternalServerError, models.ErrorResponse(err)) |
| 117 | + return |
| 118 | + } |
| 119 | + |
| 120 | + // Delete actual song file |
| 121 | + audioFilePath := song.Path |
| 122 | + configuration.DeleteFile(audioFilePath) |
| 123 | + |
| 124 | + // Delete actual thumbnail file |
| 125 | + thumbnail := song.ThumbnailPath |
| 126 | + thumbnailPath := fmt.Sprintf("%s/images/%s", configuration.Config.SourceFolder, thumbnail) |
| 127 | + configuration.DeleteFile(thumbnailPath) |
| 128 | + |
| 129 | + // Delete from database |
| 130 | + songTable.DeleteSongById(song.Id) |
| 131 | + |
| 132 | + // Delete from video_archive |
| 133 | + strSplit := strings.Split(song.Path, ".") |
| 134 | + |
| 135 | + filenameWithOutExtension := strSplit[0] |
| 136 | + strSplit = strings.Split(filenameWithOutExtension, "/") |
| 137 | + |
| 138 | + filenameWithOutExtension = strSplit[1] |
| 139 | + |
| 140 | + filePath := fmt.Sprintf("%s/%s", configuration.Config.SourceFolder, "video_archive") |
| 141 | + |
| 142 | + // Read the file |
| 143 | + file, err := os.Open(filePath) |
| 144 | + if err != nil { |
| 145 | + fmt.Println("Error opening file:", err) |
| 146 | + ctx.JSON(http.StatusInternalServerError, models.ErrorResponse(err)) |
| 147 | + return |
| 148 | + } |
| 149 | + defer file.Close() |
| 150 | + |
| 151 | + var lines []string |
| 152 | + scanner := bufio.NewScanner(file) |
| 153 | + for scanner.Scan() { |
| 154 | + line := scanner.Text() |
| 155 | + // Keep the line only if it’s not the target |
| 156 | + if strings.TrimSpace(line) != fmt.Sprintf("youtube %s", filenameWithOutExtension) { |
| 157 | + lines = append(lines, line) |
| 158 | + } |
| 159 | + } |
| 160 | + |
| 161 | + if err := scanner.Err(); err != nil { |
| 162 | + fmt.Println("Error reading file:", err) |
| 163 | + ctx.JSON(http.StatusInternalServerError, models.ErrorResponse(err)) |
| 164 | + return |
| 165 | + } |
| 166 | + |
| 167 | + // Write the updated content back to the file |
| 168 | + output := strings.Join(lines, "\n") |
| 169 | + err = os.WriteFile(filePath, []byte(output+"\n"), 0644) |
| 170 | + if err != nil { |
| 171 | + fmt.Println("Error writing file:", err) |
| 172 | + ctx.JSON(http.StatusInternalServerError, models.ErrorResponse(err)) |
| 173 | + return |
| 174 | + } |
| 175 | + } |
| 176 | + |
102 | 177 | ctx.Status(http.StatusOK) |
103 | 178 | } |
0 commit comments