testdata imgs

This commit is contained in:
j3d1 2026-09-05 16:23:36 +02:00
parent 197f173097
commit 5cd3ae5a13
35 changed files with 47 additions and 6 deletions

View file

@ -8,6 +8,7 @@ who are friends with each other.
import csv import csv
import io import io
import json import json
import mimetypes
import os import os
import random import random
import zipfile import zipfile
@ -15,6 +16,9 @@ from hashlib import sha256
from nacl.signing import SigningKey from nacl.signing import SigningKey
from nacl.encoding import HexEncoder from nacl.encoding import HexEncoder
IMGS_DIR = os.path.join(os.path.dirname(__file__), 'imgs')
IMAGE_ATTACHMENT_PROBABILITY = 0.9
# Realistic item database with shared_data category/tag references using fully qualified handles # Realistic item database with shared_data category/tag references using fully qualified handles
# Format: (name, category_handle, tags_handles, policy, description, qty, properties_list) # Format: (name, category_handle, tags_handles, policy, description, qty, properties_list)
@ -250,6 +254,21 @@ def load_shared_data():
return all_tags, all_categories, all_properties return all_tags, all_categories, all_properties
def load_available_images():
"""Read every file in imgs/ and return a list of (data, mime_type) tuples."""
images = []
for filename in sorted(os.listdir(IMGS_DIR)):
filepath = os.path.join(IMGS_DIR, filename)
if not os.path.isfile(filepath):
continue
mime_type, _ = mimetypes.guess_type(filename)
if not mime_type:
continue
with open(filepath, 'rb') as f:
images.append((f.read(), mime_type))
return images
def generate_keypair(): def generate_keypair():
"""Generate a signing key pair and return (hex_private_key, hex_public_key).""" """Generate a signing key pair and return (hex_private_key, hex_public_key)."""
signing_key = SigningKey.generate() signing_key = SigningKey.generate()
@ -341,7 +360,7 @@ def _quote_value_if_needed(value):
return value return value
def generate_inventory_csv(count, num_locations, location_id_map, item_range=None): def generate_inventory_csv(count, num_locations, location_id_map, item_range=None, available_images=None):
"""Generate a realistic inventory.csv with varied items using shared_data references and properties. """Generate a realistic inventory.csv with varied items using shared_data references and properties.
Args: Args:
@ -349,6 +368,12 @@ def generate_inventory_csv(count, num_locations, location_id_map, item_range=Non
num_locations: Number of locations num_locations: Number of locations
location_id_map: Map of location names to IDs location_id_map: Map of location names to IDs
item_range: Tuple of (start_idx, end_idx) to partition the ITEMS_DATABASE, or None for all items item_range: Tuple of (start_idx, end_idx) to partition the ITEMS_DATABASE, or None for all items
available_images: List of (data, mime_type) tuples to randomly attach to items, or None to skip
Returns:
Tuple of (inventory_csv_bytes, files) where files maps a zip arcname (matching
`toolshed.offlinedata.inventory_files()`'s 'files/<hash><ext>' convention) to file bytes,
for every image actually referenced by an item.
""" """
# Get location names from the map # Get location names from the map
location_names = list(location_id_map.keys()) location_names = list(location_id_map.keys())
@ -365,6 +390,7 @@ def generate_inventory_csv(count, num_locations, location_id_map, item_range=Non
selected_items = random.sample(available_items, min(count, len(available_items))) selected_items = random.sample(available_items, min(count, len(available_items)))
rows = [] rows = []
files = {}
for i, item_tuple in enumerate(selected_items, 1): for i, item_tuple in enumerate(selected_items, 1):
# Handle both old format (6 elements) and new format (7 elements with properties) # Handle both old format (6 elements) and new format (7 elements with properties)
if len(item_tuple) == 7: if len(item_tuple) == 7:
@ -382,6 +408,16 @@ def generate_inventory_csv(count, num_locations, location_id_map, item_range=Non
properties_str = ', '.join( properties_str = ', '.join(
f"{prop_handle}={_quote_value_if_needed(value)}" for prop_handle, value in properties_list) f"{prop_handle}={_quote_value_if_needed(value)}" for prop_handle, value in properties_list)
# Attach a random image to most items, matching `toolshed.offlinedata.inventory_files()`'s
# 'files/<hash><ext>' arcname convention so the import side resolves it as the same file.
files_str = ''
if available_images and random.random() < IMAGE_ATTACHMENT_PROBABILITY:
data, mime_type = random.choice(available_images)
extension = mimetypes.guess_extension(mime_type) or ''
arcname = f'files/{sha256(data).hexdigest()}{extension}'
files[arcname] = data
files_str = arcname
rows.append({ rows.append({
'id': str(i), 'id': str(i),
'name': name, 'name': name,
@ -393,7 +429,7 @@ def generate_inventory_csv(count, num_locations, location_id_map, item_range=Non
'storage_location': location, 'storage_location': location,
'tags': ', '.join(tags_for_item), 'tags': ', '.join(tags_for_item),
'properties': properties_str, 'properties': properties_str,
'files': '', 'files': files_str,
'created_at': '2026-08-01T00:00:00+00:00', 'created_at': '2026-08-01T00:00:00+00:00',
}) })
@ -403,7 +439,7 @@ def generate_inventory_csv(count, num_locations, location_id_map, item_range=Non
writer = csv.DictWriter(output, fieldnames=fieldnames) writer = csv.DictWriter(output, fieldnames=fieldnames)
writer.writeheader() writer.writeheader()
writer.writerows(rows) writer.writerows(rows)
return output.getvalue().encode('utf-8') return output.getvalue().encode('utf-8'), files
def generate_sample_files(): def generate_sample_files():
@ -447,9 +483,14 @@ def generate_export_zip(username, domain, friend_username, friend_domain, friend
friends_csv = generate_friends_csv(friend_username, friend_domain, friend_public_key) friends_csv = generate_friends_csv(friend_username, friend_domain, friend_public_key)
zip_file.writestr('friends.csv', friends_csv) zip_file.writestr('friends.csv', friends_csv)
inventory_csv = generate_inventory_csv(num_items, num_locations, location_id_map, item_range) available_images = load_available_images()
inventory_csv, item_files = generate_inventory_csv(
num_items, num_locations, location_id_map, item_range, available_images)
zip_file.writestr('inventory.csv', inventory_csv) zip_file.writestr('inventory.csv', inventory_csv)
for arcname, content in item_files.items():
zip_file.writestr(arcname, content)
sample_files = generate_sample_files() sample_files = generate_sample_files()
for arcname, content in sample_files.items(): for arcname, content in sample_files.items():
zip_file.writestr(arcname, content) zip_file.writestr(arcname, content)

BIN
testdata/imgs/1-600x800.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

BIN
testdata/imgs/1-800x600.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

BIN
testdata/imgs/1.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

BIN
testdata/imgs/10-600x800.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 KiB

BIN
testdata/imgs/10-800x600.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 KiB

BIN
testdata/imgs/10.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 KiB

BIN
testdata/imgs/2-600x800.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

BIN
testdata/imgs/2-800x600.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

BIN
testdata/imgs/2.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

BIN
testdata/imgs/3-600x800.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

BIN
testdata/imgs/3-800x600.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

BIN
testdata/imgs/3.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

BIN
testdata/imgs/4-600x800.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

BIN
testdata/imgs/4-800x600.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

BIN
testdata/imgs/4.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
testdata/imgs/5-600x800.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

BIN
testdata/imgs/5-800x600.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

BIN
testdata/imgs/5.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

BIN
testdata/imgs/6-600x800.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
testdata/imgs/6-800x600.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

BIN
testdata/imgs/6.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
testdata/imgs/7-600x800.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 KiB

BIN
testdata/imgs/7-800x600.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

BIN
testdata/imgs/7.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

BIN
testdata/imgs/8-600x800.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

BIN
testdata/imgs/8-800x600.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

BIN
testdata/imgs/8.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

BIN
testdata/imgs/9-600x800.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 428 KiB

BIN
testdata/imgs/9-800x600.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 522 KiB

BIN
testdata/imgs/9.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 KiB

2
testdata/user-a.key vendored
View file

@ -1 +1 @@
795e884532881938a1b03e37731443f4d1974327dafd5d508e0cb00cb0b161b6 982abc6680c1358c9d4d2436c96c00aebe36e9dd50fe184c12f1ac58fc7f8565

BIN
testdata/user-a.zip vendored

Binary file not shown.

2
testdata/user-b.key vendored
View file

@ -1 +1 @@
d011fedc3ba733baef6aa7550bbee47db66c2ad3dbfb0f6dcc14c984866df5eb 2e81e04093250c647cb2c364e39017be5aeac0303e138d6ded2e2cc7c3cdcdde

BIN
testdata/user-b.zip vendored

Binary file not shown.