Index: www/sites/all/modules/custom/np_scan/np_scan.analytics.inc
===================================================================
--- www/sites/all/modules/custom/np_scan/np_scan.analytics.inc (revision 34376)
+++ www/sites/all/modules/custom/np_scan/np_scan.analytics.inc (working copy)
@@ -56,14 +56,11 @@
// get the basic order
$rs = db_query_range("
SELECT ss.active_vid as vid
- FROM {node} n
- INNER JOIN {scan_settings} ss ON n.nid = ss.nid AND ss.status = %d
- WHERE n.nid IN (
- SELECT o.nid
- FROM {og_ancestry} o
- WHERE o.group_nid IN (" . $client_id_placeholders . ")
- )
- ORDER BY ". ($timeframe == 24 ? 'n.np_views_24' : 'n.np_views_page') ." DESC
+ FROM {scan_hits} h
+ INNER JOIN {scan_settings} ss ON h.nid = ss.nid AND ss.status = %d
+ INNER JOIN {og_ancestry} o ON h.nid = o.nid
+ WHERE o.group_nid IN (" . $client_id_placeholders . ")
+ ORDER BY ". ($timeframe == 24 ? 'h.page_today' : 'h.page_last') ." DESC
", $args, 0, $limit);
while ($row = db_fetch_object($rs)) {
$scans[$row->$key] = FALSE;
@@ -101,9 +98,12 @@
$scan_placeholders = implode(',', array_fill(0, count($scans), '%d'));
$rs = db_query("
SELECT s.scan_id, s.nid, s.vid,
- n.np_views_page, n.np_views_24 AS np_views_page_24, n.np_views_widget, n.np_views_widget_24
+ h.page_all AS np_views_page,
+ h.page_today AS np_views_page_24,
+ h.widget_all AS np_views_widget,
+ h.widget_today AS np_views_widget_24
FROM {scan} s
- INNER JOIN {node} n ON n.nid = s.nid
+ INNER JOIN {scan_hits} h ON h.nid = s.nid
WHERE s." . $key . " IN ( " . $scan_placeholders . ")
", array_keys($scans));
while ($statistics = db_fetch_object($rs)) {
@@ -215,14 +215,16 @@
scan_api_set_active_shard('misc');
// Some general statistics
$statistics = db_fetch_object(db_query("
- SELECT SUM(ss.status) AS online, COUNT(*) AS count, SUM(n.np_views_24) AS views_24, SUM(n.np_views_page) AS views, SUM(n.np_views_widget) AS widget_views
- FROM {node} n
- INNER JOIN {scan_settings} ss ON n.nid = ss.nid
- WHERE n.nid IN (
- SELECT o.nid
- FROM {og_ancestry} o
- WHERE o.group_nid IN (" . $client_id_placeholders . ")
- )
+ SELECT SUM(ss.status) AS online,
+ COUNT(*) AS count,
+ SUM(h.page_today) AS views_24,
+ SUM(h.page_all) AS views,
+ SUM(h.widget_today) AS widget_views_24,
+ SUM(h.widget_all) AS widget_views
+ FROM {scan_hits} h
+ INNER JOIN {scan_settings} ss ON h.nid = ss.nid
+ INNER JOIN {og_ancestry} o ON h.nid = o.nid
+ WHERE o.group_nid IN (" . $client_id_placeholders . ")
", $client_ids));
scan_api_set_active_shard();
Index: www/sites/all/modules/custom/np_scan/np_scan.module
===================================================================
--- www/sites/all/modules/custom/np_scan/np_scan.module (revision 34376)
+++ www/sites/all/modules/custom/np_scan/np_scan.module (working copy)
@@ -432,6 +432,36 @@
/* Backfilling. Wait until next run. */
}
}
+
+ // Mini-worker to update the page views for this minute.
+ require_once(drupal_get_path('module', 'np_potpourri') .'/BeanStalk.class.php');
+ $beanstalk = BeanStalk::open(array(
+ 'servers' => array( variable_get('np_scan_beanstalk_host', '67.220.204.51:11300') ),
+ 'select' => 'random peek',
+ 'auto_unyaml' => false,
+ ));
+
+ $beanstalk->watch('hit-logger');
+ scan_api_set_active_shard('misc');
+ while ($job = $beanstalk->reserve_with_timeout(0)) {
+ $data = explode('|', $job->get());
+ switch ($data[1]) {
+ case 'widget':
+ $query = 'UPDATE {scan_hits} SET widget_today = widget_today + 1, widget_all = widget_all + 1, widget_last = %d WHERE nid = %d';
+ break;
+ case 'page':
+ $query = 'UPDATE {scan_hits} SET page_today = page_today + 1, page_all = page_all + 1, page_last = %d WHERE nid = %d';
+ break;
+ }
+ db_query($query, $data[2], $data[0]);
+ if (db_affected_rows()) {
+ $job->delete();
+ }
+ else {
+ // Hmm, update didn't work. Let's try again in a minute...
+ $job->release(1024, 60);
+ }
+ }
scan_api_set_active_shard();
}
@@ -764,6 +794,9 @@
$scan_settings->use_globals = NP_SCAN_USE_GLOBAL_EXPLETIVES | NP_SCAN_USE_GLOBAL_USERS | NP_SCAN_USE_GLOBAL_URLS;
drupal_write_record('scan_settings', $scan_settings);
+ // Add the hit counter / denormalized data for sorting on mysql side.
+ db_query('INSERT INTO {scan_hits} (nid, client_id, status, created) VALUES (%d, %d, %d, %d)', $node->nid, $node->og_groups[0], $scan_settings->status, $node->created);
+
if (isset($node->locations)) {
foreach ($node->locations as $location) {
$location->scan_id = $scan->scan_id;
@@ -912,6 +945,7 @@
np_scan_queue_delete($row->scan_id);
}
db_query("DELETE FROM {scan} WHERE nid = %d", $node->nid);
+ db_query("DELETE FROM {scan_hits} WHERE nid = %d", $node->nid);
db_query("DELETE FROM {scan_settings} WHERE nid = %d", $node->nid);
db_query("DELETE FROM {scan_destination} WHERE nid = %d", $node->nid);
np_scan_reload_workers('scan');
Index: www/sites/all/modules/custom/np_scan_export/np_scan_export.module
===================================================================
--- www/sites/all/modules/custom/np_scan_export/np_scan_export.module (revision 34376)
+++ www/sites/all/modules/custom/np_scan_export/np_scan_export.module (working copy)
@@ -53,13 +53,7 @@
foreach($groups as $gid => $group) {
// Select all the views for scans in that group
// that were viewed in the last 24 hrs.
- $result = db_query("
- SELECT n.nid, n.title, n.created, n.np_views_page, n.np_views_24, n.np_views_widget, n.np_views_widget_24
- FROM {node} n
- LEFT JOIN {og_ancestry} oga ON n.nid = oga.nid
- INNER JOIN {node} noga ON oga.group_nid = noga.nid
- WHERE oga.group_nid = %d AND
- (n.np_views_24 > 0 OR n.np_views_widget_24 > 0)", $gid);
+ $result = db_query('SELECT h.* FROM {scan_hits} h INNER JOIN {og_ancestry} o ON h.nid = o.nid WHERE o.group_nid = %d AND (h.widget_today > 0 OR h.page_today > 0)', $gid);
$csv = '';
while ($scan = db_fetch_object($result)) {
@@ -67,10 +61,10 @@
array(
$scan->title,
url("node/$scan->nid/edit", array('absolute' => TRUE)),
- $scan->np_views_page,
- $scan->np_views_24,
- $scan->np_views_widget,
- $scan->np_views_widget_24,
+ $scan->page_all,
+ $scan->page_today,
+ $scan->widget_all,
+ $scan->widget_today,
)
);
}
Index: www/sites/all/modules/custom/np_potpourri/np_potpourri.beanstalk.inc
===================================================================
--- www/sites/all/modules/custom/np_potpourri/np_potpourri.beanstalk.inc (revision 34376)
+++ www/sites/all/modules/custom/np_potpourri/np_potpourri.beanstalk.inc (working copy)
@@ -18,6 +18,7 @@
$searchapi_stats = array();
$statworker_stats = array();
$delete_stats = array();
+ $hit_stats = array();
$default_stats = array();
$stats = array();
@@ -42,6 +43,9 @@
$beanstalk->stats_tube($prefix . "delete", $delete_stats);
$output .= t('
Scan Deletion Queue stats
');
$output .= theme('table', array(), _np_potpourri_beanstalk_format($delete_stats));
+ $beanstalk->stats_tube($prefix . "hit-logger", $hit_stats);
+ $output .= t('Scan Hit Logger Queue stats
');
+ $output .= theme('table', array(), _np_potpourri_beanstalk_format($hit_stats));
$beanstalk->stats_tube($prefix . "default", $default_stats);
$output .= t('Default Queue stats
');
$output .= theme('table', array(), _np_potpourri_beanstalk_format($default_stats));
Index: www/sites/all/modules/custom/np_scan_recommend/np_scan_recommend.info
===================================================================
--- www/sites/all/modules/custom/np_scan_recommend/np_scan_recommend.info (revision 34376)
+++ www/sites/all/modules/custom/np_scan_recommend/np_scan_recommend.info (working copy)
@@ -3,3 +3,4 @@
description = Recommend scans and scan items, and possibly other scan related voting.
package = NP
core = 6.x
+dependencies[] = np_log
Index: www/sites/all/modules/custom/np_scan_recommend/np_scan_recommend.module
===================================================================
--- www/sites/all/modules/custom/np_scan_recommend/np_scan_recommend.module (revision 34376)
+++ www/sites/all/modules/custom/np_scan_recommend/np_scan_recommend.module (working copy)
@@ -220,7 +220,8 @@
elseif ($content_type == 'scan') {
foreach ($cached as $cache) {
if ($cache['function'] == 'sum' && $cache['tag'] == NP_SCAN_RECOMMEND_SCAN && $cache['value_type'] =='points') {
- db_query('UPDATE {node} SET recommend = %d WHERE nid = %d', $cache['value'], $content_id);
+ // Table is maintained by np_log.
+ db_query('UPDATE {scan_hits} SET recommend = %d WHERE nid = %d', $cache['value'], $content_id);
}
}
}
Index: www/sites/all/modules/custom/np_log/np_log.module
===================================================================
--- www/sites/all/modules/custom/np_log/np_log.module (revision 34376)
+++ www/sites/all/modules/custom/np_log/np_log.module (working copy)
@@ -11,3 +11,39 @@
function np_log_views_api() {
return array('api' => 2.0);
}
+
+/**
+ * Implementation of hook_cron().
+ * On-the-hour cron hook to roll over daily hit counting at the proper time.
+ */
+function np_log_cron() {
+ $timestamp = time();
+ $tz = date_default_timezone_get();
+
+ $zones = db_query('SELECT DISTINCT field_timezone_value AS tz FROM {content_type_group}');
+ while ($zone = db_fetch_object($zones)) {
+ $key = 'cleanup:' . $zone->tz;
+ date_default_timezone_set($zone->tz);
+ // If we have changed days in the timezone we are processing...
+ if (date('d', variable_get($key, 0)) != date('d', $timestamp)) {
+ variable_set($key, $time);
+ // h: Hit counter table.
+ // n: Group nodes. Used to ensure we're only using the newest revision of the group node.
+ // g: Group settings. Used to match on timezone.
+ // o: Ancestry. Used to determine what nodes the matched groups have.
+ db_query("UPDATE {scan_hits} h,
+ {node} n,
+ {content_type_group} g,
+ {og_ancestry} o
+ SET widget_today = 0, page_today = 0
+ WHERE n.nid = o.group_nid
+ AND n.vid = g.vid
+ AND h.nid = o.nid
+ AND g.field_timezone_value = '%s'", $zone->tz);
+ $count = db_affected_rows();
+ watchdog('np_log', 'Reset daily counts on %count nodes in timezone %tz', array('%count' => $count, '%tz' => $zone->tz));
+ }
+ }
+ // Restore original timezone.
+ date_default_timezone_set($tz);
+}
Index: www/sites/all/modules/custom/np_log/np_log.views.inc
===================================================================
--- www/sites/all/modules/custom/np_log/np_log.views.inc (revision 34376)
+++ www/sites/all/modules/custom/np_log/np_log.views.inc (working copy)
@@ -1,9 +1,91 @@
array(
+ 'left_field' => 'nid',
+ 'field' => 'nid',
+ ),
+ );
+
+ $data['scan_hits']['widget_today'] = array(
+ 'title' => t('Widget Views: Today'),
+ 'help' => t('The number of widget views in the last 24 hours.'),
+ 'field' => array(
+ 'handler' => 'views_handler_field_numeric',
+ 'click sortable' => TRUE,
+ ),
+ 'sort' => array(
+ 'handler' => 'views_handler_sort',
+ ),
+ );
+
+ $data['scan_hits']['widget_all'] = array(
+ 'title' => t('Widget Views: All'),
+ 'help' => t('All widget views for scan.'),
+ 'field' => array(
+ 'handler' => 'views_handler_field_numeric',
+ 'click sortable' => TRUE,
+ ),
+ 'sort' => array(
+ 'handler' => 'views_handler_sort',
+ ),
+ );
+
+ $data['scan_hits']['widget_last'] = array(
+ 'title' => t('Widget Views: Last View Timestamp'),
+ 'help' => t('The timestamp of the last widget view.'),
+ 'field' => array(
+ 'handler' => 'views_handler_field_date',
+ 'click sortable' => TRUE,
+ ),
+ 'sort' => array(
+ 'handler' => 'views_handler_sort_date',
+ ),
+ );
+
+ $data['scan_hits']['page_today'] = array(
+ 'title' => t('Page Views: Today'),
+ 'help' => t('The number of page views in the last 24 hours'),
+ 'field' => array(
+ 'handler' => 'views_handler_field_numeric',
+ 'click sortable' => TRUE,
+ ),
+ 'sort' => array(
+ 'handler' => 'views_handler_sort',
+ ),
+ );
+
+ $data['scan_hits']['page_all'] = array(
+ 'title' => t('Page Views: All'),
+ 'help' => t('All page views for scan.'),
+ 'group' => t('Scan'),
+ 'field' => array(
+ 'handler' => 'views_handler_field_numeric',
+ 'click sortable' => TRUE,
+ ),
+ 'sort' => array(
+ 'handler' => 'views_handler_sort',
+ ),
+ );
+
+ $data['scan_hits']['page_last'] = array(
+ 'title' => t('Page Views: Last View Timestamp'),
+ 'help' => t('The timestamp of the last page view.'),
+ 'field' => array(
+ 'handler' => 'views_handler_field_date',
+ 'click sortable' => TRUE,
+ ),
+ 'sort' => array(
+ 'handler' => 'views_handler_sort_date',
+ ),
+ );
+
+ // @@@ Delete the rest of this when views are converted.
$data['node']['np_views_page'] = array(
- 'title' => t('Page Views'),
+ 'title' => t('LEGACY Page Views'),
'help' => t('All page views for scan.'),
'group' => t('Scan'),
'field' => array(
@@ -16,7 +98,7 @@
);
$data['node']['np_views_widget'] = array(
- 'title' => t('Widget Views: All'),
+ 'title' => t('LEGACY Widget Views: All'),
'help' => t('All widget views for scan.'),
'group' => t('Scan'),
'field' => array(
@@ -29,7 +111,7 @@
);
$data['node']['np_views_widget_24'] = array(
- 'title' => t('Widget Views: 24h'),
+ 'title' => t('LEGACY Widget Views: 24h'),
'help' => t('The number of widget views in the last 24 hours.'),
'group' => t('Scan'),
'field' => array(
@@ -42,7 +124,7 @@
);
$data['node']['np_views_24'] = array(
- 'title' => t('24 hrs views'),
+ 'title' => t('LEGACY 24 hrs views'),
'help' => t('The number of views in the last 24 hours'),
'group' => t('Scan'),
'field' => array(
Index: www/sites/all/modules/custom/np_log/np_log.install
===================================================================
--- www/sites/all/modules/custom/np_log/np_log.install (revision 0)
+++ www/sites/all/modules/custom/np_log/np_log.install (revision 0)
@@ -0,0 +1,111 @@
+ t('Stores daily and all-time tallies for widget and page views.'),
+ 'fields' => array(
+ 'nid' => array(
+ 'type' => 'int',
+ 'unsigned' => TRUE,
+ 'not null' => TRUE,
+ 'description' => t('The nid being tracked.'),
+ ),
+ 'client_id' => array(
+ 'type' => 'int',
+ 'unsigned' => TRUE,
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'description' => t('Denormalized og nid of client.'),
+ ),
+ 'created' => array(
+ 'type' => 'int',
+ 'unsigned' => TRUE,
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'description' => t('Denormalized node created time.'),
+ ),
+ 'status' => array(
+ 'type' => 'int',
+ 'size' => 'tiny',
+ 'unsigned' => TRUE,
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'description' => t('Denormalized scan status from {scan_settings}.'),
+ ),
+ 'recommendations' => array(
+ 'type' => 'int',
+ 'unsigned' => TRUE,
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'description' => t('Number of recommendations (maintained by np_scan_recommend.module)'),
+ ),
+ 'widget_today' => array(
+ 'type' => 'int',
+ 'unsigned' => TRUE,
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'description' => t('Daily widget views. Reset once a day.'),
+ ),
+ 'widget_all' => array(
+ 'type' => 'int',
+ 'unsigned' => TRUE,
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'description' => t('All time widget views.'),
+ ),
+ 'widget_last' => array(
+ 'type' => 'int',
+ 'unsigned' => TRUE,
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'description' => t('Unix timestamp of last widget view.'),
+ ),
+ 'page_today' => array(
+ 'type' => 'int',
+ 'unsigned' => TRUE,
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'description' => t('Daily page hits. Reset once a day.'),
+ ),
+ 'page_all' => array(
+ 'type' => 'int',
+ 'unsigned' => TRUE,
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'description' => t('All time page hits.'),
+ ),
+ 'page_last' => array(
+ 'type' => 'int',
+ 'unsigned' => TRUE,
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'description' => t('Unix timestamp of last page hit.'),
+ ),
+ ),
+ 'primary key' => array('nid'),
+ 'indexes' => array(
+ 'widget_today_idx' => array('widget_today'),
+ 'widget_all_idx' => array('widget_all'),
+ 'widget_last_idx' => array('widget_last'),
+ 'page_today_idx' => array('page_today'),
+ 'page_all_idx' => array('page_all'),
+ 'page_last_idx' => array('page_last'),
+ ),
+ );
+ return $schema;
+}
Index: www/np_log.php
===================================================================
--- www/np_log.php (revision 34376)
+++ www/np_log.php (working copy)
@@ -1,32 +1,30 @@
add($full_key, 1, FALSE, $expire) ? 1 : $mc->increment($full_key);
- if ($new_value && ($type == 'page' || $new_value % 5 == 0)) {
- drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE);
- db_set_active('scan');
- if ($type == 'page') {
- db_query("UPDATE {node} SET np_views_24 = np_views_24 + 1, np_views_page = np_views_page + 1 WHERE nid = %d", $nid);
- }
- else {
- db_query("UPDATE {node} SET np_views_widget_24 = %d, np_views_widget = np_views_widget + 5, np_views_widget_last = UNIX_TIMESTAMP() WHERE nid = %d", $new_value, $nid);
- }
- db_set_active();
+ $type = ($_GET['type'] == 'widget') ? 'widget' : 'page';
+ $timestamp = $_SERVER["REQUEST_TIME"];
+ //@todo This is the best place to collect the IP address of the client.
+ // We can find the proxy list in the server variable
+ // $_SERVER["HTTP_X_FORWARDED_FOR"].
+
+ if ($nid > 0) {
+ $beanstalk = BeanStalk::open(array(
+ 'servers' => array( variable_get('np_scan_beanstalk_host', '67.220.204.51:11300') ),
+ 'select' => 'random peek',
+ 'auto_unyaml' => false,
+ ));
+ $job = array(
+ $nid,
+ $type,
+ $timestamp,
+ );
+
+ $beanstalk->put(1024, 0, 120, implode('|', $job), 'hit-logger');
}
}
header('Content-type: image/gif');