diff options
author | 2010-08-07 00:43:52 +0300 | |
---|---|---|
committer | 2010-08-07 00:43:52 +0300 | |
commit | fee59abeb820b08a41a47b94b5a370fc914e6d90 (patch) | |
tree | 9ee185f081c3088dc17e30ab998ad07b2f715a55 | |
parent | Use .o files instead of .cpp in tuiclient.h (diff) | |
download | idfetch-fee59abeb820b08a41a47b94b5a370fc914e6d90.tar.gz idfetch-fee59abeb820b08a41a47b94b5a370fc914e6d90.tar.bz2 idfetch-fee59abeb820b08a41a47b94b5a370fc914e6d90.zip |
Add WebUI support
[ui_server]
tuiclient monitors segget's activity by establishing tcp connection
with segget daemon (ui_server part of it).
Same ip and port are used for WebUI which can be accessed from web
browser via http://ui_ip:ui_port/
-rw-r--r-- | segget/connection.cpp | 75 | ||||
-rw-r--r-- | segget/connection.h | 1 | ||||
-rw-r--r-- | segget/distfile.cpp | 53 | ||||
-rw-r--r-- | segget/distfile.h | 2 | ||||
-rw-r--r-- | segget/log.cpp | 11 | ||||
-rw-r--r-- | segget/log.h | 3 | ||||
-rw-r--r-- | segget/segget.conf | 10 | ||||
-rw-r--r-- | segget/segment.cpp | 6 | ||||
-rw-r--r-- | segget/tui.cpp | 12 | ||||
-rw-r--r-- | segget/tui.h | 2 | ||||
-rw-r--r-- | segget/ui_server.cpp | 366 | ||||
-rw-r--r-- | segget/ui_server.h | 9 | ||||
-rw-r--r-- | segget/webui/img/blue_progress.jpg | bin | 0 -> 815 bytes | |||
-rw-r--r-- | segget/webui/img/bw_progress.jpg | bin | 0 -> 727 bytes | |||
-rw-r--r-- | segget/webui/img/connections.jpg | bin | 0 -> 5382 bytes | |||
-rw-r--r-- | segget/webui/img/distfiles.png | bin | 0 -> 6761 bytes | |||
-rw-r--r-- | segget/webui/img/errors_log.jpg | bin | 0 -> 4754 bytes | |||
-rw-r--r-- | segget/webui/img/favicon.ico | bin | 0 -> 15086 bytes | |||
-rw-r--r-- | segget/webui/img/green_progress.jpg | bin | 0 -> 876 bytes | |||
-rw-r--r-- | segget/webui/img/log.png | bin | 0 -> 3771 bytes |
20 files changed, 467 insertions, 83 deletions
diff --git a/segget/connection.cpp b/segget/connection.cpp index af9b85e..f628f67 100644 --- a/segget/connection.cpp +++ b/segget/connection.cpp @@ -83,11 +83,8 @@ int Tconnection::start(CURLM *cm, uint network_number, uint distfile_num, Tsegme segment->parent_distfile->active_connections_num++; active=true; - debug("aaaaa"); Pcurr_mirror->start(); - debug("bbbbb"); network_array[network_num].connect(); - debug("ccccc"); stats.active_connections_counter++; segment->prepare_for_connection(cm, connection_num, network_num, distfile_num, url); @@ -265,4 +262,76 @@ void Tconnection::show_connection_progress(ulong time_diff){ }catch(...){ error_log("Error in connection.cpp: show_connection_progress()"); } +} + +string Tconnection::get_html_connection_progress(){ + try{ + ulong time_diff=time_left_from(stats.previous_time); +// stats.total_bytes_per_last_interval+=bytes_per_last_interval; + ulong speed=(bytes_per_last_interval*1000)/time_diff; + ulong avg_speed=(total_dld_bytes*1000)/time_left_from(start_time); + string eta_string; + if (avg_speed==0){ + eta_string="inf"; + }else{ + eta_string=secsToString((segment->segment_size-segment->downloaded_bytes)/avg_speed); + } + string speed_str; + string avg_speed_str; + speed_str=speedToString(speed); + avg_speed_str=speedToString(avg_speed); + int segment_percent; + if (segment->segment_size>0){ + segment_percent=segment->downloaded_bytes*100/segment->segment_size; + }else{ + segment_percent=100; + } + int distfile_percent; + if (segment->parent_distfile->size>0){ + distfile_percent=segment->parent_distfile->dld_bytes*100/segment->parent_distfile->size; + }else{ + distfile_percent=100; + } + + int unfinished_segments_distfile_percent; + //TO-DO: it's necessary to check all connections and add dld bytes to be correct !!! + if (segment->parent_distfile->size>0){ + unfinished_segments_distfile_percent=segment->downloaded_bytes*100/segment->parent_distfile->size; + }else{ + unfinished_segments_distfile_percent=0; + } + string network_type_str; + switch (network_array[network_num].network_mode){ + case MODE_REMOTE: network_type_str="Remote"; break; + case MODE_PROXY_FETCHER: network_type_str="Proxy-Fetcher"; break; + case MODE_LOCAL: network_type_str="Local"; break; + case MODE_CORAL_CDN: network_type_str="CDN"; break; + } + string progress_text= + (string)"<td>" + +"<img src=\"/img/blue_progress.jpg\" alt=\"blue_progress\" height=20 width="+toString(distfile_percent)+"/>" + +"<img src=\"/img/green_progress.jpg\" alt=\"green_progress\" height=20 width="+toString(unfinished_segments_distfile_percent)+"/>" + +"<img src=\"/img/bw_progress.jpg\" alt=\"bw_progress\" height=20 width="+toString(100-distfile_percent-unfinished_segments_distfile_percent)+" />" +// +" "+toString(distfile_percent+unfinished_segments_distfile_percent)+"%" + +" "+toString(distfile_percent)+"%" + +"</td><td>"+segment->parent_distfile->name + +"</td><td>" + +"<img src=\"/img/green_progress.jpg\" alt=\"green_progress\" height=20 width="+toString(segment_percent)+"/>" + +"<img src=\"/img/bw_progress.jpg\" alt=\"bw_progress\" height=20 width="+toString(100-segment_percent)+" />" + +" "+toString(segment_percent)+"%" + +"</td><td align=right>"+toString(segment->segment_num) + +"</td><td align=right>"+toString(segment->try_num) + +"</td><td align=right>"+toString(network_num) + +"</td><td align=center>"+network_type_str + +"</td><td align=right>"+toString(segment->downloaded_bytes) + +"</td><td align=right>"+toString(segment->segment_size) + +"</td><td align=right>"+speed_str + +"</td><td align=right>"+avg_speed_str + +"</td><td align=right>"+eta_string + +"</td>"; + return progress_text; + }catch(...){ + error_log("Error in connection.cpp: show_connection_progress()"); + } + return ""; }
\ No newline at end of file diff --git a/segget/connection.h b/segget/connection.h index 9ac5950..c1fcf6f 100644 --- a/segget/connection.h +++ b/segget/connection.h @@ -72,6 +72,7 @@ class Tconnection{ void stop(CURLcode connection_result); void inc_bytes_per_last_interval(ulong new_bytes_count); void show_connection_progress(ulong time_diff); + string get_html_connection_progress(); }; extern long script_waiting_connection_num; diff --git a/segget/distfile.cpp b/segget/distfile.cpp index e8f4916..5f5c525 100644 --- a/segget/distfile.cpp +++ b/segget/distfile.cpp @@ -59,6 +59,53 @@ using namespace std; #define ALLOW_LOWER_PRIORITY_NETWORKS 205 */ +string Tdistfile::statusToString(){ + try{ + switch(status){ + case DNEW: return "Added"; + case D_NOT_PROXY_REQUESTED: return "Not proxy requested"; + case DPROXY_REJECTED: return "Proxy rejected"; + case DPROXY_QUEUED: return "Proxy queued"; + case DPROXY_DOWNLOADING: return "Downloading via proxy"; + case DPROXY_DOWNLOADED: return "Downloaded via proxy"; + case DPROXY_FAILED: return "Failed"; + case DALL_LM_AND_PF_MIRRORS_FAILED: return "All mirrors failed"; + case DWAITING: return "Waiting"; + case DSCRIPTREJECTED: return "Rejected by script"; + case DDOWNLOADING: return "Downloading"; + case DDOWNLOADED: return "Downloaded"; + case DFAILED: return "Failed"; + } + }catch(...){ + error_log("Error: distfile.cpp: statusToString()"); + } + return "UNKNOWN status"; +} + +string Tdistfile::statusToColor(){ + try{ + switch(status){ + case DNEW: return "#FFFFFF"; + case D_NOT_PROXY_REQUESTED: return "#FFFFFF"; + case DPROXY_REJECTED: return "#FFAAAA"; + case DPROXY_QUEUED: return "#AAAAFF"; + case DPROXY_DOWNLOADING: return "#AAAAFF"; + case DPROXY_DOWNLOADED: return "#AAAAFF"; + case DPROXY_FAILED: return "#FFAAAA"; + case DALL_LM_AND_PF_MIRRORS_FAILED: return "#FFAAAA"; + case DWAITING: return "#AAAAFF"; + case DSCRIPTREJECTED: return "#FFFFAA"; + case DDOWNLOADING: return "#77DDFF"; + case DDOWNLOADED: return "#AAFFAA"; + case DFAILED: return "#FF8888"; + } + }catch(...){ + error_log("Error: distfile.cpp: statusToString()"); + } + return "#FFFFFF"; +} + + void Tdistfile::set_status(Tdistfile_status new_status){ try{ status=new_status; @@ -368,7 +415,7 @@ bool Tdistfile::choose_best_mirror(CURLM* cm, uint connection_num, uint network_ } } else{ - error_log("Can't choose mirror for segment:"+dn_segments[seg_num].file_name); + debug("Can't choose mirror for segment:"+dn_segments[seg_num].file_name); return 1; } }catch(...){ @@ -418,10 +465,10 @@ bool Tdistfile::choose_best_local_mirror(CURLM* cm, uint connection_num, uint ne } else{ debug("Can't choose LOCAL mirror for segment:"+dn_segments[seg_num].file_name); - error_log("Can't choose LOCAL mirror for segment:"+dn_segments[seg_num].file_name); +// error_log("Can't choose LOCAL mirror for segment:"+dn_segments[seg_num].file_name); if (all_mirrors_failed){ debug("All local mirrors failed in network#"+toString(network_num)); - error_log("All local mirrors failed in network#"+toString(network_num)); +// error_log("All local mirrors failed in network#"+toString(network_num)); } return 1; } diff --git a/segget/distfile.h b/segget/distfile.h index e2e8afd..5ca1d95 100644 --- a/segget/distfile.h +++ b/segget/distfile.h @@ -148,6 +148,8 @@ class Tdistfile{ Tdistfile(const Tdistfile &L); // copy constructor Tdistfile & operator=(const Tdistfile &L); ~Tdistfile(); + string statusToString(); + string statusToColor(); int request(ulong network_num, string msg); void init(); void set_status(Tdistfile_status new_status); diff --git a/segget/log.cpp b/segget/log.cpp index 4d1edfe..9c62719 100644 --- a/segget/log.cpp +++ b/segget/log.cpp @@ -26,6 +26,9 @@ #include "log.h" +vector<string> log_lines; +vector<string> error_log_lines; + string get_time(string time_format){ try{ time_format=time_format+" "; @@ -70,6 +73,10 @@ void log_no_msg(string log_msg_text){ void log(string log_msg_text){ log_no_msg(log_msg_text); try{ + log_lines.push_back(log_msg_text); + if (log_lines.size()>LOG_LINES_MAX_NUM){ + log_lines.erase(log_lines.begin(),log_lines.begin()+log_lines.size()-LOG_LINES_MAX_NUM); + } msg_log(get_time(settings.general_log_time_format)+log_msg_text); }catch(...){ error_log("Error in log.cpp: log()"); @@ -127,6 +134,10 @@ void error_log_no_msg(string error_msg_text){ void error_log(string error_msg_text){ error_log_no_msg(error_msg_text); try{ + error_log_lines.push_back(error_msg_text); + if (error_log_lines.size()>LOG_LINES_MAX_NUM){ + error_log_lines.erase(error_log_lines.begin(),error_log_lines.begin()+error_log_lines.size()-LOG_LINES_MAX_NUM); + } msg_error_log(get_time(settings.error_log_time_format)+error_msg_text); }catch(...){ error_log_no_msg("Error in log.cpp: error_log()"); diff --git a/segget/log.h b/segget/log.h index 45a158d..fb3f078 100644 --- a/segget/log.h +++ b/segget/log.h @@ -28,8 +28,11 @@ #define __LOG_H__ #include "settings.h" #include "utils.h" +#define LOG_LINES_MAX_NUM 200 using namespace std; +extern vector<string> log_lines; +extern vector<string> error_log_lines; void log_no_msg(string log_msg_text); void log(string log_msg_text); diff --git a/segget/segget.conf b/segget/segget.conf index 616ce1e..a7bccc9 100644 --- a/segget/segget.conf +++ b/segget/segget.conf @@ -242,6 +242,8 @@ user_agent=segget [ui_server] # tuiclient monitors segget's activity by establishing tcp connection # with segget daemon (ui_server part of it). +# Same ip and port are used for WebUI which can be accessed from web +# browser via http://ui_ip:ui_port/ # UI_IP # Define an ip address segget will use to provide access for tuiclients. @@ -292,11 +294,11 @@ request_port=10000 python_path=/usr/bin/python # SCRIPTS_DIR -# Define path to a dir with python scripts. Before establishing connection for +# Define a path to the dir with python scripts. Before establishing connection for # a particular segment via network# segget checks SCRIPTS_DIR. # If SCRIPTS_DIR contains net#.py file, segget will launch schedule() function # from this file to apply settings for connetion and accept or reject this -# segment for the moment. net#.py file is a causual python script file +# segment for the moment. net#.py file is a python script file # with a user-writen schedule() function. # It's necessary to import functions before using get("variable"), # set("variable",value), accept_segment() and reject_segment() in schedule(). @@ -315,7 +317,7 @@ python_path=/usr/bin/python # hour=localtime[3]; # # disable downloading distfiles that have size more than 5 000 000 bytes # # from 8-00 to 22-00. -# if hour>8 and hour<21 and (get("distfile.size"))>5000000: +# if hour>8 and hour<22 and (get("distfile.size"))>5000000: # print "reject because distfile is too big" # reject_segment() # # set speed limit 50 000 cps for distfiles larger than 1 000 000 bytes @@ -346,7 +348,7 @@ python_path=/usr/bin/python # scripts_dir=./scripts scripts_dir=./scripts -# script_socket_path +# SCRIPT_SOCKET_PATH # Segget uses AF_UNIX domain sockets for communication with python. # Specify path for the socket on your filesystem. # NOTE !: Default value can NOT be changed yet (option under development). diff --git a/segget/segment.cpp b/segget/segment.cpp index 9389820..bfbdc5c 100644 --- a/segget/segment.cpp +++ b/segget/segment.cpp @@ -131,8 +131,12 @@ int Tsegment::add_easy_handle_to_multi(CURLM *cm, uint network_num){ } curl_easy_setopt(easyhandle, CURLOPT_LOW_SPEED_TIME, network_array[network_num].low_connection_speed_time); - if ((network_array[network_num].max_connection_speed!=0) and (network_array[network_num].max_connection_speed!=(ulong)-1)){ + if (connection_array[connection_num].max_speed_limit!=0){ curl_easy_setopt(easyhandle, CURLOPT_MAX_RECV_SPEED_LARGE, network_array[network_num].max_connection_speed); + }else{ + if ((network_array[network_num].max_connection_speed!=0) and (network_array[network_num].max_connection_speed!=(ulong)-1)){ + curl_easy_setopt(easyhandle, CURLOPT_MAX_RECV_SPEED_LARGE, network_array[network_num].max_connection_speed); + } } curl_easy_setopt(easyhandle, CURLOPT_USERAGENT, network_array[network_num].user_agent.c_str()); diff --git a/segget/tui.cpp b/segget/tui.cpp index 0d26e11..2357fe7 100644 --- a/segget/tui.cpp +++ b/segget/tui.cpp @@ -29,7 +29,7 @@ extern Tsettings settings; const uint CONNECTION_LINES=3; string screenlines[DEBUG_LINE_NUM+1]; -vector<string> log_lines; +//vector<string> log_lines; uint log_lines_counter=0; uint max_published_screenline_num; @@ -78,13 +78,10 @@ void msg_clean_connection(uint connection_num){ error_log_no_msg("Error in tui.cpp: msg_clean_connection()"); } } + void msg_log(string log_text){ try{ ui_server.send_log_msg_to_all_clients(log_text); - log_lines.push_back(log_text); - if (log_lines.size()>LOG_LINES_MAX_NUM){ - log_lines.erase(log_lines.begin(),log_lines.begin()+log_lines.size()-LOG_LINES_MAX_NUM); - } // msg(20,0, error_text); }catch(...){ error_log_no_msg("Error in tui.cpp: msg_error()"); @@ -93,15 +90,12 @@ void msg_log(string log_text){ void msg_error_log(string error_log_text){ try{ ui_server.send_error_log_msg_to_all_clients(error_log_text); - log_lines.push_back(error_log_text); - if (log_lines.size()>LOG_LINES_MAX_NUM){ - log_lines.erase(log_lines.begin(),log_lines.begin()+log_lines.size()-LOG_LINES_MAX_NUM); - } // msg(20,0, error_text); }catch(...){ error_log_no_msg("Error in tui.cpp: msg_error()"); } } + void msg_total(string msg_text){ try{ msg(TOTAL_LINE_NUM,0,msg_text); diff --git a/segget/tui.h b/segget/tui.h index 8a3022b..aa2041c 100644 --- a/segget/tui.h +++ b/segget/tui.h @@ -40,7 +40,7 @@ const uint TOTAL_LINE_NUM=MAX_LINES; const uint ERROR_LINE_NUM=MAX_LINES+1; const uint LOG_LINE_NUM=MAX_LINES+2; const uint DEBUG_LINE_NUM=MAX_LINES+3; -const uint LOG_LINES_MAX_NUM=200; +//const uint LOG_LINES_MAX_NUM=200; extern string screenlines[DEBUG_LINE_NUM+1]; extern uint max_published_screenline_num; diff --git a/segget/ui_server.cpp b/segget/ui_server.cpp index 09cb26d..dbc7af9 100644 --- a/segget/ui_server.cpp +++ b/segget/ui_server.cpp @@ -70,6 +70,53 @@ void Tui_server::init(){ //prevent simultaneous writes +ulong Tui_server::send_binary_to_fd(uint fd, string image_file_name){ +// if (send_to_fd_idle) { + ifstream image_file; + try{ + image_file.open (image_file_name.c_str(), ios::in|ios::binary|ios::ate); + // file.open((settings.conf_dir+"/"+config_file_name).c_str()); + } + catch(...){ + error_log("Error opening image file: "); + // return; + } + try{ + //processing file + ifstream::pos_type size; + char * memblock; + if (image_file.is_open()){ + size = image_file.tellg(); + memblock = new char [size]; + image_file.seekg (0, ios::beg); + image_file.read (memblock, size); + + while (send_to_fd_busy){ + sleep(1); + } + send_to_fd_busy=true; + if (fd !=server_sockfd){ + if(FD_ISSET(fd,&ui_server.readfds)) { + ulong bytes_written=write(fd, memblock, size); + if (bytes_written!=size){ + debug("Error: Not all data has been sent to ui_client during send_binary_to_fd()"); + } + } + } + send_to_fd_busy=false; + image_file.close(); + delete[] memblock; + } + }catch(ifstream::failure e){ +// + }catch(...){ + // error_log("Settings file: "+config_file_name+" was opened, but an error occured while reading settings from it."); + } + + return 0; +} + + ulong Tui_server::send_to_fd(uint fd, string msg){ // if (send_to_fd_idle) { while (send_to_fd_busy){ @@ -96,14 +143,18 @@ void Tui_server::send_connection_msg_to_fd(uint fd, uint y, string msg){ void Tui_server::send_connection_msg_to_all_clients(uint y, string msg){ string message="<m>c<t>"+toString(y)+"<y>"+msg+"<.>"; for(uint fd = 0; fd <= ui_server.max_fd_num; fd++){ - send_to_fd(fd, message); + if FD_ISSET(fd, &tuiclient_fds_set){ + send_to_fd(fd, message); + } } } void Tui_server::send_log_msg_to_all_clients(string msg){ string message="<m>l<t>"+msg+"<.>"; for(uint fd = 0; fd <= ui_server.max_fd_num; fd++){ - send_to_fd(fd, message); + if FD_ISSET(fd, &tuiclient_fds_set){ + send_to_fd(fd, message); + } } } @@ -115,14 +166,247 @@ void Tui_server::send_distfile_progress_msg_to_fd(uint fd, string msg){ void Tui_server::send_distfile_progress_msg_to_all_clients(string msg){ string message="<m>d<t>"+msg+"<.>"; for(uint fd = 0; fd <= ui_server.max_fd_num; fd++){ - send_to_fd(fd, message); + if FD_ISSET(fd, &tuiclient_fds_set){ + send_to_fd(fd, message); + } } } void Tui_server::send_error_log_msg_to_all_clients(string msg){ string message="<m>e<t>"+msg+"<.>"; for(uint fd = 0; fd <= ui_server.max_fd_num; fd++){ - send_to_fd(fd, message); + if FD_ISSET(fd, &tuiclient_fds_set){ + send_to_fd(fd, message); + } + } +} + +void Tui_server::serve_tuiclient(uint fd, string msg){ + try{ + debug("tuiclient connected"); + string request_str_before,request_str_after; + split("<d>",msg,request_str_before,request_str_after); + split("<.>",request_str_after,request_str_before,request_str_after); + string distfile_by_name_lookup_request=request_str_before; + TDFsearch_rusults distfile_search_result=NOT_FOUND; + if (distfile_by_name_lookup_request.length()>0){ + for (ulong distfile_num=0; distfile_num<request_server_pkg.distfile_count; distfile_num++){ + if (distfile_by_name_lookup_request==request_server_pkg.Pdistfile_list[distfile_num]->name){ + if (request_server_pkg.Pdistfile_list[distfile_num]->get_status()==DDOWNLOADED){ + distfile_search_result=DOWNLOADED; + }else{ + distfile_search_result=IN_QUEUE; + } + break; + } + } + if (distfile_search_result==NOT_FOUND){ + for (ulong distfile_num=0; distfile_num<proxy_fetcher_pkg.distfile_count; distfile_num++){ + if (distfile_by_name_lookup_request==proxy_fetcher_pkg.Pdistfile_list[distfile_num]->name){ + if (proxy_fetcher_pkg.Pdistfile_list[distfile_num]->get_status()==DDOWNLOADED){ + distfile_search_result=DOWNLOADED; + }else{ + distfile_search_result=IN_QUEUE; + } + break; + } + } + } + }else{ + // if no name for distfile specified -> no need to find distfile + // just keep an eye on the ones in queue + distfile_search_result=IN_QUEUE; + } + switch (distfile_search_result){ + case NOT_FOUND: + ui_server.send_to_fd(fd, "<m>n<t><.>"); //distfile is not in the list quit + break; + case DOWNLOADED: + ui_server.send_to_fd(fd, "<m>N<t><.>"); //distfile is not in the list quit + break; + case IN_QUEUE: + ui_server.send_to_fd(fd, "<m>y<t><.>"); //distfile is in the list continue + // Get this info to catch up! + for (uint line_num=0; line_num<=max_published_screenline_num;line_num++){ + ui_server.send_connection_msg_to_fd(fd, line_num, screenlines[line_num]); + debug("Sending to client line:"+toString(line_num)+" "+screenlines[line_num]); + } + debug("Sending to client distfiles_num:"+toString(request_server_pkg.Pdistfile_list.size())); + for (ulong distfile_num=0; distfile_num<request_server_pkg.Pdistfile_list.size(); distfile_num++){ + ui_server.send_distfile_progress_msg_to_fd(fd, request_server_pkg.Pdistfile_list[distfile_num]->get_distfile_progress_str()); + debug("Sending to client:"+request_server_pkg.Pdistfile_list[distfile_num]->get_distfile_progress_str()); + } + for (ulong distfile_num=0; distfile_num<proxy_fetcher_pkg.Pdistfile_list.size(); distfile_num++){ + ui_server.send_distfile_progress_msg_to_fd(fd, proxy_fetcher_pkg.Pdistfile_list[distfile_num]->get_distfile_progress_str()); + debug("Sending to client:"+proxy_fetcher_pkg.Pdistfile_list[distfile_num]->get_distfile_progress_str()); + } + } + }catch(...){ + error_log_no_msg("Error in ui_server.cpp: serve_server()"); + } +} + +string Tui_server::serve_browser_distfile_progress(Tdistfile * a_distfile){ + try{ + uint percent; + if (a_distfile->size>0){ + percent=a_distfile->dld_bytes*100/a_distfile->size; + }else{ + percent=50; + } + string result=(string)"<td>" + +"<img src=\"/img/blue_progress.jpg\" alt=\"blue_progress\" height=20 width="+toString(percent)+"/>" + +"<img src=\"/img/bw_progress.jpg\" alt=\"bw_progress\" height=20 width="+toString(100-percent)+" />" + +"</td><td align=center>"+toString(percent)+"%" + +"</td><td>"+a_distfile->name + +"</td><td align=center bgcolor=\""+a_distfile->statusToColor()+"\">"+a_distfile->statusToString() + +"</td><td align=right>"+toString(a_distfile->dld_segments_count) + +"</td><td align=right>"+toString(a_distfile->segments_count) + +"</td><td align=right>"+toString(a_distfile->dld_bytes) + +"</td><td align=right>"+toString(a_distfile->size) + +"</td>"; + return result; + }catch(...){ + error_log("Error: ui_server.cpp: serve_browser_distfile_progress()"); + return ""; + } +} + +string Tui_server::get_header(string title){ + string header; + header=(string)"HTTP/1.0 200 OK\n\n" + +"<html><head><meta http-equiv=\"refresh\" content=\"1\" ><title> Segget - "+title+"</title></head>" + +"<body>" + +"<table border=0>" + +"<tr align=center>" + +"<td><a href=\"connections\"><img src=\"/img/connections.jpg\" alt=\"Segments\" height=50 width=50/></a></td>" + +"<td><a href=\"distfiles\"><img src=\"/img/distfiles.png\" alt=\"Distfiles\" height=50 width=50/></a></td>" + +"<td><a href=\"log\"><img src=\"/img/log.png\" alt=\"Log\" height=50 width=50/></a></td>" + +"<td><a href=\"errors_log\"><img src=\"/img/errors_log.jpg\" alt=\"Errors log\" height=50 width=50/></a></td>" + +"</tr>" + +"<tr align=center>" + +"<td><a href=\"connections\">Connections</a></td>" + +"<td><a href=\"distfiles\">Distfiles</a></td>" + +"<td><a href=\"log\">Log</a></td>" + +"<td><a href=\"errors_log\">Errors log</a></td>" + +"</tr>" + +"</table>" + +"<h1>"+title+"</h1>"; + return header; +} + +string Tui_server::get_footer(){ + return "</body></html>"; +} + +string Tui_server::get_connections_info(){ + try{ + string result=(string)"<center>" + +"<h3>Active connections: "+toString(stats.active_connections_counter)+"/"+toString(settings.max_connections)+"</h1>" + +"<table border=1 width=100%>" + +"<tr>" + +"<th rowspan=2>Distfile progress</th>" + +"<th rowspan=2>Distfile name</th>" + +"<th rowspan=2>Segment progress</th>" + +"<th rowspan=2>Segment #</th>" + +"<th rowspan=2>Try</th>" + +"<th colspan=2>Network</th>" + +"<th colspan=2>Bytes</th>" + +"<th colspan=2>Speed</th>" + +"<th rowspan=2 width=100>ETA</th>" + +"</tr>" + +"<tr>" + +"<th>Num</th>" + +"<th>Type</th>" + +"<th>Downloaded</th>" + +"<th>Total</th>" + +"<th>Current</th>" + +"<th>Average</th>" + +"</tr>"; + for (uint connection_num = 0; connection_num < settings.max_connections; ++connection_num) { +// debug("connection_num:"+toString(connection_num)); + if (connection_array[connection_num].active){ + result=result+"<tr>"+connection_array[connection_num].get_html_connection_progress()+"</tr>"; + } + } + result=result+"</table></center>"; + return result; + }catch(...){ + error_log("Error: ui_server.cpp: serve_browser_distfile_progress()"); + return ""; + } +} +void Tui_server::serve_browser(uint fd, string msg){ + try{ + debug("Web browser connected"); + uint pos_uri_start=msg.find("GET"); + uint pos_uri_end=msg.find("HTTP",pos_uri_start); + string uri; + if (pos_uri_end!=msg.npos){ + uri=msg.substr(pos_uri_start+4,pos_uri_end-pos_uri_start-5); + debug("Web browser requests URI:"+uri); + } + if (uri=="/connections"){ + send_to_fd(fd,get_header("Connections")); + send_to_fd(fd,get_connections_info()); + send_to_fd(fd,get_footer()); + }else if (uri=="/log"){ + ui_server.send_to_fd(fd,get_header("Log")); + ui_server.send_to_fd(fd,"<center><table border=\"1\" width=\"100%\">"); + for (uint log_line_num=0; log_line_num<log_lines.size(); log_line_num++){ + ui_server.send_to_fd(fd,"<tr><td>"+log_lines[log_line_num]+"</td></tr>"); + } + ui_server.send_to_fd(fd,"</table></center>"); + ui_server.send_to_fd(fd,get_footer()); + }else if (uri=="/errors_log"){ + ui_server.send_to_fd(fd,get_header("Errors log")); + ui_server.send_to_fd(fd,"<center><table border=\"1\" width=\"100%\">"); + for (uint error_log_line_num=0; error_log_line_num<error_log_lines.size(); error_log_line_num++){ + ui_server.send_to_fd(fd,"<tr><td>"+error_log_lines[error_log_line_num]+"</td></tr>"); + } + ui_server.send_to_fd(fd,"</table></center>"); + ui_server.send_to_fd(fd,get_footer()); + }else if (uri=="/distfiles"){ + ui_server.send_to_fd(fd,get_header("Distfiles")); + ui_server.send_to_fd(fd,"<center><table border=\"1\" width=\"100%\">"); + debug("Sending to client distfiles_num:"+toString(request_server_pkg.Pdistfile_list.size())); + ui_server.send_to_fd(fd,(string)"<tr>" + +"</th><th rowspan=2>Progress" + +"</th><th rowspan=2>Percent" + +"</th><th rowspan=2>Name" + +"</th><th rowspan=2>Status" + +"</th><th colspan=2>Segments" + +"</th><th colspan=2>Bytes" + +"</th></tr>"); + ui_server.send_to_fd(fd,(string)"<tr>" + +"</th><th>Downloaded" + +"</th><th>Total" + +"</th><th>Downloaded" + +"</th><th>Total" + +"</th></tr>"); + for (ulong distfile_num=0; distfile_num<request_server_pkg.Pdistfile_list.size(); distfile_num++){ + ui_server.send_to_fd(fd,"<tr>"+serve_browser_distfile_progress(request_server_pkg.Pdistfile_list[distfile_num])+"</tr>"); + debug("Sending to client:"+request_server_pkg.Pdistfile_list[distfile_num]->get_distfile_progress_str()); + } + for (ulong distfile_num=0; distfile_num<proxy_fetcher_pkg.Pdistfile_list.size(); distfile_num++){ + ui_server.send_to_fd(fd,"<tr>"+serve_browser_distfile_progress(proxy_fetcher_pkg.Pdistfile_list[distfile_num])+"</tr>"); + debug("Sending to client:"+proxy_fetcher_pkg.Pdistfile_list[distfile_num]->get_distfile_progress_str()); + } + ui_server.send_to_fd(fd,"</table></center>"); + ui_server.send_to_fd(fd,get_footer()); + }else if (uri=="/favicon.ico"){ + ui_server.send_binary_to_fd(fd,"./webui/img/favicon.ico"); + }else if (uri.find("/img")!=uri.npos){ + ui_server.send_binary_to_fd(fd,"./webui"+uri); + }else{ + send_to_fd(fd,get_header("Connections")); + send_to_fd(fd,get_connections_info()); + send_to_fd(fd,get_footer()); + } + shutdown(fd,2); + close(fd); + }catch(...){ + error_log_no_msg("Error in ui_server.cpp: serve_server()"); } } @@ -158,6 +442,7 @@ void *run_ui_server(void * ){ if (client_sockfd>ui_server.max_fd_num) ui_server.max_fd_num=client_sockfd; FD_SET(client_sockfd, &ui_server.readfds); +// close(client_sockfd); //If it isn’t the server, it must be client activity. If close is received, the client has gone away, and you remove it from the descriptor set. Otherwise, you “serve” the client as in the previous examples. }else{ @@ -166,6 +451,9 @@ void *run_ui_server(void * ){ if(nread == 0) { debug("nothing to read"); FD_CLR(fd, &ui_server.readfds); + if FD_ISSET(fd, &ui_server.tuiclient_fds_set){ + FD_CLR(fd, &ui_server.tuiclient_fds_set); + } close(fd); debug("Client parted from fd:"+toString(fd)); }else{ @@ -174,64 +462,20 @@ void *run_ui_server(void * ){ if (nread!=read(fd, &buffer, nread)){ debug("Not all data has been read from ui_client()"); } - string request_str_before,request_str_after; - debug("received_from tuiclient:"); - debug(buffer); - split("<d>",buffer,request_str_before,request_str_after); - split("<.>",request_str_after,request_str_before,request_str_after); - string distfile_by_name_lookup_request=request_str_before; - TDFsearch_rusults distfile_search_result=NOT_FOUND; - if (distfile_by_name_lookup_request.length()>0){ - for (ulong distfile_num=0; distfile_num<request_server_pkg.distfile_count; distfile_num++){ - if (distfile_by_name_lookup_request==request_server_pkg.Pdistfile_list[distfile_num]->name){ - if (request_server_pkg.Pdistfile_list[distfile_num]->get_status()==DDOWNLOADED){ - distfile_search_result=DOWNLOADED; - }else{ - distfile_search_result=IN_QUEUE; - } - break; - } - } - if (distfile_search_result==NOT_FOUND){ - for (ulong distfile_num=0; distfile_num<proxy_fetcher_pkg.distfile_count; distfile_num++){ - if (distfile_by_name_lookup_request==proxy_fetcher_pkg.Pdistfile_list[distfile_num]->name){ - if (proxy_fetcher_pkg.Pdistfile_list[distfile_num]->get_status()==DDOWNLOADED){ - distfile_search_result=DOWNLOADED; - }else{ - distfile_search_result=IN_QUEUE; - } - break; - } - } - } + string buffer_as_str=buffer; + debug("received_from ui_client:"+buffer_as_str); + if FD_ISSET(fd, &ui_server.tuiclient_fds_set){ + ui_server.serve_tuiclient(fd,buffer_as_str); }else{ - // if no name for distfile specified -> no need to find distfile - // just keep an eye on the ones in queue - distfile_search_result=IN_QUEUE; - } - switch (distfile_search_result){ - case NOT_FOUND: - ui_server.send_to_fd(fd, "<m>n<t><.>"); //distfile is not in the list quit - break; - case DOWNLOADED: - ui_server.send_to_fd(fd, "<m>N<t><.>"); //distfile is not in the list quit - break; - case IN_QUEUE: - ui_server.send_to_fd(fd, "<m>y<t><.>"); //distfile is in the list continue - // Get this info to catch up! - for (uint line_num=0; line_num<=max_published_screenline_num;line_num++){ - ui_server.send_connection_msg_to_fd(fd, line_num, screenlines[line_num]); - debug("Sending to client line:"+toString(line_num)+" "+screenlines[line_num]); - } - debug("Sending to client distfiles_num:"+toString(request_server_pkg.Pdistfile_list.size())); - for (ulong distfile_num=0; distfile_num<request_server_pkg.Pdistfile_list.size(); distfile_num++){ - ui_server.send_distfile_progress_msg_to_fd(fd, request_server_pkg.Pdistfile_list[distfile_num]->get_distfile_progress_str()); - debug("Sending to client:"+request_server_pkg.Pdistfile_list[distfile_num]->get_distfile_progress_str()); - } - for (ulong distfile_num=0; distfile_num<proxy_fetcher_pkg.Pdistfile_list.size(); distfile_num++){ - ui_server.send_distfile_progress_msg_to_fd(fd, proxy_fetcher_pkg.Pdistfile_list[distfile_num]->get_distfile_progress_str()); - debug("Sending to client:"+proxy_fetcher_pkg.Pdistfile_list[distfile_num]->get_distfile_progress_str()); - } + if (buffer_as_str.find("Host:")==buffer_as_str.npos){ + // it's tuiclient else it's browser + FD_SET(fd, &ui_server.tuiclient_fds_set); + ui_server.serve_tuiclient(fd,buffer_as_str); + }else{ // it's browser + ui_server.serve_browser(fd,buffer_as_str); + FD_CLR(fd, &ui_server.readfds); + close(fd); + } } } } diff --git a/segget/ui_server.h b/segget/ui_server.h index 3581564..38c12f2 100644 --- a/segget/ui_server.h +++ b/segget/ui_server.h @@ -53,7 +53,7 @@ class Tui_server{ bool send_to_fd_busy; uint server_sockfd; uint max_fd_num; - fd_set readfds, testfds; + fd_set readfds, tuiclient_fds_set, testfds; void init(); ulong send_to_fd(uint fd, string msg); void send_connection_msg_to_fd(uint fd, uint y, string msg); @@ -62,6 +62,13 @@ class Tui_server{ void send_error_log_msg_to_all_clients(string msg); void send_distfile_progress_msg_to_fd(uint fd, string msg); void send_distfile_progress_msg_to_all_clients(string msg); + void serve_tuiclient(uint fd, string msg); + ulong send_binary_to_fd(uint fd, string image_file_name); + string get_header(string title); + string get_footer(); + string serve_browser_distfile_progress(Tdistfile * a_distfile); + string get_connections_info(); + void serve_browser(uint fd, string msg); }; extern Tui_server ui_server; diff --git a/segget/webui/img/blue_progress.jpg b/segget/webui/img/blue_progress.jpg Binary files differnew file mode 100644 index 0000000..8bbefa5 --- /dev/null +++ b/segget/webui/img/blue_progress.jpg diff --git a/segget/webui/img/bw_progress.jpg b/segget/webui/img/bw_progress.jpg Binary files differnew file mode 100644 index 0000000..3ddcc2c --- /dev/null +++ b/segget/webui/img/bw_progress.jpg diff --git a/segget/webui/img/connections.jpg b/segget/webui/img/connections.jpg Binary files differnew file mode 100644 index 0000000..9e01fef --- /dev/null +++ b/segget/webui/img/connections.jpg diff --git a/segget/webui/img/distfiles.png b/segget/webui/img/distfiles.png Binary files differnew file mode 100644 index 0000000..3ab0137 --- /dev/null +++ b/segget/webui/img/distfiles.png diff --git a/segget/webui/img/errors_log.jpg b/segget/webui/img/errors_log.jpg Binary files differnew file mode 100644 index 0000000..f5fd776 --- /dev/null +++ b/segget/webui/img/errors_log.jpg diff --git a/segget/webui/img/favicon.ico b/segget/webui/img/favicon.ico Binary files differnew file mode 100644 index 0000000..5de5955 --- /dev/null +++ b/segget/webui/img/favicon.ico diff --git a/segget/webui/img/green_progress.jpg b/segget/webui/img/green_progress.jpg Binary files differnew file mode 100644 index 0000000..6c8a48d --- /dev/null +++ b/segget/webui/img/green_progress.jpg diff --git a/segget/webui/img/log.png b/segget/webui/img/log.png Binary files differnew file mode 100644 index 0000000..dd2a17a --- /dev/null +++ b/segget/webui/img/log.png |