code:
#!/usr/bin/env php
<?php
/*
 * StatusNet - a distributed open-source microblogging tool
 * Copyright (C) 2010 StatusNet, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));

$longoptions = array('dry-run', 'start=', 'end=');

$helptext = <<<END_OF_USERROLE_HELP
fixup_deletions.php [options]
Finds notices posted by deleted users and cleans them up.
Stray incompletely deleted items cause various fun problems!

     --dry-run  look but don't touch
     --start=N  start looking at profile_id N instead of 1
     --end=N    end looking at profile_id N instead of the max

END_OF_USERROLE_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

/**
 * Find the highest profile_id currently listed in the notice table;
 * this field is indexed and should return very quickly.
 *
 * We check notice.profile_id rather than profile.id because we're
 * looking for notices left behind after deletion; if the most recent
 * accounts were deleted, we wouldn't have them from profile.
 *
 * @return int
 * @access private
 */
function get_max_profile_id()
{
    $query = 'SELECT MAX(profile_id) AS id FROM notice';

    $profile = new Profile();
    $profile->query($query);

    if ($profile->fetch()) {
        return intval($profile->id);
    } else {
        die("Something went awry; could not look up max used profile_id.");
    }
}

/**
 * Check for profiles in the given id range that are missing, presumed deleted.
 *
 * @param int $start beginning profile.id, inclusive
 * @param int $end final profile.id, inclusive
 * @return array of integer profile.ids
 * @access private
 */
function get_missing_profiles($start, $end)
{
    $query = sprintf("SELECT id FROM profile WHERE id BETWEEN %d AND %d",
                     $start, $end);

    $profile = new Profile();
    $profile->query($query);

    $all = range($start, $end);
    $known = array();
    while ($row = $profile->fetch()) {
        $known[] = intval($profile->id);
    }
    unset($profile);

    $missing = array_diff($all, $known);
    return $missing;
}

/**
 * Look for stray notices from this profile and, if present, kill them.
 *
 * @param int $profile_id
 * @param bool $dry if true, we won't delete anything
 */
function cleanup_missing_profile($profile_id, $dry)
{
    $notice = new Notice();
    $notice->profile_id = $profile_id;
    $notice->find();
    if ($notice->N == 0) {
        return;
    }

    $s = ($notice->N == 1) ? '' : 's';
    print "Deleted profile $profile_id has $notice->N stray notice$s:\n";

    while ($notice->fetch()) {
        print "  notice $notice->id";
        if ($dry) {
            print " (skipped; dry run)\n";
        } else {
            $victim = clone($notice);
            try {
                $victim->delete();
                print " (deleted)\n";
            } catch (Exception $e) {
                print " FAILED: ";
                print $e->getMessage();
                print "\n";
            }
        }
    }
}

$dry = have_option('dry-run');

$max_profile_id = get_max_profile_id();
$chunk = 1000;

if (have_option('start')) {
    $begin = intval(get_option_value('start'));
} else {
    $begin = 1;
}
if (have_option('end')) {
    $final = min($max_profile_id, intval(get_option_value('end')));
} else {
    $final = $max_profile_id;
}

if ($begin < 1) {
    die("Silly human, you can't begin before profile number 1!\n");
}
if ($final < $begin) {
    die("Silly human, you can't end at $final if it's before $begin!\n");
}

// Identify missing profiles...
for ($start = $begin; $start <= $final; $start += $chunk) {
    $end = min($start + $chunk - 1, $final);

    print "Checking for missing profiles between id $start and $end";
    if ($dry) {
        print " (dry run)";
    }
    print "...\n";
    $missing = get_missing_profiles($start, $end);

    foreach ($missing as $profile_id) {
        cleanup_missing_profile($profile_id, $dry);
    }
}

echo "done.\n";


code:
#!/usr/bin/env php
<?php
/*
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2008, 2009, StatusNet, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

// Abort if called from a web server
if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
    print "This script must be run from the command line\n";
    exit();
}

define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
define('GNUSOCIAL', true);
define('STATUSNET', true);  // compatibility

require_once(INSTALLDIR . '/lib/common.php');

common_log(LOG_INFO, 'Starting to do old notices.');

$notice = new Notice();
$cnt = $notice->find();

while ($notice->fetch()) {
    common_log(LOG_INFO, 'Getting tags for notice #' . $notice->id);
    $notice->saveTags();
    $original = clone($notice);
    $notice->rendered = common_render_content($notice->content,
                                              $notice->getProfile(),
                                              $notice->hasParent() ? $notice->getParent() : null);
    $result = $notice->update($original);
    if (!$result) {
        common_log_db_error($notice, 'UPDATE', __FILE__);
    }
}

repo_name: andremichelle/gnu

license: mit


code:
#!/usr/bin/env php
<?php
/*
 * StatusNet - a distributed open-source microblogging tool
 * Copyright (C) 2010, StatusNet, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));

$helptext = <<<END_OF_FLUSHROUTER_HELP
flushrouter.php -s<sitename>
Flush the url router from cache.

END_OF_FLUSHROUTER_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

$cache = Cache::instance();
$cache->delete(Router::cacheKey());

print "OK.\n";


code:
#!/usr/bin/env php
<?php
/*
 * StatusNet - a distributed open-source microblogging tool
 * Copyright (C) 2008, 2009, StatusNet, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));

$shortoptions = 'd';
$longoptions = array('delete');

$helptext = <<<END_OF_FLUSHSITE_HELP
flushsite.php -s<sitename>
Flush the site with the given name from memcached.

END_OF_FLUSHSITE_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

$nickname = common_config('site', 'nickname');

$sn = Status_network::memGet('nickname', $nickname);

if (empty($sn)) {
    print "No such site.\n";
    exit(-1);
}

print "Flushing cache for {$nickname}...";
$sn->decache();
print "OK.\n";


code:
#!/usr/bin/env php
<?php
/*
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2008, 2009, StatusNet, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));

$helptext = <<<ENDOFHELP
getpiddir.php - print out the currently configured PID directory

ENDOFHELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

echo common_config('daemon', 'piddir');


code:
#!/usr/bin/env php
<?php
/*
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2008, 2009, StatusNet, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

/**
 * Utility script to get a list of daemons that should run, based on the
 * current configuration. This is used by startdaemons.sh to determine what
 * it should and shouldn't start up. The output is a list of space-separated
 * daemon names.
 */

define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));

$helptext = <<<ENDOFHELP
getvaliddaemons.php - print out a list of valid daemons that should be started
by the startdaemons script

ENDOFHELP;

// No unnecessary error reporting to avoid invalid daemon names
error_reporting(E_ALL & ~E_STRICT & ~E_NOTICE);

require_once INSTALLDIR.'/scripts/commandline.inc';

$daemons = array();

if (common_config('queue', 'daemon')) {
    $daemons[] = INSTALLDIR.'/scripts/queuedaemon.php';
}

if (Event::handle('GetValidDaemons', array(&$daemons))) {
    foreach ($daemons as $daemon) {
        print $daemon . ' ';
    }
    print "\n";
}


code:
#!/usr/bin/env php
<?php
/*
 * StatusNet - a distributed open-source microblogging tool
 * Copyright (C) 2011, StatusNet, Inc.
 *
 * Script to print out current version of the software
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));

$helptext = <<<END_OF_HELP
gnusocialversion.php [options]
prints out the current version of the software

END_OF_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

print GNUSOCIAL_VERSION."\n";


code:
#!/usr/bin/env php
<?php
/*
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2008, 2009, StatusNet, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));

$helptext = <<<END_OF_QUEUE_HELP
USAGE: handlequeued.php <queue> <notice id>
Run a single queued notice through background processing
as if it were being run through the queue.

END_OF_QUEUE_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

if (count($args) != 2) {
    show_help();
}

$queue = trim($args[0]);
$noticeId = intval($args[1]);

$qm = QueueManager::get();
try {
    $handler = $qm->getHandler($queue);
    $notice = Notice::getByID($noticeId);
    $result = $handler->handle($notice);
} catch (NoQueueHandlerException $e) {
    print "No handler for queue '$queue'.\n";
    exit(1);
} catch (NoResultException $e) {
    print "{$e->getMessage()}\n";
    exit(1);
} catch (Exception $e) {
    print "Exception thrown while handling: {$e->getMessage()}\n";
    exit(1);
}
if (!$result) {
    print "Failed to handle notice id $noticeId on queue '$queue'.\n";
    exit(1);
}


code:
#!/usr/bin/env php
<?php
/*
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2008, 2009, StatusNet, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));

$shortoptions = 'fi::a';
$longoptions = array('id::', 'foreground', 'all');

$helptext = <<<END_OF_IM_HELP
Daemon script for receiving new notices from IM users.

    -i --id           Identity (default none)
    -a --all          Handle XMPP for all local sites
                      (requires Stomp queue handler, status_network setup)
    -f --foreground   Stay in the foreground (default background)

END_OF_IM_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

class ImDaemon extends SpawningDaemon
{
    protected $allsites = false;

    function __construct($id=null, $daemonize=true, $threads=1, $allsites=false)
    {
        if ($threads != 1) {
            // This should never happen. :)
            throw new Exception("IMDaemon can must run single-threaded");
        }
        parent::__construct($id, $daemonize, $threads);
        $this->allsites = $allsites;
    }

    function runThread()
    {
        common_log(LOG_INFO, 'Waiting to listen to IM connections and queues');

        $master = new ImMaster($this->get_id(), $this->processManager());
        $master->init($this->allsites);
        $master->service();

        common_log(LOG_INFO, 'terminating normally');

        return $master->respawn ? self::EXIT_RESTART : self::EXIT_SHUTDOWN;
    }

}

class ImMaster extends IoMaster
{
    protected $processManager;

    function __construct($id, $processManager)
    {
        parent::__construct($id);
        $this->processManager = $processManager;
    }

    /**
     * Initialize IoManagers for the currently configured site
     * which are appropriate to this instance.
     */
    function initManagers()
    {
        $classes = array();
        if (Event::handle('StartImDaemonIoManagers', array(&$classes))) {
            $qm = QueueManager::get();
            $qm->setActiveGroup('im');
            $classes[] = $qm;
            $classes[] = $this->processManager;
        }
        Event::handle('EndImDaemonIoManagers', array(&$classes));
        foreach ($classes as $class) {
            $this->instantiate($class);
        }
    }
}

