| |
@@ -84,23 +84,27 @@
|
| |
return {
|
| |
"packages": None,
|
| |
"status": 400,
|
| |
- "last_synced": None,
|
| |
"error": "The orphan user can't be combined with anything else!"
|
| |
}
|
| |
|
| |
orphan_data = CACHE.get('packager-dashboard_orphan_page')["static_info"]["data"]
|
| |
+
|
| |
+ refresh_times_dict = {key: None for key in package_data_dict.keys()}
|
| |
+ refresh_times_dict["orphans"] = CACHE.get_refreshed_time('orphans_json').isoformat()
|
| |
+
|
| |
for package in orphan_data["packages"]:
|
| |
packages[package] = {
|
| |
"package": package,
|
| |
"kind": "primary",
|
| |
"origin": ["orphan"],
|
| |
- "data": {**package_data_dict}
|
| |
+ "data": {**package_data_dict},
|
| |
+ "refresh_times": refresh_times_dict
|
| |
}
|
| |
packages[package]["data"]["orphans"] = orphan_data["orphans"][package]
|
| |
|
| |
- return {"packages": packages,
|
| |
+ return {
|
| |
+ "packages": packages,
|
| |
"status": 200,
|
| |
- "last_synced": CACHE.get_refreshed_time('orphans_json').isoformat(),
|
| |
"error": None
|
| |
}
|
| |
|
| |
@@ -114,7 +118,6 @@
|
| |
return jsonify({
|
| |
"packages": None,
|
| |
"status": 400,
|
| |
- "last_synced": None,
|
| |
"error": "The correct format to query this endpoint is /api/v2/packager_dashboard?users=[users]&packages=[packages]"
|
| |
}), 400
|
| |
|
| |
@@ -138,6 +141,8 @@
|
| |
'abrt_reports': {}
|
| |
}
|
| |
|
| |
+ refresh_times = {key: None for key in package_data_dict}
|
| |
+
|
| |
packages = {}
|
| |
|
| |
# orphan user requires a bit of special handling since we don't care for anything else than the orphan data
|
| |
@@ -158,7 +163,8 @@
|
| |
"package": package,
|
| |
"kind": "primary" if package in user_packages["primary"] else "group",
|
| |
"origin": [user],
|
| |
- "data": {**package_data_dict}
|
| |
+ "data": {**package_data_dict},
|
| |
+ "refresh_times": {**refresh_times}
|
| |
}
|
| |
|
| |
# Remove package from explicit packages if we have it here
|
| |
@@ -169,7 +175,8 @@
|
| |
"package": package,
|
| |
"kind": "additional",
|
| |
"origin": [],
|
| |
- "data": {**package_data_dict}
|
| |
+ "data": {**package_data_dict},
|
| |
+ "refresh_times": {**refresh_times}
|
| |
}
|
| |
|
| |
flat_pkgs_list = packages.keys()
|
| |
@@ -177,6 +184,10 @@
|
| |
dashboard_helpers.update_users_access_time(users)
|
| |
|
| |
generic_data = dashboard_data_generic(flat_pkgs_list)
|
| |
+ refresh_times_dict = {key: generic_data["last_synced"] for key in package_data_dict}
|
| |
+
|
| |
+ # Generic package versions are a bit special... sigh
|
| |
+ refresh_times_dict["package_versions"] = CACHE.get_refreshed_time("package_versions_generic").isoformat()
|
| |
|
| |
prs = dashboard_data_prs(flat_pkgs_list)
|
| |
bzs = dashboard_data_bzs(flat_pkgs_list, authenticated=is_packager())
|
| |
@@ -185,14 +196,6 @@
|
| |
# Get the worst of status codes
|
| |
user_status = max(int(partial_status) for partial_status in [prs["status"], bzs["status"], abrt_reports["status"]])
|
| |
|
| |
- # Get last_synced
|
| |
- last_synced = {
|
| |
- "prs": prs["last_synced"],
|
| |
- "bzs": bzs["last_synced"],
|
| |
- "abrt_reports": abrt_reports["last_synced"],
|
| |
- "generic_data": generic_data["last_synced"]
|
| |
- }
|
| |
-
|
| |
# And finally, fill in our packages dict
|
| |
for package in flat_pkgs_list:
|
| |
packages[package]["data"] |= generic_data["data"][package]
|
| |
@@ -200,7 +203,13 @@
|
| |
packages[package]["data"]["bzs"] = bzs["data"][package]
|
| |
packages[package]["data"]["abrt_reports"] = abrt_reports["data"][package]
|
| |
|
| |
- return jsonify({"packages": packages, "status": user_status, "last_synced": last_synced, "error": None})
|
| |
+ # And exact sync times
|
| |
+ packages[package]["refresh_times"] |= generic_data["static_data_timestamps"][package]
|
| |
+ packages[package]["refresh_times"]["prs"] = prs["cache_ages"][package]
|
| |
+ packages[package]["refresh_times"]["bzs"] = bzs["cache_ages"][package]
|
| |
+ packages[package]["refresh_times"]["abrt_reports"] = abrt_reports["cache_ages"][package]
|
| |
+
|
| |
+ return jsonify({"packages": packages, "status": user_status, "error": None})
|
| |
|
| |
|
| |
@app.route('/api/v1/packager_dashboard/<user>', methods=['GET'])
|
| |
@@ -258,12 +267,18 @@
|
| |
v1_compat_generic_data["primary_packages"] = user_packages["primary"]
|
| |
v1_compat_generic_data["group_packages"] = user_packages["group"]
|
| |
|
| |
- static_info = {'status': generic_data["status"], 'data': v1_compat_generic_data, 'last_synced': generic_data["last_synced"].isoformat()}
|
| |
+ static_info = {'status': generic_data["status"], 'data': v1_compat_generic_data, 'last_synced': generic_data["last_synced"]}
|
| |
|
| |
prs = dashboard_data_prs(user_packages["combined"])
|
| |
bzs = dashboard_data_bzs(user_packages["combined"], authenticated=is_packager())
|
| |
abrt = dashboard_data_abrt(user_packages["combined"])
|
| |
|
| |
+ # Clean stuff from api/v2
|
| |
+ for drop in ["cache_ages", "static_data_timestamps"]:
|
| |
+ del prs[drop]
|
| |
+ del bzs[drop]
|
| |
+ del abrt[drop]
|
| |
+
|
| |
return jsonify({'static_info': static_info,
|
| |
'prs': prs,
|
| |
'bzs': bzs,
|
| |
@@ -274,29 +289,47 @@
|
| |
|
| |
def dashboard_data_abrt(packages):
|
| |
status = 200
|
| |
- data, load_status, last_synced, _ = CACHE.async_get_batch('packager-dashboard_abrt_issues', packages, 'low')
|
| |
+ data, load_status, cache_ages, _, _ = CACHE.async_get_batch('packager-dashboard_abrt_issues', packages, 'low')
|
| |
if load_status in [cache_utils.RefresherNotRegistered, cache_utils.AsyncRefreshInProgress]:
|
| |
status = 202
|
| |
- return {"status": status, "data": data, "last_synced": last_synced}
|
| |
+ return {
|
| |
+ "status": status,
|
| |
+ "data": data,
|
| |
+ "last_synced": min(cache_ages.values(), default=None),
|
| |
+ "cache_ages": cache_ages,
|
| |
+ "static_data_timestamps": {}
|
| |
+ }
|
| |
|
| |
def dashboard_data_prs(packages):
|
| |
status = 200
|
| |
- data, load_status, last_synced, _ = CACHE.async_get_batch('packager-dashboard_pull_requests', packages, 'low')
|
| |
+ data, load_status, cache_ages, _, _ = CACHE.async_get_batch('packager-dashboard_pull_requests', packages, 'low')
|
| |
if load_status in [cache_utils.RefresherNotRegistered, cache_utils.AsyncRefreshInProgress]:
|
| |
status = 202
|
| |
- return {"status": status, "data": data, "last_synced": last_synced}
|
| |
+ return {
|
| |
+ "status": status,
|
| |
+ "data": data,
|
| |
+ "last_synced": min(cache_ages.values(), default=None),
|
| |
+ "cache_ages": cache_ages,
|
| |
+ "static_data_timestamps": {}
|
| |
+ }
|
| |
|
| |
|
| |
def dashboard_data_bzs(packages, authenticated=False):
|
| |
status = 200
|
| |
- data, load_status, last_synced, _ = CACHE.async_get_batch('packager-dashboard_bugs', packages, 'low')
|
| |
+ data, load_status, cache_ages, _, _ = CACHE.async_get_batch('packager-dashboard_bugs', packages, 'low')
|
| |
if load_status in [cache_utils.RefresherNotRegistered, cache_utils.AsyncRefreshInProgress]:
|
| |
status = 202
|
| |
|
| |
if not authenticated:
|
| |
- return {"status": status, "data": data, "last_synced": last_synced}
|
| |
+ return {
|
| |
+ "status": status,
|
| |
+ "data": data,
|
| |
+ "last_synced": min(cache_ages.values(), default=None),
|
| |
+ "cache_ages": cache_ages,
|
| |
+ "static_data_timestamps": {}
|
| |
+ }
|
| |
|
| |
- data_private, load_status, last_synced, _ = CACHE.async_get_batch('packager-dashboard_bugs_private', packages, 'low')
|
| |
+ data_private, load_status, cache_ages, _, _ = CACHE.async_get_batch('packager-dashboard_bugs_private', packages, 'low')
|
| |
if load_status in [cache_utils.RefresherNotRegistered, cache_utils.AsyncRefreshInProgress]:
|
| |
status = 202
|
| |
|
| |
@@ -306,7 +339,13 @@
|
| |
else:
|
| |
data[package] = data_private[package]
|
| |
|
| |
- return {"status": status, "data": data, "last_synced": last_synced}
|
| |
+ return {
|
| |
+ "status": status,
|
| |
+ "data": data,
|
| |
+ "last_synced": min(cache_ages.values(), default=None),
|
| |
+ "cache_ages": cache_ages,
|
| |
+ "static_data_timestamps": {}
|
| |
+ }
|
| |
|
| |
def dashboard_data_generic(packages):
|
| |
"""
|
| |
@@ -315,17 +354,33 @@
|
| |
Returns {"status": 200/500, "data": data <dict> or None, "last_synced": Timestamp of last sync (oldest data)}
|
| |
"""
|
| |
status = 200
|
| |
- data, load_status, last_synced, missed = CACHE.async_get_batch('packager-dashboard_package_static_cache', packages, 'low', False)
|
| |
+ data, load_status, cache_ages, missed, static_data_timestamps = CACHE.async_get_batch(
|
| |
+ 'packager-dashboard_package_static_cache',
|
| |
+ packages,
|
| |
+ 'low',
|
| |
+ False
|
| |
+ )
|
| |
+
|
| |
if load_status in [cache_utils.RefresherNotRegistered, cache_utils.AsyncRefreshInProgress, cache_utils.AsyncDataIncomplete]:
|
| |
try:
|
| |
data_remaining = celery_utils.get_static_package_caches(missed, redis_count=True)
|
| |
data |= data_remaining
|
| |
- last_synced = datetime.utcnow() if missed == set(packages) else last_synced
|
| |
+ current_data_timestamps = celery_utils.get_static_data_timestamps()
|
| |
+ for miss in missed:
|
| |
+ cache_ages[miss] = str(datetime.utcnow())
|
| |
+ static_data_timestamps[miss] = current_data_timestamps
|
| |
except Exception as e:
|
| |
watchdog_utils.push_to_watchdog("sync_failed", "packager-dashboard_package_static_cache", str(e))
|
| |
data = None
|
| |
status = 500
|
| |
- return {"status": status, "data": data, "last_synced": last_synced}
|
| |
+ static_data_timestamps = {}
|
| |
+ return {
|
| |
+ "status": status,
|
| |
+ "data": data,
|
| |
+ "last_synced": min(cache_ages.values(), default=None),
|
| |
+ "cache_ages": cache_ages,
|
| |
+ "static_data_timestamps": static_data_timestamps
|
| |
+ }
|
| |
|
| |
def dashboard_static_data_package_cache(package):
|
| |
# This is just to have something for the packager-dashboard_package_static_cache handle
|
| |
Todo: