Beispiel #1
0
 /**
  * constructor
  * This should be called
  * @param int|null $id
  * @param boolean $cached
  */
 public function __construct($id = null, $cached = true)
 {
     $sid = session_id();
     if (!$cached) {
         $this->id = 'nocache';
         return true;
     }
     if (is_null($id)) {
         $this->reset();
         $data = self::_serialize($this->_state);
         $sql = 'INSERT INTO `tmp_browse` (`sid`, `data`) VALUES(?, ?)';
         Dba::write($sql, array($sid, $data));
         $this->id = Dba::insert_id();
         return true;
     } else {
         $sql = 'SELECT `data` FROM `tmp_browse` WHERE `id` = ? AND `sid` = ?';
         $db_results = Dba::read($sql, array($id, $sid));
         if ($results = Dba::fetch_assoc($db_results)) {
             $this->id = $id;
             $this->_state = (array) self::_unserialize($results['data']);
             return true;
         }
     }
     AmpError::add('browse', T_('Browse not found or expired, try reloading the page'));
     return false;
 }
Beispiel #2
0
 /**
  * set
  *
  * This sets config values.
  * @param string $name
  * @param boolean $clobber
  */
 public static function set($name, $value, $clobber = false)
 {
     if (isset(self::$_global[$name]) && !$clobber) {
         debug_event('Config', "Tried to overwrite existing key {$name} without setting clobber", 5);
         AmpError::add('Config Global', sprintf(T_('Trying to clobber \'%s\' without setting clobber'), $name));
         return false;
     }
     self::$_global[$name] = $value;
 }
Beispiel #3
0
 /**
  * update_remote_catalog
  *
  * Pulls the data from a remote catalog and adds any missing songs to the
  * database.
  */
 public function update_remote_catalog()
 {
     debug_event('subsonic_catalog', 'Updating remote catalog...', 5);
     $subsonic = $this->createClient();
     $songsadded = 0;
     // Get all artists
     $artists = $subsonic->getIndexes();
     if ($artists['success']) {
         foreach ($artists['data']['indexes']['index'] as $index) {
             foreach ($index['artist'] as $artist) {
                 // Get albums for artist
                 $albums = $subsonic->getMusicDirectory(array('id' => $artist['id']));
                 if ($albums['success']) {
                     foreach ($albums['data']['directory']['child'] as $album) {
                         if (is_array($album)) {
                             $songs = $subsonic->getMusicDirectory(array('id' => $album['id']));
                             if ($songs['success']) {
                                 foreach ($songs['data']['directory']['child'] as $song) {
                                     if (is_array($song)) {
                                         $data = array();
                                         $data['artist'] = html_entity_decode($song['artist']);
                                         $data['album'] = html_entity_decode($song['album']);
                                         $data['title'] = html_entity_decode($song['title']);
                                         $data['bitrate'] = $song['bitRate'] * 1000;
                                         $data['size'] = $song['size'];
                                         $data['time'] = $song['duration'];
                                         $data['track'] = $song['track'];
                                         $data['disk'] = $song['discNumber'];
                                         $data['mode'] = 'vbr';
                                         $data['genre'] = explode(' ', html_entity_decode($song['genre']));
                                         $data['file'] = $this->uri . '/rest/stream.view?id=' . $song['id'] . '&filename=' . urlencode($song['path']);
                                         if ($this->check_remote_song($data)) {
                                             debug_event('subsonic_catalog', 'Skipping existing song ' . $data['path'], 5);
                                         } else {
                                             $data['catalog'] = $this->id;
                                             debug_event('subsonic_catalog', 'Adding song ' . $song['path'], 5, 'ampache-catalog');
                                             if (!Song::insert($data)) {
                                                 debug_event('subsonic_catalog', 'Insert failed for ' . $song['path'], 1);
                                                 AmpError::add('general', T_('Unable to Insert Song - %s'), $song['path']);
                                             } else {
                                                 $songsadded++;
                                             }
                                         }
                                     }
                                 }
                             } else {
                                 debug_event('subsonic_catalog', 'Song error:' . $songs['error'], 3);
                                 AmpError::add('general', T_('Song Error.') . ": " . $songs['error']);
                             }
                         }
                     }
                 } else {
                     debug_event('subsonic_catalog', 'Album error:' . $albums['error'], 3);
                     AmpError::add('general', T_('Album Error.') . ": " . $albums['error']);
                 }
             }
         }
         UI::update_text('', T_('Completed updating Subsonic catalog(s).') . " " . $songsadded . " " . T_('Songs added.'));
         // Update the last update value
         $this->update_last_update();
     } else {
         debug_event('subsonic_catalog', 'Artist error:' . $artists['error'], 3);
         AmpError::add('general', T_('Artist Error.') . ": " . $artists['error']);
     }
     debug_event('subsonic_catalog', 'Catalog updated.', 5);
     return true;
 }
