WebUI with file list - now fully functional

Discussion of the Web Interface for Transmission, formerly known as Clutch. This applies to all version of Transmission
eztrans
Posts: 18
Joined: Fri Dec 19, 2008 2:30 am

Re: WebUI with file list - now fully functional

Post by eztrans »

Hi,

I used to use the cgi web interface with v1.22. I like the graph it provided and have missed that with the new version of transmission and the new web UI.

Since there didn't seem to be much interest in adding the statistics gathering code to transmission itself, I wrote a bash script that uses transmission-remote to collect the information and log it to the system log.

The script is then executed by cron every 5 minutes. For each torrent being managed by transmission, it collects the up/down speed. It then totals these up, and collects the system time and load.

This information is all logged.

The script then uses an updated version of the cgi-webui scripts plot code to generate a plot image, one for each torrent, and one showing only the totals for all. The images are then placed within the images directory in the web area.

I then altered transmission.js so that when the inspector panel is visible, the appropriate plot is displayed at the bottom of the activity tab.

I've only just got it all working, and my plan is to run it for a few days now to ensure it's actually working properly.

If people are interested in such a mechanism, I can then attach the files here. I have no idea on how to integrate it into the repository, or how to set up the dependency on gnuplot.

regards,

eztrans
def
Posts: 1
Joined: Thu Jan 22, 2009 2:00 pm

Re: WebUI with file list - now fully functional

Post by def »

Over the past few weeks I've been working on integrating file listings into the web interface as well. My approach has been similar to what has been discussed here. I started my work on the 1.5x branch, revision 7737, which I thought was the latest development version. Unfortunately I missed this thread...

Now my implementation works now but still has a few rough edges. I had some performance problems when having 50+ torrents with many files, but these are fixed now. Also priorities are only shown, the cannot be changed yet.

Now I'm curious about the status of all of this development. You were talking about rebuilding the whole web interface? Has this work started yet? Is there something in svn? Would people be interested in my changes once I'm finished with it or is all the work going into the new webinterface anyway?
duncanbeevers
Posts: 19
Joined: Thu Nov 16, 2006 8:36 pm
Location: Portland OR

Re: WebUI with file list - now fully functional

Post by duncanbeevers »

Work has been ongoing on a new interface. There's still a lot left to be done, but you can play with it now.

Check out the latest version at http://svn.dweebd.com/transmissionwebui/spinoffs/webui

Files-lists, per-file wantedness and priority are already implemented. Work on the peers list is in-progress. Lots still needs to be done on the user preferences and adding torrents. There's also a heap of graphical work to be done. Anyway, jump on IRC and say hi or just grab the code, start hacking, and email patches.

Work you've already done on retro-fitting the existing web interface may be interesting, so feel free to share those patches as well.
miraelsol
Posts: 1
Joined: Sat Jan 17, 2009 2:06 pm

Re: WebUI with file list - now fully functional

Post by miraelsol »

Hi eztrans,
I would prefer if the transmission deamon had an option to provide logging to a user selectable file. But that doesn't seem available so I would be interested in your scripts if you make them available. Cheers.
eztrans
Posts: 18
Joined: Fri Dec 19, 2008 2:30 am

Re: WebUI with file list - now fully functional

Post by eztrans »

Hi miraelsol,

I agree. I had requested a new feature in the daemon that would allow us to get it to automatically output statistics via logging. It would be much better than the cron scripts.

They are working fairly well after a week, but there's some tweaking to be done as the output I'm getting isn't quite working properly.

Also, because I'm running this all on a small asus router, the in-memory system log doesn't give statistics that last long. I need to look at getting the stats output to a disk file that can be larger, but size/time limited some how.

What I'll do this weekend if I can is bundle the scripts together into a tar and place them here. My knowledge of linux is limited, and I'm sure that there are some enterprising individuals out there that can improve them if they so desire.

eztrans
eztrans
Posts: 18
Joined: Fri Dec 19, 2008 2:30 am

Re: WebUI with file list - now fully functional

Post by eztrans »

Hi,

I said I'd get around to this and finally I have. The scripts seem to be running fairly well now. Please note that these are all being run via cron on my asus router which is running transmission-daemon v1.41b4.

The scripts make use of gnuplot to generate the graphs in the images directory in the web interface directory, so you will need to make sure that gnuplot is installed and available.

I know these aren't brilliantly written, but they work.

The first script (get_all_stats.sh) is:

Code: Select all

#!/opt/bin/bash
#
# Script to plot a up/download graph for each active torrent.
#
export TARGET=/shares/MYVOLUME1/MYSHARE1/TORRENT/target
export WORK=/shares/MYVOLUME1/MYSHARE1/TORRENT

# get the list of active torrents.
#
transmission-remote -l > ${TARGET}/tmp1

# now strip out all but the torrent number.
#
cat ${TARGET}/tmp1 | awk -F\  '{ if ($1 != "ID") print $1; }' > ${TARGET}/tmp2

export TORRENTS=`cat ${TARGET}/tmp2`

# function that will ask transmission for the name of a torrent using the torrent number as
# an input parameter.
#
getTorrentStats() {
 transmission-remote -t $1 -i > ${TARGET}/tmp3;
 export TORRENTNAME=`cat ${TARGET}/tmp3 | grep Name: | awk -F: '{ print $2; }' | sed -e "s/^ //g"`;
 export TORRENTDOWN=`cat ${TARGET}/tmp3 | grep "Download Speed:" | awk -F\  '{ print $3; }' | sed -e "s/^ //g"`;
 export TORRENTUP=`cat ${TARGET}/tmp3 | grep "Upload Speed:" | awk -F\  '{ print $3; }' | sed -e "s/^ //g"`;
 export TORRENTSTATE=`cat ${TARGET}/tmp3 | grep "State:" | awk -F\  '{ print $2; }' | sed -e "s/^ //g"`;
}

# function that will ask transmission for the name of a seed using the torrent number as
# an input parameter.
#
getTorrentName() {
 transmission-remote -t $1 -i > ${TARGET}/tmp3;
 export TORRENTNAME=`cat ${TARGET}/tmp3 | grep Name: | awk -F: '{ print $2; }' | sed -e "s/^ //g"`;
}

