Commit c6023760 authored by Clément Stenac's avatar Clément Stenac

update live counter to v2.0

parent be7e4f86
/* Hacked for multi-items
/**
* ffcounter.js - A simple "odometer-style" counter for Firefox downloads.
*
*
* ffcounter.js - A simple "odometer-style" counter for Firefox downloads.
*
* History:
* Version 0.5.1:
* - Minor tweaks to the way status is displayed.
* - Resets the request object right after the information is pulled.
* Version 0.5:
* - The script now resets the request object to fix errors in Safari.
* - Changed the way the script updates status elements.
* Version 0.4:
* - Added a default counter rate.
* - Made minor modifications to the counter status indicator.
* - If you don't want the timer on, it doesn't set the timeout.
* Version 0.3:
* - Changed the timing of HTTP requests to reflect the new feed
* refresh rate of once per minute.
* - Counter increments on a "tick" instead of a fixed rate.
* - Added support for status elements to debug/track counter metrics:
* - download rate
* - last count
* - last time
* - HTTP request status
* - time until HTTP request
* - time between counter ticks
* Version 0.2:
* - Now calculates download rates between subsequent queries for
* better accuracy.
* - Only reformats the number on an actual increment.
* - Increased the default speed.
* Version 0.1:
* - Initial release.
* Version 2.0
* - updated to work with a customized feed from Infocraft
* - instantly accurate: the feed pulls a moving 10-minute average rate
* - automatically corrects for transit delay
* - no jumping numbers; the counter speeds up or slows down to re-sync
* with the official count
*
* Copyright 2005 Infocraft
* http://www.infocraft.com/
*
* The latest version of this script can be found at:
* http://www.infocraft.com/projects/ffcounter/ffcounter.js
* http://www.infocraft.com/projects/firefox_counter/ffcounter.js
*
* You may use this script in its entirety, modify it to suit your needs,
* adapt its functions, or just use it for inspiration. However, some form
* of acknowledgement, especially a link back to http://www.infocraft.com/, is
* always appreciated.
* of acknowledgement, especially a link back to http://www.infocraft.com/,
* is always appreciated. Also, if you're mirroring the feed from Infocraft,
* please consider making a donation to help cover bandwidth costs.
*/
/*************************** Adjustable Parameters ***************************/
/******************************************************************************
* Adjustable Parameters *
******************************************************************************/
// Make sure to change these based on your settings!
var counter_url = "/retrieve.php"; // The URL of your counter mirror.
var initial_rate = 1; // The initial rate, in downloads/second.
var counterURL = "/retrieve.php"; // The URL of your local counter mirror.
var counterID = "vlccounter"; // The ID of the counter element.
var counter_id = "vlccounter"; // The id of the counter element.
var dlrate_id = "dlrate"; // The id of the download rate display element.
var last_count_id = "lastcount"; // The id of the last count display element.
var last_time_id = "lasttime"; // The id of the last time display element.
var status_id = "counterstatus"; // The id of the counter status element.
var timer_id = "countertimer"; // The id of the counter timer element.
var tick_id = "ticktime"; // The id of the tick rate element.
/******************************************************************************
* Global Variables *
******************************************************************************/
/*************************** Static Globals ***************************/
var currentCount;
var displayCount;
var rate;
var request;
var current_count = 0.0;
/******************************************************************************
* Intialization *
******************************************************************************/
var last_count = 0.0;
var last_time = null;
addEvent(window, "load", initCounter);
var download_rate = 0.0;
var tick_time = 0;
var request = null;
var counter_on = false;
function initCounter()
{
// Begin getCount interval
getCount();
setInterval("getCount()", 60000);
// Begin update timeout
update();
}
/*************************** Public Functions ***************************/
// Gets and returns the most recent delay, rate and count
function getCount()
{
// Generate the XMLHttpRequest
loadXML(counterURL);
}
// This should be called from your HTML, probably as an onload="get_count();"
// event in your <body> tag.
function get_count()
// Processes the information from a returned count XML
function processCount()
{
var delay = 60000;
if (request.readyState == 4) {
if (response = request.responseXML) {
load_xml(counter_url);
setTimeout("get_count()", delay);
count = parseInt(getNodeValue(response, "count"));
rate = parseFloat(getNodeValue(response, "rate"));
delay = parseInt(getNodeValue(response, "delay"));
if (document.getElementById(timer_id)) {
set_status(Math.round(delay / 1000));
// Determine the current count based on time difference and rate
currentCount = Math.round(count + delay * rate);
}
}
}
/*************************** Private Functions ***************************/
// Advances the status counter, indicating the length until the next increment.
function set_status(time)
function update()
{
var timer = document.getElementById(timer_id);
if (currentCount) {
interval = (1000 / rate);
if (!displayCount)
displayCount = currentCount + 1;
else if (displayCount < currentCount)
setTimeout("catchUp()", interval / 2);
else if (displayCount > currentCount)
displayCount += 0;
else
displayCount += 1;
currentCount++;
timer.firstChild.data = time;
// Update the display
setText(document.getElementById(counterID), formatCount(displayCount));
setText(document.getElementById( "dlrate"), rate );
// Reset the update timeout
setTimeout("update()", interval);
time--;
if (time > 0) {
setTimeout("set_status(" + time + ")", 1000);
} else {
setTimeout("update()", 1000);
}
}
// Adapted from the good people at ADC:
// http://developer.apple.com/internet/webcontent/xmlhttpreq.html
// this starts loading the XML data and sets up the process_request handler.
function load_xml(url)
function catchUp()
{
set_element(status_id, "Sending Request");
displayCount++;
setText(document.getElementById(counterID), formatCount(displayCount));
}
/******************************************************************************
* Utility Functions *
******************************************************************************/
function loadXML(url)
{
// branch for native XMLHttpRequest object
if (window.XMLHttpRequest) {
request = new XMLHttpRequest();
request.onreadystatechange = process_request;
request.onreadystatechange = processCount;
request.open("GET", url, true);
request.send(null);
......@@ -120,102 +130,60 @@ function load_xml(url)
} else if (window.ActiveXObject) {
request = new ActiveXObject("Microsoft.XMLHTTP");
if (request) {
request.onreadystatechange = process_request;
request.onreadystatechange = processCount;
request.open("GET", url, true);
request.send();
}
}
}
// This function is called once the request state changes. It pulls the
// relevant data from the response and sends to update_count().
function process_request()
// Adds an event handler to an element
function addEvent(element, type, handler)
{
var response;
var time;
var count_item;
var count;
set_element(status_id, "Request status: " + request.readyState);
if (request.readyState == 4) {
if (request.status == 200) {
response = request.responseXML;
time = response.getElementsByTagName('pubDate')[0].firstChild.data;
count_item = response.getElementsByTagName('item')[0];
count = count_item.getElementsByTagName('description')[0].firstChild.data;
update_count(time, count);
} else {
alert("Error: " + request.statusText());
}
set_element(status_id, "Received: " + (request.statusText ? request.statusText : request.status));
request = null;
if (element.addEventListener) {
element.addEventListener( type, handler, false );
} else if (element.attachEvent) {
element["e" + type + handler] = handler;
element[type + handler] = function() { element["e" + type + handler](window.event); }
element.attachEvent("on" + type, element[type + handler]);
}
}
// Now that the data from the XML request has been extracted, this updates the
// global variables with that data.
function update_count(time, count)
// Removes an event handler from an element
function removeEvent(element, type, handler)
{
time = new Date(time);
count = parseFloat(count.replace(/\D/g,''));
if (initial_rate > 0 || last_time) {
if (last_time && time - last_time != 0) {
download_rate = calculate_rate(time, count);
} else {
download_rate = initial_rate;
}
tick_time = Math.round(1000.0 / download_rate);
set_element(tick_id, tick_time);
set_element(dlrate_id, Math.round(download_rate * 10) / 10.0
+ (last_time ? "" : " (est.)"));
}
last_time = time;
last_count = count;
current_count = count;
set_element(last_count_id, format_count(last_count));
set_element(last_time_id, format_time(last_time));
if (!counter_on) {
counter_on = true;
update_counter();
if (element.removeEventListener) {
element.removeEventListener(type, handler, false);
} else if (element.detachEvent) {
element.detachEvent("on" + type, element[type+handler]);
element[type+handler] = null;
}
}
function update_counter()
// Sets the text of an element (element should be empty or first child text)
function setText(element, text)
{
set_element(counter_id, format_count(Math.round(current_count)));
current_count++;
var textNode = document.createTextNode(text);
if (tick_time != 0) {
setTimeout("update_counter()", tick_time);
} else {
counter_on = false;
}
if (element.firstChild)
element.replaceChild(textNode, element.firstChild);
else
element.appendChild(textNode);
}
/*************************** Utility Functions ***************************/
// Calculates the number of downloads per update interval.
function calculate_rate(new_time, new_count)
function getNodeValue(topNode, tagName)
{
var time_delta = (new_time - last_time) / 1000.0;
var count_delta = new_count - last_count;
var rate = count_delta / time_delta;
if (elements = topNode.getElementsByTagName(tagName))
value = elements[0].firstChild.data;
else
value = '';
return rate;
return value;
}
// Formats a count for display by making it into a string and inserting commas.
function format_count(count)
function formatCount(count)
{
count = count.toString();
......@@ -225,27 +193,3 @@ function format_count(count)
return count;
}
// Formats a time for display.
function format_time(time)
{
var hour = time.getHours();
var minutes = time.getMinutes();
var seconds = time.getSeconds();
if (minutes < 10)
minutes = "0" + minutes ;
if (seconds < 10)
seconds = "0" + seconds;
return hour + ":" + minutes + ":" + seconds;
}
// Sets an HTML element with element_id to the given content.
function set_element(element_id, content)
{
var element;
if (element = document.getElementById(element_id))
element.firstChild.data = content;
}
<?php
require '/home/videolan/etc/db.php';
/* Open the current */
$lines = file( "/var/www/local/www.videolan.org/counter.data" );
if( $lines == FALSE )
{
$old = "0 0\n";
}
else
{
$old = $lines[1];
}
/* Retrieve new data */
$connect = pg_connect( $connect_string );
if( !$connect )
{
die;
}
$request = pg_query($connect, "SELECT sum(number) FROM mirrors WHERE file like '%0.8.2%'" );
if( $row = pg_fetch_array($request) )
{
$new = date( "U" )." ".$row[0]."\n";
}
pg_close($connect);
/* Write data */
$file = fopen( "/var/www/local/www.videolan.org/counter.data", "w" );
fwrite( $file, $old );
fwrite( $file, $new );
?>
<?php header('Content-Type: text/xml'); ?>
<?xml version="1.0"?>
<!DOCTYPE rss SYSTEM "http://my.netscape.com/publish/formats/rss-0.91.dtd">
<?php
require '/home/videolan/etc/db.php';
$connect = pg_connect( $connect_string );
if( !$connect )
/* Open data */
$lines = file( "counter.data" );
if( $lines == FALSE )
{
die;
die;
}
echo '<rss version="0.91"><channel><pubDate>'.date("D, j M Y G:i:s").'</pubDate><description>VLC Counter</description>';
echo "<link>http://www.videolan.org</link><title>VLC</title>";
$requests = array( "%0.8.2%" =>"VLC 0.8.2",
"%vlc%" => "VLC Total",
"%0.8.2%win32%"=> "VLC 0.8.2 Win32",
"%0.8.2%dmg%"=> "VLC 0.8.2 MacOS X",
"%0.8.2%rpm%"=> "VLC 0.8.2 RPM" );
foreach( $requests as $k => $v )
{
$request = pg_query($connect, "SELECT sum(number) FROM mirrors WHERE file like '$k'" );
if( $row = pg_fetch_array($request) )
{
echo "<item><title>$v</title><description>".$row[0]."</description></item>";
}
}
echo "</channel></rss>";
pg_close($connect);
$new = explode( " ",rtrim( $lines[1] ), 2 );
$old = explode( " ",rtrim( $lines[0] ), 2 ) ;
$now = date ("U" );
$rate = ($new[1] - $old[1] ) / ( $new[0] - $old[0] ) ;
$delay = $now - $new[0] ;
echo "<counter><count>".$new[1]."</count>";
echo "<rate>".sprintf( "%.1f" , $rate )."</rate>";
echo "<delay>".$delay."</delay>";
echo "</counter>";
?>
......@@ -12,5 +12,9 @@
<?php include( $_SERVER["DOCUMENT_ROOT"]."/stats/web.inc" ); ?>
<h1>Download statistics</h1>
<p><a href="/stats/downloads.php">View download statistics</a></p>
<?php footer('$Id: index.php 3321 2005-06-25 13:53:44Z zorglub $'); ?>
......@@ -197,7 +197,7 @@ libraries and build them yourself:</p>
<div class="livecounter">
<h3 style="text-align:center;">VLC 0.8.2 Downloads<br /><span style="font-weight: bold" id="vlccounter">Loading...</span></h3>
<p style="text-align:center;"><span id="dlrate">Calculating...</span> downloads/second</p>
<p style="text-align:center;"><a href="/live.html">Full statistics</a></p>
<p style="text-align:center;"><a href="/stats/downloads.php">Full statistics</a></p>
</div>
<a href="/vlc/screenshots.html">
<img width="300" height="240"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment