This commit is contained in:
parent
9e9f77b174
commit
52e4cd2f23
1185
Cargo.lock
generated
1185
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
14
Cargo.toml
14
Cargo.toml
@ -22,16 +22,4 @@ rand = "0.10.2"
|
|||||||
serde = { version = "1.0.229", features = ["serde_derive"] }
|
serde = { version = "1.0.229", features = ["serde_derive"] }
|
||||||
serde_json = "1.0.151"
|
serde_json = "1.0.151"
|
||||||
roux = "2.2.15"
|
roux = "2.2.15"
|
||||||
structstruck = "0.5.0"
|
structstruck = "0.5.1"
|
||||||
reqwest = { version = "0.13.4", features = ["json"] }
|
|
||||||
octocrab = { version = "0.49.5", optional = true }
|
|
||||||
tempfile = { version = "3.20.0", optional = true }
|
|
||||||
self-replace = { version = "1.5.0", optional = true }
|
|
||||||
zip = { version = "7.2.0", optional = true }
|
|
||||||
nix = { version = "0.31.1", features = ["process"], optional = true }
|
|
||||||
minreq = { version = "2.14.0", features = ["https"], optional = true }
|
|
||||||
url = "2.5.8"
|
|
||||||
|
|
||||||
|
|
||||||
[features]
|
|
||||||
self-update=["octocrab", "tempfile", "self-replace", "zip", "nix", "minreq"]
|
|
||||||
|
|||||||
@ -1,9 +1,3 @@
|
|||||||
#[cfg(feature = "self-update")]
|
|
||||||
use {
|
|
||||||
minreq, octocrab, self_replace, std::convert::Infallible, std::io::Write,
|
|
||||||
std::os::unix::process::CommandExt, zip,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::Context;
|
use crate::Context;
|
||||||
use crate::Error;
|
use crate::Error;
|
||||||
|
|
||||||
@ -37,50 +31,6 @@ pub async fn version(ctx: Context<'_>) -> Result<(), Error> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "self-update")]
|
|
||||||
/// Update the bot remotely (requires Github CI)
|
|
||||||
#[poise::command(slash_command, owners_only, hide_in_help)]
|
|
||||||
pub async fn update(
|
|
||||||
ctx: Context<'_>,
|
|
||||||
#[description = "Whether to skip the update check"] override_check: bool,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
ctx.defer().await?;
|
|
||||||
// Check if the current commit hash is different from HEAD
|
|
||||||
let head: octocrab::models::repos::Ref = octocrab::instance()
|
|
||||||
.get(
|
|
||||||
"/repos/shibedrill/shibe-bot/git/refs/heads/main",
|
|
||||||
None::<&octocrab::models::Repository>,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
if let octocrab::models::repos::Object::Commit { sha, url: _ } = head.object {
|
|
||||||
if sha == env!("GIT_COMMIT_ID") {
|
|
||||||
if override_check {
|
|
||||||
info!("Update unnecessary, but check overridden.");
|
|
||||||
ctx.say("Update unecessary, but check overridden. Updating.")
|
|
||||||
.await?;
|
|
||||||
let Err(what) = self_update();
|
|
||||||
error!("Update failed: {}", what);
|
|
||||||
ctx.say(format!("Error occurred while updating: {}", what))
|
|
||||||
.await?;
|
|
||||||
} else {
|
|
||||||
info!("Update unnecessary: Commit ID of remote is same as compiled commit.");
|
|
||||||
ctx.say("Update unnecessary.").await?;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
info!("Update required, latest commit hash: {}", sha);
|
|
||||||
let Err(what) = self_update();
|
|
||||||
error!("Update failed: {}", what);
|
|
||||||
ctx.say(format!("Error occurred while updating: {}", what))
|
|
||||||
.await?;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ctx.say("Update failed: Object field in response is not a Commit.")
|
|
||||||
.await?;
|
|
||||||
error!("Checking for updates failed: Response field incorrect type");
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Shut down the bot remotely
|
/// Shut down the bot remotely
|
||||||
#[poise::command(slash_command, owners_only, hide_in_help)]
|
#[poise::command(slash_command, owners_only, hide_in_help)]
|
||||||
pub async fn shutdown(ctx: Context<'_>) -> Result<(), Error> {
|
pub async fn shutdown(ctx: Context<'_>) -> Result<(), Error> {
|
||||||
@ -116,69 +66,3 @@ pub async fn say(
|
|||||||
ctx.say(what).await?;
|
ctx.say(what).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "self-update")]
|
|
||||||
fn self_update() -> Result<Infallible, Error> {
|
|
||||||
let artifact_url = "https://nightly.link/shibedrill/shibe-bot/workflows/rust/main/artifact.zip";
|
|
||||||
let tempdir = tempfile::Builder::new().prefix("shibe-bot").tempdir()?;
|
|
||||||
trace!("Created tempdir successfully: {}", tempdir.path().display());
|
|
||||||
let response = minreq::get(artifact_url).send()?;
|
|
||||||
|
|
||||||
let mut dest = std::fs::File::create_new(tempdir.path().join("artifact.zip"))?;
|
|
||||||
let content = response.as_bytes();
|
|
||||||
dest.write_all(content)?;
|
|
||||||
trace!("Downloaded latest build artifact successfully");
|
|
||||||
|
|
||||||
let mut archive = zip::ZipArchive::new(dest)?;
|
|
||||||
trace!("Created zip archive reader");
|
|
||||||
let mut zipped_bin = archive.by_index(0)?;
|
|
||||||
let new_bin_path = tempdir.path().join("shibe-bot");
|
|
||||||
let mut new_bin = std::fs::File::create_new(&new_bin_path)?;
|
|
||||||
trace!("Created new file for binary");
|
|
||||||
|
|
||||||
std::io::copy(&mut zipped_bin, &mut new_bin)?;
|
|
||||||
trace!("Extracted binary successfully");
|
|
||||||
|
|
||||||
let new_command_path = std::env::current_exe()?;
|
|
||||||
|
|
||||||
trace!("Testing file prior to replace");
|
|
||||||
{
|
|
||||||
let _ = std::fs::File::open(&new_command_path)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
self_replace::self_replace(&new_bin_path)?;
|
|
||||||
trace!("Replaced self with new binary successfully");
|
|
||||||
|
|
||||||
trace!("Testing file after replace");
|
|
||||||
{
|
|
||||||
let _ = std::fs::File::open(&new_command_path)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
//let new_command_args: Vec<_> = std::env::args_os().skip(1).collect();
|
|
||||||
trace!(
|
|
||||||
"Got current executable path successfully: {}",
|
|
||||||
new_command_path.display()
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut command = std::process::Command::new("systemctl");
|
|
||||||
|
|
||||||
let command = command.arg("--user").arg("restart").arg("shibe-bot");
|
|
||||||
|
|
||||||
Err(Box::new(command.exec()))
|
|
||||||
}
|
|
||||||
|
|
||||||
mod test {
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
#[cfg(feature = "self-update")]
|
|
||||||
use {crate::Error, std::convert::Infallible};
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[cfg(feature = "self-update")]
|
|
||||||
fn test_self_update() -> Result<Infallible, Error> {
|
|
||||||
use crate::command::devel::self_update;
|
|
||||||
use pretty_env_logger;
|
|
||||||
pretty_env_logger::init();
|
|
||||||
self_update()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -163,7 +163,10 @@ pub async fn deer(ctx: Context<'_>) -> Result<(), Error> {
|
|||||||
let subreddit = Subreddit::new("deer");
|
let subreddit = Subreddit::new("deer");
|
||||||
let options = FeedOption::new().period(TimePeriod::ThisYear);
|
let options = FeedOption::new().period(TimePeriod::ThisYear);
|
||||||
trace!("Created subreddit and options, about to poll for hot posts...");
|
trace!("Created subreddit and options, about to poll for hot posts...");
|
||||||
let hot = subreddit.hot(50, Some(options)).await.inspect_err(|e| {error!("Error getting hot posts: {:#?}", e)})?;
|
let hot = subreddit
|
||||||
|
.hot(50, Some(options))
|
||||||
|
.await
|
||||||
|
.inspect_err(|e| error!("Error getting hot posts: {:#?}", e))?;
|
||||||
trace!("Got hot post collection...");
|
trace!("Got hot post collection...");
|
||||||
let chosen_post = {
|
let chosen_post = {
|
||||||
let mut rng = rand::rng();
|
let mut rng = rand::rng();
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
use poise::serenity_prelude as serenity;
|
use poise::serenity_prelude as serenity;
|
||||||
|
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
|
|||||||
@ -92,8 +92,6 @@ async fn main() {
|
|||||||
shutdown(),
|
shutdown(),
|
||||||
restart(),
|
restart(),
|
||||||
say(),
|
say(),
|
||||||
#[cfg(feature = "self-update")]
|
|
||||||
update(),
|
|
||||||
version(),
|
version(),
|
||||||
// Fun
|
// Fun
|
||||||
meow(),
|
meow(),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user