Beispiel #4
0
         break;
     }
     catalog_worker('update_from', null, $_POST);
     show_confirmation(T_('Subdirectory update started...'), '', AmpConfig::get('web_path') . '/admin/catalog.php', 0, 'confirmation', false);
     break;
 case 'add_catalog':
     /* Wah Demo! */
     if (AmpConfig::get('demo_mode')) {
         break;
     }
     ob_end_flush();
     if (!strlen($_POST['type']) || $_POST['type'] == 'none') {
         AmpError::add('general', T_('Error: Please select a catalog type'));
     }
     if (!strlen($_POST['name'])) {
         AmpError::add('general', T_('Error: Name not specified'));
     }
     if (!Core::form_verify('add_catalog', 'post')) {
         UI::access_denied();
         exit;
     }
     // If an error hasn't occured
     if (!AmpError::occurred()) {
         $catalog_id = Catalog::create($_POST);
         if (!$catalog_id) {
             require AmpConfig::get('prefix') . UI::find_template('show_add_catalog.inc.php');
             break;
         }
         $catalogs[] = $catalog_id;
         catalog_worker('add_to_catalog', $catalogs, $_POST);
         show_confirmation(T_('Catalog Creation started...'), '', AmpConfig::get('web_path') . '/admin/catalog.php', 0, 'confirmation', false);
Beispiel #5
0
 /**
  * update_360051
  *
  * Copy default .htaccess configurations
  */
 public static function update_360051()
 {
     require_once AmpConfig::get('prefix') . '/lib/install.lib.php';
     if (!install_check_server_apache()) {
         debug_event('update', 'Not using Apache, update 360051 skipped.', '5');
         return true;
     }
     $htaccess_play_file = AmpConfig::get('prefix') . '/play/.htaccess';
     $htaccess_rest_file = AmpConfig::get('prefix') . '/rest/.htaccess';
     $htaccess_channel_file = AmpConfig::get('prefix') . '/channel/.htaccess';
     $ret = true;
     if (!is_readable($htaccess_play_file)) {
         $created = false;
         if (check_htaccess_play_writable()) {
             if (!install_rewrite_rules($htaccess_play_file, AmpConfig::get('raw_web_path'), false)) {
                 AmpError::add('general', T_('File copy error.'));
             } else {
                 $created = true;
             }
         }
         if (!$created) {
             AmpError::add('general', T_('Cannot copy default .htaccess file.') . ' Please copy <b>' . $htaccess_play_file . '.dist</b> to <b>' . $htaccess_play_file . '</b>.');
             $ret = false;
         }
     }
     if (!is_readable($htaccess_rest_file)) {
         $created = false;
         if (check_htaccess_rest_writable()) {
             if (!install_rewrite_rules($htaccess_rest_file, AmpConfig::get('raw_web_path'), false)) {
                 AmpError::add('general', T_('File copy error.'));
             } else {
                 $created = true;
             }
         }
         if (!$created) {
             AmpError::add('general', T_('Cannot copy default .htaccess file.') . ' Please copy <b>' . $htaccess_rest_file . '.dist</b> to <b>' . $htaccess_rest_file . '</b>.');
             $ret = false;
         }
     }
     if (!is_readable($htaccess_channel_file)) {
         $created = false;
         if (check_htaccess_channel_writable()) {
             if (!install_rewrite_rules($htaccess_channel_file, AmpConfig::get('raw_web_path'), false)) {
                 AmpError::add('general', T_('File copy error.'));
             } else {
                 $created = true;
             }
         }
         if (!$created) {
             AmpError::add('general', T_('Cannot copy default .htaccess file.') . ' Please copy <b>' . $htaccess_channel_file . '.dist</b> to <b>' . $htaccess_channel_file . '</b>.');
             $ret = false;
         }
     }
     return $ret;
 }
Beispiel #6
0
 /**
  * _clean_chunk
  * This is the clean function, its broken into
  * said chunks to try to save a little memory
  */
 private function _clean_chunk($media_type, $chunk, $chunk_size)
 {
     debug_event('clean', "Starting chunk {$chunk}", 5);
     $dead = array();
     $count = $chunk * $chunk_size;
     $sql = "SELECT `id`, `file` FROM `{$media_type}` " . "WHERE `catalog`='{$this->id}' LIMIT {$count},{$chunk_size}";
     $db_results = Dba::read($sql);
     while ($results = Dba::fetch_assoc($db_results)) {
         debug_event('clean', 'Starting work on ' . $results['file'] . '(' . $results['id'] . ')', 5);
         $count++;
         if (UI::check_ticker()) {
             $file = str_replace(array('(', ')', '\''), '', $results['file']);
             UI::update_text('clean_count_' . $this->id, $count);
             UI::update_text('clean_dir_' . $this->id, scrub_out($file));
         }
         $file_info = Core::get_filesize(Core::conv_lc_file($results['file']));
         if (!file_exists(Core::conv_lc_file($results['file'])) || $file_info < 1) {
             debug_event('clean', 'File not found or empty: ' . $results['file'], 5);
             AmpError::add('general', sprintf(T_('Error File Not Found or 0 Bytes: %s'), $results['file']));
             // Store it in an array we'll delete it later...
             $dead[] = $results['id'];
         } else {
             if (!Core::is_readable(Core::conv_lc_file($results['file']))) {
                 debug_event('clean', $results['file'] . ' is not readable, but does exist', 1);
             }
         }
     }
     return $dead;
 }
Beispiel #7
0
     $_POST['username'] = $GLOBALS['user']->username;
     $mandatory_fields = (array) AmpConfig::get('registration_mandatory_fields');
     if (in_array('fullname', $mandatory_fields) && !$_POST['fullname']) {
         AmpError::add('fullname', T_("Please fill in your full name (Firstname Lastname)"));
     }
     if (in_array('website', $mandatory_fields) && !$_POST['website']) {
         AmpError::add('website', T_("Please fill in your website"));
     }
     if (in_array('state', $mandatory_fields) && !$_POST['state']) {
         AmpError::add('state', T_("Please fill in your state"));
     }
     if (in_array('city', $mandatory_fields) && !$_POST['city']) {
         AmpError::add('city', T_("Please fill in your city"));
     }
     if (!$GLOBALS['user']->update($_POST)) {
         AmpError::add('general', T_('Error Update Failed'));
     } else {
         $GLOBALS['user']->upload_avatar();
         //$_REQUEST['action'] = 'confirm';
         $title = T_('Updated');
         $text = T_('Your Account has been updated');
         $next_url = AmpConfig::get('web_path') . '/preferences.php?tab=account';
     }
     $notification_text = T_('User updated successfully');
     break;
 case 'grant':
     // Make sure we're a user and they came from the form
     if (!Access::check('interface', '25') && $GLOBALS['user']->id > 0) {
         UI::access_denied();
         exit;
     }
Beispiel #8
0
 public static function create(array $data)
 {
     $subject = trim(strip_tags($data['subject']));
     $message = trim(strip_tags($data['message']));
     if (empty($subject)) {
         AmpError::add('subject', T_('Error: Subject Required'));
     }
     $to_user = User::get_from_username($data['to_user']);
     if (!$to_user->id) {
         AmpError::add('to_user', T_('Error: Unknown user'));
     }
     if (!AmpError::occurred()) {
         $from_user = $data['from_user'] ?: $GLOBALS['user']->id;
         $creation_date = $data['creation_date'] ?: time();
         $is_read = $data['is_read'] ?: 0;
         $sql = "INSERT INTO `user_pvmsg` (`subject`, `message`, `from_user`, `to_user`, `creation_date`, `is_read`) " . "VALUES (?, ?, ?, ?, ?, ?)";
         if (Dba::write($sql, array($subject, $message, $from_user, $to_user->id, $creation_date, $is_read))) {
             $insert_id = Dba::insert_id();
             // Never send email in case of user impersonation
             if (!isset($data['from_user']) && $insert_id) {
                 if (Preference::get_by_user($to_user->id, 'notify_email')) {
                     if (!empty($to_user->email)) {
                         $mailer = new Mailer();
                         $mailer->set_default_sender();
                         $mailer->recipient = $to_user->email;
                         $mailer->recipient_name = $to_user->fullname;
                         $mailer->subject = "[" . T_('Private Message') . "] " . $subject;
                         $mailer->message = sprintf(T_("You just received a new private message from %s.\n\n\n        ----------------------\n        %s\n        ----------------------\n\n        %s\n        "), $GLOBALS['user']->fullname, $message, AmpConfig::get('web_path') . "/pvmsg.php?action=show&pvmsg_id=" . $insert_id);
                         $mailer->send();
                     }
                 }
             }
             return $insert_id;
         }
     }
     return false;
 }
Beispiel #9
0
require_once 'lib/init.php';
$action = isset($_POST['action']) ? $_POST['action'] : "";
switch ($action) {
    case 'send':
        /* Check for posted email */
        $result = false;
        if (isset($_POST['email']) && $_POST['email']) {
            /* Get the email address and the current ip*/
            $email = scrub_in($_POST['email']);
            $current_ip = isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'];
            $result = send_newpassword($email, $current_ip);
        }
        if ($result) {
            AmpError::add('general', T_('Password has been sent'));
        } else {
            AmpError::add('general', T_('Password has not been sent'));
        }
        require AmpConfig::get('prefix') . UI::find_template('show_login_form.inc.php');
        break;
    default:
        require AmpConfig::get('prefix') . UI::find_template('show_lostpassword_form.inc.php');
}
function send_newpassword($email, $current_ip)
{
    /* get the Client and set the new password */
    $client = User::get_from_email($email);
    if ($client && $client->email == $email) {
        $newpassword = generate_password(6);
        $client->update_password($newpassword);
        $mailer = new Mailer();
        $mailer->set_default_sender();
Beispiel #10
0
     switch (AmpConfig::get('auto_user')) {
         case 'admin':
             $access = '100';
             break;
         case 'user':
             $access = '25';
             break;
         case 'guest':
         default:
             $access = '5';
             break;
     }
     // auto-user level
     $new_user = User::create($username, $fullname, $email, $website, $pass1, $access, $state, $city, AmpConfig::get('admin_enable_required'));
     if (!$new_user) {
         AmpError::add('duplicate_user', T_("Error: Insert Failed"));
         require_once AmpConfig::get('prefix') . UI::find_template('show_user_registration.inc.php');
         break;
     }
     if (!AmpConfig::get('user_no_email_confirm')) {
         $client = new User($new_user);
         $validation = md5(uniqid(rand(), true));
         $client->update_validation($validation);
         // Notify user and/or admins
         Registration::send_confirmation($username, $fullname, $email, $website, $pass1, $validation);
     }
     require_once AmpConfig::get('prefix') . UI::find_template('show_registration_confirmation.inc.php');
     break;
 case 'show_add_user':
 default:
     require_once AmpConfig::get('prefix') . UI::find_template('show_user_registration.inc.php');
Beispiel #11
0
 /**
  * handshake
  *
  * This is the function that handles verifying a new handshake
  * Takes a timestamp, auth key, and username.
  * @param array
  * @return boolean
  */
 public static function handshake($input)
 {
     $timestamp = preg_replace('/[^0-9]/', '', $input['timestamp']);
     $passphrase = $input['auth'];
     if (empty($passphrase)) {
         $passphrase = $_POST['auth'];
     }
     $username = trim($input['user']);
     $ip = $_SERVER['REMOTE_ADDR'];
     $version = $input['version'];
     // Log the attempt
     debug_event('API', "Handshake Attempt, IP:{$ip} User:{$username} Version:{$version}", 5);
     // Version check shouldn't be soo restrictive... only check with initial version to not break clients compatibility
     if (intval($version) < self::$auth_version) {
         debug_event('API', 'Login Failed: version too old', 1);
         AmpError::add('api', T_('Login Failed: version too old'));
         return false;
     }
     $user_id = -1;
     // Grab the correct userid
     if (!$username) {
         $client = User::get_from_apikey($passphrase);
         if ($client) {
             $user_id = $client->id;
         }
     } else {
         $client = User::get_from_username($username);
         $user_id = $client->id;
     }
     // Log this attempt
     debug_event('API', "Login Attempt, IP:{$ip} Time: {$timestamp} User:{$username} ({$user_id}) Auth:{$passphrase}", 1);
     if ($user_id > 0 && Access::check_network('api', $user_id, 5, $ip)) {
         // Authentication with user/password, we still need to check the password
         if ($username) {
             // If the timestamp isn't within 30 minutes sucks to be them
             if ($timestamp < time() - 1800 || $timestamp > time() + 1800) {
                 debug_event('API', 'Login Failed: timestamp out of range ' . $timestamp . '/' . time(), 1);
                 AmpError::add('api', T_('Login Failed: timestamp out of range'));
                 echo XML_Data::error('401', T_('Error Invalid Handshake - ') . T_('Login Failed: timestamp out of range'));
                 return false;
             }
             // Now we're sure that there is an ACL line that matches
             // this user or ALL USERS, pull the user's password and
             // then see what we come out with
             $realpwd = $client->get_password();
             if (!$realpwd) {
                 debug_event('API', 'Unable to find user with userid of ' . $user_id, 1);
                 AmpError::add('api', T_('Invalid Username/Password'));
                 echo XML_Data::error('401', T_('Error Invalid Handshake - ') . T_('Invalid Username/Password'));
                 return false;
             }
             $sha1pass = hash('sha256', $timestamp . $realpwd);
             if ($sha1pass !== $passphrase) {
                 $client = null;
             }
         } else {
             $timestamp = time();
         }
         if ($client) {
             // Create the session
             $data = array();
             $data['username'] = $client->username;
             $data['type'] = 'api';
             $data['value'] = $timestamp;
             if (isset($input['client'])) {
                 $data['agent'] = $input['client'];
             }
             if (isset($input['geo_latitude'])) {
                 $data['geo_latitude'] = $input['geo_latitude'];
             }
             if (isset($input['geo_longitude'])) {
                 $data['geo_longitude'] = $input['geo_longitude'];
             }
             if (isset($input['geo_name'])) {
                 $data['geo_name'] = $input['geo_name'];
             }
             $token = Session::create($data);
             debug_event('API', 'Login Success, passphrase matched', 1);
             // We need to also get the 'last update' of the
             // catalog information in an RFC 2822 Format
             $sql = 'SELECT MAX(`last_update`) AS `update`, MAX(`last_add`) AS `add`, MAX(`last_clean`) AS `clean` FROM `catalog`';
             $db_results = Dba::read($sql);
             $row = Dba::fetch_assoc($db_results);
             // Now we need to quickly get the song totals
             $sql = 'SELECT COUNT(`id`) AS `song`, ' . 'COUNT(DISTINCT(`album`)) AS `album`, ' . 'COUNT(DISTINCT(`artist`)) AS `artist` ' . 'FROM `song`';
             $db_results = Dba::read($sql);
             $counts = Dba::fetch_assoc($db_results);
             // Next the video counts
             $sql = "SELECT COUNT(`id`) AS `video` FROM `video`";
             $db_results = Dba::read($sql);
             $vcounts = Dba::fetch_assoc($db_results);
             $sql = "SELECT COUNT(`id`) AS `playlist` FROM `playlist`";
             $db_results = Dba::read($sql);
             $playlist = Dba::fetch_assoc($db_results);
             $sql = "SELECT COUNT(`id`) AS `catalog` FROM `catalog` WHERE `catalog_type`='local'";
             $db_results = Dba::read($sql);
             $catalog = Dba::fetch_assoc($db_results);
             echo XML_Data::keyed_array(array('auth' => $token, 'api' => self::$version, 'session_expire' => date("c", time() + AmpConfig::get('session_length') - 60), 'update' => date("c", $row['update']), 'add' => date("c", $row['add']), 'clean' => date("c", $row['clean']), 'songs' => $counts['song'], 'albums' => $counts['album'], 'artists' => $counts['artist'], 'playlists' => $playlist['playlist'], 'videos' => $vcounts['video'], 'catalogs' => $catalog['catalog']));
             return true;
         }
         // match
     }
     // end while
     debug_event('API', 'Login Failed, unable to match passphrase', '1');
     echo XML_Data::error('401', T_('Error Invalid Handshake - ') . T_('Invalid Username/Password'));
     return false;
 }
Beispiel #12
0
         }
         if ($write_htaccess_play || $download_htaccess_play || $all) {
             $created_config = $created_config && install_rewrite_rules($htaccess_play_file, $_POST['web_path'], $download_htaccess_play);
         }
         if ($write || $download || $all) {
             $created_config = $created_config && install_create_config($download);
         }
     }
 case 'show_create_account':
     $results = parse_ini_file($configfile);
     if (!isset($created_config)) {
         $created_config = true;
     }
     /* Make sure we've got a valid config file */
     if (!check_config_values($results) || !$created_config) {
         AmpError::add('general', T_('Error: Config files not found or unreadable'));
         require_once AmpConfig::get('prefix') . UI::find_template('show_install_config.inc.php');
         break;
     }
     // Don't try to add administrator user on existing database
     if (install_check_status($configfile)) {
         require_once AmpConfig::get('prefix') . UI::find_template('show_install_account.inc.php');
     } else {
         header("Location: " . $web_path . '/login.php');
     }
     break;
 case 'create_account':
     $results = parse_ini_file($configfile);
     AmpConfig::set_by_array($results, true);
     $password2 = $_REQUEST['local_pass2'];
     if (!install_create_account($username, $password, $password2)) {
Beispiel #13
0
     break;
 case 'uninstall_localplay':
     $type = (string) scrub_in($_REQUEST['type']);
     $localplay = new Localplay($type);
     $localplay->uninstall();
     /* Show Confirmation */
     $url = AmpConfig::get('web_path') . '/admin/modules.php?action=show_localplay';
     $title = T_('Plugin Deactivated');
     $body = '';
     show_confirmation($title, $body, $url);
     break;
 case 'uninstall_catalog_type':
     $type = (string) scrub_in($_REQUEST['type']);
     $catalog = Catalog::create_catalog_type($type);
     if ($catalog == null) {
         AmpError::add('general', T_('Uninstall Failed, Catalog Error'));
         AmpError::display('general');
         break;
     }
     $catalog->uninstall();
     /* Show Confirmation */
     $url = AmpConfig::get('web_path') . '/admin/modules.php?action=show_catalog_types';
     $title = T_('Plugin Deactivated');
     $body = '';
     show_confirmation($title, $body, $url);
     break;
 case 'install_plugin':
     /* Verify that this plugin exists */
     $plugins = Plugin::get_plugins();
     if (!array_key_exists($_REQUEST['plugin'], $plugins)) {
         debug_event('plugins', 'Error: Invalid Plugin: ' . $_REQUEST['plugin'] . ' selected', '1');
Beispiel #14
0
            debug_event('Login', scrub_out($username) . ' is already logged in from ' . $session_ip . ' and attempted to login from ' . $current_ip, '1');
        }
        // if logged in multiple times
    } elseif (AmpConfig::get('auto_create') && $auth['success'] && !$user->username) {
        /* This is run if we want to autocreate users who don't
           exist (useful for non-mysql auth) */
        $access = AmpConfig::get('auto_user') ? User::access_name_to_level(AmpConfig::get('auto_user')) : '5';
        $name = $auth['name'];
        $email = $auth['email'];
        $website = $auth['website'];
        /* Attempt to create the user */
        if (User::create($username, $name, $email, $website, hash('sha256', mt_rand()), $access)) {
            $user = User::get_from_username($username);
        } else {
            $auth['success'] = false;
            AmpError::add('general', T_('Unable to create local account'));
        }
    }
    // End if auto_create
    // This allows stealing passwords validated by external means
    // such as LDAP
    if (AmpConfig::get('auth_password_save') && $auth['success'] && isset($password)) {
        $user->update_password($password);
    }
}
/* If the authentication was a success */
if (isset($auth) && $auth['success'] && isset($user)) {
    // $auth->info are the fields specified in the config file
    //   to retrieve for each user
    Session::create($auth);
    // Not sure if it was me or php tripping out,
Beispiel #15
0
        if (isset($_POST['date'])) {
            unset($_POST['date']);
        }
        if (!Core::is_library_item($_POST['object_type'])) {
            UI::access_denied();
            exit;
        }
        $shout_id = Shoutbox::create($_POST);
        header("Location:" . AmpConfig::get('web_path') . '/shout.php?action=show_add_shout&type=' . $_POST['object_type'] . '&id=' . intval($_POST['object_id']));
        exit;
        break;
    case 'show_add_shout':
        // Get our object first
        $object = Shoutbox::get_object($_REQUEST['type'], $_REQUEST['id']);
        if (!$object || !$object->id) {
            AmpError::add('general', T_('Invalid Object Selected'));
            AmpError::display('general');
            break;
        }
        $object->format();
        if (strtolower(get_class($object)) == 'song') {
            $data = $_REQUEST['offset'];
        }
        // Now go ahead and display the page where we let them add a comment etc
        require_once AmpConfig::get('prefix') . UI::find_template('show_add_shout.inc.php');
        break;
    default:
        header("Location:" . AmpConfig::get('web_path'));
        break;
}
// end switch on action
Beispiel #16
0
 /**
  * Add the song to the DB
  * @param array $song
  * @return integer
  */
 protected function insertSong($song)
 {
     $inserted = Song::insert($song);
     if ($inserted) {
         debug_event('beets_catalog', 'Adding song ' . $song['file'], 5, 'ampache-catalog');
     } else {
         debug_event('beets_catalog', 'Insert failed for ' . $song['file'], 1);
         AmpError::add('general', T_('Unable to Insert Song - %s'), $song['file']);
         AmpError::display('general');
     }
     flush();
     return $inserted;
 }
