This diff has been collapsed as it changes many lines, (556 lines changed)
Show them
Hide them
|
|
@@
-1,1044
+1,500
|
|
1
|
from ckanapi import RemoteCKAN
|
|
1
|
from ckanapi import RemoteCKAN
|
|
2
|
from datetime import datetime
|
|
2
|
from datetime import datetime
|
|
3
|
from tqdm import tqdm
|
|
|
|
|
4
|
from CKAN_JRO import logic_download
|
|
3
|
from CKAN_JRO import logic_download
|
|
5
|
from CKAN_JRO import resource
|
|
4
|
from CKAN_JRO import resource
|
|
6
|
#from ckanapi.errors import NotAuthorized, NotFound, ValidationError, SearchQueryError, SearchError, CKANAPIError, ServerIncompatibleError
|
|
5
|
#from ckanapi.errors import NotAuthorized, NotFound, ValidationError, SearchQueryError, SearchError, CKANAPIError, ServerIncompatibleError
|
|
7
|
import sys
|
|
6
|
import sys
|
|
8
|
import platform
|
|
7
|
import platform
|
|
9
|
import os
|
|
8
|
import os
|
|
10
|
import tempfile
|
|
|
|
|
11
|
import shutil
|
|
|
|
|
12
|
import zipfile
|
|
|
|
|
13
|
import concurrent.futures
|
|
|
|
|
14
|
import requests
|
|
9
|
import requests
|
|
15
|
import json
|
|
|
|
|
16
|
#import pathlib
|
|
|
|
|
17
|
import uuid
|
|
|
|
|
18
|
|
|
|
|
|
19
|
if sys.version_info.major == 3:
|
|
|
|
|
20
|
from urllib.parse import urlparse
|
|
|
|
|
21
|
else:
|
|
|
|
|
22
|
import urlparse
|
|
|
|
|
23
|
|
|
10
|
|
|
24
|
class JROAPI():
|
|
11
|
class JROAPI():
|
|
25
|
"""
|
|
12
|
"""
|
|
26
|
FINALIDAD:
|
|
13
|
FINALIDAD:
|
|
27
|
Script para administrar y obtener la data del repositorio por medio de APIs.
|
|
14
|
Script para administrar y obtener la data del repositorio por medio de APIs.
|
|
28
|
|
|
15
|
|
|
29
|
REQUISITIOS PREVIOS:
|
|
16
|
REQUISITIOS PREVIOS:
|
|
30
|
- Paso 1: Tener "pip [Python 2]" o "pip3 [Python 3]" instalado:
|
|
17
|
- Paso 1: Tener "pip [Python 2]" o "pip3 [Python 3]" instalado:
|
|
31
|
- Paso 2: Instalar lo siguiente como admininstrador:
|
|
18
|
- Paso 2: Instalar los siguientes paquetes:
|
|
32
|
En Python 2
|
|
19
|
ckanapi==4.7
|
|
33
|
- pip install ckanapi==4.5
|
|
20
|
requests
|
|
34
|
- pip install requests
|
|
|
|
|
35
|
- pip install futures
|
|
|
|
|
36
|
- pip install tqdm
|
|
|
|
|
37
|
En Python > 3
|
|
|
|
|
38
|
- pip3 install ckanapi==4.5
|
|
|
|
|
39
|
- pip3 install requests
|
|
|
|
|
40
|
- pip3 install tqdm
|
|
|
|
|
41
|
|
|
21
|
|
|
42
|
FUNCIONES DISPONIBLES:
|
|
22
|
FUNCIONES DISPONIBLES:
|
|
43
|
- action
|
|
23
|
- action
|
|
44
|
- upload_file
|
|
|
|
|
45
|
- upload_multiple_files
|
|
|
|
|
46
|
- upload_multiple_files_advance
|
|
|
|
|
47
|
- show
|
|
24
|
- show
|
|
48
|
- search
|
|
25
|
- search
|
|
49
|
- create
|
|
26
|
- create
|
|
50
|
- patch
|
|
27
|
- patch
|
|
51
|
- delete
|
|
28
|
- delete
|
|
52
|
- download_files
|
|
29
|
- download_files
|
|
53
|
|
|
30
|
|
|
54
|
EJEMPLOS:
|
|
31
|
EJEMPLOS:
|
|
55
|
#1:
|
|
32
|
#1:
|
|
56
|
with JROAPI('http://demo.example.com', Authorization='#########') as <access_name>:
|
|
33
|
with JROAPI('http://demo.example.com', Authorization='#########') as <access_name>:
|
|
57
|
... some operation(s) ...
|
|
34
|
... some operation(s) ...
|
|
58
|
#2:
|
|
35
|
#2:
|
|
59
|
<access_name> = JROAPI('http://example.com', Authorization='#########')
|
|
36
|
<access_name> = JROAPI('http://example.com', Authorization='#########')
|
|
60
|
... some operation(s) ...
|
|
37
|
... some operation(s) ...
|
|
61
|
<access_name>.ckan.close()
|
|
38
|
<access_name>.ckan.close()
|
|
62
|
|
|
39
|
|
|
63
|
REPORTAR ALGUN PROBLEMA:
|
|
40
|
REPORTAR ALGUN PROBLEMA:
|
|
64
|
Debe enviar un correo a eynilupu@igp.gob.pe detallando los siguientes pasos:
|
|
41
|
Debe enviar un correo a eynilupu@igp.gob.pe detallando los siguientes pasos:
|
|
65
|
1) Correo para contactarlo
|
|
42
|
1) Correo para contactarlo
|
|
66
|
2) Descripcion del problema
|
|
43
|
2) Descripcion del problema
|
|
67
|
3) ¿En que paso o seccion encontro el problema?
|
|
44
|
3) ¿En que paso o seccion encontro el problema?
|
|
68
|
4) ¿Cual era el resultado que usted esperaba?
|
|
45
|
4) ¿Cual era el resultado que usted esperaba?
|
|
69
|
"""
|
|
46
|
"""
|
|
70
|
def __init__(self, url, Authorization=None, secure=True):
|
|
47
|
def __init__(self, url, Authorization=None, secure=True):
|
|
71
|
#-------- Check Secure -------#
|
|
48
|
#-------- Check Secure -------#
|
|
72
|
self.verify = secure
|
|
49
|
self.verify = secure
|
|
73
|
if not secure and isinstance(secure, bool):
|
|
50
|
if not secure and isinstance(secure, bool):
|
|
74
|
session = requests.Session()
|
|
51
|
session = requests.Session()
|
|
75
|
session.verify = False
|
|
52
|
session.verify = False
|
|
76
|
else:
|
|
53
|
else:
|
|
77
|
session = None
|
|
54
|
session = None
|
|
78
|
#------------------------------#
|
|
55
|
#------------------------------#
|
|
79
|
self.url = url
|
|
56
|
self.url = url
|
|
80
|
ua = 'CKAN_JRO/2.9.2 (+'+str(self.url)+')'
|
|
57
|
ua = 'CKAN_JRO/2.9.2 (+'+str(self.url)+')'
|
|
81
|
#ua = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'
|
|
58
|
#ua = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'
|
|
82
|
self.ckan = RemoteCKAN(self.url, apikey=Authorization, user_agent=ua, session=session)
|
|
59
|
self.ckan = RemoteCKAN(self.url, apikey=Authorization, user_agent=ua, session=session)
|
|
83
|
#self.ckan = RemoteCKAN(self.url, apikey=Authorization)
|
|
60
|
#self.ckan = RemoteCKAN(self.url, apikey=Authorization)
|
|
84
|
self.Authorization = Authorization
|
|
61
|
self.Authorization = Authorization
|
|
85
|
# Change for --> self.separator = os.sep
|
|
62
|
# Change for --> self.separator = os.sep
|
|
86
|
if platform.system() == 'Windows':
|
|
63
|
if platform.system() == 'Windows':
|
|
87
|
self.separator = '\\'
|
|
64
|
self.separator = '\\'
|
|
88
|
else:
|
|
65
|
else:
|
|
89
|
self.separator = '/'
|
|
66
|
self.separator = '/'
|
|
90
|
|
|
67
|
|
|
91
|
self.chunk_size = 1024
|
|
68
|
self.chunk_size = 1024
|
|
92
|
self.list = []
|
|
69
|
self.list = []
|
|
93
|
self.dict = {}
|
|
70
|
self.dict = {}
|
|
94
|
self.str = ''
|
|
71
|
self.str = ''
|
|
95
|
self.check = 1
|
|
72
|
self.check = 1
|
|
96
|
self.cont = 0
|
|
73
|
self.cont = 0
|
|
97
|
|
|
74
|
|
|
98
|
def __enter__(self):
|
|
75
|
def __enter__(self):
|
|
99
|
return self
|
|
76
|
return self
|
|
100
|
|
|
77
|
|
|
101
|
def __exit__(self, *args):
|
|
78
|
def __exit__(self, *args):
|
|
102
|
self.ckan.close()
|
|
79
|
self.ckan.close()
|
|
103
|
|
|
80
|
|
|
104
|
def action(self, action, **kwargs):
|
|
81
|
def action(self, action, **kwargs):
|
|
105
|
"""
|
|
82
|
"""
|
|
106
|
FINALIDAD:
|
|
83
|
FINALIDAD:
|
|
107
|
Funcion para llamar a las APIs disponibles
|
|
84
|
Funcion para llamar a las APIs disponibles
|
|
108
|
|
|
85
|
|
|
109
|
APIs DISPONIBLES:
|
|
86
|
APIs DISPONIBLES:
|
|
110
|
CONSULTAR: "GUIA DE SCRIPT.pdf"
|
|
87
|
CONSULTAR: "GUIA DE SCRIPT.pdf"
|
|
111
|
|
|
88
|
|
|
112
|
EJEMPLO:
|
|
89
|
EJEMPLO:
|
|
113
|
<access_name>.action(<consuming API>, param_1 = <class 'param_1'>, ...)
|
|
90
|
<access_name>.action(<consuming API>, param_1 = <class 'param_1'>, ...)
|
|
114
|
"""
|
|
91
|
"""
|
|
115
|
#--------------- CASE: PACKAGE SEARCH ---------------#
|
|
92
|
#--------------- CASE: PACKAGE SEARCH ---------------#
|
|
116
|
if kwargs is not None:
|
|
93
|
if kwargs is not None:
|
|
117
|
if action == 'package_search':
|
|
94
|
if action == 'package_search':
|
|
118
|
self.list = ['facet_mincount', 'facet_limit', 'facet_field']
|
|
95
|
self.list = ['facet_mincount', 'facet_limit', 'facet_field']
|
|
119
|
for facet in self.list:
|
|
96
|
for facet in self.list:
|
|
120
|
if facet in kwargs:
|
|
97
|
if facet in kwargs:
|
|
121
|
kwargs[facet.replace('_', '.')] = kwargs[facet]
|
|
98
|
kwargs[facet.replace('_', '.')] = kwargs[facet]
|
|
122
|
kwargs.pop(facet)
|
|
99
|
kwargs.pop(facet)
|
|
123
|
#----------------------------------------------------#
|
|
100
|
#----------------------------------------------------#
|
|
124
|
try:
|
|
101
|
try:
|
|
125
|
return getattr(self.ckan.action, action)(**kwargs)
|
|
102
|
return getattr(self.ckan.action, action)(**kwargs)
|
|
126
|
except:
|
|
103
|
except:
|
|
127
|
_, exc_value, _ = sys.exc_info()
|
|
104
|
_, exc_value, _ = sys.exc_info()
|
|
128
|
return exc_value
|
|
105
|
return exc_value
|
|
129
|
|
|
106
|
|
|
130
|
def upload_file(self, dataset_id, file_date, file_type, file_path=False, url_or_path=False, ignore_repetition=False, **kwargs):
|
|
|
|
|
131
|
# Agregar si es interruptido por teclado
|
|
|
|
|
132
|
'''
|
|
|
|
|
133
|
FINALIDAD:
|
|
|
|
|
134
|
Funcion para crear un unico recurso (puede incluir un archivo asociado) al repositorio del ROJ.
|
|
|
|
|
135
|
|
|
|
|
|
136
|
PARAMETROS DISPONIBLES:
|
|
|
|
|
137
|
CONSULTAR: "GUIA DE SCRIPT.pdf"
|
|
|
|
|
138
|
|
|
|
|
|
139
|
ESTRUCTURA:
|
|
|
|
|
140
|
<access_name>.upload_file(dataset_id = <class 'str'>, file_date = <class 'str'>, file_type = <class 'str'>, file_path = <class 'str'>, url_or_path = <class 'str'>, param_1 = <class 'param_1'>, ...)
|
|
|
|
|
141
|
'''
|
|
|
|
|
142
|
#self.list = ['package_id', 'upload', 'voc_file_type', 'name'] #file_date
|
|
|
|
|
143
|
self.list = ['package_id', 'upload', 'voc_file_type'] #file_date
|
|
|
|
|
144
|
for key1, value1 in kwargs.items():
|
|
|
|
|
145
|
if not key1 in self.list:
|
|
|
|
|
146
|
self.dict[key1] = value1
|
|
|
|
|
147
|
|
|
|
|
|
148
|
#---------------------------#
|
|
|
|
|
149
|
if not 'others' in kwargs:
|
|
|
|
|
150
|
self.dict['others'] = ''
|
|
|
|
|
151
|
else:
|
|
|
|
|
152
|
if isinstance(kwargs['others'], list):
|
|
|
|
|
153
|
self.dict['others'] = json.dumps(kwargs['others'])
|
|
|
|
|
154
|
#---------------------------#
|
|
|
|
|
155
|
|
|
|
|
|
156
|
if isinstance(file_path, str) and isinstance(url_or_path, str):
|
|
|
|
|
157
|
return 'ERROR:: Choose one: "file_path" or "url_or_path" parameters'
|
|
|
|
|
158
|
|
|
|
|
|
159
|
if isinstance(file_path, str):
|
|
|
|
|
160
|
if not os.path.isfile(file_path):
|
|
|
|
|
161
|
return 'File "%s" not exist' % (file_path)
|
|
|
|
|
162
|
|
|
|
|
|
163
|
self.dict['upload'] = open(file_path, 'rb')
|
|
|
|
|
164
|
self.dict['name'] = os.path.basename(file_path)
|
|
|
|
|
165
|
elif isinstance(url_or_path, str):
|
|
|
|
|
166
|
self.dict['url'] = url_or_path
|
|
|
|
|
167
|
if not 'name' in self.dict:
|
|
|
|
|
168
|
self.dict['name'] = os.path.basename(url_or_path)
|
|
|
|
|
169
|
else:
|
|
|
|
|
170
|
return 'ERROR: Verify "file_path" or "url_or_path" parameters: <class "str"> or choose one'
|
|
|
|
|
171
|
|
|
|
|
|
172
|
#if not 'format' in self.dict:
|
|
|
|
|
173
|
# self.str = ''.join(pathlib.Path(file_path).suffixes)
|
|
|
|
|
174
|
# if len(self.str) > 0:
|
|
|
|
|
175
|
# self.dict['format'] = self.str.upper()[1:]
|
|
|
|
|
176
|
|
|
|
|
|
177
|
#-------------------------PACKAGE SHOW-----------------------#
|
|
|
|
|
178
|
try:
|
|
|
|
|
179
|
dataset_show = getattr(self.ckan.action, 'package_show')(id=dataset_id)['resources']
|
|
|
|
|
180
|
except:
|
|
|
|
|
181
|
_, exc_value, _ = sys.exc_info()
|
|
|
|
|
182
|
print('ERROR obtaining metadata dataset:: Use the "print" for more information')
|
|
|
|
|
183
|
return exc_value
|
|
|
|
|
184
|
|
|
|
|
|
185
|
resources_name = []
|
|
|
|
|
186
|
for u in dataset_show:
|
|
|
|
|
187
|
resources_name.append(u['name'].lower())
|
|
|
|
|
188
|
|
|
|
|
|
189
|
if self.dict['name'].lower() in resources_name:
|
|
|
|
|
190
|
if not ignore_repetition:
|
|
|
|
|
191
|
return 'ERROR:: "%s" resource already exist in this dataset' % (self.dict['name'])
|
|
|
|
|
192
|
print('WARRING:: "'+ str(self.dict['name']) +'" resource already exist in this dataset')
|
|
|
|
|
193
|
#------------------------------------------------------------#
|
|
|
|
|
194
|
try:
|
|
|
|
|
195
|
return getattr(self.ckan.action, 'resource_create')(package_id=dataset_id, file_date=file_date, voc_file_type=file_type, **self.dict)
|
|
|
|
|
196
|
except:
|
|
|
|
|
197
|
_, exc_value, _ = sys.exc_info()
|
|
|
|
|
198
|
return exc_value
|
|
|
|
|
199
|
|
|
|
|
|
200
|
def upload_multiple_files_advance(self, dataset_id, path_files, file_date, file_type, max_size=100, max_count=500, ignore_repetition=False, **kwargs):
|
|
|
|
|
201
|
# Agregar si es interruptido por teclado
|
|
|
|
|
202
|
'''
|
|
|
|
|
203
|
FINALIDAD:
|
|
|
|
|
204
|
Funcion para subir multiples archivos al repositorio del ROJ.
|
|
|
|
|
205
|
|
|
|
|
|
206
|
PARAMETROS DISPONIBLES:
|
|
|
|
|
207
|
CONSULTAR: "GUIA DE SCRIPT.pdf"
|
|
|
|
|
208
|
|
|
|
|
|
209
|
ESTRUCTURA:
|
|
|
|
|
210
|
<access_name>.upload_multiple_files_advance(dataset_id = <class 'str'>, path_files = <class 'list of strings'>, file_date = <class 'str'>, file_type = <class 'str'>, param_1 = <class 'param_1'>, ...)
|
|
|
|
|
211
|
'''
|
|
|
|
|
212
|
#-------------------------PACKAGE SHOW-----------------------#
|
|
|
|
|
213
|
try:
|
|
|
|
|
214
|
dataset_show = getattr(self.ckan.action, 'package_show')(id=dataset_id)['resources']
|
|
|
|
|
215
|
except:
|
|
|
|
|
216
|
_, exc_value, _ = sys.exc_info()
|
|
|
|
|
217
|
print('ERROR obtaining metadata dataset:: Use the "print" for more information')
|
|
|
|
|
218
|
return exc_value
|
|
|
|
|
219
|
#------------------------------------------------------------#
|
|
|
|
|
220
|
resources_name = []
|
|
|
|
|
221
|
for u in dataset_show:
|
|
|
|
|
222
|
resources_name.append(u['name'].lower())
|
|
|
|
|
223
|
#------------------------------------------------------------#
|
|
|
|
|
224
|
self.list = ['package_id', 'upload', 'voc_file_type', 'name']
|
|
|
|
|
225
|
for key1, value1 in kwargs.items():
|
|
|
|
|
226
|
if not key1 in self.list:
|
|
|
|
|
227
|
self.dict[key1] = value1
|
|
|
|
|
228
|
#------------------------------------------------------------#
|
|
|
|
|
229
|
if not 'others' in kwargs:
|
|
|
|
|
230
|
self.dict['others'] = ''
|
|
|
|
|
231
|
else:
|
|
|
|
|
232
|
if isinstance(kwargs['others'], list):
|
|
|
|
|
233
|
self.dict['others'] = json.dumps(kwargs['others'])
|
|
|
|
|
234
|
#------------------------------------------------------------#
|
|
|
|
|
235
|
total_list = []
|
|
|
|
|
236
|
#---------------CASO : "path" or "path_list"-----------------#
|
|
|
|
|
237
|
if type(path_files) is list:
|
|
|
|
|
238
|
if len(path_files) != 0:
|
|
|
|
|
239
|
path_files.sort()
|
|
|
|
|
240
|
for u in path_files:
|
|
|
|
|
241
|
if os.path.isfile(u):
|
|
|
|
|
242
|
if os.path.basename(u).lower() in resources_name:
|
|
|
|
|
243
|
if not ignore_repetition:
|
|
|
|
|
244
|
return 'ERROR:: "%s" file already exist in this dataset' % (os.path.basename(u))
|
|
|
|
|
245
|
print('WARRING:: "'+ str(os.path.basename(u)) +'" file was ignored because already exist in this dataset')
|
|
|
|
|
246
|
else:
|
|
|
|
|
247
|
total_list.append({'name':os.path.basename(u), 'size': os.stat(u).st_size, 'upload':open(u, 'rb')})
|
|
|
|
|
248
|
else:
|
|
|
|
|
249
|
return 'File "%s" does not exist' % (u)
|
|
|
|
|
250
|
else:
|
|
|
|
|
251
|
return 'ERROR:: "path_list is empty"'
|
|
|
|
|
252
|
|
|
|
|
|
253
|
elif type(path_files) is str:
|
|
|
|
|
254
|
if os.path.isdir(path_files):
|
|
|
|
|
255
|
path_order = [f for f in os.listdir(path_files) if os.path.isfile(os.path.join(path_files, f))]
|
|
|
|
|
256
|
path_order.sort()
|
|
|
|
|
257
|
if path_order:
|
|
|
|
|
258
|
for name in path_order:
|
|
|
|
|
259
|
if name.lower() in resources_name:
|
|
|
|
|
260
|
if not ignore_repetition:
|
|
|
|
|
261
|
return 'ERROR:: "%s" file already exist in this dataset' % (name)
|
|
|
|
|
262
|
print('WARRING:: "'+ name +'" file was ignored because already exist in this dataset')
|
|
|
|
|
263
|
else:
|
|
|
|
|
264
|
total_list.append({'name':name, 'size': os.stat(os.path.join(path_files, name)).st_size, 'upload':open(os.path.join(path_files, name), 'rb')})
|
|
|
|
|
265
|
else:
|
|
|
|
|
266
|
return "ERROR:: There aren't files in this directory"
|
|
|
|
|
267
|
else:
|
|
|
|
|
268
|
return 'ERROR:: Directory "%s" does not exist' % (path_files)
|
|
|
|
|
269
|
else:
|
|
|
|
|
270
|
return 'ERROR:: "path_files" must be a str or list'
|
|
|
|
|
271
|
#------------------------------------------------------------#
|
|
|
|
|
272
|
try:
|
|
|
|
|
273
|
uuid.UUID(str(dataset_id), version=4)
|
|
|
|
|
274
|
package_id_or_name = '"id": "' + str(dataset_id) + '"'
|
|
|
|
|
275
|
except ValueError:
|
|
|
|
|
276
|
package_id_or_name = '"name": "' + str(dataset_id) + '"'
|
|
|
|
|
277
|
#------------------------------------------------------------#
|
|
|
|
|
278
|
blocks = [[]]
|
|
|
|
|
279
|
size_file = 0
|
|
|
|
|
280
|
count_file = 0
|
|
|
|
|
281
|
inter_num = 0
|
|
|
|
|
282
|
for value in total_list:
|
|
|
|
|
283
|
if value['size'] > 1024 * 1024 * float(max_size):
|
|
|
|
|
284
|
return 'ERROR:: The size of the "%s" file is %sMB aprox, please change "max_size" value' % (value['name'], str(round(value['size']/(1024 * 1024), 2)))
|
|
|
|
|
285
|
if not 1 <= int(max_count) <= 999:
|
|
|
|
|
286
|
return 'ERROR:: The count of the number of files must be between 1 and 999, please change "max_count" value'
|
|
|
|
|
287
|
|
|
|
|
|
288
|
size_file = size_file + value['size']
|
|
|
|
|
289
|
count_file = count_file + 1
|
|
|
|
|
290
|
if size_file <= 1024 * 1024 * float(max_size) and count_file <= int(max_count):
|
|
|
|
|
291
|
del value['size']
|
|
|
|
|
292
|
blocks[inter_num].append(value)
|
|
|
|
|
293
|
else:
|
|
|
|
|
294
|
inter_num = inter_num + 1
|
|
|
|
|
295
|
size_file = value['size']
|
|
|
|
|
296
|
count_file = 1
|
|
|
|
|
297
|
blocks.append([])
|
|
|
|
|
298
|
del value['size']
|
|
|
|
|
299
|
blocks[inter_num].append(value)
|
|
|
|
|
300
|
#------------------------------------------------------------#
|
|
|
|
|
301
|
if len(blocks[0]) > 0:
|
|
|
|
|
302
|
print('BLOCK(S) IN TOTAL:: {}'.format(len(blocks)))
|
|
|
|
|
303
|
for count1, block in enumerate(blocks):
|
|
|
|
|
304
|
print('---- BLOCK N°{} ----'.format(count1 + 1))
|
|
|
|
|
305
|
resource_extend = []
|
|
|
|
|
306
|
files_dict = {}
|
|
|
|
|
307
|
for count2, value2 in enumerate(block):
|
|
|
|
|
308
|
value2['file_date'] = file_date
|
|
|
|
|
309
|
value2['voc_file_type'] = file_type
|
|
|
|
|
310
|
value2.update(self.dict)
|
|
|
|
|
311
|
|
|
|
|
|
312
|
#if not 'format' in value2:
|
|
|
|
|
313
|
# format = ''.join(pathlib.Path(value2['name']).suffixes)
|
|
|
|
|
314
|
# if len(format) > 0:
|
|
|
|
|
315
|
# value2['format'] = format.upper()[1:]
|
|
|
|
|
316
|
|
|
|
|
|
317
|
files_dict['update__resources__-'+ str(len(block)-count2) +'__upload'] = (value2['name'], value2['upload'])
|
|
|
|
|
318
|
del value2['upload']
|
|
|
|
|
319
|
resource_extend.append(value2)
|
|
|
|
|
320
|
|
|
|
|
|
321
|
print('BLOCK N°{} :: "{}" file(s) found >> uploading'.format(count1 + 1, len(block)))
|
|
|
|
|
322
|
try:
|
|
|
|
|
323
|
result = self.ckan.call_action(
|
|
|
|
|
324
|
'package_revise',
|
|
|
|
|
325
|
{'match': '{'+ str(package_id_or_name) +'}', 'update__resources__extend': json.dumps(resource_extend)},
|
|
|
|
|
326
|
files=files_dict
|
|
|
|
|
327
|
)
|
|
|
|
|
328
|
print('BLOCK N°{} :: Uploaded file(s) successfully'.format(count1 + 1))
|
|
|
|
|
329
|
if len(blocks) == count1 + 1:
|
|
|
|
|
330
|
return result
|
|
|
|
|
331
|
except:
|
|
|
|
|
332
|
print('ERROR :: Use the "print" for more information')
|
|
|
|
|
333
|
_, exc_value, _ = sys.exc_info()
|
|
|
|
|
334
|
return exc_value
|
|
|
|
|
335
|
else:
|
|
|
|
|
336
|
return "ERROR:: No file(s) found to upload"
|
|
|
|
|
337
|
|
|
|
|
|
338
|
def upload_multiple_files(self, dataset_id, path_files, date_files, type_files, ignore_repetition=False, **kwargs):
|
|
|
|
|
339
|
# Agregar si es interruptido por teclado
|
|
|
|
|
340
|
'''
|
|
|
|
|
341
|
FINALIDAD:
|
|
|
|
|
342
|
Funcion para subir multiples archivos al repositorio del ROJ.
|
|
|
|
|
343
|
|
|
|
|
|
344
|
PARAMETROS DISPONIBLES:
|
|
|
|
|
345
|
CONSULTAR: "GUIA DE SCRIPT.pdf"
|
|
|
|
|
346
|
|
|
|
|
|
347
|
ESTRUCTURA:
|
|
|
|
|
348
|
<access_name>.upload_multiple_files(dataset_id = <class 'str'>, path_files = <class 'str'> or <class 'list of strings'>, date_files = <class 'str'> or <class 'list of strings'>, type_files = <class 'str'> or <class 'list of strings'>, param_1 = <class 'param_1'>, ...)
|
|
|
|
|
349
|
'''
|
|
|
|
|
350
|
#-------------------------PACKAGE SHOW-----------------------#
|
|
|
|
|
351
|
try:
|
|
|
|
|
352
|
dataset_show = getattr(self.ckan.action, 'package_show')(id=dataset_id)['resources']
|
|
|
|
|
353
|
except:
|
|
|
|
|
354
|
_, exc_value, _ = sys.exc_info()
|
|
|
|
|
355
|
print('ERROR obtaining metadata dataset:: Use the "print" for more information')
|
|
|
|
|
356
|
return exc_value
|
|
|
|
|
357
|
#------------------------------------------------------------#
|
|
|
|
|
358
|
resources_name = []
|
|
|
|
|
359
|
for u in dataset_show:
|
|
|
|
|
360
|
resources_name.append(u['name'].lower())
|
|
|
|
|
361
|
#------------------------------------------------------------#
|
|
|
|
|
362
|
|
|
|
|
|
363
|
params_dict = {'upload':[], 'name':[]}
|
|
|
|
|
364
|
#if not 'format' in kwargs:
|
|
|
|
|
365
|
# params_dict.update({'format':[]})
|
|
|
|
|
366
|
#---------------CASO : "path" or "path_list"-----------------#
|
|
|
|
|
367
|
if type(path_files) is list:
|
|
|
|
|
368
|
if len(path_files) != 0:
|
|
|
|
|
369
|
path_files.sort()
|
|
|
|
|
370
|
for u in path_files:
|
|
|
|
|
371
|
if os.path.isfile(u):
|
|
|
|
|
372
|
if os.path.basename(u).lower() in resources_name:
|
|
|
|
|
373
|
if not ignore_repetition:
|
|
|
|
|
374
|
return 'ERROR:: "%s" file already exist in this dataset' % (os.path.basename(u))
|
|
|
|
|
375
|
print('WARRING:: "'+ str(os.path.basename(u)) +'" file was ignored because already exist in this dataset')
|
|
|
|
|
376
|
else:
|
|
|
|
|
377
|
params_dict['upload'].append(open(u, 'rb'))
|
|
|
|
|
378
|
params_dict['name'].append(os.path.basename(u))
|
|
|
|
|
379
|
#if not 'format' in kwargs:
|
|
|
|
|
380
|
# format = ''.join(pathlib.Path(u).suffixes)
|
|
|
|
|
381
|
# if len(format) > 0:
|
|
|
|
|
382
|
# params_dict['format'].append(format.upper()[1:])
|
|
|
|
|
383
|
# else:
|
|
|
|
|
384
|
# params_dict['format'].append('')
|
|
|
|
|
385
|
else:
|
|
|
|
|
386
|
return 'File "%s" does not exist' % (u)
|
|
|
|
|
387
|
else:
|
|
|
|
|
388
|
return 'ERROR:: "path_list is empty"'
|
|
|
|
|
389
|
elif type(path_files) is str:
|
|
|
|
|
390
|
if os.path.isdir(path_files):
|
|
|
|
|
391
|
path_order = [f for f in os.listdir(path_files) if os.path.isfile(os.path.join(path_files, f))]
|
|
|
|
|
392
|
path_order.sort()
|
|
|
|
|
393
|
if path_order:
|
|
|
|
|
394
|
for name in path_order:
|
|
|
|
|
395
|
if name.lower() in resources_name:
|
|
|
|
|
396
|
if not ignore_repetition:
|
|
|
|
|
397
|
return 'ERROR:: "%s" file already exist in this dataset' % (name)
|
|
|
|
|
398
|
print('WARRING:: "'+ str(name) +'" file was ignored because already exist in this dataset')
|
|
|
|
|
399
|
else:
|
|
|
|
|
400
|
params_dict['upload'].append(open(os.path.join(path_files, name), 'rb'))
|
|
|
|
|
401
|
params_dict['name'].append(name)
|
|
|
|
|
402
|
#if not 'format' in kwargs:
|
|
|
|
|
403
|
# format = ''.join(pathlib.Path(name).suffixes)
|
|
|
|
|
404
|
# if len(format) > 0:
|
|
|
|
|
405
|
# params_dict['format'].append(format.upper()[1:])
|
|
|
|
|
406
|
# else:
|
|
|
|
|
407
|
# params_dict['format'].append('')
|
|
|
|
|
408
|
else:
|
|
|
|
|
409
|
return "ERROR:: There aren't files in this directory"
|
|
|
|
|
410
|
else:
|
|
|
|
|
411
|
return 'ERROR:: Directory "%s" does not exist' % (path_files)
|
|
|
|
|
412
|
else:
|
|
|
|
|
413
|
return 'ERROR:: "path_files" must be a str or list'
|
|
|
|
|
414
|
#------------------------------------------------------------#
|
|
|
|
|
415
|
params_no_dict = {'package_id': dataset_id}
|
|
|
|
|
416
|
if type(date_files) is list:
|
|
|
|
|
417
|
params_dict['file_date'] = date_files
|
|
|
|
|
418
|
else:
|
|
|
|
|
419
|
params_no_dict['file_date'] = date_files
|
|
|
|
|
420
|
|
|
|
|
|
421
|
if type(type_files) is list:
|
|
|
|
|
422
|
params_dict['voc_file_type'] = type_files
|
|
|
|
|
423
|
else:
|
|
|
|
|
424
|
params_no_dict['voc_file_type'] = type_files
|
|
|
|
|
425
|
|
|
|
|
|
426
|
for key1, value1 in kwargs.items():
|
|
|
|
|
427
|
if not key1 in params_dict and not key1 in params_no_dict and key1 != 'others':
|
|
|
|
|
428
|
if type(value1) is list:
|
|
|
|
|
429
|
params_dict[key1] = value1
|
|
|
|
|
430
|
else:
|
|
|
|
|
431
|
params_no_dict[key1] = value1
|
|
|
|
|
432
|
#------------------------------------------#
|
|
|
|
|
433
|
if not 'others' in kwargs:
|
|
|
|
|
434
|
params_no_dict['others'] = ''
|
|
|
|
|
435
|
else:
|
|
|
|
|
436
|
if isinstance(kwargs['others'], tuple):
|
|
|
|
|
437
|
params_dict['others'] = [json.dumps(w) for w in kwargs['others']]
|
|
|
|
|
438
|
elif isinstance(kwargs['others'], list):
|
|
|
|
|
439
|
params_no_dict['others'] = json.dumps(kwargs['others'])
|
|
|
|
|
440
|
elif isinstance(kwargs['others'], str):
|
|
|
|
|
441
|
params_no_dict['others'] = kwargs['others']
|
|
|
|
|
442
|
else:
|
|
|
|
|
443
|
return 'ERROR:: "others" must be a tuple, list or str'
|
|
|
|
|
444
|
#------------------------------------------#
|
|
|
|
|
445
|
len_params_dict = []
|
|
|
|
|
446
|
for value2 in params_dict.values():
|
|
|
|
|
447
|
len_params_dict.append(len(value2))
|
|
|
|
|
448
|
|
|
|
|
|
449
|
if len(list(set(len_params_dict))) > 1:
|
|
|
|
|
450
|
return 'ERROR:: All lists must be the same length: %s' % (len(params_dict['name']))
|
|
|
|
|
451
|
#------------------------------------------------------------#
|
|
|
|
|
452
|
print('"{}" file(s) found >> uploading'.format(len(params_dict['name'])))
|
|
|
|
|
453
|
for v in range(len(params_dict['name'])):
|
|
|
|
|
454
|
try:
|
|
|
|
|
455
|
send = {}
|
|
|
|
|
456
|
for key_dict, value_dict in params_dict.items():
|
|
|
|
|
457
|
send[key_dict] = value_dict[v]
|
|
|
|
|
458
|
for key_no_dict, value_no_dict in params_no_dict.items():
|
|
|
|
|
459
|
send[key_no_dict] = value_no_dict
|
|
|
|
|
460
|
|
|
|
|
|
461
|
self.list.append(getattr(self.ckan.action, 'resource_create')(**send))
|
|
|
|
|
462
|
print('File #{} :: "{}" was uploaded successfully'.format(v+1, params_dict['name'][v]))
|
|
|
|
|
463
|
except:
|
|
|
|
|
464
|
_, exc_value, _ = sys.exc_info()
|
|
|
|
|
465
|
self.list.append(exc_value)
|
|
|
|
|
466
|
print('File #{} :: Error uploading "{}" file'.format(v+1, params_dict['name'][v]))
|
|
|
|
|
467
|
return self.list
|
|
|
|
|
468
|
#------------------------------------------------------------#
|
|
|
|
|
469
|
|
|
|
|
|
470
|
def show(self, type_option, id, **kwargs):
|
|
107
|
def show(self, type_option, id, **kwargs):
|
|
471
|
'''
|
|
108
|
'''
|
|
472
|
FINALIDAD:
|
|
109
|
FINALIDAD:
|
|
473
|
Funcion personalizada para una busqueda en especifico.
|
|
110
|
Funcion personalizada para una busqueda en especifico.
|
|
474
|
|
|
111
|
|
|
475
|
PARAMETROS DISPONIBLES:
|
|
112
|
PARAMETROS DISPONIBLES:
|
|
476
|
CONSULTAR: "GUIA DE SCRIPT.pdf"
|
|
113
|
CONSULTAR: "GUIA DE SCRIPT.pdf"
|
|
477
|
|
|
114
|
|
|
478
|
ESTRUCTURA:
|
|
115
|
ESTRUCTURA:
|
|
479
|
<access_name>.show(type_option = <class 'str'>, id = <class 'str'>, param_1 = <class 'param_1'>, ...)
|
|
116
|
<access_name>.show(type_option = <class 'str'>, id = <class 'str'>, param_1 = <class 'param_1'>, ...)
|
|
480
|
'''
|
|
117
|
'''
|
|
481
|
if type(type_option) is str:
|
|
118
|
if type(type_option) is str:
|
|
482
|
try:
|
|
119
|
try:
|
|
483
|
if type_option == 'dataset':
|
|
120
|
if type_option == 'dataset':
|
|
484
|
return getattr(self.ckan.action, 'package_show')(id=id, **kwargs)
|
|
121
|
return getattr(self.ckan.action, 'package_show')(id=id, **kwargs)
|
|
485
|
elif type_option == 'resource':
|
|
122
|
elif type_option == 'resource':
|
|
486
|
return getattr(self.ckan.action, 'resource_show')(id=id, **kwargs)
|
|
123
|
return getattr(self.ckan.action, 'resource_show')(id=id, **kwargs)
|
|
487
|
elif type_option == 'project':
|
|
124
|
elif type_option == 'project':
|
|
488
|
return getattr(self.ckan.action, 'organization_show')(id=id, **kwargs)
|
|
125
|
return getattr(self.ckan.action, 'organization_show')(id=id, **kwargs)
|
|
489
|
elif type_option == 'collaborator':
|
|
126
|
elif type_option == 'collaborator':
|
|
490
|
return getattr(self.ckan.action, 'package_collaborator_list_for_user')(id=id, **kwargs)
|
|
127
|
return getattr(self.ckan.action, 'package_collaborator_list_for_user')(id=id, **kwargs)
|
|
491
|
elif type_option == 'member':
|
|
128
|
elif type_option == 'member':
|
|
492
|
return getattr(self.ckan.action, 'organization_list_for_user')(id=id, **kwargs)
|
|
129
|
return getattr(self.ckan.action, 'organization_list_for_user')(id=id, **kwargs)
|
|
493
|
elif type_option == 'vocabulary':
|
|
130
|
elif type_option == 'vocabulary':
|
|
494
|
return getattr(self.ckan.action, 'vocabulary_show')(id=id, **kwargs)
|
|
131
|
return getattr(self.ckan.action, 'vocabulary_show')(id=id, **kwargs)
|
|
495
|
elif type_option == 'tag':
|
|
132
|
elif type_option == 'tag':
|
|
496
|
if not 'vocabulary_id' in kwargs:
|
|
133
|
if not 'vocabulary_id' in kwargs:
|
|
497
|
print('Missing "vocabulary_id" value: assume it is a free tag')
|
|
134
|
print('Missing "vocabulary_id" value: assume it is a free tag')
|
|
498
|
return getattr(self.ckan.action, 'tag_show')(id=id, **kwargs)
|
|
135
|
return getattr(self.ckan.action, 'tag_show')(id=id, **kwargs)
|
|
499
|
elif type_option == 'user':
|
|
136
|
elif type_option == 'user':
|
|
500
|
return getattr(self.ckan.action, 'user_show')(id=id, **kwargs)
|
|
137
|
return getattr(self.ckan.action, 'user_show')(id=id, **kwargs)
|
|
501
|
elif type_option == 'job':
|
|
138
|
elif type_option == 'job':
|
|
502
|
return getattr(self.ckan.action, 'job_show')(id=id, **kwargs)
|
|
139
|
return getattr(self.ckan.action, 'job_show')(id=id, **kwargs)
|
|
503
|
else:
|
|
140
|
else:
|
|
504
|
return 'ERROR:: "type_option = %s" is not accepted' % (type_option)
|
|
141
|
return 'ERROR:: "type_option = %s" is not accepted' % (type_option)
|
|
505
|
except:
|
|
142
|
except:
|
|
506
|
_, exc_value, _ = sys.exc_info()
|
|
143
|
_, exc_value, _ = sys.exc_info()
|
|
507
|
return exc_value
|
|
144
|
return exc_value
|
|
508
|
else:
|
|
145
|
else:
|
|
509
|
return 'ERROR:: "type_option" must be a str'
|
|
146
|
return 'ERROR:: "type_option" must be a str'
|
|
510
|
|
|
147
|
|
|
511
|
def search(self, type_option, query=None, **kwargs):
|
|
148
|
def search(self, type_option, query=None, **kwargs):
|
|
512
|
'''
|
|
149
|
'''
|
|
513
|
FINALIDAD:
|
|
150
|
FINALIDAD:
|
|
514
|
Funcion personalizada para busquedas que satisfagan algun criterio.
|
|
151
|
Funcion personalizada para busquedas que satisfagan algun criterio.
|
|
515
|
|
|
152
|
|
|
516
|
PARAMETROS DISPONIBLES:
|
|
153
|
PARAMETROS DISPONIBLES:
|
|
517
|
CONSULTAR: "GUIA DE SCRIPT.pdf"
|
|
154
|
CONSULTAR: "GUIA DE SCRIPT.pdf"
|
|
518
|
|
|
155
|
|
|
519
|
ESTRUCTURA:
|
|
156
|
ESTRUCTURA:
|
|
520
|
<access_name>.search(type_option = <class 'str'>, query = <class 'dict'>, param_1 = <class 'param_1'>, ...)
|
|
157
|
<access_name>.search(type_option = <class 'str'>, query = <class 'dict'>, param_1 = <class 'param_1'>, ...)
|
|
521
|
'''
|
|
158
|
'''
|
|
522
|
if type(type_option) is str:
|
|
159
|
if type(type_option) is str:
|
|
523
|
try:
|
|
160
|
try:
|
|
524
|
if type_option == 'dataset':
|
|
161
|
if type_option == 'dataset':
|
|
525
|
key_replace = ['fq', 'fq_list', 'include_private']
|
|
162
|
key_replace = ['fq', 'fq_list', 'include_private']
|
|
526
|
key_point = ['facet_mincount', 'facet_limit', 'facet_field']
|
|
163
|
key_point = ['facet_mincount', 'facet_limit', 'facet_field']
|
|
527
|
for key1, value1 in kwargs.items():
|
|
164
|
for key1, value1 in kwargs.items():
|
|
528
|
if not key1 in key_replace:
|
|
165
|
if not key1 in key_replace:
|
|
529
|
if key1 in key_point:
|
|
166
|
if key1 in key_point:
|
|
530
|
self.dict[key1.replace('_', '.')] = value1
|
|
167
|
self.dict[key1.replace('_', '.')] = value1
|
|
531
|
else:
|
|
168
|
else:
|
|
532
|
self.dict[key1] = value1
|
|
169
|
self.dict[key1] = value1
|
|
533
|
|
|
170
|
|
|
534
|
if query is not None:
|
|
171
|
if query is not None:
|
|
535
|
if type(query) is dict:
|
|
172
|
if type(query) is dict:
|
|
536
|
self.dict['fq_list'] = []
|
|
173
|
self.dict['fq_list'] = []
|
|
537
|
#NUM_RESOURCES_MIN / NUM_RESOURCES_MAX
|
|
174
|
#NUM_RESOURCES_MIN / NUM_RESOURCES_MAX
|
|
538
|
#----------------------------------------------------#
|
|
175
|
#----------------------------------------------------#
|
|
539
|
if 'dataset_start_date' in query:
|
|
176
|
if 'dataset_start_date' in query:
|
|
540
|
if type(query['dataset_start_date']) is str:
|
|
177
|
if type(query['dataset_start_date']) is str:
|
|
541
|
try:
|
|
178
|
try:
|
|
542
|
datetime.strptime(query['dataset_start_date'], '%Y-%m-%d')
|
|
179
|
datetime.strptime(query['dataset_start_date'], '%Y-%m-%d')
|
|
543
|
if len(query['dataset_start_date']) != 10:
|
|
180
|
if len(query['dataset_start_date']) != 10:
|
|
544
|
return '"dataset_start_date", must be: <YYYY-MM-DD>'
|
|
181
|
return '"dataset_start_date", must be: <YYYY-MM-DD>'
|
|
545
|
self.dict['fq_list'].append('dataset_start_date:"'+query['dataset_start_date']+'"')
|
|
182
|
self.dict['fq_list'].append('dataset_start_date:"'+query['dataset_start_date']+'"')
|
|
546
|
self.list.append('dataset_start_date')
|
|
183
|
self.list.append('dataset_start_date')
|
|
547
|
except:
|
|
184
|
except:
|
|
548
|
return '"dataset_start_date" incorrect: "%s"' % (query['dataset_start_date'])
|
|
185
|
return '"dataset_start_date" incorrect: "%s"' % (query['dataset_start_date'])
|
|
549
|
else:
|
|
186
|
else:
|
|
550
|
return '"dataset_start_date" must be <str>'
|
|
187
|
return '"dataset_start_date" must be <str>'
|
|
551
|
#----------------------------------------------------#
|
|
188
|
#----------------------------------------------------#
|
|
552
|
if 'dataset_end_date' in query:
|
|
189
|
if 'dataset_end_date' in query:
|
|
553
|
if type(query['dataset_end_date']) is str:
|
|
190
|
if type(query['dataset_end_date']) is str:
|
|
554
|
try:
|
|
191
|
try:
|
|
555
|
datetime.strptime(query['dataset_end_date'], '%Y-%m-%d')
|
|
192
|
datetime.strptime(query['dataset_end_date'], '%Y-%m-%d')
|
|
556
|
if len(query['dataset_end_date']) != 10:
|
|
193
|
if len(query['dataset_end_date']) != 10:
|
|
557
|
return '"dataset_end_date", must be: <YYYY-MM-DD>'
|
|
194
|
return '"dataset_end_date", must be: <YYYY-MM-DD>'
|
|
558
|
|
|
195
|
|
|
559
|
if 'dataset_start_date' in query:
|
|
196
|
if 'dataset_start_date' in query:
|
|
560
|
if query['dataset_start_date'] > query['dataset_end_date']:
|
|
197
|
if query['dataset_start_date'] > query['dataset_end_date']:
|
|
561
|
return '"dataset_end_date" must be greater than "dataset_start_date"'
|
|
198
|
return '"dataset_end_date" must be greater than "dataset_start_date"'
|
|
562
|
|
|
199
|
|
|
563
|
self.dict['fq_list'].append('dataset_end_date:"'+query['dataset_end_date']+'"')
|
|
200
|
self.dict['fq_list'].append('dataset_end_date:"'+query['dataset_end_date']+'"')
|
|
564
|
self.list.append('dataset_end_date')
|
|
201
|
self.list.append('dataset_end_date')
|
|
565
|
except:
|
|
202
|
except:
|
|
566
|
return '"dataset_end_date" incorrect: "%s"' % (query['dataset_end_date'])
|
|
203
|
return '"dataset_end_date" incorrect: "%s"' % (query['dataset_end_date'])
|
|
567
|
else:
|
|
204
|
else:
|
|
568
|
return '"dataset_end_date" must be <str>'
|
|
205
|
return '"dataset_end_date" must be <str>'
|
|
569
|
#----------------------------------------------------#
|
|
206
|
#----------------------------------------------------#
|
|
570
|
for key, value in query.items():
|
|
207
|
for key, value in query.items():
|
|
571
|
if value is not None and not key in self.list:
|
|
208
|
if value is not None and not key in self.list:
|
|
572
|
self.dict['fq_list'].append(str(key)+':"'+str(value)+'"')
|
|
209
|
self.dict['fq_list'].append(str(key)+':"'+str(value)+'"')
|
|
573
|
else:
|
|
210
|
else:
|
|
574
|
return '"query" must be <dict>'
|
|
211
|
return '"query" must be <dict>'
|
|
575
|
|
|
212
|
|
|
576
|
return getattr(self.ckan.action, 'package_search')(include_private=True, **self.dict)
|
|
213
|
return getattr(self.ckan.action, 'package_search')(include_private=True, **self.dict)
|
|
577
|
|
|
214
|
|
|
578
|
elif type_option == 'resource':
|
|
215
|
elif type_option == 'resource':
|
|
579
|
for key1, value1 in kwargs.items():
|
|
216
|
for key1, value1 in kwargs.items():
|
|
580
|
if key1 != 'fields':
|
|
217
|
if key1 != 'fields':
|
|
581
|
self.dict[key1] = value1
|
|
218
|
self.dict[key1] = value1
|
|
582
|
|
|
219
|
|
|
583
|
if query is not None:
|
|
220
|
if query is not None:
|
|
584
|
if type(query) is dict:
|
|
221
|
if type(query) is dict:
|
|
585
|
#----------------------------------------------------#
|
|
222
|
#----------------------------------------------------#
|
|
586
|
if 'file_date_min' in query:
|
|
223
|
if 'file_date_min' in query:
|
|
587
|
if type(query['file_date_min']) is str:
|
|
224
|
if type(query['file_date_min']) is str:
|
|
588
|
try:
|
|
225
|
try:
|
|
589
|
datetime.strptime(query['file_date_min'], '%Y-%m-%d')
|
|
226
|
datetime.strptime(query['file_date_min'], '%Y-%m-%d')
|
|
590
|
if len(query['file_date_min']) != 10:
|
|
227
|
if len(query['file_date_min']) != 10:
|
|
591
|
return '"file_date_min", must be: <YYYY-MM-DD>'
|
|
228
|
return '"file_date_min", must be: <YYYY-MM-DD>'
|
|
592
|
except:
|
|
229
|
except:
|
|
593
|
return '"file_date_min" incorrect: "%s"' % (query['file_date_min'])
|
|
230
|
return '"file_date_min" incorrect: "%s"' % (query['file_date_min'])
|
|
594
|
else:
|
|
231
|
else:
|
|
595
|
return '"file_date_min" must be <str>'
|
|
232
|
return '"file_date_min" must be <str>'
|
|
596
|
#----------------------------------------------------#
|
|
233
|
#----------------------------------------------------#
|
|
597
|
if 'file_date_max' in query:
|
|
234
|
if 'file_date_max' in query:
|
|
598
|
if type(query['file_date_max']) is str:
|
|
235
|
if type(query['file_date_max']) is str:
|
|
599
|
try:
|
|
236
|
try:
|
|
600
|
datetime.strptime(query['file_date_max'], '%Y-%m-%d')
|
|
237
|
datetime.strptime(query['file_date_max'], '%Y-%m-%d')
|
|
601
|
if len(query['file_date_max']) != 10:
|
|
238
|
if len(query['file_date_max']) != 10:
|
|
602
|
return '"file_date_max", must be: <YYYY-MM-DD>'
|
|
239
|
return '"file_date_max", must be: <YYYY-MM-DD>'
|
|
603
|
|
|
240
|
|
|
604
|
if 'file_date_min' in query:
|
|
241
|
if 'file_date_min' in query:
|
|
605
|
if query['file_date_min'] > query['file_date_max']:
|
|
242
|
if query['file_date_min'] > query['file_date_max']:
|
|
606
|
return '"file_date_max" must be greater than "file_date_min"'
|
|
243
|
return '"file_date_max" must be greater than "file_date_min"'
|
|
607
|
except:
|
|
244
|
except:
|
|
608
|
return '"file_date_max" incorrect: "%s"' % (query['file_date_max'])
|
|
245
|
return '"file_date_max" incorrect: "%s"' % (query['file_date_max'])
|
|
609
|
else:
|
|
246
|
else:
|
|
610
|
return '"file_date_max" must be <str>'
|
|
247
|
return '"file_date_max" must be <str>'
|
|
611
|
#----------------------------------------------------#
|
|
248
|
#----------------------------------------------------#
|
|
612
|
self.dict['query'] = query
|
|
249
|
self.dict['query'] = query
|
|
613
|
else:
|
|
250
|
else:
|
|
614
|
return '"query" must be <dict>'
|
|
251
|
return '"query" must be <dict>'
|
|
615
|
return getattr(self.ckan.action, 'resources_search')(**self.dict)
|
|
252
|
return getattr(self.ckan.action, 'resources_search')(**self.dict)
|
|
616
|
|
|
253
|
|
|
617
|
elif type_option == 'tag':
|
|
254
|
elif type_option == 'tag':
|
|
618
|
for key1, value1 in kwargs.items():
|
|
255
|
for key1, value1 in kwargs.items():
|
|
619
|
if key1 != 'fields':
|
|
256
|
if key1 != 'fields':
|
|
620
|
self.dict[key1] = value1
|
|
257
|
self.dict[key1] = value1
|
|
621
|
|
|
258
|
|
|
622
|
if not 'vocabulary_id' in kwargs:
|
|
259
|
if not 'vocabulary_id' in kwargs:
|
|
623
|
print('Missing "vocabulary_id" value: tags that don’t belong to any vocabulary')
|
|
260
|
print('Missing "vocabulary_id" value: tags that don’t belong to any vocabulary')
|
|
624
|
else:
|
|
261
|
else:
|
|
625
|
print('Only tags that belong to "{}" vocabulary'.format(kwargs['vocabulary_id']))
|
|
262
|
print('Only tags that belong to "{}" vocabulary'.format(kwargs['vocabulary_id']))
|
|
626
|
|
|
263
|
|
|
627
|
if query is not None:
|
|
264
|
if query is not None:
|
|
628
|
if type(query) is dict:
|
|
265
|
if type(query) is dict:
|
|
629
|
if 'search' in query:
|
|
266
|
if 'search' in query:
|
|
630
|
if type(query['search']) is list or type(query['search']) is str:
|
|
267
|
if type(query['search']) is list or type(query['search']) is str:
|
|
631
|
self.dict['query'] = query['search']
|
|
268
|
self.dict['query'] = query['search']
|
|
632
|
else:
|
|
269
|
else:
|
|
633
|
return '"search" must be <list> or <str>'
|
|
270
|
return '"search" must be <list> or <str>'
|
|
634
|
else:
|
|
271
|
else:
|
|
635
|
return '"query" must be <dict>'
|
|
272
|
return '"query" must be <dict>'
|
|
636
|
return getattr(self.ckan.action, 'tag_search')(**self.dict)
|
|
273
|
return getattr(self.ckan.action, 'tag_search')(**self.dict)
|
|
637
|
|
|
274
|
|
|
638
|
else:
|
|
275
|
else:
|
|
639
|
return 'ERROR:: "type_option = %s" is not accepted' % (type_option)
|
|
276
|
return 'ERROR:: "type_option = %s" is not accepted' % (type_option)
|
|
640
|
|
|
277
|
|
|
641
|
except:
|
|
278
|
except:
|
|
642
|
_, exc_value, _ = sys.exc_info()
|
|
279
|
_, exc_value, _ = sys.exc_info()
|
|
643
|
return exc_value
|
|
280
|
return exc_value
|
|
644
|
else:
|
|
281
|
else:
|
|
645
|
return 'ERROR:: "type_option" must be <str>'
|
|
282
|
return 'ERROR:: "type_option" must be <str>'
|
|
646
|
|
|
283
|
|
|
647
|
def create(self, type_option, select=None, **kwargs):
|
|
284
|
def create(self, type_option, select=None, **kwargs):
|
|
648
|
'''
|
|
285
|
'''
|
|
649
|
FINALIDAD:
|
|
286
|
FINALIDAD:
|
|
650
|
Funcion personalizada para crear.
|
|
287
|
Funcion personalizada para crear.
|
|
651
|
|
|
288
|
|
|
652
|
PARAMETROS DISPONIBLES:
|
|
289
|
PARAMETROS DISPONIBLES:
|
|
653
|
CONSULTAR: "GUIA DE SCRIPT.pdf"
|
|
290
|
CONSULTAR: "GUIA DE SCRIPT.pdf"
|
|
654
|
|
|
291
|
|
|
655
|
ESTRUCTURA:
|
|
292
|
ESTRUCTURA:
|
|
656
|
<access_name>.create(type_option = <class 'str'>, param_1 = <class 'param_1'>, ...)
|
|
293
|
<access_name>.create(type_option = <class 'str'>, param_1 = <class 'param_1'>, ...)
|
|
657
|
'''
|
|
294
|
'''
|
|
658
|
if type(type_option) is str:
|
|
295
|
if type(type_option) is str:
|
|
659
|
try:
|
|
296
|
try:
|
|
660
|
if type_option == 'dataset':
|
|
297
|
if type_option == 'dataset':
|
|
661
|
return getattr(self.ckan.action, 'package_create')(**kwargs)
|
|
298
|
return getattr(self.ckan.action, 'package_create')(**kwargs)
|
|
662
|
if type_option == 'resource':
|
|
299
|
if type_option == 'resource':
|
|
663
|
return resource.resource_create(self, **kwargs)
|
|
300
|
return resource.resource_create(self, **kwargs)
|
|
664
|
elif type_option == 'project':
|
|
301
|
elif type_option == 'project':
|
|
665
|
return getattr(self.ckan.action, 'organization_create')(**kwargs)
|
|
302
|
return getattr(self.ckan.action, 'organization_create')(**kwargs)
|
|
666
|
elif type_option == 'member':
|
|
303
|
elif type_option == 'member':
|
|
667
|
return getattr(self.ckan.action, 'organization_member_create')(**kwargs)
|
|
304
|
return getattr(self.ckan.action, 'organization_member_create')(**kwargs)
|
|
668
|
elif type_option == 'collaborator':
|
|
305
|
elif type_option == 'collaborator':
|
|
669
|
return getattr(self.ckan.action, 'package_collaborator_create')(**kwargs)
|
|
306
|
return getattr(self.ckan.action, 'package_collaborator_create')(**kwargs)
|
|
670
|
elif type_option == 'vocabulary':
|
|
307
|
elif type_option == 'vocabulary':
|
|
671
|
return getattr(self.ckan.action, 'vocabulary_create')(**kwargs)
|
|
308
|
return getattr(self.ckan.action, 'vocabulary_create')(**kwargs)
|
|
672
|
elif type_option == 'tag':
|
|
309
|
elif type_option == 'tag':
|
|
673
|
return getattr(self.ckan.action, 'tag_create')(**kwargs)
|
|
310
|
return getattr(self.ckan.action, 'tag_create')(**kwargs)
|
|
674
|
elif type_option == 'user':
|
|
311
|
elif type_option == 'user':
|
|
675
|
return getattr(self.ckan.action, 'user_create')(**kwargs)
|
|
312
|
return getattr(self.ckan.action, 'user_create')(**kwargs)
|
|
676
|
elif type_option == 'views':
|
|
313
|
elif type_option == 'views':
|
|
677
|
if 'resource' == select:
|
|
314
|
if 'resource' == select:
|
|
678
|
self.list = ['package']
|
|
315
|
self.list = ['package']
|
|
679
|
for key1, value1 in kwargs.items():
|
|
316
|
for key1, value1 in kwargs.items():
|
|
680
|
if not key1 in self.list:
|
|
317
|
if not key1 in self.list:
|
|
681
|
self.dict[key1] = value1
|
|
318
|
self.dict[key1] = value1
|
|
682
|
return getattr(self.ckan.action, 'resource_create_default_resource_views')(**self.dict)
|
|
319
|
return getattr(self.ckan.action, 'resource_create_default_resource_views')(**self.dict)
|
|
683
|
elif 'dataset' == select:
|
|
320
|
elif 'dataset' == select:
|
|
684
|
return getattr(self.ckan.action, 'package_create_default_resource_views')(**kwargs)
|
|
321
|
return getattr(self.ckan.action, 'package_create_default_resource_views')(**kwargs)
|
|
685
|
else:
|
|
322
|
else:
|
|
686
|
return 'ERROR:: "select = %s" is not accepted' % (select)
|
|
323
|
return 'ERROR:: "select = %s" is not accepted' % (select)
|
|
687
|
else:
|
|
324
|
else:
|
|
688
|
return 'ERROR:: "type_option = %s" is not accepted' % (type_option)
|
|
325
|
return 'ERROR:: "type_option = %s" is not accepted' % (type_option)
|
|
689
|
except:
|
|
326
|
except:
|
|
690
|
_, exc_value, _ = sys.exc_info()
|
|
327
|
_, exc_value, _ = sys.exc_info()
|
|
691
|
return exc_value
|
|
328
|
return exc_value
|
|
692
|
else:
|
|
329
|
else:
|
|
693
|
return 'ERROR:: "type_option" must be <str>'
|
|
330
|
return 'ERROR:: "type_option" must be <str>'
|
|
694
|
|
|
331
|
|
|
695
|
def patch(self, type_option, **kwargs):
|
|
332
|
def patch(self, type_option, **kwargs):
|
|
696
|
'''
|
|
333
|
'''
|
|
697
|
FINALIDAD:
|
|
334
|
FINALIDAD:
|
|
698
|
Funciones personalizadas para actualizar
|
|
335
|
Funciones personalizadas para actualizar
|
|
699
|
|
|
336
|
|
|
700
|
PARAMETROS DISPONIBLES:
|
|
337
|
PARAMETROS DISPONIBLES:
|
|
701
|
CONSULTAR: "GUIA DE SCRIPT.pdf"
|
|
338
|
CONSULTAR: "GUIA DE SCRIPT.pdf"
|
|
702
|
|
|
339
|
|
|
703
|
ESTRUCTURA:
|
|
340
|
ESTRUCTURA:
|
|
704
|
<access_name>.patch(type_option = <class 'str'>, param_1 = <class 'param_1'>, ...)
|
|
341
|
<access_name>.patch(type_option = <class 'str'>, param_1 = <class 'param_1'>, ...)
|
|
705
|
'''
|
|
342
|
'''
|
|
706
|
if type(type_option) is str:
|
|
343
|
if type(type_option) is str:
|
|
707
|
try:
|
|
344
|
try:
|
|
708
|
if type_option == 'dataset':
|
|
345
|
if type_option == 'dataset':
|
|
709
|
#Agregar que solo se debe modificar parámetros del Dataset y que no incluya Resources
|
|
346
|
#Agregar que solo se debe modificar parámetros del Dataset y que no incluya Resources
|
|
710
|
return getattr(self.ckan.action, 'package_patch')(**kwargs)
|
|
347
|
return getattr(self.ckan.action, 'package_patch')(**kwargs)
|
|
711
|
elif type_option == 'project':
|
|
348
|
elif type_option == 'project':
|
|
712
|
return getattr(self.ckan.action, 'organization_patch')(**kwargs)
|
|
349
|
return getattr(self.ckan.action, 'organization_patch')(**kwargs)
|
|
713
|
elif type_option == 'resource':
|
|
350
|
elif type_option == 'resource':
|
|
714
|
return resource.resource_patch(self, **kwargs)
|
|
351
|
return resource.resource_patch(self, **kwargs)
|
|
715
|
elif type_option == 'member':
|
|
352
|
elif type_option == 'member':
|
|
716
|
return getattr(self.ckan.action, 'organization_member_create')(**kwargs)
|
|
353
|
return getattr(self.ckan.action, 'organization_member_create')(**kwargs)
|
|
717
|
elif type_option == 'collaborator':
|
|
354
|
elif type_option == 'collaborator':
|
|
718
|
return getattr(self.ckan.action, 'package_collaborator_create')(**kwargs)
|
|
355
|
return getattr(self.ckan.action, 'package_collaborator_create')(**kwargs)
|
|
719
|
else:
|
|
356
|
else:
|
|
720
|
return 'ERROR:: "type_option = %s" is not accepted' % (type_option)
|
|
357
|
return 'ERROR:: "type_option = %s" is not accepted' % (type_option)
|
|
721
|
except:
|
|
358
|
except:
|
|
722
|
_, exc_value, _ = sys.exc_info()
|
|
359
|
_, exc_value, _ = sys.exc_info()
|
|
723
|
return exc_value
|
|
360
|
return exc_value
|
|
724
|
else:
|
|
361
|
else:
|
|
725
|
return 'ERROR:: "type_option" must be <str>'
|
|
362
|
return 'ERROR:: "type_option" must be <str>'
|
|
726
|
|
|
363
|
|
|
727
|
def delete(self, type_option, select=None, **kwargs):
|
|
364
|
def delete(self, type_option, select=None, **kwargs):
|
|
728
|
'''
|
|
365
|
'''
|
|
729
|
FINALIDAD:
|
|
366
|
FINALIDAD:
|
|
730
|
Función personalizada para eliminar y/o purgar.
|
|
367
|
Función personalizada para eliminar y/o purgar.
|
|
731
|
|
|
368
|
|
|
732
|
PARAMETROS DISPONIBLES:
|
|
369
|
PARAMETROS DISPONIBLES:
|
|
733
|
CONSULTAR: "GUIA DE SCRIPT.pdf"
|
|
370
|
CONSULTAR: "GUIA DE SCRIPT.pdf"
|
|
734
|
|
|
371
|
|
|
735
|
ESTRUCTURA:
|
|
372
|
ESTRUCTURA:
|
|
736
|
<access_name>.delete(type_option = <class 'str'>, param_1 = <class 'param_1'>, ...)
|
|
373
|
<access_name>.delete(type_option = <class 'str'>, param_1 = <class 'param_1'>, ...)
|
|
737
|
'''
|
|
374
|
'''
|
|
738
|
if type(type_option) is str:
|
|
375
|
if type(type_option) is str:
|
|
739
|
try:
|
|
376
|
try:
|
|
740
|
if type_option == 'dataset':
|
|
377
|
if type_option == 'dataset':
|
|
741
|
if select is None:
|
|
378
|
if select is None:
|
|
742
|
return 'ERROR:: "select" must not be "None"'
|
|
379
|
return 'ERROR:: "select" must not be "None"'
|
|
743
|
else:
|
|
380
|
else:
|
|
744
|
if 'delete' == select:
|
|
381
|
if 'delete' == select:
|
|
745
|
return getattr(self.ckan.action, 'package_delete')(**kwargs)
|
|
382
|
return getattr(self.ckan.action, 'package_delete')(**kwargs)
|
|
746
|
elif 'purge' == select:
|
|
383
|
elif 'purge' == select:
|
|
747
|
return getattr(self.ckan.action, 'dataset_purge')(**kwargs)
|
|
384
|
return getattr(self.ckan.action, 'dataset_purge')(**kwargs)
|
|
748
|
else:
|
|
385
|
else:
|
|
749
|
return 'ERROR:: "select = %s" is not accepted' % (select)
|
|
386
|
return 'ERROR:: "select = %s" is not accepted' % (select)
|
|
750
|
elif type_option == 'project':
|
|
387
|
elif type_option == 'project':
|
|
751
|
if select is None:
|
|
388
|
if select is None:
|
|
752
|
return 'ERROR:: "select" must not be "None"'
|
|
389
|
return 'ERROR:: "select" must not be "None"'
|
|
753
|
else:
|
|
390
|
else:
|
|
754
|
if 'delete' == select:
|
|
391
|
if 'delete' == select:
|
|
755
|
return getattr(self.ckan.action, 'organization_delete')(**kwargs)
|
|
392
|
return getattr(self.ckan.action, 'organization_delete')(**kwargs)
|
|
756
|
elif 'purge' == select:
|
|
393
|
elif 'purge' == select:
|
|
757
|
return getattr(self.ckan.action, 'organization_purge')(**kwargs)
|
|
394
|
return getattr(self.ckan.action, 'organization_purge')(**kwargs)
|
|
758
|
else:
|
|
395
|
else:
|
|
759
|
return 'ERROR:: "select = %s" is not accepted' % (select)
|
|
396
|
return 'ERROR:: "select = %s" is not accepted' % (select)
|
|
760
|
elif type_option == 'resource':
|
|
397
|
elif type_option == 'resource':
|
|
761
|
if select is None:
|
|
398
|
if select is None:
|
|
762
|
return 'ERROR:: "select" must not be "None"'
|
|
399
|
return 'ERROR:: "select" must not be "None"'
|
|
763
|
else:
|
|
400
|
else:
|
|
764
|
return resource.resource_delete(self, select, **kwargs)
|
|
401
|
return resource.resource_delete(self, select, **kwargs)
|
|
765
|
elif type_option == 'vocabulary':
|
|
402
|
elif type_option == 'vocabulary':
|
|
766
|
return getattr(self.ckan.action, 'vocabulary_delete')(**kwargs)
|
|
403
|
return getattr(self.ckan.action, 'vocabulary_delete')(**kwargs)
|
|
767
|
elif type_option == 'tag':
|
|
404
|
elif type_option == 'tag':
|
|
768
|
return getattr(self.ckan.action, 'tag_delete')(**kwargs)
|
|
405
|
return getattr(self.ckan.action, 'tag_delete')(**kwargs)
|
|
769
|
elif type_option == 'user':
|
|
406
|
elif type_option == 'user':
|
|
770
|
return getattr(self.ckan.action, 'user_delete')(**kwargs)
|
|
407
|
return getattr(self.ckan.action, 'user_delete')(**kwargs)
|
|
771
|
else:
|
|
408
|
else:
|
|
772
|
return 'ERROR:: "type_option = %s" is not accepted' % (type_option)
|
|
409
|
return 'ERROR:: "type_option = %s" is not accepted' % (type_option)
|
|
773
|
except:
|
|
410
|
except:
|
|
774
|
_, exc_value, _ = sys.exc_info()
|
|
411
|
_, exc_value, _ = sys.exc_info()
|
|
775
|
return exc_value
|
|
412
|
return exc_value
|
|
776
|
else:
|
|
413
|
else:
|
|
777
|
return 'ERROR:: "type_option" must be <str>'
|
|
414
|
return 'ERROR:: "type_option" must be <str>'
|
|
778
|
|
|
|
|
|
779
|
def f_status_note(self, total, result, path):
|
|
|
|
|
780
|
file_txt = open(path+'status_note.txt', 'w')
|
|
|
|
|
781
|
file_txt = open(path+'status_note.txt', 'a')
|
|
|
|
|
782
|
|
|
|
|
|
783
|
file_txt.write('DOWNLOADED FILE(S): "%s"' % (len(result['name'])))
|
|
|
|
|
784
|
file_txt.write(''+ os.linesep)
|
|
|
|
|
785
|
for u in result['name']:
|
|
|
|
|
786
|
file_txt.write(' - '+ u + os.linesep)
|
|
|
|
|
787
|
file_txt.write(''+ os.linesep)
|
|
|
|
|
788
|
|
|
|
|
|
789
|
file_txt.write('FAILED FILE(S): "%s"' % (len(total['name'])-len(result['name'])))
|
|
|
|
|
790
|
file_txt.write(''+ os.linesep)
|
|
|
|
|
791
|
if len(total['name'])-len(result['name']) != 0:
|
|
|
|
|
792
|
for u in total['name']:
|
|
|
|
|
793
|
if not u in result['name']:
|
|
|
|
|
794
|
file_txt.write(' - '+ u + os.linesep)
|
|
|
|
|
795
|
else:
|
|
|
|
|
796
|
file_txt.write(' "None"'+ os.linesep)
|
|
|
|
|
797
|
|
|
|
|
|
798
|
def f_name(self, name_dataset, ext, tempdir):
|
|
|
|
|
799
|
while self.check:
|
|
|
|
|
800
|
self.str = ''
|
|
|
|
|
801
|
if self.cont == 0:
|
|
|
|
|
802
|
if os.path.exists(tempdir + name_dataset + ext):
|
|
|
|
|
803
|
self.str = name_dataset+'('+str(self.cont+1)+')'+ext
|
|
|
|
|
804
|
else:
|
|
|
|
|
805
|
self.check = self.check * 0
|
|
|
|
|
806
|
self.str = name_dataset + ext
|
|
|
|
|
807
|
else:
|
|
|
|
|
808
|
if not os.path.exists(tempdir + name_dataset+'('+str(self.cont)+')'+ext):
|
|
|
|
|
809
|
self.check = self.check * 0
|
|
|
|
|
810
|
self.str = name_dataset+'('+str(self.cont)+')'+ ext
|
|
|
|
|
811
|
self.cont = self.cont+1
|
|
|
|
|
812
|
return self.str
|
|
|
|
|
813
|
|
|
|
|
|
814
|
def f_zipdir(self, path, ziph, zip_name):
|
|
|
|
|
815
|
for root, _, files in os.walk(path):
|
|
|
|
|
816
|
print('.....')
|
|
|
|
|
817
|
print('Creating: "{}" >>'.format(zip_name))
|
|
|
|
|
818
|
for __file in tqdm(iterable=files, total=len(files)):
|
|
|
|
|
819
|
new_dir = os.path.relpath(os.path.join(root, __file), os.path.join(path, '..'))
|
|
|
|
|
820
|
ziph.write(os.path.join(root, __file), new_dir)
|
|
|
|
|
821
|
print('Created >>')
|
|
|
|
|
822
|
|
|
|
|
|
823
|
def download_by_step(self, response, tempdir_name):
|
|
|
|
|
824
|
try:
|
|
|
|
|
825
|
# ---------- REPLACE URL --------- #
|
|
|
|
|
826
|
if urlparse(self.url).netloc != 'www.igp.gob.pe' and urlparse(response['url']).netloc == 'www.igp.gob.pe':
|
|
|
|
|
827
|
response['url'] = response['url'].replace(urlparse(response['url']).scheme + '://' + urlparse(response['url']).netloc,
|
|
|
|
|
828
|
urlparse(self.url).scheme + '://' + urlparse(self.url).netloc)
|
|
|
|
|
829
|
#----------------------------------#
|
|
|
|
|
830
|
with requests.get(response['url'], stream=True, headers={'Authorization': self.Authorization}, verify=self.verify) as resp:
|
|
|
|
|
831
|
if resp.status_code == 200:
|
|
|
|
|
832
|
with open(tempdir_name+response['name'], 'wb') as file:
|
|
|
|
|
833
|
for chunk in resp.iter_content(chunk_size = self.chunk_size):
|
|
|
|
|
834
|
if chunk:
|
|
|
|
|
835
|
file.write(chunk)
|
|
|
|
|
836
|
except requests.exceptions.RequestException:
|
|
|
|
|
837
|
pass
|
|
|
|
|
838
|
|
|
415
|
|
|
839
|
def download_files(self, **kwargs):
|
|
416
|
def download_files(self, id_or_name, processes=1, path=os.path.expanduser("~"), **kwargs):
|
|
840
|
'''
|
|
|
|
|
841
|
FINALIDAD:
|
|
|
|
|
842
|
Funcion personalizada para la descarga de archivos existentes de un dataset.
|
|
|
|
|
843
|
|
|
|
|
|
844
|
PARAMETROS DISPONIBLES:
|
|
|
|
|
845
|
CONSULTAR: "GUIA DE SCRIPT.pdf"
|
|
|
|
|
846
|
|
|
|
|
|
847
|
ESTRUCTURA:
|
|
|
|
|
848
|
<access_name>.download_files(id = <class 'str'>, param_1 = <class 'param_1'>, ...)
|
|
|
|
|
849
|
'''
|
|
|
|
|
850
|
dict_local = {}
|
|
|
|
|
851
|
#----------------------------------------------#
|
|
|
|
|
852
|
if 'zip' in kwargs:
|
|
|
|
|
853
|
if type(kwargs['zip']) is not bool:
|
|
|
|
|
854
|
return 'ERROR:: "zip" must be: <class "bool">'
|
|
|
|
|
855
|
else:
|
|
|
|
|
856
|
dict_local['zip'] = kwargs['zip']
|
|
|
|
|
857
|
else:
|
|
|
|
|
858
|
dict_local['zip'] = False
|
|
|
|
|
859
|
#----------------------------------------------#
|
|
|
|
|
860
|
if 'status_note' in kwargs:
|
|
|
|
|
861
|
if type(kwargs['status_note']) is not bool:
|
|
|
|
|
862
|
return 'ERROR:: "status_note" must be: <class "bool">'
|
|
|
|
|
863
|
else:
|
|
|
|
|
864
|
dict_local['status_note'] = kwargs['status_note']
|
|
|
|
|
865
|
else:
|
|
|
|
|
866
|
dict_local['status_note'] = False
|
|
|
|
|
867
|
#----------------------------------------------#
|
|
|
|
|
868
|
if 'path' in kwargs:
|
|
|
|
|
869
|
if type(kwargs['path']) is str:
|
|
|
|
|
870
|
if os.path.isdir(kwargs['path']) == False:
|
|
|
|
|
871
|
return 'ERROR:: "path" does not exist'
|
|
|
|
|
872
|
else:
|
|
|
|
|
873
|
if kwargs['path'][-1:] != self.separator:
|
|
|
|
|
874
|
dict_local['path'] = kwargs['path']+self.separator
|
|
|
|
|
875
|
else:
|
|
|
|
|
876
|
dict_local['path'] = kwargs['path']
|
|
|
|
|
877
|
|
|
|
|
|
878
|
txt = dict_local['path']+datetime.now().strftime("%Y_%m_%d_%H_%M_%S_%f")+'.txt'
|
|
|
|
|
879
|
if int(platform.python_version()[0]) == 3:
|
|
|
|
|
880
|
try:
|
|
|
|
|
881
|
file_txt = open(txt, 'w')
|
|
|
|
|
882
|
file_txt.close()
|
|
|
|
|
883
|
os.remove(txt)
|
|
|
|
|
884
|
except PermissionError:
|
|
|
|
|
885
|
return 'ERROR:: Access denied, you are not authorized to write files: "%s"' % (dict_local['path'])
|
|
|
|
|
886
|
else:
|
|
|
|
|
887
|
try:
|
|
|
|
|
888
|
file_txt = open(txt, 'w')
|
|
|
|
|
889
|
file_txt.close()
|
|
|
|
|
890
|
os.remove(txt)
|
|
|
|
|
891
|
except:
|
|
|
|
|
892
|
return 'ERROR:: Access denied, you are not authorized to write files: "%s"' % (dict_local['path'])
|
|
|
|
|
893
|
else:
|
|
|
|
|
894
|
return 'ERROR:: "path" must be: <class "str">'
|
|
|
|
|
895
|
else:
|
|
|
|
|
896
|
dict_local['path'] = ''
|
|
|
|
|
897
|
#----------------------------------------------#
|
|
|
|
|
898
|
for key, value in kwargs.items():
|
|
|
|
|
899
|
if not key in dict_local:
|
|
|
|
|
900
|
self.dict[key] = value
|
|
|
|
|
901
|
try:
|
|
|
|
|
902
|
response = getattr(self.ckan.action, 'url_resources')(**self.dict)
|
|
|
|
|
903
|
except:
|
|
|
|
|
904
|
_, exc_value, _ = sys.exc_info()
|
|
|
|
|
905
|
return exc_value
|
|
|
|
|
906
|
|
|
|
|
|
907
|
if len(response) != 0:
|
|
|
|
|
908
|
#--------------TEMP PATH---------------#
|
|
|
|
|
909
|
if dict_local['zip']:
|
|
|
|
|
910
|
tempdir = tempfile.mkdtemp(prefix=kwargs['id']+'-')+self.separator
|
|
|
|
|
911
|
os.mkdir(tempdir+kwargs['id'])
|
|
|
|
|
912
|
dir_name = tempdir + kwargs['id'] + self.separator
|
|
|
|
|
913
|
else:
|
|
|
|
|
914
|
dir = self.f_name(kwargs['id'], '', dict_local['path'])
|
|
|
|
|
915
|
os.mkdir(dict_local['path'] + dir)
|
|
|
|
|
916
|
dir_name = dict_local['path'] + dir + self.separator
|
|
|
|
|
917
|
#-----------DOWNLOAD FILES-------------#
|
|
|
|
|
918
|
print('.....')
|
|
|
|
|
919
|
print('Downloading "{}" file(s) >>'.format(len(response)))
|
|
|
|
|
920
|
name_total = {'name': []}
|
|
|
|
|
921
|
with concurrent.futures.ThreadPoolExecutor() as executor:
|
|
|
|
|
922
|
for u in tqdm(iterable=response, total=len(response)):
|
|
|
|
|
923
|
name_total['name'].append(u['name'])
|
|
|
|
|
924
|
executor.submit(self.download_by_step, u, dir_name)
|
|
|
|
|
925
|
name_check = {}
|
|
|
|
|
926
|
name_check['name'] = [f for f in os.listdir(dir_name) if os.path.isfile(os.path.join(dir_name, f))]
|
|
|
|
|
927
|
print('"{}" downloaded file(s) successfully >>'.format(len(name_check['name'])))
|
|
|
|
|
928
|
#--------------------------------------#
|
|
|
|
|
929
|
if len(name_check['name']) != 0:
|
|
|
|
|
930
|
#----------Status Note---------#
|
|
|
|
|
931
|
if dict_local['status_note']:
|
|
|
|
|
932
|
print('.....')
|
|
|
|
|
933
|
print('Creating: "status_note.txt" >>')
|
|
|
|
|
934
|
self.f_status_note(name_total, name_check, dir_name)
|
|
|
|
|
935
|
print('Created>>')
|
|
|
|
|
936
|
#----------ZIP CREATE----------#
|
|
|
|
|
937
|
if dict_local['zip']:
|
|
|
|
|
938
|
zip_name = self.f_name(kwargs['id'], '.zip', dict_local['path'])
|
|
|
|
|
939
|
ziph = zipfile.ZipFile(dict_local['path'] + zip_name, 'w', zipfile.ZIP_DEFLATED, allowZip64=True)
|
|
|
|
|
940
|
self.f_zipdir(dir_name, ziph, zip_name)
|
|
|
|
|
941
|
ziph.close()
|
|
|
|
|
942
|
#Delete Temporal Path
|
|
|
|
|
943
|
if os.path.exists(tempdir[:-1]):
|
|
|
|
|
944
|
shutil.rmtree(tempdir[:-1])
|
|
|
|
|
945
|
#------------------------------#
|
|
|
|
|
946
|
print('.....')
|
|
|
|
|
947
|
return 'DOWNLOAD FINISHED'
|
|
|
|
|
948
|
else:
|
|
|
|
|
949
|
#Delete Temporal Path
|
|
|
|
|
950
|
if dict_local['zip']:
|
|
|
|
|
951
|
if os.path.exists(tempdir[:-1]):
|
|
|
|
|
952
|
shutil.rmtree(tempdir[:-1])
|
|
|
|
|
953
|
else:
|
|
|
|
|
954
|
if os.path.exists(dir_name[:-1]):
|
|
|
|
|
955
|
shutil.rmtree(dir_name[:-1])
|
|
|
|
|
956
|
return 'NO FILES WERE DOWNLOADED'
|
|
|
|
|
957
|
else:
|
|
|
|
|
958
|
return 'FILES NOT FOUND'
|
|
|
|
|
959
|
|
|
|
|
|
960
|
def download_files_advance(self, id_or_name, processes=1, path=os.path.expanduser("~"), **kwargs):
|
|
|
|
|
961
|
'''
|
|
417
|
'''
|
|
962
|
FINALIDAD:
|
|
418
|
FINALIDAD:
|
|
963
|
Funcion personalizada avanzada para la descarga de archivos existentes de un(os) dataset(s).
|
|
419
|
Funcion personalizada avanzada para la descarga de archivos existentes de un(os) dataset(s).
|
|
964
|
|
|
420
|
|
|
965
|
PARAMETROS DISPONIBLES:
|
|
421
|
PARAMETROS DISPONIBLES:
|
|
966
|
CONSULTAR: "GUIA DE SCRIPT.pdf"
|
|
422
|
CONSULTAR: "GUIA DE SCRIPT.pdf"
|
|
967
|
|
|
423
|
|
|
968
|
ESTRUCTURA:
|
|
424
|
ESTRUCTURA:
|
|
969
|
<access_name>.download_files_advance(id_or_name= <class 'str' or 'list'>, param_1 = <class 'param_1'>, ...)
|
|
425
|
<access_name>.download_files(id_or_name= <class 'str' or 'list'>, param_1 = <class 'param_1'>, ...)
|
|
970
|
'''
|
|
426
|
'''
|
|
971
|
#------------------ PATH ----------------------#
|
|
427
|
#------------------ PATH ----------------------#
|
|
972
|
if isinstance(path, str):
|
|
428
|
if isinstance(path, str):
|
|
973
|
if os.path.isdir(path):
|
|
429
|
if os.path.isdir(path):
|
|
974
|
if not path.endswith(os.sep):
|
|
430
|
if not path.endswith(os.sep):
|
|
975
|
path = path + os.sep
|
|
431
|
path = path + os.sep
|
|
976
|
test_txt = path + datetime.now().strftime("%Y_%m_%d_%H_%M_%S_%f")+'.txt'
|
|
432
|
test_txt = path + datetime.now().strftime("%Y_%m_%d_%H_%M_%S_%f")+'.txt'
|
|
977
|
try:
|
|
433
|
try:
|
|
978
|
file_txt = open(test_txt, 'w')
|
|
434
|
file_txt = open(test_txt, 'w')
|
|
979
|
file_txt.close()
|
|
435
|
file_txt.close()
|
|
980
|
os.remove(test_txt)
|
|
436
|
os.remove(test_txt)
|
|
981
|
except:
|
|
437
|
except:
|
|
982
|
return 'ERROR:: Access denied, you are not authorized to write files: "%s"' % (path)
|
|
438
|
return 'ERROR:: Access denied, you are not authorized to write files: "%s"' % (path)
|
|
983
|
else:
|
|
439
|
else:
|
|
984
|
return 'ERROR:: "path" does not exist'
|
|
440
|
return 'ERROR:: "path" does not exist'
|
|
985
|
else:
|
|
441
|
else:
|
|
986
|
return 'ERROR:: "path" must be: <class "str">'
|
|
442
|
return 'ERROR:: "path" must be: <class "str">'
|
|
987
|
|
|
443
|
|
|
988
|
#------------------ PROCESSES -----------------#
|
|
444
|
#------------------ PROCESSES -----------------#
|
|
989
|
if not isinstance(processes, int):
|
|
445
|
if not isinstance(processes, int):
|
|
990
|
return 'ERROR:: "processes" must be: <class "int">'
|
|
446
|
return 'ERROR:: "processes" must be: <class "int">'
|
|
991
|
|
|
447
|
|
|
992
|
#------------------ ID OR NAME ----------------#
|
|
448
|
#------------------ ID OR NAME ----------------#
|
|
993
|
if isinstance(id_or_name, str):
|
|
449
|
if isinstance(id_or_name, str):
|
|
994
|
id_or_name = [id_or_name]
|
|
450
|
id_or_name = [id_or_name]
|
|
995
|
elif isinstance(id_or_name, list):
|
|
451
|
elif isinstance(id_or_name, list):
|
|
996
|
id_or_name = list(map(str, id_or_name))
|
|
452
|
id_or_name = list(map(str, id_or_name))
|
|
997
|
else:
|
|
453
|
else:
|
|
998
|
return 'ERROR:: dataset "id_or_name" must be: <class "str" or "list">'
|
|
454
|
return 'ERROR:: dataset "id_or_name" must be: <class "str" or "list">'
|
|
999
|
#----------------------------------------------#
|
|
455
|
#----------------------------------------------#
|
|
1000
|
arguments = {
|
|
456
|
arguments = {
|
|
1001
|
'--apikey': self.Authorization,
|
|
457
|
'--apikey': self.Authorization,
|
|
1002
|
'--ckan-user': None,
|
|
458
|
'--ckan-user': None,
|
|
1003
|
'--config': None,
|
|
459
|
'--config': None,
|
|
1004
|
'--datapackages': path,
|
|
460
|
'--datapackages': path,
|
|
1005
|
'--datastore-fields': False,
|
|
461
|
'--datastore-fields': False,
|
|
1006
|
'--get-request': False,
|
|
462
|
'--get-request': False,
|
|
1007
|
'--insecure': not self.verify,
|
|
463
|
'--insecure': not self.verify,
|
|
1008
|
'--processes': str(processes),
|
|
464
|
'--processes': str(processes),
|
|
1009
|
'--quiet': False,
|
|
465
|
'--quiet': False,
|
|
1010
|
'--remote': self.url,
|
|
466
|
'--remote': self.url,
|
|
1011
|
'--worker': False,
|
|
467
|
'--worker': False,
|
|
1012
|
#'--log': 'log.txt',
|
|
468
|
#'--log': 'log.txt',
|
|
1013
|
#'--all': False,
|
|
469
|
#'--all': False,
|
|
1014
|
#'--gzip': False,
|
|
470
|
#'--gzip': False,
|
|
1015
|
#'--output': None,
|
|
471
|
#'--output': None,
|
|
1016
|
#'--max-records': None,
|
|
472
|
#'--max-records': None,
|
|
1017
|
#'--output-json': False,
|
|
473
|
#'--output-json': False,
|
|
1018
|
#'--output-jsonl': False,
|
|
474
|
#'--output-jsonl': False,
|
|
1019
|
#'--create-only': False,
|
|
475
|
#'--create-only': False,
|
|
1020
|
#'--help': False,
|
|
476
|
#'--help': False,
|
|
1021
|
#'--input': None,
|
|
477
|
#'--input': None,
|
|
1022
|
#'--input-json': False,
|
|
478
|
#'--input-json': False,
|
|
1023
|
#'--start-record': '1',
|
|
479
|
#'--start-record': '1',
|
|
1024
|
#'--update-only': False,
|
|
480
|
#'--update-only': False,
|
|
1025
|
#'--upload-logo': False,
|
|
481
|
#'--upload-logo': False,
|
|
1026
|
#'--upload-resources': False,
|
|
482
|
#'--upload-resources': False,
|
|
1027
|
#'--version': False,
|
|
483
|
#'--version': False,
|
|
1028
|
'ID_OR_NAME': id_or_name,
|
|
484
|
'ID_OR_NAME': id_or_name,
|
|
1029
|
'datasets': True,
|
|
485
|
'datasets': True,
|
|
1030
|
'dump': True,
|
|
486
|
'dump': True,
|
|
1031
|
#'ACTION_NAME': None,
|
|
487
|
#'ACTION_NAME': None,
|
|
1032
|
#'KEY:JSON': [],
|
|
488
|
#'KEY:JSON': [],
|
|
1033
|
#'KEY=STRING': [],
|
|
489
|
#'KEY=STRING': [],
|
|
1034
|
#'KEY@FILE': [],
|
|
490
|
#'KEY@FILE': [],
|
|
1035
|
#'action': False,
|
|
491
|
#'action': False,
|
|
1036
|
#'delete': False,
|
|
492
|
#'delete': False,
|
|
1037
|
#'groups': False,
|
|
493
|
#'groups': False,
|
|
1038
|
#'load': False,
|
|
494
|
#'load': False,
|
|
1039
|
#'organizations': False,
|
|
495
|
#'organizations': False,
|
|
1040
|
#'related': False,
|
|
496
|
#'related': False,
|
|
1041
|
#'search': False,
|
|
497
|
#'search': False,
|
|
1042
|
#'users': False
|
|
498
|
#'users': False
|
|
1043
|
}
|
|
499
|
}
|
|
1044
|
return logic_download.dump_things_change(self.ckan, 'datasets', arguments, **kwargs)
No newline at end of file
|
|
500
|
return logic_download.dump_things_change(self.ckan, 'datasets', arguments, **kwargs)
|