2** EPITECH PROJECT, 2024
9import { GithubWidget } from "./github_widget";
10import { WeatherApi } from "./weather_api";
11import { Darling } from "./darling";
13export namespace Widgets {
15 export const no_widgets = [
22 html: "<p>No widgets available</p>"
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
36 const raw_widgets_list = Object.keys(available_widgets);
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]);
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");
46 return await WeatherApi.get_weather_widget(widget_name, index, user_info, database);
48 return "<p>Widget gathering error, the content for the given widget could not be fetched successfully.</p>";
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>`;
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");
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>";
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>";
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));
76 console.error("Error fetching Github widget:", error);
77 return "<p>Widget gathering error...</p>";
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}`);
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}`);
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>`;
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>`;
105 export async function get_available_widget_names() {
106 console.log("get_available_widget_names");
107 return raw_widgets_list;
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);
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);
122 if (!widget || widget.length === 0) {
123 console.error("No widgets found for user");
127 // Convert widgetNames to a lookup map (id -> name)
128 const widgetNameMap = Object.fromEntries(widgetNames.map((w: any) => [w.id, w.widget_name]));
130 // console.log("widgetNames", widgetNameMap);
131 // console.log("widget", widget);
133 let final_build = [];
135 console.log("Iterating over widgets");
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>";
141 // console.log(`widget_id: ${widget_id}, widget_name: ${widget_name}`);
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);
147 if (widget_name in available_widgets) {
148 console.log("Widget name found in available_widgets");
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}`);
155 console.error(`Error executing widget ${widget_name}:`, error);
160 widget_index: Number(widget[i].widget_index),
161 widget_id: Number(widget[i].widget_id),
162 db_index: Number(widget[i].id),
164 option: widget[i].widget_option,
167 // console.log("widgetNode", widgetNode);
168 final_build.push(widgetNode);
169 // console.log("final_build", final_build);
171 console.log("iteration finished");
172 // console.log("final_build", final_build);
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");
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]);
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");
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;
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");
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()];
242 console.error("The widget type is invalid.");
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.");
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");
266 // console.log("widget_informations_update", widget_informations_update);
267 // console.log("Widget updated successfully");
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>";
278 const finalName = widget_name.toLowerCase();
279 // console.log(`finalName: ${finalName}`);
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`);
289 if (!(finalName in available_widgets)) {
290 console.error(`Widget ${finalName} not found in available_widgets`);
293 let widgetContent = widgetError;
295 widgetContent = await available_widgets[finalName](finalName, widgetNameMap[finalName], user_info, database) || widgetError;
297 console.error(`Error executing widget ${finalName}:`, error);
301 widget_id: Number(widgetNameMap[finalName]),
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");
322 await database.dropFromTable(user_widget_table, `id='${widget_id}'`, []);