Beispiel #17
0
     if (!User::check_username($username)) {
         AmpError::add('username', T_('Error Username already exists'));
     }
     // Check the mail for correct address formation.
     if (!Mailer::validate_address($email)) {
         AmpError::add('email', T_('Invalid email address'));
     }
     /* If we've got an error then show add form! */
     if (AmpError::occurred()) {
         require_once AmpConfig::get('prefix') . UI::find_template('show_add_user.inc.php');
         break;
     }
     /* Attempt to create the user */
     $user_id = User::create($username, $fullname, $email, $website, $pass1, $access, $state, $city);
     if (!$user_id) {
         AmpError::add('general', T_("Error: Insert Failed"));
     }
     $user = new User($user_id);
     $user->upload_avatar();
     if ($access == 5) {
         $access = T_('Guest');
     } elseif ($access == 25) {
         $access = T_('User');
     } elseif ($access == 100) {
         $access = T_('Admin');
     }
     /* HINT: %1 Username, %2 Access num */
     show_confirmation(T_('New User Added'), sprintf(T_('%1$s has been created with an access level of %2$s'), $username, $access), AmpConfig::get('web_path') . '/admin/users.php');
     break;
 case 'enable':
     $client = new User($_REQUEST['user_id']);
Beispiel #18
0
 public static function create(array $data)
 {
     $feed = $data['feed'];
     // Feed must be http/https
     if (strpos($feed, "http://") !== 0 && strpos($feed, "https://") !== 0) {
         AmpError::add('feed', T_('Wrong feed url'));
     }
     $catalog_id = intval($data['catalog']);
     if ($catalog_id <= 0) {
         AmpError::add('catalog', T_('Target catalog required'));
     } else {
         $catalog = Catalog::create_from_id($catalog_id);
         if ($catalog->gather_types !== "podcast") {
             AmpError::add('catalog', T_('Wrong target catalog type'));
         }
     }
     if (AmpError::occurred()) {
         return false;
     }
     $title = T_('Unknown');
     $website = null;
     $description = null;
     $language = null;
     $copyright = null;
     $generator = null;
     $lastbuilddate = 0;
     $episodes = array();
     $arturl = '';
     $xmlstr = file_get_contents($feed);
     if ($xmlstr === false) {
         AmpError::add('feed', T_('Cannot access the feed.'));
     } else {
         $xml = simplexml_load_string($xmlstr);
         if ($xml === false) {
             AmpError::add('feed', T_('Cannot read the feed.'));
         } else {
             $title = html_entity_decode($xml->channel->title);
             $website = $xml->channel->link;
             $description = html_entity_decode($xml->channel->description);
             $language = $xml->channel->language;
             $copyright = html_entity_decode($xml->channel->copyright);
             $generator = html_entity_decode($xml->channel->generator);
             $lastbuilddatestr = $xml->channel->lastBuildDate;
             if ($lastbuilddatestr) {
                 $lastbuilddate = strtotime($lastbuilddatestr);
             }
             if ($xml->channel->image) {
                 $arturl = $xml->channel->image->url;
             }
             $episodes = $xml->channel->item;
         }
     }
     if (AmpError::occurred()) {
         return false;
     }
     $sql = "INSERT INTO `podcast` (`feed`, `catalog`, `title`, `website`, `description`, `language`, `copyright`, `generator`, `lastbuilddate`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
     $db_results = Dba::write($sql, array($feed, $catalog_id, $title, $website, $description, $language, $copyright, $generator, $lastbuilddate));
     if ($db_results) {
         $id = Dba::insert_id();
         $podcast = new Podcast($id);
         $dirpath = $podcast->get_root_path();
         if (!is_dir($dirpath)) {
             if (mkdir($dirpath) === false) {
                 debug_event('podcast', 'Cannot create directory ' . $dirpath, 1);
             }
         }
         if (!empty($arturl)) {
             $art = new Art($id, 'podcast');
             $art->insert_url($arturl);
         }
         if (count($episodes) > 0) {
             $podcast->add_episodes($episodes);
         }
     }
     return $db_results;
 }
