rda-python-icoads 3.0.2__tar.gz → 3.0.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rda_python_icoads-3.0.2/src/rda_python_icoads.egg-info → rda_python_icoads-3.0.4}/PKG-INFO +1 -1
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/pyproject.toml +1 -1
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads/fillicoads.py +98 -7
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads/fillmonth.py +55 -5
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads/pg_imma.py +21 -1
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4/src/rda_python_icoads.egg-info}/PKG-INFO +1 -1
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/LICENSE +0 -0
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/MANIFEST.in +0 -0
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/README.md +0 -0
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/setup.cfg +0 -0
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads/PgIMMA.py +0 -0
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads/R3.0-stat_doc.pdf +0 -0
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads/README_R3.0_Subset.html +0 -0
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads/__init__.py +0 -0
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads/checkicoads.py +0 -0
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads/cleanicoads.py +0 -0
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads/countattm.py +0 -0
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads/countattmvar.py +0 -0
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads/counticoads.py +0 -0
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads/countsst.py +0 -0
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads/fillinventory.py +0 -0
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads/fillitable.py +0 -0
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads/fixiidx.py +0 -0
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads/imma1_subset.py +0 -0
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads/maxsst.py +0 -0
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads/msg +0 -0
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads/msg3.0_subset_readme.txt +0 -0
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads/msg3_subset.py +0 -0
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads/msg_download.py +0 -0
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads/msgsubset.f +0 -0
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads/rdimma1_csv.f +0 -0
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads/writeicoads.py +0 -0
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads.egg-info/SOURCES.txt +0 -0
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads.egg-info/dependency_links.txt +0 -0
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads.egg-info/entry_points.txt +0 -0
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads.egg-info/requires.txt +0 -0
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads.egg-info/top_level.txt +0 -0
- {rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/tests/test_icoads.py +0 -0
|
@@ -117,6 +117,85 @@ class FillIcoads(PgIMMA):
|
|
|
117
117
|
|
|
118
118
|
if fcnt > 1: self.pglog("{} ({}) filled for {} files".format('/'.join(map(str, tcounts)), self.PVALS['names'], fcnt), self.LOGWRN)
|
|
119
119
|
|
|
120
|
+
#
|
|
121
|
+
# get the first data date in a given imma file
|
|
122
|
+
#
|
|
123
|
+
def get_imma_file_date(self, fname):
|
|
124
|
+
|
|
125
|
+
fdate = None
|
|
126
|
+
IMMA = open(fname, 'r', encoding = 'latin_1')
|
|
127
|
+
line = IMMA.readline()
|
|
128
|
+
self.identify_attm_name(line) # the date offset depends on the attm name
|
|
129
|
+
while line:
|
|
130
|
+
if not (self.PVALS['uatti'] and line[0:2] == self.PVALS['uatti']):
|
|
131
|
+
fdate = self.get_imma_date(line)
|
|
132
|
+
if fdate: break
|
|
133
|
+
line = IMMA.readline()
|
|
134
|
+
IMMA.close()
|
|
135
|
+
|
|
136
|
+
return fdate
|
|
137
|
+
|
|
138
|
+
#
|
|
139
|
+
# get the latest date filled into the inventory
|
|
140
|
+
#
|
|
141
|
+
def get_max_filled_date(self):
|
|
142
|
+
|
|
143
|
+
pgrec = self.pgget(f"{self.CNTLSC}.inventory", "max(date) mdate", "", self.LGEREX)
|
|
144
|
+
|
|
145
|
+
return self.format_date(pgrec['mdate']) if pgrec and pgrec['mdate'] else None
|
|
146
|
+
|
|
147
|
+
#
|
|
148
|
+
# the iidx values are allocated sequentially, so no date can be filled while an earlier one is
|
|
149
|
+
# still missing; a month must be filled up before the next month is filled, and a month cannot
|
|
150
|
+
# be skipped; months are sequenced by fillmonth, this only guards a direct call
|
|
151
|
+
#
|
|
152
|
+
def check_fill_order(self, fdate):
|
|
153
|
+
|
|
154
|
+
mdate = self.get_max_filled_date()
|
|
155
|
+
if not mdate: return # nothing filled yet
|
|
156
|
+
if self.diffdate(mdate, fdate) >= 0: return # the file holds filled dates already
|
|
157
|
+
|
|
158
|
+
rdate = self.adddate(mdate, 0, 0, 1) # the first missing date
|
|
159
|
+
if self.diffdate(fdate[0:7] + "-01", rdate) <= 0: return # the file covers it
|
|
160
|
+
|
|
161
|
+
self.pglog("{}: filled through {} only, fill from {} before filling {}".format(
|
|
162
|
+
mdate[0:7], mdate, rdate, fdate[0:7]), self.LGEREX)
|
|
163
|
+
|
|
164
|
+
#
|
|
165
|
+
# skip the dates that are filled already if the month of the given file is resumed
|
|
166
|
+
#
|
|
167
|
+
def get_resume_date(self, fname, fdate, bdate):
|
|
168
|
+
|
|
169
|
+
mdate = self.get_max_filled_date()
|
|
170
|
+
if not mdate: return bdate # nothing filled yet
|
|
171
|
+
if self.diffdate(mdate, fdate) < 0: return bdate # none of this file is filled yet
|
|
172
|
+
if self.diffdate(mdate, self.enddate(fdate, 0, 'M')) > 0: return bdate # refilling an earlier month
|
|
173
|
+
|
|
174
|
+
rdate = self.adddate(mdate, 0, 0, 1)
|
|
175
|
+
if bdate and self.diffdate(bdate, rdate) >= 0: return bdate
|
|
176
|
+
|
|
177
|
+
self.pglog("> {}: filled through {} already, continue filling from {}".format(
|
|
178
|
+
op.basename(fname), mdate, rdate), self.LOGWRN)
|
|
179
|
+
|
|
180
|
+
return rdate
|
|
181
|
+
|
|
182
|
+
#
|
|
183
|
+
# log an error, without stopping, if the month of the given file is not filled up, so that
|
|
184
|
+
# a partial fill is reported by the calling process and the month is resumed on a rerun
|
|
185
|
+
#
|
|
186
|
+
def check_month_filled(self, fname, fdate, bdate):
|
|
187
|
+
|
|
188
|
+
edate = self.enddate(fdate, 0, 'M')
|
|
189
|
+
pgrec = self.pgget(f"{self.CNTLSC}.inventory", "max(date) mdate",
|
|
190
|
+
"date BETWEEN '{}-01' AND '{}'".format(fdate[0:7], edate), self.LGEREX)
|
|
191
|
+
mdate = self.format_date(pgrec['mdate']) if pgrec and pgrec['mdate'] else None
|
|
192
|
+
if mdate == edate:
|
|
193
|
+
if bdate: self.pglog("> {}: filled up through {}".format(fdate[0:7], edate), self.LOGWRN)
|
|
194
|
+
return
|
|
195
|
+
|
|
196
|
+
self.pglog("{}: PARTIAL fill of {}, filled through {} of {}; rerun to fill the remaining dates".format(
|
|
197
|
+
op.basename(fname), fdate[0:7], (mdate if mdate else 'nothing'), edate), self.LOGERR)
|
|
198
|
+
|
|
120
199
|
#
|
|
121
200
|
# read icoads record from given file name and save them into IVADDB
|
|
122
201
|
#
|
|
@@ -125,19 +204,29 @@ class FillIcoads(PgIMMA):
|
|
|
125
204
|
iname = fname if addinventory else None
|
|
126
205
|
self.pglog("Record IMMA records in File '{}' into IVADDB".format(fname), self.WARNLG)
|
|
127
206
|
|
|
128
|
-
IMMA = open(fname, 'r', encoding = 'latin_1')
|
|
129
207
|
acounts = [0]*self.TABLECOUNT
|
|
130
208
|
records = {}
|
|
209
|
+
bdate = self.PVALS['dates'][0] if self.PVALS['dtlen'] > 0 else None
|
|
210
|
+
edate = self.PVALS['dates'][1] if self.PVALS['dtlen'] > 1 else None
|
|
211
|
+
|
|
212
|
+
fdate = self.get_imma_file_date(fname) if iname else None
|
|
213
|
+
if fdate:
|
|
214
|
+
if self.PVALS['dtlen'] == 0: self.check_fill_order(fdate)
|
|
215
|
+
bdate = self.get_resume_date(fname, fdate, bdate)
|
|
216
|
+
|
|
217
|
+
IMMA = open(fname, 'r', encoding = 'latin_1')
|
|
131
218
|
|
|
132
219
|
# get the first valid date and do initialization
|
|
220
|
+
cdate = None
|
|
133
221
|
line = IMMA.readline()
|
|
134
222
|
self.identify_attm_name(line) # check and record standalone attm name
|
|
135
223
|
while line:
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
self.
|
|
139
|
-
|
|
140
|
-
|
|
224
|
+
if not (self.PVALS['uatti'] and line[0:2] == self.PVALS['uatti']): # a standalone attm line holds no date
|
|
225
|
+
cdate = self.get_imma_date(line)
|
|
226
|
+
if cdate and (not bdate or self.diffdate(cdate, bdate) >= 0):
|
|
227
|
+
self.init_indices_for_date(cdate, iname)
|
|
228
|
+
records = self.get_imma_records(cdate, line, records)
|
|
229
|
+
break
|
|
141
230
|
line = IMMA.readline()
|
|
142
231
|
|
|
143
232
|
line = IMMA.readline()
|
|
@@ -152,7 +241,7 @@ class FillIcoads(PgIMMA):
|
|
|
152
241
|
for i in range(self.TABLECOUNT): acounts[i] += acnts[i]
|
|
153
242
|
records = {}
|
|
154
243
|
cdate = idate
|
|
155
|
-
if
|
|
244
|
+
if edate and self.diffdate(cdate, edate) > 0: break
|
|
156
245
|
self.init_indices_for_date(cdate, iname)
|
|
157
246
|
records = self.get_imma_records(idate, line, records)
|
|
158
247
|
line = IMMA.readline()
|
|
@@ -165,6 +254,8 @@ class FillIcoads(PgIMMA):
|
|
|
165
254
|
|
|
166
255
|
self.pglog("{} ({}) filled from {}".format(' '.join(map(str, acounts)), self.PVALS['names'], op.basename(fname)), self.LOGWRN)
|
|
167
256
|
|
|
257
|
+
if fdate and self.PVALS['dtlen'] == 0: self.check_month_filled(fname, fdate, bdate)
|
|
258
|
+
|
|
168
259
|
return acounts
|
|
169
260
|
|
|
170
261
|
# main function to execute this script
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
# 2025-03-03 transferred to package rda_python_icoads from
|
|
9
9
|
# https://github.com/NCAR/rda-icoads.git
|
|
10
10
|
# 2026-09-04 convert to class FillMonth
|
|
11
|
+
# 2026-09-09 fill each missing month, in order, up to the given month
|
|
11
12
|
# Purpose : process ICOADS monthly data file in IMMA1 format and fill into IVADDB
|
|
12
13
|
#
|
|
13
14
|
# Github : https://github.com/NCAR/rda-python-icoads.git
|
|
@@ -18,8 +19,9 @@ import sys
|
|
|
18
19
|
import re
|
|
19
20
|
from os import path as op
|
|
20
21
|
from rda_python_common.pg_util import PgUtil
|
|
22
|
+
from rda_python_common.pg_dbi import PgDBI
|
|
21
23
|
|
|
22
|
-
class FillMonth(PgUtil):
|
|
24
|
+
class FillMonth(PgUtil, PgDBI):
|
|
23
25
|
|
|
24
26
|
def __init__(self):
|
|
25
27
|
super().__init__()
|
|
@@ -27,7 +29,8 @@ class FillMonth(PgUtil):
|
|
|
27
29
|
'filenames' : ["IMMA1_R3.0.2_", "IMMA1_R3.0.3_"], # IMMA1_R3.0.3_ since 2025-08
|
|
28
30
|
'fillicoads' : "fillicoads -i ",
|
|
29
31
|
'fillitable' : "fillitable -t -v dck pt sid -r ",
|
|
30
|
-
'cdmsmonth' : "cdmsmonth "
|
|
32
|
+
'cdmsmonth' : "cdmsmonth ",
|
|
33
|
+
'inventory' : "cntldb.inventory"
|
|
31
34
|
}
|
|
32
35
|
|
|
33
36
|
#
|
|
@@ -36,7 +39,7 @@ class FillMonth(PgUtil):
|
|
|
36
39
|
def main(self):
|
|
37
40
|
|
|
38
41
|
argv = sys.argv[1:]
|
|
39
|
-
smonth =
|
|
42
|
+
smonth = None
|
|
40
43
|
|
|
41
44
|
for arg in argv:
|
|
42
45
|
if arg == "-b":
|
|
@@ -47,7 +50,6 @@ class FillMonth(PgUtil):
|
|
|
47
50
|
ms = re.match(r'^(\d+)-(\d+)', arg)
|
|
48
51
|
if ms:
|
|
49
52
|
smonth = "{:04}-{:02}".format(int(ms.group(1)), int(ms.group(2)))
|
|
50
|
-
srange = "{}-01 {}".format(smonth, self.enddate(smonth, 0, 'M'))
|
|
51
53
|
else:
|
|
52
54
|
self.pglog(arg +": Invalid month format", self.LGWNEX)
|
|
53
55
|
else:
|
|
@@ -56,14 +58,62 @@ class FillMonth(PgUtil):
|
|
|
56
58
|
if not smonth:
|
|
57
59
|
print("Usage: fillmonth ProcessMonth")
|
|
58
60
|
print(" Provide a month (YYYY-MM), to fill monthly IMMA1 into IVADDB")
|
|
61
|
+
print(" Any earlier month not filled up yet is filled first, in order")
|
|
59
62
|
sys.exit(0)
|
|
60
63
|
|
|
61
64
|
self.PGLOG['LOGFILE'] = "icoads.log"
|
|
65
|
+
self.ivaddb_dbname()
|
|
62
66
|
self.cmdlog("fillmonth {}".format(' '.join(argv)))
|
|
63
|
-
self.
|
|
67
|
+
months = self.get_fill_months(smonth)
|
|
68
|
+
if len(months) > 1:
|
|
69
|
+
self.pglog("> {}: fill {} months, {} through {}, in order".format(
|
|
70
|
+
smonth, len(months), months[0][0], months[-1][0]), self.LOGWRN)
|
|
71
|
+
mcnt = len(months)
|
|
72
|
+
for i in range(mcnt):
|
|
73
|
+
(cmonth, bdate, edate) = months[i]
|
|
74
|
+
self.fill_monthly_data(cmonth, "{} {}".format(bdate, edate))
|
|
75
|
+
if self.month_filled(cmonth, edate) or (i + 1) == mcnt: continue
|
|
76
|
+
# a later month cannot be filled while this one is short of dates
|
|
77
|
+
self.pglog("> {}: filled partially, stop before {}".format(cmonth, months[i+1][0]), self.LOGWRN)
|
|
78
|
+
break
|
|
64
79
|
self.cmdlog()
|
|
65
80
|
sys.exit(0)
|
|
66
81
|
|
|
82
|
+
#
|
|
83
|
+
# the iidx values are allocated sequentially, so every month between the last filled date
|
|
84
|
+
# and the given month must be filled, in order; return a [month, bdate, edate] per month,
|
|
85
|
+
# with bdate on the first month set to resume a partially filled month
|
|
86
|
+
#
|
|
87
|
+
def get_fill_months(self, smonth):
|
|
88
|
+
|
|
89
|
+
edate = self.enddate(smonth, 0, 'M')
|
|
90
|
+
pgrec = self.pgget(self.CMDS['inventory'], "max(date) mdate", "", self.LGEREX)
|
|
91
|
+
mdate = self.format_date(pgrec['mdate']) if pgrec and pgrec['mdate'] else None
|
|
92
|
+
if not mdate: return [[smonth, smonth + "-01", edate]] # nothing filled yet
|
|
93
|
+
|
|
94
|
+
bdate = self.adddate(mdate, 0, 0, 1) # resume the partial month, or start the next one
|
|
95
|
+
if self.diffdate(bdate, edate) > 0: return [[smonth, smonth + "-01", edate]] # refill an earlier month
|
|
96
|
+
|
|
97
|
+
months = []
|
|
98
|
+
while self.diffdate(bdate, edate) <= 0:
|
|
99
|
+
cmonth = bdate[0:7]
|
|
100
|
+
cedate = self.enddate(cmonth, 0, 'M')
|
|
101
|
+
if self.diffdate(cedate, edate) > 0: cedate = edate
|
|
102
|
+
months.append([cmonth, bdate, cedate])
|
|
103
|
+
bdate = self.adddate(cedate, 0, 0, 1)
|
|
104
|
+
|
|
105
|
+
return months
|
|
106
|
+
|
|
107
|
+
#
|
|
108
|
+
# check if the given month is filled through its last date
|
|
109
|
+
#
|
|
110
|
+
def month_filled(self, cmonth, edate):
|
|
111
|
+
|
|
112
|
+
pgrec = self.pgget(self.CMDS['inventory'], "max(date) mdate",
|
|
113
|
+
"date BETWEEN '{}-01' AND '{}'".format(cmonth, edate), self.LGEREX)
|
|
114
|
+
|
|
115
|
+
return (pgrec and pgrec['mdate'] and self.format_date(pgrec['mdate']) == edate)
|
|
116
|
+
|
|
67
117
|
#
|
|
68
118
|
# locate the monthly IMMA1 file, gunzip it if only the gzipped one is on file
|
|
69
119
|
#
|
|
@@ -375,7 +375,7 @@ class PgIMMA(PgOPT):
|
|
|
375
375
|
self.UIDOFFSET = 4
|
|
376
376
|
self.UIDLENGTH = 15
|
|
377
377
|
atti = line[15:17]
|
|
378
|
-
CURRN3 = int(line[12])
|
|
378
|
+
self.CURRN3 = int(line[12])
|
|
379
379
|
else:
|
|
380
380
|
atti = None
|
|
381
381
|
|
|
@@ -622,8 +622,28 @@ class PgIMMA(PgOPT):
|
|
|
622
622
|
#
|
|
623
623
|
# add multiple imma records into different tables in RDADB
|
|
624
624
|
#
|
|
625
|
+
# all writes for one date are wrapped in a single transaction, so an interrupted
|
|
626
|
+
# fill can never leave an inventory record behind without its data; the date is
|
|
627
|
+
# then simply refilled when the file is processed again
|
|
628
|
+
#
|
|
625
629
|
def add_imma_records(self, cdate, records):
|
|
626
630
|
|
|
631
|
+
self.starttran()
|
|
632
|
+
try:
|
|
633
|
+
acnts = self.add_date_records(cdate, records)
|
|
634
|
+
except BaseException:
|
|
635
|
+
self.aborttran()
|
|
636
|
+
self.pglog("{}: records rolled back for the date".format(cdate), self.LOGWRN)
|
|
637
|
+
raise
|
|
638
|
+
self.endtran()
|
|
639
|
+
|
|
640
|
+
return acnts
|
|
641
|
+
|
|
642
|
+
#
|
|
643
|
+
# add all records of one date into the attm and the control tables
|
|
644
|
+
#
|
|
645
|
+
def add_date_records(self, cdate, records):
|
|
646
|
+
|
|
627
647
|
if self.INVENTORY and self.IMMA_NAMES[0] in records: # add counting record into inventory table
|
|
628
648
|
rcnt = len(records[self.IMMA_NAMES[0]]['iidx'])
|
|
629
649
|
if rcnt > 0: self.INVENTORY = self.add_inventory_record(self.INVENTORY['fname'], cdate, rcnt, self.INVENTORY)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads/README_R3.0_Subset.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads/msg3.0_subset_readme.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads.egg-info/entry_points.txt
RENAMED
|
File without changes
|
{rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads.egg-info/requires.txt
RENAMED
|
File without changes
|
{rda_python_icoads-3.0.2 → rda_python_icoads-3.0.4}/src/rda_python_icoads.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|