diff --git a/plugins/libkolab/bin/modcache.sh b/plugins/libkolab/bin/modcache.sh index 869edf09..cac2bf09 100755 --- a/plugins/libkolab/bin/modcache.sh +++ b/plugins/libkolab/bin/modcache.sh @@ -1,234 +1,259 @@ #!/usr/bin/env php * * Copyright (C) 2012-2014, Kolab Systems AG * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ define('INSTALL_PATH', __DIR__ . '/../../../'); ini_set('display_errors', 1); require_once INSTALL_PATH . 'program/include/clisetup.php'; function print_usage() { print "Usage: modcache.sh ACTION [OPTIONS] [USERNAME ARGS ...]\n"; print "Possible actions are: expunge, clear, prewarm\n"; print "-a, --all Clear/expunge all caches\n"; print "-h, --host IMAP host name\n"; print "-u, --user IMAP user name to authenticate\n"; print "-t, --type Object types to clear/expunge cache\n"; print "-l, --limit Limit the number of records to be expunged\n"; } // read arguments $opts = rcube_utils::get_opt(array( 'a' => 'all', 'h' => 'host', 'u' => 'user', 'p' => 'password', 't' => 'type', 'l' => 'limit', 'v' => 'verbose', )); $opts['username'] = !empty($opts[1]) ? $opts[1] : $opts['user']; $action = $opts[0]; $rcmail = rcube::get_instance(rcube::INIT_WITH_DB | rcube::INIT_WITH_PLUGINS); +// Make --host argument optional where the default_host is a simple string +if (empty($opts['host'])) { + $opts['host'] = imap_host(); +} + // connect to database $db = $rcmail->get_dbh(); $db->db_connect('w'); if (!$db->is_connected() || $db->is_error()) die("No DB connection\n"); ini_set('display_errors', 1); // All supported object types $all_types = array('contact','configuration','event','file','journal','note','task'); /* * Script controller */ switch (strtolower($action)) { /* * Clear/expunge all cache records */ case 'expunge': $folder_types = $opts['type'] ? explode(',', $opts['type']) : $all_types; $folder_types_db = array_map(array($db, 'quote'), $folder_types); $expire = strtotime(!empty($opts[2]) ? $opts[2] : 'now - 10 days'); $sql_where = "type IN (" . join(',', $folder_types_db) . ")"; if ($opts['username']) { $sql_where .= ' AND resource LIKE ?'; } $sql_query = "DELETE FROM %s WHERE folder_id IN (SELECT folder_id FROM kolab_folders WHERE $sql_where) AND created <= " . $db->quote(date('Y-m-d 00:00:00', $expire)); if ($opts['limit']) { $sql_query .= ' LIMIT ' . intval($opts['limit']); } foreach ($folder_types as $type) { $table_name = 'kolab_cache_' . $type; $db->query(sprintf($sql_query, $table_name), resource_prefix($opts).'%'); echo $db->affected_rows() . " records deleted from '$table_name'\n"; } $db->query("UPDATE kolab_folders SET ctag='' WHERE $sql_where", resource_prefix($opts).'%'); break; case 'clear': $folder_types = $opts['type'] ? explode(',', $opts['type']) : $all_types; $folder_types_db = array_map(array($db, 'quote'), $folder_types); if ($opts['all']) { $sql_query = "DELETE FROM kolab_folders WHERE 1"; } else if ($opts['username']) { $sql_query = "DELETE FROM kolab_folders WHERE type IN (" . join(',', $folder_types_db) . ") AND resource LIKE ?"; } if ($sql_query) { $db->query($sql_query, resource_prefix($opts).'%'); echo $db->affected_rows() . " records deleted from 'kolab_folders'\n"; } break; /* * Prewarm cache by synchronizing objects for the given user */ case 'prewarm': // make sure libkolab classes are loaded $rcmail->plugins->load_plugin('libkolab'); if (authenticate($opts)) { $folder_types = $opts['type'] ? explode(',', $opts['type']) : $all_types; foreach ($folder_types as $type) { // sync every folder of the given type foreach (kolab_storage::get_folders($type) as $folder) { echo "Synching " . $folder->name . " ($type) ... "; echo $folder->count($type) . "\n"; // also sync distribution lists in contact folders if ($type == 'contact') { echo "Synching " . $folder->name . " (distribution-list) ... "; echo $folder->count('distribution-list') . "\n"; } } } } else die("Authentication failed for " . $opts['user']); break; /** * Update the cache meta columns from the serialized/xml data * (might be run after a schema update) */ case 'update': // make sure libkolab classes are loaded $rcmail->plugins->load_plugin('libkolab'); $folder_types = $opts['type'] ? explode(',', $opts['type']) : $all_types; foreach ($folder_types as $type) { $class = 'kolab_storage_cache_' . $type; $sql_result = $db->query("SELECT folder_id FROM kolab_folders WHERE type=? AND synclock = 0", $type); while ($sql_result && ($sql_arr = $db->fetch_assoc($sql_result))) { $folder = new $class; $folder->select_by_id($sql_arr['folder_id']); echo "Updating " . $sql_arr['folder_id'] . " ($type) "; foreach ($folder->select() as $object) { $object['_formatobj']->to_array(); // load data $folder->save($object['_msguid'], $object, $object['_msguid']); echo "."; } echo "done.\n"; } } break; /* * Unknown action => show usage */ default: print_usage(); exit; } /** * Compose cache resource URI prefix for the given user credentials */ function resource_prefix($opts) { return 'imap://' . str_replace('%', '\\%', urlencode($opts['username'])) . '@' . $opts['host'] . '/'; } /** * Authenticate to the IMAP server with the given user credentials */ function authenticate(&$opts) { global $rcmail; // prompt for password if (empty($opts['password']) && ($opts['username'] || $opts['user'])) { $opts['password'] = prompt_silent("Password: "); } // simulate "login as" feature if ($opts['user'] && $opts['user'] != $opts['username']) $_POST['_loginas'] = $opts['username']; else if (empty($opts['user'])) $opts['user'] = $opts['username']; // let the kolab_auth plugin do its magic $auth = $rcmail->plugins->exec_hook('authenticate', array( 'host' => trim($opts['host']), 'user' => trim($opts['user']), 'pass' => $opts['password'], 'cookiecheck' => false, 'valid' => !empty($opts['user']) && !empty($opts['host']), )); if ($auth['valid']) { $storage = $rcmail->get_storage(); if ($storage->connect($auth['host'], $auth['user'], $auth['pass'], 143, false)) { if ($opts['verbose']) echo "IMAP login succeeded.\n"; if (($user = rcube_user::query($opts['username'], $auth['host'])) && $user->ID) $rcmail->user = $user; } else die("Login to IMAP server failed!\n"); } else { die("Invalid login credentials!\n"); } return $auth['valid']; } +function imap_host() +{ + global $rcmail; + + $default_host = $rcmail->config->get('default_host'); + + if (is_array($default_host)) { + $key = key($default_host); + $imap_host = is_numeric($key) ? $default_host[$key] : $key; + } + else { + $imap_host = $default_host; + } + + // strip protocol prefix + $uri = parse_url($imap_host); + if (!empty($uri['host'])) { + return $uri['host']; + } +} diff --git a/plugins/libkolab/bin/randomcontacts.sh b/plugins/libkolab/bin/randomcontacts.sh index 3fb496d7..dc2bbb52 100755 --- a/plugins/libkolab/bin/randomcontacts.sh +++ b/plugins/libkolab/bin/randomcontacts.sh @@ -1,178 +1,196 @@ #!/usr/bin/env php * * Copyright (C) 2014, Kolab Systems AG * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ define('INSTALL_PATH', __DIR__ . '/../../../'); ini_set('display_errors', 1); require_once INSTALL_PATH . 'program/include/clisetup.php'; function print_usage() { print "Usage: randomcontacts.sh [OPTIONS] USERNAME FOLDER\n"; - print "Create random contact that for then given user in the specified folder.\n"; + print "Create random contact for a given user in a specified folder.\n"; print "-n, --num Number of contacts to be created, defaults to 50\n"; print "-h, --host IMAP host name\n"; print "-p, --password IMAP user password\n"; } // read arguments $opts = rcube_utils::get_opt(array( 'n' => 'num', 'h' => 'host', 'u' => 'user', 'p' => 'pass', 'v' => 'verbose', )); $opts['username'] = !empty($opts[0]) ? $opts[0] : $opts['user']; $opts['folder'] = $opts[1]; $rcmail = rcube::get_instance(rcube::INIT_WITH_DB | rcube::INIT_WITH_PLUGINS); $rcmail->plugins->load_plugins(array('libkolab')); ini_set('display_errors', 1); - if (empty($opts['host'])) { - $opts['host'] = $rcmail->config->get('default_host'); - if (is_array($opts['host'])) // not unique - $opts['host'] = null; + $opts['host'] = imap_host(); } if (empty($opts['username']) || empty($opts['folder']) || empty($opts['host'])) { print_usage(); exit; } // prompt for password if (empty($opts['pass'])) { $opts['pass'] = rcube_utils::prompt_silent("Password: "); } // parse $host URL $a_host = parse_url($opts['host']); if ($a_host['host']) { $host = $a_host['host']; $imap_ssl = (isset($a_host['scheme']) && in_array($a_host['scheme'], array('ssl','imaps','tls'))) ? TRUE : FALSE; $imap_port = isset($a_host['port']) ? $a_host['port'] : ($imap_ssl ? 993 : 143); } else { $host = $opts['host']; $imap_port = 143; } // instantiate IMAP class $IMAP = $rcmail->get_storage(); // try to connect to IMAP server if ($IMAP->connect($host, $opts['username'], $opts['pass'], $imap_port, $imap_ssl)) { print "IMAP login successful.\n"; $user = rcube_user::query($opts['username'], $host); $rcmail->user = $user ?: new rcube_user(null, array('username' => $opts['username'], 'host' => $host)); } else { die("IMAP login failed for user " . $opts['username'] . " @ $host\n"); } // get contacts folder $folder = kolab_storage::get_folder($opts['folder']); if (!$folder || empty($folder->type)) { die("Invalid Address Book " . $opts['folder'] . "\n"); } $format = new kolab_format_contact; $num = $opts['num'] ? intval($opts['num']) : 50; echo "Creating $num contacts in " . $folder->get_resource_uri() . "\n"; for ($i=0; $i < $num; $i++) { // generate random names $contact = array( 'surname' => random_string(rand(1,2)), 'firstname' => random_string(rand(1,2)), 'organization' => random_string(rand(0,2)), 'profession' => random_string(rand(1,2)), 'email' => array(), 'phone' => array(), 'address' => array(), 'notes' => random_string(rand(10,200)), ); // randomly add email addresses $em = rand(1,3); for ($e=0; $e < $em; $e++) { $type = array_rand($format->emailtypes); $contact['email'][] = array( 'address' => strtolower(random_string(1) . '@' . random_string(1) . '.tld'), 'type' => $type, ); } // randomly add phone numbers $ph = rand(1,4); for ($p=0; $p < $ph; $p++) { $type = array_rand($format->phonetypes); $contact['phone'][] = array( 'number' => '+'.rand(2,8).rand(1,9).rand(1,9).rand(0,9).rand(0,9).rand(0,9).rand(0,9).rand(0,9).rand(0,9).rand(0,9).rand(0,9), 'type' => $type, ); } // randomly add addresses $ad = rand(0,2); for ($a=0; $a < $ad; $a++) { $type = array_rand($format->addresstypes); $contact['address'][] = array( 'street' => random_string(rand(1,3)), 'locality' => random_string(rand(1,2)), 'code' => rand(1000, 89999), 'country' => random_string(1), 'type' => $type, ); } $contact['name'] = $contact['firstname'] . ' ' . $contact['surname']; if ($folder->save($contact, 'contact')) { echo "."; } else { echo "x"; break; // abort on error } } echo " done.\n"; function random_string($len) { $words = explode(" ", "The Hough transform is named after Paul Hough who patented the method in 1962. It is a technique which can be used to isolate features of a particular shape within an image. Because it requires that the desired features be specified in some parametric form, the classical Hough transform is most commonly used for the de- tection of regular curves such as lines, circles, ellipses, etc. A generalized Hough transform can be employed in applications where a simple analytic description of a features is not possible. Due to the computational complexity of the generalized Hough algorithm, we restrict the main focus of this discussion to the classical Hough transform. Despite its domain restrictions, the classical Hough transform hereafter referred to without the classical prefix retains many applications, as most manufac- tured parts and many anatomical parts investigated in medical imagery contain feature boundaries which can be described by regular curves. The main advantage of the Hough transform technique is that it is tolerant of gaps in feature boundary descriptions and is relatively unaffected by image noise."); for ($i = 0; $i < $len; $i++) { $str .= $words[rand(0,count($words)-1)] . " "; } return rtrim($str); } + +function imap_host() +{ + global $rcmail; + + $default_host = $rcmail->config->get('default_host'); + + if (is_array($default_host)) { + $key = key($default_host); + $imap_host = is_numeric($key) ? $default_host[$key] : $key; + } + else { + $imap_host = $default_host; + } + + // strip protocol prefix + $uri = parse_url($imap_host); + if (!empty($uri['host'])) { + return $uri['host']; + } +} diff --git a/plugins/libkolab/bin/readcache.sh b/plugins/libkolab/bin/readcache.sh index ddc30e7f..56de7aea 100755 --- a/plugins/libkolab/bin/readcache.sh +++ b/plugins/libkolab/bin/readcache.sh @@ -1,147 +1,159 @@ #!/usr/bin/env php * * Copyright (C) 2014, Kolab Systems AG * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ define('INSTALL_PATH', __DIR__ . '/../../../'); ini_set('display_errors', 1); libxml_use_internal_errors(true); require_once INSTALL_PATH . 'program/include/clisetup.php'; function print_usage() { print "Usage: readcache.sh [OPTIONS] FOLDER\n"; print "-h, --host IMAP host name\n"; print "-l, --limit Limit the number of records to be listed\n"; } // read arguments $opts = rcube_utils::get_opt(array( 'h' => 'host', 'l' => 'limit', 'v' => 'verbose', )); $folder = $opts[0]; $imap_host = $opts['host']; $rcmail = rcube::get_instance(rcube::INIT_WITH_DB | rcube::INIT_WITH_PLUGINS); if (empty($imap_host)) { - $default_host = $rcmail->config->get('default_host'); - if (is_array($default_host)) { - list($k,$v) = each($default_host); - $imap_host = is_numeric($k) ? $v : $k; - } - else { - $imap_host = $default_host; - } - - // strip protocol prefix - $imap_host = preg_replace('!^[a-z]+://!', '', $imap_host); + $imap_host = imap_host(); } if (empty($folder) || empty($imap_host)) { print_usage(); exit; } // connect to database $db = $rcmail->get_dbh(); $db->db_connect('r'); if (!$db->is_connected() || $db->is_error()) die("No DB connection\n"); // resolve folder_id if (!is_numeric($folder)) { if (strpos($folder, '@')) { list($mailbox, $domain) = explode('@', $folder); list($username, $subpath) = explode('/', preg_replace('!^user/!', '', $mailbox), 2); $folder_uri = 'imap://' . urlencode($username.'@'.$domain) . '@' . $imap_host . '/' . $subpath; } else { die("Invalid mailbox identifier! Example: user/john.doe/Calendar@example.org\n"); } print "Resolving folder $folder_uri..."; $sql_result = $db->query('SELECT * FROM `kolab_folders` WHERE `resource`=?', $folder_uri); if ($sql_result && ($folder_data = $db->fetch_assoc($sql_result))) { $folder_id = $folder_data['folder_id']; print $folder_id; } print "\n"; } else { $folder_id = intval($folder); $sql_result = $db->query('SELECT * FROM `kolab_folders` WHERE `folder_id`=?', $folder_id); if ($sql_result) { $folder_data = $db->fetch_assoc($sql_result); } } if (empty($folder_data)) { die("Can't find cache mailbox for '$folder'\n"); } print "Querying cache for folder $folder_id ($folder_data[type])...\n"; $extra_cols = array( 'event' => array('dtstart','dtend'), 'contact' => array('type'), ); $cache_table = $db->table_name('kolab_cache_' . $folder_data['type']); $extra_cols_ = $extra_cols[$folder_data['type']] ?: array(); $sql_arr = $db->fetch_assoc($db->query("SELECT COUNT(*) as cnt FROM `$cache_table` WHERE `folder_id`=?", intval($folder_id))); print "CTag = " . $folder_data['ctag'] . "\n"; print "Lock = " . $folder_data['synclock'] . "\n"; print "Count = " . $sql_arr['cnt'] . "\n"; print "----------------------------------------------------------------------------------\n"; print "\t\t\t\t\t"; print join("\t", array_map(function($c) { return '<' . strtoupper($c) . '>'; }, $extra_cols_)); print "\n----------------------------------------------------------------------------------\n"; $result = $db->limitquery("SELECT * FROM `$cache_table` WHERE `folder_id`=?", 0, $opts['limit'], intval($folder_id)); while ($result && ($sql_arr = $db->fetch_assoc($result))) { print $sql_arr['msguid'] . "\t" . $sql_arr['uid'] . "\t" . $sql_arr['changed']; // try to unserialize data block $object = @unserialize(@base64_decode($sql_arr['data'])); print "\t" . ($object === false ? 'FAIL!' : ($object['uid'] == $sql_arr['uid'] ? 'OK' : '!!!')); // check XML validity $xml = simplexml_load_string($sql_arr['xml']); print "\t" . ($xml === false ? 'FAIL!' : 'OK'); // print extra cols array_walk($extra_cols_, function($c) use ($sql_arr) { print "\t" . $sql_arr[$c]; }); print "\n"; } print "----------------------------------------------------------------------------------\n"; echo "Done.\n"; + + +function imap_host() +{ + global $rcmail; + + $default_host = $rcmail->config->get('default_host'); + + if (is_array($default_host)) { + $key = key($default_host); + $imap_host = is_numeric($key) ? $default_host[$key] : $key; + } + else { + $imap_host = $default_host; + } + + // strip protocol prefix + $uri = parse_url($imap_host); + if (!empty($uri['host'])) { + return $uri['host']; + } +}