Beispiel #19
0
 /**
  * update_remote_catalog
  *
  * Pulls the data from a remote catalog and adds any missing songs to the
  * database.
  */
 public function update_remote_catalog()
 {
     $songsadded = 0;
     try {
         $api = $this->createClient();
         if ($api != null) {
             // Get all liked songs
             $songs = json_decode($api->get('me/favorites'));
             if ($songs) {
                 foreach ($songs as $song) {
                     if ($song->streamable == true && $song->kind == 'track') {
                         $data = array();
                         $data['artist'] = $song->user->username;
                         $data['album'] = $data['artist'];
                         $data['title'] = $song->title;
                         $data['year'] = $song->release_year;
                         $data['mode'] = 'vbr';
                         $data['genre'] = explode(' ', $song->genre);
                         $data['comment'] = $song->description;
                         $data['file'] = $song->stream_url . '.mp3';
                         // Always stream as mp3, if evolve => $song->original_format;
                         $data['size'] = $song->original_content_size;
                         $data['time'] = intval($song->duration / 1000);
                         if ($this->check_remote_song($data)) {
                             debug_event('soundcloud_catalog', 'Skipping existing song ' . $data['file'], 5);
                         } else {
                             $data['catalog'] = $this->id;
                             debug_event('soundcloud_catalog', 'Adding song ' . $data['file'], 5, 'ampache-catalog');
                             if (!Song::insert($data)) {
                                 debug_event('soundcloud_catalog', 'Insert failed for ' . $data['file'], 1);
                                 AmpError::add('general', T_('Unable to Insert Song - %s'), $data['file']);
                             } else {
                                 $songsadded++;
                             }
                         }
                     }
                 }
                 UI::update_text('', T_('Completed updating SoundCloud catalog(s).') . " " . $songsadded . " " . T_('Songs added.'));
                 // Update the last update value
                 $this->update_last_update();
             } else {
                 AmpError::add('general', T_('API Error: cannot get song list.'));
             }
         } else {
             AmpError::add('general', T_('API Error: cannot connect to SoundCloud.'));
         }
     } catch (Exception $ex) {
         AmpError::add('general', T_('SoundCloud exception: ') . $ex->getMessage());
     }
     return true;
 }
