topo_map_processor 0.1.10__tar.gz → 0.1.12__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.
Files changed (22) hide show
  1. {topo_map_processor-0.1.10 → topo_map_processor-0.1.12}/PKG-INFO +9 -45
  2. {topo_map_processor-0.1.10 → topo_map_processor-0.1.12}/README.md +7 -43
  3. {topo_map_processor-0.1.10 → topo_map_processor-0.1.12}/pyproject.toml +1 -9
  4. {topo_map_processor-0.1.10 → topo_map_processor-0.1.12}/topo_map_processor/_version.py +16 -3
  5. {topo_map_processor-0.1.10 → topo_map_processor-0.1.12}/topo_map_processor/processor.py +9 -4
  6. {topo_map_processor-0.1.10 → topo_map_processor-0.1.12}/topo_map_processor/tools/retile.py +7 -12
  7. {topo_map_processor-0.1.10 → topo_map_processor-0.1.12}/topo_map_processor/tools/retile_e2e.py +2 -1
  8. {topo_map_processor-0.1.10 → topo_map_processor-0.1.12}/topo_map_processor/tools/tile.py +18 -1
  9. topo_map_processor-0.1.12/topo_map_processor/tools/utils.py +31 -0
  10. topo_map_processor-0.1.10/topo_map_processor/bash_scripts/generate_lists.sh +0 -33
  11. topo_map_processor-0.1.10/topo_map_processor/bash_scripts/upload_to_release.sh +0 -148
  12. topo_map_processor-0.1.10/topo_map_processor/tools/__init__.py +0 -0
  13. topo_map_processor-0.1.10/topo_map_processor/tools/download_mosaic.py +0 -375
  14. topo_map_processor-0.1.10/topo_map_processor/tools/execute_bash.py +0 -59
  15. topo_map_processor-0.1.10/topo_map_processor/tools/partition.py +0 -604
  16. topo_map_processor-0.1.10/topo_map_processor/tools/partition_basic.py +0 -514
  17. topo_map_processor-0.1.10/topo_map_processor/tools/tile_sources.py +0 -470
  18. {topo_map_processor-0.1.10 → topo_map_processor-0.1.12}/.gitignore +0 -0
  19. {topo_map_processor-0.1.10 → topo_map_processor-0.1.12}/LICENSE +0 -0
  20. {topo_map_processor-0.1.10 → topo_map_processor-0.1.12}/topo_map_processor/__init__.py +0 -0
  21. {topo_map_processor-0.1.10/topo_map_processor/bash_scripts → topo_map_processor-0.1.12/topo_map_processor/tools}/__init__.py +0 -0
  22. {topo_map_processor-0.1.10 → topo_map_processor-0.1.12}/topo_map_processor/tools/collect_bounds.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: topo_map_processor
3
- Version: 0.1.10
3
+ Version: 0.1.12
4
4
  Summary: Library for processing topographic maps
5
5
  Project-URL: homepage, https://github.com/ramSeraph/topo_map_processor
6
6
  Project-URL: repository, https://github.com/ramSeraph/topo_map_processor.git
@@ -32,7 +32,7 @@ License: This is free and unencumbered software released into the public domain.
32
32
  License-File: LICENSE
33
33
  Requires-Python: >=3.12
34
34
  Requires-Dist: mercantile>=1.2.1
35
- Requires-Dist: pmtiles==3.4.1
35
+ Requires-Dist: pmtiles-mosaic>=0.1.0
36
36
  Requires-Dist: requests>=2.32.4
37
37
  Requires-Dist: shapely>=2.1.1
38
38
  Provides-Extra: easyocr
@@ -184,7 +184,13 @@ The `get_intersection_point` method is the most critical part to customize for a
184
184
  3. Identifying the point closest to the expected corner position, while also matching an expected angle and distance from an anchor point.
185
185
 
186
186
  ![corner for 4way intersection point](/samples/corner3.png)