if (have_option('i', 'id')) {
    $id = get_option_value('i', 'id');
} else if (count($args) > 0) {
    $id = $args[0];
} else {
    $id = null;
}

$foreground = have_option('f', 'foreground');
$all = have_option('a') || have_option('--all');

$daemon = new ImDaemon($id, !$foreground, 1, $all);

$daemon->runOnce();


code:
#!/usr/bin/env php
<?php
/*
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2010 StatusNet, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));

$shortoptions = 'i:n:f:';
$longoptions = array('id=', 'nickname=', 'file=');

$helptext = <<<END_OF_IMPORTTWITTERATOM_HELP
importtwitteratom.php [options]
import an Atom feed from Twitter as notices by a user

  -i --id       ID of user to update
  -n --nickname nickname of the user to update
  -f --file     file to import (Atom-only for now)

END_OF_IMPORTTWITTERATOM_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

function getAtomFeedDocument()
{
    $filename = get_option_value('f', 'file');

    if (empty($filename)) {
        show_help();
        exit(1);
    }

    if (!file_exists($filename)) {
        throw new Exception("No such file '$filename'.");
    }

    if (!is_file($filename)) {
        throw new Exception("Not a regular file: '$filename'.");
    }

    if (!is_readable($filename)) {
        throw new Exception("File '$filename' not readable.");
    }

    $xml = file_get_contents($filename);

    $dom = DOMDocument::loadXML($xml);

    if ($dom->documentElement->namespaceURI != Activity::ATOM ||
        $dom->documentElement->localName != 'feed') {
        throw new Exception("'$filename' is not an Atom feed.");
    }

    return $dom;
}

function importActivityStream($user, $doc)
{
    $feed = $doc->documentElement;

    $entries = $feed->getElementsByTagNameNS(Activity::ATOM, 'entry');

    for ($i = $entries->length - 1; $i >= 0; $i--) {
        $entry = $entries->item($i);
        $activity = new Activity($entry, $feed);
        $object = $activity->objects[0];
        if (!have_option('q', 'quiet')) {
            print $activity->content . "\n";
        }
        $html = common_purify(getTweetHtml($object->link));

        $content = html_entity_decode(strip_tags($html), ENT_QUOTES, 'UTF-8');

        $notice = Notice::saveNew($user->id,
                                  $content,
                                  'importtwitter',
                                  array('uri' => $object->id,
                                        'url' => $object->link,
                                        'rendered' => $html,
                                        'created' => common_sql_date($activity->time),
                                        'replies' => array(),
                                        'groups' => array()));
    }
}

function getTweetHtml($url)
{
    try {
        $client = new HTTPClient();
        $response = $client->get($url);
    } catch (Exception $e) {
        print "ERROR: HTTP response " . $e->getMessage() . "\n";
        return false;
    }

    if (!$response->isOk()) {
        print "ERROR: HTTP response " . $response->getCode() . "\n";
        return false;
    }

    $body = $response->getBody();

    return tweetHtmlFromBody($body);
}

function tweetHtmlFromBody($body)
{
    $doc = DOMDocument::loadHTML($body);
    $xpath = new DOMXPath($doc);

    $spans = $xpath->query('//span[@class="entry-content"]');

    if ($spans->length == 0) {
        print "ERROR: No content in tweet page.\n";
        return '';
    }

    $span = $spans->item(0);

    $children = $span->childNodes;

    $text = '';

    for ($i = 0; $i < $children->length; $i++) {
        $child = $children->item($i);
        if ($child instanceof DOMElement &&
            $child->tagName == 'a' &&
            !preg_match('#^https?://#', $child->getAttribute('href'))) {
            $child->setAttribute('href', 'http://twitter.com' . $child->getAttribute('href'));
        }
        $text .= $doc->saveXML($child);
    }

    return $text;
}

try {

    $doc = getAtomFeedDocument();
    $user = getUser();

    importActivityStream($user, $doc);

} catch (Exception $e) {
    print $e->getMessage()."\n";
    exit(1);
}


code:
#!/usr/bin/env php
<?php
/**
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2010, StatusNet, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 *
 * @category Installation
 * @package  Installation
 *
 * @author   Brion Vibber <brion@status.net>
 * @author   Mikael Nordfeldth <mmn@hethane.se>
 * @license  GNU Affero General Public License http://www.gnu.org/licenses/
 * @version  1.1.x
 * @link     http://status.net
 */

if (php_sapi_name() !== 'cli') {
    exit(1);
}

define('INSTALLDIR', dirname(dirname(__FILE__)));
set_include_path(get_include_path() . PATH_SEPARATOR . INSTALLDIR . '/extlib');

require_once INSTALLDIR . '/lib/installer.php';
require_once 'Console/Getopt.php';

class CliInstaller extends Installer
{
    public $verbose = true;

    /**
     * Go for it!
     * @return boolean success
     */
    function main()
    {
        if ($this->prepare()) {
        if (!$this->checkPrereqs()) {
            return false;
        }
            return $this->handle();
       } else {
            $this->showHelp();
            return false;
        }
    }

    /**
     * Get our input parameters...
     * @return boolean success
     */
    function prepare()
    {
        $shortoptions = 'qvh';
        $longoptions = array('quiet', 'verbose', 'help', 'skip-config');
        $map = array(
            '-s'         => 'server',
            '--server'   => 'server',
            '-p'         => 'path',
            '--path'     => 'path',
            '--sitename' => 'sitename',
            '--fancy'    => 'fancy',
            '--ssl'      => 'ssl',

            '--dbtype'   => 'dbtype',
            '--host'     => 'host',
            '--database' => 'database',
            '--username' => 'username',
            '--password' => 'password',

            '--admin-nick' => 'adminNick',
            '--admin-pass' => 'adminPass',
            '--admin-email' => 'adminEmail',

            '--site-profile' => 'siteProfile'
        );
        foreach ($map as $arg => $target) {
            if (substr($arg, 0, 2) == '--') {
                $longoptions[] = substr($arg, 2) . '=';
            } else {
                $shortoptions .= substr($arg, 1) . ':';
            }
        }

        $parser = new Console_Getopt();
        $result = $parser->getopt($_SERVER['argv'], $shortoptions, $longoptions);
        if (PEAR::isError($result)) {
            $this->warning($result->getMessage());
            return false;
        }
        list($options, $args) = $result;

        // defaults
        $this->dbtype = 'mysql';
        $this->verbose = true;
        // ssl is defaulted in lib/installer.php

        foreach ($options as $option) {
            $arg = $option[0];
            if (isset($map[$arg])) {
                $var = $map[$arg];
                $this->$var = $option[1];
                if ($arg == '--fancy') {
                    $this->$var = ($option[1] != 'false') && ($option[1] != 'no');
                }
            } else if ($arg == '--skip-config') {
                $this->skipConfig = true;
            } else if ($arg == 'q' || $arg == '--quiet') {
                $this->verbose = false;
            } else if ($arg == 'v' || $arg == '--verbose') {
                $this->verbose = true;
            } else if ($arg == 'h' || $arg == '--help') {
                // will go back to show help
                return false;
            }
        }

        $fail = false;
        if (empty($this->server)) {
            $this->updateStatus("You must specify a web server for the site.", true);
            // path is optional though
            $fail = true;
        }

        if (!$this->validateDb()) {
            $fail = true;
        }

        if (!$this->validateAdmin()) {
            $fail = true;
        }

        return !$fail;
    }

    function handle()
    {
        return $this->doInstall();
    }

