/* E-UrlWatch.c * * Copyright (C) 1999-2000 Tom Gilbert * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA */ #include "config.h" #include "epplet.h" #include "utils.h" #if 0 #define D(a) { printf("%s +%u : ",__FILE__,__LINE__); \ printf a; fflush(stdout); } #else #define D(a) { /* No debug */; } #endif static Epplet_gadget btn_conf, btn_close, btn_help, btn_www, btn_ftp, btn_wget; static Epplet_gadget lbl_url, btn_file_url, btn_urllist, btn_conf; static Epplet_gadget url_p; static char *urllist[10] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static int num_urls = 0; struct { char *str; unsigned int len; unsigned int pos; } dtext; struct { int win; int save_urls; int check_url_file; int do_new_url_command; int always_show_file_urls; char *new_url_command; char *url_save_file; char *url_file; char *www_command; char *ftp_command; char *get_command; } opt; static Window confwin = 0; static Epplet_gadget txt_new_url_command; static Epplet_gadget txt_url_save_file; static Epplet_gadget txt_url_file; static Epplet_gadget txt_www_command; static Epplet_gadget txt_ftp_command; static Epplet_gadget txt_get_command; static void display_string(const char *string); static void handle_url(const char *url, const char *type); static int url_in_popup(const char *url); static char *validate_url(const char *url); static void check_url_file(void *data); static void out_cb(void *data, Window w); static void work_out_cb(void *data, Window w); static void save_config(void) { /* This saves our options. Numbers are printed into a buffer to make * strings. */ char buf[10]; Esnprintf(buf, sizeof(buf), "%d", opt.always_show_file_urls); Epplet_modify_config("ALWAYS_SHOW_FILE_URLS", buf); Esnprintf(buf, sizeof(buf), "%d", opt.save_urls); Epplet_modify_config("SAVE_URLS", buf); Esnprintf(buf, sizeof(buf), "%d", opt.check_url_file); Epplet_modify_config("CHECK_URL_FILE", buf); Esnprintf(buf, sizeof(buf), "%d", opt.do_new_url_command); Epplet_modify_config("RUN_COMMAND_ON_NEW_URL", buf); Epplet_modify_config("WWW_COMMAND", opt.www_command); Epplet_modify_config("FTP_COMMAND", opt.ftp_command); Epplet_modify_config("GET_COMMAND", opt.get_command); Epplet_modify_config("URL_SAVE_FILE", opt.url_save_file); Epplet_modify_config("URL_CHECK_FILE", opt.url_file); Epplet_modify_config("NEW_URL_COMMAND", opt.new_url_command); } static void load_config(void) { /* This reloads our config. */ char *home = getenv("HOME"); char buf[1024]; opt.save_urls = atoi(Epplet_query_config_def("SAVE_URLS", "1")); opt.check_url_file = atoi(Epplet_query_config_def("CHECK_URL_FILE", "1")); opt.always_show_file_urls = atoi(Epplet_query_config_def("ALWAYS_SHOW_FILE_URLS", "0")); opt.do_new_url_command = atoi(Epplet_query_config_def("RUN_COMMAND_ON_NEW_URL", "1")); /* If reloading, free the old string before assigning a new one */ if (opt.www_command) free(opt.www_command); opt.www_command = _Strdup(Epplet_query_config_def ("WWW_COMMAND", "gnome-moz-remote --newwin \"%s\" &")); if (opt.ftp_command) free(opt.ftp_command); opt.ftp_command = _Strdup(Epplet_query_config_def ("FTP_COMMAND", "gnome-moz-remote --newwin \"%s\" &")); if (opt.get_command) free(opt.get_command); opt.get_command = _Strdup(Epplet_query_config_def ("GET_COMMAND", "Eterm -O -e wget \"%s\" &")); if (opt.url_save_file) free(opt.url_save_file); Esnprintf(buf, sizeof(buf), "%s/.Urls", home); opt.url_save_file = _Strdup(Epplet_query_config_def("URL_SAVE_FILE", buf)); if (opt.url_file) free(opt.url_file); Esnprintf(buf, sizeof(buf), "%s/.te/.urls", home); opt.url_file = _Strdup(Epplet_query_config_def("URL_CHECK_FILE", buf)); if (opt.new_url_command) free(opt.new_url_command); Esnprintf(buf, sizeof(buf), "esdplay %s/wooeep.wav &", Epplet_data_dir()); opt.new_url_command = _Strdup(Epplet_query_config_def("NEW_URL_COMMAND", buf)); } static void cb_close(void *data __UNUSED__) { /* save options */ save_config(); /* User closed, so forget session restart */ Epplet_unremember(); /* Sync drawing and ipc to eesh */ Esync(); exit(0); } static void cb_help(void *data __UNUSED__) { Epplet_show_about("E-UrlWatch"); } static void apply_config(void) { /* Apply options from settings dialog */ if (opt.new_url_command) free(opt.new_url_command); opt.new_url_command = _Strdup(Epplet_textbox_contents(txt_new_url_command)); if (opt.url_save_file) free(opt.url_save_file); opt.url_save_file = _Strdup(Epplet_textbox_contents(txt_url_save_file)); if (opt.url_file) free(opt.url_file); opt.url_file = _Strdup(Epplet_textbox_contents(txt_url_file)); if (opt.www_command) free(opt.www_command); opt.www_command = _Strdup(Epplet_textbox_contents(txt_www_command)); if (opt.ftp_command) free(opt.ftp_command); opt.ftp_command = _Strdup(Epplet_textbox_contents(txt_ftp_command)); if (opt.get_command) free(opt.get_command); opt.get_command = _Strdup(Epplet_textbox_contents(txt_get_command)); if (opt.check_url_file) Epplet_timer(check_url_file, NULL, 1, "URLCHECK_TIMER"); } static void ok_cb(void *data __UNUSED__) { apply_config(); save_config(); Epplet_window_destroy(confwin); confwin = 0; } static void apply_cb(void *data __UNUSED__) { apply_config(); } static void cancel_cb(void *data __UNUSED__) { /* close config window */ Epplet_window_destroy(confwin); confwin = 0; load_config(); } static void cb_config(void *data __UNUSED__) { Epplet_gadget lbl, btn_check_file, btn_save, btn_do_new_url_command, btn_always_show_file_urls; if (confwin) return; /* Save any cahnges made though the main window, so we can revert using * the cancel button */ save_config(); /* Create the window using my lovely config window api ;) */ confwin = Epplet_create_window_config(440, 360, "E-UrlWatch Config", ok_cb, &confwin, apply_cb, &confwin, cancel_cb, &confwin); /* Put stuff in the window */ Epplet_gadget_show(lbl = Epplet_create_label(10, 10, "WWW Command:", 2)); Epplet_gadget_show(txt_www_command = Epplet_create_textbox(NULL, opt.www_command, 10, 25, 420, 20, 2, NULL, NULL)); Epplet_gadget_show(lbl = Epplet_create_label(10, 50, "FTP Command:", 2)); Epplet_gadget_show(txt_ftp_command = Epplet_create_textbox(NULL, opt.ftp_command, 10, 65, 420, 20, 2, NULL, NULL)); Epplet_gadget_show(lbl = Epplet_create_label(10, 90, "GET Command:", 2)); Epplet_gadget_show(txt_get_command = Epplet_create_textbox(NULL, opt.get_command, 10, 105, 420, 20, 2, NULL, NULL)); Epplet_draw_line(confwin, 130, 0, 130, 440, 0, 0, 0); Epplet_gadget_show(btn_save = Epplet_create_togglebutton(NULL, NULL, 10, 135, 12, 12, &opt.save_urls, NULL, NULL)); Epplet_gadget_show(lbl = Epplet_create_label(30, 135, "Save all urls handled?", 2)); Epplet_gadget_show(lbl = Epplet_create_label(10, 150, "File to save urls in:", 2)); Epplet_gadget_show(txt_url_save_file = Epplet_create_textbox(NULL, opt.url_save_file, 10, 165, 420, 20, 2, NULL, NULL)); Epplet_gadget_show(btn_check_file = Epplet_create_togglebutton(NULL, NULL, 10, 195, 12, 12, &opt.check_url_file, NULL, NULL)); Epplet_gadget_show(lbl = Epplet_create_label(30, 195, "Watch a file for new urls? (Eg. Third Eye Url Catcher)", 2)); Epplet_gadget_show(lbl = Epplet_create_label(20, 210, "File to watch:", 2)); Epplet_gadget_show(txt_url_file = Epplet_create_textbox(NULL, opt.url_file, 10, 225, 420, 20, 2, NULL, NULL)); Epplet_gadget_show(btn_do_new_url_command = Epplet_create_togglebutton(NULL, NULL, 10, 255, 12, 12, &opt.do_new_url_command, NULL, NULL)); Epplet_gadget_show(lbl = Epplet_create_label(30, 255, "Run command when a new url is detected?", 2)); Epplet_gadget_show(lbl = Epplet_create_label(10, 270, "Command to run:", 2)); Epplet_gadget_show(txt_new_url_command = Epplet_create_textbox(NULL, opt.new_url_command, 10, 285, 420, 20, 2, NULL, NULL)); Epplet_gadget_show(btn_always_show_file_urls = Epplet_create_togglebutton(NULL, NULL, 10, 315, 12, 12, &opt.always_show_file_urls, NULL, NULL)); Epplet_gadget_show(lbl = Epplet_create_label(30, 315, "Automatically launch every new url in watched file?", 2)); Epplet_window_show(confwin); Epplet_window_pop_context(); } /* A click on a url in the url list. Launch the url */ static void cb_url_listp(void *data) { char *url = (char *)data; D(("In cb_url_listp: About to call handle_url on -->%s<--\n", url)); handle_url(url, "www"); } /* Create the url list popup */ static void build_url_list(void) { int i, j; j = num_urls - 1; D(("In build_url_list: num_urls = -->%d<--\n", num_urls)); url_p = Epplet_create_popup(); for (i = 0; i < 10; i++) { if (urllist[j]) { Epplet_add_popup_entry(url_p, urllist[j], NULL, cb_url_listp, (void *)urllist[j]); D(("In build_url_list: adding = -->%s<--\n", urllist[j])); --j; if (j < 0) j = 9; } else break; } Epplet_change_popbutton_popup(btn_urllist, url_p); } /* Stick a new url in the list. Don't rebuild the popup yet though. */ static void add_url_to_url_list(const char *url) { if (num_urls == 10) num_urls = 0; D(("In add_url_to_url_list: adding = -->%s<--\n", url)); if (urllist[num_urls]) { free(urllist[num_urls]); urllist[num_urls] = NULL; } urllist[num_urls] = _Strdup(url); num_urls++; } /* Add a url then rebuild the popup */ static void add_url_to_popup(const char *url) { D(("In add_url_to_popup: adding = -->%s<--\n", url)); add_url_to_url_list(url); build_url_list(); } /* Extract a url from the X cut buffer. This is currently technically * broken, as it only examines buffer 0 */ static char * get_url_from_paste_buffer(void) { static char *url; Display *thedisplay; int len = 0; thedisplay = Epplet_get_display(); if (url) XFree(url); /* This needs to be XFreed at some point */ url = XFetchBuffer(thedisplay, &len, 0); return url; } /* Pull a url from a file. I have not used the position parameter yet, so * that part may not work. (I think it will though ;) */ static const char * get_url_from_file_list(char *file, int position) { FILE *fp; static char buf[256]; int j = 0; D(("In get_url_from_file_list\n")); if (!(fp = fopen(file, "r"))) { fprintf(stderr, "Unable to open file -->%s<-- for reading\n", file); return "Error opening url file!"; } if (position == -1) { while (!feof(fp)) { j++; fgets(buf, sizeof(buf), fp); } D(("In get_url_from_file_list: There are %d urls in the file\n", j)); } else { while (!feof(fp) && j < position) { j++; fgets(buf, sizeof(buf), fp); } D(("In get_url_from_file_list: Asked for url %d returning url %d\n", position, j)); } D(("In get_url_from_file_list: buf is -->%s<--\n", buf)); fclose(fp); return buf; } /* New file in url file. Show the "New!" button */ static void display_url_from_file(const char *url) { char *validurl; if (!(validurl = validate_url(url))) return; /* Perform new url command (eg play a sound) */ if (opt.do_new_url_command && opt.new_url_command) system(opt.new_url_command); if (opt.always_show_file_urls) handle_url(validurl, "www"); else { display_string(validurl); Epplet_gadget_show(btn_file_url); } if (!url_in_popup(validurl)) add_url_to_popup(validurl); } /* Examine the file for changes */ static void check_url_file(void *data __UNUSED__) { static off_t lastfilesize = 0; off_t filesize = 0; struct stat filestat; D(("In check_url_file, url_file -->%s<--\n", opt.url_file)); if (stat(opt.url_file, &filestat) != 0) { D(("stat() failed on -->%s<--\n", opt.url_file)); } else { filesize = filestat.st_size; if ((filesize != lastfilesize) && (lastfilesize != 0)) display_url_from_file(get_url_from_file_list(opt.url_file, -1)); lastfilesize = filesize; } if (opt.check_url_file) Epplet_timer(check_url_file, NULL, 1, "URLCHECK_TIMER"); } /* Search string for url. Fix up url if needed. */ static char * validate_url(const char *url) { char *p; char *ret = NULL; static char *orig_ret = NULL; D(("In validate_url: url -->%s<--\n", url)); if (!url) return NULL; if (orig_ret) free(orig_ret); ret = orig_ret = _Strdup(url); /* First, try searching for http://, in case there is a lot of text, * with an embedded url somewhere inside... */ p = strstr(ret, "http://"); if (p) ret = p; else { /* Ok. No "http://", maybe a "www." ? */ p = strstr(ret, "http://"); if (p) ret = p; } /* Kill at end of line */ p = strchr(ret, '\n'); if (p) *p = '\0'; /* Skip first spaces */ p = ret; while (*p == ' ') p++; ret = p; /* Kill at next space */ p = strchr(ret, ' '); if (p) *p = '\0'; /* If just www.blah, add the http:// to avoid confusing nutscrape */ if (*ret == 'w' && *(ret + 1) == 'w' && *(ret + 2) == 'w') { char *temp = _Strjoin(NULL, "http://", ret, NULL); free(orig_ret); ret = _Strdup(temp); free(temp); } D(("In validate_url: ret -->%s<--\n", ret)); /* Now some checks */ if (strlen(ret) < 1) return 0; if (*ret == '-') return 0; return ret; } /* Save url in file */ static void save_url(const char *url) { FILE *fp; if ((fp = fopen(opt.url_save_file, "a"))) { fprintf(fp, "%s\n", url); fclose(fp); } } /* Set scrolly string to default */ static void reset_string(void *data __UNUSED__) { display_string("E-UrlWatch"); Epplet_gadget_hide(btn_file_url); Epplet_register_focus_out_handler(out_cb, NULL); Epplet_gadget_hide(lbl_url); } /* Scroll the string around */ static void scroll_string(void *data __UNUSED__) { char buf[20]; static int back = 0; static int pause = 0; if (dtext.len > 19) { if (dtext.pos > (dtext.len - 19)) { dtext.pos = dtext.len - 19; back = 1; pause = 1; } else if (dtext.pos == 0) { back = 0; pause = 1; } Esnprintf(buf, sizeof(buf), "%s", dtext.str + dtext.pos); if (!back) dtext.pos += 1; else dtext.pos -= 1; Epplet_change_label(lbl_url, buf); } else Epplet_change_label(lbl_url, dtext.str); if (pause) { Epplet_timer(scroll_string, NULL, 1.0, "SCROLL_TIMER"); pause = 0; } else Epplet_timer(scroll_string, NULL, 0.3, "SCROLL_TIMER"); Esync(); } /* Check to see if the url is already in the list. */ static int url_in_popup(const char *url) { int i; D(("In url_in_popup: url is -->%s<--\n", url)); for (i = 0; i < 10; i++) { if ((urllist[i]) && (!strcmp(urllist[i], url))) { D(("In url_in_popup: A match! Returning TRUE\n")); return 1; } else { D(("In url_in_popup: No match between list item -->%s<-- and url -->%s<--\n", urllist[i], url)); } } return 0; } /* Stick a string in the scrolly display */ static void display_string(const char *string) { D(("In display_string: String -->%s<--\n", string)); if (dtext.str) free(dtext.str); dtext.str = _Strdup(string); dtext.len = strlen(string); dtext.pos = 0; Epplet_timer(scroll_string, NULL, 0.1, "SCROLL_TIMER"); Epplet_timer(reset_string, NULL, 20, "RESET_TIMER"); } /* Do something with the url. Launch it, prolly. */ static void handle_url(const char *url, const char *type) { char *sys = NULL; int len = 0; if (!url) return; D(("In handle_url: url -->%s<--\n", url)); if (!strcmp(type, "www")) { /* This should be close enough :) */ len = strlen(opt.www_command) + strlen(url) + 2; sys = malloc(len); Esnprintf(sys, len, opt.www_command, url); } else if (!strcmp(type, "ftp")) { /* This should be close enough :) */ len = strlen(opt.ftp_command) + strlen(url) + 2; sys = malloc(len); Esnprintf(sys, len, opt.ftp_command, url); } else if (!strcmp(type, "get")) { /* This should be close enough :) */ len = strlen(opt.get_command) + strlen(url) + 2; sys = malloc(len); Esnprintf(sys, len, opt.get_command, url); } else { /* This should be close enough :) */ len = strlen(opt.www_command) + strlen(url) + 2; sys = malloc(len); Esnprintf(sys, len, opt.www_command, url); } D(("In handle_url: About to system() -->%s<--\n", sys)); system(sys); if (!url_in_popup(url)) add_url_to_popup(url); free(sys); if (opt.save_urls) save_url(url); } /* Amongst all the fluff, this is the bit that does the actual work. */ static void cb_shoot(void *data) { char *url; char *validurl; url = get_url_from_paste_buffer(); D(("In cb_shoot: url -->%s<--\n", url)); if (!(validurl = validate_url(url))) return; D(("In cb_shoot: valid url -->%s<--\n", validurl)); Epplet_register_focus_out_handler(work_out_cb, NULL); display_string(validurl); /*richlowe is a hamster */ handle_url(validurl, data); } /* Someone clicked on the "New!" button */ static void cb_btn_file_url(void *data __UNUSED__) { if (dtext.str && strcmp(dtext.str, "E-UrlWatch")) { handle_url(dtext.str, "www"); } } static void create_epplet_layout(void) { Epplet_gadget_show(lbl_url = Epplet_create_label(2, 34, " ", 0)); Epplet_gadget_show(btn_close = Epplet_create_std_button("CLOSE", 2, 2, cb_close, NULL)); Epplet_gadget_show(btn_help = Epplet_create_std_button("HELP", 16, 2, cb_help, NULL)); Epplet_gadget_show(btn_www = Epplet_create_text_button("WWW", 4, 17, 28, 13, cb_shoot, (char *)"www")); Epplet_gadget_show(btn_ftp = Epplet_create_text_button("FTP", 34, 17, 28, 13, cb_shoot, (char *)"ftp")); Epplet_gadget_show(btn_wget = Epplet_create_text_button("GET", 64, 17, 28, 13, cb_shoot, (char *)"get")); btn_file_url = Epplet_create_text_button("New!", 30, 2, 34, 12, cb_btn_file_url, NULL); Epplet_gadget_show(btn_conf = Epplet_create_std_button("CONFIGURE", 82, 2, cb_config, NULL)); url_p = Epplet_create_popup(); Epplet_add_popup_entry(url_p, "Url List is currently empty", NULL, NULL, NULL); Epplet_gadget_show(btn_urllist = Epplet_create_popupbutton(NULL, NULL, 68, 2, 12, 12, "ARROW_DOWN", url_p)); if (opt.check_url_file) Epplet_timer(check_url_file, NULL, 1, "URLCHECK_TIMER"); display_string("Welcome to E-UrlWatch ;-)"); } static void clean_exit(void) { save_config(); Epplet_cleanup(); } static void in_cb(void *data __UNUSED__, Window w) { if (w == Epplet_get_main_window()) { Epplet_gadget_show(btn_urllist); Epplet_gadget_show(btn_conf); Epplet_gadget_show(btn_help); Epplet_gadget_show(btn_close); Epplet_gadget_show(lbl_url); } } static void out_cb(void *data __UNUSED__, Window w) { if (w == Epplet_get_main_window()) { Epplet_gadget_hide(btn_close); Epplet_gadget_hide(btn_help); Epplet_gadget_hide(btn_conf); Epplet_gadget_hide(btn_urllist); Epplet_gadget_hide(lbl_url); } } static void work_out_cb(void *data __UNUSED__, Window w) { if (w == Epplet_get_main_window()) { Epplet_gadget_hide(btn_close); Epplet_gadget_hide(btn_help); Epplet_gadget_hide(btn_conf); Epplet_gadget_hide(btn_urllist); } } int main(int argc, char **argv) { Epplet_adjust_priority(10); atexit(clean_exit); Epplet_Init("E-UrlWatch", "0.1", "Enlightenment Url Watcher Epplet", 6, 3, argc, argv, 0); Epplet_load_config(); load_config(); create_epplet_layout(); Epplet_register_focus_in_handler(in_cb, NULL); Epplet_register_focus_out_handler(out_cb, NULL); Epplet_show(); Epplet_Loop(); return 0; }