All pastes #604806 Raw Edit

Miscellany

public text v1 · immutable
·published 2007-07-05 19:45 UTC
rendered paste body
// intermission.js
// JavaScript controller for a Transmission web interface


window.addEvent('domready', function() {
    intermission = new Intermission();
});


Torrent = new Class({
    initialize : function(torrent) {
        this.completed = torrent.completed;  // this might change
        this.id = torrent.id;  // we assume this..
        this.name = torrent.name;  // .. and this ..
        this.size = torrent.size;  // .. and this don't change
        this.state = torrent.state;

        if (this.state == "downloading") {
            this.download_speed = torrent.download_speed;
            this.eta = torrent.eta;
            this.peers_uploading = torrent.peers_uploading;
            this.peers_total = torrent.peers_total;
            this.upload_speed = torrent.upload_speed;
        }
        else if (this.state == "seeding") {
            this.peers_downloading  = torrent.peers_downloading;
            this.peers_total = torrent.peers_total;
            this.upload_speed = torrent.upload_speed;
        }

        this.tds = new Array();
        this.selected = false;
    },

    grafter : function() {
        var completedAndETA = this.humaniseCompletedOfSize();
        if (this.state == "downloading") {
            completedAndETA += ' - ' + this.humaniseETA();
        }

        // You can find graft() here -> http://tinyurl.com/y7yqch
        // .. real skank-a-thon with the IDing of stuff atm :)
        graft(
            $("torrents"),
            ['div', {id : "di1" + this.id, class : "torrent"},
                ['table', {id : "tab" + this.id},
                    ['tr', {id : "tr1" + this.id},
                        ['td', {id : "td1" + this.id, class : "torrent_name", colspan : 2}, this.name]
                    ],
                    ['tr', {id : "tr2" + this.id},
                        ['td', {id : "td2" + this.id}, completedAndETA]
                    ],
                    ['tr', {id : "tr3" + this.id},
                        ['td', {id : "td3" + this.id},
                            ['div', {id : "di2" + this.id, class : "progress_border"},
                                ['div', {id : "di3" + this.id, class : "progress_bar", style : "width:" + this.progressWidth() + ";"}]
                            ]
                        ]
                    ],
                    ['tr', {id : "tr4" + this.id},
                        ['td', {id : "td4" + this.id}, this.stateAndPeers()]
                    ]
                ]
            ]
        );

        // Store references to our <td> elements for updating later
        // .. we don't need to with the skank naming system, but it's nicer
        this.tds = [$("td1" + this.id), $("td2" + this.id), $("td3" + this.id), $("td4" + this.id)];
        this.progress = $("di3" + this.id);

        $("di1" + this.id).addEvent('click', this.toggle.bind(this));
    },

    humaniseBytes : function(value) {
        // Turn size byte counts into something prettier
        if (value < 1024000) {
            return (value / 1024).round(2) + ' KB';
        }
        else if (value < 1048576000) {
            return (value / 1048576).round(2) + ' MB';
        }
        else if (value < 1073741824000) {
            return (value / 1073741824).round(2) + ' GB';
        } else {
            return (value / 1099511627776).round(2) + ' TB';
        }
    },

    humaniseCompletedOfSize : function() {
        // Return x of y (%)
        return this.humaniseBytes(this.completed)
            + ' of '
            + this.humaniseBytes(this.size)
            + ' ('
            + ((this.completed / this.size) * 100).round(2)
            + '%)';
    },

    humaniseETA : function() {
        // Turn seconds into something readable - not nice, needs replacing
        var hours = Math.floor(this.eta / 3600);
        var minutes = Math.floor((this.eta % 3600) / 60);
        var seconds = Math.floor((this.eta % 3600) % 60);
    
        if (minutes == 0 && hours == 0) {
            var response = seconds + ' seconds remaining';    
        } else {
            var response = hours + ' hours ' + minutes + ' minutes remaining';
        }
    
        return response;
    },

    humaniseSpeed : function(value, type) {
        // Turn speed byte counts into something prettier
        if (value < 1024000) {
            return (value / 1024).round(2) + 'KB/s';
        }
        else if (value < 1048576000) {
            return (value / 1048576).round(2) + 'MB/s';
        }
        else if (value < 1073741824000) {
            return (value / 1073741824).round(2) + 'GB/s';
        } else {
            return (value / 1099511627776).round(2) + 'TB/s';
        }
    },

    progressWidth : function() {
        // Return a suitable % width for the CSS progress bar
        width = (this.completed / this.size) * 100;
        if (width < 1) {
            return '0%';
        }
        else if (width < 2) {
            return width + '%';
        } else {
            return (width - 1) + '%';
        }
    },

    toggle : function(event) {
        id = $("di1" + $(event.target).id.substr(3));
        if (this.selected) {
            this.selected = false;
            id.setStyle('background-color', '#fff');
        } else {
            this.selected = true;
            id.setStyle('background-color', '#00f');
        }
    },

    stateAndPeers : function() {
        // Return state and peer data if active, otherwise just state
        if (this.state == "downloading") {
            return 'Downloading from '
                + this.peers_uploading
                + ' of '
                + this.peers_total
                + ' peers - DL: '
                + this.humaniseSpeed(this.download_speed)
                + ', UL: '
                + this.humaniseSpeed(this.upload_speed);
        }
        else if (this.state == "seeding") {
            return 'Seeding to '
                + this.peers_downloading
                + ' of '
                + this.peers_total
                + ' peers - UL: '
                + this.humaniseSpeed(this.upload_speed);
        } else {
            return this.state.capitalize();
        }
    },

    updater : function(torrent) {
        // Update the data for the this torrent
        this.completed = torrent.completed;
        this.state = torrent.state;

        var completedAndETA = this.humaniseCompletedOfSize();
        if (this.state == "downloading") {
            this.download_speed = torrent.download_speed;
            this.eta = torrent.eta;
            this.peers_uploading = torrent.peers_uploading;
            this.peers_total = torrent.peers_total;
            this.upload_speed = torrent.upload_speed;
            completedAndETA += ' - ' + this.humaniseETA();
        }
        else if (torrent.state == "seeding") {
            this.peers_downloading = torrent.peers_downloading;
            this.peers_total = torrent.peers_total;
            this.upload_speed = torrent.upload_speed;
        }

        // Update the <td>s we grafted earlier
        this.tds[1].setHTML(completedAndETA);
        this.progress.setStyle("width", this.progressWidth());
        this.tds[3].setHTML(this.stateAndPeers());
    }
});