Beispiel #20
0
 /**
  * create
  *
  * This takes a keyed array of data and trys to insert it as a
  * new ACL entry
  * @param array $data
  * @return boolean
  */
 public static function create(array $data)
 {
     if (!self::_verify_range($data['start'], $data['end'])) {
         return false;
     }
     // Check existing ACLs to make sure we're not duplicating values here
     if (self::exists($data)) {
         debug_event('ACL Create', 'Error: An ACL equal to the created one already exists. Not adding another one: ' . $data['start'] . ' - ' . $data['end'], 1);
         AmpError::add('general', T_('Duplicate ACL defined'));
         return false;
     }
     $start = @inet_pton($data['start']);
     $end = @inet_pton($data['end']);
     $name = $data['name'];
     $user = $data['user'] ?: '-1';
     $level = intval($data['level']);
     $type = self::validate_type($data['type']);
     $enabled = make_bool($data['enabled']) ? 1 : 0;
     $sql = 'INSERT INTO `access_list` (`name`, `level`, `start`, `end`, ' . '`user`,`type`,`enabled`) VALUES (?, ?, ?, ?, ?, ?, ?)';
     Dba::write($sql, array($name, $level, $start, $end, $user, $type, $enabled));
     return true;
 }
Beispiel #21
0
 public static function process_action($action, $catalogs, $options = null)
 {
     if (!$options || !is_array($options)) {
         $options = array();
     }
     switch ($action) {
         case 'add_to_all_catalogs':
             $catalogs = Catalog::get_catalogs();
         case 'add_to_catalog':
             if ($catalogs) {
                 foreach ($catalogs as $catalog_id) {
                     $catalog = Catalog::create_from_id($catalog_id);
                     if ($catalog !== null) {
                         $catalog->add_to_catalog($options);
                     }
                 }
                 if (!defined('SSE_OUTPUT')) {
                     AmpError::display('catalog_add');
                 }
             }
             break;
         case 'update_all_catalogs':
             $catalogs = Catalog::get_catalogs();
         case 'update_catalog':
             if ($catalogs) {
                 foreach ($catalogs as $catalog_id) {
                     $catalog = Catalog::create_from_id($catalog_id);
                     if ($catalog !== null) {
                         $catalog->verify_catalog();
                     }
                 }
             }
             break;
         case 'full_service':
             if (!$catalogs) {
                 $catalogs = Catalog::get_catalogs();
             }
             /* This runs the clean/verify/add in that order */
             foreach ($catalogs as $catalog_id) {
                 $catalog = Catalog::create_from_id($catalog_id);
                 if ($catalog !== null) {
                     $catalog->clean_catalog();
                     $catalog->verify_catalog();
                     $catalog->add_to_catalog();
                 }
             }
             Dba::optimize_tables();
             break;
         case 'clean_all_catalogs':
             $catalogs = Catalog::get_catalogs();
         case 'clean_catalog':
             if ($catalogs) {
                 foreach ($catalogs as $catalog_id) {
                     $catalog = Catalog::create_from_id($catalog_id);
                     if ($catalog !== null) {
                         $catalog->clean_catalog();
                     }
                 }
                 // end foreach catalogs
                 Dba::optimize_tables();
             }
             break;
         case 'update_from':
             $catalog_id = 0;
             // First see if we need to do an add
             if ($options['add_path'] != '/' && strlen($options['add_path'])) {
                 if ($catalog_id = Catalog_local::get_from_path($options['add_path'])) {
                     $catalog = Catalog::create_from_id($catalog_id);
                     if ($catalog !== null) {
                         $catalog->add_to_catalog(array('subdirectory' => $options['add_path']));
                     }
                 }
             }
             // end if add
             // Now check for an update
             if ($options['update_path'] != '/' && strlen($options['update_path'])) {
                 if ($catalog_id = Catalog_local::get_from_path($options['update_path'])) {
                     $songs = Song::get_from_path($options['update_path']);
                     foreach ($songs as $song_id) {
                         Catalog::update_single_item('song', $song_id);
                     }
                 }
             }
             // end if update
             if ($catalog_id <= 0) {
                 AmpError::add('general', T_("This subdirectory is not part of an existing catalog. Update cannot be processed."));
             }
             break;
         case 'gather_media_art':
             if (!$catalogs) {
                 $catalogs = Catalog::get_catalogs();
             }
             // Iterate throught the catalogs and gather as needed
             foreach ($catalogs as $catalog_id) {
                 $catalog = Catalog::create_from_id($catalog_id);
                 if ($catalog !== null) {
                     require AmpConfig::get('prefix') . UI::find_template('show_gather_art.inc.php');
                     flush();
                     $catalog->gather_art();
                 }
             }
             break;
     }
 }
