16
16
from novelsave .exceptions import SourceNotFoundException
17
17
from novelsave .utils .helpers import url_helper , string_helper
18
18
from .. import checks , mfmt
19
- from ..decorators import ensure_close
19
+ from ..decorators import session_task
20
20
from ..session import SessionFragment , SessionHandler
21
21
22
22
23
23
class DownloadHandler (SessionFragment ):
24
- download_threads : int = Provide ["discord_config.download.threads" ]
25
-
26
24
def __init__ (self , * args , ** kwargs ):
27
25
super (DownloadHandler , self ).__init__ (* args , ** kwargs )
28
26
@@ -46,12 +44,12 @@ async def download_state(self, ctx: commands.Context):
46
44
async def packaging_state (self , ctx : commands .Context ):
47
45
await ctx .send ("I'm currently packaging the novel." )
48
46
49
- @ensure_close
47
+ @session_task ()
50
48
def download (self , url : str , targets : List [str ]):
51
49
self .session .state = self .info_state
52
50
53
51
try :
54
- source_gateway = self .session .source_service .source_from_url (url )
52
+ source_gateway = self .session .source_service () .source_from_url (url )
55
53
except SourceNotFoundException :
56
54
self .session .send_sync (mfmt .error ("This website is not yet supported." ))
57
55
self .session .send_sync (
@@ -61,7 +59,7 @@ def download(self, url: str, targets: List[str]):
61
59
return
62
60
63
61
try :
64
- packagers = self .session .packager_provider .filter_packagers (targets )
62
+ packagers = self .session .packager_provider () .filter_packagers (targets )
65
63
except ValueError as e :
66
64
self .session .send_sync (mfmt .error (str (e )))
67
65
return
@@ -77,9 +75,11 @@ def download(self, url: str, targets: List[str]):
77
75
f"volumes of { chapter_count } chapters."
78
76
)
79
77
80
- novel = self .session .novel_service .insert_novel (novel_dto )
81
- self .session .novel_service .insert_chapters (novel , novel_dto .volumes )
82
- self .session .novel_service .insert_metadata (novel , novel_dto .metadata )
78
+ novel_service = self .session .novel_service ()
79
+
80
+ novel = novel_service .insert_novel (novel_dto )
81
+ novel_service .insert_chapters (novel , novel_dto .volumes )
82
+ novel_service .insert_metadata (novel , novel_dto .metadata )
83
83
84
84
self .session .state = self .download_state
85
85
self .download_thumbnail (novel )
@@ -114,57 +114,61 @@ def download_thumbnail(self, novel: Novel):
114
114
)
115
115
return
116
116
117
- thumbnail_path = self .session .path_service .thumbnail_path (novel )
118
- self .session .novel_service .set_thumbnail_asset (
119
- novel , self .session .path_service .relative_to_data_dir (thumbnail_path )
117
+ path_service = self .session .path_service ()
118
+ novel_service = self .session .novel_service ()
119
+
120
+ thumbnail_path = path_service .thumbnail_path (novel )
121
+ novel_service .set_thumbnail_asset (
122
+ novel , path_service .relative_to_data_dir (thumbnail_path )
120
123
)
121
124
122
125
thumbnail_path .parent .mkdir (parents = True , exist_ok = True )
123
- self .session .file_service .write_bytes (thumbnail_path , response .content )
126
+ self .session .file_service () .write_bytes (thumbnail_path , response .content )
124
127
125
128
size = string_helper .format_bytes (len (response .content ))
126
129
self .session .send_sync (f"Downloaded and saved thumbnail image ({ size } )." )
127
130
128
131
def download_chapters (self , novel : Novel , source_gateway : BaseSourceGateway ):
129
- chapters = self .session .novel_service .get_pending_chapters (novel , - 1 )
132
+ novel_service = self .session .novel_service ()
133
+
134
+ chapters = novel_service .get_pending_chapters (novel , - 1 )
130
135
if not chapters :
131
136
logger .info ("Skipped chapter download as none are pending." )
132
137
return
133
138
134
139
self .session .send_sync (
135
- f"Downloading { len (chapters )} chapters using { self .download_threads } threads…"
140
+ f"Downloading { len (chapters )} chapters using { self .session . thread_count - 1 } threads…"
136
141
)
142
+
137
143
self .total = len (chapters )
138
144
self .value = 1
139
145
140
- with futures .ThreadPoolExecutor (
141
- max_workers = self .download_threads
142
- ) as download_executor :
143
- download_futures = [
144
- download_executor .submit (
145
- source_gateway .update_chapter_content ,
146
- self .session .dto_adapter .chapter_to_dto (c ),
147
- )
148
- for c in chapters
149
- ]
150
-
151
- for chapter in futures .as_completed (download_futures ):
152
- try :
153
- chapter_dto = chapter .result ()
154
- except Exception as e :
155
- logger .exception (e )
156
- continue
157
-
158
- chapter_dto .content = self .session .asset_service .collect_assets (
159
- novel , chapter_dto
160
- )
161
- self .session .novel_service .update_content (chapter_dto )
146
+ dto_adapter = self .session .dto_adapter ()
147
+ asset_service = self .session .asset_service ()
162
148
163
- logger .debug (
164
- f"Chapter content downloaded: '{ chapter_dto .title } ' ({ chapter_dto .index } )"
165
- )
149
+ download_futures = [
150
+ self .session .executor .submit (
151
+ source_gateway .update_chapter_content ,
152
+ dto_adapter .chapter_to_dto (c ),
153
+ )
154
+ for c in chapters
155
+ ]
156
+
157
+ for chapter in futures .as_completed (download_futures ):
158
+ try :
159
+ chapter_dto = chapter .result ()
160
+ except Exception as e :
161
+ logger .exception (e )
162
+ continue
163
+
164
+ chapter_dto .content = asset_service .collect_assets (novel , chapter_dto )
165
+ novel_service .update_content (chapter_dto )
166
+
167
+ logger .debug (
168
+ f"Chapter content downloaded: '{ chapter_dto .title } ' ({ chapter_dto .index } )"
169
+ )
166
170
167
- self .value += 1
171
+ self .value += 1
168
172
169
173
def package (self , novel : Novel , packagers : Iterable [BasePackager ]):
170
174
formats = ", " .join (p .keywords ()[0 ] for p in packagers )
@@ -179,6 +183,7 @@ def package(self, novel: Novel, packagers: Iterable[BasePackager]):
179
183
else :
180
184
self .session .send_sync (f"Uploading { output .name } …" )
181
185
186
+ # TODO: ability upload larger than 8 Mb
182
187
if output .stat ().st_size > 7.99 * 1024 * 1024 :
183
188
self .session .send_sync (
184
189
mfmt .error (
0 commit comments