    function showHelp()
    {
        echo <<<END_HELP
install_cli.php - StatusNet command-line installer

    -s --server=<name>   Use <name> as server name (required)
    -p --path=<path>     Use <path> as path name
       --sitename        User-friendly site name (required)
       --fancy           Whether to use fancy URLs (default no)
       --ssl             Server SSL enabled (default never),
                         [never | always]

       --dbtype          'mysql' (default) or 'pgsql'
       --host            Database hostname (required)
       --database        Database/schema name (required)
       --username        Database username (required)
       --password        Database password (required)

       --admin-nick      Administrator nickname (required)
       --admin-pass      Initial password for admin user (required)
       --admin-email     Initial email address for admin user
       --admin-updates   'yes' (default) or 'no', whether to subscribe
                         admin to update@status.net (default yes)

       --site-profile    site profile ['public', 'private' (default), 'community', 'singleuser']

       --skip-config     Don't write a config.php -- use with caution,
                         requires a global configuration file.

      General options:

    -q --quiet           Quiet (little output)
    -v --verbose         Verbose (lots of output)
    -h --help            Show this message and quit.

END_HELP;
    }

    function warning($message, $submessage='')
    {
        print $this->html2text($message) . "\n";
        if ($submessage != '') {
            print "  " . $this->html2text($submessage) . "\n";
        }
        print "\n";
    }

    function updateStatus($status, $error=false)
    {
        if ($this->verbose || $error) {
            if ($error) {
                print "ERROR: ";
            }
            print $this->html2text($status);
            print "\n";
        }
    }

    private function html2text($html)
    {
        // break out any links for text legibility
        $breakout = preg_replace('/<a[^>+]\bhref="(.*)"[^>]*>(.*)<\/a>/',
                                 '\2 <\1>',
                                 $html);
        return html_entity_decode(strip_tags($breakout), ENT_QUOTES, 'UTF-8');
    }
}

$installer = new CliInstaller();
$ok = $installer->main();
exit($ok ? 0 : 1);


code:
<?php
/*
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2012 StatusNet, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));

$shortoptions = 'i:n:g:G:';
$longoptions = array('id=', 'nickname=', 'group=', 'group-id=');

$helptext = <<<END_OF_HELP
joingroup.php [options]

Adds a local user to a local group.

  -i --id       ID of user to add
  -n --nickname nickname of the user to add
  -g --group    nickname or alias of group
  -G --group-id ID of group

END_OF_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

try {
    $user = getUser();
    $lgroup = null;
    if (have_option('G', 'group-id')) {
        $gid = get_option_value('G', 'group-id');
        $lgroup = Local_group::getKV('group_id', $gid);
    } else if (have_option('g', 'group')) {
        $gnick = get_option_value('g', 'group');
        $lgroup = Local_group::getKV('nickname', $gnick);
    }
    if (!$lgroup instanceof Local_group) {
        throw new Exception("No such local group: $gnick");
    }
    $group = User_group::getKV('id', $lgroup->group_id);
    $user->joinGroup($group);
    print "OK\n";
} catch (Exception $e) {
    print $e->getMessage()."\n";
    exit(1);
}


code:
<?php
/*
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2012 StatusNet, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));

$shortoptions = 'i:n:g:G:';
$longoptions = array('id=', 'nickname=', 'group=', 'group-id=');

$helptext = <<<END_OF_HELP
leavegroup.php [options]

Removes a local user from a local group.

  -i --id       ID of user to remove
  -n --nickname nickname of the user to remove
  -g --group    nickname or alias of group
  -G --group-id ID of group

END_OF_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

try {
    $user = getUser();
    $lgroup = null;
    if (have_option('G', 'group-id')) {
        $gid = get_option_value('G', 'group-id');
        $lgroup = Local_group::getKV('group_id', $gid);
    } else if (have_option('g', 'group')) {
        $gnick = get_option_value('g', 'group');
        $lgroup = Local_group::getKV('nickname', $gnick);
    }
    if (!$lgroup instanceof Local_group) {
        throw new Exception("No such local group: $gnick");
    }
    $group = User_group::getKV('id', $lgroup->group_id);
    $user->leaveGroup($group);
    print "OK\n";
} catch (Exception $e) {
    print $e->getMessage()."\n";
    exit(1);
}


code:
#!/usr/bin/env php
<?php
/*
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2008, 2009, StatusNet, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));

$helptext = <<<END_OF_HELP
Script for converting mail messages into notices. Takes message body
as STDIN.

END_OF_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';
require_once INSTALLDIR.'/lib/mailhandler.php';

if (common_config('emailpost', 'enabled')) {
    $mh = new MailHandler();
    $mh->handle_message(file_get_contents('php://stdin'));
}


code:
#!/usr/bin/env php
<?php
/*
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2010, StatusNet, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

// Abort if called from a web server

define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));

require_once INSTALLDIR.'/scripts/commandline.inc';

$base = INSTALLDIR;
$encBase = escapeshellarg($base);

$ver = GNUSOCIAL_VERSION;

// @fixme hack
if (preg_match('/^(\d+)\.(\d+)\.(\d+)/', $ver, $matches)) {
    list(, $a, $b, $c) = $matches;
    if ($c > '0') {
        $cprime = $c - 1;
        $prev = "$a.$b.$cprime";
    } else {
        die("This is a .0 release; you need to provide a thingy.\n");
    }
}

$tag = $ver;
$prefix = "statusnet-$tag";
$target = "$prefix.tar.gz";

$cmd = <<<END
(cd $encBase && git archive --prefix=$prefix/ $tag | gzip > /tmp/$target) && \
(cd /tmp && tar zxf $target && cd $prefix && make) && \
(cd $encBase && git log --oneline {$prev}..{$tag} > /tmp/$prefix/Changelog) && \
(cd /tmp && tar zcf $target $prefix) && \
(cd /tmp && rm -rf $prefix) && \
(mv /tmp/$target .)
END;

echo $cmd;
echo "\n";


code:
#!/usr/bin/env php
<?php
/*
 * StatusNet - a distributed open-source microblogging tool
 * Copyright (C) 2008, 2009, StatusNet, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));

$shortoptions = 'g:n:';
$longoptions = array('nickname=', 'group=');

$helptext = <<<END_OF_MAKEGROUPADMIN_HELP
makegroupadmin.php [options]
makes a user the admin of a group

  -g --group    group to add an admin to
  -n --nickname nickname of the new admin

END_OF_MAKEGROUPADMIN_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

$nickname = get_option_value('n', 'nickname');
$groupname = get_option_value('g', 'group');

if (empty($nickname) || empty($groupname)) {
    print "Must provide a nickname and group.\n";
    exit(1);
}

try {

    $user = User::getKV('nickname', $nickname);

    if (empty($user)) {
        throw new Exception("No user named '$nickname'.");
    }

    $group = User_group::getKV('nickname', $groupname);

    if (empty($group)) {
        throw new Exception("No group named '$groupname'.");
    }

    $member = Group_member::pkeyGet(array('group_id' => $group->id,
                                          'profile_id' => $user->id));

    if (empty($member)) {
        $member = new Group_member();

        $member->group_id   = $group->id;
        $member->profile_id = $user->id;
        $member->created    = common_sql_now();

        if (!$member->insert()) {
            throw new Exception("Can't add '$nickname' to '$groupname'.");
        }
    }

    if ($member->is_admin) {
        throw new Exception("'$nickname' is already an admin of '$groupname'.");
    }

    $orig = clone($member);

    $member->is_admin = 1;

    if (!$member->update($orig)) {
        throw new Exception("Can't make '$nickname' admin of '$groupname'.");
    }

} catch (Exception $e) {
    print $e->getMessage() . "\n";
    exit(1);
}


code:
#!/bin/bash

# live fast! die young!

set -e

# move_status_network.sh nickname newserver

export nickname="$1"
export newdbhost="$2"

source /etc/statusnet/setup.cfg

function set_maintenance_mode()
{
    local nickname=$1;

    php $PHPBASE/scripts/settag.php $nickname maintenancemode;
}

function get_current_db_info()
{
    local nickname=$1;

    #FIXME I couldn't make this work better

    export dbhost=`mysql -NB -h $SITEDBHOSTNAME -u $ADMIN --password=$ADMINPASS -e "SELECT dbhost FROM status_network WHERE nickname = '$nickname'" $SITEDB`
    export dbuser=`mysql -NB -h $SITEDBHOSTNAME -u $ADMIN --password=$ADMINPASS -e "SELECT dbuser FROM status_network WHERE nickname = '$nickname'" $SITEDB`
    export dbpass=`mysql -NB -h $SITEDBHOSTNAME -u $ADMIN --password=$ADMINPASS -e "SELECT dbpass FROM status_network WHERE nickname = '$nickname'" $SITEDB`
    export dbname=`mysql -NB -h $SITEDBHOSTNAME -u $ADMIN --password=$ADMINPASS -e "SELECT dbname FROM status_network WHERE nickname = '$nickname'" $SITEDB`
}

function create_empty_db()
{
    local newdbhost=$1;
    local dbuser=$2;
    local dbpass=$3;
    local dbname=$4;

    mysqladmin -h $newdbhost -u $ADMIN --password=$ADMINPASS create $dbname;

    mysql -h $newdbhost -u $ADMIN --password=$ADMINPASS -e "GRANT ALL ON $dbname.* TO '$dbuser'@'localhost' IDENTIFIED BY '$dbpass';" $dbname;
    mysql -h $newdbhost -u $ADMIN --password=$ADMINPASS -e "GRANT ALL ON $dbname.* TO '$dbuser'@'%' IDENTIFIED BY '$dbpass';" $dbname;
}

function transfer_data()
{
    local dbhost=$1;
    local newdbhost=$2;
    local dbuser=$3;
    local dbpass=$4;
    local dbname=$5;
    local dumpfile=`mktemp`;

    mysqldump -h $dbhost -u $ADMIN --password=$ADMINPASS $dbname > $dumpfile;
    mysql -h $newdbhost -u $ADMIN --password=$ADMINPASS $dbname < $dumpfile;
    rm $dumpfile;
}

function update_routing_table()
{
    local nickname=$1;
    local newdbhost=$2;

    mysql -h $SITEDBHOSTNAME -u $ADMIN --password=$ADMINPASS -e "UPDATE status_network set dbhost = '$newdbhost' where nickname = '$nickname'" $SITEDB
}

function flush_site()
{
    local nickname=$1;

    php $PHPBASE/scripts/flushsite.php -s$nickname.$WILDCARD
}

function unset_maintenance_mode()
{
    local nickname=$1;

    php $PHPBASE/scripts/settag.php -d $nickname maintenancemode;
}

echo -n Setting maintenance mode on $nickname...
set_maintenance_mode $nickname
echo DONE.
echo -n Getting current database info...
get_current_db_info $nickname
echo DONE.
echo -n Creating empty $dbname database on server $newdbhost...
create_empty_db $newdbhost $dbuser $dbpass $dbname
echo DONE
echo -n Copying $dbname database from $dbhost to $newdbhost...
transfer_data $dbhost $newdbhost $dbuser $dbpass $dbname
echo DONE
echo -n Updating the routing table for $nickname to use $dbname on $newdbhost...
update_routing_table $nickname $newdbhost
echo DONE
echo -n Flushing $nickname site from cache...
flush_site $nickname
echo DONE
echo -n Turning off maintenance mode on $nickname...
unset_maintenance_mode $nickname
echo DONE.


code:
<?php
/**
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2010 StatusNet, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));

$shortoptions = 'i:n:r:w:y';
$longoptions = array('id=', 'nickname=', 'remote=', 'password=');

$helptext = <<<END_OF_MOVEUSER_HELP
moveuser.php [options]
Move a local user to a remote account.

  -i --id       ID of user to move
  -n --nickname nickname of the user to move
  -r --remote   Full ID of remote users
  -w --password Password of remote user
  -y --yes      do not wait for confirmation

Remote user identity must be a Webfinger (nickname@example.com) or
an HTTP or HTTPS URL (http://example.com/social/site/user/nickname).

END_OF_MOVEUSER_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

try {

    $user = getUser();

    $remote = get_option_value('r', 'remote');

    if (empty($remote)) {
        show_help();
        exit(1);
    }

    $password = get_option_value('w', 'password');

    if (!have_option('y', 'yes')) {
        print "WARNING: EXPERIMENTAL FEATURE! Moving accounts will delete data from the source site.\n";
        print "\n";
        print "About to PERMANENTLY move user '{$user->nickname}' to $remote. Are you sure? [y/N] ";
        $response = fgets(STDIN);
        if (strtolower(trim($response)) != 'y') {
            print "Aborting.\n";
            exit(0);
        }
    }

    $qm = QueueManager::get();

    $qm->enqueue(array($user, $remote, $password), 'acctmove');

} catch (Exception $e) {
    print $e->getMessage()."\n";
    exit(1);
}


code:
#!/usr/bin/env php
<?php
/*
 * StatusNet - a distributed open-source microblogging tool
 * Copyright (C) 2008, 2009, StatusNet, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));

$shortoptions = 'i::yv';
$longoptions = array('id=', 'yes', 'verbose');

$helptext = <<<END_OF_HELP
nukefile.php [options]
deletes a file and related notices from the database

  -i --id       ID of the file
  -v --verbose  Be verbose (print the contents of the notices deleted).

END_OF_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

if (have_option('i', 'id')) {
    $id = get_option_value('i', 'id');
    $file = File::getKV('id', $id);
    if (!$file instanceof File) {
        print "Can't find file with ID $id\n";
        exit(1);
    }
} else {
    print "You must provide a file ID.\n";
    exit(1);
}

$verbose = have_option('v', 'verbose');

if (!have_option('y', 'yes')) {
    try {
        $filename = $file->getFilename();
    } catch (Exception $e) {
        $filename = '(remote file or no filename)';
    }
    print "About to PERMANENTLY delete file ($filename) with id=={$file->id}) AND its related notices. Are you sure? [y/N] ";
    $response = fgets(STDIN);
    if (strtolower(trim($response)) != 'y') {
        print "Aborting.\n";
        exit(0);
    }
}

print "Finding notices...\n";
try {
    $ids = File_to_post::getNoticeIDsByFile($file);
    $notice = Notice::multiGet('id', $ids);
    while ($notice->fetch()) {
        print "Deleting notice {$notice->id}".($verbose ? ": $notice->content\n" : "\n");
        $notice->delete();
    }
} catch (NoResultException $e) {
    print "No notices found with this File attached.\n";
}
print "Deleting File object together with possibly locally stored copy.\n";
$file->delete();
print "DONE.\n";


code:
#!/usr/bin/env php
<?php
/*
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2010, StatusNet, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

/**
 * Sends control signals to running queue daemons.
 *
 * @author Brion Vibber <brion@status.net>
 * @package QueueHandler
 */