Beispiel #22
0
 /**
  * create_type
  *
  * This creates a new catalog type entry for a catalog
  * It checks to make sure its parameters is not already used before creating
  * the catalog.
  */
 public static function create_type($catalog_id, $data)
 {
     // TODO: This Method should be required / provided by parent
     $uri = $data['uri'];
     if (substr($uri, 0, 7) != 'http://' && substr($uri, 0, 8) != 'https://') {
         AmpError::add('general', T_('Error: Beets selected, but path is not a URL'));
         return false;
     }
     // Make sure this uri isn't already in use by an existing catalog
     $selectSql = 'SELECT `id` FROM `catalog_beets` WHERE `uri` = ?';
     $db_results = Dba::read($selectSql, array($uri));
     if (Dba::num_rows($db_results)) {
         debug_event('catalog', 'Cannot add catalog with duplicate uri ' . $uri, 1);
         AmpError::add('general', sprintf(T_('Error: Catalog with %s already exists'), $uri));
         return false;
     }
     $insertSql = 'INSERT INTO `catalog_beetsremote` (`uri`, `catalog_id`) VALUES (?, ?)';
     Dba::write($insertSql, array($uri, $catalog_id));
     return true;
 }
Beispiel #23
0
 /**
  * update
  * This function is an all encompasing update function that
  * calls the mini ones does all the error checking and all that
  * good stuff
  */
 public function update(array $data)
 {
     if (empty($data['username'])) {
         AmpError::add('username', T_('Error Username Required'));
     }
     if ($data['password1'] != $data['password2'] and !empty($data['password1'])) {
         AmpError::add('password', T_("Error Passwords don't match"));
     }
     if (AmpError::occurred()) {
         return false;
     }
     if (!isset($data['fullname_public'])) {
         $data['fullname_public'] = false;
     }
     foreach ($data as $name => $value) {
         if ($name == 'password1') {
             $name = 'password';
         } else {
             $value = scrub_in($value);
         }
         switch ($name) {
             case 'password':
             case 'access':
             case 'email':
             case 'username':
             case 'fullname':
             case 'fullname_public':
             case 'website':
             case 'state':
             case 'city':
                 if ($this->{$name} != $value) {
                     $function = 'update_' . $name;
                     $this->{$function}($value);
                 }
                 break;
             case 'clear_stats':
                 Stats::clear($this->id);
                 break;
             default:
                 // Rien a faire
                 break;
         }
     }
     return $this->id;
 }
