@@ -24,14 +24,30 @@ use crate::{
24
24
} ;
25
25
26
26
27
+ static EPISODE_SPLIT_FRAME : [ u32 ; 3 ] = [ 0 , 34288 , 68334 ] ;
28
+
29
+
27
30
pub ( crate ) async fn handler (
28
- Path ( ( season, episode, target) ) : Path < ( String , String , String ) > ,
31
+ Path ( ( season, episode, target) ) : Path < ( u8 , String , String ) > ,
29
32
State ( scheduler) : State < Arc < Scheduler > > ,
30
33
) -> impl IntoResponse {
31
- let season = season. to_lowercase ( ) ;
32
- let episode = episode. to_lowercase ( ) ;
34
+ let season = match season {
35
+ 1 => "" ,
36
+ 2 => "ave-" ,
37
+ _ => ""
38
+ } ;
39
+
40
+ let mut episode = episode. to_lowercase ( ) ;
33
41
let target = target. to_lowercase ( ) ;
34
42
43
+ let env_config = match ENV_CONFIG . get ( ) {
44
+ Some ( env) => env,
45
+ None => return (
46
+ StatusCode :: INTERNAL_SERVER_ERROR ,
47
+ "Failed to load server env."
48
+ ) . into_response ( )
49
+ } ;
50
+
35
51
let (
36
52
target_frame,
37
53
target_format
@@ -42,8 +58,6 @@ pub(crate) async fn handler(
42
58
"Failed to parse target file."
43
59
) . into_response ( ) ,
44
60
} ;
45
-
46
- let animated_frame = target_frame. split_once ( "-" ) ;
47
61
48
62
let target_format = match target_format {
49
63
"png" => ImageFormat :: Png ,
@@ -52,6 +66,14 @@ pub(crate) async fn handler(
52
66
"jpg" | "jpeg" => ImageFormat :: Jpeg ,
53
67
_ => return StatusCode :: UNSUPPORTED_MEDIA_TYPE . into_response ( )
54
68
} ;
69
+
70
+ let mut animated_frame: Option < ( u32 , u32 ) > = target_frame
71
+ . split_once ( "-" )
72
+ . and_then (
73
+ |r| r. 0 . parse ( ) . ok ( ) . zip ( r. 1 . parse ( ) . ok ( ) )
74
+ ) ;
75
+
76
+ let mut frame = target_frame. parse ( ) . ok ( ) ;
55
77
56
78
if animated_frame. is_some ( ) && target_format != ImageFormat :: Gif {
57
79
return (
@@ -60,56 +82,62 @@ pub(crate) async fn handler(
60
82
) . into_response ( ) ;
61
83
}
62
84
63
- let env_config = match ENV_CONFIG . get ( ) {
64
- Some ( env) => env,
65
- None => return (
66
- StatusCode :: INTERNAL_SERVER_ERROR ,
67
- "Failed to parse target file."
68
- ) . into_response ( )
69
- } ;
70
-
71
- let season_name = match season. as_str ( ) {
72
- "1" | "mygo" => "" ,
73
- "2" | "ave" | "ave-mujica" => "ave-" ,
74
- _ => ""
75
- } ;
76
-
77
- if let Some ( animated_frame) = animated_frame {
85
+ if season. is_empty ( ) {
86
+ let offset = match episode. as_str ( ) {
87
+ "1" => Some ( EPISODE_SPLIT_FRAME [ 0 ] ) ,
88
+ "2" => Some ( EPISODE_SPLIT_FRAME [ 1 ] ) ,
89
+ "3" => Some ( EPISODE_SPLIT_FRAME [ 2 ] ) ,
90
+ _ => None
91
+ } ;
92
+
93
+ if let Some ( offset) = offset {
94
+ match ( frame, animated_frame) {
95
+ ( Some ( f) , None ) => {
96
+ frame = Some ( f + offset)
97
+ } ,
98
+ ( None , Some ( a_f) ) => {
99
+ animated_frame = Some ( ( a_f. 0 + offset, a_f. 1 + offset) )
100
+ } ,
101
+ _ => return (
102
+ StatusCode :: BAD_REQUEST ,
103
+ "Failed to request file with target frame."
104
+ ) . into_response ( )
105
+ }
106
+ episode = String :: from ( "1-3" ) ;
107
+ }
108
+ }
109
+
110
+ match ( frame, animated_frame) {
111
+ ( Some ( frame) , None ) => return handle_static_image (
112
+ env_config,
113
+ season,
114
+ & episode,
115
+ frame,
116
+ target_format
117
+ ) . await ,
118
+ ( None , Some ( animated_frame) ) =>
78
119
return handle_animated_image (
79
120
env_config,
80
- & season_name ,
121
+ season ,
81
122
& episode,
82
123
animated_frame,
83
124
scheduler
84
- ) . await ;
85
- } else {
86
- return handle_static_image (
87
- env_config,
88
- & season_name,
89
- & episode,
90
- target_frame,
91
- target_format
92
- ) . await ;
125
+ ) . await ,
126
+ _ => return (
127
+ StatusCode :: BAD_REQUEST ,
128
+ "Failed to request file with target frame."
129
+ ) . into_response ( )
93
130
}
94
131
}
95
132
96
133
async fn handle_animated_image (
97
134
env_config : & EnvConfig ,
98
- season_name : & str ,
135
+ season : & str ,
99
136
episode : & str ,
100
- animated_frame : ( & str , & str ) ,
137
+ animated_frame : ( u32 , u32 ) ,
101
138
scheduler : Arc < Scheduler >
102
139
) -> Response < Body > {
103
- let u32_frame: Option < ( u32 , u32 ) > = animated_frame. 0 . parse ( ) . ok ( )
104
- . zip ( animated_frame. 1 . parse ( ) . ok ( ) ) ;
105
-
106
- let ( start_frame, end_frame) = match u32_frame {
107
- Some ( r) => r,
108
- None => return (
109
- StatusCode :: BAD_REQUEST ,
110
- "Failed to convert frame range to u32."
111
- ) . into_response ( ) ,
112
- } ;
140
+ let ( start_frame, end_frame) = animated_frame;
113
141
114
142
if start_frame >= end_frame || start_frame <= 0 {
115
143
return (
@@ -133,25 +161,25 @@ async fn handle_animated_image(
133
161
env_config,
134
162
start_frame,
135
163
frames,
136
- & season_name ,
164
+ season ,
137
165
& episode,
138
166
scheduler
139
167
) . await
140
168
}
141
169
142
170
async fn handle_static_image (
143
171
env_config : & EnvConfig ,
144
- season_name : & str ,
172
+ season : & str ,
145
173
episode : & str ,
146
- target_frame : & str ,
147
- target_format : ImageFormat
174
+ frame : u32 ,
175
+ format : ImageFormat
148
176
) -> Response < Body > {
149
177
let source_file_path = format ! (
150
178
"{}/{}{}_{}.webp" ,
151
179
env_config. image_source_path,
152
- season_name ,
180
+ season ,
153
181
episode,
154
- target_frame
182
+ frame
155
183
) ;
156
184
157
185
if let Ok ( exists) = fs:: try_exists ( & source_file_path) . await {
@@ -176,5 +204,5 @@ async fn handle_static_image(
176
204
) . into_response ( ) ,
177
205
} ;
178
206
179
- convert_static_image ( reader, target_format ) . await
207
+ convert_static_image ( reader, format ) . await
180
208
}
0 commit comments