comparison Resources/Samples/Python/Replicate.py @ 1351:fa09aa513fd4

script to copy one server to another
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 30 Apr 2015 15:17:40 +0200
parents
children b1291df2f780
comparison
equal deleted inserted replaced
1350:724dc4e17d38 1351:fa09aa513fd4
1 #!/usr/bin/python
2
3 # Orthanc - A Lightweight, RESTful DICOM Store
4 # Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics
5 # Department, University Hospital of Liege, Belgium
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 # This program is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 # General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20
21 import base64
22 import httplib2
23 import json
24 import re
25 import sys
26
27 URL_REGEX = re.compile('(http|https)://((.+?):(.+?)@|)(.*)')
28
29
30 if len(sys.argv) != 3:
31 print("""
32 Script to copy the content of one Orthanc server to another Orthanc
33 server through their REST API.
34
35 Usage: %s [SourceURI] [TargetURI]
36 For instance: %s http://orthanc:password@localhost:8042/ http://localhost:8043/
37 """ % (sys.argv[0], sys.argv[0]))
38 exit(-1)
39
40
41
42 def CreateHeaders(parsedUrl):
43 headers = { }
44 username = parsedUrl.group(3)
45 password = parsedUrl.group(4)
46
47 if username != None and password != None:
48 # This is a custom reimplementation of the
49 # "Http.add_credentials()" method for Basic HTTP Access
50 # Authentication (for some weird reason, this method does not
51 # always work)
52 # http://en.wikipedia.org/wiki/Basic_access_authentication
53 headers['authorization'] = 'Basic ' + base64.b64encode(username + ':' + password)
54
55 return headers
56
57
58 def GetBaseUrl(parsedUrl):
59 return '%s://%s' % (parsedUrl.group(1), parsedUrl.group(5))
60
61
62 def DoGetString(url):
63 global URL_REGEX
64 parsedUrl = URL_REGEX.match(url)
65 headers = CreateHeaders(parsedUrl)
66
67 h = httplib2.Http()
68 resp, content = h.request(GetBaseUrl(parsedUrl), 'GET', headers = headers)
69
70 if resp.status == 200:
71 return content
72 else:
73 raise Exception('Unable to contact Orthanc at: ' + url)
74
75
76 def DoPostDicom(url, body):
77 global URL_REGEX
78 parsedUrl = URL_REGEX.match(url)
79 headers = CreateHeaders(parsedUrl)
80 headers['content-type'] = 'application/dicom'
81
82 h = httplib2.Http()
83 resp, content = h.request(GetBaseUrl(parsedUrl), 'POST',
84 body = body,
85 headers = headers)
86
87 if resp.status != 200:
88 raise Exception('Unable to contact Orthanc at: ' + url)
89
90
91 def _DecodeJson(s):
92 if (sys.version_info >= (3, 0)):
93 return json.loads(s.decode())
94 else:
95 return json.loads(s)
96
97
98 def DoGetJson(url):
99 return _DecodeJson(DoGetString(url))
100
101
102 SOURCE = sys.argv[1]
103 TARGET = sys.argv[2]
104
105 for study in DoGetJson('%s/studies' % SOURCE):
106 print('Sending study %s...' % study)
107 for instance in DoGetJson('%s/studies/%s/instances' % (SOURCE, study)):
108 dicom = DoGetString('%s/instances/%s/file' % (SOURCE, instance['ID']))
109 DoPostDicom('%s/instances' % TARGET, dicom)