transfers = new Hash();
transfers_count = 0;


Intermission = new Class({
    initialize : function() {
        this.torrentsRefresh();

        $('pauseAllLink').addEvent('click', this.toolbarMethod.pass('pauseAll').bind(this));
        $('resumeAllLink').addEvent('click', this.toolbarMethod.pass('resumeAll').bind(this));
        $('manualRefreshLink').addEvent('click', this.torrentsRefresh.bind(this));

        // periodical = this.torrentsRefresh.periodical(5000, this, 1);  // update every x milliseconds
    },

    toolbarMethod : function(method) {
        new Ajax('ajax/toolbar.php', {
            data : 'method=' + method,
            method : 'post',
        }).request();
    },

    torrentsRefresh : function(event) {
        // Figure out if we're tracking any torrents, then request an update
        var torrentsRefreshURL = 'ajax/torrentsRefresh.php';

        var string_ids_known = transfers.keys();
        if (string_ids_known.length > 0) {                    
            var ids_known = string_ids_known.map(function(key, index) {
                return key.toInt();
            });
            torrentsRefreshURL += '?ids=' + Json.toString(ids_known);
        }

        new Ajax(torrentsRefreshURL, {
            method : 'get',
            onComplete : this.torrentsRefreshComplete
        }).request();
    },

    torrentsRefreshComplete : function(data) {
        // Handle the Json sent back from the server
        var torrents = Json.evaluate(data);

        $each(torrents['torrents'], function(torrent) {
            // Three possibilities - deleted, removed or existing torrent data
            if (torrent.internal == 'deleted') {
                transfers_count -= 1;
                transfers.remove(torrent.id);
                $("di1" + torrent.id).remove();
            }
            else if (torrent.internal == 'new') {
                transfers_count += 1;
                transfers.set(torrent.id, new Torrent(torrent));
                transfers.get(torrent.id).grafter();
            }
            else if (torrent.internal == 'old') {
                transfers.get(torrent.id).updater(torrent);
            }
        });

        $('statusbar').setHTML(transfers_count + ' transfers');
    }
});

// EOF