187
- - **`get_4way_intersection_point`**: This is a more robust version for crosshair-style corners. It specifically looks for intersections where four lines meet, making it less prone to errors from stray lines in the map collar.
187
+ - **`get_4way_intersection_point`**: This is a more robust version for crosshair-style corners. It works by:
188
+ 1. Isolating lines based on their color.
189
+ 2. Optionally removing any text that might interfere with line detection.
190
+ 3. Ignoring the edges of the corner image patch to avoid spurious intersections with the border.
191
+ 4. Detecting all horizontal and vertical lines and finding their intersection points.
192
+ 5. Validating each intersection by checking for the presence of lines extending in all four directions (up, down, left, right) from the intersection point. This ensures it's a true 4-way "crosshair" intersection.
193
+ 6. It is designed to be very specific and will fail if it doesn't find exactly one 4-way intersection.
188
194
 
189
195
  ![corner for biggest contour corner](/samples/corner2.png)
190
196
  - **`get_biggest_contour_corner`**: This strategy is designed for corners that are marked by a solid shape or a filled area (e.g., a colored square or circle). It works by:
@@ -208,15 +214,6 @@ Similar to corner detection, the `locate_grid_lines` method can be implemented u
208
214
 
209
215
  - **`get_grid_line_corrections`**: This method serves as a refinement step to improve accuracy. While the transformer provides a very close estimate, this function can correct for minor printing or scanning inaccuracies. For each projected grid intersection, it searches a small area in the actual image for the *true* intersection of printed lines, adjusting the point to match the visual data. This ensures that the lines targeted for removal are precisely the ones printed on the map.
210
216
 
211
- ### Tile Sources
212
-
213
- The `topo_map_processor.tools.tile_sources` module provides classes for reading tiles from different sources.
214
-
215
- - `DiskTilesSource`: Reads tiles from a directory on the local disk.
216
- - `MBTilesSource`: Reads tiles from an MBTiles file.
217
- - `PMTilesSource`: Reads tiles from a PMTiles file.
218
- - `StackedTileSource`: Combines multiple tile sources (Disk, MBTiles, PMTiles) into a single logical source, allowing for seamless access across different storage types.
219
-
220
217
  ### Command-Line Tools
221
218
 
222
219
  This project provides several command-line tools to work with topographic maps. These tools are dynamically loaded, and you can get the most up-to-date usage information by running the tool with the `--help` flag.
