9 #include <Xm/RowColumn.h>
12 #include <curl/curl.h>
19 char *days[] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday"};
24 printf("ERROR: Out of memory\n");
29 memback(void *contents, size_t size, size_t nmemb, void *userp)
31 size_t realsize = size * nmemb;
32 struct memstruct *mem = (struct memstruct *)userp;
34 char *ptr = realloc(mem->memory, mem->size + realsize + 1);
38 memcpy(&(mem->memory[mem->size]), contents, realsize);
39 mem->size += realsize;
40 mem->memory[mem->size] = 0;
48 CURL *curl = curl_easy_init();
52 fprintf(stderr, "ERROR: Failed to initialize cURL\n");
56 struct memstruct chunk;
57 chunk.memory = malloc(1); // Grown as needed by the realloc in memback()
58 chunk.size = 0; // No data yet
61 "https://nobilis.nobles.edu/skyworld/castlemenu.php?Date=";
62 int len = strlen(baseurl) + strlen(date) + 1;
63 char *url = (char *) malloc(len);
64 snprintf(url, len, "%s%s", baseurl, date);
65 printf("INFO: Using URL %s\n", url);
66 curl_easy_setopt(curl, CURLOPT_URL, url);
67 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, memback);
68 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
69 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
71 printf("INFO: Fetching webpage\n");
72 res = curl_easy_perform(curl);
75 if (res != CURLE_OK) {
76 fprintf(stderr,"ERROR: Could not fetch webpage:\n%s\n",
77 curl_easy_strerror(res));
81 curl_easy_cleanup(curl);
84 printf("INFO: Parsing HTML\n");
86 char *outp = (char *) calloc(1, sizeof(char));
89 // Extract text from between HTML tags
93 for (int i = 345; chunk.memory[i]; i++) {
94 char c = chunk.memory[i];
95 if (c == '<') intag = true;
98 outp = (char *) realloc(outp, j);
101 strncat(outp, next, 2);
103 if (c == '>') intag = false;
108 // Strip empty newlines
109 char *nl = (char *) calloc(1, sizeof(char));
113 for (int i = 0; outp[i]; i++) {
115 if (!((outp[i] == '\n' && outp[i+1] == '\n') ||
116 (outp[i] == ' ' && outp[i+1] == ' '))) {
117 nl = (char *) realloc(nl, j);
120 strncat(nl, next, 2);
129 dayback(Widget unused, XtPointer client_data, XtPointer call_data)
132 Widget disp = (Widget) client_data;
133 XmListCallbackStruct *list_cbs = (XmListCallbackStruct *) call_data;
134 char *nl = getmenu(days[list_cbs->item_position - 1]);
135 char *oldtext = XmTextGetString(disp) ;
136 XmTextReplace((Widget) disp, 0, strlen(oldtext), nl);
141 // Convert an array of strings to an array of compound strings
143 ArgvToXmStringTable (int argc, char **argv)
146 (XmStringTable) XtMalloc((argc+1) * sizeof (XmString));
147 if (!new) return (XmStringTable) 0;
149 new[argc] = (XmString) 0;
150 while (--argc >= 0) {
151 new[argc] = XmStringGenerate ((XtPointer) argv[argc], "tag2",
152 XmCHARSET_TEXT, NULL);
159 main(int argc, char *argv[])
161 // Parse CLI arguments
162 bool showUsage = false;
165 for (int i = 0; i < 5; i++) {
166 if (strcasecmp(argv[1], days[i]) == 0) {
173 if (argc > 2 || showUsage) {
174 printf("Usage: %s [optional: day of the week]\n", argv[0]);
179 Widget toplevel, rowcol, daysel, disp;
184 XtSetLanguageProc(NULL, NULL, NULL);
185 toplevel = XtVaOpenApplication(&app, "Castle Menu", NULL, 0, &argc, argv,
186 NULL, sessionShellWidgetClass, NULL);
189 XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++;
190 rowcol = XmCreateRowColumn(toplevel, "rowcol", args, n);
191 XtManageChild(rowcol);
193 // Create text widget to display menu
195 char *nl = getmenu((argv[1]) ? argv[1] : "");
196 XtSetArg(args[n], XmNvalue, nl); n++;
197 XtSetArg(args[n], XmNeditable, False); n++;
198 XtSetArg(args[n], XmNcolumns, 80); n++;
199 XtSetArg(args[n], XmNrows, 20); n++;
200 XtSetArg(args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++;
201 XtSetArg(args[n], XmNcursorPositionVisible, False); n++;
202 disp = XmCreateScrolledText(rowcol, "text", args, n);
206 // Create day selector
207 strs = ArgvToXmStringTable(XtNumber(days), days);
208 daysel = XmCreateScrolledList(rowcol, "list", NULL, 0);
209 XtVaSetValues(daysel, XmNitems, strs, XmNitemCount, XtNumber(days), NULL);
210 XtAddCallback(daysel, XmNbrowseSelectionCallback, dayback, (XtPointer) disp);
211 XtManageChild(daysel);
213 // Display everything
214 XtRealizeWidget(toplevel);