tw/commands/
run.rs

1use std::fs;
2
3use ab_glyph::{FontArc, PxScale};
4use image::{ImageBuffer, Rgba};
5use imageproc::drawing::draw_text_mut;
6use reqwest::{
7    header::{HeaderMap, HeaderValue, AUTHORIZATION, CONTENT_TYPE},
8    ClientBuilder,
9};
10
11use crate::{
12    types::{Item, Query},
13    Config,
14};
15
16pub async fn run() -> anyhow::Result<()> {
17    let mut config = match Config::get_config() {
18        Ok(config) => config,
19        Err(err) => {
20            eprintln!("{:?}", err);
21            return Err(err);
22        }
23    };
24
25    let get_items_query = [
26        r#"
27        query GetBoardItemsByPerson {
28          boards(ids: 4539781298) {
29            items_page(
30              query_params: {rules: [{column_id: "person", compare_value: [""#,
31        &config.person_name, // Insert dynamic value here
32        r#""], operator: contains_text}]}
33            ) {
34              items {
35                name
36                column_values {
37                  text
38                  type
39                }
40              }
41            }
42          }
43        }
44        "#,
45    ]
46    .concat();
47
48    let mut headers = HeaderMap::new();
49    headers.insert(
50        CONTENT_TYPE,
51        HeaderValue::from_str("application/json").expect("lol bro fuck you"),
52    );
53    headers.insert(
54        AUTHORIZATION,
55        HeaderValue::from_str(&config.api_key).expect("lol bro fuck you mfker"),
56    );
57
58    let client = ClientBuilder::new()
59        .default_headers(headers)
60        .build()
61        .expect("Couldn't get client");
62
63    let res = client
64        .post("https://api.monday.com/v2")
65        .json(&Query {
66            query: get_items_query,
67        })
68        .send()
69        .await
70        .unwrap();
71
72    let response = res
73        .json::<serde_json::Value>()
74        .await
75        .expect("There was an issue getting the data");
76
77    // Get all the current working on it items
78    let items = Item::items_from_response(response)
79        .expect("Couldn't get items")
80        .into_iter()
81        .filter(|item| {
82            if let (Some(person), Some(status)) =
83                (item.column_values.get(1), item.column_values.get(5))
84            {
85                person.text == Some("Suryansh Srivastava".to_string())
86                    && status.text == Some("Working on it".to_string())
87            } else {
88                false
89            }
90        })
91        .collect::<Vec<Item>>();
92
93    let image_width = config.output_image.width;
94    let image_height = config.output_image.height;
95
96    // Load the image
97    let mut img = ImageBuffer::from_pixel(image_width, image_height, Rgba([0, 0, 0, 255]));
98
99    // Load the font
100    let font = fs::read(config.font.path)
101        .expect("Couldn't load the font. Please recheck the path given in your config.");
102    let font = FontArc::try_from_vec(font).expect("Failed to load font");
103
104    // Define the text properties
105    let scale = PxScale::from(50.0); // Font size
106
107    // let mut start_height = 170;
108    // let increment = 50;
109    let width_offset = ((config.width_offset_perc / 100.0) * image_width as f32) as i32;
110
111    // Draw the text onto the image
112    draw_text_mut(
113        &mut img,
114        Rgba([255u8, 255u8, 255u8, 255u8]), // Black color with full opacity
115        width_offset,
116        100,
117        scale, // Pass the PxScale directly here
118        &font, // Pass the font as a reference
119        "Luganodes Todos:",
120    );
121
122    for item in items {
123        let out_str = format!("{}", item);
124        draw_text_mut(
125            &mut img,
126            Rgba([255u8, 255u8, 255u8, 255u8]), // Black color with full opacity
127            width_offset,
128            config.start_height,
129            scale, // Pass the PxScale directly here
130            &font, // Pass the font as a reference
131            &out_str,
132        );
133        config.start_height += config.height_increment;
134    }
135
136    config.start_height += 50;
137
138    draw_text_mut(
139        &mut img,
140        Rgba([255u8, 255u8, 255u8, 255u8]), // Black color with full opacity
141        width_offset,
142        config.start_height,
143        scale, // Pass the PxScale directly here
144        &font, // Pass the font as a reference
145        "Personal:",
146    );
147
148    let todos_file = fs::read_to_string(config.todos_path).expect("Couldn't load personal file");
149    let todos = todos_file.split("\n");
150
151    config.start_height += 60;
152
153    for todo in todos {
154        draw_text_mut(
155            &mut img,
156            Rgba([255u8, 255u8, 255u8, 255u8]), // Black color with full opacity
157            width_offset,
158            config.start_height,
159            scale, // Pass the PxScale directly here
160            &font, // Pass the font as a reference
161            todo,
162        );
163        config.start_height += config.height_increment;
164    }
165
166    // Save the output image
167    img.save(config.output_image.path)
168        .expect("Failed to save image");
169
170    Ok(())
171}