1
0
Fork 0
mirror of https://github.com/Yetangitu/ampache synced 2025-10-03 09:49:30 +02:00

Add count_type column on object_count table

Add stream control plugins (Hits and Bandwidth)
This commit is contained in:
Afterster 2014-10-24 07:48:50 +02:00
parent a5bd894531
commit b98b1a5a95
11 changed files with 370 additions and 16 deletions

View file

@ -83,7 +83,7 @@ if (Core::is_playable_item($_REQUEST['action'])) {
$media_ids[] = $media_id;
break;
case 'video':
$media_ids[] = array('Video', $media_id);
$media_ids[] = array('object_type' => 'Video', 'object_id' => $media_id);
break;
} // switch on type
} // foreach media_id
@ -94,6 +94,12 @@ if (Core::is_playable_item($_REQUEST['action'])) {
} // action switch
}
if (!User::stream_control($media_ids)) {
debug_event('UI::access_denied', 'Stream control failed for user ' . $GLOBALS['user']->username, '3');
UI::access_denied();
exit;
}
// Write/close session data to release session lock for this script.
// This to allow other pages from the same session to be processed
// Do NOT change any session variable after this call

View file

@ -377,6 +377,28 @@ class Graph
$this->render_graph('Bandwidth', $MyData, $zoom, $width, $height);
}
public function get_total_bandwidth($user = 0, $start_date = null, $end_date = null)
{
$total = 0;
$values = $this->get_all_type_pts('get_user_bandwidth_pts', $user, null, 0, $start_date, $end_date, 'month');
foreach ($values as $date => $value) {
$total += $value;
}
return $total;
}
public function get_total_hits($user = 0, $start_date = null, $end_date = null)
{
$total = 0;
$values = $this->get_all_type_pts('get_user_hits_pts', $user, null, 0, $start_date, $end_date, 'month');
foreach ($values as $date => $value) {
$total += $value;
}
return $total;
}
public function render_catalog_files($catalog = 0, $object_type = null, $object_id = 0, $start_date = null, $end_date = null, $zoom = 'day', $width = 0, $height = 0)
{
$MyData = new pData();

View file

@ -1090,7 +1090,7 @@ class Search extends playlist_object
break;
case 'played_times':
$where[] = "`song`.`id` IN (SELECT `object_count`.`object_id` FROM `object_count` " .
"WHERE `object_count`.`object_type` = 'song'" .
"WHERE `object_count`.`object_type` = 'song' AND `object_count`.`count_type` = 'stream' " .
"GROUP BY `object_count`.`object_id` HAVING COUNT(*) $sql_match_operator '$input')";
break;
case 'catalog':

View file

@ -1552,7 +1552,7 @@ class Song extends database_object implements media, library_item
$user_id = intval($user_id);
$sql = "SELECT `object_id`, `user`, `object_type`, `date`, `agent`, `geo_latitude`, `geo_longitude`, `geo_name` " .
"FROM `object_count` WHERE `object_type`='song' ";
"FROM `object_count` WHERE `object_type` = 'song' AND `count_type` = 'stream' ";
if (AmpConfig::get('catalog_disable')) {
$sql .= "AND " . Catalog::get_enable_filter('song', '`object_id`') . " ";
}

View file

@ -90,7 +90,7 @@ class Stats
* This inserts a new record for the specified object
* with the specified information, amazing!
*/
public static function insert($type, $oid, $user, $agent='', $location)
public static function insert($type, $oid, $user, $agent='', $location, $count_type = 'stream')
{
if (!self::is_already_inserted($type, $oid, $user)) {
$type = self::validate_type($type);
@ -105,9 +105,9 @@ class Stats
if (isset($location['name']))
$geoname = $location['name'];
$sql = "INSERT INTO `object_count` (`object_type`,`object_id`,`date`,`user`,`agent`, `geo_latitude`, `geo_longitude`, `geo_name`) " .
" VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
$db_results = Dba::write($sql, array($type, $oid, time(), $user, $agent, $latitude, $longitude, $geoname));
$sql = "INSERT INTO `object_count` (`object_type`,`object_id`,`count_type`,`date`,`user`,`agent`, `geo_latitude`, `geo_longitude`, `geo_name`) " .
" VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
$db_results = Dba::write($sql, array($type, $oid, $count_type, time(), $user, $agent, $latitude, $longitude, $geoname));
if (!$db_results) {
debug_event('statistics', 'Unabled to insert statistics:' . $sql, '3');
@ -121,15 +121,15 @@ class Stats
* is_already_inserted
* Check if the same stat has not already been inserted within a graceful delay
*/
public static function is_already_inserted($type, $oid, $user)
public static function is_already_inserted($type, $oid, $user, $count_type = 'stream')
{
$delay = time() - 10; // We look 10 seconds in the past
$sql = "SELECT `id` FROM `object_count` ";
$sql .= "WHERE `object_count`.`user` = ? AND `object_count`.`object_type` = '" . $type ."' AND `object_count`.`object_id` = ? AND `object_count`.`date` >= ? ";
$sql .= "WHERE `object_count`.`user` = ? AND `object_count`.`object_type` = ? AND `object_count`.`object_id` = ? AND `object_count`.`count_type` = ? AND `object_count`.`date` >= ? ";
$sql .= "ORDER BY `object_count`.`date` DESC";
$db_results = Dba::read($sql, array($user, $oid, $delay));
$db_results = Dba::read($sql, array($user, $type, $oid, $count_type, $delay));
$results = array();
while ($row = Dba::fetch_assoc($db_results)) {
@ -144,10 +144,10 @@ class Stats
* get_object_count
* Get count for an object
*/
public static function get_object_count($object_type, $object_id)
public static function get_object_count($object_type, $object_id, $count_type = 'stream')
{
$sql = "SELECT COUNT(*) AS `object_cnt` FROM `object_count` WHERE `object_type`= ? AND `object_id` = ?";
$db_results = Dba::read($sql, array($object_type, $object_id));
$sql = "SELECT COUNT(*) AS `object_cnt` FROM `object_count` WHERE `object_type`= ? AND `object_id` = ? AND `count_type` = ?";
$db_results = Dba::read($sql, array($object_type, $object_id, $count_type));
$results = Dba::fetch_assoc($db_results);

View file

@ -467,9 +467,12 @@ class Update
$update_string = '- Add users geolocation.<br />';
$version[] = array('version' => '370022','description' => $update_string);
$update_string = " - Add Aurora.js webplayer option<br />";
$update_string = " - Add Aurora.js webplayer option.<br />";
$version[] = array('version' => '370023','description' => $update_string);
$update_string = " - Add count_type column to object_count table.<br />";
$version[] = array('version' => '370024','description' => $update_string);
return $version;
}
@ -3179,4 +3182,19 @@ class Update
return $retval;
}
/**
* update 370024
*
* Add count_type column to object_count table
*/
public static function update_370024()
{
$retval = true;
$sql = "ALTER TABLE `object_count` ADD COLUMN `count_type` VARCHAR(16) NOT NULL DEFAULT 'stream'";
$retval = Dba::write($sql) ? $retval : false;
return $retval;
}
}

View file

@ -1367,4 +1367,29 @@ class User extends database_object
} // rebuild_all_preferences
/**
* stream_control
* Check all stream control plugins
* @param array $media_ids
* @param User $user
* @return boolean
*/
public static function stream_control($media_ids, User $user = null)
{
if ($user == null) {
$user = $GLOBALS['user'];
}
foreach (Plugin::get_plugins('stream_control') as $plugin_name) {
$plugin = new Plugin($plugin_name);
if ($plugin->load($user)) {
if (!$plugin->_plugin->stream_control($media_ids)) {
return false;
}
}
}
return true;
}
} //end user class

View file

@ -0,0 +1,132 @@
<?php
/* vim:set softtabstop=4 shiftwidth=4 expandtab: */
/**
*
* LICENSE: GNU General Public License, version 2 (GPLv2)
* Copyright 2001 - 2014 Ampache.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License v2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
class AmpacheStreamBandwidth
{
public $name = 'Stream Bandwidth';
public $categories = 'stream_control';
public $description = 'Stream Control Bandwidth per user';
public $url = '';
public $version = '000001';
public $min_ampache = '370024';
public $max_ampache = '999999';
private $user_id;
private $bandwidth_days;
private $bandwidth_max;
/**
* Constructor
* This function does nothing...
*/
public function __construct() {
return true;
} // constructor
/**
* install
* This is a required plugin function. It inserts our preferences
* into Ampache
*/
public function install() {
if (Preference::exists('stream_control_bandwidth_max')) { return false; }
Preference::insert('stream_control_bandwidth_max','Stream control maximal bandwidth (Mo)','1024','50','integer','plugins');
Preference::insert('stream_control_bandwidth_days','Stream control bandwidth history (days)','30','50','integer','plugins');
return true;
} // install
/**
* uninstall
* This is a required plugin function. It removes our preferences from
* the database returning it to its original form
*/
public function uninstall() {
Preference::delete('stream_control_bandwidth_max');
Preference::delete('stream_control_bandwidth_days');
return true;
} // uninstall
/**
* upgrade
* This is a recommended plugin function
*/
public function upgrade() {
return true;
} // upgrade
/**
* Check stream control
* @param array $media_ids
* @return boolean
*/
public function stream_control($media_ids)
{
// No check if unlimited bandwidth (= -1)
if ($this->bandwidth_max < 0)
return true;
// Calculate all media size
$next_total = 0;
foreach ($media_ids as $media_id) {
$media = new $media_id['object_type']($media_id['object_id']);
$next_total += $media->size;
}
$graph = new Graph();
$end_date = time();
$start_date = $end_date - ($this->bandwidth_days * 86400);
$current_total = $graph->get_total_bandwidth($this->user_id, $start_date, $end_date);
$next_total += $current_total;
$max = $this->bandwidth_max * 1024 * 1024;
debug_event('stream_control_bandwidth', 'Next stream bandwidth will be ' . $next_total . ' / ' . $max, 3);
return ($next_total <= $max);
}
/**
* load
* This loads up the data we need into this object, this stuff comes
* from the preferences.
*/
public function load($user) {
$user->set_preferences();
$data = $user->prefs;
$this->user_id = $user->id;
if (intval($data['stream_control_bandwidth_max'])) {
$this->bandwidth_max = intval($data['stream_control_bandwidth_max']);
}
else {
$this->bandwidth_max = 1024;
}
if (intval($data['stream_control_bandwidth_days']) > 0) {
$this->bandwidth_days = intval($data['stream_control_bandwidth_days']);
}
else {
$this->bandwidth_days = 30;
}
return true;
} // load
}

View file

@ -0,0 +1,126 @@
<?php
/* vim:set softtabstop=4 shiftwidth=4 expandtab: */
/**
*
* LICENSE: GNU General Public License, version 2 (GPLv2)
* Copyright 2001 - 2014 Ampache.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License v2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
class AmpacheStreamHits
{
public $name = 'Stream Hits';
public $categories = 'stream_control';
public $description = 'Stream Control Hits per user';
public $url = '';
public $version = '000001';
public $min_ampache = '370024';
public $max_ampache = '999999';
private $user_id;
private $hits_days;
private $hits_max;
/**
* Constructor
* This function does nothing...
*/
public function __construct() {
return true;
} // constructor
/**
* install
* This is a required plugin function. It inserts our preferences
* into Ampache
*/
public function install() {
if (Preference::exists('stream_control_hits_max')) { return false; }
Preference::insert('stream_control_hits_max','Stream control maximal hits','-1','50','integer','plugins');
Preference::insert('stream_control_hits_days','Stream control hits history (days)','30','50','integer','plugins');
return true;
} // install
/**
* uninstall
* This is a required plugin function. It removes our preferences from
* the database returning it to its original form
*/
public function uninstall() {
Preference::delete('stream_control_hits_max');
Preference::delete('stream_control_hits_days');
return true;
} // uninstall
/**
* upgrade
* This is a recommended plugin function
*/
public function upgrade() {
return true;
} // upgrade
/**
* Check stream control
* @param array $media_ids
* @return boolean
*/
public function stream_control($media_ids)
{
// No check if unlimited hits (= -1)
if ($this->hits_max < 0)
return true;
$next_total = count($media_ids);
$graph = new Graph();
$end_date = time();
$start_date = $end_date - ($this->hits_days * 86400);
$current_total = $graph->get_total_hits($this->user_id, $start_date, $end_date);
$next_total += $current_total;
debug_event('stream_control_bandwidth', 'Next stream hits will be ' . $next_total . ' / ' . $this->hits_max, 3);
return ($next_total <= $this->hits_max);
}
/**
* load
* This loads up the data we need into this object, this stuff comes
* from the preferences.
*/
public function load($user) {
$user->set_preferences();
$data = $user->prefs;
$this->user_id = $user->id;
if (intval($data['stream_control_hits_max'])) {
$this->hits_max = intval($data['stream_control_hits_max']);
}
else {
$this->hits_max = -1;
}
if (intval($data['stream_control_hits_days']) > 0) {
$this->hits_days = intval($data['stream_control_hits_days']);
}
else {
$this->hits_days = 30;
}
return true;
} // load
}