Beispiel #24
0
/**
 * install_create_account
 * this creates your initial account and sets up the preferences for the -1 user and you
 */
function install_create_account($username, $password, $password2)
{
    if (!strlen($username) or !strlen($password)) {
        AmpError::add('general', T_('No Username/Password specified'));
        return false;
    }
    if ($password !== $password2) {
        AmpError::add('general', T_('Passwords do not match'));
        return false;
    }
    if (!Dba::check_database()) {
        AmpError::add('general', sprintf(T_('Database connection failed: %s'), Dba::error()));
        return false;
    }
    if (!Dba::check_database_inserted()) {
        AmpError::add('general', sprintf(T_('Database select failed: %s'), Dba::error()));
        return false;
    }
    $username = Dba::escape($username);
    $password = Dba::escape($password);
    $insert_id = User::create($username, 'Administrator', '', '', $password, '100');
    if (!$insert_id) {
        AmpError::add('general', sprintf(T_('Administrative user creation failed: %s'), Dba::error()));
        return false;
    }
    // Fix the system users preferences
    User::fix_preferences('-1');
    return true;
}
Beispiel #25
0
 /**
  * create
  * This is a static function that takes a key'd array for input
  * and if everything is good creates the object.
  */
 public static function create(array $data)
 {
     // Make sure we've got a name
     if (!strlen($data['name'])) {
         AmpError::add('name', T_('Name Required'));
     }
     $allowed_array = array('https', 'http', 'mms', 'mmsh', 'mmsu', 'mmst', 'rtsp', 'rtmp');
     $elements = explode(":", $data['url']);
     if (!in_array($elements['0'], $allowed_array)) {
         AmpError::add('url', T_('Invalid URL must be http:// or https://'));
     }
     if (!empty($data['site_url'])) {
         $elements = explode(":", $data['site_url']);
         if (!in_array($elements['0'], $allowed_array)) {
             AmpError::add('site_url', T_('Invalid URL must be http:// or https://'));
         }
     }
     // Make sure it's a real catalog
     $catalog = Catalog::create_from_id($data['catalog']);
     if (!$catalog->name) {
         AmpError::add('catalog', T_('Invalid Catalog'));
     }
     if (AmpError::occurred()) {
         return false;
     }
     // If we've made it this far everything must be ok... I hope
     $sql = "INSERT INTO `live_stream` (`name`,`site_url`,`url`,`catalog`,`codec`) " . "VALUES (?, ?, ?, ?, ?)";
     $db_results = Dba::write($sql, array($data['name'], $data['site_url'], $data['url'], $catalog->id, $data['codec']));
     return $db_results;
 }