# This function will plot the data for the specified torrent.
#
doPlot() {
 export WORK=/shares/MYVOLUME1/MYSHARE1/TORRENT
 export GNUPLOT=/opt/bin/gnuplot
 export GNUPLOT_COMMAND=${WORK}/transfer.gnuplot
 export GNUPLOT_DATA=${WORK}/trans.data

 if [ $1 == "ALL" ]; then
   export GNUPLOT_OUTPUT=/opt/share/transmission/web/images/transfer.png
 else
   export GNUPLOT_OUTPUT=/opt/share/transmission/web/images/transfer_$1.png
 fi

#TZ offset in seconds. Use +- sign. DST manually
 export TIMEZONE_OFFSET=+39600

 if [ $1 == "ALL" ]; then
   logread | sed  -n -e "/transmission/{s/.* \([0-9]\{1,10\}\) ALL \([0-9.]\{1,\}\) \([0-9.]\{1,\}\) \([0-9.]\{1,\}\)/\1 \2 -\3 \4/;t data;p;b;:data w ${GNUPLOT_DATA}" -e "}"
 else
   export SEDEXP="/transmission/{s/.* \([0-9]\{1,10\}\) ${1} \([0-9.]\{1,\}\) \([0-9.]\{1,\}\) \([0-9.]\{1,\}\) \([0-9.]\{1,\}\) \([0-9.]\{1,\}\)/\1 \2 -\3 \6 \4 \5/;t data;p;b;:data w ${GNUPLOT_DATA}"
   logread | sed  -n -e "${SEDEXP}" -e "}"
 fi

 if [ ! -x ${GNUPLOT} ]; then
   echo "<p>gnuplot: ${GNUPLOT} not found. Properly configure paths "
   echo "in transmission.conf for transfer graphing!</p>"
   return
 fi

 if [ ! -s ${GNUPLOT_DATA} ]; then
   # No data, don't bother trying to plot anything.
   return
 fi

 TZO=${TIMEZONE_OFFSET:-0}
cat > ${GNUPLOT_COMMAND} << __EOF__
set terminal png small size 800,600
set output '${GNUPLOT_OUTPUT}'
set xdata time
set timefmt "%s"
set format x "%H:%M\n%m/%d"
set ytics nomirror
set y2tics nomirror
set y2range [0:]
set ylabel "Transmission transfer rate [kB/s]"
set y2label "System load (5 min average)"
set y2tics (0,25,50,75,100)
set xlabel "Time [UTC ${TZO} seconds] - $2"
__EOF__

if [ $1 == "ALL" ]; then
cat >> ${GNUPLOT_COMMAND} << __EOF__
plot '${GNUPLOT_DATA}' using (\$1+${TZO}):2 title 'total download' axis x1y1 with impulses, \
    '${GNUPLOT_DATA}' using (\$1+${TZO}):3 title 'total upload' with impulses, \
    '${GNUPLOT_DATA}' using (\$1+${TZO}):(\$4*100.0) axis x1y2 title 'load' with lines
quit
__EOF__
else
cat >> ${GNUPLOT_COMMAND} << __EOF__
plot '${GNUPLOT_DATA}' using (\$1+${TZO}):2 title 'download' axis x1y1 with impulses, \
    '${GNUPLOT_DATA}' using (\$1+${TZO}):3 title 'upload' with impulses, \
    '${GNUPLOT_DATA}' using (\$1+${TZO}):5 axis x1y1 title 'total download' with lines, \
    '${GNUPLOT_DATA}' using (\$1+${TZO}):6 axis x1y1 title 'total upload' with lines, \
    '${GNUPLOT_DATA}' using (\$1+${TZO}):(\$4*100.0) axis x1y2 title 'load' with lines
quit
__EOF__
fi

 ${GNUPLOT} ${GNUPLOT_COMMAND}
}

# Now, for each torrent in the list, calculate the totals, and log them.
#
export TOTALDOWN=0.0
export TOTALUP=0.0
export LOAD=`uptime | awk -F, '{ print $5 }' | sed -e "s/ //g"`
export NOW=`date +%s`
export TOTALS=`transmission-remote -t a -i | grep "Speed" | awk -F\  '{ if ($1 == "Download") downl += $3; if ($1 == "Upload") upl += $3} END {print downl, " ", upl}' | sed -e "s/   / /g"`

for TORRENT in ${TORRENTS};
do
 export TORRENTNO=`echo ${TORRENT} | awk -F\t '{ print $1 };'`
 getTorrentStats $TORRENTNO

 if [ ${TORRENTSTATE} != "Stopped" ]; then
   echo "${TORRENTNO} ${TORRENTNAME} ${TORRENTDOWN} / ${TORRENTUP}, Totals: ${TOTALS}, Load: ${LOAD}"
   logger -t transmission "${NOW} ${TORRENTNO} ${TORRENTDOWN} ${TORRENTUP} ${TOTALS} ${LOAD}"
 fi
done;

# this allows us to plot an overall up/down graph
echo "ALL ${TOTALS}, Load: ${LOAD}"
logger -t transmission "${NOW} ALL ${TOTALS} ${LOAD}"

# now plot each torrent's data.
for TORRENT in ${TORRENTS};
do
 export TORRENTNO=`echo ${TORRENT} | awk -F\t '{ print $1 };'`
 getTorrentName $TORRENTNO
 doPlot ${TORRENTNO} "${TORRENTNAME}"
done;

# plot the overall stats
doPlot ALL "Total Bandwidth Usage"

# remove any temp files.
rm ${TARGET}/tmp1
rm ${TARGET}/tmp2
rm ${TARGET}/tmp3
This script is for those of us with limited bandwidth and ISP's that include uploads in the usage meter. It basically detects a complete and seeding torrent, removes it from transmission and places the downloaded files in a target directory:

Code: Select all

#!/opt/bin/bash
#
# Script to move all seeding file to a target directory.
#
export TARGET=/shares/MYVOLUME1/MYSHARE1/TORRENT/target
export WORK=/shares/MYVOLUME1/MYSHARE1/TORRENT

# get the list of seeding torrents.
#
transmission-remote -l | grep "100% *Done .* Idle" > ${TARGET}/tmpmo1

# now strip out all but the torrent number.
#
cat ${TARGET}/tmpmo1 | awk -F\  '{ if ($1 != "ID") print $1; }' > ${TARGET}/tmpmo2