define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));

$shortoptions = 'ur';
$longoptions = array('update', 'restart', 'stop');

$helptext = <<<END_OF_QUEUECTL_HELP
Send broadcast events to control any running queue handlers.
(Currently for Stomp queues only.)

Events relating to current site (as selected with -s etc)
    -u --update       Announce new site or updated configuration. Running
                      daemons will start subscribing to any new queues needed
                      for this site.

Global events:
    -r --restart      Graceful restart of all threads
       --stop         Graceful shutdown of all threads

END_OF_QUEUECTL_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

function doSendControl($message, $event, $param='')
{
    print $message;
    $qm = QueueManager::get();
    if ($qm->sendControlSignal($event, $param)) {
        print " sent.\n";
    } else {
        print " FAILED.\n";
    }
}

$actions = 0;

if (have_option('u') || have_option('--update')) {
    $nickname = common_config('site', 'nickname');
    doSendControl("Sending site update signal to queue daemons for $nickname",
                  "update", $nickname);
    $actions++;
}

if (have_option('r') || have_option('--restart')) {
    doSendControl("Sending graceful restart signal to queue daemons...",
                  "restart");
    $actions++;
}

if (have_option('--stop')) {
    doSendControl("Sending graceful shutdown signal to queue daemons...",
                  "shutdown");
    $actions++;
}

if (!$actions) {
    show_help();
}


code:
#!/usr/bin/env php
<?php
/*
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2008, 2009, StatusNet, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));

$shortoptions = 'fi:at:';
$longoptions = array('id=', 'foreground', 'all', 'threads=');

/**
 * Attempts to get a count of the processors available on the current system
 * to fan out multiple threads.
 *
 * Recognizes Linux and Mac OS X; others will return default of 1.
 *
 * @fixme move this to SpawningDaemon, but to get the default val for help
 *        text we seem to need it before loading infrastructure
 * @return intval
 */
function getProcessorCount()
{
    $cpus = 0;
    switch (PHP_OS) {
    case 'Linux':
        $cpuinfo = file('/proc/cpuinfo');
        foreach (file('/proc/cpuinfo') as $line) {
            if (preg_match('/^processor\s+:\s+(\d+)\s?$/', $line)) {
                $cpus++;
            }
        }
        break;
    case 'Darwin':
        $cpus = intval(shell_exec("/usr/sbin/sysctl -n hw.ncpu 2>/dev/null"));
        break;
    }
    if ($cpus) {
        return $cpus;
    }
    return 1;
}

$threads = getProcessorCount();
$helptext = <<<END_OF_QUEUE_HELP
Daemon script for running queued items.

    -i --id           Identity (default none)
    -f --foreground   Stay in the foreground (default background)
    -a --all          Handle queues for all local sites
                      (requires Stomp queue handler, status_network setup)
    -t --threads=<n>  Spawn <n> processing threads (default $threads)

END_OF_QUEUE_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

require_once(INSTALLDIR.'/lib/daemon.php');
require_once(INSTALLDIR.'/classes/Queue_item.php');
require_once(INSTALLDIR.'/classes/Notice.php');

