X-Git-Url: http://git.polytechnique.org/?a=blobdiff_plain;ds=sidebyside;f=banana%2Fbanana.inc.php.in;h=f09dc2bf27ec0efa740c2d260039591684e7bf0d;hb=b2b4d61351dcec375a00d6507c73d7bb122b4074;hp=f4b19b0880e2d90150fc849ab9a8d9898f555b7b;hpb=57efc445e11b5420269ba7c4a90ae534ae44771f;p=banana.git diff --git a/banana/banana.inc.php.in b/banana/banana.inc.php.in index f4b19b0..f09dc2b 100644 --- a/banana/banana.inc.php.in +++ b/banana/banana.inc.php.in @@ -7,6 +7,8 @@ * Copyright: See COPYING files that comes with this distribution ********************************************************************************/ +require_once dirname(__FILE__) . '/text.func.inc.php'; + class Banana { @@ -19,13 +21,15 @@ class Banana 'headers' => array('From' => 'Anonymous '), 'display' => 0, 'lastnews' => 0, - 'locale' => 'fr_FR', + 'locale' => 'fr_FR.UTF-8', 'subscribe' => array(), 'autoup' => 1); static public $boxpattern; static public $withtabs = true; + static public $mimeparts = array(); ### Spool ### + static public $spool_root = '/var/spool/banana'; static public $spool_max = 3000; static public $spool_tbefore = 5; static public $spool_tafter = 5; @@ -42,10 +46,12 @@ class Banana ### Message display ### static public $msgshow_headers = array('from', 'newsgroups', 'followup-to', 'to', 'cc', 'reply-to', 'organization', 'date', 'references', 'in-reply-to'); - static public $msgshow_mimeparts = array('multipart/report', 'multipart/mixed', 'text/html', 'text/plain', 'text/enriched', 'text', 'message'); + static public $msgshow_mimeparts = array('multipart/report', 'multipart/mixed', + 'text/html', 'text/plain', 'text/enriched', 'text', 'message'); static public $msgshow_xface = true; - static public $msgshow_wrap = 78; + static public $msgshow_wrap = 80; static public $msgshow_externalimages = false; + static public $msgshow_hasextimages = false; static public $msgshow_withthread = true; /** Match an url @@ -59,7 +65,7 @@ class Banana * $matches[2] = "http://www.polytechnique.org" * $matches[3] = "]" */ - static public $msgshow_url = '(["\[])?((?:[a-z]+:\/\/|www\.)(?:[\.\,\;\!]*[a-z\@0-9~%$£µ&i#\-+=_\/\?]+)+)(["\]])?'; + static public $msgshow_url = '(["\[])?((?:[a-z]+:\/\/|www\.)(?:[\.\,\;\!\:]*[a-z\@0-9~%$£µ&i#\-+=_\/\?]+)+)(["\]])?'; ### Message edition ### static public $msgedit_canattach = true; @@ -71,15 +77,27 @@ class Banana */ static public $msgedit_mimeparts = array('multipart/report', 'multipart/mixed', 'text/plain', 'text/enriched', 'text/html', 'text', 'message'); +### Feed configuration ### + static public $feed_active = true; + static public $feed_format = 'rss2'; + static public $feed_updateOnDemand = false; // Update the feed each time sbd check it + static public $feed_copyright = null; // Global copyright informations + static public $feed_generator = 'Banana @VERSION@'; // Feed generator + static public $feed_email = null; // Admin e-mail + static public $feed_namePrefix = 'Banana :: '; + static public $feed_size = 15; // Number of messages in the feed + ### Protocole ### /** News serveur to use */ static public $nntp_host = 'news://localhost:119/'; static public $mbox_path = '/var/mail'; + static public $mbox_helper = './mbox-helper'; ### Debug ### static public $debug_nntp = false; + static public $debug_mbox = false; static public $debug_smarty = false; @@ -91,10 +109,12 @@ class Banana const ACTION_BOX_NEEDED = 1; // mask const ACTION_BOX_LIST = 2; const ACTION_BOX_SUBS = 4; + const ACTION_BOX_FEED = 8; const ACTION_MSG_LIST = 3; const ACTION_MSG_READ = 5; const ACTION_MSG_NEW = 9; const ACTION_MSG_CANCEL = 17; + const ACTION_MSG_IMAGES = 33; // Box list view const BOXES_ALL = 0; @@ -136,7 +156,6 @@ class Banana */ public function __construct($params = null, $protocole = 'NNTP', $pageclass = 'BananaPage') { - Banana::load('text.func'); if (is_null($params)) { $this->params = $_GET; } else { @@ -156,6 +175,16 @@ class Banana Banana::load('page'); } Banana::$page = new $pageclass; + $types = array('multipart/report' => _b_('Rapport d\'erreur'), + 'multipart/mixed' => _b_('Composition'), + 'text/html' => _b_('Texte formaté'), + 'text/plain' => _b_('Texte brut'), + 'text/enriched' => _b_('Texte enrichi'), + 'text' => _b_('Texte'), + 'message/rfc822' => _b_('Mail'), + 'message' => _b_('Message'), + 'source' => _b_('Source')); + Banana::$mimeparts = array_merge($types, Banana::$mimeparts); } /** Fill state vars (Banana::$group, Banana::$artid, Banana::$action, Banana;:$part, Banana::$first) @@ -167,16 +196,26 @@ class Banana Banana::$first = isset($this->params['first']) ? $this->params['first'] : null; Banana::$part = isset($this->params['part']) ? $this->params['part'] : 'text'; + $action = @$this->params['action']; + if ($action == 'rss' || $action == 'rss2' || $action == 'atom') { + if ($action == 'rss') { + $action = 'rss2'; + } + Banana::$feed_format = $action; + Banana::$action = Banana::ACTION_BOX_FEED; + return; + } + // Look for the action to execute if (is_null(Banana::$group)) { - if (isset($this->params['action']) && $this->params['action'] == 'subscribe') { + if ($action == 'subscribe') { Banana::$action = Banana::ACTION_BOX_SUBS; } else { Banana::$action = Banana::ACTION_BOX_LIST; } return; } - $action = isset($this->params['action']) ? $this->params['action'] : null; + if (is_null(Banana::$artid)) { if ($action == 'new') { Banana::$action = Banana::ACTION_MSG_NEW; @@ -192,6 +231,9 @@ class Banana case 'cancel': Banana::$action = Banana::ACTION_MSG_CANCEL; return; + case 'showext': + Banana::$action = Banana::ACTION_MSG_IMAGES; + return; default: Banana::$action = Banana::ACTION_MSG_READ; } @@ -214,7 +256,7 @@ class Banana return Banana::$page->kill(_b_('Connexion non-valide')); } if (Banana::$action & Banana::ACTION_BOX_NEEDED) { - if(Banana::$boxpattern && !preg_match('/' . Banana::$boxpattern . '/i', $group)) { + if(Banana::$boxpattern && !preg_match('/' . Banana::$boxpattern . '/i', Banana::$group)) { Banana::$page->setPage('group'); return Banana::$page->kill(_b_("Ce newsgroup n'existe pas ou vous n'avez pas l'autorisation d'y accéder")); } @@ -228,9 +270,14 @@ class Banana case Banana::ACTION_BOX_LIST: $error = $this->action_listBoxes(); break; + case Banana::ACTION_BOX_FEED: + $this->action_feed(); // generate its own xml + break; case Banana::ACTION_MSG_LIST: $error = $this->action_showThread(Banana::$group, Banana::$first); break; + case Banana::ACTION_MSG_IMAGES: + Banana::$msgshow_externalimages = true; case Banana::ACTION_MSG_READ: $error = $this->action_showMessage(Banana::$group, Banana::$artid, Banana::$part); break; @@ -251,6 +298,54 @@ class Banana return Banana::$page->run(); } + /** Build and post a new message + * @return postid (or -1 if the message has not been found) + */ + public function post($dest, $reply, $subject, $body) + { + $hdrs = Banana::$protocole->requestedHeaders(); + $headers = Banana::$profile['headers']; + $headers[$hdrs['dest']] = $dest; + if ($reply) { + $headers[$hdrs['reply']] = $reply; + } + $headers['Subject'] = $subject; + $msg = BananaMessage::newMessage($headers, $body); + if (Banana::$protocole->send($msg)) { + Banana::$group = ($reply ? $reply : $dest); + $this->loadSpool(Banana::$group); + return Banana::$spool->getPostId($subject); + } + return -1; + } + + /** Return the CSS code to include in the headers + */ + public function css() + { + return Banana::$page->css; + } + + /** Return the Link to the feed of the page + */ + public function feed() + { + if (!Banana::$feed_active) { + return null; + } + return Banana::$page->makeURL(array('group' => Banana::$group, 'action' => Banana::$feed_format)); + } + + /** Return the execution backtrace of the current BananaProtocole + */ + public function backtrace() + { + if (Banana::$protocole) { + return Banana::$protocole->backtrace(); + } + return null; + } + /**************************************************************************/ /* actions */ /**************************************************************************/ @@ -276,12 +371,39 @@ class Banana { Banana::$page->setPage('forums'); $groups = Banana::$protocole->getBoxList(Banana::BOXES_SUB, Banana::$profile['lastnews'], true); - $newgroups = Banana::$protocole->getBoxList(Banana::BOXES_NEW, Banana::$profile['lastnews'], true); Banana::$page->assign('groups', $groups); - Banana::$page->assign('newgroups', $newgroups); + if (empty(Banana::$profile['subscribe']) || Banana::$profile['lastnews']) { + $newgroups = Banana::$protocole->getBoxList(Banana::BOXES_NEW, Banana::$profile['lastnews'], true); + Banana::$page->assign('newgroups', $newgroups); + } return true; } + protected function action_feed() + { + Banana::load('feed'); + if (Banana::$group) { + if (Banana::$feed_updateOnDemand) { + $this->loadSpool(Banana::$group); + } + $feed =& BananaFeed::getFeed(); + $feed->toXML(); + } + if (Banana::$profile['subscribe']) { + $subfeed = null; + foreach (Banana::$profile['subscribe'] as $group) { + Banana::$group = $group; + if (Banana::$feed_updateOnDemand) { + $this->loadSpool($group); + } + $feed =& BananaFeed::getFeed(); + $subfeed =& BananaFeed::merge($subfeed, $feed, _b_('Abonnements'), _b_('Mes abonnements Banana')); + } + $subfeed->toXML(); + } + Banana::$page->feed(); + } + protected function action_showThread($group, $first) { Banana::$page->setPage('thread'); @@ -324,7 +446,8 @@ class Banana } exit; } elseif ($partid == 'text') { - Banana::$page->assign('body', $msg->getFormattedBody()); + $partid = null; + Banana::$page->assign('body', $msg->getFormattedBody($partid)); } elseif ($partid == 'source') { $text = Banana::$protocole->getMessageSource($artid); if (!is_utf8($text)) { @@ -343,7 +466,9 @@ class Banana Banana::$page->assign('groups', $groups); } Banana::$page->assign_by_ref('message', $msg); + Banana::$page->assign('extimages', Banana::$msgshow_hasextimages); Banana::$page->assign('headers', Banana::$msgshow_headers); + Banana::$page->assign('type', $partid); return true; } @@ -365,16 +490,25 @@ class Banana $hdr_values = array(); foreach ($hdrs as $header) { $hdr_values[$header] = isset($headers[$header]['fixed']) ? $headers[$header]['fixed'] : @$_POST[$header]; + if (!is_utf8($hdr_values[$header])) { + $hdr_values[$header] = utf8_encode($hdr_values[$header]); + } + if ($headers != 'Subject') { + $hdr_values[$header] = str_replace(', ', ',', $hdr_values[$header]); + } } - if ($artid) { + if (!is_null($artid)) { $old =& $this->loadMessage($group, $artid); $hdr_values['References'] = $old->getHeaderValue('references') . $old->getHeaderValue('message-id'); } $msg = null; + if (isset($_POST['body']) && !is_utf8($_POST['body'])) { + $_POST['body'] = utf8_encode($_POST['body']); + } if (empty($hdr_values['Subject'])) { Banana::$page->trig(_b_('Le message doit avoir un sujet')); - } elseif (Banana::$msgedit_canattach && isset($_FILES['attachment'])) { - $uploaded = $_FILES['attachment']; + } elseif (Banana::$msgedit_canattach && isset($_FILES['attachment']) && $_FILES['attachment']['name']) { + $uploaded =& $_FILES['attachment']; if (!is_uploaded_file($uploaded['tmp_name'])) { Banana::$page->trig(_b_('Une erreur est survenue lors du téléchargement du fichier')); } else { @@ -385,10 +519,13 @@ class Banana } if (!is_null($msg)) { if (Banana::$protocole->send($msg)) { - Banana::$page->redirect(array('group' => $group, 'artid' => $artid)); - } - Banana::$page->trig(_b_('Une erreur est survenue lors de l\'envoi du message :') . '
' + $this->loadSpool($group); + $newid = Banana::$spool->updateUnread(Banana::$profile['lastnews']); + Banana::$page->redirect(array('group' => $group, 'artid' => $newid ? $newid : $artid)); + } else { + Banana::$page->trig(_b_('Une erreur est survenue lors de l\'envoi du message :') . '
' . Banana::$protocole->lastError()); + } } } else { if (!is_null($artid)) { @@ -445,6 +582,83 @@ class Banana } /**************************************************************************/ + /* Spoolgen functions */ + /**************************************************************************/ + + private function checkErrors() + { + if (Banana::$protocole->lastErrno()) { + echo "\nL'erreur suivante s'est produite : " + . Banana::$protocole->lastErrno() . " " + . Banana::$protocole->lastError() . "\n"; + return false; + } + return true; + } + + static public function createAllSpool(array $protos) + { + foreach ($protos as $proto) { + $banana = new Banana(array(), $proto); + + if (!$banana->checkErrors()) { + continue; + } + $groups = Banana::$protocole->getBoxList(); + if (!$banana->checkErrors()) { + continue; + } + + print "** $proto **\n"; + foreach (array_keys($groups) as $g) { + print "Generating spool for $g: "; + Banana::$group = $g; + $spool = $banana->loadSpool($g); + if (!$banana->checkErrors()) { + break; + } + print "done.\n"; + unset($spool); + Banana::$spool = null; + } + print "\n"; + } + } + + static public function refreshAllFeeds(array $protos) + { + Banana::load('feed'); + Banana::$feed_updateOnDemand = true; // In order to force update + foreach ($protos as $proto) { + $banana = new Banana(array(), $proto); + + if (!$banana->checkErrors()) { + continue; + } + $groups = Banana::$protocole->getBoxList(); + if (!$banana->checkErrors()) { + continue; + } + + print "** $proto **\n"; + foreach (array_keys($groups) as $g) { + print "Generating feed cache for $g: "; + Banana::$group = $g; + $spool = $banana->loadSpool($g); + if (!$banana->checkErrors()) { + break; + } + $feed =& BananaFeed::getFeed(); + print "done.\n"; + unset($feed); + unset($spool); + Banana::$spool = null; + } + print "\n"; + } + } + + /**************************************************************************/ /* Private functions */ /**************************************************************************/ @@ -453,15 +667,23 @@ class Banana Banana::load('spool'); if (!Banana::$spool || Banana::$spool->group != $group) { $clean = false; - if ($group == @$_SESSION['banana_group'] && isset($_SESSION['banana_spool'])) { - Banana::$spool = unserialize($_SESSION['banana_spool']); - $clean = @(Banana::$profile['lastnews'] != $_SESSION['banana_lastnews']); + if (php_sapi_name() != 'cli') { + if ($group == @$_SESSION['banana_group'] && isset($_SESSION['banana_spool'])) { + Banana::$spool = unserialize($_SESSION['banana_spool']); + $clean = @(Banana::$profile['lastnews'] != $_SESSION['banana_lastnews']); + } else { + unset($_SESSION['banana_message']); + unset($_SESSION['banana_artid']); + unset($_SESSION['banana_showhdr']); + } } BananaSpool::getSpool($group, Banana::$profile['lastnews'], Banana::$profile['autoup'] || $clean); - $_SESSION['banana_group'] = $group; - if (!Banana::$profile['display']) { - $_SESSION['banana_spool'] = serialize(Banana::$spool); - $_SESSION['banana_lastnews'] = Banana::$profile['lastnews']; + if (php_sapi_name() != 'cli') { + $_SESSION['banana_group'] = $group; + if (!Banana::$profile['display']) { + $_SESSION['banana_spool'] = serialize(Banana::$spool); + $_SESSION['banana_lastnews'] = Banana::$profile['lastnews']; + } } Banana::$spool->setMode(Banana::$profile['display'] ? Banana::SPOOL_UNREAD : Banana::SPOOL_ALL); } @@ -492,13 +714,14 @@ class Banana if ($group == $_SESSION['banana_group']) { if (!Banana::$profile['display']) { $_SESSION['banana_spool'] = serialize(Banana::$spool); - } + } if ($artid == $_SESSION['banana_artid']) { unset($_SESSION['banana_message']); unset($_SESSION['banana_showhdr']); unset($_SESSION['banana_artid']); } } + $this->loadSpool($group); return true; }