Mercurial > hg > orthanc
annotate OrthancServer/Sources/ServerJobs/ArchiveJob.cpp @ 4613:2684544ff03c db-changes
maximum number of database retries for writer collisions is now set by the plugins
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 08 Apr 2021 10:46:12 +0200 |
parents | ff8170d17d90 |
children | f7d5372b59b3 |
rev | line source |
---|---|
2632 | 1 /** |
2 * Orthanc - A Lightweight, RESTful DICOM Store | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
4437
d9473bd5ed43
upgrade to year 2021
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4341
diff
changeset
|
5 * Copyright (C) 2017-2021 Osimis S.A., Belgium |
2632 | 6 * |
7 * This program is free software: you can redistribute it and/or | |
8 * modify it under the terms of the GNU General Public License as | |
9 * published by the Free Software Foundation, either version 3 of the | |
10 * License, or (at your option) any later version. | |
11 * | |
12 * In addition, as a special exception, the copyright holders of this | |
13 * program give permission to link the code of its release with the | |
14 * OpenSSL project's "OpenSSL" library (or with modified versions of it | |
15 * that use the same license as the "OpenSSL" library), and distribute | |
16 * the linked executables. You must obey the GNU General Public License | |
17 * in all respects for all of the code used other than "OpenSSL". If you | |
18 * modify file(s) with this exception, you may extend this exception to | |
19 * your version of the file(s), but you are not obligated to do so. If | |
20 * you do not wish to do so, delete this exception statement from your | |
21 * version. If you delete this exception statement from all source files | |
22 * in the program, then also delete it here. | |
23 * | |
24 * This program is distributed in the hope that it will be useful, but | |
25 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
27 * General Public License for more details. | |
28 * | |
29 * You should have received a copy of the GNU General Public License | |
30 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
31 **/ | |
32 | |
33 | |
34 #include "../PrecompiledHeadersServer.h" | |
35 #include "ArchiveJob.h" | |
36 | |
4045 | 37 #include "../../../OrthancFramework/Sources/Cache/SharedArchive.h" |
38 #include "../../../OrthancFramework/Sources/Compression/HierarchicalZipWriter.h" | |
39 #include "../../../OrthancFramework/Sources/DicomParsing/DicomDirWriter.h" | |
40 #include "../../../OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.h" | |
41 #include "../../../OrthancFramework/Sources/Logging.h" | |
42 #include "../../../OrthancFramework/Sources/OrthancException.h" | |
3181
6fd38327e777
Fix issue #130 (Orthanc failed to start when /tmp partition was full)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3095
diff
changeset
|
43 #include "../OrthancConfiguration.h" |
3095
beeeb6096f27
removing dependencies upon ServerContext
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3060
diff
changeset
|
44 #include "../ServerContext.h" |
2632 | 45 |
46 #include <stdio.h> | |
47 | |
48 #if defined(_MSC_VER) | |
49 #define snprintf _snprintf | |
50 #endif | |
51 | |
52 static const uint64_t MEGA_BYTES = 1024 * 1024; | |
53 static const uint64_t GIGA_BYTES = 1024 * 1024 * 1024; | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
54 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
55 static const char* const MEDIA_IMAGES_FOLDER = "IMAGES"; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
56 static const char* const KEY_DESCRIPTION = "Description"; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
57 static const char* const KEY_INSTANCES_COUNT = "InstancesCount"; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
58 static const char* const KEY_UNCOMPRESSED_SIZE_MB = "UncompressedSizeMB"; |
4341
977c2759eb0a
Archive/media jobs report the size of the created ZIP file in content field "ArchiveSizeMB"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4205
diff
changeset
|
59 static const char* const KEY_ARCHIVE_SIZE_MB = "ArchiveSizeMB"; |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
60 static const char* const KEY_TRANSCODE = "Transcode"; |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
61 |
2632 | 62 |
63 namespace Orthanc | |
64 { | |
65 static bool IsZip64Required(uint64_t uncompressedSize, | |
66 unsigned int countInstances) | |
67 { | |
68 static const uint64_t SAFETY_MARGIN = 64 * MEGA_BYTES; // Should be large enough to hold DICOMDIR | |
69 static const unsigned int FILES_MARGIN = 10; | |
70 | |
71 /** | |
72 * Determine whether ZIP64 is required. Original ZIP format can | |
73 * store up to 2GB of data (some implementation supporting up to | |
74 * 4GB of data), and up to 65535 files. | |
75 * https://en.wikipedia.org/wiki/Zip_(file_format)#ZIP64 | |
76 **/ | |
77 | |
78 const bool isZip64 = (uncompressedSize >= 2 * GIGA_BYTES - SAFETY_MARGIN || | |
79 countInstances >= 65535 - FILES_MARGIN); | |
80 | |
81 LOG(INFO) << "Creating a ZIP file with " << countInstances << " files of size " | |
82 << (uncompressedSize / MEGA_BYTES) << "MB using the " | |
83 << (isZip64 ? "ZIP64" : "ZIP32") << " file format"; | |
84 | |
85 return isZip64; | |
86 } | |
87 | |
88 | |
89 class ArchiveJob::ResourceIdentifiers : public boost::noncopyable | |
90 { | |
91 private: | |
92 ResourceType level_; | |
93 std::string patient_; | |
94 std::string study_; | |
95 std::string series_; | |
96 std::string instance_; | |
97 | |
98 static void GoToParent(ServerIndex& index, | |
99 std::string& current) | |
100 { | |
101 std::string tmp; | |
102 | |
103 if (index.LookupParent(tmp, current)) | |
104 { | |
105 current = tmp; | |
106 } | |
107 else | |
108 { | |
109 throw OrthancException(ErrorCode_UnknownResource); | |
110 } | |
111 } | |
112 | |
113 | |
114 public: | |
115 ResourceIdentifiers(ServerIndex& index, | |
116 const std::string& publicId) | |
117 { | |
118 if (!index.LookupResourceType(level_, publicId)) | |
119 { | |
120 throw OrthancException(ErrorCode_UnknownResource); | |
121 } | |
122 | |
123 std::string current = publicId;; | |
124 switch (level_) // Do not add "break" below! | |
125 { | |
126 case ResourceType_Instance: | |
127 instance_ = current; | |
128 GoToParent(index, current); | |
129 | |
130 case ResourceType_Series: | |
131 series_ = current; | |
132 GoToParent(index, current); | |
133 | |
134 case ResourceType_Study: | |
135 study_ = current; | |
136 GoToParent(index, current); | |
137 | |
138 case ResourceType_Patient: | |
139 patient_ = current; | |
140 break; | |
141 | |
142 default: | |
143 throw OrthancException(ErrorCode_InternalError); | |
144 } | |
145 } | |
146 | |
147 ResourceType GetLevel() const | |
148 { | |
149 return level_; | |
150 } | |
151 | |
152 const std::string& GetIdentifier(ResourceType level) const | |
153 { | |
154 // Some sanity check to ensure enumerations are not altered | |
155 assert(ResourceType_Patient < ResourceType_Study); | |
156 assert(ResourceType_Study < ResourceType_Series); | |
157 assert(ResourceType_Series < ResourceType_Instance); | |
158 | |
159 if (level > level_) | |
160 { | |
161 throw OrthancException(ErrorCode_InternalError); | |
162 } | |
163 | |
164 switch (level) | |
165 { | |
166 case ResourceType_Patient: | |
167 return patient_; | |
168 | |
169 case ResourceType_Study: | |
170 return study_; | |
171 | |
172 case ResourceType_Series: | |
173 return series_; | |
174 | |
175 case ResourceType_Instance: | |
176 return instance_; | |
177 | |
178 default: | |
179 throw OrthancException(ErrorCode_InternalError); | |
180 } | |
181 } | |
182 }; | |
183 | |
184 | |
185 class ArchiveJob::IArchiveVisitor : public boost::noncopyable | |
186 { | |
187 public: | |
188 virtual ~IArchiveVisitor() | |
189 { | |
190 } | |
191 | |
192 virtual void Open(ResourceType level, | |
193 const std::string& publicId) = 0; | |
194 | |
195 virtual void Close() = 0; | |
196 | |
197 virtual void AddInstance(const std::string& instanceId, | |
4510
a3635a01a945
fix signature of virtual method
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4509
diff
changeset
|
198 uint64_t uncompressedSize) = 0; |
2632 | 199 }; |
200 | |
201 | |
202 class ArchiveJob::ArchiveIndex : public boost::noncopyable | |
203 { | |
204 private: | |
205 struct Instance | |
206 { | |
207 std::string id_; | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
208 uint64_t uncompressedSize_; |
2632 | 209 |
210 Instance(const std::string& id, | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
211 uint64_t uncompressedSize) : |
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
212 id_(id), |
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
213 uncompressedSize_(uncompressedSize) |
2632 | 214 { |
215 } | |
216 }; | |
217 | |
218 // A "NULL" value for ArchiveIndex indicates a non-expanded node | |
219 typedef std::map<std::string, ArchiveIndex*> Resources; | |
220 | |
221 ResourceType level_; | |
222 Resources resources_; // Only at patient/study/series level | |
223 std::list<Instance> instances_; // Only at instance level | |
224 | |
225 | |
226 void AddResourceToExpand(ServerIndex& index, | |
227 const std::string& id) | |
228 { | |
229 if (level_ == ResourceType_Instance) | |
230 { | |
231 FileInfo tmp; | |
232 if (index.LookupAttachment(tmp, id, FileContentType_Dicom)) | |
233 { | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
234 instances_.push_back(Instance(id, tmp.GetUncompressedSize())); |
2632 | 235 } |
236 } | |
237 else | |
238 { | |
239 resources_[id] = NULL; | |
240 } | |
241 } | |
242 | |
243 | |
244 public: | |
4205 | 245 explicit ArchiveIndex(ResourceType level) : |
2632 | 246 level_(level) |
247 { | |
248 } | |
249 | |
250 ~ArchiveIndex() | |
251 { | |
252 for (Resources::iterator it = resources_.begin(); | |
253 it != resources_.end(); ++it) | |
254 { | |
255 delete it->second; | |
256 } | |
257 } | |
258 | |
259 | |
260 void Add(ServerIndex& index, | |
261 const ResourceIdentifiers& resource) | |
262 { | |
263 const std::string& id = resource.GetIdentifier(level_); | |
264 Resources::iterator previous = resources_.find(id); | |
265 | |
266 if (level_ == ResourceType_Instance) | |
267 { | |
268 AddResourceToExpand(index, id); | |
269 } | |
270 else if (resource.GetLevel() == level_) | |
271 { | |
272 // Mark this resource for further expansion | |
273 if (previous != resources_.end()) | |
274 { | |
275 delete previous->second; | |
276 } | |
277 | |
278 resources_[id] = NULL; | |
279 } | |
280 else if (previous == resources_.end()) | |
281 { | |
282 // This is the first time we meet this resource | |
3712
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
283 std::unique_ptr<ArchiveIndex> child(new ArchiveIndex(GetChildResourceType(level_))); |
2632 | 284 child->Add(index, resource); |
285 resources_[id] = child.release(); | |
286 } | |
287 else if (previous->second != NULL) | |
288 { | |
289 previous->second->Add(index, resource); | |
290 } | |
291 else | |
292 { | |
293 // Nothing to do: This item is marked for further expansion | |
294 } | |
295 } | |
296 | |
297 | |
298 void Expand(ServerIndex& index) | |
299 { | |
300 if (level_ == ResourceType_Instance) | |
301 { | |
302 // Expanding an instance node makes no sense | |
303 return; | |
304 } | |
305 | |
306 for (Resources::iterator it = resources_.begin(); | |
307 it != resources_.end(); ++it) | |
308 { | |
309 if (it->second == NULL) | |
310 { | |
311 // This is resource is marked for expansion | |
312 std::list<std::string> children; | |
313 index.GetChildren(children, it->first); | |
314 | |
3712
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
315 std::unique_ptr<ArchiveIndex> child(new ArchiveIndex(GetChildResourceType(level_))); |
2632 | 316 |
317 for (std::list<std::string>::const_iterator | |
318 it2 = children.begin(); it2 != children.end(); ++it2) | |
319 { | |
320 child->AddResourceToExpand(index, *it2); | |
321 } | |
322 | |
323 it->second = child.release(); | |
324 } | |
325 | |
326 assert(it->second != NULL); | |
327 it->second->Expand(index); | |
328 } | |
329 } | |
330 | |
331 | |
332 void Apply(IArchiveVisitor& visitor) const | |
333 { | |
334 if (level_ == ResourceType_Instance) | |
335 { | |
336 for (std::list<Instance>::const_iterator | |
337 it = instances_.begin(); it != instances_.end(); ++it) | |
338 { | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
339 visitor.AddInstance(it->id_, it->uncompressedSize_); |
2632 | 340 } |
341 } | |
342 else | |
343 { | |
344 for (Resources::const_iterator it = resources_.begin(); | |
345 it != resources_.end(); ++it) | |
346 { | |
347 assert(it->second != NULL); // There must have been a call to "Expand()" | |
348 visitor.Open(level_, it->first); | |
349 it->second->Apply(visitor); | |
350 visitor.Close(); | |
351 } | |
352 } | |
353 } | |
354 }; | |
355 | |
356 | |
357 | |
358 class ArchiveJob::ZipCommands : public boost::noncopyable | |
359 { | |
360 private: | |
361 enum Type | |
362 { | |
363 Type_OpenDirectory, | |
364 Type_CloseDirectory, | |
365 Type_WriteInstance | |
366 }; | |
367 | |
368 class Command : public boost::noncopyable | |
369 { | |
370 private: | |
371 Type type_; | |
372 std::string filename_; | |
373 std::string instanceId_; | |
374 | |
375 public: | |
376 explicit Command(Type type) : | |
377 type_(type) | |
378 { | |
379 assert(type_ == Type_CloseDirectory); | |
380 } | |
381 | |
382 Command(Type type, | |
383 const std::string& filename) : | |
384 type_(type), | |
385 filename_(filename) | |
386 { | |
387 assert(type_ == Type_OpenDirectory); | |
388 } | |
389 | |
390 Command(Type type, | |
391 const std::string& filename, | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
392 const std::string& instanceId) : |
2632 | 393 type_(type), |
394 filename_(filename), | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
395 instanceId_(instanceId) |
2632 | 396 { |
397 assert(type_ == Type_WriteInstance); | |
398 } | |
399 | |
400 void Apply(HierarchicalZipWriter& writer, | |
401 ServerContext& context, | |
402 DicomDirWriter* dicomDir, | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
403 const std::string& dicomDirFolder, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
404 bool transcode, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
405 DicomTransferSyntax transferSyntax) const |
2632 | 406 { |
407 switch (type_) | |
408 { | |
409 case Type_OpenDirectory: | |
410 writer.OpenDirectory(filename_.c_str()); | |
411 break; | |
412 | |
413 case Type_CloseDirectory: | |
414 writer.CloseDirectory(); | |
415 break; | |
416 | |
417 case Type_WriteInstance: | |
418 { | |
419 std::string content; | |
420 | |
421 try | |
422 { | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
423 context.ReadDicom(content, instanceId_); |
2632 | 424 } |
425 catch (OrthancException& e) | |
426 { | |
427 LOG(WARNING) << "An instance was removed after the job was issued: " << instanceId_; | |
428 return; | |
429 } | |
2636 | 430 |
431 //boost::this_thread::sleep(boost::posix_time::milliseconds(300)); | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
432 |
2632 | 433 writer.OpenFile(filename_.c_str()); |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
434 |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
435 bool transcodeSuccess = false; |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
436 |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
437 std::unique_ptr<ParsedDicomFile> parsed; |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
438 |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
439 if (transcode) |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
440 { |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
441 // New in Orthanc 1.7.0 |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
442 std::set<DicomTransferSyntax> syntaxes; |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
443 syntaxes.insert(transferSyntax); |
3945
0b3256c3ee14
simplified IDicomTranscoder
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3930
diff
changeset
|
444 |
0b3256c3ee14
simplified IDicomTranscoder
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3930
diff
changeset
|
445 IDicomTranscoder::DicomImage source, transcoded; |
0b3256c3ee14
simplified IDicomTranscoder
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3930
diff
changeset
|
446 source.SetExternalBuffer(content); |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
447 |
3951
5fe8c6d3212e
removed useless information "hasSopInstanceUidChanged"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3945
diff
changeset
|
448 if (context.Transcode(transcoded, source, syntaxes, true /* allow new SOP instance UID */)) |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
449 { |
3945
0b3256c3ee14
simplified IDicomTranscoder
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3930
diff
changeset
|
450 writer.Write(transcoded.GetBufferData(), transcoded.GetBufferSize()); |
2632 | 451 |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
452 if (dicomDir != NULL) |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
453 { |
3945
0b3256c3ee14
simplified IDicomTranscoder
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3930
diff
changeset
|
454 std::unique_ptr<ParsedDicomFile> tmp(transcoded.ReleaseAsParsedDicomFile()); |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
455 dicomDir->Add(dicomDirFolder, filename_, *tmp); |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
456 } |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
457 |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
458 transcodeSuccess = true; |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
459 } |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
460 else |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
461 { |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
462 LOG(INFO) << "Cannot transcode instance " << instanceId_ |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
463 << " to transfer syntax: " << GetTransferSyntaxUid(transferSyntax); |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
464 } |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
465 } |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
466 |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
467 if (!transcodeSuccess) |
2632 | 468 { |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
469 writer.Write(content); |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
470 |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
471 if (dicomDir != NULL) |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
472 { |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
473 if (parsed.get() == NULL) |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
474 { |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
475 parsed.reset(new ParsedDicomFile(content)); |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
476 } |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
477 |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
478 dicomDir->Add(dicomDirFolder, filename_, *parsed); |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
479 } |
2632 | 480 } |
481 | |
482 break; | |
483 } | |
484 | |
485 default: | |
486 throw OrthancException(ErrorCode_InternalError); | |
487 } | |
488 } | |
489 }; | |
490 | |
491 std::deque<Command*> commands_; | |
492 uint64_t uncompressedSize_; | |
493 unsigned int instancesCount_; | |
494 | |
495 | |
496 void ApplyInternal(HierarchicalZipWriter& writer, | |
497 ServerContext& context, | |
498 size_t index, | |
499 DicomDirWriter* dicomDir, | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
500 const std::string& dicomDirFolder, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
501 bool transcode, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
502 DicomTransferSyntax transferSyntax) const |
2632 | 503 { |
504 if (index >= commands_.size()) | |
505 { | |
506 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
507 } | |
508 | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
509 commands_[index]->Apply(writer, context, dicomDir, dicomDirFolder, transcode, transferSyntax); |
2632 | 510 } |
511 | |
512 public: | |
513 ZipCommands() : | |
514 uncompressedSize_(0), | |
515 instancesCount_(0) | |
516 { | |
517 } | |
518 | |
519 ~ZipCommands() | |
520 { | |
521 for (std::deque<Command*>::iterator it = commands_.begin(); | |
522 it != commands_.end(); ++it) | |
523 { | |
524 assert(*it != NULL); | |
525 delete *it; | |
526 } | |
527 } | |
528 | |
529 size_t GetSize() const | |
530 { | |
531 return commands_.size(); | |
532 } | |
533 | |
534 unsigned int GetInstancesCount() const | |
535 { | |
536 return instancesCount_; | |
537 } | |
538 | |
539 uint64_t GetUncompressedSize() const | |
540 { | |
541 return uncompressedSize_; | |
542 } | |
543 | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
544 // "media" flavor (with DICOMDIR) |
2632 | 545 void Apply(HierarchicalZipWriter& writer, |
546 ServerContext& context, | |
547 size_t index, | |
548 DicomDirWriter& dicomDir, | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
549 const std::string& dicomDirFolder, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
550 bool transcode, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
551 DicomTransferSyntax transferSyntax) const |
2632 | 552 { |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
553 ApplyInternal(writer, context, index, &dicomDir, dicomDirFolder, transcode, transferSyntax); |
2632 | 554 } |
555 | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
556 // "archive" flavor (without DICOMDIR) |
2632 | 557 void Apply(HierarchicalZipWriter& writer, |
558 ServerContext& context, | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
559 size_t index, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
560 bool transcode, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
561 DicomTransferSyntax transferSyntax) const |
2632 | 562 { |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
563 ApplyInternal(writer, context, index, NULL, "", transcode, transferSyntax); |
2632 | 564 } |
565 | |
566 void AddOpenDirectory(const std::string& filename) | |
567 { | |
568 commands_.push_back(new Command(Type_OpenDirectory, filename)); | |
569 } | |
570 | |
571 void AddCloseDirectory() | |
572 { | |
573 commands_.push_back(new Command(Type_CloseDirectory)); | |
574 } | |
575 | |
576 void AddWriteInstance(const std::string& filename, | |
577 const std::string& instanceId, | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
578 uint64_t uncompressedSize) |
2632 | 579 { |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
580 commands_.push_back(new Command(Type_WriteInstance, filename, instanceId)); |
2632 | 581 instancesCount_ ++; |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
582 uncompressedSize_ += uncompressedSize; |
2632 | 583 } |
584 | |
585 bool IsZip64() const | |
586 { | |
587 return IsZip64Required(GetUncompressedSize(), GetInstancesCount()); | |
588 } | |
589 }; | |
590 | |
591 | |
592 | |
593 class ArchiveJob::ArchiveIndexVisitor : public IArchiveVisitor | |
594 { | |
595 private: | |
596 ZipCommands& commands_; | |
597 ServerContext& context_; | |
598 char instanceFormat_[24]; | |
599 unsigned int counter_; | |
600 | |
601 static std::string GetTag(const DicomMap& tags, | |
602 const DicomTag& tag) | |
603 { | |
604 const DicomValue* v = tags.TestAndGetValue(tag); | |
605 if (v != NULL && | |
606 !v->IsBinary() && | |
607 !v->IsNull()) | |
608 { | |
609 return v->GetContent(); | |
610 } | |
611 else | |
612 { | |
613 return ""; | |
614 } | |
615 } | |
616 | |
617 public: | |
618 ArchiveIndexVisitor(ZipCommands& commands, | |
619 ServerContext& context) : | |
620 commands_(commands), | |
621 context_(context), | |
622 counter_(0) | |
623 { | |
624 if (commands.GetSize() != 0) | |
625 { | |
626 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
627 } | |
628 | |
629 snprintf(instanceFormat_, sizeof(instanceFormat_) - 1, "%%08d.dcm"); | |
630 } | |
631 | |
632 virtual void Open(ResourceType level, | |
4205 | 633 const std::string& publicId) ORTHANC_OVERRIDE |
2632 | 634 { |
635 std::string path; | |
636 | |
637 DicomMap tags; | |
638 if (context_.GetIndex().GetMainDicomTags(tags, publicId, level, level)) | |
639 { | |
640 switch (level) | |
641 { | |
642 case ResourceType_Patient: | |
643 path = GetTag(tags, DICOM_TAG_PATIENT_ID) + " " + GetTag(tags, DICOM_TAG_PATIENT_NAME); | |
644 break; | |
645 | |
646 case ResourceType_Study: | |
647 path = GetTag(tags, DICOM_TAG_ACCESSION_NUMBER) + " " + GetTag(tags, DICOM_TAG_STUDY_DESCRIPTION); | |
648 break; | |
649 | |
650 case ResourceType_Series: | |
651 { | |
652 std::string modality = GetTag(tags, DICOM_TAG_MODALITY); | |
653 path = modality + " " + GetTag(tags, DICOM_TAG_SERIES_DESCRIPTION); | |
654 | |
655 if (modality.size() == 0) | |
656 { | |
657 snprintf(instanceFormat_, sizeof(instanceFormat_) - 1, "%%08d.dcm"); | |
658 } | |
659 else if (modality.size() == 1) | |
660 { | |
661 snprintf(instanceFormat_, sizeof(instanceFormat_) - 1, "%c%%07d.dcm", | |
662 toupper(modality[0])); | |
663 } | |
664 else if (modality.size() >= 2) | |
665 { | |
666 snprintf(instanceFormat_, sizeof(instanceFormat_) - 1, "%c%c%%06d.dcm", | |
667 toupper(modality[0]), toupper(modality[1])); | |
668 } | |
669 | |
670 counter_ = 0; | |
671 | |
672 break; | |
673 } | |
674 | |
675 default: | |
676 throw OrthancException(ErrorCode_InternalError); | |
677 } | |
678 } | |
679 | |
680 path = Toolbox::StripSpaces(Toolbox::ConvertToAscii(path)); | |
681 | |
682 if (path.empty()) | |
683 { | |
684 path = std::string("Unknown ") + EnumerationToString(level); | |
685 } | |
686 | |
687 commands_.AddOpenDirectory(path.c_str()); | |
688 } | |
689 | |
4205 | 690 virtual void Close() ORTHANC_OVERRIDE |
2632 | 691 { |
692 commands_.AddCloseDirectory(); | |
693 } | |
694 | |
695 virtual void AddInstance(const std::string& instanceId, | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
696 uint64_t uncompressedSize) ORTHANC_OVERRIDE |
2632 | 697 { |
698 char filename[24]; | |
699 snprintf(filename, sizeof(filename) - 1, instanceFormat_, counter_); | |
700 counter_ ++; | |
701 | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
702 commands_.AddWriteInstance(filename, instanceId, uncompressedSize); |
2632 | 703 } |
704 }; | |
705 | |
706 | |
707 class ArchiveJob::MediaIndexVisitor : public IArchiveVisitor | |
708 { | |
709 private: | |
710 ZipCommands& commands_; | |
711 unsigned int counter_; | |
712 | |
713 public: | |
4591
ff8170d17d90
moving all accesses to databases from IDatabaseWrapper to ITransaction
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4588
diff
changeset
|
714 explicit MediaIndexVisitor(ZipCommands& commands) : |
2632 | 715 commands_(commands), |
716 counter_(0) | |
717 { | |
718 } | |
719 | |
720 virtual void Open(ResourceType level, | |
4205 | 721 const std::string& publicId) ORTHANC_OVERRIDE |
2632 | 722 { |
723 } | |
724 | |
4205 | 725 virtual void Close() ORTHANC_OVERRIDE |
2632 | 726 { |
727 } | |
728 | |
729 virtual void AddInstance(const std::string& instanceId, | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
730 uint64_t uncompressedSize) ORTHANC_OVERRIDE |
2632 | 731 { |
732 // "DICOM restricts the filenames on DICOM media to 8 | |
733 // characters (some systems wrongly use 8.3, but this does not | |
734 // conform to the standard)." | |
735 std::string filename = "IM" + boost::lexical_cast<std::string>(counter_); | |
4509
98b7b9d21d83
removed ServerContext::ReadAttachment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
736 commands_.AddWriteInstance(filename, instanceId, uncompressedSize); |
2632 | 737 |
738 counter_ ++; | |
739 } | |
740 }; | |
741 | |
742 | |
743 class ArchiveJob::ZipWriterIterator : public boost::noncopyable | |
744 { | |
745 private: | |
3712
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
746 ServerContext& context_; |
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
747 ZipCommands commands_; |
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
748 std::unique_ptr<HierarchicalZipWriter> zip_; |
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
749 std::unique_ptr<DicomDirWriter> dicomDir_; |
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
750 bool isMedia_; |
2632 | 751 |
752 public: | |
4591
ff8170d17d90
moving all accesses to databases from IDatabaseWrapper to ITransaction
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4588
diff
changeset
|
753 ZipWriterIterator(const TemporaryFile& target, |
2632 | 754 ServerContext& context, |
755 ArchiveIndex& archive, | |
756 bool isMedia, | |
757 bool enableExtendedSopClass) : | |
758 context_(context), | |
759 isMedia_(isMedia) | |
760 { | |
761 if (isMedia) | |
762 { | |
4588 | 763 MediaIndexVisitor visitor(commands_); |
2632 | 764 archive.Expand(context.GetIndex()); |
765 | |
766 commands_.AddOpenDirectory(MEDIA_IMAGES_FOLDER); | |
767 archive.Apply(visitor); | |
768 commands_.AddCloseDirectory(); | |
769 | |
770 dicomDir_.reset(new DicomDirWriter); | |
771 dicomDir_->EnableExtendedSopClass(enableExtendedSopClass); | |
772 } | |
773 else | |
774 { | |
775 ArchiveIndexVisitor visitor(commands_, context); | |
776 archive.Expand(context.GetIndex()); | |
777 archive.Apply(visitor); | |
778 } | |
779 | |
780 zip_.reset(new HierarchicalZipWriter(target.GetPath().c_str())); | |
781 zip_->SetZip64(commands_.IsZip64()); | |
782 } | |
783 | |
784 size_t GetStepsCount() const | |
785 { | |
786 return commands_.GetSize() + 1; | |
787 } | |
788 | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
789 void RunStep(size_t index, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
790 bool transcode, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
791 DicomTransferSyntax transferSyntax) |
2632 | 792 { |
793 if (index > commands_.GetSize()) | |
794 { | |
795 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
796 } | |
797 else if (index == commands_.GetSize()) | |
798 { | |
799 // Last step: Add the DICOMDIR | |
800 if (isMedia_) | |
801 { | |
802 assert(dicomDir_.get() != NULL); | |
803 std::string s; | |
804 dicomDir_->Encode(s); | |
805 | |
806 zip_->OpenFile("DICOMDIR"); | |
807 zip_->Write(s); | |
808 } | |
809 } | |
810 else | |
811 { | |
812 if (isMedia_) | |
813 { | |
814 assert(dicomDir_.get() != NULL); | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
815 commands_.Apply(*zip_, context_, index, *dicomDir_, |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
816 MEDIA_IMAGES_FOLDER, transcode, transferSyntax); |
2632 | 817 } |
818 else | |
819 { | |
820 assert(dicomDir_.get() == NULL); | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
821 commands_.Apply(*zip_, context_, index, transcode, transferSyntax); |
2632 | 822 } |
823 } | |
824 } | |
825 | |
826 unsigned int GetInstancesCount() const | |
827 { | |
828 return commands_.GetInstancesCount(); | |
829 } | |
830 | |
831 uint64_t GetUncompressedSize() const | |
832 { | |
833 return commands_.GetUncompressedSize(); | |
834 } | |
835 }; | |
836 | |
837 | |
2966 | 838 ArchiveJob::ArchiveJob(ServerContext& context, |
2632 | 839 bool isMedia, |
840 bool enableExtendedSopClass) : | |
841 context_(context), | |
842 archive_(new ArchiveIndex(ResourceType_Patient)), // root | |
843 isMedia_(isMedia), | |
844 enableExtendedSopClass_(enableExtendedSopClass), | |
845 currentStep_(0), | |
846 instancesCount_(0), | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
847 uncompressedSize_(0), |
4341
977c2759eb0a
Archive/media jobs report the size of the created ZIP file in content field "ArchiveSizeMB"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4205
diff
changeset
|
848 archiveSize_(0), |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
849 transcode_(false), |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
850 transferSyntax_(DicomTransferSyntax_LittleEndianImplicit) |
2632 | 851 { |
2966 | 852 } |
853 | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
854 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
855 ArchiveJob::~ArchiveJob() |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
856 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
857 if (!mediaArchiveId_.empty()) |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
858 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
859 context_.GetMediaArchive().Remove(mediaArchiveId_); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
860 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
861 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
862 |
2966 | 863 |
864 void ArchiveJob::SetSynchronousTarget(boost::shared_ptr<TemporaryFile>& target) | |
865 { | |
866 if (target.get() == NULL) | |
2632 | 867 { |
868 throw OrthancException(ErrorCode_NullPointer); | |
869 } | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
870 else if (writer_.get() != NULL || // Already started |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
871 synchronousTarget_.get() != NULL || |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
872 asynchronousTarget_.get() != NULL) |
2966 | 873 { |
874 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
875 } | |
876 else | |
877 { | |
878 synchronousTarget_ = target; | |
879 } | |
2632 | 880 } |
881 | |
882 | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
883 void ArchiveJob::SetDescription(const std::string& description) |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
884 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
885 if (writer_.get() != NULL) // Already started |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
886 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
887 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
888 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
889 else |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
890 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
891 description_ = description; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
892 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
893 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
894 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
895 |
2632 | 896 void ArchiveJob::AddResource(const std::string& publicId) |
897 { | |
898 if (writer_.get() != NULL) // Already started | |
899 { | |
900 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
901 } | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
902 else |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
903 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
904 ResourceIdentifiers resource(context_.GetIndex(), publicId); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
905 archive_->Add(context_.GetIndex(), resource); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
906 } |
2632 | 907 } |
908 | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
909 |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
910 void ArchiveJob::SetTranscode(DicomTransferSyntax transferSyntax) |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
911 { |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
912 if (writer_.get() != NULL) // Already started |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
913 { |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
914 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
915 } |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
916 else |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
917 { |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
918 transcode_ = true; |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
919 transferSyntax_ = transferSyntax; |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
920 } |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
921 } |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
922 |
2632 | 923 |
2812
ea7aea6f6a95
improved naming of methods in IJob
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2730
diff
changeset
|
924 void ArchiveJob::Reset() |
2632 | 925 { |
2955 | 926 throw OrthancException(ErrorCode_BadSequenceOfCalls, |
927 "Cannot resubmit the creation of an archive"); | |
2632 | 928 } |
929 | |
930 | |
931 void ArchiveJob::Start() | |
932 { | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
933 TemporaryFile* target = NULL; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
934 |
2966 | 935 if (synchronousTarget_.get() == NULL) |
936 { | |
3181
6fd38327e777
Fix issue #130 (Orthanc failed to start when /tmp partition was full)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3095
diff
changeset
|
937 { |
6fd38327e777
Fix issue #130 (Orthanc failed to start when /tmp partition was full)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3095
diff
changeset
|
938 OrthancConfiguration::ReaderLock lock; |
6fd38327e777
Fix issue #130 (Orthanc failed to start when /tmp partition was full)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3095
diff
changeset
|
939 asynchronousTarget_.reset(lock.GetConfiguration().CreateTemporaryFile()); |
6fd38327e777
Fix issue #130 (Orthanc failed to start when /tmp partition was full)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3095
diff
changeset
|
940 } |
6fd38327e777
Fix issue #130 (Orthanc failed to start when /tmp partition was full)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3095
diff
changeset
|
941 |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
942 target = asynchronousTarget_.get(); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
943 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
944 else |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
945 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
946 target = synchronousTarget_.get(); |
2966 | 947 } |
3181
6fd38327e777
Fix issue #130 (Orthanc failed to start when /tmp partition was full)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3095
diff
changeset
|
948 |
6fd38327e777
Fix issue #130 (Orthanc failed to start when /tmp partition was full)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3095
diff
changeset
|
949 assert(target != NULL); |
6fd38327e777
Fix issue #130 (Orthanc failed to start when /tmp partition was full)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3095
diff
changeset
|
950 target->Touch(); // Make sure we can write to the temporary file |
2966 | 951 |
2632 | 952 if (writer_.get() != NULL) |
953 { | |
954 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
955 } | |
956 | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
957 writer_.reset(new ZipWriterIterator(*target, context_, *archive_, |
2632 | 958 isMedia_, enableExtendedSopClass_)); |
959 | |
960 instancesCount_ = writer_->GetInstancesCount(); | |
961 uncompressedSize_ = writer_->GetUncompressedSize(); | |
962 } | |
963 | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
964 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
965 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
966 namespace |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
967 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
968 class DynamicTemporaryFile : public IDynamicObject |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
969 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
970 private: |
3712
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
971 std::unique_ptr<TemporaryFile> file_; |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
972 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
973 public: |
4205 | 974 explicit DynamicTemporaryFile(TemporaryFile* f) : file_(f) |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
975 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
976 if (f == NULL) |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
977 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
978 throw OrthancException(ErrorCode_NullPointer); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
979 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
980 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
981 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
982 const TemporaryFile& GetFile() const |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
983 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
984 assert(file_.get() != NULL); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
985 return *file_; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
986 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
987 }; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
988 } |
2632 | 989 |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
990 |
4341
977c2759eb0a
Archive/media jobs report the size of the created ZIP file in content field "ArchiveSizeMB"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4205
diff
changeset
|
991 void ArchiveJob::RefreshArchiveSize() |
977c2759eb0a
Archive/media jobs report the size of the created ZIP file in content field "ArchiveSizeMB"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4205
diff
changeset
|
992 { |
977c2759eb0a
Archive/media jobs report the size of the created ZIP file in content field "ArchiveSizeMB"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4205
diff
changeset
|
993 if (synchronousTarget_.get() != NULL) |
977c2759eb0a
Archive/media jobs report the size of the created ZIP file in content field "ArchiveSizeMB"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4205
diff
changeset
|
994 { |
977c2759eb0a
Archive/media jobs report the size of the created ZIP file in content field "ArchiveSizeMB"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4205
diff
changeset
|
995 archiveSize_ = synchronousTarget_->GetFileSize(); |
977c2759eb0a
Archive/media jobs report the size of the created ZIP file in content field "ArchiveSizeMB"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4205
diff
changeset
|
996 } |
977c2759eb0a
Archive/media jobs report the size of the created ZIP file in content field "ArchiveSizeMB"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4205
diff
changeset
|
997 |
977c2759eb0a
Archive/media jobs report the size of the created ZIP file in content field "ArchiveSizeMB"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4205
diff
changeset
|
998 if (asynchronousTarget_.get() != NULL) |
977c2759eb0a
Archive/media jobs report the size of the created ZIP file in content field "ArchiveSizeMB"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4205
diff
changeset
|
999 { |
977c2759eb0a
Archive/media jobs report the size of the created ZIP file in content field "ArchiveSizeMB"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4205
diff
changeset
|
1000 archiveSize_ = asynchronousTarget_->GetFileSize(); |
977c2759eb0a
Archive/media jobs report the size of the created ZIP file in content field "ArchiveSizeMB"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4205
diff
changeset
|
1001 } |
977c2759eb0a
Archive/media jobs report the size of the created ZIP file in content field "ArchiveSizeMB"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4205
diff
changeset
|
1002 } |
977c2759eb0a
Archive/media jobs report the size of the created ZIP file in content field "ArchiveSizeMB"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4205
diff
changeset
|
1003 |
977c2759eb0a
Archive/media jobs report the size of the created ZIP file in content field "ArchiveSizeMB"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4205
diff
changeset
|
1004 |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1005 void ArchiveJob::FinalizeTarget() |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1006 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1007 writer_.reset(); // Flush all the results |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1008 |
4341
977c2759eb0a
Archive/media jobs report the size of the created ZIP file in content field "ArchiveSizeMB"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4205
diff
changeset
|
1009 RefreshArchiveSize(); |
977c2759eb0a
Archive/media jobs report the size of the created ZIP file in content field "ArchiveSizeMB"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4205
diff
changeset
|
1010 |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1011 if (asynchronousTarget_.get() != NULL) |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1012 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1013 // Asynchronous behavior: Move the resulting file into the media archive |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1014 mediaArchiveId_ = context_.GetMediaArchive().Add( |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1015 new DynamicTemporaryFile(asynchronousTarget_.release())); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1016 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1017 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1018 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1019 |
3658
2d90dd30858c
providing job ID to the IJob::Step() methods
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
1020 JobStepResult ArchiveJob::Step(const std::string& jobId) |
2632 | 1021 { |
1022 assert(writer_.get() != NULL); | |
1023 | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1024 if (synchronousTarget_.get() != NULL && |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1025 synchronousTarget_.unique()) |
2632 | 1026 { |
1027 LOG(WARNING) << "A client has disconnected while creating an archive"; | |
3240
e44e0127e553
Fix issue #134 (/patient/modify gives 500, should really be 400)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3181
diff
changeset
|
1028 return JobStepResult::Failure(ErrorCode_NetworkProtocol, |
e44e0127e553
Fix issue #134 (/patient/modify gives 500, should really be 400)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3181
diff
changeset
|
1029 "A client has disconnected while creating an archive"); |
2632 | 1030 } |
4341
977c2759eb0a
Archive/media jobs report the size of the created ZIP file in content field "ArchiveSizeMB"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4205
diff
changeset
|
1031 |
2632 | 1032 if (writer_->GetStepsCount() == 0) |
1033 { | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1034 FinalizeTarget(); |
2632 | 1035 return JobStepResult::Success(); |
1036 } | |
1037 else | |
1038 { | |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1039 writer_->RunStep(currentStep_, transcode_, transferSyntax_); |
2632 | 1040 |
1041 currentStep_ ++; | |
1042 | |
1043 if (currentStep_ == writer_->GetStepsCount()) | |
1044 { | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1045 FinalizeTarget(); |
2632 | 1046 return JobStepResult::Success(); |
1047 } | |
1048 else | |
1049 { | |
4341
977c2759eb0a
Archive/media jobs report the size of the created ZIP file in content field "ArchiveSizeMB"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4205
diff
changeset
|
1050 RefreshArchiveSize(); |
2632 | 1051 return JobStepResult::Continue(); |
1052 } | |
1053 } | |
1054 } | |
1055 | |
1056 | |
1057 float ArchiveJob::GetProgress() | |
1058 { | |
1059 if (writer_.get() == NULL || | |
1060 writer_->GetStepsCount() == 0) | |
1061 { | |
1062 return 1; | |
1063 } | |
1064 else | |
1065 { | |
1066 return (static_cast<float>(currentStep_) / | |
1067 static_cast<float>(writer_->GetStepsCount() - 1)); | |
1068 } | |
1069 } | |
1070 | |
1071 | |
1072 void ArchiveJob::GetJobType(std::string& target) | |
1073 { | |
1074 if (isMedia_) | |
1075 { | |
1076 target = "Media"; | |
1077 } | |
1078 else | |
1079 { | |
1080 target = "Archive"; | |
1081 } | |
1082 } | |
1083 | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1084 |
2632 | 1085 void ArchiveJob::GetPublicContent(Json::Value& value) |
1086 { | |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1087 value = Json::objectValue; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1088 value[KEY_DESCRIPTION] = description_; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1089 value[KEY_INSTANCES_COUNT] = instancesCount_; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1090 value[KEY_UNCOMPRESSED_SIZE_MB] = |
2643 | 1091 static_cast<unsigned int>(uncompressedSize_ / MEGA_BYTES); |
4341
977c2759eb0a
Archive/media jobs report the size of the created ZIP file in content field "ArchiveSizeMB"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4205
diff
changeset
|
1092 value[KEY_ARCHIVE_SIZE_MB] = |
977c2759eb0a
Archive/media jobs report the size of the created ZIP file in content field "ArchiveSizeMB"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4205
diff
changeset
|
1093 static_cast<unsigned int>(archiveSize_ / MEGA_BYTES); |
3913
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1094 |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1095 if (transcode_) |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1096 { |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1097 value[KEY_TRANSCODE] = GetTransferSyntaxUid(transferSyntax_); |
6ddad3e0b569
transcoding ZIP archive and media
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3713
diff
changeset
|
1098 } |
2632 | 1099 } |
2976
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1100 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1101 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1102 bool ArchiveJob::GetOutput(std::string& output, |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1103 MimeType& mime, |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1104 const std::string& key) |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1105 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1106 if (key == "archive" && |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1107 !mediaArchiveId_.empty()) |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1108 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1109 SharedArchive::Accessor accessor(context_.GetMediaArchive(), mediaArchiveId_); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1110 |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1111 if (accessor.IsValid()) |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1112 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1113 const DynamicTemporaryFile& f = dynamic_cast<DynamicTemporaryFile&>(accessor.GetItem()); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1114 f.GetFile().Read(output); |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1115 mime = MimeType_Zip; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1116 return true; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1117 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1118 else |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1119 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1120 return false; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1121 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1122 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1123 else |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1124 { |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1125 return false; |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1126 } |
cb5d75143da0
Asynchronous generation of ZIP archives and DICOM medias
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
2966
diff
changeset
|
1127 } |
2632 | 1128 } |