Beispiel #26
0
 /**
  * update_remote_catalog
  *
  * Pulls the data from a remote catalog and adds any missing songs to the
  * database.
  */
 public function update_remote_catalog($type = 0)
 {
     set_time_limit(0);
     $remote_handle = $this->connect();
     if (!$remote_handle) {
         return false;
     }
     // Get the song count, etc.
     $remote_catalog_info = $remote_handle->info();
     // Tell 'em what we've found, Johnny!
     UI::update_text('', sprintf(T_('%u remote catalog(s) found (%u songs)'), $remote_catalog_info['catalogs'], $remote_catalog_info['songs']));
     // Hardcoded for now
     $step = 500;
     $current = 0;
     $total = $remote_catalog_info['songs'];
     while ($total > $current) {
         $start = $current;
         $current += $step;
         try {
             $songs = $remote_handle->send_command('songs', array('offset' => $start, 'limit' => $step));
         } catch (Exception $e) {
             AmpError::add('general', $e->getMessage());
             AmpError::display('general');
             flush();
         }
         // Iterate over the songs we retrieved and insert them
         foreach ($songs as $data) {
             if ($this->check_remote_song($data['song'])) {
                 debug_event('remote_catalog', 'Skipping existing song ' . $data['song']['url'], 5);
             } else {
                 $data['song']['catalog'] = $this->id;
                 $data['song']['file'] = preg_replace('/ssid=.*?&/', '', $data['song']['url']);
                 if (!Song::insert($data['song'])) {
                     debug_event('remote_catalog', 'Insert failed for ' . $data['song']['self']['id'], 1);
                     AmpError::add('general', T_('Unable to Insert Song - %s'), $data['song']['title']);
                     AmpError::display('general');
                     flush();
                 }
             }
         }
     }
     // end while
     UI::update_text('', T_('Completed updating remote catalog(s).'));
     // Update the last update value
     $this->update_last_update();
     return true;
 }
Beispiel #27
0
 /**
  * gather_folder
  * This returns the art from the folder of the files
  * If a limit is passed or the preferred filename is found the current
  * results set is returned
  * @param int $limit
  * @return array
  */
 public function gather_folder($limit = 5)
 {
     if (!$limit) {
         $limit = 5;
     }
     $results = array();
     $preferred = false;
     // For storing which directories we've already done
     $processed = array();
     /* See if we are looking for a specific filename */
     $preferred_filename = AmpConfig::get('album_art_preferred_filename');
     // Array of valid extensions
     $image_extensions = array('bmp', 'gif', 'jp2', 'jpeg', 'jpg', 'png');
     $dirs = array();
     if ($this->type == 'album') {
         $media = new Album($this->uid);
         $songs = $media->get_songs();
         foreach ($songs as $song_id) {
             $song = new Song($song_id);
             $dirs[] = Core::conv_lc_file(dirname($song->file));
         }
     } else {
         if ($this->type == 'video') {
             $media = new Video($this->uid);
             $dirs[] = Core::conv_lc_file(dirname($media->file));
         }
     }
     foreach ($dirs as $dir) {
         if (isset($processed[$dir])) {
             continue;
         }
         debug_event('folder_art', "Opening {$dir} and checking for Album Art", 3);
         /* Open up the directory */
         $handle = opendir($dir);
         if (!$handle) {
             AmpError::add('general', T_('Error: Unable to open') . ' ' . $dir);
             debug_event('folder_art', "Error: Unable to open {$dir} for album art read", 2);
             continue;
         }
         $processed[$dir] = true;
         // Recurse through this dir and create the files array
         while (false !== ($file = readdir($handle))) {
             $extension = pathinfo($file);
             $extension = $extension['extension'];
             // Make sure it looks like an image file
             if (!in_array($extension, $image_extensions)) {
                 continue;
             }
             $full_filename = $dir . '/' . $file;
             // Make sure it's got something in it
             if (!Core::get_filesize($full_filename)) {
                 debug_event('folder_art', "Empty file, rejecting {$file}", 5);
                 continue;
             }
             // Regularise for mime type
             if ($extension == 'jpg') {
                 $extension = 'jpeg';
             }
             // Take an md5sum so we don't show duplicate
             // files.
             $index = md5($full_filename);
             if ($file == $preferred_filename) {
                 // We found the preferred filename and
                 // so we're done.
                 debug_event('folder_art', "Found preferred image file: {$file}", 5);
                 $preferred[$index] = array('file' => $full_filename, 'mime' => 'image/' . $extension, 'title' => 'Folder');
                 break;
             }
             debug_event('folder_art', "Found image file: {$file}", 5);
             $results[$index] = array('file' => $full_filename, 'mime' => 'image/' . $extension, 'title' => 'Folder');
         }
         // end while reading dir
         closedir($handle);
     }
     // end foreach dirs
     if (is_array($preferred)) {
         // We found our favourite filename somewhere, so we need
         // to dump the other, less sexy ones.
         $results = $preferred;
     }
     debug_event('folder_art', 'Results: ' . json_encode($results), 5);
     if ($limit && count($results) > $limit) {
         $results = array_slice($results, 0, $limit);
     }
     return array_values($results);
 }
Beispiel #28
0
 /**
  * clean_catalog_proc
  *
  * Removes songs that no longer exist.
  */
 public function clean_catalog_proc()
 {
     $dead = 0;
     $client = $this->createClient();
     if ($client != null) {
         $sql = 'SELECT `id`, `file` FROM `song` WHERE `catalog` = ?';
         $db_results = Dba::read($sql, array($this->id));
         while ($row = Dba::fetch_assoc($db_results)) {
             debug_event('dropbox-clean', 'Starting work on ' . $row['file'] . '(' . $row['id'] . ')', 5, 'ampache-catalog');
             $file = $this->get_rel_path($row['file']);
             $metadata = $client->getMetadata($file);
             if ($metadata) {
                 debug_event('dropbox-clean', 'keeping song', 5, 'ampache-catalog');
             } else {
                 debug_event('dropbox-clean', 'removing song', 5, 'ampache-catalog');
                 $dead++;
                 Dba::write('DELETE FROM `song` WHERE `id` = ?', array($row['id']));
             }
         }
     } else {
         AmpError::add('general', T_('API Error: cannot connect to Dropbox.'));
     }
     return $dead;
 }