ccfx 0.4.0__py3-none-any.whl → 0.5.0__py3-none-any.whl

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.
ccfx/ccfx.py CHANGED
@@ -27,7 +27,8 @@ from osgeo import gdal, ogr, osr
27
27
  import py7zr
28
28
  import subprocess
29
29
  import multiprocessing
30
-
30
+ from mutagen.mp3 import MP3
31
+ from mutagen.id3 import ID3, TPE1, TALB, TIT2, TRCK, TDRC, TCON, APIC, COMM, USLT, TPE2, TCOM, TPE3, TPE4, TCOP, TENC, TSRC, TBPM
31
32
 
32
33
 
33
34
  # functions
@@ -63,6 +64,138 @@ def getExtension(filePath:str) -> str:
63
64
  return os.path.splitext(filePath)[1].lstrip('.')
64
65
 
65
66
 
67
+ def getMp3Metadata(fn, imagePath=None):
68
+ '''
69
+ This function takes a path to mp3 and returns a dictionary with
70
+ the following keys:
71
+ - artist, album, title, track number, year, genre
72
+ '''
73
+ metadata = {}
74
+
75
+ try:
76
+ audio = MP3(fn, ID3=ID3)
77
+
78
+ if 'TPE1' in audio.tags: metadata['artist'] = str(audio.tags['TPE1'])
79
+ else: metadata['artist'] = "Unknown Artist"
80
+
81
+ if 'TALB' in audio.tags: metadata['album'] = str(audio.tags['TALB'])
82
+ else: metadata['album'] = "Unknown Album"
83
+
84
+ if 'TIT2' in audio.tags: metadata['title'] = str(audio.tags['TIT2'])
85
+ else: metadata['title'] = os.path.basename(fn).replace('.mp3', '')
86
+
87
+ if 'TRCK' in audio.tags: metadata['track_number'] = str(audio.tags['TRCK'])
88
+ else: metadata['track_number'] = "0"
89
+
90
+ if 'TDRC' in audio.tags: metadata['year'] = str(audio.tags['TDRC'])
91
+ else: metadata['year'] = "Unknown Year"
92
+
93
+ if 'TCON' in audio.tags: metadata['genre'] = str(audio.tags['TCON'])
94
+ else: metadata['genre'] = "Unknown Genre"
95
+
96
+ if imagePath is not None:
97
+ foundImage = False
98
+ if audio.tags:
99
+ for tagKey in audio.tags.keys():
100
+ if tagKey.startswith("APIC:"):
101
+ with open(imagePath, 'wb') as img_file:
102
+ img_file.write(audio.tags[tagKey].data)
103
+ foundImage = True
104
+ break
105
+ if not foundImage:
106
+ print("No image found in metadata.")
107
+
108
+ except Exception as e:
109
+ print(f"Error extracting metadata from {fn}: {e}")
110
+ # Set default values if extraction fails
111
+ metadata = {
112
+ 'artist': "Unknown Artist",
113
+ 'album': "Unknown Album",
114
+ 'title': os.path.basename(fn).replace('.mp3', ''),
115
+ 'track_number': "0",
116
+ 'year': "Unknown Year",
117
+ 'genre': "Unknown Genre"
118
+ }
119
+
120
+ return metadata
121
+
122
+ def guessMimeType(imagePath):
123
+ ext = os.path.splitext(imagePath.lower())[1]
124
+ if ext in ['.jpg', '.jpeg']:
125
+ return 'image/jpeg'
126
+ elif ext == '.png':
127
+ return 'image/png'
128
+ return 'image/png'
129
+
130
+ def setMp3Metadata(fn, metadata, imagePath=None):
131
+ '''
132
+ This function takes a path to an mp3 and a metadata dictionary,
133
+ then writes that metadata to the file's ID3 tags.
134
+
135
+ The metadata dictionary should have these keys:
136
+ - artist, album, title, track_number, year, genre
137
+
138
+ Additionally, an optional imagePath parameter can be provided to
139
+ attach album artwork from a PNG or JPEG file.
140
+
141
+ Alternatively, you can include an 'imagePath' key in the metadata
142
+ dictionary instead of using the separate parameter.
143
+ '''
144
+ try:
145
+ # Try to load existing ID3 tags or create new ones if they don't exist
146
+ try:
147
+ audio = ID3(fn)
148
+ except:
149
+ audio = ID3()
150
+
151
+ # Set artist
152
+ if 'artist' in metadata and metadata['artist']: audio['TPE1'] = TPE1(encoding=3, text=metadata['artist'])
153
+ if 'album' in metadata and metadata['album']: audio['TALB'] = TALB(encoding=3, text=metadata['album'])
154
+ if 'title' in metadata and metadata['title']: audio['TIT2'] = TIT2(encoding=3, text=metadata['title'])
155
+ if 'track_number' in metadata and metadata['track_number']: audio['TRCK'] = TRCK(encoding=3, text=metadata['track_number'])
156
+ if 'year' in metadata and metadata['year']: audio['TDRC'] = TDRC(encoding=3, text=metadata['year'])
157
+ if 'genre' in metadata and metadata['genre']: audio['TCON'] = TCON(encoding=3, text=metadata['genre'])
158
+ if 'comment' in metadata and metadata['comment']: audio['COMM'] = COMM(encoding=3, text=metadata['comment'])
159
+ if 'lyrics' in metadata and metadata['lyrics']: audio['USLT'] = USLT(encoding=3, text=metadata['lyrics'])
160
+ if 'publisher' in metadata and metadata['publisher']: audio['TPUB'] = TPE2(encoding=3, text=metadata['publisher'])
161
+ if 'composer' in metadata and metadata['composer']: audio['TCOM'] = TCOM(encoding=3, text=metadata['composer'])
162
+ if 'conductor' in metadata and metadata['conductor']: audio['TPE3'] = TPE3(encoding=3, text=metadata['conductor'])
163
+ if 'performer' in metadata and metadata['performer']: audio['TPE4'] = TPE4(encoding=3, text=metadata['performer'])
164
+ if 'copyright' in metadata and metadata['copyright']: audio['TCOP'] = TCOP(encoding=3, text=metadata['copyright'])
165
+ if 'encoded_by' in metadata and metadata['encoded_by']: audio['TENC'] = TENC(encoding=3, text=metadata['encoded_by'])
166
+ if 'encoder' in metadata and metadata['encoder']: audio['TENC'] = TENC(encoding=3, text=metadata['encoder'])
167
+ if 'isrc' in metadata and metadata['isrc']: audio['TSRC'] = TSRC(encoding=3, text=metadata['isrc'])
168
+ if 'bpm' in metadata and metadata['bpm']: audio['TBPM'] = TBPM(encoding=3, text=metadata['bpm'])
169
+ # Check if image path is in metadata dictionary and not provided as parameter
170
+ if imagePath is None and 'imagePath' in metadata:
171
+ imagePath = metadata['imagePath']
172
+
173
+ # Attach image if provided
174
+ if imagePath and os.path.exists(imagePath):
175
+ with open(imagePath, 'rb') as img_file:
176
+ img_data = img_file.read()
177
+
178
+ # Determine image MIME type
179
+ mime = guessMimeType(imagePath)
180
+
181
+ # Create APIC frame for album artwork
182
+ audio['APIC'] = APIC(
183
+ encoding=3, # UTF-8 encoding
184
+ mime=mime, # MIME type of the image
185
+ type=3, # 3 means 'Cover (front)'
186
+ desc='Cover', # Description
187
+ data=img_data # The image data
188
+ )
189
+
190
+ # Save changes to the file
191
+ audio.save(fn)
192
+ return True
193
+
194
+ except Exception as e:
195
+ print(f"Error writing metadata to {fn}: {e}")
196
+ return False
197
+
198
+
66
199
  def deleteFile(filePath:str, v:bool = False) -> bool:
