ccfx 1.0.7__py3-none-any.whl → 1.0.8__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 +45 -45
- {ccfx-1.0.7.dist-info → ccfx-1.0.8.dist-info}/METADATA +1 -1
- {ccfx-1.0.7.dist-info → ccfx-1.0.8.dist-info}/RECORD +6 -6
- {ccfx-1.0.7.dist-info → ccfx-1.0.8.dist-info}/WHEEL +0 -0
- {ccfx-1.0.7.dist-info → ccfx-1.0.8.dist-info}/licenses/LICENSE +0 -0
- {ccfx-1.0.7.dist-info → ccfx-1.0.8.dist-info}/top_level.txt +0 -0
ccfx/ccfx.py
CHANGED
@@ -35,7 +35,7 @@ import math
|
|
35
35
|
import requests
|
36
36
|
from tqdm import tqdm
|
37
37
|
import yt_dlp
|
38
|
-
from typing import Optional
|
38
|
+
from typing import Optional, Any
|
39
39
|
from datetime import datetime, timedelta
|
40
40
|
from PIL import Image
|
41
41
|
|
@@ -72,7 +72,7 @@ def getExtension(filePath:str) -> str:
|
|
72
72
|
return os.path.splitext(filePath)[1].lstrip('.')
|
73
73
|
|
74
74
|
|
75
|
-
def getMp3Metadata(fn, imagePath=None):
|
75
|
+
def getMp3Metadata(fn: str, imagePath: Optional[str] = None) -> dict:
|
76
76
|
'''
|
77
77
|
This function takes a path to mp3 and returns a dictionary with
|
78
78
|
the following keys:
|
@@ -127,7 +127,7 @@ def getMp3Metadata(fn, imagePath=None):
|
|
127
127
|
return metadata
|
128
128
|
|
129
129
|
|
130
|
-
def guessMimeType(imagePath):
|
130
|
+
def guessMimeType(imagePath: str) -> str:
|
131
131
|
ext = os.path.splitext(imagePath.lower())[1]
|
132
132
|
if ext in ['.jpg', '.jpeg']:
|
133
133
|
return 'image/jpeg'
|
@@ -240,7 +240,7 @@ def parseYoutubeChannelVideos(channelUrl: str, maxItems: Optional[int] = None) -
|
|
240
240
|
return [f"https://www.youtube.com/watch?v={e['id']}" for e in entries if e.get("id")]
|
241
241
|
|
242
242
|
|
243
|
-
def runSWATPlus(txtinoutDir: str, finalDir: str, executablePath: str = "swatplus", v: bool = True):
|
243
|
+
def runSWATPlus(txtinoutDir: str, finalDir: str, executablePath: str = "swatplus", v: bool = True) -> None:
|
244
244
|
os.chdir(txtinoutDir)
|
245
245
|
|
246
246
|
if not v:
|
@@ -339,7 +339,7 @@ def formatTimedelta(delta: timedelta) -> str:
|
|
339
339
|
return f"{time_fmt}"
|
340
340
|
|
341
341
|
|
342
|
-
def setMp3Metadata(fn, metadata, imagePath=None):
|
342
|
+
def setMp3Metadata(fn: str, metadata: dict, imagePath: Optional[str] = None) -> bool:
|
343
343
|
'''
|
344
344
|
This function takes a path to an mp3 and a metadata dictionary,
|
345
345
|
then writes that metadata to the file's ID3 tags.
|
@@ -434,7 +434,7 @@ def deleteFile(filePath:str, v:bool = False) -> bool:
|
|
434
434
|
|
435
435
|
return deleted
|
436
436
|
|
437
|
-
def removeImageColour(inPath:str, outPath:str, colour:tuple = (255, 255, 255), tolerance:int = 30):
|
437
|
+
def removeImageColour(inPath:str, outPath:str, colour:tuple = (255, 255, 255), tolerance:int = 30) -> None:
|
438
438
|
'''
|
439
439
|
Remove a specific color from an image.
|
440
440
|
colour: RGB tuple, e.g., (255, 0, 0) for red
|
@@ -457,7 +457,7 @@ def removeImageColour(inPath:str, outPath:str, colour:tuple = (255, 255, 255), t
|
|
457
457
|
img.putdata(new_data)
|
458
458
|
img.save(outPath)
|
459
459
|
|
460
|
-
def makeTransparent(inPath:str, outPath:str, colour:tuple = (255, 255, 255), tolerance:int = 30):
|
460
|
+
def makeTransparent(inPath:str, outPath:str, colour:tuple = (255, 255, 255), tolerance:int = 30) -> None:
|
461
461
|
'''
|
462
462
|
Make some pixels in an image transparent.
|
463
463
|
'''
|
@@ -519,7 +519,7 @@ def deletePath(path:str, v:bool = False) -> bool:
|
|
519
519
|
deleted = False
|
520
520
|
|
521
521
|
|
522
|
-
def downloadChunk(url, start, end, path):
|
522
|
+
def downloadChunk(url: str, start: int, end: int, path: str) -> None:
|
523
523
|
headers = {'Range': f'bytes={start}-{end}'}
|
524
524
|
response = requests.get(url, headers=headers, stream=True)
|
525
525
|
with open(path, 'wb') as f:
|
@@ -528,7 +528,7 @@ def downloadChunk(url, start, end, path):
|
|
528
528
|
f.write(chunk)
|
529
529
|
|
530
530
|
|
531
|
-
def formatStringBlock(input_str, max_chars=70):
|
531
|
+
def formatStringBlock(input_str: str, max_chars: int = 70) -> str:
|
532
532
|
'''
|
533
533
|
This function takes a string and formats it into a block of text
|
534
534
|
with a maximum number of characters per line.
|
@@ -559,7 +559,7 @@ def formatStringBlock(input_str, max_chars=70):
|
|
559
559
|
|
560
560
|
|
561
561
|
|
562
|
-
def downloadFile(url, save_path, exists_action='resume', num_connections=5, v=False):
|
562
|
+
def downloadFile(url: str, save_path: str, exists_action: str = 'resume', num_connections: int = 5, v: bool = False) -> None:
|
563
563
|
if v:
|
564
564
|
print(f"\ndownloading {url}")
|
565
565
|
fname = getFileBaseName(url, extension=True)
|
@@ -649,7 +649,7 @@ def systemPlatform() -> str:
|
|
649
649
|
'''
|
650
650
|
return platform.system()
|
651
651
|
|
652
|
-
def progressBar(count, total, message=""):
|
652
|
+
def progressBar(count: int, total: int, message: str = "") -> None:
|
653
653
|
percent = int(count / total * 100)
|
654
654
|
filled = int(percent / 2)
|
655
655
|
bar = '█' * filled + '░' * (50 - filled)
|
@@ -669,7 +669,7 @@ def fileCount(path:str = "./", extension:str = ".*", v:bool = True) -> int:
|
|
669
669
|
print(f'> there are {count} {extension if not extension ==".*" else ""} files in {path}')
|
670
670
|
return count
|
671
671
|
|
672
|
-
def resampleRaster(inFile:str, outFile:str, resolution:float, dstSRS = None, resamplingMethod = 'bilinear', replaceOutput:bool = True, v:bool = True) -> str:
|
672
|
+
def resampleRaster(inFile:str, outFile:str, resolution:float, dstSRS = None, resamplingMethod = 'bilinear', replaceOutput:bool = True, v:bool = True) -> Optional[str]:
|
673
673
|
'''
|
674
674
|
Resample a raster file
|
675
675
|
inFile: input raster file
|
@@ -740,7 +740,7 @@ def watchFileCount(path:str="./", extension:str = ".*", interval:float = 0.2, du
|
|
740
740
|
return None
|
741
741
|
|
742
742
|
|
743
|
-
def pythonVariable(filename, option, variable=None):
|
743
|
+
def pythonVariable(filename: str, option: str, variable: Any = None) -> Any:
|
744
744
|
'''
|
745
745
|
option: save, load or open
|
746
746
|
|
@@ -774,7 +774,7 @@ def listFolders(path:str) -> list:
|
|
774
774
|
else:
|
775
775
|
return []
|
776
776
|
|
777
|
-
def readFrom(filename, decode_codec = None, v=False):
|
777
|
+
def readFrom(filename: str, decode_codec: Optional[str] = None, v: bool = False) -> Any:
|
778
778
|
'''
|
779
779
|
a function to read ascii files
|
780
780
|
'''
|
@@ -793,16 +793,16 @@ def readFrom(filename, decode_codec = None, v=False):
|
|
793
793
|
|
794
794
|
|
795
795
|
def pointsToGeodataframe(
|
796
|
-
rowList,
|
797
|
-
columnNames,
|
798
|
-
latIndex,
|
799
|
-
lonIndex,
|
800
|
-
auth = "EPSG",
|
801
|
-
code = "4326",
|
802
|
-
outShape = "",
|
803
|
-
format = "gpkg",
|
804
|
-
v = False,
|
805
|
-
includeLatLon = True ) -> geopandas.GeoDataFrame:
|
796
|
+
rowList: list,
|
797
|
+
columnNames: list,
|
798
|
+
latIndex: int,
|
799
|
+
lonIndex: int,
|
800
|
+
auth: str = "EPSG",
|
801
|
+
code: str = "4326",
|
802
|
+
outShape: str = "",
|
803
|
+
format: str = "gpkg",
|
804
|
+
v: bool = False,
|
805
|
+
includeLatLon: bool = True ) -> geopandas.GeoDataFrame:
|
806
806
|
df = pandas.DataFrame(rowList, columns = columnNames)
|
807
807
|
geometry = [
|
808
808
|
Point(row[lonIndex], row[latIndex]) for row in rowList
|
@@ -824,10 +824,10 @@ def pointsToGeodataframe(
|
|
824
824
|
return gdf
|
825
825
|
|
826
826
|
|
827
|
-
def readFile(filename, decode_codec = None, v=False):
|
827
|
+
def readFile(filename: str, decode_codec: Optional[str] = None, v: bool = False) -> Any:
|
828
828
|
return readFrom(filename, decode_codec, v)
|
829
829
|
|
830
|
-
def writeTo(filename, file_text, encode_codec = None, v=False) -> bool:
|
830
|
+
def writeTo(filename: str, file_text: Any, encode_codec: Optional[str] = None, v: bool = False) -> bool:
|
831
831
|
'''
|
832
832
|
a function to write ascii files
|
833
833
|
'''
|
@@ -846,13 +846,13 @@ def writeTo(filename, file_text, encode_codec = None, v=False) -> bool:
|
|
846
846
|
if v: print("\t> wrote {0}".format(getFileBaseName(filename, extension=True)))
|
847
847
|
return True
|
848
848
|
|
849
|
-
def writeToFile(filename, file_text, encode_codec = None, v=False) -> bool:
|
849
|
+
def writeToFile(filename: str, file_text: Any, encode_codec: Optional[str] = None, v: bool = False) -> bool:
|
850
850
|
return writeTo(filename, file_text, encode_codec, v)
|
851
851
|
|
852
|
-
def writeFile(filename, file_text, encode_codec = None, v=False) -> bool:
|
852
|
+
def writeFile(filename: str, file_text: Any, encode_codec: Optional[str] = None, v: bool = False) -> bool:
|
853
853
|
return writeTo(filename, file_text, encode_codec, v)
|
854
854
|
|
855
|
-
def createPath(pathName, v = False):
|
855
|
+
def createPath(pathName: str, v: bool = False) -> str:
|
856
856
|
'''
|
857
857
|
this function creates a directory if it does not exist
|
858
858
|
pathName: the path to create
|
@@ -871,7 +871,7 @@ def createPath(pathName, v = False):
|
|
871
871
|
return pathName
|
872
872
|
|
873
873
|
|
874
|
-
def renameNetCDFvariable(input_file: str, output_file: str, old_var_name: str, new_var_name: str, v = False) -> None:
|
874
|
+
def renameNetCDFvariable(input_file: str, output_file: str, old_var_name: str, new_var_name: str, v: bool = False) -> None:
|
875
875
|
"""
|
876
876
|
Renames a variable in a NetCDF file using CDO if it exists.
|
877
877
|
If the variable does not exist, the file is copied without modification.
|
@@ -907,7 +907,7 @@ def renameNetCDFvariable(input_file: str, output_file: str, old_var_name: str, n
|
|
907
907
|
print(f"Error: {e.stderr}")
|
908
908
|
|
909
909
|
|
910
|
-
def compressTo7z(input_dir: str, output_file: str, compressionLevel: int = 4, excludeExt: list = None, v: bool = False) -> None:
|
910
|
+
def compressTo7z(input_dir: str, output_file: str, compressionLevel: int = 4, excludeExt: Optional[list] = None, v: bool = False) -> None:
|
911
911
|
"""
|
912
912
|
Compresses the contents of a directory to a .7z archive with maximum compression.
|
913
913
|
|
@@ -1210,8 +1210,8 @@ def ignoreWarnings(ignore:bool = True, v:bool = False) -> None:
|
|
1210
1210
|
return None
|
1211
1211
|
|
1212
1212
|
|
1213
|
-
def createGrid(topLeft: list = None, bottomRight: list = None, resolution: float = None,
|
1214
|
-
inputShape: str = None, crs: str = "EPSG:4326", saveVector: str = None) -> geopandas.GeoDataFrame:
|
1213
|
+
def createGrid(topLeft: Optional[list] = None, bottomRight: Optional[list] = None, resolution: Optional[float] = None,
|
1214
|
+
inputShape: Optional[str] = None, crs: str = "EPSG:4326", saveVector: Optional[str] = None) -> geopandas.GeoDataFrame:
|
1215
1215
|
'''
|
1216
1216
|
This function creates a grid of polygons based on either a shapefile or corner coordinates
|
1217
1217
|
|
@@ -1341,7 +1341,7 @@ def netcdfVariableDimensions(ncFile: str, variable: str) -> dict:
|
|
1341
1341
|
|
1342
1342
|
return bands_info
|
1343
1343
|
|
1344
|
-
def netcdfExportTif(ncFile: str, variable: str, outputFile: Optional[str] = None, band: int = None, v:bool = True) -> gdal.Dataset:
|
1344
|
+
def netcdfExportTif(ncFile: str, variable: str, outputFile: Optional[str] = None, band: Optional[int] = None, v:bool = True) -> gdal.Dataset:
|
1345
1345
|
'''
|
1346
1346
|
Export a variable from a NetCDF file to a GeoTiff file
|
1347
1347
|
ncFile: NetCDF file
|
@@ -1401,8 +1401,8 @@ def netcdfSumMaps(ncFiles:list, variable:str, band:int = 1) -> numpy.ndarray:
|
|
1401
1401
|
def tiffWriteArray(array: numpy.ndarray, outputFile: str,
|
1402
1402
|
geoTransform: tuple = (0, 1, 0, 0, 0, -1),
|
1403
1403
|
projection: str = 'EPSG:4326',
|
1404
|
-
noData:float = None,
|
1405
|
-
v:bool = False) -> gdal.Dataset:
|
1404
|
+
noData: Optional[float] = None,
|
1405
|
+
v: bool = False) -> gdal.Dataset:
|
1406
1406
|
'''
|
1407
1407
|
Write a numpy array to a GeoTIFF file
|
1408
1408
|
array : numpy array to write
|
@@ -1448,7 +1448,7 @@ def copyFile(source:str, destination:str, v:bool = True) -> None:
|
|
1448
1448
|
if v: print(f'> {source} copied to \t - {destination}')
|
1449
1449
|
|
1450
1450
|
|
1451
|
-
def copyDirectory(source:str, destination:str, recursive = True, v:bool = True, filter = []) -> None:
|
1451
|
+
def copyDirectory(source:str, destination:str, recursive: bool = True, v:bool = True, filter: list = []) -> None:
|
1452
1452
|
'''
|
1453
1453
|
Copy a directory from source to destination
|
1454
1454
|
source: source directory
|
@@ -1499,7 +1499,7 @@ def copyFolder(source:str, destination:str, v:bool = True) -> None:
|
|
1499
1499
|
copyDirectory(source, destination, v=v)
|
1500
1500
|
|
1501
1501
|
|
1502
|
-
def convertCoordinates(lon, lat, srcEPSG, dstCRS) -> tuple:
|
1502
|
+
def convertCoordinates(lon: float, lat: float, srcEPSG: str, dstCRS: str) -> tuple:
|
1503
1503
|
"""
|
1504
1504
|
this function converts coordinates from one CRS to another
|
1505
1505
|
|
@@ -1516,7 +1516,7 @@ def convertCoordinates(lon, lat, srcEPSG, dstCRS) -> tuple:
|
|
1516
1516
|
return (new_lon, new_lat)
|
1517
1517
|
|
1518
1518
|
|
1519
|
-
def extractRasterValue(rasterPath: str, lat: float, lon: float, coordProj: str = 'EPSG:4326') -> float:
|
1519
|
+
def extractRasterValue(rasterPath: str, lat: float, lon: float, coordProj: str = 'EPSG:4326') -> Optional[float]:
|
1520
1520
|
"""
|
1521
1521
|
Extract raster value at given coordinates.
|
1522
1522
|
|
@@ -1561,7 +1561,7 @@ def extractRasterValue(rasterPath: str, lat: float, lon: float, coordProj: str =
|
|
1561
1561
|
return float(value)
|
1562
1562
|
|
1563
1563
|
|
1564
|
-
def getRasterValue(rasterPath: str, lat: float, lon: float, coordProj: str = 'EPSG:4326') -> float:
|
1564
|
+
def getRasterValue(rasterPath: str, lat: float, lon: float, coordProj: str = 'EPSG:4326') -> Optional[float]:
|
1565
1565
|
'''
|
1566
1566
|
this function is a wrapper for extractRasterValue
|
1567
1567
|
'''
|
@@ -1588,9 +1588,9 @@ def showProgress(count: int, end: int, message: str, barLength: int = 100) -> No
|
|
1588
1588
|
percentStr = f'{percent:03.1f}'
|
1589
1589
|
filled = int(barLength * count / end)
|
1590
1590
|
bar = '█' * filled + '░' * (barLength - filled)
|
1591
|
-
print(f'\r{bar} {
|
1591
|
+
print(f'\r{message} |{bar}| {percent}% [{count}/{end}]', end='', flush=True)
|
1592
1592
|
if count == end:
|
1593
|
-
print(f'\r{bar} {
|
1593
|
+
print(f'\r{message} |{bar}| {percent}% [{count}/{end}] ', end='', flush=True)
|
1594
1594
|
print()
|
1595
1595
|
|
1596
1596
|
|
@@ -1621,7 +1621,7 @@ def dualProgress(primaryCount: int, primaryEnd: int,
|
|
1621
1621
|
print(f'\r{bar} {formattedPrimaryPercent.rjust(6)}% | {formattedSecondaryPercent.rjust(6)}% ', end='', flush=True)
|
1622
1622
|
|
1623
1623
|
|
1624
|
-
def listAllFiles(folder, extension="*"):
|
1624
|
+
def listAllFiles(folder: str, extension: str = "*") -> list:
|
1625
1625
|
list_of_files = []
|
1626
1626
|
# Getting the current work directory (cwd)
|
1627
1627
|
thisdir = folder
|
@@ -1643,7 +1643,7 @@ def listAllFiles(folder, extension="*"):
|
|
1643
1643
|
return list_of_files
|
1644
1644
|
|
1645
1645
|
|
1646
|
-
def clipFeatures(inputFeaturePath:str, boundaryFeature:str, outputFeature:str, keepOnlyTypes = None, v = False) -> geopandas.GeoDataFrame:
|
1646
|
+
def clipFeatures(inputFeaturePath:str, boundaryFeature:str, outputFeature:str, keepOnlyTypes: Optional[list] = None, v: bool = False) -> geopandas.GeoDataFrame:
|
1647
1647
|
'''
|
1648
1648
|
keepOnlyTypes = ['MultiPolygon', 'Polygon', 'Point', etc]
|
1649
1649
|
|
@@ -2023,7 +2023,7 @@ def getTimeseriesStats(data:pandas.DataFrame, observed:Optional[str] = None, sim
|
|
2023
2023
|
|
2024
2024
|
return stats
|
2025
2025
|
|
2026
|
-
def readSWATPlusOutputs(filePath: str, column: Optional[str] = None, unit: Optional[int] = None, gis_id: Optional[int] = None, name: Optional[str] = None):
|
2026
|
+
def readSWATPlusOutputs(filePath: str, column: Optional[str] = None, unit: Optional[int] = None, gis_id: Optional[int] = None, name: Optional[str] = None) -> Optional[pandas.DataFrame]:
|
2027
2027
|
'''
|
2028
2028
|
Read SWAT+ output files and return a pandas DataFrame with proper date handling
|
2029
2029
|
and optional filtering capabilities.
|
@@ -1,11 +1,11 @@
|
|
1
1
|
ccfx/__init__.py,sha256=UK62VcGS84SJyGVg1bK4FltZj7OkpdoyhoFWeXcKsX0,144
|
2
|
-
ccfx/ccfx.py,sha256=
|
2
|
+
ccfx/ccfx.py,sha256=0i4XemdSzj3HY-kfSZ26qeDjnNyyNpIKlp0tvcE6vP4,76939
|
3
3
|
ccfx/excel.py,sha256=vm_cm4huKKx4_Nstr5neJzhBLmoZjg8qxjzz4hcF5hg,4754
|
4
4
|
ccfx/mssqlConnection.py,sha256=C3HxzgZHmHy_de9EbMaXzR8NrkJxwHc8a00qzxQu_gs,8984
|
5
5
|
ccfx/sqliteConnection.py,sha256=pOT9BBEAcm2kmoS0yBkUi4m9srQVe62J4xG5bnddvis,16207
|
6
6
|
ccfx/word.py,sha256=AGa64jX5Zl5qotZh5L0QmrsjTnktIBhmj_ByRKZ88vw,3061
|
7
|
-
ccfx-1.0.
|
8
|
-
ccfx-1.0.
|
9
|
-
ccfx-1.0.
|
10
|
-
ccfx-1.0.
|
11
|
-
ccfx-1.0.
|
7
|
+
ccfx-1.0.8.dist-info/licenses/LICENSE,sha256=EuxaawJg_OOCLfikkCGgfXPZmxR-x_5PH7_2e9M-3eA,1099
|
8
|
+
ccfx-1.0.8.dist-info/METADATA,sha256=5OweW94ia3GPVjjHmZd8nzklqRtX5oC9uS4Tokr375E,11282
|
9
|
+
ccfx-1.0.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
10
|
+
ccfx-1.0.8.dist-info/top_level.txt,sha256=_cSvSA1WX2K8TgoV3iBJUdUZZqMKJbOPLNnKLYSLHaw,5
|
11
|
+
ccfx-1.0.8.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|