export SEEDS=`cat ${TARGET}/tmpmo2`

# function that will ask transmission for the name of a seed using the torrent number as
# an input parameter.
#
getSeedName() {
 transmission-remote -t $1 -i | grep Name: | awk -F: '{ print $2; }' | sed -e "s/^ //g"
}

# Now, for each seed in the list, get the name, remove it from transmission, and automatically move
# the downloaded file(s) to the target area.
#
for SEED in ${SEEDS};
do
 export SEEDNO=`echo ${SEED} | awk -F\t '{ print $1 };'`
 export SEEDNAME=`getSeedName "${SEEDNO}"`

 echo "From: <from@address>" > ${TARGET}/tmpmo3
 echo "To: <to@address>" >> ${TARGET}/tmpmo3
 echo "Subject: ${SEEDNAME} is complete" >> ${TARGET}/tmpmo3
 echo "Moving \"${WORK}/${SEEDNAME}\" to \"${TARGET}\"" >> ${TARGET}/tmpmo3

 transmission-remote -t ${SEEDNO} -r
 chmod 777 "${WORK}/${SEEDNAME}"
 mv "${WORK}/${SEEDNAME}" ${TARGET}
 mini_sendmail -sserver.com -t < ${TARGET}/tmpmo3
done;

rm ${TARGET}/tmpmo1
rm ${TARGET}/tmpmo2
rm ${TARGET}/tmpmo3
Finally, this is the file within the transmission web UI that I changed to include the graphs generated by the get_all_stats.sh script (Note that the only lines I changed include the term "image_prefix" or "image_suffix) I've included in the code snipped below only the area I changed (due to size limitations):

I was going to include the entire file here or attach it, but no matter what I try it's either too big, or the forum doesn't like the filename. So if you want the entire file, PM me, and I'll try to get it to you that way.

Code: Select all

...
       /*
        * Update the inspector with the latest data for the selected torrents
        */
       updateInspector: function() {
               if (!this[Prefs._ShowInspector]) return;

               var torrents = this.getSelectedTorrents();
               if (!torrents.length && iPhone) {
                       transmission.hideInspector();
                       return;
               }

               var creator = 'N/A';
               var comment = 'N/A';
               var date_created = 'N/A';
               var error = '';
               var hash = 'N/A';
               var have_public = false;
               var have_private = false;
               var name;
               var sizeWhenDone = 0;
               var sizeDone = 0;
               var total_completed = 0;
               var total_download = 0;
               var total_download_peers = 0;
               var total_download_speed = 0;
               var total_have = 0;
               var total_leechers = 0;
               var total_size = 0;
               var total_seeders = 0;
               var total_state = null;
               var total_swarm_speed = 0;
               var total_tracker = null;
               var total_upload = 0;
               var total_upload_peers = 0;
               var total_upload_speed = 0;
               var total_verified = 0;
               var na = 'N/A';
               var image_prefix = '<img src="images/transfer';
               var image_suffix = '.png" alt="Activity" width="100%" scalefit="1"/>';

               $("#torrent_inspector_size, .inspector_row div").css('color', '#222');

               if (0 == torrents.length) {
                       var ti = '#torrent_inspector_';
                       setInnerHTML( $(ti+'name')[0], 'No Selection' );
                       setInnerHTML( $(ti+'size')[0], na );
                       setInnerHTML( $(ti+'tracker')[0], na );
                       setInnerHTML( $(ti+'hash')[0], na );
                       setInnerHTML( $(ti+'state')[0], na );
                       setInnerHTML( $(ti+'download_speed')[0], na );
                       setInnerHTML( $(ti+'upload_speed')[0], na );
                       setInnerHTML( $(ti+'uploaded')[0], na );
                       setInnerHTML( $(ti+'downloaded')[0], na );
                       setInnerHTML( $(ti+'ratio')[0], na );
                       setInnerHTML( $(ti+'total_seeders')[0], na );
                       setInnerHTML( $(ti+'total_leechers')[0], na );
                       setInnerHTML( $(ti+'graph_image')[0], image_prefix + image_suffix );
                       setInnerHTML( $(ti+'swarm_speed')[0], na );
                       setInnerHTML( $(ti+'have')[0], na );
                       setInnerHTML( $(ti+'upload_to')[0], na );
                       setInnerHTML( $(ti+'download_from')[0], na );
                       setInnerHTML( $(ti+'secure')[0], na );
                       setInnerHTML( $(ti+'creator_date')[0], na );
                       setInnerHTML( $(ti+'progress')[0], na );
                       setInnerHTML( $(ti+'comment')[0], na );
                       setInnerHTML( $(ti+'creator')[0], na );
                       setInnerHTML( $(ti+'error')[0], na );
                       this.updateVisibleFileLists();
                       $("#torrent_inspector_size, .inspector_row > div:contains('N/A')").css('color', '#666');
                       return;
               }

               name = torrents.length == 1
                       ? torrents[0].name()
                       : torrents.length+' Transfers Selected';

               if( torrents.length == 1 )
               {
                       var t = torrents[0];
                       if( t._error_message )
                       {
                               error = t._error_message ;
                       }
                       if( t._comment)
                       {
                               comment = t._comment ;
                       }
                       if( t._creator )
                       {
                               creator = t._creator ;
                       }
                       hash = t.hash();
                       date_created = Math.formatTimestamp( t._creator_date );
               }

               for(i = 0; i < torrents.length; ++i ) {
                       var t = torrents[i];
                       sizeWhenDone         += t._sizeWhenDone;
                       sizeDone             += t._sizeWhenDone - t._leftUntilDone;
                       total_completed      += t.completed();
                       total_verified       += t._verified;
                       total_size           += t.size();
                       total_upload         += t.uploadTotal();
                       total_download       += t.downloadTotal();
                       total_upload_speed   += t.uploadSpeed();
                       total_download_speed += t.downloadSpeed();
                       total_seeders        += t.totalSeeders();
                       total_leechers       += t.totalLeechers();
                       total_upload_peers   += t.peersGettingFromUs();
                       total_download_peers += t.peersSendingToUs();
                       total_swarm_speed    += t.swarmSpeed();
                       if( total_state == null )
                               total_state = t.stateStr();
                       else if ( total_state.search ( t.stateStr() ) == -1 )
                               total_state += '/' + t.stateStr();
                       var tracker = t._tracker;
                       if( total_tracker == null )
                               total_tracker = tracker;
                       else if ( total_tracker.search ( tracker ) == -1 )
                               total_tracker += ', ' + tracker;
                       if( t._is_private )
                               have_private = true;
                       else
                               have_public = true;
               }

               var private_string = '';
               if( have_private && have_public ) private_string = 'Mixed';
               else if( have_private ) private_string = 'Private Torrent';
               else if( have_public ) private_string = 'Public Torrent';

               var ti = '#torrent_inspector_';
               $(ti+'name')[0].innerHTML            = name;
               $(ti+'size')[0].innerHTML            = torrents.length ? Math.formatBytes( total_size ) : 'N/A';
               $(ti+'tracker')[0].innerHTML         = total_tracker;
               $(ti+'hash')[0].innerHTML            = hash;
               $(ti+'state')[0].innerHTML           = total_state;
               $(ti+'download_speed')[0].innerHTML  = torrents.length ? Math.formatBytes( total_download_speed ) + '/s' : 'N/A';
               $(ti+'upload_speed')[0].innerHTML    = torrents.length ? Math.formatBytes( total_upload_speed ) + '/s' : 'N/A';
               $(ti+'uploaded')[0].innerHTML        = torrents.length ? Math.formatBytes( total_upload ) : 'N/A';
               $(ti+'downloaded')[0].innerHTML      = torrents.length ? Math.formatBytes( total_download ) : 'N/A';
               $(ti+'ratio')[0].innerHTML           = torrents.length ? Math.ratio( total_upload, total_download ) : 'N/A';
               $(ti+'total_seeders')[0].innerHTML   = torrents.length ? total_seeders : 'N/A';
               $(ti+'total_leechers')[0].innerHTML  = torrents.length ? total_leechers : 'N/A';
               $(ti+'graph_image')[0].innerHTML     = image_prefix + '_' + torrents[0].id() + image_suffix;
               $(ti+'swarm_speed')[0].innerHTML     = torrents.length ? Math.formatBytes(total_swarm_speed) + '/s' : 'N/A';
               $(ti+'have')[0].innerHTML            = torrents.length ? Math.formatBytes(total_completed) + ' (' + Math.formatBytes(total_verified) + ' verified)' : 'N/A';
               $(ti+'upload_to')[0].innerHTML       = torrents.length ? total_upload_peers : 'N/A';
               $(ti+'download_from')[0].innerHTML   = torrents.length ? total_download_peers : 'N/A';
               $(ti+'secure')[0].innerHTML          = private_string;
               $(ti+'creator_date')[0].innerHTML    = date_created;
               $(ti+'progress')[0].innerHTML        = torrents.length ? Math.ratio( sizeDone*100, sizeWhenDone ) + '%' : 'N/A';
               $(ti+'comment')[0].innerHTML         = comment;
               $(ti+'creator')[0].innerHTML         = creator;
               $(ti+'error')[0].innerHTML           = error;

               $(".inspector_row > div:contains('N/A')").css('color', '#666');
               this.updateVisibleFileLists();
       },
...

duncanbeevers
Posts: 19
Joined: Thu Nov 16, 2006 8:36 pm
Location: Portland OR

Re: WebUI with file list - now fully functional

Post by duncanbeevers »

Ambitious!
eztrans
Posts: 18
Joined: Fri Dec 19, 2008 2:30 am

Re: WebUI with file list - now fully functional

Post by eztrans »

Not really meant to be. I just like to get a feeling for how active things are. My logs on the machine are very small so I typically only get about 4 hours of graphing. I plan to update the scripts to manage a log file per torrent, but that a bell/whistle that can come later.

eztrans
snake98
Posts: 8
Joined: Thu Jul 10, 2008 9:30 pm

Re: WebUI with file list - now fully functional

Post by snake98 »

eztrans
I can't get it to display, it shuts down the transmission web interface, no torrents are dispalyed

here is what i did

vi /opt/share/transmission/web/javascript/transmission.js

here are the four lines of code

var image_prefix = '<img src="images/transfer';
var image_suffix = '.png" alt="Activity" width="100%" scalefit="1"/>';


setInnerHTML( $(ti+'graph_image')[0], image_prefix + image_suffix );

$(ti+'graph_image')[0].innerHTML = image_prefix + '_' + torrents[0].id() + image_suffix;

to add web interface, and a total of 4 lines,

If i delete this line

$(ti+'graph_image')[0].innerHTML = image_prefix + '_' + torrents[0].id() + 1;

the website works again, but no graph

all so line 40 of get_all_stat.sh has a hard path for work, probably should delete that line

but the script isn't make any data, all I have is trans.data in my work folder, but it's blank
Last edited by snake98 on Fri Mar 13, 2009 12:17 am, edited 1 time in total.
eztrans
Posts: 18
Joined: Fri Dec 19, 2008 2:30 am

Re: WebUI with file list - now fully functional

Post by eztrans »

snake98,

The line you are removing shouldn't break the webui, but as it is, some info: The get_all_stats script will generate a graph for each active torrent, and then one more that provides a total bandwidth graph. The idea is that when a torrent is selected in the webui, you see that torrent's graph. When none is selected, you see the graph of total bandwidth. So the one that's breaking is the one that shows the total bandwidth.

Now onto the next part of your msg:

1. do you have gnuplot installed?
2. is it on the path?
3. this script was written to run on an asus wl700ge router. as such the "logger" command outputs a line to the system log. to read the log and collect the stats in the trans.data file the script uses the logread command (~ lines 55, 58). If you're not running on the same router, then logread may not work, and you may need to change this to cat the system log file where your logger command is logging to.

When logger logs on my router, I get lines such as:

Mar 12 12:00:15 transmission: 1236823202 ALL 0 0 0.08
Mar 12 12:04:08 transmission: 1236823444 1 0.0 0.0 0 0 0.07

If your logger command is not outputting the same format to the log file then the lines beginning with logread in the script may not find the data you're after which would be a pain as it might involve reworking the regular expressions at ~line 55,58.

Yes there are a few hard paths. Sorry; I thought I had tidied it up a bit for the forum but obviously I missed a couple of things.

Let me know if that helps at all.
snake98
Posts: 8
Joined: Thu Jul 10, 2008 9:30 pm

Re: WebUI with file list - now fully functional

Post by snake98 »

Could you where what the target and work directory need to point to?
I assume this works on bt 1.51, I'm running on a wrt600n, with dd-wrt sp2, gnuplot is installed, and logread and logger are also

okay I made the change, my logread doesn't work

and my trans.data is still blank it's something with the sed command

also this is the line that crashes the web i had the wrong one before

setInnerHTML( $(ti+'graph_image')[0], image_prefix + image_suffix );

Code: Select all

export readlog="cat /var/log/messages"
...

if [ $1 == "ALL" ]; then
   $readlog | sed  -n -e "/transmission/{s/.* \([0-9]\{1,10\}\) ALL \([0-9.]\{1,\}\) \([0-9.]\{1,\}\) \([0-9.]\{1,\}\)/\1 \2 -\3 \4/;t data;p;b;:data w ${GNUPLOT_DATA}" -e "}"
else
   export SEDEXP="/transmission/{s/.* \([0-9]\{1,10\}\) ${1} \([0-9.]\{1,\}\) \([0-9.]\{1,\}\) \([0-9.]\{1,\}\) \([0-9.]\{1,\}\) \([0-9.]\{1,\}\)/\1 \2 -\3 \6 \4 \5/;t data;p;b;:data w ${GNUPLOT_DATA}"
   $readlog | sed  -n -e "${SEDEXP}" -e "}"
fi

Here is my out put when I run the scripts, still no images in /opt/share/transmission/web/images

Code: Select all

root@wrt600n:/tmp/var/log# /opt/scripts/torrent_graph_get_all.sh
1 Looney Tunes - Golden Collection Volume 6 30.7 / 0.0, Totals: 96.9 5, Load:
3 Earth 2 12.9 / 5.0, Totals: 96.9 5, Load:
4 Tiny Toon Adventures 26.8 / 0.0, Totals: 96.9 5, Load:
/opt/scripts/torrent_graph_get_all.sh: line 122: [: too many arguments
ALL 96.9 5, Load:
Mar 12 07:19:22 wrt600n user.notice transmission: 1236842356 1 15.3 0.0 107.9 5
Mar 12 07:19:27 wrt600n user.notice transmission: 1236842356 2 103.6 3.5 107.9 5
Mar 12 07:19:40 wrt600n user.notice transmission: 1236842356 4 9.7 1.5 107.9 5
Mar 12 07:19:42 wrt600n user.notice transmission: 1236842356 ALL 107.9 5
Mar 12 07:26:40 wrt600n user.notice transmission: test
Mar 12 08:31:54 wrt600n user.notice transmission: 1236846672 1 30.7 0.0 96.9 5
Mar 12 08:31:58 wrt600n user.notice transmission: 1236846672 3 12.9 5.0 96.9 5
Mar 12 08:32:17 wrt600n user.notice transmission: 1236846672 4 26.8 0.0 96.9 5
Mar 12 08:32:39 wrt600n user.notice transmission: 1236846672 ALL 96.9 5
Mar 12 07:19:22 wrt600n user.notice transmission: 1236842356 1 15.3 0.0 107.9 5
Mar 12 07:19:27 wrt600n user.notice transmission: 1236842356 2 103.6 3.5 107.9 5
Mar 12 07:19:40 wrt600n user.notice transmission: 1236842356 4 9.7 1.5 107.9 5
Mar 12 07:19:42 wrt600n user.notice transmission: 1236842356 ALL 107.9 5
Mar 12 07:26:40 wrt600n user.notice transmission: test
Mar 12 08:31:54 wrt600n user.notice transmission: 1236846672 1 30.7 0.0 96.9 5
Mar 12 08:31:58 wrt600n user.notice transmission: 1236846672 3 12.9 5.0 96.9 5
Mar 12 08:32:17 wrt600n user.notice transmission: 1236846672 4 26.8 0.0 96.9 5
Mar 12 08:32:39 wrt600n user.notice transmission: 1236846672 ALL 96.9 5
Mar 12 07:19:22 wrt600n user.notice transmission: 1236842356 1 15.3 0.0 107.9 5
Mar 12 07:19:27 wrt600n user.notice transmission: 1236842356 2 103.6 3.5 107.9 5
Mar 12 07:19:40 wrt600n user.notice transmission: 1236842356 4 9.7 1.5 107.9 5
Mar 12 07:19:42 wrt600n user.notice transmission: 1236842356 ALL 107.9 5
Mar 12 07:26:40 wrt600n user.notice transmission: test
Mar 12 08:31:54 wrt600n user.notice transmission: 1236846672 1 30.7 0.0 96.9 5
Mar 12 08:31:58 wrt600n user.notice transmission: 1236846672 3 12.9 5.0 96.9 5
Mar 12 08:32:17 wrt600n user.notice transmission: 1236846672 4 26.8 0.0 96.9 5
Mar 12 08:32:39 wrt600n user.notice transmission: 1236846672 ALL 96.9 5
Mar 12 07:19:22 wrt600n user.notice transmission: 1236842356 1 15.3 0.0 107.9 5
Mar 12 07:19:27 wrt600n user.notice transmission: 1236842356 2 103.6 3.5 107.9 5
Mar 12 07:19:40 wrt600n user.notice transmission: 1236842356 4 9.7 1.5 107.9 5
Mar 12 07:19:42 wrt600n user.notice transmission: 1236842356 ALL 107.9 5
Mar 12 07:26:40 wrt600n user.notice transmission: test
Mar 12 08:31:54 wrt600n user.notice transmission: 1236846672 1 30.7 0.0 96.9 5
Mar 12 08:31:58 wrt600n user.notice transmission: 1236846672 3 12.9 5.0 96.9 5
Mar 12 08:32:17 wrt600n user.notice transmission: 1236846672 4 26.8 0.0 96.9 5
Mar 12 08:32:39 wrt600n user.notice transmission: 1236846672 ALL 96.9 5
Mar 12 07:19:22 wrt600n user.notice transmission: 1236842356 1 15.3 0.0 107.9 5
Mar 12 07:19:27 wrt600n user.notice transmission: 1236842356 2 103.6 3.5 107.9 5
Mar 12 07:19:40 wrt600n user.notice transmission: 1236842356 4 9.7 1.5 107.9 5
Mar 12 07:19:42 wrt600n user.notice transmission: 1236842356 ALL 107.9 5
Mar 12 07:26:40 wrt600n user.notice transmission: test
Mar 12 08:31:54 wrt600n user.notice transmission: 1236846672 1 30.7 0.0 96.9 5
Mar 12 08:31:58 wrt600n user.notice transmission: 1236846672 3 12.9 5.0 96.9 5
Mar 12 08:32:17 wrt600n user.notice transmission: 1236846672 4 26.8 0.0 96.9 5
Mar 12 08:32:39 wrt600n user.notice transmission: 1236846672 ALL 96.9 5
Last edited by snake98 on Thu Mar 12, 2009 10:30 pm, edited 1 time in total.
eztrans
Posts: 18
Joined: Fri Dec 19, 2008 2:30 am

Re: WebUI with file list - now fully functional

Post by eztrans »

snake98

Looking at the transmission lines in your output log, they all seem to be missing an entry, and this will be why the regular expressions are failing to get the data for you.

Note that in my logs:

Mar 12 12:00:15 transmission: 1236823202 ALL 0 0 0.08
Mar 12 12:04:08 transmission: 1236823444 1 0.0 0.0 0 0 0.07

And your logs:

Mar 12 08:32:39 wrt600n user.notice transmission: 1236846672 ALL 96.9 5
Mar 12 07:19:22 wrt600n user.notice transmission: 1236842356 1 15.3 0.0 107.9 5

If we strip away the date, and guff at the start we get:

transmission: 1236823202 ALL 0 0 0.08
transmission: 1236823444 1 0.0 0.0 0 0 0.07

And your logs:

transmission: 1236846672 ALL 96.9 5
transmission: 1236842356 1 15.3 0.0 107.9 5

The ALL lines should contain:

TIMENOW ALL DOWNTOTAL UPTOTAL CPULOAD

The per-torrent lines should contain:

TIMENOW TORRENTNUMBER TORRENTDOWN TORRENTUP DOWNTOTAL UPTOTAL CPULOAD

From what I can see, I'm guessing that you're missing the CPULOAD at the end. I also note that in your output, there is an error being reported at line 122 and this would be around the place the LOAD variable is set, or the TOTALS variable.

See if that helps.
snake98
Posts: 8
Joined: Thu Jul 10, 2008 9:30 pm

Re: WebUI with file list - now fully functional

Post by snake98 »

eztrans

okay I got that working I don't use the system logger anymore I use a log file, it work better.

here is my output

Code: Select all

root@wrt600n:/opt/torrent# /opt/scripts/torrent_graph_get_all.sh
1 Looney Tunes - Golden Collection Volume 6 52.0 / 4.5, Totals: 179.3 20.1, Load: 1.89
3 Earth 2 72.8 / 4.5, Totals: 179.3 20.1, Load: 1.89
4 Tiny Toon Adventures 12.7 / 3.5, Totals: 179.3 20.1, Load: 1.89
/opt/scripts/torrent_graph_get_all.sh: line 125: [: too many arguments
ALL 179.3 20.1, Load: 1.89

Earth 2
^
"/opt/torrent/transfer.gnuplot", line 13: invalid command

root@wrt600n:/opt/torrent# 

here is my trans.log

Code: Select all

cat trans.log
1236870439 1 80.4 7.4 142.6 15 1.80
1236870439 3 56.7 4.0 142.6 15 1.80
1236870439 4 26.3 0.3 142.6 15 1.80
1236870439 ALL 142.6 15 1.80
here is my torrent_get_all.sh

Code: Select all

#!/opt/bin/bash
#
# Script to plot a up/download graph for each active torrent.
#
export TARGET=/opt/torrent/target
export WORK=/opt/torrent

export readlog=${WORK}/trans.log
# get the list of active torrents.
#
transmission-remote -l > ${TARGET}/tmp1

# now strip out all but the torrent number.
#
cat ${TARGET}/tmp1 | awk -F\  '{ if ($1 != "ID") print $1; }' > ${TARGET}/tmp2

export TORRENTS=`cat ${TARGET}/tmp2`

# function that will ask transmission for the name of a torrent using the torrent number as
# an input parameter.
#
getTorrentStats() {
transmission-remote -t $1 -i > ${TARGET}/tmp3;
export TORRENTNAME=`cat ${TARGET}/tmp3 | grep Name: | awk -F: '{ print $2; }' | sed -e "s/^ //g"`;
export TORRENTDOWN=`cat ${TARGET}/tmp3 | grep "Download Speed:" | awk -F\  '{ print $3; }' | sed -e "s/^ //g"`;
export TORRENTUP=`cat ${TARGET}/tmp3 | grep "Upload Speed:" | awk -F\  '{ print $3; }' | sed -e "s/^ //g"`;
export TORRENTSTATE=`cat ${TARGET}/tmp3 | grep "State:" | awk -F\  '{ print $2; }' | sed -e "s/^ //g"`;
}

# function that will ask transmission for the name of a seed using the torrent number as
# an input parameter.
#
getTorrentName() {
transmission-remote -t $1 -i > ${TARGET}/tmp3;
export TORRENTNAME=`cat ${TARGET}/tmp3 | grep Name: | awk -F: '{ print $2; }' | sed -e "s/^ //g"`;
}

# This function will plot the data for the specified torrent.
#
doPlot() {
export GNUPLOT=/opt/bin/gnuplot
export GNUPLOT_COMMAND=${WORK}/transfer.gnuplot
export GNUPLOT_DATA=${WORK}/trans.data

if [ $1 == "ALL" ]; then
   export GNUPLOT_OUTPUT=/opt/share/transmission/web/images/transfer.png
else
   export GNUPLOT_OUTPUT=/opt/share/transmission/web/images/transfer_$1.png
fi

#TZ offset in seconds. Use +- sign. DST manually
export TIMEZONE_OFFSET=+39600

if [ $1 == "ALL" ]; then
  # $readlog | sed  -n -e "/transmission/{s/.*: \([0-9]\{1,10\}\) ALL \([0-9.]\{1,\}\) \([0-9.]\{1,\}\) \([0-9.]\{1,\}\)/\1 \2 -\3 \4/;t data;p;b;:data w ${GNUPLOT_DATA}" -e "}"
  #export readlogrun="grep ALL ${readlog} | sed s/ALL/  "
  export readlogrun=`sed -n '/ALL/p' <${readlog} | sed s/ALL//  > ${GNUPLOT_DATA}`
  $readlogrun 
  else
  # export SEDEXP="/transmission/{s/.*: \([0-9]\{1,10\}\) \([0-9.]\{1,\}\) \([0-9.]\{1,\}\) \([0-9.]\{1,\}\) \([0-9.]\{1,\}\) \([0-9.]\{1,\}\)/\1 \2 -\3 \6 \4 \5/;t data;p;b;:data w ${GNUPLOT_DATA}"
  export readlogrun=`sed -n '/ ${1} /p' <${readlog} | sed s/ ${1} / /  > ${GNUPLOT_DATA}`
  $readlogrun 
fi

if [ ! -x ${GNUPLOT} ]; then
   echo "<p>gnuplot: ${GNUPLOT} not found. Properly configure paths "
   echo "in transmission.conf for transfer graphing!</p>"
   return
fi

if [ ! -s ${GNUPLOT_DATA} ]; then
   # No data, don't bother trying to plot anything.
   return
fi

TZO=${TIMEZONE_OFFSET:-0}
cat > ${GNUPLOT_COMMAND} << __EOF__
set terminal png small size 800,600
set output '${GNUPLOT_OUTPUT}'
set xdata time
set timefmt "%s"
set format x "%H:%M\n%m/%d"
set ytics nomirror
set y2tics nomirror
set y2range [0:]
set ylabel "Transmission transfer rate [kB/s]"
set y2label "System load (5 min average)"
set y2tics (0,25,50,75,100)
set xlabel "Time [UTC ${TZO} seconds] - $2"
__EOF__

if [ $1 == "ALL" ]; then
cat >> ${GNUPLOT_COMMAND} << __EOF__
plot '${GNUPLOT_DATA}' using (\$1+${TZO}):2 title 'total download' axis x1y1 with impulses, \
    '${GNUPLOT_DATA}' using (\$1+${TZO}):3 title 'total upload' with impulses, \
    '${GNUPLOT_DATA}' using (\$1+${TZO}):(\$4*100.0) axis x1y2 title 'load' with lines
quit
__EOF__
else
cat >> ${GNUPLOT_COMMAND} << __EOF__
plot '${GNUPLOT_DATA}' using (\$1+${TZO}):2 title 'download' axis x1y1 with impulses, \
    '${GNUPLOT_DATA}' using (\$1+${TZO}):3 title 'upload' with impulses, \
    '${GNUPLOT_DATA}' using (\$1+${TZO}):5 axis x1y1 title 'total download' with lines, \
    '${GNUPLOT_DATA}' using (\$1+${TZO}):6 axis x1y1 title 'total upload' with lines, \
    '${GNUPLOT_DATA}' using (\$1+${TZO}):(\$4*100.0) axis x1y2 title 'load' with lines
quit
__EOF__
fi

${GNUPLOT} ${GNUPLOT_COMMAND}
}

# Now, for each torrent in the list, calculate the totals, and log them.
#
export TOTALDOWN=0.0
export TOTALUP=0.0
export LOAD=`uptime | awk -F, '{ print $3 }' | sed -e "s/ //g"`
export NOW=`date +%s`
export TOTALS=`transmission-remote -t a -i | grep "Speed" | awk -F\  '{ if ($1 == "Download") downl += $3; if ($1 == "Upload") upl += $3} END {print downl, " ", upl}' | sed -e "s/   / /g"`

for TORRENT in ${TORRENTS};
do
export TORRENTNO=`echo ${TORRENT} | awk -F\t '{ print $1 };'`
getTorrentStats $TORRENTNO

if [ ${TORRENTSTATE} != "Stopped" ]; then
   echo "${TORRENTNO} ${TORRENTNAME} ${TORRENTDOWN} / ${TORRENTUP}, Totals: ${TOTALS}, Load: ${LOAD}"
#     logger -t transmission "${NOW} ${TORRENTNO} ${TORRENTDOWN} ${TORRENTUP} ${TOTALS} ${LOAD}"
   echo "${NOW} ${TORRENTNO} ${TORRENTDOWN} ${TORRENTUP} ${TOTALS} ${LOAD}" >> $WORK/trans.log
fi
done;

# this allows us to plot an overall up/down graph
echo "ALL ${TOTALS}, Load: ${LOAD}"
# logger -t transmission "${NOW} ALL ${TOTALS} ${LOAD}"
echo "${NOW} ALL ${TOTALS} ${LOAD}" >> $WORK/trans.log

# now plot each torrent's data.
for TORRENT in ${TORRENTS};
do
export TORRENTNO=`echo ${TORRENT} | awk -F\t '{ print $1 };'`
getTorrentName $TORRENTNO
doPlot ${TORRENTNO} "${TORRENTNAME}"
done;

# plot the overall stats
doPlot ALL "Total Bandwidth Usage"

# remove any temp files.
rm ${TARGET}/tmp1
rm ${TARGET}/tmp2
rm ${TARGET}/tmp3

it's creating pngs now, but I can't get the website to display them, the line that is giving me problems are this line

$(ti+'graph_image')[0].innerHTML = image_prefix + '_' + torrents[0].id() + 1;

can you recheck those files or e-mail or transmission.js
Last edited by snake98 on Fri Mar 13, 2009 4:32 pm, edited 2 times in total.
eztrans
Posts: 18
Joined: Fri Dec 19, 2008 2:30 am

Re: WebUI with file list - now fully functional

Post by eztrans »

snake98,

I think the problem is in the changes you did to transmission.js.

The line:

$(ti+'graph_image')[0].innerHTML = image_prefix + '_' + torrents[0].id() + 1;

you quoted in your message should (I believe) read:

$(ti+'graph_image')[0].innerHTML = image_prefix + '_' + torrents[0].id() + image_suffix;

Not quite sure how that happened. I checked my original post and it seems OK there.

eztrans
snake98
Posts: 8
Joined: Thu Jul 10, 2008 9:30 pm

Re: WebUI with file list - now fully functional

Post by snake98 »

eztrans

I made the change but no luck here is my file

Code: Select all

		var total_upload = 0;
		var total_upload_peers = 0;
		var total_upload_speed = 0;
		var total_verified = 0;
		var na = 'N/A';
		var image_prefix = '<img src="images/transfer';
		var image_suffix = '.png" alt="Activity" width="100%" scalefit="1"/>';
		
		$("#torrent_inspector_size, .inspector_row div").css('color', '#222');

		if( torrents.length == 0 )
		{
			var ti = '#torrent_inspector_';
			setInnerHTML( $(ti+'name')[0], 'No Selection' );
			setInnerHTML( $(ti+'size')[0], na );
			setInnerHTML( $(ti+'tracker')[0], na );
			setInnerHTML( $(ti+'hash')[0], na );
			setInnerHTML( $(ti+'state')[0], na );
			setInnerHTML( $(ti+'download_speed')[0], na );
			setInnerHTML( $(ti+'upload_speed')[0], na );
			setInnerHTML( $(ti+'uploaded')[0], na );
			setInnerHTML( $(ti+'downloaded')[0], na );
			setInnerHTML( $(ti+'ratio')[0], na );
			setInnerHTML( $(ti+'total_seeders')[0], na );
			setInnerHTML( $(ti+'total_leechers')[0], na );
			setInnerHTML( $(ti+'graph_image')[0], image_prefix + image_suffix );
			setInnerHTML( $(ti+'swarm_speed')[0], na );
			setInnerHTML( $(ti+'have')[0], na );
			setInnerHTML( $(ti+'upload_to')[0], na );
			setInnerHTML( $(ti+'download_from')[0], na );
			setInnerHTML( $(ti+'secure')[0], na );
			setInnerHTML( $(ti+'creator_date')[0], na );
			setInnerHTML( $(ti+'progress')[0], na );
			setInnerHTML( $(ti+'comment')[0], na );
			setInnerHTML( $(ti+'creator')[0], na );
			setInnerHTML( $(ti+'error')[0], na );		
			$("#torrent_inspector_size, .inspector_row > div:contains('N/A')").css('color', '#666');
			return;
		}

		name = torrents.length == 1
			? torrents[0].name()
			: torrents.length+' Transfers Selected';

		if( torrents.length == 1 )
		{
			var t = torrents[0];
			if( t._error_message )
			{
				error = t._error_message ;
			}
			if( t._comment)
			{
				comment = t._comment ;
			}
			if( t._creator )
			{
				creator = t._creator ;
			}
			hash = t.hash();
			date_created = Math.formatTimestamp( t._creator_date );
		}

		for( i=0; i<torrents.length; ++i ) {
			var t = torrents[i];
			sizeWhenDone         += t._sizeWhenDone;
			sizeDone             += t._sizeWhenDone - t._leftUntilDone;
			total_completed      += t.completed();
			total_verified       += t._verified;
			total_size           += t.size();
			total_upload         += t.uploadTotal();
			total_download       += t.downloadTotal();
			total_upload_speed   += t.uploadSpeed();
			total_download_speed += t.downloadSpeed();
			total_seeders        += t.totalSeeders();
			total_leechers       += t.totalLeechers();
			total_upload_peers   += t.peersGettingFromUs();
			total_download_peers += t.peersSendingToUs();
			total_swarm_speed    += t.swarmSpeed();
			if( total_state == null )
				total_state = t.stateStr();
			else if ( total_state.search ( t.stateStr() ) == -1 )
				total_state += '/' + t.stateStr();
			var tracker = t._tracker;
			if( total_tracker == null )
				total_tracker = tracker;
			else if ( total_tracker.search ( tracker ) == -1 )  
				total_tracker += ', ' + tracker;
			if( t._is_private )
				have_private = true;
			else
				have_public = true;
		}

		var private_string = '';
		if( have_private && have_public ) private_string = 'Mixed';
		else if( have_private ) private_string = 'Private Torrent';
		else if( have_public ) private_string = 'Public Torrent';	

		var ti = '#torrent_inspector_';
		$(ti+'name')[0].innerHTML            = name;
		$(ti+'size')[0].innerHTML            = torrents.length ? Math.formatBytes( total_size ) : 'N/A';
		$(ti+'tracker')[0].innerHTML         = total_tracker;
		$(ti+'hash')[0].innerHTML            = hash;
		$(ti+'state')[0].innerHTML           = total_state;
		$(ti+'download_speed')[0].innerHTML  = torrents.length ? Math.formatBytes( total_download_speed ) + '/s' : 'N/A';
		$(ti+'upload_speed')[0].innerHTML    = torrents.length ? Math.formatBytes( total_upload_speed ) + '/s' : 'N/A';
		$(ti+'uploaded')[0].innerHTML        = torrents.length ? Math.formatBytes( total_upload ) : 'N/A';
		$(ti+'downloaded')[0].innerHTML      = torrents.length ? Math.formatBytes( total_download ) : 'N/A';
		$(ti+'ratio')[0].innerHTML           = torrents.length ? Math.ratio( total_upload, total_download ) : 'N/A';
		$(ti+'total_seeders')[0].innerHTML   = torrents.length ? total_seeders : 'N/A';
		$(ti+'total_leechers')[0].innerHTML  = torrents.length ? total_leechers : 'N/A';
		$(ti+'graph_image')[0].innerHTML     = image_prefix + '_' + torrents[0].id() + image_suffix;
		$(ti+'swarm_speed')[0].innerHTML     = torrents.length ? Math.formatBytes(total_swarm_speed) + '/s' : 'N/A';
		$(ti+'have')[0].innerHTML            = torrents.length ? Math.formatBytes(total_completed) + ' (' + Math.formatBytes(total_verified) + ' verified)' : 'N/A';
		$(ti+'upload_to')[0].innerHTML       = torrents.length ? total_upload_peers : 'N/A';
		$(ti+'download_from')[0].innerHTML   = torrents.length ? total_download_peers : 'N/A';
		$(ti+'secure')[0].innerHTML          = private_string;
		$(ti+'creator_date')[0].innerHTML    = date_created;
		$(ti+'progress')[0].innerHTML        = torrents.length ? Math.ratio( sizeDone*100, sizeWhenDone ) + '%' : 'N/A';
		$(ti+'comment')[0].innerHTML         = comment;
		$(ti+'creator')[0].innerHTML         = creator;
		$(ti+'error')[0].innerHTML           = error;
		
		$(".inspector_row > div:contains('N/A')").css('color', '#666');
	},
Post Reply