mirror of
https://github.com/arcan1s/ahriman.git
synced 2025-07-10 04:25:47 +00:00
feat: add silent logs reload
This commit is contained in:
@ -97,7 +97,7 @@
|
||||
<input id="package-info-refresh-input" type="checkbox" class="form-check-input" value="" checked>
|
||||
<label for="package-info-refresh-input" class="form-check-label">update pacman databases</label>
|
||||
|
||||
<button id="package-info-update-button" type="submit" class="btn btn-success" onclick="packageInfoUpdate()" data-bs-dismiss="modal"><i class="bi bi-play"></i><span class="d-none d-sm-inline"> update</span></button>
|
||||
<button id="package-info-update-button" type="submit" class="btn btn-success" onclick="packageInfoUpdate()"><i class="bi bi-play"></i><span class="d-none d-sm-inline"> update</span></button>
|
||||
<button id="package-info-remove-button" type="submit" class="btn btn-danger" onclick="packageInfoRemove()" data-bs-dismiss="modal"><i class="bi bi-trash"></i><span class="d-none d-sm-inline"> remove</span></button>
|
||||
{% endif %}
|
||||
{% if autorefresh_intervals %}
|
||||
@ -315,6 +315,69 @@
|
||||
}
|
||||
|
||||
function loadLogs(packageBase, onFailure) {
|
||||
const sortFn = (left, right) => left.process_id.localeCompare(right.process_id) || left.version.localeCompare(right.version);
|
||||
const compareFn = (left, right) => left.process_id === right.process_id && left.version === right.version;
|
||||
|
||||
makeRequest(
|
||||
`/api/v2/packages/${packageBase}/logs`,
|
||||
{
|
||||
query: {
|
||||
architecture: repository.architecture,
|
||||
head: true,
|
||||
repository: repository.repository,
|
||||
},
|
||||
convert: response => response.json(),
|
||||
},
|
||||
data => {
|
||||
const currentVersions = Array.from(packageInfoLogsVersions.children)
|
||||
.map(el => {
|
||||
return {
|
||||
process_id: el.dataset.processId,
|
||||
version: el.dataset.version,
|
||||
};
|
||||
})
|
||||
.sort(sortFn);
|
||||
const newVersions = data
|
||||
.map(el => {
|
||||
return {
|
||||
process_id: el.process_id,
|
||||
version: el.version,
|
||||
};
|
||||
})
|
||||
.sort(sortFn);
|
||||
|
||||
if (currentVersions.equals(newVersions, compareFn))
|
||||
loadLogsActive(packageBase);
|
||||
else
|
||||
loadLogsAll(packageBase, onFailure);
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
function loadLogsActive(packageBase) {
|
||||
const activeLogSelector = packageInfoLogsVersions.querySelector(".active");
|
||||
|
||||
if (activeLogSelector) {
|
||||
makeRequest(
|
||||
`/api/v2/packages/${packageBase}/logs`,
|
||||
{
|
||||
query: {
|
||||
architecture: repository.architecture,
|
||||
repository: repository.repository,
|
||||
version: activeLogSelector.dataset.version,
|
||||
process_id: activeLogSelector.dataset.processId,
|
||||
},
|
||||
convert: response => response.json(),
|
||||
},
|
||||
data => {
|
||||
activeLogSelector.dataset.logs = convertLogs(data);
|
||||
activeLogSelector.click();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function loadLogsAll(packageBase, onFailure) {
|
||||
makeRequest(
|
||||
`/api/v2/packages/${packageBase}/logs`,
|
||||
{
|
||||
@ -440,29 +503,6 @@
|
||||
packagesAdd(packageBase, [], repository, {refresh: packageInfoRefreshInput.checked});
|
||||
}
|
||||
|
||||
function reloadActiveLogs(packageBase) {
|
||||
const activeLogSelector = packageInfoLogsVersions.querySelector(".active");
|
||||
|
||||
if (activeLogSelector) {
|
||||
makeRequest(
|
||||
`/api/v2/packages/${packageBase}/logs`,
|
||||
{
|
||||
query: {
|
||||
architecture: repository.architecture,
|
||||
repository: repository.repository,
|
||||
version: activeLogSelector.dataset.version,
|
||||
process_id: activeLogSelector.dataset.processId,
|
||||
},
|
||||
convert: response => response.json(),
|
||||
},
|
||||
data => {
|
||||
activeLogSelector.dataset.logs = convertLogs(data);
|
||||
activeLogSelector.click();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function showPackageInfo(packageBase) {
|
||||
const isPackageBaseSet = packageBase !== undefined;
|
||||
if (isPackageBaseSet) {
|
||||
@ -502,7 +542,7 @@
|
||||
const packageBase = packageInfoModal.dataset.package;
|
||||
// we only poll status and logs here
|
||||
loadPackage(packageBase);
|
||||
reloadActiveLogs(packageBase);
|
||||
loadLogs(packageBase);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -218,6 +218,21 @@
|
||||
});
|
||||
}
|
||||
|
||||
Array.prototype.equals = function (right, comparator) {
|
||||
let index = this.length;
|
||||
if (index !== right.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (index--) {
|
||||
if (!comparator(this[index], right[index])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Date.prototype.toISOStringShort = function () {
|
||||
const pad = number => String(number).padStart(2, "0");
|
||||
return `${this.getFullYear()}-${pad(this.getMonth() + 1)}-${pad(this.getDate())} ${pad(this.getHours())}:${pad(this.getMinutes())}:${pad(this.getSeconds())}`;
|
||||
|
@ -27,6 +27,9 @@ class LogsSearchSchema(PaginationSchema):
|
||||
request log search schema
|
||||
"""
|
||||
|
||||
head = fields.Boolean(metadata={
|
||||
"description": "Return versions only without fetching logs themselves",
|
||||
})
|
||||
version = fields.String(metadata={
|
||||
"description": "Package version to search",
|
||||
"example": __version__,
|
||||
|
@ -17,7 +17,10 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import itertools
|
||||
|
||||
from aiohttp.web import Response, json_response
|
||||
from dataclasses import replace
|
||||
from typing import ClassVar
|
||||
|
||||
from ahriman.models.user_access import UserAccess
|
||||
@ -28,7 +31,8 @@ from ahriman.web.views.status_view_guard import StatusViewGuard
|
||||
|
||||
|
||||
class LogsView(StatusViewGuard, BaseView):
|
||||
"""
|
||||
""" else:
|
||||
|
||||
package logs web view
|
||||
|
||||
Attributes:
|
||||
@ -66,5 +70,14 @@ class LogsView(StatusViewGuard, BaseView):
|
||||
|
||||
logs = self.service(package_base=package_base).package_logs_get(package_base, version, process, limit, offset)
|
||||
|
||||
head = self.request.query.get("head", "false")
|
||||
# pylint: disable=protected-access
|
||||
if self.configuration._convert_to_boolean(head): # type: ignore[attr-defined]
|
||||
# logs should be sorted already
|
||||
logs = [
|
||||
replace(next(log_records), message="") # remove messages
|
||||
for _, log_records in itertools.groupby(logs, lambda log_record: log_record.log_record_id)
|
||||
]
|
||||
|
||||
response = [log_record.view() for log_record in logs]
|
||||
return json_response(response)
|
||||
|
@ -139,3 +139,41 @@ async def test_get_not_found(client: TestClient, package_ahriman: Package) -> No
|
||||
response = await client.get(f"/api/v2/packages/{package_ahriman.base}/logs")
|
||||
assert response.status == 404
|
||||
assert not response_schema.validate(await response.json())
|
||||
|
||||
|
||||
async def test_get_head(client: TestClient, package_ahriman: Package) -> None:
|
||||
"""
|
||||
must return only versions if head parameter is set
|
||||
"""
|
||||
await client.post(f"/api/v1/packages/{package_ahriman.base}",
|
||||
json={"status": BuildStatusEnum.Success.value, "package": package_ahriman.view()})
|
||||
await client.post(f"/api/v1/packages/{package_ahriman.base}/logs",
|
||||
json={"created": 42.0, "message": "message 1", "version": "42"})
|
||||
await client.post(f"/api/v1/packages/{package_ahriman.base}/logs",
|
||||
json={"created": 43.0, "message": "message 2", "version": "42"})
|
||||
await client.post(f"/api/v1/packages/{package_ahriman.base}/logs",
|
||||
json={"created": 44.0, "message": "message 3", "version": "43"})
|
||||
request_schema = pytest.helpers.schema_request(LogsView.get, location="querystring")
|
||||
response_schema = pytest.helpers.schema_response(LogsView.get)
|
||||
|
||||
payload = {"head": "true"}
|
||||
assert not request_schema.validate(payload)
|
||||
response = await client.get(f"/api/v2/packages/{package_ahriman.base}/logs", params=payload)
|
||||
assert response.status == 200
|
||||
|
||||
logs = await response.json()
|
||||
assert not response_schema.validate(logs)
|
||||
assert logs == [
|
||||
{
|
||||
"created": 42.0,
|
||||
"message": "",
|
||||
"version": "42",
|
||||
"process_id": LogRecordId.DEFAULT_PROCESS_ID,
|
||||
},
|
||||
{
|
||||
"created": 44.0,
|
||||
"message": "",
|
||||
"version": "43",
|
||||
"process_id": LogRecordId.DEFAULT_PROCESS_ID,
|
||||
},
|
||||
]
|
||||
|
Reference in New Issue
Block a user