Skip to content

Commit 44e6c86

Browse files
committed
Add even more fields
1 parent 2674fce commit 44e6c86

3 files changed

Lines changed: 198 additions & 10 deletions

File tree

root/app/keyvaluestore.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ def __contains__(self, key):
3838
def __getitem__(self, key):
3939
item = self.conn.execute("SELECT value FROM kv WHERE key = ?", (key,)).fetchone()
4040
return item[0] if item else None
41+
def get_updated_at(self, key):
42+
item = self.conn.execute("SELECT updated_at FROM kv WHERE key = ?", (key,)).fetchone()
43+
return item[0] if item else None
4144
def set_value(self, key, value, schema_version):
4245
self.conn.execute("REPLACE INTO kv (key, value, updated_at, schema_version) VALUES (?, ?, CURRENT_TIMESTAMP, ?)", (key, value, schema_version))
4346
self.conn.commit()

root/app/models.py

Lines changed: 77 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,93 @@ class Changelog(BaseModel):
1515
date: str
1616
desc: str
1717

18+
class Volume(BaseModel):
19+
path: str
20+
host_path: str
21+
desc: str
22+
optional: bool
23+
24+
class Port(BaseModel):
25+
external: str
26+
internal: str
27+
desc: str
28+
optional: bool
29+
30+
class EnvVar(BaseModel):
31+
name: str
32+
value: str
33+
desc: str
34+
optional: bool
35+
36+
class EnvVar(BaseModel):
37+
name: str
38+
value: str
39+
desc: str
40+
optional: bool
41+
42+
class Custom(BaseModel):
43+
name: str
44+
name_compose: str
45+
value: str
46+
desc: str
47+
optional: bool
48+
49+
class SecurityOpt(BaseModel):
50+
run_var: str
51+
compose_var: str
52+
desc: str
53+
optional: bool
54+
55+
class Device(BaseModel):
56+
path: str
57+
host_path: str
58+
desc: str
59+
optional: bool
60+
61+
class Cap(BaseModel):
62+
cap_add: str
63+
desc: str
64+
optional: bool
65+
66+
class Hostname(BaseModel):
67+
hostname: str
68+
desc: str
69+
optional: bool
70+
71+
class MacAddress(BaseModel):
72+
mac_address: str
73+
desc: str
74+
optional: bool
75+
1876
class Image(BaseModel):
1977
name: str
2078
github_url: str
21-
project_url: str
79+
project_url: str | None
80+
project_logo: str | None
81+
application_setup: str
2282
description: str
2383
version: str
2484
version_timestamp: str
25-
changelog: list[Changelog]
2685
category: str
2786
stable: bool
28-
deprecated: bool
87+
deprecated: bool | None
2988
stars: int
89+
readonly_supported: bool | None
90+
nonroot_supported: bool | None
91+
privileged: bool | None
92+
networking: str | None
93+
hostname: Hostname | None
94+
mac_address: MacAddress | None
3095
tags: list[Tag]
3196
architectures: list[Architecture]
97+
env_vars: list[EnvVar] | None
98+
volumes: list[Volume] | None
99+
ports: list[Port] | None
100+
custom: list[Custom] | None
101+
security_opt: list[SecurityOpt] | None
102+
devices: list[Device] | None
103+
caps: list[Cap] | None
104+
changelog: list[Changelog] | None
32105

33106
class Repository(BaseModel):
34107
linuxserver: list[Image]
@@ -38,4 +111,5 @@ class ImagesData(BaseModel):
38111

39112
class ImagesResponse(BaseModel):
40113
status: str
114+
last_updated: str
41115
data: ImagesData

root/app/updater.py

Lines changed: 118 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import lsio_github as gh
22
from keyvaluestore import KeyValueStore, set_db_schema
3-
from models import Architecture, Changelog, Tag, Image, Repository, ImagesData, ImagesResponse, IMAGES_SCHEMA_VERSION
3+
from models import Architecture, Changelog, Tag, EnvVar, Volume, Port
4+
from models import Custom, SecurityOpt, Device, Cap, Hostname, MacAddress, Image
5+
from models import Repository, ImagesData, ImagesResponse, IMAGES_SCHEMA_VERSION
46

57
import datetime
68
import os
@@ -31,7 +33,7 @@ def get_architectures(readme_vars):
3133

