Dashboard  2
Lot's of data
Loading...
Searching...
No Matches
widgets.ts
Go to the documentation of this file.
1/*
2** EPITECH PROJECT, 2024
3** area-rattrapage
4** File description:
5** widgets.ts
6*/
7
8import DB from "./db";
9import { GithubWidget } from "./github_widget";
10import { WeatherApi } from "./weather_api";
11import { Darling } from "./darling";
12
13export namespace Widgets {
14
15 export const no_widgets = [
16 {
17 index: -1,
18 widget_index: -1,
19 db_index: -1,
20 name: "no_widget",
21 option: 0,
22 html: "<p>No widgets available</p>"
23 }
24 ];
25
26 export const available_widgets: Record<string, Function> = {
27 "sample_widget": get_sample_widget,
28 "clock": get_clock_widget,
29 "picture": get_random_picture,
30 "weather": get_weather_widget,
31 "github": get_github_widget,
32 "darling": get_darling_widget,
33 "darling_full": get_darling_widget_full
34 };
35
36 const raw_widgets_list = Object.keys(available_widgets);
37
38 export function extractValuesByKey<T, K extends keyof T>(list: T[], key: K): T[K][] {
39 console.log("extractValuesByKey");
40 return list.map(obj => obj[key]);
41 }
42
43 export async function get_weather_widget(widget_name: string, index: number, user_info: any, database: DB): Promise<string> {
44 console.log("get_weather_widget");
45 try {
46 return await WeatherApi.get_weather_widget(widget_name, index, user_info, database);
47 } catch (error) {
48 return "<p>Widget gathering error, the content for the given widget could not be fetched successfully.</p>";
49 }
50 }
51
52 export async function get_random_picture(widget_name: string, index: number, user_info: any, database: DB): Promise<string> {
53 console.log("get_random_picture");
54 const widget_id = `${widget_name}_${index}`;
55 const randomWidth = Math.floor(Math.random() * 1000) + 200;
56 const randomHeight = Math.floor(Math.random() * 1000) + 200;
57 return `<img src="https://picsum.photos/${randomWidth}/${randomHeight}?random=${index}" id="${widget_id}"></img>`;
58 }
59
60 export async function get_github_widget(widget_name: string, index: number, user_info: any, database: DB): Promise<string> {
61 console.log("get_github_widget");
62 try {
63 const sso_id = await database.getContentFromTable("sso_oauth", ["id"], "provider_name='github'");
64 if (!user_info.id || sso_id.length === 0 || !sso_id[0].id) {
65 return "<p>Widget gathering error...</p>";
66 }
67 const oauth_token = await database.getContentFromTable("sso_connections", ["token"], `service_id='${sso_id[0].id}' AND user_id='${user_info.id}'`);
68 if (!oauth_token || oauth_token.length === 0) {
69 return "<p>Please connect to GitHub.<br>Please connect to your github account by presing this button<button onclick='sso()'>here</button></p>";
70 }
71 // console.log("Oauth token:", oauth_token);
72 const finalOauthToken = oauth_token[oauth_token.length - 1].token;
73 // console.log("final oauth token:", finalOauthToken);
74 return await GithubWidget.injector(widget_name, index, String(finalOauthToken));
75 } catch (error) {
76 console.error("Error fetching Github widget:", error);
77 return "<p>Widget gathering error...</p>";
78 }
79 }
80
81 export async function get_darling_widget(widget_name: string, index: number, user_info: any, database: DB): Promise<string> {
82 console.log("get_darling_widget");
83 const response = await Darling.getDarling();
84 // console.log(`Darling response: ${response}`);
85 return response;
86 }
87
88 export async function get_darling_widget_full(widget_name: string, index: number, user_info: any, database: DB): Promise<string> {
89 console.log("get_darling_widget_full");
90 const response = await Darling.getDarlingFull();
91 // console.log(`Darling response: ${response}`);
92 return response;
93 }
94
95 export async function get_sample_widget(widget_name: string, index: number, user_info: any, database: DB): Promise<string> {
96 console.log("get_sample_widget");
97 return `<div id="${widget_name}_${index}"><p>Hello world</p></div>`;
98 }
99
100 export async function get_clock_widget(widget_name: string, index: number, user_info: any, database: DB): Promise<string> {
101 console.log("get_clock_widget");
102 return `<div id="${widget_name}_${index}"><iframe src="https://timeday.co/clock?locale=en&timezone=Europe%2FBrussels&showDate=true&showTime=true&dateFormat=full&timeFormat=24h&showSeconds=true&showTimezone=false&fontSize=18&fontColor=%2523000000&fontWeight=normal&fontStyle=normal&fontDecoration=none&fontFamily=__className_9fd9c5&fontName=orbitron&borderShow=false&borderSize=1&borderStyle=solid&borderColor=%2523000000&borderRadius=rounded-md&backgroundColor=%2523ffffff&alignmentHorizontal=center&alignmentVertical=middle&paddingTop=4&paddingRight=4&paddingBottom=4&paddingLeft=4&width=400&height=40&styleType=standard" width="400" height="40" frameborder="0" style="border:none;"></iframe></div>`;
103 }
104
105 export async function get_available_widget_names() {
106 console.log("get_available_widget_names");
107 return raw_widgets_list;
108 }
109
110 export async function get_user_widgets(user_info: any, database: DB): Promise<typeof no_widgets | any> {
111 console.log("get_user_widgets");
112 // Fetch all widget definitions
113 const widgetNames = await database.getContentFromTable("widgets", ["id", "widget_name"]);
114 // console.log("widgetNames", widgetNames);
115
116 // Fetch user-specific widgets
117 // console.log(`User id: ${user_info.id}`);
118 console.log("Getting user widgets");
119 const widget = await database.getContentFromTable("user_widgets", ["id", "widget_id", "widget_index", "widget_option"], `user_id='${user_info.id}'`);
120 // console.log("widget", widget);
121
122 if (!widget || widget.length === 0) {
123 console.error("No widgets found for user");
124 return no_widgets;
125 }
126
127 // Convert widgetNames to a lookup map (id -> name)
128 const widgetNameMap = Object.fromEntries(widgetNames.map((w: any) => [w.id, w.widget_name]));
129
130 // console.log("widgetNames", widgetNameMap);
131 // console.log("widget", widget);
132
133 let final_build = [];
134
135 console.log("Iterating over widgets");
136
137 for (let i = 0; i < widget.length; i++) {
138 const widget_id = Number(widget[i].widget_id);
139 const widget_name = widgetNameMap[widget_id].toLowerCase() || "<Unknown Widget>";
140
141 // console.log(`widget_id: ${widget_id}, widget_name: ${widget_name}`);
142
143 let widgetContent = "<p>Widget gathering error, the content for the given widget could not be fetched successfully.</p>";
144 // console.log(`Widget content (default error): ${widgetContent}`);
145 // console.log(`widget_name: ${widget_name}, available_widgets: `, available_widgets);
146
147 if (widget_name in available_widgets) {
148 console.log("Widget name found in available_widgets");
149 try {
150 console.log("Trying to fetch widget content");
151 widgetContent = await available_widgets[widget_name](widget_name, widget[i].widget_index, user_info, database)
152 || "<p>Widget gathering error, the content for the given widget could not be fetched successfully.</p>";
153 // console.log(`Widget content: ${widgetContent}`);
154 } catch (error) {
155 console.error(`Error executing widget ${widget_name}:`, error);
156 }
157 }
158
159 let widgetNode = {
160 widget_index: Number(widget[i].widget_index),
161 widget_id: Number(widget[i].widget_id),
162 db_index: Number(widget[i].id),
163 name: widget_name,
164 option: widget[i].widget_option,
165 html: widgetContent
166 };
167 // console.log("widgetNode", widgetNode);
168 final_build.push(widgetNode);
169 // console.log("final_build", final_build);
170 }
171 console.log("iteration finished");
172 // console.log("final_build", final_build);
173
174 return final_build;
175 }
176
177 export async function add_user_widget(user_info: any, widget_id: string, widget_location: string | null, database: DB): Promise<boolean | { index: Number, db_index: Number, name: string, option: Number, html: string }> {
178 console.log("add_user_widget");
179 // console.log("user_info", user_info);
180 // console.log("widget_id", widget_id);
181 // console.log("widget_location", widget_location);
182 const user_id = Number(user_info.id);
183 const widget_id_int = Number(widget_id);
184 // console.log("user_id", user_id);
185 // console.log("widget_id_int", widget_id_int);
186 if (isNaN(user_id) || isNaN(widget_id_int)) {
187 console.error("Invalid user_id or widget_id");
188 return false;
189 }
190 const widget_location_int = widget_location ? Number(widget_location) : 0;
191 const user_widget_table = "user_widgets";
192 const lastEnteredWidget = await database.getContentFromTable(user_widget_table, ["widget_index"], `user_id='${user_id}'`);
193 // console.log("lastEnteredWidget", lastEnteredWidget);
194 const widgetIndex = lastEnteredWidget.length > 0 ? Number(lastEnteredWidget[lastEnteredWidget.length - 1].widget_index) + 1 : 0;
195 // console.log("widgetIndex", widgetIndex);
196 await database.writeToTable(user_widget_table, ["user_id", "widget_id", "widget_index", "widget_option"], [user_id, widget_id_int, widgetIndex, widget_location_int]);
197 return true;
198 }
199
200 export async function update_user_widget(user_info: any, user_widget_id: string, widget_type: string, widget_location: string | null, database: DB): Promise<boolean> {
201 console.log("update_user_widget");
202 console.log("user_info", user_info);
203 console.log("User widget id", user_widget_id);
204 console.log("widget_type", widget_type);
205 console.log("widget_location", widget_location);
206 const user_widget_table = "user_widgets";
207 const user_widget_id_int = Number(user_widget_id);
208 const user_id = Number(user_info.id);
209 // console.log("user_id", user_id);
210 // console.log("widget_id_int", user_widget_id_int);
211 if (isNaN(user_id) || isNaN(user_widget_id_int)) {
212 console.error("Invalid user_id or widget_id");
213 return false;
214 }
215 // Fetch all widget definitions
216 const widgetNames = await database.getContentFromTable("widgets", ["id", "widget_name"]);
217 // console.log("widgetNames", widgetNames);
218 // Convert widgetNames to a lookup map (id -> name)
219 const widgetNameMap = Object.fromEntries(widgetNames.map((w: any) => [Number(w.id), w.widget_name.toLowerCase()]));
220 // Convert widgetNames to a lookup map (name -> id)
221 const widgetIdMap = Object.fromEntries(widgetNames.map((w: any) => [w.widget_name.toLowerCase(), Number(w.id)]));
222 let cleaned_widget_location = "";
223 if (typeof widget_location === "string" && widget_location !== null) {
224 cleaned_widget_location = widget_location;
225 }
226 // console.log("user_widget_table", user_widget_table);
227 const widget_informations = await database.getContentFromTable(user_widget_table, ["*"], `id = '${user_widget_id_int}'`);
228 // console.log("widget_informations", widget_informations);
229 if (!widget_informations || widget_informations.length === 0) {
230 console.error("The user widget doesn't exist");
231 return false;
232 }
233 const widget_informations_node = widget_informations[0];
234 // console.log("widget_informations_node: ", widget_informations_node);
235 // console.log("user_info: ", user_info);
236 // console.log("widget_type: ", widget_type);
237 let widget_type_int = Number(widget_type);
238 if (typeof widget_type === "string") {
239 if (widget_type.toLowerCase() in widgetIdMap) {
240 widget_type_int = widgetIdMap[widget_type.toLowerCase()];
241 } else {
242 console.error("The widget type is invalid.");
243 return false;
244 }
245 }
246 // console.log("widget_type_int: ", widget_type_int);
247 const user_info_id = Number(user_info.id);
248 // console.log("user_info_id: ", user_info_id);
249 // console.log("user_widget_id: ", user_widget_id);
250 // console.log("user_widget_id_int: ", user_widget_id_int);
251 // console.log(`user_info_id !== Number(widget_informations_node["user_id"]): ${user_info_id} !== ${Number(widget_informations_node["user_id"])}: `, (user_info_id !== Number(widget_informations_node["user_id"])));
252 // console.log(`widget_type_int !== Number(widget_informations_node["widget_id"]): ${widget_type_int} !== ${Number(widget_informations_node["widget_id"])}: `, (widget_type_int !== Number(widget_informations_node["widget_id"])));
253 // console.log(`user_widget_id_int !== Number(widget_informations_node["id"]): ${user_widget_id_int} !== ${Number(widget_informations_node["id"])}: `, (user_widget_id_int !== Number(widget_informations_node["id"])));
254 if (user_info_id !== Number(widget_informations_node["user_id"]) || user_widget_id_int !== Number(widget_informations_node["id"])) {
255 console.error("The user id or user_widget_id is invalid.");
256 return false;
257 }
258 // Update the widget information
259 await database.updateTable(user_widget_table, ["widget_id", "widget_option"], [widget_type_int, cleaned_widget_location], "id = ?", [user_widget_id]);
260 // console.log('widget updated (before check)');
261 const widget_informations_update = await database.getContentFromTable(user_widget_table, ["*"], `id = '${user_widget_id_int}'`);
262 if (!widget_informations_update || widget_informations_update.length === 0) {
263 console.error("The user widget doesn't exist");
264 return false;
265 }
266 // console.log("widget_informations_update", widget_informations_update);
267 // console.log("Widget updated successfully");
268 return true;
269 }
270
271 export async function get_widget_info(user_info: any, widget_name: string, database: DB): Promise<boolean | { widget_id: Number, name: string, option: Number, html: string }> {
272 console.log("get_widget_info");
273 // console.log("user_info", user_info);
274 // console.log("widget_name", widget_name);
275 const widgetNames = await database.getContentFromTable("widgets", ["widget_name", "id"]);
276 const widgetError = "<p>Widget gathering error, the content for the given widget could not be fetched successfully.</p>";
277
278 const finalName = widget_name.toLowerCase();
279 // console.log(`finalName: ${finalName}`);
280
281 // Convert widgetNames to a lookup map (name -> id)
282 const widgetNameMap = Object.fromEntries(widgetNames.map((w: any) => [w.widget_name.toLowerCase(), Number(w.id)]));
283 // console.log("widgetMap: ", widgetNameMap);
284 // console.log("available_widgets: ", available_widgets);
285 if (!(finalName in widgetNameMap)) {
286 console.error(`Widget ${finalName} not found in widgetNameMap`);
287 return false;
288 }
289 if (!(finalName in available_widgets)) {
290 console.error(`Widget ${finalName} not found in available_widgets`);
291 return false;
292 }
293 let widgetContent = widgetError;
294 try {
295 widgetContent = await available_widgets[finalName](finalName, widgetNameMap[finalName], user_info, database) || widgetError;
296 } catch (error) {
297 console.error(`Error executing widget ${finalName}:`, error);
298 }
299
300 return {
301 widget_id: Number(widgetNameMap[finalName]),
302 name: widget_name,
303 option: 0,
304 html: widgetContent
305 };
306 }
307
308 export async function delete_user_widget(user_info: any, widget_id: string, database: DB): Promise<boolean> {
309 console.log("delete_user_widget");
310 // console.log("user_info", user_info);
311 // console.log("widget_id", widget_id);
312 const user_widget_table = "user_widgets";
313 // console.log("user_info = ", user_info);
314 const user_id = Number(user_info.id);
315 // console.log(`Deleting widget ${widget_id} for user ${user_id}`);
316 const current_widget = await database.getContentFromTable(user_widget_table, ["*"], `user_id='${user_id}' AND id='${widget_id}'`);
317 // console.log("current_widget", current_widget);
318 if (current_widget.length === 0) {
319 console.error("No widgets found for the given user");
320 return false;
321 }
322 await database.dropFromTable(user_widget_table, `id='${widget_id}'`, []);
323 return true;
324 }
325}