/**
 * Queue handling daemon...
 *
 * The queue daemon by default launches in the background, at which point
 * it'll pass control to the configured QueueManager class to poll for updates.
 *
 * We can then pass individual items through the QueueHandler subclasses
 * they belong to.
 */
class QueueDaemon extends SpawningDaemon
{
    protected $allsites = false;

    function __construct($id=null, $daemonize=true, $threads=1, $allsites=false)
    {
        parent::__construct($id, $daemonize, $threads);
        $this->allsites = $allsites;
    }

    /**
     * Setup and start of run loop for this queue handler as a daemon.
     * Most of the heavy lifting is passed on to the QueueManager's service()
     * method, which passes control on to the QueueHandler's handle()
     * method for each item that comes in on the queue.
     *
     * @return boolean true on success, false on failure
     */
    function runThread()
    {
        $this->log(LOG_INFO, 'checking for queued notices');

        $master = new QueueMaster($this->get_id(), $this->processManager());
        $master->init($this->allsites);
        try {
            $master->service();
        } catch (Exception $e) {
            common_log(LOG_ERR, "Unhandled exception: " . $e->getMessage() . ' ' .
                str_replace("\n", " ", $e->getTraceAsString()));
            return self::EXIT_ERR;
        }

        $this->log(LOG_INFO, 'finished servicing the queue');

        $this->log(LOG_INFO, 'terminating normally');

        return $master->respawn ? self::EXIT_RESTART : self::EXIT_SHUTDOWN;
    }
}

class QueueMaster extends IoMaster
{
    protected $processManager;

    function __construct($id, $processManager)
    {
        parent::__construct($id);
        $this->processManager = $processManager;
    }

    /**
     * Initialize IoManagers which are appropriate to this instance.
     */
    function initManagers()
    {
        $managers = array();
        if (Event::handle('StartQueueDaemonIoManagers', array(&$managers))) {
            $qm = QueueManager::get();
            $qm->setActiveGroup('main');
            $managers[] = $qm;
            $managers[] = $this->processManager;
        }
        Event::handle('EndQueueDaemonIoManagers', array(&$managers));

        foreach ($managers as $manager) {
            $this->instantiate($manager);
        }
    }
}

if (have_option('i')) {
    $id = get_option_value('i');
} else if (have_option('--id')) {
    $id = get_option_value('--id');
} else if (count($args) > 0) {
    $id = $args[0];
} else {
    $id = null;
}

if (have_option('t')) {
    $threads = intval(get_option_value('t'));
} else if (have_option('--threads')) {
    $threads = intval(get_option_value('--threads'));
} else {
    //If there is no argument for number of threads
    //Try reading a config option for the number
    $threads = common_config('queue','threads');
}
if (!$threads) {
    $threads = getProcessorCount();
}

common_log(LOG_INFO, sprintf('Launching QueueDaemon background process with %1$d threads.', $threads));

$daemonize = !(have_option('f') || have_option('--foreground'));
$all = have_option('a') || have_option('--all');

$daemon = new QueueDaemon($id, $daemonize, $threads, $all);
$daemon->runOnce();


code:
#!/usr/bin/env php
<?php
/*
 * StatusNet - a distributed open-source microblogging tool
 * Copyright (C) 2008, 2009, StatusNet, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));

$shortoptions = 'n:w:f:e:';
$longoptions = array('nickname=', 'password=', 'fullname=', 'email=');

$helptext = <<<END_OF_REGISTERUSER_HELP
registeruser.php [options]
registers a user in the database

  -n --nickname nickname of the new user
  -w --password password of the new user
  -f --fullname full name of the new user (optional)
  -e --email    email address of the new user (optional)

END_OF_REGISTERUSER_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

$nickname = get_option_value('n', 'nickname');
$password = get_option_value('w', 'password');
$fullname = get_option_value('f', 'fullname');

$email = get_option_value('e', 'email');

if (empty($nickname) || empty($password)) {
    print "Must provide a username and password.\n";
    exit(1);
}

try {

    $user = User::getKV('nickname', $nickname);

    if (!empty($user)) {
        throw new Exception("A user named '$nickname' already exists.");
    }

    $user = User::register(array('nickname' => $nickname,
                                 'password' => $password,
                                 'fullname' => $fullname));

    if (empty($user)) {
        throw new Exception("Can't register user '$nickname' with password '$password' and fullname '$fullname'.");
    }

    if (!empty($email)) {

        $orig = clone($user);

        $user->email = $email;

        // Throws exception on failure.
        $user->updateWithKeys($orig);
    }

} catch (Exception $e) {
    print $e->getMessage() . "\n";
    exit(1);
}


code:
#!/usr/bin/env php
<?php
/*
 * StatusNet - a distributed open-source microblogging tool
 * Copyright (C) 2008, 2009, StatusNet, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));

$shortoptions = 'y';
$longoptions = array('yes');

$helptext = <<<END_OF_HELP
remove_duplicate_file_urls.php [options]
Remove duplicate URL entries in the file and file_redirection tables because they for some reason were not unique.

  -y --yes      do not wait for confirmation

END_OF_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

if (!have_option('y', 'yes')) {
    print "About to remove duplicate URL entries in file and file_redirection tables. Are you sure? [y/N] ";
    $response = fgets(STDIN);
    if (strtolower(trim($response)) != 'y') {
        print "Aborting.\n";
        exit(0);
    }
}

$file = new File();
$file->query('SELECT id, url, COUNT(*) AS c FROM file GROUP BY url HAVING c > 1');
print "\nFound {$file->N} URLs with duplicate entries in file table";
while ($file->fetch()) {
    // We've got a URL that is duplicated in the file table
    $dupfile = new File();
    $dupfile->url = $file->url;
    if ($dupfile->find(true)) {
        print "\nDeleting duplicate entries in file table for URL: {$file->url} [";
        // Leave one of the URLs in the database by using ->find(true)
        // and only deleting starting with this fetch.
        while($dupfile->fetch()) {
            print ".";
            $dupfile->delete();
        }
        print "]\n";
    } else {
        print "\nWarning! URL suddenly disappeared from database: {$file->url}\n";
    }
}

$file = new File_redirection();
$file->query('SELECT file_id, url, COUNT(*) AS c FROM file_redirection GROUP BY url HAVING c > 1');
print "\nFound {$file->N} URLs with duplicate entries in file_redirection table";
while ($file->fetch()) {
    // We've got a URL that is duplicated in the file_redirection table
    $dupfile = new File_redirection();
    $dupfile->url = $file->url;
    if ($dupfile->find(true)) {
        print "\nDeleting duplicate entries in file table for URL: {$file->url} [";
        // Leave one of the URLs in the database by using ->find(true)
        // and only deleting starting with this fetch.
        while($dupfile->fetch()) {
            print ".";
            $dupfile->delete();
        }
        print "]\n";
    } else {
        print "\nWarning! URL suddenly disappeared from database: {$file->url}\n";
    }
}
print "\nDONE.\n";


code:
#!/usr/bin/env php
<?php

define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));

$shortoptions = 'e::ay';
$longoptions = array('email=', 'all', 'yes');

$self = basename($_SERVER['PHP_SELF']);

$helptext = <<<END_OF_HELP
{$self} [options]
resends confirmation email either for a specific email (if found) or for
all lingering confirmations.

NOTE: You probably want to do something like this to your database first so
only relatively fresh accounts get resent this:

    DELETE FROM confirm_address WHERE modified < DATE_SUB(NOW(), INTERVAL 1 month);

Options:

  -e --email        e-mail address to send for
  -a --all          send for all emails in confirm_address table
  -y --yes          skip interactive verification

END_OF_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

$all = false;
$ca = null;

if (have_option('e', 'email')) {
    $email = get_option_value('e', 'email');
    try {
        $ca = Confirm_address::getByAddress($email, 'email');
    } catch (NoResultException $e) {
        print sprintf("Can't find %s address %s in %s table.\n", $e->obj->address_type, $e->obj->address, $e->obj->tableName());
        exit(1);
    }
} elseif (have_option('a', 'all')) {
    $all = true;
    $ca = new Confirm_address();
    $ca->address_type = 'email';
    if (!$ca->find()) {
        print "confirm_address table contains no lingering email addresses\n";
        exit(0);
    }
} else {
    print "You must provide an email (or --all).\n";
    exit(1);
}

if (!have_option('y', 'yes')) {
    print "About to resend confirm_address email to {$ca->N} recipients. Are you sure? [y/N] ";
    $response = fgets(STDIN);
    if (strtolower(trim($response)) != 'y') {
        print "Aborting.\n";
        exit(0);
    }
}

function mailConfirmAddress(Confirm_address $ca)
{
    try {
        $user = User::getByID($ca->user_id);
        $profile = $user->getProfile();
        if ($profile->isSilenced()) {
            $ca->delete();
            return;
        }
        if ($user->email === $ca->address) {
            throw new AlreadyFulfilledException('User already has identical confirmed email address.');
        }
    } catch (AlreadyFulfilledException $e) {
        print "\n User already had verified email: "._ve($ca->address);
        $ca->delete();
    } catch (Exception $e) {
        print "\n Failed to get user with ID "._ve($user_id).', deleting confirm_address entry: '._ve($e->getMessage());
        $ca->delete();
        return;
    }
    mail_confirm_address($user, $ca->code, $user->getNickname(), $ca->address);
}

require_once(INSTALLDIR . '/lib/mail.php');

if (!$all) {
    mailConfirmAddress($ca);
} else {
    while ($ca->fetch()) {
        mailConfirmAddress($ca);
    }
}

print "\nDONE.\n";


code:
<?php
/*
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2010 StatusNet, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));

$shortoptions = 'i:n:f:';
$longoptions = array('id=', 'nickname=', 'file=');

$helptext = <<<END_OF_RESTOREUSER_HELP
restoreuser.php [options]
Restore a backed-up user file to the database. If
neither ID or name provided, will create a new user.

  -i --id       ID of user to export
  -n --nickname nickname of the user to export
  -f --file     file to read from (STDIN by default)

END_OF_RESTOREUSER_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

function getActivityStreamDocument()
{
    $filename = get_option_value('f', 'file');

    if (empty($filename)) {
        show_help();
        exit(1);
    }

    if (!file_exists($filename)) {
        throw new Exception("No such file '$filename'.");
    }

    if (!is_file($filename)) {
        throw new Exception("Not a regular file: '$filename'.");
    }

    if (!is_readable($filename)) {
        throw new Exception("File '$filename' not readable.");
    }

    // TRANS: Commandline script output. %s is the filename that contains a backup for a user.
    printfv(_("Getting backup from file '%s'.")."\n",$filename);

    $xml = file_get_contents($filename);

    return $xml;
}

try {
    try {
        $user = getUser();
    } catch (NoUserArgumentException $noae) {
        $user = null;
    }
    $xml = getActivityStreamDocument();
    $qm = QueueManager::get();
    $qm->enqueue(array($user, $xml, true), 'feedimp');
} catch (Exception $e) {
    print $e->getMessage()."\n";
    exit(1);
}


code:
#!/usr/bin/env php
<?php
/**
 * GNU social - a federating social network
 *
 * LICENCE: 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 <http://www.gnu.org/licenses/>.
 *
 * @category  Plugin
 * @package   GNUsocial
 * @copyright 2008 Free Software Foundation http://fsf.org
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link      https://www.gnu.org/software/social/
 */

