partially made /bk_week_add command
This commit is contained in:
@@ -11,6 +11,7 @@ futures = "0.3.31"
|
|||||||
poise = "0.6.1"
|
poise = "0.6.1"
|
||||||
pyo3 = "0.23.4"
|
pyo3 = "0.23.4"
|
||||||
rand = "0.9.0"
|
rand = "0.9.0"
|
||||||
|
regex = "1.11.1"
|
||||||
serde = "1.0.217"
|
serde = "1.0.217"
|
||||||
serde_json = "1.0.138"
|
serde_json = "1.0.138"
|
||||||
tokio = { version = "1.43.0", features = ["rt-multi-thread"] }
|
tokio = { version = "1.43.0", features = ["rt-multi-thread"] }
|
||||||
|
|||||||
+46
-14
@@ -1,11 +1,11 @@
|
|||||||
use crate::{rs_println, Context, Error};
|
use crate::{rs_println, websocket, Context, Error};
|
||||||
use crate::messages::{send_embed, send_msg, EmbedOptions};
|
use crate::messages::{send_embed, send_msg, EmbedOptions};
|
||||||
use crate::data;
|
use crate::data;
|
||||||
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
|
||||||
use poise::serenity_prelude::Timestamp;
|
use poise::serenity_prelude::Timestamp;
|
||||||
use serde_json::Value;
|
use serde_json::{json, Value};
|
||||||
|
|
||||||
|
|
||||||
#[poise::command(slash_command, prefix_command)]
|
#[poise::command(slash_command, prefix_command)]
|
||||||
@@ -53,6 +53,7 @@ async fn get_post_from_data(ctx: Context<'_>, reddit_data: &Value, url: &str) ->
|
|||||||
if let Some(post) = bk_week.get(url) {
|
if let Some(post) = bk_week.get(url) {
|
||||||
if post.get("removed").is_some() {
|
if post.get("removed").is_some() {
|
||||||
send_post_removed_message(ctx, url).await;
|
send_post_removed_message(ctx, url).await;
|
||||||
|
return Ok(None);
|
||||||
}
|
}
|
||||||
return Ok(Some(post.clone()));
|
return Ok(Some(post.clone()));
|
||||||
}
|
}
|
||||||
@@ -71,18 +72,18 @@ async fn get_post_from_data(ctx: Context<'_>, reddit_data: &Value, url: &str) ->
|
|||||||
async fn send_embed_for_post(ctx: Context<'_>, post: Value, url: &str) -> Result<(), Error> {
|
async fn send_embed_for_post(ctx: Context<'_>, post: Value, url: &str) -> Result<(), Error> {
|
||||||
let embed_options = EmbedOptions {
|
let embed_options = EmbedOptions {
|
||||||
desc: format!(
|
desc: format!(
|
||||||
r#"**Spoilers for fair review!**
|
r#"**Spoilers and vote length anonymizer for fair review!**
|
||||||
Upvotes: ||`{}`||
|
Upvotes: ||`{:>6}`||
|
||||||
URL: ||<{}>||
|
URL: ||<{}>||
|
||||||
Added by human: `{}`
|
Added by human: {}
|
||||||
Added by bot: `{}`
|
Added by bot: {}
|
||||||
Approved by human: `{}`
|
Approved by human: {}
|
||||||
Approved by bot: `[not implemented]`"#,
|
Approved by bot: `[not implemented]`"#,
|
||||||
post["post_data"]["upvotes"],
|
post["post_data"]["upvotes"].as_i64().unwrap(),
|
||||||
url,
|
url,
|
||||||
post["added"]["by_human"],
|
if post["added"] ["by_human"].as_bool().unwrap() { "✅" } else { "❌" },
|
||||||
post["added"]["by_bot"],
|
if post["added"] ["by_bot"].as_bool().unwrap() { "✅" } else { "❌" },
|
||||||
post["approved"]["by_human"]
|
if post["approved"]["by_human"].as_bool().unwrap() { "✅" } else { "❌" }
|
||||||
).trim().to_string(),
|
).trim().to_string(),
|
||||||
title: Some(post["post_data"]["title"].as_str().unwrap().to_string()),
|
title: Some(post["post_data"]["title"].as_str().unwrap().to_string()),
|
||||||
url: Some(url.to_string()),
|
url: Some(url.to_string()),
|
||||||
@@ -143,16 +144,43 @@ async fn send_data_corrupted_message(ctx: Context<'_>, url: &str) {
|
|||||||
#[poise::command(slash_command, prefix_command)]
|
#[poise::command(slash_command, prefix_command)]
|
||||||
pub async fn bk_week_add(
|
pub async fn bk_week_add(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
#[description = "The post URL"] url: Option<String>,
|
#[description = "The post URL"] url: String,
|
||||||
#[description = "Wether to approve it after adding it"] approve: Option<bool>
|
#[description = "Wether to approve it after adding it"] approve: Option<bool>
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
{
|
{
|
||||||
// update data
|
// TODO: auto approve
|
||||||
// use python_comms.rs to tell python to update its data
|
data::update_re_data(ctx.data()).await;
|
||||||
|
let reddit_data = get_reddit_data(ctx).await.unwrap();
|
||||||
|
|
||||||
|
if let Some(bk_week) = reddit_data.get("bk_weekly_art_posts") {
|
||||||
|
websocket::send_cmd_json("add_post_url", json!([&url])).await;
|
||||||
|
|
||||||
|
if let Some(post) = bk_week.get(&url) {
|
||||||
|
if post.get("removed").is_some() {
|
||||||
|
send_unremove_msg(ctx, &url).await;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
send_updated_msg(ctx, &url).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async fn send_unremove_msg(ctx: Context<'_>, url: &str) {
|
||||||
|
send_msg(ctx, format!("Un-removed post with URL \"{}\"!", url), true, true).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async fn send_updated_msg(ctx: Context<'_>, url: &str) {
|
||||||
|
send_msg(ctx, format!("Updated post with URL \"{}\"!", url), true, true).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[poise::command(slash_command, prefix_command)]
|
#[poise::command(slash_command, prefix_command)]
|
||||||
pub async fn bk_week_remove(
|
pub async fn bk_week_remove(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
@@ -165,6 +193,8 @@ pub async fn bk_week_remove(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[poise::command(slash_command, prefix_command)]
|
#[poise::command(slash_command, prefix_command)]
|
||||||
pub async fn bk_week_approve(
|
pub async fn bk_week_approve(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
@@ -177,6 +207,8 @@ pub async fn bk_week_approve(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[poise::command(slash_command, prefix_command)]
|
#[poise::command(slash_command, prefix_command)]
|
||||||
pub async fn bk_week_disapprove(
|
pub async fn bk_week_disapprove(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
|
|||||||
+22
@@ -5,6 +5,7 @@ use crate::messages::{send_embed, send_msg, edit_msg, EmbedOptions};
|
|||||||
|
|
||||||
use poise::serenity_prelude::{GetMessages, OnlineStatus, Timestamp, UserId};
|
use poise::serenity_prelude::{GetMessages, OnlineStatus, Timestamp, UserId};
|
||||||
use rand::{seq::IteratorRandom, Rng};
|
use rand::{seq::IteratorRandom, Rng};
|
||||||
|
use regex::Regex;
|
||||||
|
|
||||||
|
|
||||||
#[poise::command(slash_command, prefix_command)]
|
#[poise::command(slash_command, prefix_command)]
|
||||||
@@ -185,6 +186,27 @@ pub async fn write_json(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[poise::command(slash_command, prefix_command)]
|
||||||
|
pub async fn re_shorturl(
|
||||||
|
ctx: Context<'_>,
|
||||||
|
#[description = "A Reddit post URL"] url: String
|
||||||
|
) -> Result<(), Error>
|
||||||
|
{
|
||||||
|
let re = Regex::new(r"comments/([a-zA-Z0-9]+)").unwrap();
|
||||||
|
|
||||||
|
if let Some(caps) = re.captures(&url) {
|
||||||
|
let post_id = &caps[1];
|
||||||
|
let short_url = format!("https://redd.it/{}", post_id);
|
||||||
|
send_msg(ctx, format!("ShortURL: <{}>", short_url), true, true).await;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
println!("Post ID not found in the URL");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* async fn autocomplete_rule_list(_: Context<'_>, _partial: &str) -> Vec<String> {
|
/* async fn autocomplete_rule_list(_: Context<'_>, _partial: &str) -> Vec<String> {
|
||||||
let json_str = std::fs::read_to_string("./data/write_json.json")
|
let json_str = std::fs::read_to_string("./data/write_json.json")
|
||||||
.expect("No JSON preset file exists.");
|
.expect("No JSON preset file exists.");
|
||||||
|
|||||||
+3
-1
@@ -136,9 +136,11 @@ async fn gen_bot(data: Data) -> Client {
|
|||||||
cmds::stop(),
|
cmds::stop(),
|
||||||
cmds::eight_ball(),
|
cmds::eight_ball(),
|
||||||
cmds::write_json(),
|
cmds::write_json(),
|
||||||
|
cmds::re_shorturl(),
|
||||||
//cmds::rule(),
|
//cmds::rule(),
|
||||||
bk_week_cmds::bk_week_help(),
|
bk_week_cmds::bk_week_help(),
|
||||||
bk_week_cmds::bk_week_get()
|
bk_week_cmds::bk_week_get(),
|
||||||
|
bk_week_cmds::bk_week_add()
|
||||||
],
|
],
|
||||||
event_handler: events::event_handler,
|
event_handler: events::event_handler,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|||||||
+8
-2
@@ -85,13 +85,19 @@ def read_data(bot: botPy.Bot):
|
|||||||
raise Exception("reddit_data.json file wasn't created properly. Delete the file and retry.")
|
raise Exception("reddit_data.json file wasn't created properly. Delete the file and retry.")
|
||||||
|
|
||||||
|
|
||||||
def write_data(bot: botPy.Bot):
|
def write_data(bot: botPy.Bot) -> bool:
|
||||||
bot.data_f.seek(0)
|
bot.data_f.seek(0)
|
||||||
json.dump(bot.data, bot.data_f, indent=2)
|
json.dump(bot.data, bot.data_f, indent=2)
|
||||||
bot.data_f.truncate()
|
bot.data_f.truncate()
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def add_post_to_data(bot: botPy.Bot, new_data: PostData) -> bool:
|
def add_post_to_data(bot: botPy.Bot, new_data: PostData, bypass_conditions: bool = False) -> bool:
|
||||||
|
if bypass_conditions:
|
||||||
|
bot.data[BK_WEEKLY][new_data.url] = new_data.to_json()
|
||||||
|
py_print(f"Added post \"{new_data.url}\" (Conditions bypassed)")
|
||||||
|
return True
|
||||||
|
|
||||||
if new_data.url not in bot.data[BK_WEEKLY]:
|
if new_data.url not in bot.data[BK_WEEKLY]:
|
||||||
bot.data[BK_WEEKLY][new_data.url] = new_data.to_json()
|
bot.data[BK_WEEKLY][new_data.url] = new_data.to_json()
|
||||||
py_print(f"Added post \"{new_data.url}\"")
|
py_print(f"Added post \"{new_data.url}\"")
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ from macros import *
|
|||||||
import bot as botPy
|
import bot as botPy
|
||||||
import data
|
import data
|
||||||
import py_websocket
|
import py_websocket
|
||||||
import posts
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|||||||
+83
-13
@@ -1,15 +1,17 @@
|
|||||||
import emoji
|
import emoji
|
||||||
import reddit
|
from praw import models
|
||||||
|
|
||||||
import data
|
import data
|
||||||
import bot as botPy
|
import bot as botPy
|
||||||
from macros import *
|
from macros import *
|
||||||
|
|
||||||
|
|
||||||
def add_new_posts(bot: botPy.Bot):
|
def add_new_posts(bot: botPy.Bot):
|
||||||
check_emoji = emoji.emojize(":check_mark_button:")
|
check_emoji = emoji.emojize(":check_mark_button:")
|
||||||
cross_emoji = emoji.emojize(":cross_mark:")
|
cross_emoji = emoji.emojize(":cross_mark:")
|
||||||
|
|
||||||
py_print("Fetching posts...")
|
py_print("Fetching posts...")
|
||||||
posts = reddit.fetch_posts_with_flair(bot, "Original Art")
|
posts = fetch_posts_with_flair(bot, "Original Art")
|
||||||
|
|
||||||
py_print("Evaluating posts...")
|
py_print("Evaluating posts...")
|
||||||
|
|
||||||
@@ -17,11 +19,12 @@ def add_new_posts(bot: botPy.Bot):
|
|||||||
without_media = 0
|
without_media = 0
|
||||||
not_added = 0
|
not_added = 0
|
||||||
for post in posts:
|
for post in posts:
|
||||||
media = reddit.has_media(post)
|
media = has_media(post)
|
||||||
|
|
||||||
media_urls = "\n ".join(media[3])
|
media_urls = "\n ".join(media[3])
|
||||||
|
|
||||||
if bot.args["dev"]: py_print(
|
if bot.args["dev"]:
|
||||||
|
py_print(
|
||||||
f"\n{post.title}",
|
f"\n{post.title}",
|
||||||
f"\n {post.shortlink}"
|
f"\n {post.shortlink}"
|
||||||
f"\n {check_emoji if media[0] else cross_emoji} Media ({media[1]}) [{media[2]}]",
|
f"\n {check_emoji if media[0] else cross_emoji} Media ({media[1]}) [{media[2]}]",
|
||||||
@@ -34,15 +37,7 @@ def add_new_posts(bot: botPy.Bot):
|
|||||||
|
|
||||||
post_added = data.add_post_to_data(
|
post_added = data.add_post_to_data(
|
||||||
bot,
|
bot,
|
||||||
data.PostData(
|
get_post_details(post)
|
||||||
post.shortlink,
|
|
||||||
post.title,
|
|
||||||
post.score,
|
|
||||||
int(post.created_utc),
|
|
||||||
media[1],
|
|
||||||
media[3],
|
|
||||||
added_by_bot = True,
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if post_added: added_posts += 1
|
if post_added: added_posts += 1
|
||||||
@@ -54,3 +49,78 @@ def add_new_posts(bot: botPy.Bot):
|
|||||||
f"and {not_added} weren't added because they are removed or already existed")
|
f"and {not_added} weren't added because they are removed or already existed")
|
||||||
|
|
||||||
data.write_data(bot)
|
data.write_data(bot)
|
||||||
|
|
||||||
|
|
||||||
|
def fetch_posts_with_flair(bot: botPy.Bot, flair_name: str) -> list[models.Submission]:
|
||||||
|
posts: list[models.Submission] = []
|
||||||
|
|
||||||
|
# ~36 OG-art posts per week, round limit to 50, 75 or 100
|
||||||
|
for post in bot.sr.search(f"flair:\"{flair_name}\"", sort="new", limit=10):
|
||||||
|
posts.append(post)
|
||||||
|
|
||||||
|
return posts
|
||||||
|
|
||||||
|
|
||||||
|
def has_media(post: models.Submission) -> tuple[bool, str, int, list[str]]:
|
||||||
|
media_type: str = None
|
||||||
|
media_count = 0
|
||||||
|
media_urls: list[str] = []
|
||||||
|
|
||||||
|
if hasattr(post, "post_hint"):
|
||||||
|
media_type = post.post_hint
|
||||||
|
media_count = 1
|
||||||
|
media_urls.append(post.url)
|
||||||
|
|
||||||
|
elif getattr(post, "is_gallery", False):
|
||||||
|
if not post.is_gallery: pass
|
||||||
|
media_type = "multiple"
|
||||||
|
|
||||||
|
gallery_items = getattr(post, "gallery_data", {}).get("items", [])
|
||||||
|
media_metadata = getattr(post, "media_metadata", {})
|
||||||
|
|
||||||
|
media_count = len(gallery_items)
|
||||||
|
|
||||||
|
for item in gallery_items:
|
||||||
|
media_id = item.get("media_id")
|
||||||
|
image_url = media_metadata.get(media_id, {}).get("s", {}).get("u")
|
||||||
|
|
||||||
|
if image_url:
|
||||||
|
media_urls.append(image_url)
|
||||||
|
|
||||||
|
|
||||||
|
return (media_type != None, media_type, media_count, media_urls)
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: convert to asyncpraw because praw wont SHUT THE FUCK UP
|
||||||
|
# Gosh i gotta handle so much pain dont i?
|
||||||
|
def from_url(bot: botPy.Bot, url: str) -> tuple[bool, models.Submission]:
|
||||||
|
post = bot.r.submission(url=url)
|
||||||
|
|
||||||
|
if hasattr(post, "id"):
|
||||||
|
return True, post
|
||||||
|
else:
|
||||||
|
return False, None
|
||||||
|
|
||||||
|
|
||||||
|
def get_post_details(post: models.Submission):
|
||||||
|
media = has_media(post)
|
||||||
|
|
||||||
|
return data.PostData(
|
||||||
|
post.shortlink,
|
||||||
|
post.title,
|
||||||
|
post.score,
|
||||||
|
int(post.created_utc),
|
||||||
|
media[1],
|
||||||
|
media[3],
|
||||||
|
added_by_bot = True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def add_post_url(bot, url: str) -> bool:
|
||||||
|
result, post = from_url(bot, url)
|
||||||
|
|
||||||
|
if not result:
|
||||||
|
return result
|
||||||
|
|
||||||
|
post_data = get_post_details(post)
|
||||||
|
data.add_post_to_data(bot, post_data, True)
|
||||||
@@ -5,6 +5,7 @@ import json
|
|||||||
from macros import py_print
|
from macros import py_print
|
||||||
import bot as botPy
|
import bot as botPy
|
||||||
import data
|
import data
|
||||||
|
import posts
|
||||||
|
|
||||||
ws_global = None
|
ws_global = None
|
||||||
is_connected = False
|
is_connected = False
|
||||||
@@ -25,15 +26,17 @@ async def websocket_client(bot: botPy.Bot):
|
|||||||
while True:
|
while True:
|
||||||
response = await ws.recv()
|
response = await ws.recv()
|
||||||
py_print(f"Received from Rust: {response}")
|
py_print(f"Received from Rust: {response}")
|
||||||
parse_json(response, bot)
|
await parse_json(response, bot)
|
||||||
|
|
||||||
|
|
||||||
def parse_json(response: str, bot: botPy.Bot):
|
async def parse_json(response: str, bot: botPy.Bot):
|
||||||
if response.startswith("json:"):
|
if response.startswith("json:"):
|
||||||
json_str = response[5:]
|
json_str = response[5:]
|
||||||
try:
|
try:
|
||||||
json_response = json.loads(json_str)
|
json_response = json.loads(json_str)
|
||||||
json_to_func(json_response, bot)
|
result = await json_to_func(json_response, bot)
|
||||||
|
await ws_global.ping()
|
||||||
|
await send_message(f"json:{json.dumps(result)}")
|
||||||
except json.JSONDecodeError as e:
|
except json.JSONDecodeError as e:
|
||||||
if bot.args["dev"]: py_print(f"failed to parse json: {json_str}\n reason: {e}")
|
if bot.args["dev"]: py_print(f"failed to parse json: {json_str}\n reason: {e}")
|
||||||
|
|
||||||
@@ -44,7 +47,7 @@ def run_thread(bot: botPy.Bot):
|
|||||||
loop.run_until_complete(websocket_client(bot))
|
loop.run_until_complete(websocket_client(bot))
|
||||||
|
|
||||||
|
|
||||||
def json_to_func(v: dict, bot: botPy.Bot):
|
async def json_to_func(v: dict, bot: botPy.Bot) -> dict:
|
||||||
if "type" not in v or "value" not in v or not isinstance(v, dict):
|
if "type" not in v or "value" not in v or not isinstance(v, dict):
|
||||||
if bot.args["dev"]: py_print("JSON is not a dictionary or does not include \"type\" and \"value\" keys.")
|
if bot.args["dev"]: py_print("JSON is not a dictionary or does not include \"type\" and \"value\" keys.")
|
||||||
return
|
return
|
||||||
@@ -53,9 +56,14 @@ def json_to_func(v: dict, bot: botPy.Bot):
|
|||||||
return
|
return
|
||||||
|
|
||||||
value_supported = True
|
value_supported = True
|
||||||
|
result = {"type": "result", "value": False}
|
||||||
|
|
||||||
match v["value"]:
|
match v["value"]:
|
||||||
case "update_data_file": data.write_data(bot)
|
case "update_data_file": result = {"type": "result", "value": data.write_data(bot)}
|
||||||
|
case "add_post_url": result = {"type": "result", "value": await posts.add_post_url(bot, *v["args"])}
|
||||||
case _: value_supported = False
|
case _: value_supported = False
|
||||||
|
|
||||||
if bot.args["dev"] and not value_supported:
|
if bot.args["dev"] and not value_supported:
|
||||||
py_print(f"Value {v['value']} is not supported")
|
py_print(f"Value {v['value']} is not supported")
|
||||||
|
|
||||||
|
return result
|
||||||
+45
-9
@@ -1,6 +1,8 @@
|
|||||||
|
use futures::stream::SplitStream;
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
use futures::SinkExt;
|
use futures::SinkExt;
|
||||||
use tokio::net::TcpListener;
|
use tokio::net::{TcpListener, TcpStream};
|
||||||
|
use tokio_tungstenite::WebSocketStream;
|
||||||
use tokio_tungstenite::{accept_async, tungstenite};
|
use tokio_tungstenite::{accept_async, tungstenite};
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@@ -10,8 +12,10 @@ use crate::rs_println;
|
|||||||
use crate::Args;
|
use crate::Args;
|
||||||
|
|
||||||
type Sender = Arc<Mutex<Option<futures::stream::SplitSink<tokio_tungstenite::WebSocketStream<tokio::net::TcpStream>, tungstenite::Message>>>>;
|
type Sender = Arc<Mutex<Option<futures::stream::SplitSink<tokio_tungstenite::WebSocketStream<tokio::net::TcpStream>, tungstenite::Message>>>>;
|
||||||
|
type Receiver = Arc<Mutex<Option<SplitStream<WebSocketStream<TcpStream>>>>>;
|
||||||
|
|
||||||
static mut GLOBAL_SENDER: Option<Sender> = None;
|
static mut GLOBAL_SENDER: Option<Sender> = None;
|
||||||
|
static mut GLOBAL_RECEIVER: Option<Receiver> = None;
|
||||||
static mut REPLY_HELLO: bool = false;
|
static mut REPLY_HELLO: bool = false;
|
||||||
|
|
||||||
|
|
||||||
@@ -20,6 +24,11 @@ async fn set_sender(sender: Sender) {
|
|||||||
GLOBAL_SENDER = Some(sender);
|
GLOBAL_SENDER = Some(sender);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
async fn set_receiver(receiver: Receiver) {
|
||||||
|
unsafe {
|
||||||
|
GLOBAL_RECEIVER = Some(receiver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pub async fn send_msg(msg: &str) {
|
pub async fn send_msg(msg: &str) {
|
||||||
@@ -34,17 +43,41 @@ pub async fn send_msg(msg: &str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub async fn send_cmd_json(func_name: &str, func_args: Value) {
|
pub async fn send_cmd_json(func_name: &str, func_args: Value) -> Option<Value> {
|
||||||
unsafe {
|
unsafe {
|
||||||
if let Some(sender) = &GLOBAL_SENDER {
|
let Some(sender) = &GLOBAL_SENDER else { return None };
|
||||||
let mut sender = sender.lock().await;
|
let mut sender = sender.lock().await;
|
||||||
if let Some(s) = sender.as_mut() {
|
let Some(s) = sender.as_mut() else { return None };
|
||||||
let json_str: String = format!(
|
|
||||||
|
let json_str = format!(
|
||||||
"json:{{\"type\": \"function\", \"value\":\"{}\", \"args\": {}}}",
|
"json:{{\"type\": \"function\", \"value\":\"{}\", \"args\": {}}}",
|
||||||
func_name, func_args
|
func_name, func_args
|
||||||
);
|
);
|
||||||
s.send(tungstenite::Message::Text(json_str.into())).await.unwrap();
|
|
||||||
|
if s.send(tungstenite::Message::Text(json_str.into())).await.is_err() {
|
||||||
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let r = receive_response().await;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async fn receive_response() -> Option<Value> {
|
||||||
|
unsafe {
|
||||||
|
let Some(receiver) = &GLOBAL_RECEIVER else { return None };
|
||||||
|
let mut receiver = receiver.lock().await;
|
||||||
|
let Some(r) = receiver.as_mut() else { return None };
|
||||||
|
|
||||||
|
let Some(Ok(msg)) = r.next().await else { return None };
|
||||||
|
let tungstenite::Message::Text(response) = msg else { return None };
|
||||||
|
|
||||||
|
if response.starts_with("json:") {
|
||||||
|
return serde_json::from_str(&response[5..]).ok();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return serde_json::from_str(&response).ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -63,12 +96,15 @@ pub async fn start(args: Args) {
|
|||||||
async fn handle_connections(listener: TcpListener, args: Args) {
|
async fn handle_connections(listener: TcpListener, args: Args) {
|
||||||
while let Ok((stream, _)) = listener.accept().await {
|
while let Ok((stream, _)) = listener.accept().await {
|
||||||
let ws_stream = accept_async(stream).await.unwrap();
|
let ws_stream = accept_async(stream).await.unwrap();
|
||||||
let (sender, mut receiver) = ws_stream.split();
|
let (sender, receiver) = ws_stream.split();
|
||||||
|
|
||||||
let sender_arc = Arc::new(Mutex::new(Some(sender)));
|
let sender_arc = Arc::new(Mutex::new(Some(sender)));
|
||||||
set_sender(sender_arc.clone()).await;
|
let receiver_arc = Arc::new(Mutex::new(Some(receiver)));
|
||||||
|
|
||||||
while let Some(Ok(msg)) = receiver.next().await {
|
set_sender(sender_arc.clone()).await;
|
||||||
|
set_receiver(receiver_arc.clone()).await;
|
||||||
|
|
||||||
|
while let Some(Ok(msg)) = receiver_arc.lock().await.as_mut().unwrap().next().await {
|
||||||
handle_message(msg, args.clone()).await;
|
handle_message(msg, args.clone()).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user