@@ -233,39 +230,6 @@ collect-bounds --bounds-dir <directory> --output-file <file> [--preexisting-file
233
230
  - `--output-file`: Output GeoJSON file path. (Required)
234
231
  - `--preexisting-file`: Pre existing GeoJSON file path. (Optional)
235
232
 
236
- #### `download-mosaic`
237
-
238
- Downloads a PMTiles mosaic and converts it to a single MBTiles or PMTiles file. A mosaic is a JSON file that lists multiple PMTiles files.
239
-
240
- ```bash
241
- download-mosaic --mosaic-url <url> [--output-file <file>] [--archive-type <type>] [--request-timeout-secs <seconds>] [--num-http-retries <retries>]
242
- ```
243
-
244
- - `--mosaic-url`, `-u`: URL of the mosaic JSON file. (Required)
245
- - `--output-file`, `-o`: Output MBTiles/PMTiles file name. The format is inferred from the extension (`.mbtiles` or `.pmtiles`). If not specified, it is derived from the mosaic URL. (Optional)
246
- - `--archive-type`: Type of archive to create (`mbtiles` or `pmtiles`). Required if `--output-file` is not provided or its extension is not recognized.
247
- - `--request-timeout-secs`, `-t`: Timeout for HTTP requests in seconds (default: 60).
248
- - `--num-http-retries`, `-r`: Number of retries for HTTP requests (default: 3).
249
-
250
- #### `partition`
251
-
252
- Partitions a large set of tiles into smaller PMTiles files. This is useful for managing large datasets, for example, to stay within file size limits for services like GitHub Releases. It creates a mosaic file if the output is partitioned into multiple files.
253
-
254
- ```bash
255
- partition --from-source <source> [--from-source <source> ...] --to-pmtiles <file> [--size-limit <limit>]
256
- ```
257
-
258
- - `--from-source`: Path to a source file or directory. Can be repeated. Supported sources:
259
- - `.mbtiles` file: e.g., `path/to/file.mbtiles`
260
- - `.pmtiles` file (supports glob patterns): e.g., `path/to/*.pmtiles`
261
- - Directory containing tiles: e.g., `path/to/tiles_dir`
262
- - `--to-pmtiles`: Output PMTiles file. The prefix for partitioned files will be derived from this argument.
263
- - `--size-limit`: Maximum size of each partition. Can be a number in bytes (e.g., `100000000`), or with units (e.g., `100M`, `2G`), or a preset:
264
- - `github_release`: 2GB limit
265
- - `github_file`: 100MB limit
266
- - `cloudflare_object`: 512MB limit
267
- The overhead (delta) is scaled proportionally based on the `github_release` preset (2GB with 5MB overhead). Defaults to `github_release`.
268
-
269
233
  #### `retile`
270
234
 
271
235
  Retiles a specific list of sheets (GeoTIFFs) and updates the corresponding tiles in an existing tile set. It can determine which other sheets are affected and need to be pulled in to correctly retile the area.
@@ -135,7 +135,13 @@ The `get_intersection_point` method is the most critical part to customize for a
135
135
  3. Identifying the point closest to the expected corner position, while also matching an expected angle and distance from an anchor point.
136
136
 
137
137
  ![corner for 4way intersection point](/samples/corner3.png)
138
- - **`get_4way_intersection_point`**: This is a more robust version for crosshair-style corners. It specifically looks for intersections where four lines meet, making it less prone to errors from stray lines in the map collar.
138
+ - **`get_4way_intersection_point`**: This is a more robust version for crosshair-style corners. It works by:
139
+ 1. Isolating lines based on their color.
140
+ 2. Optionally removing any text that might interfere with line detection.
141
+ 3. Ignoring the edges of the corner image patch to avoid spurious intersections with the border.
142
+ 4. Detecting all horizontal and vertical lines and finding their intersection points.
143
+ 5. Validating each intersection by checking for the presence of lines extending in all four directions (up, down, left, right) from the intersection point. This ensures it's a true 4-way "crosshair" intersection.
144
+ 6. It is designed to be very specific and will fail if it doesn't find exactly one 4-way intersection.
139
145
 
140
146
  ![corner for biggest contour corner](/samples/corner2.png)
141
147
  - **`get_biggest_contour_corner`**: This strategy is designed for corners that are marked by a solid shape or a filled area (e.g., a colored square or circle). It works by:
@@ -159,15 +165,6 @@ Similar to corner detection, the `locate_grid_lines` method can be implemented u
159
165
 
160
166
  - **`get_grid_line_corrections`**: This method serves as a refinement step to improve accuracy. While the transformer provides a very close estimate, this function can correct for minor printing or scanning inaccuracies. For each projected grid intersection, it searches a small area in the actual image for the *true* intersection of printed lines, adjusting the point to match the visual data. This ensures that the lines targeted for removal are precisely the ones printed on the map.
161
167
 
162
- ### Tile Sources
163
-
164
- The `topo_map_processor.tools.tile_sources` module provides classes for reading tiles from different sources.
165
-
166
- - `DiskTilesSource`: Reads tiles from a directory on the local disk.
167
- - `MBTilesSource`: Reads tiles from an MBTiles file.
168
- - `PMTilesSource`: Reads tiles from a PMTiles file.
169
- - `StackedTileSource`: Combines multiple tile sources (Disk, MBTiles, PMTiles) into a single logical source, allowing for seamless access across different storage types.
170
-
171
168
  ### Command-Line Tools
172
169
 
173
170
  This project provides several command-line tools to work with topographic maps. These tools are dynamically loaded, and you can get the most up-to-date usage information by running the tool with the `--help` flag.
@@ -184,39 +181,6 @@ collect-bounds --bounds-dir <directory> --output-file <file> [--preexisting-file
184
181
  - `--output-file`: Output GeoJSON file path. (Required)
185
182
  - `--preexisting-file`: Pre existing GeoJSON file path. (Optional)
186
183
 
187
- #### `download-mosaic`
188
-
189
- Downloads a PMTiles mosaic and converts it to a single MBTiles or PMTiles file. A mosaic is a JSON file that lists multiple PMTiles files.
190
-
191
- ```bash
192
- download-mosaic --mosaic-url <url> [--output-file <file>] [--archive-type <type>] [--request-timeout-secs <seconds>] [--num-http-retries <retries>]
193
- ```
194
-
195
- - `--mosaic-url`, `-u`: URL of the mosaic JSON file. (Required)
196
- - `--output-file`, `-o`: Output MBTiles/PMTiles file name. The format is inferred from the extension (`.mbtiles` or `.pmtiles`). If not specified, it is derived from the mosaic URL. (Optional)
197
- - `--archive-type`: Type of archive to create (`mbtiles` or `pmtiles`). Required if `--output-file` is not provided or its extension is not recognized.
198
- - `--request-timeout-secs`, `-t`: Timeout for HTTP requests in seconds (default: 60).
199
- - `--num-http-retries`, `-r`: Number of retries for HTTP requests (default: 3).
200
-
201
- #### `partition`
202
-
203
- Partitions a large set of tiles into smaller PMTiles files. This is useful for managing large datasets, for example, to stay within file size limits for services like GitHub Releases. It creates a mosaic file if the output is partitioned into multiple files.
204
-
205
- ```bash
206
- partition --from-source <source> [--from-source <source> ...] --to-pmtiles <file> [--size-limit <limit>]
207
- ```
208
-
209
- - `--from-source`: Path to a source file or directory. Can be repeated. Supported sources:
210
- - `.mbtiles` file: e.g., `path/to/file.mbtiles`
211
- - `.pmtiles` file (supports glob patterns): e.g., `path/to/*.pmtiles`
212
- - Directory containing tiles: e.g., `path/to/tiles_dir`
213
- - `--to-pmtiles`: Output PMTiles file. The prefix for partitioned files will be derived from this argument.
214
- - `--size-limit`: Maximum size of each partition. Can be a number in bytes (e.g., `100000000`), or with units (e.g., `100M`, `2G`), or a preset:
215
- - `github_release`: 2GB limit
216
- - `github_file`: 100MB limit
217
- - `cloudflare_object`: 512MB limit
218
- The overhead (delta) is scaled proportionally based on the `github_release` preset (2GB with 5MB overhead). Defaults to `github_release`.
219
-
220
184
  #### `retile`
221
185
 
222
186
  Retiles a specific list of sheets (GeoTIFFs) and updates the corresponding tiles in an existing tile set. It can determine which other sheets are affected and need to be pulled in to correctly retile the area.
@@ -9,7 +9,7 @@ authors = [
9
9
  ]
10
10
  dependencies = [
11
11
  "mercantile>=1.2.1",
12
- "pmtiles==3.4.1",
12
+ "pmtiles-mosaic>=0.1.0",
13
13
  "requests>=2.32.4",
14
14
  "shapely>=2.1.1",
15
15
  ]
@@ -38,16 +38,10 @@ repository = "https://github.com/ramSeraph/topo_map_processor.git"
38
38
 
39
39
  [project.scripts]
40
40
  collect-bounds = "topo_map_processor.tools.collect_bounds:cli"
41
- download-mosaic = "topo_map_processor.tools.download_mosaic:cli"
42
- partition = "topo_map_processor.tools.partition:cli"
43
- partition-basic = "topo_map_processor.tools.partition_basic:cli"
44
41
  retile = "topo_map_processor.tools.retile:cli"
45
42
  tile = "topo_map_processor.tools.tile:cli"
46
- generate-lists = "topo_map_processor.tools.execute_bash:generate_lists"
47
- upload-to-release = "topo_map_processor.tools.execute_bash:upload_to_release"
48
43
  retile-e2e = "topo_map_processor.tools.retile_e2e:cli"
49
44
 
50
-
51
45
  [build-system]
52
46
  requires = [
53
47
  "hatchling",
@@ -64,12 +58,10 @@ version-file = "topo_map_processor/_version.py"
64
58
  [tool.hatch.build.targets.sdist]
65
59
  include = [
66
60
  "topo_map_processor",
67
- "topo_map_processor/bash_scripts/**",
68
61
  ]
69
62
 
70
63
  [tool.hatch.build.targets.wheel]
71
64
  include = [
72
65
  "topo_map_processor",
73
- "topo_map_processor/bash_scripts/**",
74
66
  ]
75
67
 
@@ -1,7 +1,14 @@
1
1
  # file generated by setuptools-scm
2
2
  # don't change, don't track in version control
3
3
 
4
- __all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
4
+ __all__ = [
5
+ "__version__",
6
+ "__version_tuple__",
7
+ "version",
8
+ "version_tuple",
9
+ "__commit_id__",
10
+ "commit_id",
11
+ ]
5
12
 
6
13
  TYPE_CHECKING = False
7
14
  if TYPE_CHECKING:
@@ -9,13 +16,19 @@ if TYPE_CHECKING:
9
16
  from typing import Union
10
17
 
11
18
  VERSION_TUPLE = Tuple[Union[int, str], ...]
19
+ COMMIT_ID = Union[str, None]
12
20
  else:
13
21
  VERSION_TUPLE = object
22
+ COMMIT_ID = object
14
23
 
15
24
  version: str
16
25
  __version__: str
17
26
  __version_tuple__: VERSION_TUPLE
18
27
  version_tuple: VERSION_TUPLE
28
+ commit_id: COMMIT_ID
29
+ __commit_id__: COMMIT_ID
19
30
 
20
- __version__ = version = '0.1.10'
21
- __version_tuple__ = version_tuple = (0, 1, 10)
31
+ __version__ = version = '0.1.12'
32
+ __version_tuple__ = version_tuple = (0, 1, 12)
33
+
34
+ __commit_id__ = commit_id = None
@@ -1074,12 +1074,16 @@ class TopoMapProcessor:
1074
1074
 
1075
1075
  return ip
1076
1076
 
1077
- def get_4way_intersection_point(self, img, line_color,
1077
+ def get_4way_intersection_point(self, img, line_color, remove_text,
1078
1078
  find_line_scale, find_line_iter,
1079
- cwidth, ext_thresh):
1079
+ cwidth, ext_thresh, direction,
1080
+ remove_corner_edges_ratio):
1080
1081
  img_mask = self.get_color_mask(img, line_color)
1081
1082
 
1082
- self.remove_text(img_mask)
1083
+ if remove_text:
1084
+ self.remove_text(img_mask)
1085
+
1086
+ self.remove_corner_edges(img_mask, direction, remove_corner_edges_ratio)
1083
1087
 
1084
1088
  h, w = img_mask.shape[:2]
1085
1089
  self.show_image(img_mask)
@@ -1106,7 +1110,8 @@ class TopoMapProcessor:
1106
1110
  if len(four_corner_ips) > 1:
1107
1111
  continue
1108
1112
 
1109
- self.show_points(four_corner_ips, img_mask, [0, 255, 0])
1113
+ self.show_points(four_corner_ips, img_mask, [0, 255, 0])
1114
+
1110
1115
  if len(four_corner_ips) > 1:
1111
1116
  raise Exception(f'multiple intersection points found - {len(four_corner_ips)}')
1112
1117
 
@@ -1,16 +1,7 @@
1
- # /// script
2
- # requires-python = ">=3.12"
3
- # dependencies = [
4
- # "mercantile",
5
- # "pmtiles",
6
- # "shapely",
7
- # ]
8
- # ///
9
1
 
10
2
  import os
11
3
  import re
12
4
  import sys
13
- import glob
14
5
  import json
15
6
  import argparse
16
7
 
@@ -33,7 +24,9 @@ from osgeo_utils.gdal2tiles import (
33
24
  DividedCache,
34
25
  )
35
26
 
36
- from .tile_sources import create_source_from_paths, MissingTileError
27
+ from pmtiles_mosaic.tile_sources import create_source_from_paths, MissingTileError
28
+
29
+ from .utils import relax_open_file_limit
37
30
 
38
31
  def run_external(cmd):
39
32
  print(f'running cmd - {cmd}')
@@ -309,8 +302,8 @@ class Tiler:
309
302
  prev_affected_tiles = curr_affected_tiles
310
303
 
311
304
  metadata = self.orig_tile_source.get_metadata()
312
- metadata['minzoom'] = self.orig_tile_source.min_zoom
313
- metadata['maxzoom'] = self.orig_tile_source.max_zoom
305
+ metadata['minzoom'] = min_zoom
306
+ metadata['maxzoom'] = max_zoom
314
307
  self.disk_handler.save_metadata(metadata)
315
308
  print('All Done!!!')
316
309
 
@@ -454,6 +447,8 @@ def retile_main(args):
454
447
  if tile_extension == 'jpg':
455
448
  tile_extension = 'jpeg'
456
449
 
450
+ relax_open_file_limit()
451
+
457
452
  os.environ['GDAL_CACHEMAX'] = '2048'
458
453
  os.environ['GDAL_MAX_DATASET_POOL_SIZE'] = '5000'
459
454
  os.environ['GDAL_DISABLE_READDIR_ON_OPEN'] = 'TRUE'
@@ -8,7 +8,8 @@ import sys
8
8
  from pathlib import Path
9
9
  from multiprocessing import set_start_method
10
10
 
11
- from .partition import partition_main
11
+ from pmtiles_mosaic.partition import partition_main
12
+
12
13
  from .retile import retile_main
13
14
 
14
15
 
@@ -9,9 +9,12 @@ import subprocess
9
9
 
10
10
  from pathlib import Path
11
11
  from multiprocessing import set_start_method, cpu_count
12
+ from pprint import pprint
12
13
 
13
14
  from osgeo_utils.gdal2tiles import submain as gdal2tiles_main
14
15
 
16
+ from .utils import relax_open_file_limit
17
+
15
18
  SUPPORTED_FORMATS = ['webp', 'jpeg', 'png']
16
19
 
17
20
  def run_external(cmd):
@@ -56,6 +59,14 @@ def get_tiler_cmd_params(tile_extension, tile_quality):
56
59
 
57
60
  raise ValueError(f'Unsupported tile extension: {tile_extension}, {SUPPORTED_FORMATS=}')
58
61
 
62
+ def get_format(tile_extension):
63
+ if tile_extension == 'webp':
64
+ return 'webp'
65
+ if tile_extension == 'jpeg':
66
+ return 'jpeg'
67
+ if tile_extension == 'png':
68
+ return 'png'
69
+ raise ValueError(f'Unsupported tile extension: {tile_extension}, {SUPPORTED_FORMATS=}')
59
70
 
60
71
 
61
72
  def cli():
@@ -86,6 +97,7 @@ def cli():
86
97
  else:
87
98
  attribution_text = args.attribution
88
99
 
100
+ relax_open_file_limit()
89
101
 
90
102
  tiles_dir = Path(args.tiles_dir)
91
103
  tiles_dir.mkdir(parents=True, exist_ok=True)
@@ -131,10 +143,12 @@ def cli():
131
143
 
132
144
  metadata_file = tiles_dir / 'tiles.json'
133
145
 
146
+ fmt = get_format(args.tile_extension)
147
+
134
148
  # it is not really a proper tilejson spec.. it is the basic things needed to populate a pmtiles metadata
135
149
  metadata = {
136
150
  'type': 'baselayer',
137
- 'format': format,
151
+ 'format': fmt,
138
152
  'attribution': attribution_text,
139
153
  'description': args.description,
140
154
  'name': args.name,
@@ -142,6 +156,9 @@ def cli():
142
156
  'maxzoom': args.max_zoom,
143
157
  'minzoom': args.min_zoom,
144
158
  }
159
+
160
+ print(f'writing metadata to {metadata_file}')
161
+ pprint(metadata)
145
162
  metadata_file.write_text(json.dumps(metadata, indent=2))
146
163
 
147
164
  print('All Done!!')
@@ -0,0 +1,31 @@
1
+
2
+ import resource
3
+
4
+
5
+ def relax_open_file_limit():
6
+
7
+ # Get the current soft and hard limits for open files
8
+ current_soft, current_hard = resource.getrlimit(resource.RLIMIT_NOFILE)
9
+ print(f"Current open file limits: Soft={current_soft}, Hard={current_hard}")
10
+
11
+ # Set new soft and hard limits for open files
12
+ new_soft = resource.RLIM_INFINITY # Set to unlimited
13
+ new_hard = resource.RLIM_INFINITY # Set to unlimited
14
+
15
+ try:
16
+ resource.setrlimit(resource.RLIMIT_NOFILE, (new_soft, new_hard))
17
+ print(f"New open file limits set: Soft={new_soft}, Hard={new_hard}")
18
+ except Exception as e:
19
+ print(f"Error setting resource limit to unlimited: {e}")
20
+ print('Increasing soft limit to match the hard limit instead')
21
+ new_soft = current_hard
22
+ new_hard = current_hard
23
+ try:
24
+ resource.setrlimit(resource.RLIMIT_NOFILE, (new_soft, new_hard))
25
+ print(f"New open file limits set: Soft={new_soft}, Hard={new_hard}")
26
+ except Exception as e:
27
+ print(f"Error setting soft resource limit to match hard limit: {e}")
28
+
29
+ # Verify the new limits
30
+ updated_soft, updated_hard = resource.getrlimit(resource.RLIMIT_NOFILE)
31
+ print(f"Verified open file limits: Soft={updated_soft}, Hard={updated_hard}")
@@ -1,33 +0,0 @@
1
- #!/bin/bash
2
-
3
- prog_name=${COMMNAND_NAME:-$(basename "$0")}
4
- release_base=$1
5
- ext=$2
6
-
7
- if [ -z "$release_base" ] || [ -z "$ext" ]; then
8
- echo "Usage: $prog_name <release_base> <extension>"
9
- exit 1
10
- fi
11
-
12
- #owner=$(gh repo view --json owner -q .owner.login)
13
- #name=$(gh repo view --json name -q .name)
14
- #repo="$owner/$name"
15
-
16
- echo "getting file list"
17
- echo "name,size,url" > listing_files.csv
18
-
19
- # Get all releases, then filter for the base release and any -extra releases.
20
- releases_to_process=$(gh release list --repo "$repo" --json tagName -q '.[].tagName' | grep -E "^${release_base}(-extra[0-9]+)?$")
21
- releases_to_process=$(echo "$releases_to_process" | sort -u)
22
-
23
- echo "Will process releases: $releases_to_process"
24
-
25
- for release in $releases_to_process; do
26
- echo "Processing release: $release"
27
- gh release view "$release" --json assets -q ".assets[] | select(.name | endswith(\"$ext\")) | \"\\(.name),\\(.size),\\(.url)\"" >> listing_files.csv
28
- done
29
-
30
- gh release upload "$release_base" listing_files.csv --clobber
31
-
32
- rm listing_files.csv
33
-
@@ -1,148 +0,0 @@
1
- #!/bin/bash
2
-
3
- # A script to upload files from a folder to a GitHub release,
4
- # skipping files that already exist in the release.
5
- # If the fourth argument is 'yes', it will overwrite existing assets.
6
-
7
- set -e
8
- set -o pipefail
9
-
10
- # --- Configuration ---
11
- # TAG: The git tag of the release to upload to.
12
- # FOLDER: The local folder containing the files to upload.
13
- # OVERWRITE: Optional. Set to 'yes' to allow overwriting existing assets.
14
- prog_name=${COMMNAND_NAME:-$(basename "$0")}
15
-
16
- if [ "$#" -lt 3 ] || [ "$#" -gt 4 ]; then
17
- echo "Usage: $prog_name <tag> <folder> <extension_without_the_leading_dot> [yes_to_overwrite]"
18
- exit 1
19
- fi
20
-
21
- TAG="$1"
22
- FOLDER="$2"
23
- EXT="$3"
24
- OVERWRITE_FLAG=${4:-no}
25
-
26
- # --- Pre-flight Checks ---
27
-
28
- # Check if gh is installed
29
- if ! command -v gh &> /dev/null; then
30
- echo "Error: gh command-line tool is not installed. Please install it to continue."
31
- exit 1
32
- fi
33
-
34
- if [ -z "$TAG" ]; then
35
- echo "Error: Release tag is not specified."
36
- exit 1
37
- fi
38
-
39
- if [ ! -d "$FOLDER" ]; then
40
- echo "Error: Folder '$FOLDER' not found."
41
- exit 1
42
- fi
43
-
44
- if [ -z "$EXT" ]; then
45
- echo "Error: Extension '$EXT' is not specified."
46
- exit 1
47
- fi
48
-
49
- ALLOW_OVERWRITE=0
50
- if [ "$OVERWRITE_FLAG" == "yes" ]; then
51
- ALLOW_OVERWRITE=1
52
- echo "Overwrite flag is set. Existing assets will be overwritten."
53
- fi
54
-
55
- # --- Main Logic ---
56
-
57
- echo "Fetching existing assets for releases matching pattern '${TAG}(-extra[0-9]+)?'..."
58
-
59
- # Get all releases, then filter for the base release and any -extra releases, and sort them
60
- RELEASES_TO_PROCESS=$(gh release list --json tagName -q '.[].tagName' | grep -E "^${TAG}(-extra[0-9]+)?$" | sort -V)
61
-
62
- if [ -z "$RELEASES_TO_PROCESS" ]; then
63
- echo "Error: No releases found matching pattern '${TAG}(-extra[0-9]+)?'." >&2
64
- exit 1
65
- fi
66
-
67
- echo "Found releases: $RELEASES_TO_PROCESS"
68
-
69
- # Store assets with their release tags. Format: "asset_name release_tag"
70
- EXISTING_ASSETS_WITH_RELEASES=""
71
- for release in $RELEASES_TO_PROCESS; do
72
- echo "Fetching assets from release: $release"
73
- assets=$(gh release view "$release" --json assets -q '.assets[].name' 2>/dev/null || echo "")
74
- if [ -n "$assets" ]; then
75
- while IFS= read -r asset_name; do
76
- if [ -n "$asset_name" ]; then
77
- EXISTING_ASSETS_WITH_RELEASES="${EXISTING_ASSETS_WITH_RELEASES}${asset_name} ${release}"$'
78
- '
79
- fi
80
- done <<< "$assets"
81
- fi
82
- done
83
-
84
- # Determine available releases and their current asset counts
85
- AVAILABLE_RELEASES=()
86
- AVAILABLE_ASSET_COUNTS=()
87
- for release in $RELEASES_TO_PROCESS; do
88
- count=$(gh release view "$release" --json assets -q '.assets | length' 2>/dev/null || echo "0")
89
-
90
- MAX_ASSETS=998
91
- if [ "$release" == "$TAG" ]; then
92
- MAX_ASSETS=988
93
- fi
94
-
95
- if [ "$count" -lt "$MAX_ASSETS" ]; then
96
- AVAILABLE_RELEASES+=("$release")
97
- AVAILABLE_ASSET_COUNTS+=("$count")
98
- fi
99
- done
100
-
101
- echo "Starting upload process from folder '$FOLDER'..."
102
-
103
- # Find all files in the folder that are not yet in any release and loop through them.
104
- find "${FOLDER}" -type f | grep "^.*\.${EXT}$" | while read -r FILE_PATH; do
105
- FILENAME=$(basename "$FILE_PATH")
106
- echo "Processing file: $FILENAME"
107
-
108
- set +o pipefail
109
- RELEASE_FOR_ASSET=$(echo -n "$EXISTING_ASSETS_WITH_RELEASES" | grep "^${FILENAME} " | head -n 1 | awk '{print $2}')
110
- set -o pipefail
111
-
112
- if [ -n "$RELEASE_FOR_ASSET" ]; then
113
- # Asset exists
114
- if [ "$ALLOW_OVERWRITE" -eq 1 ]; then
115
- echo " -> Overwriting '$FILENAME' in release '$RELEASE_FOR_ASSET'..."
116
- gh release upload "$RELEASE_FOR_ASSET" "$FILE_PATH" --clobber
117
- else
118
- echo " -> Skipping '$FILENAME', it already exists in release '$RELEASE_FOR_ASSET'."
119
- fi
120
- continue
121
- fi
122
-
123
- # Find a release to upload to for a new asset
124
- if [ ${#AVAILABLE_RELEASES[@]} -eq 0 ]; then
125
- echo "Error: All existing releases are full. No space to upload '$FILENAME'." >&2
126
- exit 1
127
- fi
128
-
129
- UPLOAD_TARGET=${AVAILABLE_RELEASES[0]}
130
-
131
- echo " -> Uploading '$FILENAME' to '$UPLOAD_TARGET'..."
132
- gh release upload "$UPLOAD_TARGET" "$FILE_PATH"
133
-
134
- # Update asset count and remove release from available list if full
135
- AVAILABLE_ASSET_COUNTS[0]=$((${AVAILABLE_ASSET_COUNTS[0]} + 1))
136
-
137
- MAX_ASSETS=998
138
- if [ "$UPLOAD_TARGET" == "$TAG" ]; then
139
- MAX_ASSETS=988
140
- fi
141
-
142
- if [ "${AVAILABLE_ASSET_COUNTS[0]}" -ge "$MAX_ASSETS" ]; then
143
- AVAILABLE_RELEASES=("${AVAILABLE_RELEASES[@]:1}")
144
- AVAILABLE_ASSET_COUNTS=("${AVAILABLE_ASSET_COUNTS[@]:1}")
145
- fi
146
- done
147
-
148
- echo "Upload process complete."