3234
def get_changelogs(readme_vars):
3335
if "changelogs" not in readme_vars:
34-
return [Changelog(date="01.01.50", desc="No changelog")]
36+
return None
3537
changelogs = []
3638
for item in readme_vars["changelogs"][0:3]:
3739
changelogs.append(Changelog(date=item["date"][0:-1], desc=item["desc"]))
@@ -47,6 +49,98 @@ def get_description(readme_vars):
4749
description = description.replace("({{ project_url }})", "")
4850
return description
4951

52+
def get_env_vars(readme_vars):
53+
env_vars = []
54+
if readme_vars.get("common_param_env_vars_enabled", False):
55+
env_vars.extend([
56+
EnvVar(name="PUID", value="1000", desc="User ID", optional=False),
57+
EnvVar(name="PGID", value="1000", desc="Group ID", optional=False),
58+
EnvVar(name="TZ", value="Etc/UTC", desc="Timezone", optional=False),
59+
])
60+
if "param_env_vars" in readme_vars:
61+
for item in readme_vars["param_env_vars"]:
62+
env_vars.append(EnvVar(name=item["env_var"], value=item["env_value"], desc=item["desc"], optional=False))
63+
if "opt_param_env_vars" in readme_vars:
64+
for item in readme_vars["opt_param_env_vars"]:
65+
env_vars.append(EnvVar(name=item["env_var"], value=item["env_value"], desc=item["desc"], optional=True))
66+
return env_vars if env_vars else None
67+
68+
def get_volumes(readme_vars):
69+
volumes = []
70+
if "param_volumes" in readme_vars:
71+
for item in readme_vars["param_volumes"]:
72+
volumes.append(Volume(path=item["vol_path"], host_path=item["vol_host_path"], desc=item["desc"], optional=False))
73+
if "opt_param_volumes" in readme_vars:
74+
for item in readme_vars["opt_param_volumes"]:
75+
volumes.append(Volume(path=item["vol_path"], host_path=item["vol_host_path"], desc=item["desc"], optional=True))
76+
return volumes if volumes else None
77+
78+
def get_ports(readme_vars):
79+
ports = []
80+
if "param_ports" in readme_vars:
81+
for item in readme_vars["param_ports"]:
82+
ports.append(Port(external=item["external_port"], internal=item["internal_port"], desc=item["port_desc"], optional=False))
83+
if "opt_param_ports" in readme_vars:
84+
for item in readme_vars["opt_param_ports"]:
85+
ports.append(Port(external=item["external_port"], internal=item["internal_port"], desc=item["port_desc"], optional=True))
86+
return ports if ports else None
87+
88+
def get_custom(readme_vars):
89+
custom = []
90+
if "custom_params" in readme_vars:
91+
for item in readme_vars["custom_params"]:
92+
custom.append(Custom(name=item["name"], name_compose=item["name_compose"], value=item["value"], desc=item["desc"], optional=False))
93+
if "opt_custom_params" in readme_vars:
94+
for item in readme_vars["opt_custom_params"]:
95+
custom.append(Custom(name=item["name"], name_compose=item["name_compose"], value=item["value"], desc=item["desc"], optional=True))
96+
return custom if custom else None
97+
98+
def get_security_opt(readme_vars):
99+
security_opts = []
100+
if "security_opt_param_vars" in readme_vars:
101+
for item in readme_vars["security_opt_param_vars"]:
102+
security_opts.append(SecurityOpt(run_var=item["run_var"], compose_var=item["compose_var"], desc=item["desc"], optional=False))
103+
if "opt_security_opt_param_vars" in readme_vars:
104+
for item in readme_vars["opt_security_opt_param_vars"]:
105+
security_opts.append(SecurityOpt(run_var=item["run_var"], compose_var=item["compose_var"], desc=item["desc"], optional=True))
106+
return security_opts if security_opts else None
107+
108+
def get_devices(readme_vars):
109+
devices = []
110+
if "param_devices" in readme_vars:
111+
for item in readme_vars["param_devices"]:
112+
devices.append(Device(path=item["device_path"], host_path=item["device_host_path"], desc=item["desc"], optional=False))
113+
if "opt_param_devices" in readme_vars:
114+
for item in readme_vars["opt_param_devices"]:
115+
devices.append(Device(path=item["device_path"], host_path=item["device_host_path"], desc=item["desc"], optional=True))
116+
return devices if devices else None
117+
118+
def get_caps(readme_vars):
119+
caps = []
120+
if "cap_add_param_vars" in readme_vars:
121+
for item in readme_vars["cap_add_param_vars"]:
122+
caps.append(Cap(cap_add=item["cap_add_var"], desc=item["desc"], optional=False))
123+
if "opt_cap_add_param_vars" in readme_vars:
124+
for item in readme_vars["opt_cap_add_param_vars"]:
125+
caps.append(Cap(cap_add=item["cap_add_var"], desc=item["desc"], optional=True))
126+
return caps if caps else None
127+
128+
def get_hostname(readme_vars):
129+
include_hostname = readme_vars.get("param_usage_include_hostname", False)
130+
if not include_hostname:
131+
return None
132+
optional = include_hostname == "optional"
133+
hostname = readme_vars.get("param_hostname", False).replace("{{ project_name }}", readme_vars["project_name"])
134+
return Hostname(hostname=hostname, desc=readme_vars.get("param_hostname_desc", ""), optional=optional)
135+
136+
def get_mac_address(readme_vars):
137+
include_mac_address = readme_vars.get("param_usage_include_mac_address", False)
138+
if not include_mac_address:
139+
return None
140+
optional = include_mac_address == "optional"
141+
hostname = readme_vars.get("param_mac_address", False)
142+
return MacAddress(mac_address=hostname, desc=readme_vars.get("param_mac_address_desc", ""), optional=optional)
143+
50144
def get_image(repo):
51145
if not repo.name.startswith("docker-") or repo.name.startswith("docker-baseimage-"):
52146
return None
@@ -57,22 +151,37 @@ def get_image(repo):
57151
if "Internal" in categories:
58152
return None
59153
tags, stable = get_tags(readme_vars)
60-
deprecated = readme_vars.get("project_deprecation_status", False)
154+
deprecated = readme_vars.get("project_deprecation_status", None)
61155
version, version_timestamp = gh.get_last_stable_release(repo)
62156
return Image(
63157
name=repo.name.replace("docker-", ""),
64158
github_url=repo.html_url,
65-
project_url=readme_vars.get("project_url", ""),
159+
stars=repo.stargazers_count,
160+
project_url=readme_vars.get("project_url", None),
161+
project_logo=readme_vars.get("project_logo", None),
162+
application_setup=f"{repo.html_url}?tab=readme-ov-file#application-setup",
66163
description=get_description(readme_vars),
67164
version=version,
68165
version_timestamp=version_timestamp,
69166
changelog=get_changelogs(readme_vars),
70167
category=categories,
71168
stable=stable,
72169
deprecated=deprecated,
73-
stars=repo.stargazers_count,
74170
tags=tags,
75-
architectures=get_architectures(readme_vars)
171+
architectures=get_architectures(readme_vars),
172+
readonly_supported=readme_vars.get("readonly_supported", None),
173+
nonroot_supported=readme_vars.get("nonroot_supported", None),
174+
privileged=readme_vars.get("privileged", None),
175+
networking=readme_vars.get("param_net", None),
176+
hostname=get_hostname(readme_vars),
177+
mac_address=get_mac_address(readme_vars),
178+
env_vars=get_env_vars(readme_vars),
179+
volumes=get_volumes(readme_vars),
180+
ports=get_ports(readme_vars),
181+
custom=get_custom(readme_vars),
182+
security_opt=get_security_opt(readme_vars),
183+
devices=get_devices(readme_vars),
184+
caps=get_caps(readme_vars),
76185
)
77186

78187
def update_images():
@@ -89,7 +198,9 @@ def update_images():
89198
if not image:
90199
continue
91200
images.append(image)
92-
new_state = ImagesResponse(status="OK", data=ImagesData(repositories=Repository(linuxserver=images))).model_dump_json()
201+
data = ImagesData(repositories=Repository(linuxserver=images))
202+
response = ImagesResponse(status="OK", last_updated=kv.get_updated_at("images"), data=data)
203+
new_state = response.model_dump_json(exclude_none=True)
93204
kv.set_value("images", new_state, IMAGES_SCHEMA_VERSION)
94205
print(f"{datetime.datetime.now()} - updated images")
95206

0 commit comments

Comments
 (0)