diff --git a/src/instance_info.rs b/src/instance_info.rs
index c05ce5c..5f82ce6 100644
--- a/src/instance_info.rs
+++ b/src/instance_info.rs
@@ -85,7 +85,7 @@ fn info_html(req: &Request
) -> Result, Error> {
pub struct InstanceInfo {
package_name: String,
crate_version: String,
- git_commit: String,
+ pub git_commit: String,
deploy_date: String,
compile_mode: String,
deploy_unix_ts: i64,
diff --git a/src/main.rs b/src/main.rs
index 556cf57..4923921 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -2,15 +2,16 @@
#![forbid(unsafe_code)]
#![allow(clippy::cmp_owned)]
-// Import Crates
+use cached::proc_macro::cached;
use clap::{Arg, ArgAction, Command};
+use std::str::FromStr;
use futures_lite::FutureExt;
+use hyper::Uri;
use hyper::{header::HeaderValue, Body, Request, Response};
-
use log::info;
use once_cell::sync::Lazy;
-use redlib::client::{canonical_path, proxy};
+use redlib::client::{canonical_path, proxy, CLIENT};
use redlib::server::{self, RequestExt};
use redlib::utils::{error, redirect, ThemeAssets};
use redlib::{config, duplicates, headers, instance_info, post, search, settings, subreddit, user};
@@ -217,6 +218,11 @@ async fn main() {
app
.at("/highlighted.js")
.get(|_| resource(include_str!("../static/highlighted.js"), "text/javascript", false).boxed());
+ app
+ .at("/check_update.js")
+ .get(|_| resource(include_str!("../static/check_update.js"), "text/javascript", false).boxed());
+
+ app.at("/commits.atom").get(|_| async move { proxy_commit_info().await }.boxed());
// Proxy media through Redlib
app.at("/vid/:id/:size").get(|r| proxy(r, "https://v.redd.it/{id}/DASH_{size}").boxed());
@@ -374,3 +380,22 @@ async fn main() {
eprintln!("Server error: {e}");
}
}
+
+pub async fn proxy_commit_info() -> Result, String> {
+ Ok(
+ Response::builder()
+ .status(200)
+ .header("content-type", "application/atom+xml")
+ .body(Body::from(fetch_commit_info().await))
+ .unwrap_or_default(),
+ )
+}
+
+#[cached(time = 600)]
+async fn fetch_commit_info() -> String {
+ let uri = Uri::from_str("https://github.com/redlib-org/redlib/commits/main.atom").expect("Invalid URI");
+
+ let resp: Body = CLIENT.get(uri).await.expect("Failed to request GitHub").into_body();
+
+ hyper::body::to_bytes(resp).await.expect("Failed to read body").iter().copied().map(|x| x as char).collect()
+}
diff --git a/static/check_update.js b/static/check_update.js
new file mode 100644
index 0000000..7741edb
--- /dev/null
+++ b/static/check_update.js
@@ -0,0 +1,38 @@
+async function checkInstanceUpdateStatus() {
+ try {
+ const response = await fetch('/commits.atom');
+ const text = await response.text();
+ const parser = new DOMParser();
+ const xmlDoc = parser.parseFromString(text, "application/xml");
+ const entries = xmlDoc.getElementsByTagName('entry');
+ const localCommit = document.getElementById('git_commit').dataset.value;
+
+ let statusMessage = '';
+
+ if (entries.length > 0) {
+ const commitHashes = Array.from(entries).map(entry => {
+ const id = entry.getElementsByTagName('id')[0].textContent;
+ return id.split('/').pop();
+ });
+
+ const commitIndex = commitHashes.indexOf(localCommit);
+
+ if (commitIndex === 0) {
+ statusMessage = '✅ Instance is up to date.';
+ } else if (commitIndex > 0) {
+ statusMessage = `⚠️ This instance is not up to date and is ${commitIndex} commits old. Test and confirm on an up-to-date instance before reporting.`;
+ } else {
+ statusMessage = `⚠️ This instance is not up to date and is at least ${commitHashes.length} commits old. Test and confirm on an up-to-date instance before reporting.`;
+ }
+ } else {
+ statusMessage = '⚠️ Unable to fetch commit information.';
+ }
+
+ document.getElementById('update-status').innerText = statusMessage;
+ } catch (error) {
+ console.error('Error fetching commits:', error);
+ document.getElementById('update-status').innerText = '⚠️ Error checking update status.';
+ }
+}
+
+checkInstanceUpdateStatus();
diff --git a/templates/error.html b/templates/error.html
index e831200..f7a2d5d 100644
--- a/templates/error.html
+++ b/templates/error.html
@@ -6,10 +6,15 @@
{{ msg }}
+
+
+
+
+
Head back home?
-{% endblock %}
\ No newline at end of file
+{% endblock %}