View file

@ -287,6 +287,12 @@ if ($type == 'song') {
$media->format();
}
if (!User::stream_control(array(array('object_type' => $type, 'object_id' => $media->id)))) {
debug_event('UI::access_denied', 'Stream control failed for user ' . $GLOBALS['user']->username . ' on ' . $media->get_stream_name(), 3);
UI::access_denied();
exit;
}
if ($media->catalog) {
// Build up the catalog for our current object
$catalog = Catalog::create_from_id($media->catalog);
@ -372,6 +378,16 @@ if ($_GET['action'] == 'download' AND AmpConfig::get('download')) {
exit();
}
if (!$share_id) {
if ($_SERVER['REQUEST_METHOD'] != 'HEAD') {
debug_event('play', 'Registering download stats for {' . $media->get_stream_name() . '}...', '5');
$sessionkey = $sid ?: Stream::get_session();
$agent = Session::agent($sessionkey);
$location = Session::get_geolocation($sessionkey);
Stats::insert($type, $media->id, $uid, $agent, $location, 'download');
}
}
// Check to see if we should be throttling because we can get away with it
if (AmpConfig::get('rate_limit') > 0) {
while (!feof($fp)) {
@ -569,7 +585,7 @@ if (!isset($_REQUEST['segment'])) {
} else {
if (!$share_id) {
if ($_SERVER['REQUEST_METHOD'] != 'HEAD') {
debug_event('play', 'Registering stats for {'.$media->get_stream_name() .'}...', '5');
debug_event('play', 'Registering stream stats for {'.$media->get_stream_name() .'}...', '5');
$sessionkey = $sid ?: Stream::get_session();
$agent = Session::agent($sessionkey);
$location = Session::get_geolocation($sessionkey);

View file

@ -162,7 +162,16 @@ switch ($_REQUEST['action']) {
debug_event('stream.php' , 'Stream Type: ' . $stream_type . ' Media IDs: '. json_encode($media_ids), 5);
if (count(media_ids)) {
if (count($media_ids)) {
if ($stream_type != 'democratic') {
if (!User::stream_control($media_ids)) {
debug_event('UI::access_denied', 'Stream control failed for user ' . $GLOBALS['user']->username, 3);
UI::access_denied();
exit;
}
}
if ($GLOBALS['user']->id > -1) {
Session::update_username(Stream::get_session(), $GLOBALS['user']->username);
}