define('INSTALLDIR', realpath(dirname(__DIR__)));

$shortoptions = 'i:n:a:';
$longoptions = ['id=', 'nickname=', 'subject=', 'all='];

$helptext = <<<END_OF_USEREMAIL_HELP
sendemail.php [options] < <message body>
Sends given email text to user.

  -i --id       id of the user to query
  -a --all      send to all users
  -n --nickname nickname of the user to query
     --subject  mail subject line (required)

END_OF_USEREMAIL_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

$all = have_option('a', 'all');

if ($all) {
    $user = new User();
    $user->find();
} else if (have_option('i', 'id')) {
    $id = get_option_value('i', 'id');
    $user = User::getKV('id', $id);
    if (empty($user)) {
        print "Can't find user with ID $id\n";
        exit(1);
    }
    unset ($id);
} else if (have_option('n', 'nickname')) {
    $nickname = get_option_value('n', 'nickname');
    $user = User::getKV('nickname', $nickname);
    if (empty($user)) {
        print "Can't find user with nickname '$nickname'.\n";
        exit(1);
    }
    unset($nickname);
} else {
    print "You must provide a user by --id, --nickname or just send something to --all\n";
    exit(1);
}

if (!have_option('subject')) {
    echo "You must provide a subject line for the mail in --subject='...' param.\n";
    exit(1);
}
$subject = get_option_value('subject');

if (posix_isatty(STDIN)) {
    print "You must provide message input on stdin!\n";
    exit(1);
}
$body = file_get_contents('php://stdin');

if ($all) {
    while ($user->fetch()) {
        _send($user, $subject, $body);
    }
} else {
    _send($user, $subject, $body);
}

function _send($user, $subject, $body) {
    if (empty($user->email)) {
        // @fixme unconfirmed address?
        print "No email registered for user '$user->nickname'.\n";
        return;
    }
    print "Sending to $user->email... ";
    if (mail_to_user($user, $subject, $body)) {
        print "done.\n";
    } else {
        print "failed.\n";
        return;
    }
}