67
200
  '''
68
201
  Delete a file
@@ -439,8 +572,11 @@ def moveDirectoryFiles(srcDir: str, destDir: str, v: bool = False) -> bool:
439
572
  src_file = os.path.join(root, file)
440
573
  dest_file = os.path.join(dest_root, file)
441
574
  if v:
442
- print(f"\t> Moving file \n\t - {src_file}\n\t - to {dest_file}")
443
- shutil.move(src_file, dest_file)
575
+ print(f"\t> Moving file \n\t - {src_file}\n\t to {dest_file}")
576
+ try:
577
+ shutil.move(src_file, dest_file)
578
+ except Exception as e:
579
+ print(f"! Error moving file: {e}")
444
580
 
445
581
  return True
446
582
 
@@ -1314,4 +1450,25 @@ def getMSE(data:pandas.DataFrame, observed:str = None, simulated:str = None, res
1314
1450
 
1315
1451
  return stats['MSE']
1316
1452
 
1453
+ def getTimeseriesStats(data:pandas.DataFrame, observed:str = None, simulated:str = None, resample:str = None ) -> dict:
1454
+ '''
1455
+ this function is a wrapper for calculateTimeseriesStats specifically to return all stats
1456
+
1457
+ data: pandas.DataFrame
1458
+ DataFrame containing the timeseries data
1459
+ observed: str
1460
+ name of the observed column
1461
+ simulated: str
1462
+ name of the simulated column
1463
+ resample: str
1464
+ if specified, the data will be resampled to the specified frequency
1465
+ available options: 'H' (hourly), 'D' (daily), 'M' (monthly), 'Y' (yearly)
1466
+
1467
+ return: dict
1468
+ dictionary containing all stats
1469
+ '''
1470
+ stats = calculateTimeseriesStats(data, observed, simulated, resample)
1471
+
1472
+ return stats
1473
+
1317
1474
  ignoreWarnings()
@@ -1,146 +1,148 @@
1
- Metadata-Version: 2.1
2
- Name: ccfx
3
- Version: 0.4.0
4
- Summary: This package implifies regular coommon actions for quick prototyping in a user friendly way
5
- Author-email: Celray James CHAWANDA <celray@chawanda.com>
6
- License: MIT
7
- Project-URL: Homepage, https://github.com/celray/ccfx
8
- Classifier: Programming Language :: Python :: 3
9
- Classifier: License :: OSI Approved :: MIT License
10
- Classifier: Operating System :: OS Independent
11
- Requires-Python: >=3.10
12
- Description-Content-Type: text/markdown
13
- License-File: LICENSE
14
- Requires-Dist: netCDF4
15
- Requires-Dist: gdal
16
- Requires-Dist: numpy
17
- Requires-Dist: shapely
18
- Requires-Dist: geopandas
19
- Requires-Dist: pandas
20
- Requires-Dist: xlsxwriter
21
- Requires-Dist: pyodbc
22
- Requires-Dist: sqlalchemy
23
- Requires-Dist: python-docx
24
- Requires-Dist: py7zr
25
-
26
- # ccfx
27
-
28
- `ccfx` is a comprehensive Python package designed to streamline file and data management, geospatial analysis, and NetCDF file processing for quick prototyping. The library provides versatile tools for file handling, raster and vector manipulation, database connectivity, and data export for geospatial and scientific computing projects.
29
-
30
- ## Features
31
-
32
- 1. **File Management**:
33
- - List, delete, move, and count files within directories.
34
- - Monitor file count over time in a specific directory.
35
- - Save, load, and manage Python variables via pickle serialization.
36
-
37
- 2. **Geospatial Data Processing**:
38
- - Read, write, and manage raster and vector geospatial data.
39
- - Clip rasters by bounding boxes and extract raster values at specified coordinates.
40
- - Create grids of polygons based on shapefile boundaries with user-defined resolutions.
41
- - Convert coordinates between coordinate reference systems (CRS).
42
- - Write NumPy arrays to GeoTIFF files with projection and geotransform settings.
43
-
44
- 3. **NetCDF File Handling**:
45
- - List available variables and dimensions in NetCDF files.
46
- - Export NetCDF variables to GeoTIFF format.
47
- - Calculate sum and average maps from NetCDF data across multiple files.
48
-
49
- 4. **Database Connectivity**:
50
- - Access and interact with databases using ODBC and SQLAlchemy for flexible database management.
51
- - Connect to both SQL Server and SQLite databases.
52
-
53
- 5. **Progress Tracking and System Info**:
54
- - Display dynamic progress bars for long-running operations.
55
- - Check the system’s platform information.
56
- - Enable or disable warnings programmatically.
57
-
58
- 6. **Excel and Word File Handling**:
59
- - Create and modify Excel files using xlsxwriter.
60
- - Generate Word documents with advanced formatting options using python-docx.
61
-
62
- ## Installation
63
-
64
- Install `ccfx` via pip:
65
- ```bash
66
- pip install ccfx
67
- ```
68
-
69
- ## Dependencies
70
-
71
- `ccfx` relies on the following libraries:
72
-
73
- - **netCDF4**: For working with NetCDF files.
74
- - **gdal**: Required for geospatial raster data manipulation.
75
- - **numpy**: For array processing and numerical operations.
76
- - **pandas**: For data manipulation and analysis.
77
- - **shapely**: Provides geometric operations for spatial data.
78
- - **geopandas**: Extends pandas to handle geospatial data.
79
- - **xlsxwriter**: For creating and writing Excel files.
80
- - **pyodbc**: Enables connectivity to databases through ODBC.
81
- - **sqlalchemy**: Provides SQL toolkit and ORM features for database access.
82
- - **python-docx**: Enables creation and manipulation of Word documents.
83
-
84
- These dependencies will be installed automatically when `ccfx` is installed.
85
-
86
- ## API Reference
87
-
88
- ### `listFiles(path: str, ext: str = None) -> list`
89
- Lists all files in a directory with a specified extension.
90
-
91
- - **Parameters**:
92
- - `path` (str): The directory to search.
93
- - `ext` (str, optional): File extension to filter by, e.g., `'txt'`, `'.txt'`, `'*txt'`, or `'*.txt'`.
94
-
95
- - **Returns**:
96
- - `list`: A list of file paths matching the criteria.
97
-
98
- ### `deleteFile(filePath: str, v: bool = False) -> bool`
99
- Deletes a specified file with optional verbose output.
100
-
101
- - **Parameters**:
102
- - `filePath` (str): Path to the file to be deleted.
103
- - `v` (bool, optional): If `True`, prints a confirmation message. Defaults to `False`.
104
-
105
- - **Returns**:
106
- - `bool`: `True` if deletion was successful; `False` otherwise.
107
-
108
- ### `createGrid(shapefile_path: str, resolution: float, useDegree: bool = True) -> tuple`
109
- Generates a grid of polygons from a shapefile at a given resolution.
110
-
111
- - **Parameters**:
112
- - `shapefile_path` (str): Path to the shapefile.
113
- - `resolution` (float): Resolution of the grid.
114
- - `useDegree` (bool, optional): If `True`, coordinates are in degrees. Defaults to `True`.
115
-
116
- - **Returns**:
117
- - `tuple`: Contains grid coordinates and metadata.
118
-
119
- ### `clipRasterByExtent(inFile: str, outFile: str, bounds: tuple) -> str`
120
- Clips a raster to specified bounding box coordinates.
121
-
122
- - **Parameters**:
123
- - `inFile` (str): Path to the input raster file.
124
- - `outFile` (str): Path to the output clipped raster file.
125
- - `bounds` (tuple): Bounding box as `(minx, miny, maxx, maxy)`.
126
-
127
- - **Returns**:
128
- - `str`: Path to the clipped raster file.
129
-
130
- ### `netcdfVariablesList(ncFile: str) -> list`
131
- Lists all variables in a NetCDF file.
132
-
133
- - **Parameters**:
134
- - `ncFile` (str): Path to the NetCDF file.
135
-
136
- - **Returns**:
137
- - `list`: A list of variable names in the file.
138
-
139
- ### ... And More ...
140
-
141
- ## Contributing
142
-
143
- Contributions are welcome! Please fork the repository, make your changes, and submit a pull request.
144
-
145
- ## License
146
- This project is licensed under the MIT License.
1
+ Metadata-Version: 2.4
2
+ Name: ccfx
3
+ Version: 0.5.0
4
+ Summary: This package simplifies regular common actions for quick prototyping in a user friendly way
5
+ Author-email: Celray James CHAWANDA <celray@chawanda.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/celray/ccfx
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.10
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: netCDF4
15
+ Requires-Dist: gdal
16
+ Requires-Dist: numpy
17
+ Requires-Dist: shapely
18
+ Requires-Dist: geopandas
19
+ Requires-Dist: pandas
20
+ Requires-Dist: xlsxwriter
21
+ Requires-Dist: pyodbc
22
+ Requires-Dist: sqlalchemy
23
+ Requires-Dist: python-docx
24
+ Requires-Dist: py7zr
25
+ Requires-Dist: mutagen
26
+ Dynamic: license-file
27
+
28
+ # ccfx
29
+
30
+ `ccfx` is a comprehensive Python package designed to streamline file and data management, geospatial analysis, and NetCDF file processing for quick prototyping. The library provides versatile tools for file handling, raster and vector manipulation, database connectivity, and data export for geospatial and scientific computing projects.
31
+
32
+ ## Features
33
+
34
+ 1. **File Management**:
35
+ - List, delete, move, and count files within directories.
36
+ - Monitor file count over time in a specific directory.
37
+ - Save, load, and manage Python variables via pickle serialization.
38
+
39
+ 2. **Geospatial Data Processing**:
40
+ - Read, write, and manage raster and vector geospatial data.
41
+ - Clip rasters by bounding boxes and extract raster values at specified coordinates.
42
+ - Create grids of polygons based on shapefile boundaries with user-defined resolutions.
43
+ - Convert coordinates between coordinate reference systems (CRS).
44
+ - Write NumPy arrays to GeoTIFF files with projection and geotransform settings.
45
+
46
+ 3. **NetCDF File Handling**:
47
+ - List available variables and dimensions in NetCDF files.
48
+ - Export NetCDF variables to GeoTIFF format.
49
+ - Calculate sum and average maps from NetCDF data across multiple files.
50
+
51
+ 4. **Database Connectivity**:
52
+ - Access and interact with databases using ODBC and SQLAlchemy for flexible database management.
53
+ - Connect to both SQL Server and SQLite databases.
54
+
55
+ 5. **Progress Tracking and System Info**:
56
+ - Display dynamic progress bars for long-running operations.
57
+ - Check the system’s platform information.
58
+ - Enable or disable warnings programmatically.
59
+
60
+ 6. **Excel and Word File Handling**:
61
+ - Create and modify Excel files using xlsxwriter.
62
+ - Generate Word documents with advanced formatting options using python-docx.
63
+
64
+ ## Installation
65
+
66
+ Install `ccfx` via pip:
67
+ ```bash
68
+ pip install ccfx
69
+ ```
70
+
71
+ ## Dependencies
72
+
73
+ `ccfx` relies on the following libraries:
74
+
75
+ - **netCDF4**: For working with NetCDF files.
76
+ - **gdal**: Required for geospatial raster data manipulation.
77
+ - **numpy**: For array processing and numerical operations.
78
+ - **pandas**: For data manipulation and analysis.
79
+ - **shapely**: Provides geometric operations for spatial data.
80
+ - **geopandas**: Extends pandas to handle geospatial data.
81
+ - **xlsxwriter**: For creating and writing Excel files.
82
+ - **pyodbc**: Enables connectivity to databases through ODBC.
83
+ - **sqlalchemy**: Provides SQL toolkit and ORM features for database access.
84
+ - **python-docx**: Enables creation and manipulation of Word documents.
85
+
86
+ These dependencies will be installed automatically when `ccfx` is installed.
87
+
88
+ ## API Reference
89
+
90
+ ### `listFiles(path: str, ext: str = None) -> list`
91
+ Lists all files in a directory with a specified extension.
92
+
93
+ - **Parameters**:
94
+ - `path` (str): The directory to search.
95
+ - `ext` (str, optional): File extension to filter by, e.g., `'txt'`, `'.txt'`, `'*txt'`, or `'*.txt'`.
96
+
97
+ - **Returns**:
98
+ - `list`: A list of file paths matching the criteria.
99
+
100
+ ### `deleteFile(filePath: str, v: bool = False) -> bool`
101
+ Deletes a specified file with optional verbose output.
102
+
103
+ - **Parameters**:
104
+ - `filePath` (str): Path to the file to be deleted.
105
+ - `v` (bool, optional): If `True`, prints a confirmation message. Defaults to `False`.
106
+
107
+ - **Returns**:
108
+ - `bool`: `True` if deletion was successful; `False` otherwise.
109
+
110
+ ### `createGrid(shapefile_path: str, resolution: float, useDegree: bool = True) -> tuple`
111
+ Generates a grid of polygons from a shapefile at a given resolution.
112
+
113
+ - **Parameters**:
114
+ - `shapefile_path` (str): Path to the shapefile.
115
+ - `resolution` (float): Resolution of the grid.
116
+ - `useDegree` (bool, optional): If `True`, coordinates are in degrees. Defaults to `True`.
117
+
118
+ - **Returns**:
119
+ - `tuple`: Contains grid coordinates and metadata.
120
+
121
+ ### `clipRasterByExtent(inFile: str, outFile: str, bounds: tuple) -> str`
122
+ Clips a raster to specified bounding box coordinates.
123
+
124
+ - **Parameters**:
125
+ - `inFile` (str): Path to the input raster file.
126
+ - `outFile` (str): Path to the output clipped raster file.
127
+ - `bounds` (tuple): Bounding box as `(minx, miny, maxx, maxy)`.
128
+
129
+ - **Returns**:
130
+ - `str`: Path to the clipped raster file.
131
+
132
+ ### `netcdfVariablesList(ncFile: str) -> list`
133
+ Lists all variables in a NetCDF file.
134
+
135
+ - **Parameters**:
136
+ - `ncFile` (str): Path to the NetCDF file.
137
+
138
+ - **Returns**:
139
+ - `list`: A list of variable names in the file.
140
+
141
+ ### ... And More ...
142
+
143
+ ## Contributing
144
+
145
+ Contributions are welcome! Please fork the repository, make your changes, and submit a pull request.
146
+
147
+ ## License
148
+ This project is licensed under the MIT License.
@@ -0,0 +1,11 @@
1
+ ccfx/__init__.py,sha256=VmBeF3oj6JTJ_793d4i8PvhyF8_FxaxA1L_FmHWqitc,142
2
+ ccfx/ccfx.py,sha256=A61uV0bKlusLAcLlgNVhKaMQ4KutWxB7hzEQnitJpus,51808
3
+ ccfx/excel.py,sha256=cQ4TQW49XqbMB3sSS0IOhO3-WArIolEBIrvOvhFyPtI,4757
4
+ ccfx/mssqlConnection.py,sha256=TwyZXhHHI7zy6BSfH1pszuHVJ5cmndRC5dVxvEtSTks,7904
5
+ ccfx/sqliteConnection.py,sha256=jEJ94D5ySt84N7AeDpa27Rclt1NaKhkX6nYzidwApIg,11104
6
+ ccfx/word.py,sha256=AGa64jX5Zl5qotZh5L0QmrsjTnktIBhmj_ByRKZ88vw,3061
7
+ ccfx-0.5.0.dist-info/licenses/LICENSE,sha256=2-M3fBUS3FmrSIrqd3cZDmxXxojWVJtZY-SHSRE6RxM,1098
8
+ ccfx-0.5.0.dist-info/METADATA,sha256=6tpyj3FwWBdkm8BCvU26J9rZFsP_mCIoZUxTb71GYRA,5381
9
+ ccfx-0.5.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
10
+ ccfx-0.5.0.dist-info/top_level.txt,sha256=_cSvSA1WX2K8TgoV3iBJUdUZZqMKJbOPLNnKLYSLHaw,5
11
+ ccfx-0.5.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.6.0)
2
+ Generator: setuptools (78.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,11 +0,0 @@
1
- ccfx/__init__.py,sha256=VmBeF3oj6JTJ_793d4i8PvhyF8_FxaxA1L_FmHWqitc,142
2
- ccfx/ccfx.py,sha256=TcGb46QY57295iRfRnMwdm_fjjQ1Z-VDDlzveahRoEw,44547
3
- ccfx/excel.py,sha256=cQ4TQW49XqbMB3sSS0IOhO3-WArIolEBIrvOvhFyPtI,4757
4
- ccfx/mssqlConnection.py,sha256=TwyZXhHHI7zy6BSfH1pszuHVJ5cmndRC5dVxvEtSTks,7904
5
- ccfx/sqliteConnection.py,sha256=jEJ94D5ySt84N7AeDpa27Rclt1NaKhkX6nYzidwApIg,11104
6
- ccfx/word.py,sha256=AGa64jX5Zl5qotZh5L0QmrsjTnktIBhmj_ByRKZ88vw,3061
7
- ccfx-0.4.0.dist-info/LICENSE,sha256=2-M3fBUS3FmrSIrqd3cZDmxXxojWVJtZY-SHSRE6RxM,1098
8
- ccfx-0.4.0.dist-info/METADATA,sha256=3llLy7xyGpG1tpvmB9LZc4csbq-R41UoGMlR95ajT-s,5482
9
- ccfx-0.4.0.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
10
- ccfx-0.4.0.dist-info/top_level.txt,sha256=_cSvSA1WX2K8TgoV3iBJUdUZZqMKJbOPLNnKLYSLHaw,5
11
- ccfx-0.4.0.dist-info/RECORD,,