1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
using HyperBooru.Services;
using HyperBooru.Util;
using ImageMagick;
using Microsoft.AspNetCore.Mvc;
using MimeDetective;
using System.Security.Cryptography;
namespace HyperBooru.Controllers;
[ApiController]
[Route("/media")]
public class MediaController : Controller {
private IMediaService mediaService;
private IConfigService config;
private HBContext db;
public MediaController(
IMediaService mediaService,
IConfigService config,
HBContext db) {
this.mediaService = mediaService;
this.config = config;
this.db = db;
}
[HttpGet("{mediaId}")]
public IActionResult Fetch([FromRoute] Guid mediaId) {
var media = db.Media.First(m => m.Guid == mediaId);
if(media is null)
return NotFound();
var fs = System.IO.File.OpenRead(mediaService.GetPath(media));
return new FileStreamResult(fs, media.MimeType);
}
[HttpGet("thumb/{mediaId}")]
public IActionResult Thumbnail(
[FromRoute] Guid mediaId,
[FromQuery] int? w,
[FromQuery] int? h) {
var media = db.Media.First(m => m.Guid == mediaId);
if(media is null)
return NotFound();
if(media.MimeType.Split("/")[0] != "image")
return BadRequest("Media object not an image");
using var image = new MagickImage(mediaService.GetPath(media));
if(w is null && h is null)
return BadRequest("Both width and height cannot be null!");
if(w > image.Width || h > image.Height)
return BadRequest("Requested thumbnail size is larger than original media");
int width = (int)(w is not null ? w : image.Width * h / image.Height);
int height = (int)(h is not null ? h : image.Height * w / image.Width);
var thumbPath = mediaService.GetPath(media, width, height);
if(!System.IO.File.Exists(thumbPath)) {
image.Resize(new MagickGeometry(width, height));
image.Write(thumbPath);
}
var fs = System.IO.File.OpenRead(thumbPath);
return new FileStreamResult(fs, "image/jpeg");
}
[HttpDelete("{mediaId}")]
public void Delete([FromRoute] Guid mediaId) {
mediaService.Delete(mediaId);
}
[HttpPost]
public IActionResult Upload() {
if(Request.Form.Files.Count == 0)
return BadRequest("No files");
Media media = new();
foreach(var formFile in Request.Form.Files) {
try {
// Parse timestamps from headers
DateTime? lastAccessTime =
formFile.Headers["X-HyperBooru-LastAccessTime"]
.ElementAtOrDefault(0)?
.TryParseDateTimeUtc();
DateTime? lastWriteTime =
formFile.Headers["X-HyperBooru-LastWriteTime"]
.ElementAtOrDefault(0)?
.TryParseDateTimeUtc();
DateTime? createTime =
formFile.Headers["X-HyperBooru-CreateTime"]
.ElementAtOrDefault(0)?
.TryParseDateTimeUtc();
media = mediaService.Create(
formFile.OpenReadStream(),
formFile.FileName,
formFile.Headers["X-HyperBooru-Checksum"]
.ElementAtOrDefault(0),
lastAccessTime,
lastWriteTime,
createTime);
} catch(MediaCreateException e) {
return BadRequest(e.Message);
}
}
if(Request.Form.Files.Count == 1)
return Redirect($"/ViewMedia?m={media.Guid}");
else
return Redirect($"/Gallery");
}
}
|