code:
#!/usr/bin/env php
<?php
/*
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2008, 2009, StatusNet, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));

$helptext = <<<END_OF_GC_HELP
sessiongc.php

Delete old sessions from the server

END_OF_GC_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

$maxlifetime = ini_get('session.gc_maxlifetime');

print "Deleting sessions older than $maxlifetime seconds.\n";

Session::gc($maxlifetime);


code:
#!/usr/bin/env php
<?php
/*
 * StatusNet - a distributed open-source microblogging tool
 * Copyright (C) 2008, 2009, StatusNet, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));

$shortoptions = 'da';
$longoptions = array('delete', 'all');

$helptext = <<<END_OF_SETCONFIG_HELP
setconfig.php [options] [section] [setting] <value>
With three args, set the setting to the value.
With two args, just show the setting.
With -d, delete the setting.
With no args, lists all currently set values.

  [section]   section to use (required)
  [setting]   setting to use (required)
  <value>     value to set (optional)

  -d --delete delete the setting (no value)
  -a --all    list all configuration, not just the database values

END_OF_SETCONFIG_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

if (empty($args)) {
    if (have_option('a', 'all')) {
        foreach ($config as $section => $section_value) {
            foreach ($section_value as $setting => $value) {
                if (have_option('v', 'verbose') || !is_array($value)) {
                    // Don't print array's without the verbose flag
                    printf("%-20s %-20s %s\n", $section, $setting, var_export($value, true));
                }
            }
        }
    } else {
        $count = 0;
        $config = new Config();
        $config->find();
        while ($config->fetch()) {
            $count++;
            printf("%-20s %-20s %s\n", $config->section, $config->setting,
                   var_export($config->value, true));
        }
        if ($count == 0) {
            print "No configuration set in database for this site.\n";
        }
    }
    exit(0);
}

if (count($args) < 2 || count($args) > 3) {
    show_help();
    exit(1);
}

$section = $args[0];
$setting = $args[1];

if (count($args) == 3) {
    $value = $args[2];
} else {
    $value = null;
}

try {

    if (have_option('d', 'delete')) { // Delete
        if (count($args) != 2) {
            show_help();
            exit(1);
        }

        if (have_option('v', 'verbose')) {
            print "Deleting setting $section/$setting...";
        }

        $setting = Config::pkeyGet(array('section' => $section,
                                         'setting' => $setting));

        if (empty($setting)) {
            print "Not found.\n";
        } else {
            $result = $setting->delete();
            if ($result) {
                print "DONE.\n";
            } else {
                print "ERROR.\n";
            }
        }
    } else if (count($args) == 2) { // show
        if (have_option('v', 'verbose')) {
            print "$section/$setting = ";
        }
        $value = common_config($section, $setting);
        print "$value\n";
    } else { // set
        if (have_option('v', 'verbose')) {
            print "Setting $section/$setting...";
        }
        Config::save($section, $setting, $value);
        print "DONE.\n";
    }

} catch (Exception $e) {
    print $e->getMessage() . "\n";
    exit(1);
}


code:
#!/usr/bin/env php
<?php
/*
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2008, 2009, StatusNet, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));

$helptext = <<<END_OF_PASSWORD_HELP
setpassword.php <username> <password>

Sets the password of user with name <username> to <password>

END_OF_PASSWORD_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

if (count($args) < 2) {
    show_help();
}

$nickname = $args[0];
$password = $args[1];

if (mb_strlen($password) < 6) {
    print "Password must be 6 characters or more.\n";
    exit(1);
}

try {
    $user = User::getByNickname($nickname);
    $user->setPassword($password);
} catch (NoSuchUserException $e) {
    print $e->getMessage();
    exit(1);
}

print "Password for user '$nickname' updated.\n";


code:
#!/usr/bin/env php
<?php
/*
 * StatusNet - a distributed open-source microblogging tool
 * Copyright (C) 2008, 2009, StatusNet, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));

$shortoptions = 'd';
$longoptions = array('delete');

$helptext = <<<END_OF_SETTAG_HELP
settag.php [options] <site> <tag>
Set the tag <tag> for site <site>.

With -d, delete the tag.

END_OF_SETTAG_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

if (count($args) < 1) {
    show_help();
    exit(1);
}

$nickname = $args[0];
$sn = Status_network::memGet('nickname', $nickname);

if (empty($sn)) {
    print "No such site ($nickname).\n";
    exit(-1);
}

$tags = $sn->getTags();

if (count($args) == 1) {
	print(implode(', ', $tags) . "\n");
	exit(0);
}
$tag = $args[1];
$i = array_search($tag, $tags);

if ($i !== false) {
    if (have_option('d', 'delete')) { // Delete
        unset($tags[$i]);

        $result = $sn->setTags($tags);
        if (!$result) {
            print "Couldn't update.\n";
            exit(-1);
        }
    } else {
        print "Already set.\n";
        exit(0);
    }
} else {
    if (have_option('d', 'delete')) { // Delete
        print "No such tag.\n";
        exit(0);
    } else {
        $tags[] = $tag;
        $result = $sn->setTags($tags);
        if (!$result) {
            print "Couldn't update.\n";
            exit(-1);
        }
    }
}


code:
# CONFIGURATION FILE for setup_status_network.sh

export DBHOST=localhost
export DBHOSTNAME=masterdb.example.net
export DBBASE=_example_net
export USERBASE=_example_net
export ADMIN=root
export ADMINPASS=yourpassword
export SITEDB=example_net_site
export AVATARBASE=/var/www/avatar.example.net
export BACKGROUNDBASE=/var/www/background.example.net
export FILEBASE=/var/www/file.example.net
export PWDGEN="pwgen 20"
export PHPBASE=/var/www/statusnet
export WILDCARD=example.net
export MAILTEMPLATE=/etc/statusnet/newsite-mail.txt
export MAILSUBJECT="Your new StatusNet site"
export POSTINSTALL=/etc/statusnet/morestuff.sh
export WEBUSER=www-data
export WEBGROUP=www-data
export TAGS=tag1,tag2,tag3


code:
#!/bin/bash

# live fast! die young!

set -e

source /etc/statusnet/setup.cfg

# setup_status_network.sh mysite 'My Site' '1user' 'owner@example.com' 'Firsty McLastname'

export nickname="$1"
export sitename="$2"
export tags="$3"
export email="$4"
export fullname="$5"
export siteplan="$6"

if [ "$siteplan" == '' ]; then
    siteplan='single-user'
fi

# Fixme: if this is changed later we need to update profile URLs
# for the created user.
export server="$nickname.$WILDCARD"

# End-user info
export userpass=`$PWDGEN`
export roles="administrator moderator owner"

# DB info
export password=`$PWDGEN`
export database=$nickname$DBBASE
export username=$nickname$USERBASE

# Create the db

mysqladmin -h $DBHOST -u $ADMIN --password=$ADMINPASS create $database

for f in statusnet.sql innodb.sql sms_carrier.sql foreign_services.sql notice_source.sql; do
    mysql -h $DBHOST -u $ADMIN --password=$ADMINPASS $database < ../db/$f;
done

mysql -h $DBHOST -u $ADMIN --password=$ADMINPASS $SITEDB << ENDOFCOMMANDS

GRANT ALL ON $database.* TO '$username'@'localhost' IDENTIFIED BY '$password';
GRANT ALL ON $database.* TO '$username'@'%' IDENTIFIED BY '$password';
INSERT INTO status_network (nickname, dbhost, dbuser, dbpass, dbname, sitename, created)
VALUES ('$nickname', '$DBHOSTNAME', '$username', '$password', '$database', '$sitename', now());

ENDOFCOMMANDS

for top in $AVATARBASE $FILEBASE $BACKGROUNDBASE; do
    mkdir $top/$nickname
    chmod a+w $top/$nickname
done

php $PHPBASE/scripts/checkschema.php -s"$server"

php $PHPBASE/scripts/settag.php -s"$server" "$nickname" "$tags"

php $PHPBASE/scripts/registeruser.php \
  -s"$server" \
  -n"$nickname" \
  -f"$fullname" \
  -w"$userpass" \
  -e"$email"

for role in $roles
do
  php $PHPBASE/scripts/userrole.php \
    -s"$server" \
    -n"$nickname" \
    -r"$role"
done

if [ -f "$MAILTEMPLATE" ]
then
    # fixme how safe is this? are sitenames sanitized?
    cat $MAILTEMPLATE | \
      sed "s/\$nickname/$nickname/" | \
      sed "s/\$sitename/$sitename/" | \
      sed "s/\$userpass/$userpass/" | \
      sed "s/\$siteplan/$siteplan/" | \
      php $PHPBASE/scripts/sendemail.php \
        -s"$server" \
        -n"$nickname" \
        --subject="$MAILSUBJECT"
else
    echo "No mail template, not sending email."
fi

if [ -f "$POSTINSTALL" ]
then
    echo "Running $POSTINSTALL ..."
    source "$POSTINSTALL"
fi


code:
#!/usr/bin/env php
<?php
/*
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2009, StatusNet, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));

$shortoptions = "t:l:v:k:";

$helptext = <<<ENDOFHELP
USAGE: showcache.php <args>
shows the cached object based on the args

  -t table     Table to look up
  -l column    Column to look up, default "id"
  -v value     Value to look up
  -k key       Key to look up; other args are ignored

ENDOFHELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

$karg = get_option_value('k');

if (!empty($karg)) {
    $k = Cache::key($karg);
} else {
    $table = get_option_value('t');
    if (empty($table)) {
        die("No table or key specified\n");
    }
    $column = get_option_value('l');
    if (empty($column)) {
        $column = 'id';
    }
    $value = get_option_value('v');

    $k = Memcached_DataObject::cacheKey($table, $column, $value);
}

print "Checking key '$k'...\n";

$c = Cache::instance();

if (empty($c)) {
    die("Can't initialize cache object!\n");
}

$obj = $c->get($k);

if (empty($obj)) {
    print "Empty.\n";
} else {
    var_dump($obj);
    print "\n";
}


code:
#!/usr/bin/env php
<?php
/*
 * StatusNet - a distributed open-source microblogging tool
 * Copyright (C) 2010, StatusNet, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));

require_once INSTALLDIR.'/scripts/commandline.inc';

foreach (StatusNet::getActivePlugins() as $plugin=>$args) {
    echo "$plugin: ";
    if (empty($args)) {
        echo "(no args)\n";
    } else {
        foreach ($args as $arg => $val) {
            echo "\n  $arg: ";
            var_export($val);
        }
        echo "\n";
    }
    echo "\n";
}


code:
#!/usr/bin/env php
<?php
/*
 * StatusNet - a distributed open-source microblogging tool
 * Copyright (C) 2008, 2009, StatusNet, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));

$helptext = <<<END_OF_SHOWTABLE_HELP
showtable.php <tablename>
Shows the structure of a table

END_OF_SHOWTABLE_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

if (count($args) != 1) {
    show_help();
}

$name = $args[0];

$schema = Schema::get();

$td = $schema->getTableDef($name);

print_r($td);


code:
#!/usr/bin/env php
<?php
/*
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2009, StatusNet, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

// Abort if called from a web server

define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));

$helptext = <<<ENDOFHELP
console.php - provide an interactive PHP interpreter for testing

ENDOFHELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

// Assume we're on a terminal if on Windows, otherwise posix_isatty tells us.
define('CONSOLE_INTERACTIVE', !function_exists('posix_isatty') || posix_isatty(0));
define('CONSOLE_READLINE', CONSOLE_INTERACTIVE && function_exists('readline'));

if (CONSOLE_READLINE && CONSOLE_INTERACTIVE) {
    define('CONSOLE_HISTORY', getenv("HOME") . "/.statusnet_console_history");
    if (file_exists(CONSOLE_HISTORY)) {
        readline_read_history(CONSOLE_HISTORY);
    }
}

function read_input_line($prompt)
{
    if (CONSOLE_INTERACTIVE) {
        if (CONSOLE_READLINE) {
            $line = readline($prompt);
            if (trim($line) != '') {
                readline_add_history($line);
                if (defined('CONSOLE_HISTORY')) {
                    // Save often; it's easy to hit fatal errors.
                    readline_write_history(CONSOLE_HISTORY);
                }
            }
            return $line;
        } else {
            return readline_emulation($prompt);
        }
    } else {
        return fgets(STDIN);
    }
}

/**
 * On Unix-like systems where PHP readline extension isn't present,
 * -cough- Mac OS X -cough- we can shell out to bash to do it for us.
 * This lets us at least handle things like arrow keys, but we don't
 * get any entry history. :(
 *
 * Shamelessly ripped from when I wrote the same code for MediaWiki. :)
 * @author Brion Vibber <brion@status.net>
 *
 * @param string $prompt
 * @return mixed string on success, false on fail or EOF
 */
