summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--actions/finishremotesubscribe.php13
-rw-r--r--actions/login.php9
-rw-r--r--classes/Login_token.php42
-rw-r--r--classes/statusnet.ini3
-rw-r--r--db/08to09.sql11
-rw-r--r--db/08to09_pg.sql9
-rw-r--r--db/statusnet.sql10
-rw-r--r--db/statusnet_pg.sql12
-rw-r--r--lib/command.php27
-rw-r--r--lib/commandinterpreter.php6
-rw-r--r--lib/jabber.php1
-rw-r--r--lib/router.php2
-rw-r--r--plugins/InfiniteScroll/infinitescroll.js2
-rw-r--r--plugins/Mapstraction/MapstractionPlugin.php68
-rw-r--r--plugins/Meteor/meteorupdater.js2
-rw-r--r--plugins/MobileProfile/MobileProfilePlugin.php7
-rw-r--r--plugins/Realtime/realtimeupdate.js2
-rw-r--r--plugins/UserFlag/UserFlagPlugin.php2
-rw-r--r--plugins/UserFlag/flagprofile.php26
-rw-r--r--plugins/UserFlag/flagprofileform.php12
-rw-r--r--scripts/updateavatarurl.php128
21 files changed, 259 insertions, 135 deletions
diff --git a/actions/finishremotesubscribe.php b/actions/finishremotesubscribe.php
index b1cec66f4..deee70f36 100644
--- a/actions/finishremotesubscribe.php
+++ b/actions/finishremotesubscribe.php
@@ -89,12 +89,16 @@ class FinishremotesubscribeAction extends Action
}
$remote = Remote_profile::staticGet('uri', $service->getListenerURI());
+ if ($remote) {
+ // Note remote profile may not have been saved yet.
+ // @fixme not convinced this is correct at all!
- $profile = Profile::staticGet($remote->id);
+ $profile = Profile::staticGet($remote->id);
- if ($user->hasBlocked($profile)) {
- $this->clientError(_('That user has blocked you from subscribing.'));
- return;
+ if ($user->hasBlocked($profile)) {
+ $this->clientError(_('That user has blocked you from subscribing.'));
+ return;
+ }
}
/* Perform the handling itself via libomb. */
@@ -122,6 +126,7 @@ class FinishremotesubscribeAction extends Action
/* The service URLs are not accessible from datastore, so setting them
after insertion of the profile. */
+ $remote = Remote_profile::staticGet('uri', $service->getListenerURI());
$orig_remote = clone($remote);
$remote->postnoticeurl =
diff --git a/actions/login.php b/actions/login.php
index cee29fd09..cd1326813 100644
--- a/actions/login.php
+++ b/actions/login.php
@@ -79,8 +79,6 @@ class LoginAction extends Action
$this->clientError(_('Already logged in.'));
} else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$this->checkLogin();
- } else if (isset($args['user_id']) && isset($args['token'])){
- $this->checkLogin($args['user_id'],$args['token']);
} else {
common_ensure_session();
$this->showForm();
@@ -97,7 +95,7 @@ class LoginAction extends Action
* @return void
*/
- function checkLogin($user_id=null, $token=null)
+ function checkLogin()
{
if(isset($token) && isset($user_id)){
//Token based login (from the LoginCommand)
@@ -139,6 +137,11 @@ class LoginAction extends Action
$user = common_check_user($nickname, $password);
}
+ $nickname = common_canonical_nickname($this->trimmed('nickname'));
+ $password = $this->arg('password');
+
+ $user = common_check_user($nickname, $password);
+
if (!$user) {
$this->showForm(_('Incorrect username or password.'));
return;
diff --git a/classes/Login_token.php b/classes/Login_token.php
deleted file mode 100644
index bd6381f90..000000000
--- a/classes/Login_token.php
+++ /dev/null
@@ -1,42 +0,0 @@
-<?php
-/**
- * Table Definition for group_alias
- *
- * 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/>.
- */
-
-if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
-
-require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
-
-class Login_token extends Memcached_DataObject
-{
- ###START_AUTOCODE
- /* the code below is auto generated do not remove the above tag */
-
- public $__table = 'login_token'; // table name
- public $user_id; // int(4) primary_key not_null
- public $token; // char(32) not_null
- public $created; // datetime() not_null
- public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
-
- /* Static get */
- function staticGet($k,$v=NULL) { return DB_DataObject::staticGet('Login_token',$k,$v); }
-
- /* the code above is auto generated do not remove the tag below */
- ###END_AUTOCODE
-}
diff --git a/classes/statusnet.ini b/classes/statusnet.ini
index b2509dac5..835faeb0b 100644
--- a/classes/statusnet.ini
+++ b/classes/statusnet.ini
@@ -1,4 +1,3 @@
-
[avatar]
profile_id = 129
original = 17
@@ -542,4 +541,4 @@ created = 142
modified = 384
[user_group__keys]
-id = N \ No newline at end of file
+id = N
diff --git a/db/08to09.sql b/db/08to09.sql
index 64640f4ce..8d463fab4 100644
--- a/db/08to09.sql
+++ b/db/08to09.sql
@@ -72,13 +72,4 @@ create table location_namespace (
created datetime not null comment 'date the record was created',
modified timestamp comment 'date this record was modified'
-) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
-
-create table login_token (
- user_id integer not null comment 'user owning this token' references user (id),
- token char(32) not null comment 'token useable for logging in',
- created datetime not null comment 'date this record was created',
- modified timestamp comment 'date this record was modified',
-
- constraint primary key (user_id)
-) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
+) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin; \ No newline at end of file
diff --git a/db/08to09_pg.sql b/db/08to09_pg.sql
index 233af82ef..b312d47dd 100644
--- a/db/08to09_pg.sql
+++ b/db/08to09_pg.sql
@@ -39,15 +39,6 @@ create table profile_role (
);
-create table login_token (
- user_id integer not null /* comment 'user owning this token'*/ references "user" (id),
- token char(32) not null /* comment 'token useable for logging in'*/,
- created timestamp not null DEFAULT CURRENT_TIMESTAMP /* comment 'date this record was created'*/,
- modified timestamp /* comment 'date this record was modified'*/,
-
- primary key (user_id)
-);
-
DROP index fave_user_id_idx;
CREATE index fave_user_id_idx on fave (user_id,modified);
diff --git a/db/statusnet.sql b/db/statusnet.sql
index 18abcdfdb..f7b3b113b 100644
--- a/db/statusnet.sql
+++ b/db/statusnet.sql
@@ -575,13 +575,3 @@ create table location_namespace (
modified timestamp comment 'date this record was modified'
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
-
-create table login_token (
- user_id integer not null comment 'user owning this token' references user (id),
- token char(32) not null comment 'token useable for logging in',
- created datetime not null comment 'date this record was created',
- modified timestamp comment 'date this record was modified',
-
- constraint primary key (user_id)
-) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
-
diff --git a/db/statusnet_pg.sql b/db/statusnet_pg.sql
index 81b329d1e..cd72d66ea 100644
--- a/db/statusnet_pg.sql
+++ b/db/statusnet_pg.sql
@@ -570,14 +570,4 @@ create table profile_role (
primary key (profile_id, role)
-);
-
-create table login_token (
- user_id integer not null /* comment 'user owning this token'*/ references "user" (id),
- token char(32) not null /* comment 'token useable for logging in'*/,
- created timestamp not null DEFAULT CURRENT_TIMESTAMP /* comment 'date this record was created'*/,
- modified timestamp /* comment 'date this record was modified'*/,
-
- primary key (user_id)
-);
-
+); \ No newline at end of file
diff --git a/lib/command.php b/lib/command.php
index 7e98156b6..bcc551c81 100644
--- a/lib/command.php
+++ b/lib/command.php
@@ -579,32 +579,6 @@ class OnCommand extends Command
}
}
-class LoginCommand extends Command
-{
- function execute($channel)
- {
- $login_token = Login_token::staticGet('user_id',$this->user->id);
- if($login_token){
- $login_token->delete();
- }
- $login_token = new Login_token();
- $login_token->user_id = $this->user->id;
- $login_token->token = common_good_rand(16);
- $login_token->created = common_sql_now();
- $result = $login_token->insert();
- if (!$result) {
- common_log_db_error($login_token, 'INSERT', __FILE__);
- $channel->error($this->user, sprintf(_('Could not create login token for %s'),
- $this->user->nickname));
- return;
- }
- $channel->output($this->user,
- sprintf(_('This link is useable only once, and is good for only 2 minutes: %s'),
- common_local_url('login',
- array('user_id'=>$login_token->user_id, 'token'=>$login_token->token))));
- }
-}
-
class SubscriptionsCommand extends Command
{
function execute($channel)
@@ -692,7 +666,6 @@ class HelpCommand extends Command
"reply #<notice_id> - reply to notice with a given id\n".
"reply <nickname> - reply to the last notice from user\n".
"join <group> - join group\n".
- "login - Get a link to login to the web interface\n".
"drop <group> - leave group\n".
"stats - get your stats\n".
"stop - same as 'off'\n".
diff --git a/lib/commandinterpreter.php b/lib/commandinterpreter.php
index 665015afc..25f2e4b3e 100644
--- a/lib/commandinterpreter.php
+++ b/lib/commandinterpreter.php
@@ -41,12 +41,6 @@ class CommandInterpreter
return null;
}
return new HelpCommand($user);
- case 'login':
- if ($arg) {
- return null;
- } else {
- return new LoginCommand($user);
- }
case 'subscribers':
if ($arg) {
return null;
diff --git a/lib/jabber.php b/lib/jabber.php
index a8e295ea5..01aed8ffa 100644
--- a/lib/jabber.php
+++ b/lib/jabber.php
@@ -176,7 +176,6 @@ function jabber_format_entry($profile, $notice)
$xs = new XMLStringer();
$xs->elementStart('html', array('xmlns' => 'http://jabber.org/protocol/xhtml-im'));
$xs->elementStart('body', array('xmlns' => 'http://www.w3.org/1999/xhtml'));
- $xs->element("img", array('src'=> $profile->avatarUrl(AVATAR_MINI_SIZE)));
$xs->element('a', array('href' => $profile->profileurl),
$profile->nickname);
$xs->text(": ");
diff --git a/lib/router.php b/lib/router.php
index b22185126..beb98eb04 100644
--- a/lib/router.php
+++ b/lib/router.php
@@ -88,8 +88,6 @@ class Router
$m->connect('doc/:title', array('action' => 'doc'));
- $m->connect('main/login?user_id=:user_id&token=:token', array('action'=>'login'), array('user_id'=> '[0-9]+', 'token'=>'.+'));
-
// main stuff is repetitive
$main = array('login', 'logout', 'register', 'subscribe',
diff --git a/plugins/InfiniteScroll/infinitescroll.js b/plugins/InfiniteScroll/infinitescroll.js
index 0dafef6d5..0c8edce2b 100644
--- a/plugins/InfiniteScroll/infinitescroll.js
+++ b/plugins/InfiniteScroll/infinitescroll.js
@@ -1,6 +1,6 @@
jQuery(document).ready(function($){
$('notices_primary').infinitescroll({
- debug: true,
+ debug: false,
infiniteScroll : false,
nextSelector : 'body#public li.nav_next a,'+
'body#all li.nav_next a,'+
diff --git a/plugins/Mapstraction/MapstractionPlugin.php b/plugins/Mapstraction/MapstractionPlugin.php
index 37306a23c..c0c2c5b8e 100644
--- a/plugins/Mapstraction/MapstractionPlugin.php
+++ b/plugins/Mapstraction/MapstractionPlugin.php
@@ -110,6 +110,11 @@ class MapstractionPlugin extends Plugin
function onEndShowScripts($action)
{
$actionName = $action->trimmed('action');
+ // These are the ones that have maps on 'em
+ if (!in_array($actionName,
+ array('showstream', 'all', 'allmap', 'usermap'))) {
+ return true;
+ }
switch ($this->provider)
{
@@ -146,6 +151,39 @@ class MapstractionPlugin extends Plugin
$action->raw(sprintf('var _provider = "%s";', $this->provider));
$action->elementEnd('script');
+ switch ($actionName) {
+ case 'usermap':
+ case 'showstream':
+ $notice = empty($action->tag)
+ ? $action->user->getNotices(($action->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1)
+ : $action->user->getTaggedNotices($action->tag, ($action->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1, 0, 0, null);
+ break;
+ case 'all':
+ case 'allmap':
+ $cur = common_current_user();
+ if (!empty($cur) && $cur->id == $action->user->id) {
+ $notice = $action->user->noticeInbox(($action->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1);
+ } else {
+ $notice = $action->user->noticesWithFriends(($action->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1);
+ }
+ break;
+ }
+
+ $jsonArray = array();
+
+ while ($notice->fetch()) {
+ if (!empty($notice->lat) && !empty($notice->lon)) {
+ $jsonNotice = $this->noticeAsJson($notice);
+ $jsonArray[] = $jsonNotice;
+ }
+ }
+
+ $action->elementStart('script', array('type' => 'text/javascript'));
+ $action->raw('/*<![CDATA[*/'); // XHTML compat for Safari
+ $action->raw('var _notices = ' . json_encode($jsonArray));
+ $action->raw('/*]]>*/'); // XHTML compat for Safari
+ $action->elementEnd('script');
+
return true;
}
@@ -176,4 +214,34 @@ class MapstractionPlugin extends Plugin
$action->elementEnd('div');
}
+
+ function noticeAsJson($notice)
+ {
+ // FIXME: this code should be abstracted to a neutral third
+ // party, like Notice::asJson(). I'm not sure of the ethics
+ // of refactoring from within a plugin, so I'm just abusing
+ // the ApiAction method. Don't do this unless you're me!
+
+ require_once(INSTALLDIR.'/lib/api.php');
+
+ $act = new ApiAction('/dev/null');
+
+ $arr = $act->twitterStatusArray($notice, true);
+ $arr['url'] = $notice->bestUrl();
+ $arr['html'] = $notice->rendered;
+ $arr['source'] = $arr['source'];
+
+ if (!empty($notice->reply_to)) {
+ $reply_to = Notice::staticGet('id', $notice->reply_to);
+ if (!empty($reply_to)) {
+ $arr['in_reply_to_status_url'] = $reply_to->bestUrl();
+ }
+ $reply_to = null;
+ }
+
+ $profile = $notice->getProfile();
+ $arr['user']['profile_url'] = $profile->profileurl;
+
+ return $arr;
+ }
}
diff --git a/plugins/Meteor/meteorupdater.js b/plugins/Meteor/meteorupdater.js
index 9ce68775b..cdd1d63fa 100644
--- a/plugins/Meteor/meteorupdater.js
+++ b/plugins/Meteor/meteorupdater.js
@@ -1,6 +1,4 @@
// Update the local timeline from a Meteor server
-// XXX: If @a is subscribed to @b, @a should get @b's notices in @a's Personal timeline.
-// Do Replies timeline.
var MeteorUpdater = function()
{
diff --git a/plugins/MobileProfile/MobileProfilePlugin.php b/plugins/MobileProfile/MobileProfilePlugin.php
index fd6057550..0b1e4de28 100644
--- a/plugins/MobileProfile/MobileProfilePlugin.php
+++ b/plugins/MobileProfile/MobileProfilePlugin.php
@@ -31,7 +31,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
exit(1);
}
-define('PAGE_TYPE_PREFS',
+define('PAGE_TYPE_PREFS_MOBILEPROFILE',
'application/vnd.wap.xhtml+xml, application/xhtml+xml, text/html;q=0.9');
require_once INSTALLDIR.'/plugins/Mobile/WAP20Plugin.php';
@@ -159,8 +159,7 @@ class MobileProfilePlugin extends WAP20Plugin
common_config('site', 'server'))) {
// FIXME: Redirect to equivalent page on mobile site instead
- header("Location: ".$this->_common_path(''));
- exit();
+ common_redirect($this->_common_path(''), 302);
}
}
@@ -173,7 +172,7 @@ class MobileProfilePlugin extends WAP20Plugin
$_SERVER['HTTP_ACCEPT'] : null;
$cp = common_accept_to_prefs($httpaccept);
- $sp = common_accept_to_prefs(PAGE_TYPE_PREFS);
+ $sp = common_accept_to_prefs(PAGE_TYPE_PREFS_MOBILEPROFILE);
$type = common_negotiate_type($cp, $sp);
diff --git a/plugins/Realtime/realtimeupdate.js b/plugins/Realtime/realtimeupdate.js
index 9ea5c3bce..ce0297339 100644
--- a/plugins/Realtime/realtimeupdate.js
+++ b/plugins/Realtime/realtimeupdate.js
@@ -281,6 +281,8 @@ RealtimeUpdate = {
return false;
});
+
+ $('#showstream .entity_profile').css({'width':'69%'});
}
}
diff --git a/plugins/UserFlag/UserFlagPlugin.php b/plugins/UserFlag/UserFlagPlugin.php
index 4717a63dd..60c0c2c0a 100644
--- a/plugins/UserFlag/UserFlagPlugin.php
+++ b/plugins/UserFlag/UserFlagPlugin.php
@@ -97,7 +97,7 @@ class UserFlagPlugin extends Plugin
{
$user = common_current_user();
- if (!empty($user)) {
+ if (!empty($user) && ($user->id != $profile->id)) {
$action->elementStart('li', 'entity_flag');
diff --git a/plugins/UserFlag/flagprofile.php b/plugins/UserFlag/flagprofile.php
index 8ff2f1f72..9bce7865b 100644
--- a/plugins/UserFlag/flagprofile.php
+++ b/plugins/UserFlag/flagprofile.php
@@ -72,6 +72,28 @@ class FlagprofileAction extends ProfileFormAction
return true;
}
+
+ /**
+ * Handle request
+ *
+ * Overriding the base Action's handle() here to deal check
+ * for Ajax and return an HXR response if necessary
+ *
+ * @param array $args $_REQUEST args; handled in prepare()
+ *
+ * @return void
+ */
+
+ function handle($args)
+ {
+ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
+ $this->handlePost();
+ if (!$this->boolean('ajax')) {
+ $this->returnToArgs();
+ }
+ }
+ }
+
/**
* Handle POST
*
@@ -97,6 +119,10 @@ class FlagprofileAction extends ProfileFormAction
}
$ufp->free();
+
+ if ($this->boolean('ajax')) {
+ $this->ajaxResults();
+ }
}
function ajaxResults() {
diff --git a/plugins/UserFlag/flagprofileform.php b/plugins/UserFlag/flagprofileform.php
index 262dad4a7..c20929a20 100644
--- a/plugins/UserFlag/flagprofileform.php
+++ b/plugins/UserFlag/flagprofileform.php
@@ -48,6 +48,18 @@ require_once INSTALLDIR.'/lib/form.php';
class FlagProfileForm extends ProfileActionForm
{
/**
+ * class of the form
+ * Action this form provides
+ *
+ * @return string class of the form
+ */
+
+ function formClass()
+ {
+ return 'form_entity_flag';
+ }
+
+ /**
* Action this form provides
*
* @return string Name of the action, lowercased.
diff --git a/scripts/updateavatarurl.php b/scripts/updateavatarurl.php
new file mode 100644
index 000000000..dfcfc118c
--- /dev/null
+++ b/scripts/updateavatarurl.php
@@ -0,0 +1,128 @@
+#!/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:n:a';
+$longoptions = array('id=', 'nickname=', 'all');
+
+$helptext = <<<END_OF_UPDATEAVATARURL_HELP
+updateavatarurl.php [options]
+update the URLs of all avatars in the system
+
+ -i --id ID of user to update
+ -n --nickname nickname of the user to update
+ -a --all update all
+
+END_OF_UPDATEAVATARURL_HELP;
+
+require_once INSTALLDIR.'/scripts/commandline.inc';
+
+try {
+ $user = null;
+
+ if (have_option('i', 'id')) {
+ $id = get_option_value('i', 'id');
+ $user = User::staticGet('id', $id);
+ if (empty($user)) {
+ throw new Exception("Can't find user with id '$id'.");
+ }
+ updateAvatars($user);
+ } else if (have_option('n', 'nickname')) {
+ $nickname = get_option_value('n', 'nickname');
+ $user = User::staticGet('nickname', $nickname);
+ if (empty($user)) {
+ throw new Exception("Can't find user with nickname '$nickname'");
+ }
+ updateAvatars($user);
+ } else if (have_option('a', 'all')) {
+ $user = new User();
+ if ($user->find()) {
+ while ($user->fetch()) {
+ updateAvatars($user);
+ }
+ }
+ } else {
+ throw new Exception("You have to provide an ID or nickname or 'all'.");
+ }
+} catch (Exception $e) {
+ print $e->getMessage()."\n";
+ exit(1);
+}
+
+function updateAvatars($user)
+{
+ $touched = false;
+
+ if (!have_option('q', 'quiet')) {
+ print "Updating avatars for user '".$user->nickname."' (".$user->id.")...";
+ }
+
+ $avatar = new Avatar();
+
+ $avatar->profile_id = $user->id;
+
+ if (!$avatar->find()) {
+ if (have_option('v', 'verbose')) {
+ print "(none found)...";
+ }
+ } else {
+ while ($avatar->fetch()) {
+ if (have_option('v', 'verbose')) {
+ if ($avatar->original) {
+ print "original...";
+ } else {
+ print $avatar->width."...";
+ }
+ }
+
+ $orig = clone($avatar);
+
+ $avatar->url = Avatar::url($avatar->filename);
+
+ if ($avatar->url != $orig->url) {
+ $sql =
+ "UPDATE avatar SET url = '" . $avatar->url . "' ".
+ "WHERE profile_id = " . $avatar->profile_id . " ".
+ "AND width = " . $avatar->width . " " .
+ "AND height = " . $avatar->height . " ";
+
+ if ($avatar->original) {
+ $sql .= "AND original = 1 ";
+ }
+
+ if (!$avatar->query($sql)) {
+ throw new Exception("Can't update avatar for user " . $user->nickname . ".");
+ } else {
+ $touched = true;
+ }
+ }
+ }
+ }
+
+ if ($touched) {
+ $profile = $user->getProfile();
+ common_broadcast_profile($profile);
+ }
+
+ if (have_option('v', 'verbose')) {
+ print "DONE.\n";
+ }
+}