Logging Downloads
I am interested in keeping track of the number of times something is downloaded from a site - potentially expanding the feature in the future to track number of downloads per-day etc. This comes under the heading of "Im sure this has been done before, and probably done better, however this is how I did it"
Overview
- Modify any links to downloadable items replacing the direct url of the downloadable item with an ASP page and an ID (instead of http://www.danielhordern.com/downloads/something.zip with http://www.danielhordern.com/downloadstats.asp?id=1)
- DownloadStats.asp will retrieve the id param and look up a matching record in a database table
- The filename / path details will be extracted, the record count will be updated and the file sent back to the client browser
1) Database
A table (named Downloads) was created with the following attributes, DownloadID being the primary key.
Notes:
- My working version has an extra field (MembershipLevel) allowing for support of username / password protected downloads
- A more comprehensive solution would move DownloadCount into another table that logged all counts either with a time/date stamp, or grouped by date
| Field | Data type |
| ID | Autonumber |
| Path | Text:200 |
| Filename | Text:200 |
| DownloadCount | Number:Long Integer |
2) DownloadStats.asp
| <%@ Language=JavaScript %>
<% //Ensure that this page is not cached. Response.Expires = 0; //------------------------------------------------------------------- // global & constants //------------------------------------------------------------------- // this is typically defined elsewhere in your site (config.asp?) // var g_DBConnectionStr = 'Provider=Microsoft.Jet.OLEDB.4.0; Data Source=d:\sites\yoursite\databases\db.mdb'; // wrap in function to hide local vars function doPage() { var id = _Safe_GetQueryStr('id'); if( id == 'undefined' ) id = ''; _DownloadFile( id ); } doPage(); function _DownloadFile( Id ) { var downloadPath = ''; try { var sqlStr = 'SELECT Downloads.Path, Downloads.Filename, Downloads.MemberLevel FROM Downloads '; sqlStr += 'WHERE Downloads.ID=' + Id; var oConnection = db_OpenConnection( g_DBConnectionStr ); var oRs = db_OpenRecordset( oConnection, sqlStr ); var oDate = new Date(); if (!oRs.EOF) { if( oRs('MemberLevel').value == 0 ) { downloadPath = oRs('Path').value + oRs('Filename').value ; // clean up // db_CloseRecordset( oRs ); oRs = undefined; // and search for Id in LinkStats table // sqlStr = 'SELECT DownloadStats.ID, DownloadStats.Date, DownloadStats.Count FROM DownloadStats '; sqlStr += 'WHERE DownloadStats.ID=' + Id + ' AND DownloadStats.Date=' + db_WrapDate(oDate.formatMediumDMY()); oRs = db_OpenRecordset( oConnection, sqlStr, adOpenDynamic, adLockOptimistic ); if( !oRs.EOF ) { oRs('Count')++; } else { oRs.AddNew(); oRs.Fields('ID').Value = Id; oRs.Fields('Date').Value = oDate.formatMediumDMY(); oRs.Fields('Count').Value = 1; } // update record oRs.Update(); // clean up db_CloseConnection( oConnection, oRs ); oRs = undefined; oConnection = undefined; // redirect Response.Redirect( downloadPath ); // no more script Response.End(); } } } catch(e) { Response.Write('_DownloadFile(): ' + e.description + '<br>'); } } /*************************************************************************** extracted from utils/utils.asp returns request value as string ****************************************************************************/ function _Safe_GetQueryStr( Key ) { var str = ''; if( Request(Key).Count == 1) { str = new String(Request(Key)); } return str; } /*************************************************************************** external functions used from utils/database.asp write replacements or copy from database.asp article ConnectionObj function db_OpenConnection( ConnectionStr ) function db_CloseConnection( ConnectionObj, RecordsetObj ) RecordsetObj function db_OpenRecordset( ConnectionObj, SqlStr, CursorType, LockType ) function db_CloseRecordset ( RecordsetObj ) ****************************************************************************/ %> |