function readline_emulation($prompt)
{
    if (CONSOLE_INTERACTIVE && file_exists(trim(shell_exec('which bash')))) {
        $encPrompt = escapeshellarg($prompt);
        $command = "read -er -p $encPrompt && echo \"\$REPLY\"";
        $encCommand = escapeshellarg($command);
        $metaCommand = "bash -c $encCommand";

        // passthru passes our STDIN and TTY to the child...
        // We can pull the returned string via output buffering.
        ob_start();
        $retval = false;
        passthru($metaCommand, $retval);
        $line = ob_get_contents();
        ob_end_clean();

        if ($retval == 0) {
            return $line;
        } elseif ($retval == 127) {
            // Couldn't execute bash even though we thought we saw it.
            // Shell probably spit out an error message, sorry :(
            // Fall through to fgets()...
        } else {
            // EOF/ctrl+D
            return false;
        }
    }

    // Fallback... we'll have no editing controls, EWWW
    if (feof(STDIN)) {
        return false;
    }
    if (CONSOLE_INTERACTIVE) {
        print $prompt;
    }
    return fgets(STDIN);
}

function console_help()
{
    print "Welcome to GNU social's interactive PHP console!\n";
    print "Type some PHP code and it'll execute...\n";
    print "\n";
    print "Hint: return a value of any type to output it via var_export():\n";
    print "  \$profile = new Profile();\n";
    print "  \$profile->find();\n";
    print "  \$profile->fetch();\n";
    print "  return \$profile;\n";
    print "\n";
    print "Note that PHP is cranky and you can easily kill your session by mistyping.\n";
    print "\n";
    print "Type ctrl+D or enter 'exit' to exit.\n";
}

if (CONSOLE_INTERACTIVE) {
    print "GNU social interactive PHP console... type ctrl+D or enter 'exit' to exit.\n";
    $prompt = common_slugify(common_config('site', 'name')) . '> ';
} else {
    $prompt = '';
}
while (!feof(STDIN)) {
    $line = read_input_line($prompt);
    if ($line === false) {
        if (CONSOLE_INTERACTIVE) {
            print "\n";
        }
        break;
    } elseif ($line !== '') {
        try {
            if (trim($line) == 'exit') {
                break;
            } elseif (trim($line) == 'help') {
                console_help();
                continue;
            }

            // Let's do this!
            $result = eval($line);
            if ($result === false) {
                // parse error
            } elseif ($result === null) {
                // no return
            } else {
                // return value from eval'd code
                var_export($result);
            }
        } catch (Exception $e) {
            print get_class($e) . ": " . $e->getMessage() . "\n";
        }
    }
    if (CONSOLE_INTERACTIVE) {
        print "\n";
    }
}


code:
#!/bin/sh

# StatusNet - a distributed open-source microblogging tool

# Copyright (C) 2008, 2009, StatusNet, Inc.
#
# 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 <http://www.gnu.org/licenses/>.

# This program tries to start the daemons for StatusNet.
# Note that the 'maildaemon' needs to run as a mail filter.

ARGSG=
ARGSD=

if [ $# -gt 0 ]; then
    ARGSG="$ARGSG -s$1"
    ID=`echo $1 | sed s/\\\\./_/g`
    ARGSD="$ARGSD -s$1 -i$ID"
fi

if [ $# -gt 1 ]; then
    ARGSD="$ARGSD -p$2"
    ARGSG="$ARGSG -p$2"
fi

DIR=`dirname $0`
DAEMONS=`php $DIR/getvaliddaemons.php $ARGSG`

for f in $DAEMONS; do

    echo "Starting $f..."
    php $f $ARGSD
    echo "DONE."

done


code:
#!/bin/bash

# StatusNet - a distributed open-source microblogging tool

# Copyright (C) 2008, 2009, StatusNet, Inc.
#
# 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 <http://www.gnu.org/licenses/>.

# This program tries to stop the daemons for GNU social that were
# previously started by startdaemons.sh

ARGSG=
SITENAME=
SITE=
ID="*"

# stopdaemons.sh [server [path]]

if [ $# -gt 0 ] ; then
	SITENAME="$1"
	SITE="-s$SITENAME"
	ID=`echo $SITENAME | sed s/\\\\./_/g`
	ARGSG="$ARGSG -s$1"
fi

if [ $# -gt 1 ]; then
	ARGSG="$ARGSG -p$2"
fi

SDIR=`dirname $0`
DIR=`php $SDIR/getpiddir.php $SITE`

DAEMONS=`php $SDIR/getvaliddaemons.php $ARGSG`

for f in $DAEMONS; do
    f=$(basename $f .php)

	FILES="$DIR/$f.$ID.pid"

	for ff in "$FILES" ; do

	 	PID=`cat $ff 2>/dev/null`
		if [ -n "$PID" ] ; then
		 	echo -n "Stopping $f ($PID)..."
			if kill -3 $PID 2>/dev/null ; then
				count=0
				while kill -0 $PID 2>/dev/null ;  do
					sleep 1
					count=$(($count + 1))
					if [ $count -gt 5 ]; then break; fi
				done
				if kill -9 $PID 2>/dev/null ; then
					echo "FORCIBLY TERMINATED"
				else
					echo "STOPPED CLEANLY"
				fi
			else
				echo "NOT FOUND"
			fi
		fi
		rm -f $ff
	done
done


code:
#!/usr/bin/env php
<?php
/*
 * StatusNet - a distributed open-source microblogging tool
 * Copyright (C) 2009-2010, StatusNet, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));

$shortoptions = 'i::n::y';
$longoptions = array('id=', 'nickname=', 'yes', 'dry-run', 'all');

$helptext = <<<END_OF_HELP
strip_geo.php [options]
Removes geolocation info from the given user's notices.

  -i --id       ID of the user (may be a remote profile)
  -n --nickname nickname of the user
  -y --yes      do not wait for confirmation
     --dry-run  list affected notices without deleting
     --all      run over and decache all messages, even if they don't
                have geo data now (helps to fix cache bugs)

END_OF_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

if (have_option('i', 'id')) {
    $id = get_option_value('i', 'id');
    $profile = Profile::getKV('id', $id);
    if (empty($profile)) {
        print "Can't find local or remote profile with ID $id\n";
        exit(1);
    }
} else if (have_option('n', 'nickname')) {
    $nickname = get_option_value('n', 'nickname');
    $user = User::getKV('nickname', $nickname);
    if (empty($user)) {
        print "Can't find local user with nickname '$nickname'\n";
        exit(1);
    }
    $profile = $user->getProfile();
} else {
    print "You must provide either an ID or a nickname.\n\n";
    show_help();
    exit(1);
}

if (!have_option('y', 'yes') && !have_option('--dry-run')) {
    print "About to PERMANENTLY remove geolocation data from user '{$profile->nickname}' ({$profile->id})'s notices. Are you sure? [y/N] ";
    $response = fgets(STDIN);
    if (strtolower(trim($response)) != 'y') {
        print "Aborting.\n";
        exit(0);
    }
}

// @fixme for a very prolific poster this could be too many.
$notice = new Notice();
$notice->profile_id = $profile->id;
if (have_option('--all')) {
    print "Finding all notices by $profile->nickname...";
} else {
    print "Finding notices by $profile->nickname with geolocation data...";
    $notice->whereAdd("lat != ''");
}
$notice->find();

if ($notice->N) {
    print " $notice->N found.\n";
    while ($notice->fetch()) {
        print "notice id $notice->id ";
        if (have_option('v') || have_option('--verbose')) {
            print "({$notice->lat},{$notice->lon}) ";
            if ($notice->location_ns) {
                print "ns {$notice->location_ns} id {$notice->location_id} ";
            }
        }
        if (have_option('--dry-run')) {
            // sucka
            echo "(skipped)";
        } else {
            // note: setting fields to null and calling update() doesn't save the nulled fields
            $orig = clone($notice);
            $update = clone($notice);

            // In theory we could hit a chunk of notices at once in the UPDATE,
            // but we're going to have to decache them individually anyway and
            // it doesn't hurt to make sure we don't hold up replication with
            // what might be a very slow single UPDATE.
            $query = sprintf('UPDATE notice ' .
                             'SET lat=NULL,lon=NULL,location_ns=NULL,location_id=NULL ' .
                             'WHERE id=%d', $notice->id);
            $ok = $update->query($query);
            if ($ok) {
                // And now we decache him manually, as query() doesn't know what we're doing...
                $orig->decache();
                echo "(removed)";
            } else {
                echo "(unchanged?)";
            }
        }
        print "\n";
    }
} else {
    print " none found.\n";
}

print "DONE.\n";


code:
#!/usr/bin/env php
<?php
/*
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2008, 2009, StatusNet, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 */
define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));

$helptext = <<<ENDOFHELP
uncache_users.php <idfile>

Uncache users listed in an ID file, default 'ids.txt'.

ENDOFHELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

$id_file = (count($args) > 1) ? $args[0] : 'ids.txt';

common_log(LOG_INFO, 'Updating user inboxes.');

$ids = file($id_file);

$memc = Cache::instance();

foreach ($ids as $id) {

	$user = User::getKV('id', $id);

	if (!$user) {
		common_log(LOG_WARNING, 'No such user: ' . $id);
		continue;
	}

    $user->decache();

    $memc->delete(Cache::key('user:notices_with_friends:'. $user->id));
    $memc->delete(Cache::key('user:notices_with_friends:'. $user->id . ';last'));
}