partially implement publish_new

This commit is contained in:
Quaternions 2024-12-06 21:00:19 -08:00
parent 2aacb4c87c
commit dac135f624
4 changed files with 65 additions and 12 deletions

View File

@ -64,6 +64,20 @@ pub struct Context{
pub type ReqwestError=reqwest::Error; pub type ReqwestError=reqwest::Error;
// there are lots of action endpoints and they all follow the same pattern
macro_rules! action{
($fname:ident,$action:ident)=>{
pub async fn $fname(&self,config:SubmissionID)->Result<(),Error>{
let url_raw=format!(concat!("{}/submissions/{}/status/",stringify!($action)),self.base_url,config.0);
let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::ParseError)?;
self.patch(url).await.map_err(Error::Reqwest)?
.error_for_status().map_err(Error::Reqwest)?;
Ok(())
}
};
}
impl Context{ impl Context{
pub fn new( pub fn new(
base_url:String, base_url:String,
@ -120,13 +134,6 @@ impl Context{
Ok(()) Ok(())
} }
pub async fn action_submission_validate(&self,config:SubmissionID)->Result<(),Error>{ action!(action_submission_validate,validate);
let url_raw=format!("{}/submissions/{}/status/validate",self.base_url,config.0); action!(action_submission_publish,publish);
let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::ParseError)?;
self.patch(url).await.map_err(Error::Reqwest)?
.error_for_status().map_err(Error::Reqwest)?;
Ok(())
}
} }

View File

@ -17,6 +17,8 @@ impl std::fmt::Display for StartupError{
} }
impl std::error::Error for StartupError{} impl std::error::Error for StartupError{}
pub const GROUP_STRAFESNET:u64=6980477;
#[tokio::main] #[tokio::main]
async fn main()->Result<(),StartupError>{ async fn main()->Result<(),StartupError>{
// talk to roblox // talk to roblox
@ -30,7 +32,7 @@ async fn main()->Result<(),StartupError>{
// connect to nats // connect to nats
let (publish_new,publish_fix,validator)=tokio::try_join!( let (publish_new,publish_fix,validator)=tokio::try_join!(
publish_new::Publisher::new(nasty.clone(),cookie_context.clone()), publish_new::Publisher::new(nasty.clone(),cookie_context.clone(),api.clone()),
publish_fix::Publisher::new(nasty.clone(),cookie_context.clone()), publish_fix::Publisher::new(nasty.clone(),cookie_context.clone()),
// clone nats here because it's dropped within the function scope, // clone nats here because it's dropped within the function scope,
// meanining the last reference is dropped... // meanining the last reference is dropped...

View File

@ -14,6 +14,7 @@ pub struct ValidateRequest{
} }
// Create a new map // Create a new map
#[derive(serde::Deserialize)]
pub struct PublishNewRequest{ pub struct PublishNewRequest{
pub submission_id:i64, pub submission_id:i64,
pub model_id:u64, pub model_id:u64,
@ -23,6 +24,7 @@ pub struct PublishNewRequest{
//games:HashSet<GameID>, //games:HashSet<GameID>,
} }
#[derive(serde::Deserialize)]
pub struct PublishFixRequest{ pub struct PublishFixRequest{
pub submission_id:i64, pub submission_id:i64,
pub model_id:u64, pub model_id:u64,

View File

@ -1,7 +1,13 @@
use futures::StreamExt; use futures::StreamExt;
use crate::nats_types::PublishNewRequest;
#[derive(Debug)] #[derive(Debug)]
enum PublishError{ enum PublishError{
Get(rbx_asset::cookie::GetError),
Json(serde_json::Error),
Create(rbx_asset::cookie::CreateError),
ApiActionSubmissionPublish(api::Error),
} }
impl std::fmt::Display for PublishError{ impl std::fmt::Display for PublishError{
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{ fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
@ -13,23 +19,59 @@ impl std::error::Error for PublishError{}
pub struct Publisher{ pub struct Publisher{
subscriber:async_nats::Subscriber, subscriber:async_nats::Subscriber,
roblox_cookie:rbx_asset::cookie::CookieContext, roblox_cookie:rbx_asset::cookie::CookieContext,
api:api::Context,
} }
impl Publisher{ impl Publisher{
pub async fn new( pub async fn new(
nats:async_nats::Client, nats:async_nats::Client,
roblox_cookie:rbx_asset::cookie::CookieContext, roblox_cookie:rbx_asset::cookie::CookieContext,
api:api::Context,
)->Result<Self,async_nats::SubscribeError>{ )->Result<Self,async_nats::SubscribeError>{
Ok(Self{ Ok(Self{
subscriber:nats.subscribe("publish_new").await?, subscriber:nats.subscribe("publish_new").await?,
roblox_cookie, roblox_cookie,
api,
}) })
} }
pub async fn run(mut self){ pub async fn run(mut self){
while let Some(message)=self.subscriber.next().await{ while let Some(message)=self.subscriber.next().await{
self.publish(message).await self.publish_supress_error(message).await
} }
} }
async fn publish(&self,message:async_nats::Message){ async fn publish_supress_error(&self,message:async_nats::Message){
match self.publish(message).await{
Ok(())=>println!("Published, hooray!"),
Err(e)=>println!("[PublishNew] There was an error, oopsie! {e}"),
}
}
async fn publish(&self,message:async_nats::Message)->Result<(),PublishError>{
println!("publish {:?}",message); println!("publish {:?}",message);
// decode json
let publish_info:PublishNewRequest=serde_json::from_slice(&message.payload).map_err(PublishError::Json)?;
// download the map model version
let model_data=self.roblox_cookie.get_asset(rbx_asset::cookie::GetAssetRequest{
asset_id:publish_info.model_id,
version:Some(publish_info.model_version),
}).await.map_err(PublishError::Get)?;
// upload the map to the strafesnet group
let upload_response=self.roblox_cookie.create(rbx_asset::cookie::CreateRequest{
name:publish_info.display_name,
description:"".to_owned(),
ispublic:false,
allowComments:false,
groupId:Some(crate::GROUP_STRAFESNET),
},model_data).await.map_err(PublishError::Create)?;
// create the map entry in the game database, including release date
// game_rpc.maps.create(upload_response.AssetId)
// mark submission as published
self.api.action_submission_publish(
api::SubmissionID(publish_info.submission_id)
).await.map_err(PublishError::ApiActionSubmissionPublish)?;
Ok(())
} }
} }