This commit is contained in:
2026-09-23 21:46:36 +02:00
parent c187b0c45e
commit 80f6136399
9 changed files with 115 additions and 8 deletions
+2 -2
View File
@@ -1,4 +1,4 @@
# AssetManager 0.5.5.83 # AssetManager 0.5.5.84
AssetManager is a self-hosted web application for managing IT equipment and other organizational assets. It provides asset inventory, software inventory, remote job execution, reporting, privacy/retention documentation, and optional integration with MeshCentral. AssetManager is a self-hosted web application for managing IT equipment and other organizational assets. It provides asset inventory, software inventory, remote job execution, reporting, privacy/retention documentation, and optional integration with MeshCentral.
@@ -8,7 +8,7 @@ The project is licensed under the **Apache License 2.0** and may be used, modifi
- configurable asset categories, fields, status values, images, and assignments - configurable asset categories, fields, status values, images, and assignments
- asset lists, detail views, history, bulk editing, Excel import/export, duplicate merging, and tree views - asset lists, detail views, history, bulk editing, Excel import/export, duplicate merging, and tree views
- hardware and software inventory with comparison and aggregation views - hardware and software inventory with comparison, aggregation views, and Excel export
- static Setup Analyzer for Windows installer technology, silent parameters, deployment-script export, and persistent software-package creation - static Setup Analyzer for Windows installer technology, silent parameters, deployment-script export, and persistent software-package creation
- install, uninstall, and reinstall software-package jobs with MeshCentral file transfer, callback tracking, process control, and optional post-install application launch - install, uninstall, and reinstall software-package jobs with MeshCentral file transfer, callback tracking, process control, and optional post-install application launch
- job definitions and remote job execution with status tracking, callbacks, retries, and logs - job definitions and remote job execution with status tracking, callbacks, retries, and logs
+1 -1
View File
@@ -1 +1 @@
0.5.5.83 0.5.5.84
+2 -1
View File
@@ -931,7 +931,8 @@ BASE_TRANSLATIONS.update({
"software.summary_table": ("Aggregated entries", "Kumulierte Einträge"), "software.summary_table": ("Aggregated entries", "Kumulierte Einträge"),
"software.table_filter_help": ("Use the filter row below the column headings to narrow the list.", "Die Filterzeile unterhalb der Spaltenüberschriften grenzt die Liste ein."), "software.table_filter_help": ("Use the filter row below the column headings to narrow the list.", "Die Filterzeile unterhalb der Spaltenüberschriften grenzt die Liste ein."),
"software.numeric_filter_help": ("Numeric columns support operators such as < 2, >= 5, 1..10 or 'between 1 and 10'.", "Numerische Spalten unterstützen Operatoren wie < 2, >= 5, 1..10 oder „zwischen 1 und 10“."), "software.numeric_filter_help": ("Numeric columns support operators such as < 2, >= 5, 1..10 or 'between 1 and 10'.", "Numerische Spalten unterstützen Operatoren wie < 2, >= 5, 1..10 oder „zwischen 1 und 10“."),
"software.numeric_filter_placeholder": ("e.g. < 2 or 1..5", "z. B. < 2 oder 1..5") "software.numeric_filter_placeholder": ("e.g. < 2 or 1..5", "z. B. < 2 oder 1..5"),
"software.export_excel": ("Export Excel", "Excel exportieren")
}) })
+85
View File
@@ -6200,6 +6200,91 @@ def software_installations_page(request: Request, db: Session = Depends(get_db))
return response return response
@app.get("/software/installations/export.xlsx")
def software_installations_export_excel(request: Request, db: Session = Depends(get_db)):
_require_admin(request)
language_code = _request_language(request)
software_entries = _software_installation_rows(db)
headers = [
translate(db, language_code, "common.assets", "Assets"),
translate(db, language_code, "common.name", "Name"),
translate(db, language_code, "about.version", "Version"),
translate(db, language_code, "software.publisher", "Publisher"),
translate(db, language_code, "software.architecture", "Architecture"),
translate(db, language_code, "software.platform", "Platform"),
translate(db, language_code, "software.install_date", "Installation date"),
translate(db, language_code, "software.last_seen", "Last seen"),
]
rows = []
for entry in software_entries:
platform = str(entry.platform or "unknown")
rows.append([
entry.asset_name or "",
entry.name or "",
entry.version or "",
entry.publisher or "",
entry.architecture or "",
translate(db, language_code, f"software.platform.{platform}", platform),
entry.install_date or "",
entry.last_seen_at or "",
])
return _xlsx_response(
"assetmanager-software-installations.xlsx",
headers,
rows,
)
@app.get("/software/summary/export.xlsx")
def software_summary_export_excel(request: Request, db: Session = Depends(get_db)):
_require_admin(request)
language_code = _request_language(request)
allowed_groupings = {"name_platform", "software", "version"}
grouping = str(
request.query_params.get("grouping")
or request.session.get("software_summary_grouping")
or "software"
).strip().lower()
if grouping not in allowed_groupings:
grouping = "software"
software_summary = _software_summary_rows(db, grouping)
headers = [
translate(db, language_code, "common.name", "Name"),
translate(db, language_code, "software.publisher", "Publisher"),
translate(db, language_code, "software.platform", "Platform"),
translate(db, language_code, "software.versions", "Versions"),
translate(db, language_code, "software.version_count", "Number of versions"),
translate(db, language_code, "software.unique_asset_count", "Unique assets"),
translate(db, language_code, "software.inventory_entry_count", "Inventory entries"),
translate(db, language_code, "software.last_seen", "Last seen"),
]
rows = []
for row in software_summary:
platform = str(row.get("platform") or "unknown")
rows.append([
row.get("name") or "",
row.get("publisher") or "",
translate(db, language_code, f"software.platform.{platform}", platform),
row.get("versions") or "",
row.get("version_count") or 0,
row.get("asset_count") or 0,
row.get("entries") or 0,
row.get("last_seen_at") or "",
])
return _xlsx_response(
f"assetmanager-software-summary-{grouping}.xlsx",
headers,
rows,
)
@app.get("/software/summary") @app.get("/software/summary")
def software_summary_page(request: Request, db: Session = Depends(get_db)): def software_summary_page(request: Request, db: Session = Depends(get_db)):
_require_admin(request) _require_admin(request)
@@ -5,8 +5,11 @@
<h1>{{ t('software.all_installations') }}</h1> <h1>{{ t('software.all_installations') }}</h1>
<p class="muted">{{ t('software.all_installations_help') }}</p> <p class="muted">{{ t('software.all_installations_help') }}</p>
</div> </div>
<div class="toolbar-actions">
<a class="button" href="/software/installations/export.xlsx">📥 {{ t('software.export_excel') }}</a>
<a class="button button-secondary" href="/software">{{ t('common.back') }}</a> <a class="button button-secondary" href="/software">{{ t('common.back') }}</a>
</div> </div>
</div>
<section class="panel" data-software-selection> <section class="panel" data-software-selection>
<div class="software-section-heading"> <div class="software-section-heading">
+3
View File
@@ -5,8 +5,11 @@
<h1>{{ t('software.aggregated_list') }}</h1> <h1>{{ t('software.aggregated_list') }}</h1>
<p class="muted">{{ t('software.aggregated_list_help') }}</p> <p class="muted">{{ t('software.aggregated_list_help') }}</p>
</div> </div>
<div class="toolbar-actions">
<a class="button" href="/software/summary/export.xlsx?grouping={{ grouping|urlencode }}">📥 {{ t('software.export_excel') }}</a>
<a class="button button-secondary" href="/software">{{ t('common.back') }}</a> <a class="button button-secondary" href="/software">{{ t('common.back') }}</a>
</div> </div>
</div>
<section class="panel"> <section class="panel">
<div class="software-section-heading"> <div class="software-section-heading">
+1 -1
View File
@@ -1,2 +1,2 @@
APP_VERSION = "0.5.5.83" APP_VERSION = "0.5.5.84"
__version__ = APP_VERSION __version__ = APP_VERSION
+2 -1
View File
@@ -1,3 +1,4 @@
- [0.5.5.84](UPDATE-0.5.5.84.md) - add Excel export to detailed and aggregated software inventory lists.
- [0.5.5.83](UPDATE-0.5.5.83.md) - fix Windows PowerShell compatibility for post-install application start. - [0.5.5.83](UPDATE-0.5.5.83.md) - fix Windows PowerShell compatibility for post-install application start.
- [0.5.5.82](UPDATE-0.5.5.82.md) - add optional post-install application launch in the active interactive user session. - [0.5.5.82](UPDATE-0.5.5.82.md) - add optional post-install application launch in the active interactive user session.
- [0.5.5.81](UPDATE-0.5.5.81.md) - fix generated PowerShell process-control syntax for software jobs. - [0.5.5.81](UPDATE-0.5.5.81.md) - fix generated PowerShell process-control syntax for software jobs.
@@ -19,7 +20,7 @@
Release notes are stored outside the project root to keep the repository overview compact. Release notes are stored outside the project root to keep the repository overview compact.
The current release is **0.5.5.83**. The current release is **0.5.5.84**.
Older notes are concise English summaries migrated from the original release documents. Git history remains authoritative for exact implementation details. Older notes are concise English summaries migrated from the original release documents. Git history remains authoritative for exact implementation details.
+14
View File
@@ -0,0 +1,14 @@
# Update 0.5.5.84
## Added
- Excel export button on the detailed software installation list.
- Excel export button on the aggregated software list.
- The aggregated export uses the grouping currently selected in the user interface.
- Export headers and platform labels follow the current user language.
- Excel files include the same core columns as their corresponding software tables.
## Export endpoints
- `/software/installations/export.xlsx`
- `/software/summary/export.xlsx?grouping=...`