Changeset 401

Show
Ignore:
Timestamp:
07/02/08 08:17:50 (2 months ago)
Author:
charles
Message:

(1) implement sorting by tracker, by ratio, and by activity. (2) get the torrent list's pause/resume button working again. (3) fix ratio error.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/rpc/web/javascript/common.js

    r400 r401  
    254254} 
    255255 
     256/** 
     257 * @brief strcmp()-style compare useful for sorting 
     258 */ 
     259String.prototype.compareTo = function( that ) { 
     260        // FIXME: how to fold these two comparisons together? 
     261        if( this < that ) return -1; 
     262        if( this > that ) return 1; 
     263        return 0; 
     264} 
     265 
     266 
    256267/*** 
    257268****  Preferences 
  • branches/rpc/web/javascript/torrent.js

    r400 r401  
    1212 
    1313// Constants 
    14 Torrent._StatusSeeding         = 'seeding'
    15 Torrent._StatusDownloading     = 'downloading'
    16 Torrent._StatusPaused          = 'paused'
    17 Torrent._StatusChecking        = 'verifying local data'
    18 Torrent._StatusWaitingToCheck  =  'waiting to verify'
     14Torrent._StatusWaitingToCheck  = 1
     15Torrent._StatusChecking        = 2
     16Torrent._StatusDownloading     = 4
     17Torrent._StatusSeeding         = 8
     18Torrent._StatusPaused          = 16
    1919Torrent._InfiniteTimeRemaining = 215784000; // 999 Hours - may as well be infinite 
    2020Torrent._MaxProgressBarWidth   = 100; // reduce this to make the progress bar shorter (%) 
     
    132132        size: function() { return this._size; }, 
    133133        state: function() { return this._state; }, 
     134        stateStr: function() { 
     135                switch( this.state() ) { 
     136                        case Torrent._StatusSeeding:        return 'Seeding'; 
     137                        case Torrent._StatusDownloading:    return 'Downloading'; 
     138                        case Torrent._StatusPaused:         return 'Paused'; 
     139                        case Torrent._StatusChecking:       return 'Verifying local data'; 
     140                        case Torrent._StatusWaitingToCheck: return 'Waiting to verify'; 
     141                        default:                            return 'error'; 
     142                } 
     143        }, 
    134144        swarmSpeed: function() { return this._swarm_speed; }, 
    135145        totalLeechers: function() { return this._total_leechers; }, 
     
    207217         * Process a click event on the pause/resume button 
    208218         */ 
    209         clickPauseResumeButton: function(event) { 
    210                 // Prevents click event resulting in selection of torrent 
     219        clickPauseResumeButton: function( event ) 
     220        { 
     221                // prevent click event resulting in selection of torrent 
    211222                event.stopPropagation(); 
     223 
     224                // either stop or start the torrent 
    212225                var torrent = event.data.element._torrent; 
    213                  
    214                 var action; 
    215                 var name; 
    216                 if( torrent.isActive( ) ) { 
    217                         name = "torrent_pause"; 
    218                         action = 'pauseTorrents'; 
    219                 } else { 
    220                         name = "torrent_resume"; 
    221                         action = 'resumeTorrents'; 
    222                 } 
    223                  
    224                 torrent._element._pause_resume_button_image[0].style.className = name; 
    225                 // Send an ajax request to perform the action 
    226                 torrent._controller.remote.request(action, $.toJSON([torrent._id])); 
     226                if( torrent.isActive( ) ) 
     227                        torrent._controller.stopTorrent( torrent ); 
     228                else 
     229                        torrent._controller.startTorrent( torrent ); 
    227230        }, 
    228231 
     
    244247        { 
    245248                // These variables never change after the inital load 
    246                 if (data.name)         this._name         = data.name; 
    247249                if (data.isPrivate)    this._is_private   = data.isPrivate; 
    248250                if (data.hashString)   this._hashString   = data.hashString; 
     
    254256                if (data.dateCreated)  this._creator_date = data.dateCreated; 
    255257                if (data.path)         this._torrent_file = data.path;//FIXME 
     258                if (data.name) { 
     259                        this._name = data.name; 
     260                        this._name_lc = this._name.toLowerCase( ); 
     261                } 
    256262                 
    257263                // Set the regularly-changing torrent variables 
     
    272278                this._total_leechers    = data.leechers; 
    273279                this._total_seeders     = data.seeders; 
    274                  
    275                 switch( data.status ) { 
    276                         case 1: this._state = Torrent._StatusWaitingToCheck; break; 
    277                         case 2: this._state = Torrent._StatusChecking; break; 
    278                         case 4: this._state = Torrent._StatusDownloading; break; 
    279                         case 8: this._state = Torrent._StatusSeeding; break; 
    280                         case 16: this._state = Torrent._StatusPaused; break; 
    281                 } 
    282                  
    283                 this._is_running = this._state != Torrent._StatusPaused; 
     280                this._state             = data.status; 
    284281                 
    285282                // Get -1 returned sometimes (maybe torrents with errors?) 
     
    299296                 
    300297                // Figure out the percent completed 
    301                 var percent_completed = Math.min( 1.0, ( this._completed / this._size ) ); 
    302                 var css_completed_width = Math.floor( percent_completed * Torrent._MaxProgressBarWidth ); 
     298                var percent = Math.min( 1.0, ( this._completed / this._size ) ); 
     299                var css_completed_width = Math.floor( percent * Torrent._MaxProgressBarWidth ); 
    303300                 
    304301                // Add the progress bar 
     
    306303                if( notDone ) 
    307304                { 
     305                        var eta = ''; 
     306                         
     307                        if( this.isActive( ) ) 
     308                        { 
     309                                eta = '-'; 
     310                                if (this._eta < 0 || this._eta >= Torrent._InfiniteTimeRemaining ) 
     311                                        eta += 'remaining time unknown'; 
     312                                else 
     313                                        eta += Math.formatSeconds(this._eta) + ' remaining'; 
     314                        } 
     315                         
    308316                        // Create the 'progress details' label 
    309                         // Eg: '101 MB of 631 MB (16.02%) - 2 hr 30 min remaining' 
    310                         progress_details = Math.formatBytes(this._completed) + ' of '; 
    311                         progress_details += Math.formatBytes(this._size) + ' ('; 
    312                         progress_details += Math.ratio( this._completed, this._size ) + '%)'; 
    313                         if ((this._eta < 0 || this._eta >= Torrent._InfiniteTimeRemaining) && this.isActive()) { 
    314                                 progress_details += ' - remaining time unknown'; 
    315                         } else if (this.isActive()) { 
    316                                 progress_details += ' - ' + Math.formatSeconds(this._eta) + ' remaining'; 
    317                         } 
     317                        // Eg: '101 MB of 631 MB (16.02%) - 2 hr remaining' 
     318                        progress_details = Math.formatBytes( this._completed ) 
     319                                         + ' of ' 
     320                                         + Math.formatBytes( this._size ) 
     321                                         + ' (' 
     322                                         + Math.ratio( this._completed, this._size ) 
     323                                         + '%)' 
     324                                         + eta; 
    318325                         
    319326                        // Update the 'in progress' bar 
    320327                        var class_name = (this.isActive()) ? 'in_progress' : 'incomplete_stopped'; 
    321                         root._progress_complete_container.removeClass(); 
    322                         root._progress_complete_container.addClass('torrent_progress_bar'); 
    323                         root._progress_complete_container.addClass(class_name); 
    324                         root._progress_complete_container.css('width', css_completed_width + '%'); 
     328                        var e = root._progress_complete_container; 
     329                        e.removeClass(); 
     330                        e.addClass('torrent_progress_bar'); 
     331                        e.addClass(class_name); 
     332                        e.css('width', css_completed_width + '%'); 
    325333                         
    326334                        // Update the 'incomplete' bar 
    327                         if (! root._progress_incomplete_container.is('.incomplete')) { 
    328                                 root._progress_incomplete_container.removeClass(); 
    329                                 root._progress_incomplete_container.addClass('torrent_progress_bar in_progress'); 
     335                        e = root._progress_incomplete_container; 
     336                        if( !e.is('.incomplete')) { 
     337                                e.removeClass(); 
     338                                e.addClass('torrent_progress_bar in_progress'); 
    330339                        } 
    331                         root._progress_incomplete_container.css('width', (Torrent._MaxProgressBarWidth - css_completed_width) + '%'); 
    332                         root._progress_incomplete_container.show(); 
     340                        e.css('width', (Torrent._MaxProgressBarWidth - css_completed_width) + '%'); 
     341                        e.show(); 
    333342                         
    334343                        // Create the 'peer details' label 
    335344                        // Eg: 'Downloading from 36 of 40 peers - DL: 60.2 KB/s UL: 4.3 KB/s' 
    336                         if (this._state == Torrent._StatusChecking) { 
    337                                 peer_details = 'Checking existing files'; 
    338                                  
    339                         } else if (this._state == Torrent._StatusWaitingToCheck) { 
    340                                 peer_details = 'Waiting to check existing files'; 
    341                                  
    342                         } else { 
    343                                 peer_details = 'Downloading from ' + this._peers_downloading + ' of '; 
    344                                 peer_details += this._peers_total + ' peers - DL: '; 
    345                                 peer_details += Math.formatBytes(this._download_speed) + '/s UL: '; 
    346                                 peer_details += Math.formatBytes(this._upload_speed) + '/s';                     
     345                        if( !this.isDownloading( ) ) 
     346                                peer_details = this.stateStr( ); 
     347                        else { 
     348                                peer_details = 'Downloading from ' 
     349                                             + this._peers_downloading 
     350                                             + ' of ' 
     351                                             + this._peers_total 
     352                                             + ' peers - DL: ' 
     353                                             + Math.formatBytes(this._download_speed) 
     354                                             + '/s UL: ' 
     355                                             + Math.formatBytes(this._upload_speed) 
     356                                             + '/s'; 
    347357                        } 
    348358                         
    349                 } else { 
    350                          
     359                } 
     360                else 
     361                { 
    351362                        // Update the 'in progress' bar 
    352363                        var class_name = (this.isActive()) ? 'complete' : 'complete_stopped'; 
    353                         root._progress_complete_container.removeClass(); 
    354                         root._progress_complete_container.addClass('torrent_progress_bar ' + class_name ); 
     364                        var e = root._progress_complete_container; 
     365                        e.removeClass(); 
     366                        e.addClass('torrent_progress_bar ' + class_name ); 
    355367                         
    356368                        // Create the 'progress details' label 
    357369                        // Eg: '698.05 MB, uploaded 8.59 GB (Ratio: 12.3)' 
    358                         progress_details = Math.formatBytes(this._size) + ', uploaded '; 
    359                         progress_details += Math.formatBytes(this._upload_total) + ' (Ratio '; 
    360                         progress_details += Math.ratio(this._completed, this._size) + ')'; 
     370                        progress_details = Math.formatBytes( this._size ) 
     371                                         + ', uploaded '; 
     372                                         + Math.formatBytes( this._upload_total ) 
     373                                         + ' (Ratio ' 
     374                                         + Math.ratio( this._upload_total, this._download_total ) 
     375                                         + ')'; 
    361376                         
    362377                        // Hide the 'incomplete' bar 
     
    368383                        // Create the 'peer details' label 
    369384                        // Eg: 'Seeding to 13 of 22 peers - UL: 36.2 KB/s' 
    370                         peer_details = 'Seeding to ' + this._peers_uploading + ' of '; 
    371                         peer_details += this._peers_total + ' peers - UL: '; 
    372                         peer_details += Math.formatBytes(this._upload_speed) + '/s'; 
     385                        if( !this.isSeeding( ) ) 
     386                                peer_details = this.stateStr( ); 
     387                        else 
     388                                peer_details = 'Seeding to ' 
     389                                             + this._peers_uploading 
     390                                             + ' of ' 
     391                                             + this._peers_total 
     392                                             + ' peers - UL: ' 
     393                                             + Math.formatBytes(this._upload_speed) 
     394                                             + '/s'; 
    373395                } 
    374396                 
     
    377399                 
    378400                // Update the peer details and pause/resume button 
    379                 if (this._state == Torrent._StatusPaused ) { 
    380                        peer_details = 'Paused'; 
    381                         root._pause_resume_button_image[0].alt = 'Resume'; 
    382                         root._pause_resume_button_image[0].className = "torrent_resume"; 
     401                e = root._pause_resume_button_image[0]; 
     402                if ( this.state() == Torrent._StatusPaused ) { 
     403                        e.alt = 'Resume'; 
     404                        e.className = "torrent_resume"; 
    383405                } else { 
    384                         root._pause_resume_button_image[0].alt = 'Pause'; 
    385                         root._pause_resume_button_image[0].className = "torrent_pause"; 
    386                 } 
    387                  
    388                 if (this._error_message && this._error_message != '' && this._error_message != 'other' ) { 
     406                        e.alt = 'Pause'; 
     407                        e.className = "torrent_pause"; 
     408                } 
     409                 
     410                if( this._error_message && 
     411                    this._error_message != '' && 
     412                    this._error_message != 'other' ) { 
    389413                        peer_details = this._error_message; 
    390414                } 
     
    432456                        return pass; 
    433457                 
    434                 var pos = this.name().toLowerCase().indexOf( search.toLowerCase() ); 
     458                var pos = this._name_lc.indexOf( search.toLowerCase() ); 
    435459                pass = pos != -1; 
    436460                return pass; 
     
    450474/** Helper function for sortTorrents(). */ 
    451475Torrent.compareByName = function( a, b ) { 
    452         // FIXME: how to fold these two comparisons together? 
    453         if( a.name() < b.name() ) return -1; 
    454         if( a.name() > b.name() ) return 1; 
    455         return 0; 
     476        return a._name_lc.compareTo( b._name_lc ); 
     477}; 
     478 
     479/** Helper function for sortTorrents(). */ 
     480Torrent.compareByTracker = function( a, b ) { 
     481        return a._tracker.compareTo( b._tracker ); 
     482}; 
     483 
     484/** Helper function for sortTorrents(). */ 
     485Torrent.compareByState = function( a, b ) { 
     486        return a.state() - b.state(); 
    456487}; 
    457488 
     
    461492}; 
    462493 
     494/** Helper function for sortTorrents(). */ 
     495Torrent.compareByProgress = function( a, b ) { 
     496        var a_prog = Math.ratio( a._completed, a._size ); 
     497        var b_prog = Math.ratio( b._completed, b._size ); 
     498        if( a_prog !== b_prog ) 
     499                return a_prog - b_prog; 
     500        var a_ratio = Math.ratio( a._upload_total, a._download_total ); 
     501        var b_ratio = Math.ratio( b._upload_total, b._download_total ); 
     502        return a_ratio - b_ratio; 
     503} 
    463504 
    464505/** 
     
    472513        { 
    473514                case Prefs._SortByActivity: 
    474                         torrents.sort(this.compareByAge); 
     515                        torrents.sort( this.compareByActivity ); 
    475516                        break; 
    476517                case Prefs._SortByAge: 
    477                         torrents.sort(this.compareByAge); 
     518                        torrents.sort( this.compareByAge ); 
    478519                        break; 
    479520                case Prefs._SortByQueue: 
    480                         torrents.sort(this.compareById); 
     521                        torrents.sort( this.compareById ); 
    481522                        break; 
    482523                case Prefs._SortByProgress: 
    483                         // FIXME 
     524                        torrents.sort( this.compareByProgress ); 
     525                        break; 
    484526                case Prefs._SortByState: 
    485                         // FIXME 
     527                        torrents.sort( this.compareByState ); 
     528                        break; 
    486529                case Prefs._SortByTracker: 
    487                         // FIXME 
     530                        torrents.sort( this.compareByTracker ); 
     531                        break; 
    488532                case Prefs._SortByName: 
    489                         torrents.sort(this.compareByName); 
     533                        torrents.sort( this.compareByName ); 
    490534                        break; 
    491535                default: 
     
    501545 
    502546/** 
     547 * @brief fast binary search to find a torrent 
    503548 * @param torrents an array of torrents sorted by Id 
    504549 * @param id the id to search for 
  • branches/rpc/web/javascript/transmission.js

    r400 r401  
    853853                        total_swarm_speed    += t.swarmSpeed(); 
    854854                        if( total_state == null ) 
    855                                 total_state = t.state(); 
    856                         else if ( total_state.search ( t.state() ) == -1 ) 
    857                                 total_state += '/' + t.state(); 
     855                                total_state = t.stateStr(); 
     856                        else if ( total_state.search ( t.stateStr() ) == -1 ) 
     857                                total_state += '/' + t.stateStr(); 
    858858                        var tracker = t._tracker; 
    859859                        if ( total_tracker.search ( tracker ) == -1 )   
     
    11191119                        var torrent = torrents[0]; 
    11201120                        var header = 'Remove ' + torrent.name() + '?'; 
    1121                         var message = 'The torrent \"' + torrent.name() + '\" is ' + torrent.state(); 
     1121                        var message = 'The torrent \"' + torrent.name() + '\" is ' + torrent.stateStr(); 
    11221122                        if( torrent._error_message && torrent._error_message != '' ) message += ', but reporting an error'; 
    11231123                        message += '. Remove this torrent? '; 
     
    11441144                tr.startTorrents( tr.getAllTorrents( ) ); 
    11451145        }, 
     1146        startTorrent: function( torrent ) { 
     1147                this.startTorrents( [ torrent ] ); 
     1148        }, 
    11461149        startTorrents: function( torrents ) { 
    11471150                this.remote.startTorrents( torrents ); 
     
    11551158                var tr = transmission; 
    11561159                tr.stopTorrents( tr.getAllTorrents( ) ); 
     1160        }, 
     1161        stopTorrent: function( torrent ) { 
     1162                this.stopTorrents( [ torrent ] ); 
    11571163        }, 
    11581164        stopTorrents: function( torrents ) { 
  • branches/rpc/web/javascript/transmission.remote.js

    r400 r401  
    3939 
    4040        /* 
    41          * Perform a generic remote request 
    42          */ 
    43         request: function(action, param ) { 
    44                 if (param == null) { 
    45                         param = '0'; 
    46                 } 
    47                  
    48                 $.ajax({ 
    49                         type: 'GET', 
    50                         url: 'remote/index.php?action=' + action +  
    51                                 '&param=' + param, 
    52                         dataType: "script", 
    53                         error: this.ajaxError 
    54                 }); 
    55         }, 
    56  
    57         /* 
    5841         * Display an error if an ajax request fails, and stop sending requests 
    5942         */ 
    6043        ajaxError: function(request, error_string, exception) { 
    61                 this._error = request.responseText ? request.responseText.trim().replace(/(<([^>]+)>)/ig,"") : ""; 
    62                 if( this._error.length == 0 ) 
     44                this._error = request.responseText 
     45                            ? request.responseText.trim().replace(/(<([^>]+)>)/ig,"") 
     46                            : ""; 
     47                if( !this._error.length ) 
    6348                        this._error = 'Server not responding'; 
    6449                 
     
    122107                o.method = 'session-set'; 
    123108                o.arguments = args; 
    124                 $.post( RPC._Root, $.toJSON(o), function(){remote.loadDaemonPrefs();}, "json" ); 
     109                $.post( RPC._Root, $.toJSON(o), function(){ 
     110                        remote.loadDaemonPrefs(); 
     111                }, "json" ); 
    125112        }, 
    126113 
    127114        /* 
    128115         * Upload Torrent by URL 
    129          */ 
    130116        addTorrentByURL: function() { 
    131117                $('#torrent_upload_form')[0].action = 'remote/index.php?action=addTorrentByURL&param=[]'; 
    132118                $('#torrent_upload_form').ajaxSubmit({dataType: 'script', type: 'POST'}); 
    133119        }, 
     120         */ 
    134121};