Projects
Kolab:3.4
roundcubemail-plugins-kolab
Log In
Username
Password
We truncated the diff of some files because they were too big. If you want to see the full diff for every file,
click here
.
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 31
View file
roundcubemail-plugins-kolab.spec
Changed
@@ -23,7 +23,7 @@ %global roundcube_lib %{_var}/lib/roundcubemail Name: roundcubemail-plugins-kolab -Version: 3.1.7 +Version: 3.1.8 Release: 1%{?dist} Summary: Kolab Groupware plugins for Roundcube Webmail @@ -38,6 +38,7 @@ BuildArch: noarch Requires: php-kolabformat >= 1.0 +Requires: php-kolab >= 0.5 Requires: php-pear(HTTP_Request2) Requires: roundcubemail >= 1.0 Obsoletes: roundcubemail-kolab < %{version}-%{release} @@ -208,6 +209,9 @@ %attr(0770,root,%{httpd_group}) %{roundcube_lib}/plugins/odfviewer %changelog +* Mon Nov 25 2013 Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> - 3.1.8-1 +- New upstream version + * Mon Nov 11 2013 Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> - 3.1.7-1 - Extend xml column for photo and crypt keys - Fix SQL syntax when purging a folder
View file
debian.changelog
Changed
@@ -1,3 +1,9 @@ +roundcubemail-plugins-kolab (1:3.1.8-0~kolab1) unstable; urgency=low + + * New upstream release + + -- Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> Mon, 25 Nov 2013 18:41:13 +0200 + roundcubemail-plugins-kolab (1:3.1.7-0~kolab2) unstable; urgency=low * If both kolab.inc.php and libkolab.inc.php exist (in postinst), make sure only libkolab.inc.php exists
View file
roundcubemail-plugins-kolab-3.1.7.tar.gz/plugins/calendar/calendar.php -> roundcubemail-plugins-kolab-3.1.8.tar.gz/plugins/calendar/calendar.php
Changed
@@ -88,15 +88,6 @@ require($this->home . '/lib/calendar_ui.php'); $this->ui = new calendar_ui($this); - // load Calendar user interface which includes jquery-ui - if (!$this->rc->output->ajax_call && !$this->rc->output->env['framed']) { - $this->ui->init(); - - // settings are required in (almost) every GUI step - if ($this->rc->action != 'attend') - $this->rc->output->set_env('calendar_settings', $this->load_settings()); - } - // catch iTIP confirmation requests that don're require a valid session if ($this->rc->action == 'attend' && !empty($_REQUEST['_t'])) { $this->add_hook('startup', array($this, 'itip_attend_response')); @@ -104,8 +95,32 @@ else if ($this->rc->action == 'feed' && !empty($_REQUEST['_cal'])) { $this->add_hook('startup', array($this, 'ical_feed_export')); } - else if ($this->rc->task == 'calendar' && $this->rc->action != 'save-pref') { - if ($this->rc->action != 'upload') { + else { + // default startup routine + $this->add_hook('startup', array($this, 'startup')); + } + } + + /** + * Startup hook + */ + public function startup($args) + { + // the calendar module can be enabled/disabled by the kolab_auth plugin + if ($this->rc->config->get('calendar_disabled', false) || !$this->rc->config->get('calendar_enabled', true)) + return; + + // load Calendar user interface + if (!$this->rc->output->ajax_call && !$this->rc->output->env['framed']) { + $this->ui->init(); + + // settings are required in (almost) every GUI step + if ($args['action'] != 'attend') + $this->rc->output->set_env('calendar_settings', $this->load_settings()); + } + + if ($args['task'] == 'calendar' && $args['action'] != 'save-pref') { + if ($args['action'] != 'upload') { $this->load_driver(); } @@ -138,19 +153,19 @@ } } } - else if ($this->rc->task == 'settings') { + else if ($args['task'] == 'settings') { // add hooks for Calendar settings $this->add_hook('preferences_sections_list', array($this, 'preferences_sections_list')); $this->add_hook('preferences_list', array($this, 'preferences_list')); $this->add_hook('preferences_save', array($this, 'preferences_save')); } - else if ($this->rc->task == 'mail') { + else if ($args['task'] == 'mail') { // hooks to catch event invitations on incoming mails - if ($this->rc->action == 'show' || $this->rc->action == 'preview') { + if ($args['action'] == 'show' || $args['action'] == 'preview') { $this->add_hook('message_load', array($this, 'mail_message_load')); $this->add_hook('template_object_messagebody', array($this, 'mail_messagebody_html')); } - + // add 'Create event' item to message menu if ($this->api->output->type == 'html') { $this->api->add_content(html::tag('li', null, @@ -167,7 +182,7 @@ $this->api->output->add_label('calendar.createfrommail'); } } - + // add hooks to display alarms $this->add_hook('pending_alarms', array($this, 'pending_alarms')); $this->add_hook('dismiss_alarms', array($this, 'dismiss_alarms')); @@ -928,27 +943,24 @@ public function refresh($attr) { // refresh the entire calendar every 10th time to also sync deleted events - $refetch = rand(0,10) == 10; + if (rand(0,10) == 10) { + $this->rc->output->command('plugin.refresh_calendar', array('refetch' => true)); + return; + } foreach ($this->driver->list_calendars(true) as $cal) { - if ($refetch) { - $this->rc->output->command('plugin.refresh_calendar', - array('source' => $cal['id'], 'refetch' => true)); - } - else { - $events = $this->driver->load_events( - get_input_value('start', RCUBE_INPUT_GET), - get_input_value('end', RCUBE_INPUT_GET), - get_input_value('q', RCUBE_INPUT_GET), - $cal['id'], - 1, - $attr['last'] - ); + $events = $this->driver->load_events( + get_input_value('start', RCUBE_INPUT_GET), + get_input_value('end', RCUBE_INPUT_GET), + get_input_value('q', RCUBE_INPUT_GET), + $cal['id'], + 1, + $attr['last'] + ); - foreach ($events as $event) { - $this->rc->output->command('plugin.refresh_calendar', - array('source' => $cal['id'], 'update' => $this->_client_event($event))); - } + foreach ($events as $event) { + $this->rc->output->command('plugin.refresh_calendar', + array('source' => $cal['id'], 'update' => $this->_client_event($event))); } } }
View file
roundcubemail-plugins-kolab-3.1.7.tar.gz/plugins/calendar/calendar_ui.js -> roundcubemail-plugins-kolab-3.1.8.tar.gz/plugins/calendar/calendar_ui.js
Changed
@@ -2103,6 +2103,10 @@ if (me.fisheye_date) me.fisheye_view(me.fisheye_date); } + // refetch all calendars + else if (p.refetch) { + fc.fullCalendar('refetchEvents'); + } // remove temp events fc.fullCalendar('removeEvents', function(e){ return e.temp; });
View file
roundcubemail-plugins-kolab-3.1.7.tar.gz/plugins/calendar/drivers/kolab/kolab_driver.php -> roundcubemail-plugins-kolab-3.1.8.tar.gz/plugins/calendar/drivers/kolab/kolab_driver.php
Changed
@@ -110,7 +110,7 @@ // include virtual folders for a full folder tree if (!$active && !$personal && !$this->rc->output->ajax_call && in_array($this->rc->action, array('index',''))) - $folders = $this->_folder_hierarchy($folders, $this->rc->get_storage()->get_hierarchy_delimiter()); + $folders = kolab_storage::folder_hierarchy($folders); foreach ($folders as $id => $cal) { $fullname = $cal->get_name(); @@ -148,39 +148,6 @@ } /** - * Check the folder tree and add the missing parents as virtual folders - */ - private function _folder_hierarchy($folders, $delim) - { - $parents = array(); - $existing = array_map(function($folder){ return $folder->get_name(); }, $folders); - foreach ($folders as $id => $folder) { - $path = explode($delim, $folder->name); - array_pop($path); - - // skip top folders or ones with a custom displayname - if (count($path) <= 1 || kolab_storage::custom_displayname($folder->name)) - continue; - - while (count($path) > 1 && ($parent = join($delim, $path))) { - if (!in_array($parent, $existing) && !$parents[$parent]) { - $name = kolab_storage::object_name($parent, $folder->get_namespace()); - $parents[$parent] = new virtual_kolab_calendar($name, $folder->get_namespace()); - $parents[$parent]->id = kolab_storage::folder_id($parent); - } - array_pop($path); - } - } - - // add virtual parents to the list and sort again - if (count($parents)) { - $folders = kolab_storage::sort_folders(array_merge($folders, array_values($parents))); - } - - return $folders; - } - - /** * Get list of calendars according to specified filters * * @param bool $writeable Return only writeable calendars @@ -1278,32 +1245,3 @@ } } - - -/** - * Helper class that represents a virtual IMAP folder - * with a subset of the kolab_calendar API. - */ -class virtual_kolab_calendar -{ - public $name; - public $namespace; - public $virtual = true; - - public function __construct($name, $ns) - { - $this->name = $name; - $this->namespace = $ns; - } - - public function get_name() - { - return $this->name; - } - - public function get_namespace() - { - return $this->namespace; - } -} -
View file
roundcubemail-plugins-kolab-3.1.7.tar.gz/plugins/calendar/skins/larry/calendar.css -> roundcubemail-plugins-kolab-3.1.8.tar.gz/plugins/calendar/skins/larry/calendar.css
Changed
@@ -158,7 +158,7 @@ } #calendarslist li.virtual { - padding-top: 2px; + height: 12px; } #calendarslist li label { @@ -231,6 +231,7 @@ #calendarslist li.virtual span.calname { color: #aaa; + top: 2px; } #calfeedurl,
View file
roundcubemail-plugins-kolab-3.1.7.tar.gz/plugins/libcalendaring/libvcalendar.php -> roundcubemail-plugins-kolab-3.1.8.tar.gz/plugins/libcalendaring/libvcalendar.php
Changed
@@ -557,7 +557,6 @@ switch ($prop->name) { case 'TRIGGER': foreach ($prop->parameters as $param) { - console(strval($param->name), strval($param->value)); if ($param->name == 'VALUE' && $param->value == 'DATE-TIME') { $trigger = '@' . $prop->getDateTime()->format('U'); }
View file
roundcubemail-plugins-kolab-3.1.7.tar.gz/plugins/libkolab/lib/kolab_format.php -> roundcubemail-plugins-kolab-3.1.8.tar.gz/plugins/libkolab/lib/kolab_format.php
Changed
@@ -123,7 +123,7 @@ if (!$dateonly) $result->setTime($datetime->format('G'), $datetime->format('i'), $datetime->format('s')); - if ($tz && in_array($tz->getName(), array('UTC','GMT','+00:00'))) + if ($tz && in_array($tz->getName(), array('UTC', 'GMT', '+00:00', 'Z'))) $result->setUTC(true); else if ($tz !== false) $result->setTimezone($tz->getName());
View file
roundcubemail-plugins-kolab-3.1.7.tar.gz/plugins/libkolab/lib/kolab_storage.php -> roundcubemail-plugins-kolab-3.1.8.tar.gz/plugins/libkolab/lib/kolab_storage.php
Changed
@@ -433,13 +433,14 @@ // get username $pos = strpos($folder, $delim); if ($pos) { - $prefix = '('.substr($folder, 0, $pos).') '; + $prefix = '('.substr($folder, 0, $pos).')'; $folder = substr($folder, $pos+1); } else { - $prefix = '('.$folder.')'; + $prefix = $folder; $folder = ''; } + $found = true; $folder_ns = 'other'; break; @@ -467,7 +468,7 @@ $folder = str_replace(html::quote($delim), ' » ', $folder); if ($prefix) - $folder = html::quote($prefix) . ' ' . $folder; + $folder = html::quote($prefix) . ($folder !== '' ? ' ' . $folder : ''); if (!$folder_ns) $folder_ns = 'personal'; @@ -492,7 +493,8 @@ } /** - * Helper method to generate a truncated folder name to display + * Helper method to generate a truncated folder name to display. + * Note: $origname is a string returned by self::object_name() */ public static function folder_displayname($origname, &$names) { @@ -504,10 +506,29 @@ $length = strlen($names[$i] . ' » '); $prefix = substr($name, 0, $length); $count = count(explode(' » ', $prefix)); - $name = str_repeat(' ', $count-1) . '» ' . substr($name, $length); + $diff = 1; + + // check if prefix folder is in other users namespace + for ($n = count($names)-1; $n >= 0; $n--) { + if (strpos($prefix, '(' . $names[$n] . ') ') === 0) { + $diff = 0; + break; + } + } + + $name = str_repeat(' ', $count - $diff) . '» ' . substr($name, $length); + break; + } + // other users namespace and parent folder exists + else if (strpos($name, '(' . $names[$i] . ') ') === 0) { + $length = strlen('(' . $names[$i] . ') '); + $prefix = substr($name, 0, $length); + $count = count(explode(' » ', $prefix)); + $name = str_repeat(' ', $count) . '» ' . substr($name, $length); break; } } + $names[] = $origname; return $name; @@ -525,8 +546,8 @@ */ public static function folder_selector($type, $attrs, $current = '') { - // get all folders of specified type - $folders = self::get_folders($type, false); + // get all folders of specified type (sorted) + $folders = self::get_folders($type, true); $delim = self::$imap->get_hierarchy_delimiter(); $names = array(); @@ -540,13 +561,15 @@ // Filter folders list foreach ($folders as $c_folder) { $name = $c_folder->name; + // skip current folder and it's subfolders if ($len && ($name == $current || strpos($name, $current.$delim) === 0)) { continue; } // always show the parent of current folder - if ($p_len && $name == $parent) { } + if ($p_len && $name == $parent) { + } // skip folders where user have no rights to create subfolders else if ($c_folder->get_owner() != $_SESSION['username']) { $rights = $c_folder->get_myrights(); @@ -555,17 +578,14 @@ } } - $names[$name] = self::object_name($name); - } + // Make sure parent folder is listed (might be skipped e.g. if it's namespace root) + if ($p_len && !isset($names[$parent]) && strpos($name, $parent.$delim) === 0) { + $names[$parent] = self::object_name($parent); + } - // Make sure parent folder is listed (might be skipped e.g. if it's namespace root) - if ($p_len && !isset($names[$parent])) { - $names[$parent] = self::object_name($parent); + $names[$name] = self::object_name($name); } - // Sort folders list - asort($names, SORT_LOCALE_STRING); - // Build SELECT field of parent folder $attrs['is_escaped'] = true; $select = new html_select($attrs); @@ -643,7 +663,8 @@ unset($folderdata[$folder]); } } - return array_keys($folderdata); + + return self::$imap->sort_folder_list(array_keys($folderdata), true); } // Get folders list @@ -683,26 +704,74 @@ */ public static function sort_folders($folders) { - $pad = ' '; + $pad = ' '; + $out = array(); $nsnames = array('personal' => array(), 'shared' => array(), 'other' => array()); + foreach ($folders as $folder) { $folders[$folder->name] = $folder; $ns = $folder->get_namespace(); $nsnames[$ns][$folder->name] = strtolower(html_entity_decode(self::object_name($folder->name, $ns), ENT_COMPAT, RCUBE_CHARSET)) . $pad; // decode » } - $names = array(); - foreach ($nsnames as $ns => $dummy) { - asort($nsnames[$ns], SORT_LOCALE_STRING); - $names += $nsnames[$ns]; + // $folders is a result of get_folders() we can assume folders were already sorted + foreach (array_keys($nsnames) as $ns) { + // asort($nsnames[$ns], SORT_LOCALE_STRING); + foreach (array_keys($nsnames[$ns]) as $utf7name) { + $out[] = $folders[$utf7name]; + } } - $out = array(); - foreach ($names as $utf7name => $name) { - $out[] = $folders[$utf7name]; + return $out; + } + + + /** + * Check the folder tree and add the missing parents as virtual folders + * + * @param array $folders Folders list + * + * @return array Folders list + */ + public static function folder_hierarchy($folders) + { + $_folders = array(); + $existing = array_map(function($folder){ return $folder->get_name(); }, $folders); + $delim = rcube::get_instance()->get_storage()->get_hierarchy_delimiter(); + + foreach ($folders as $idx => $folder) { + $path = explode($delim, $folder->name); + array_pop($path); + + // skip top folders or ones with a custom displayname + if (count($path) <= 1 || kolab_storage::custom_displayname($folder->name)) { + } + else { + $parents = array(); + + while (count($path) > 1 && ($parent = join($delim, $path))) { + $name = kolab_storage::object_name($parent, $folder->get_namespace()); + if (!in_array($name, $existing)) { + $parents[$parent] = new virtual_kolab_storage_folder($parent, $name, $folder->get_namespace()); + $existing[] = $name; + } + + array_pop($path); + } + + if (!empty($parents)) { + $parents = array_reverse(array_values($parents)); + foreach ($parents as $parent) { + $_folders[] = $parent; + }
View file
roundcubemail-plugins-kolab-3.1.7.tar.gz/plugins/libkolab/lib/kolab_storage_cache.php -> roundcubemail-plugins-kolab-3.1.8.tar.gz/plugins/libkolab/lib/kolab_storage_cache.php
Changed
@@ -117,6 +117,15 @@ } /** + * Getter for the numeric ID used in cache tables + */ + public function get_folder_id() + { + $this->_read_folder_data(); + return $this->folder_id; + } + + /** * Synchronize local cache data with remote */ public function synchronize() @@ -341,7 +350,7 @@ $this->db->query( "UPDATE $this->cache_table SET folder_id=?, msguid=? ". "WHERE folder_id=? AND msguid=?", - $target->folder_id, + $target->cache->get_folder_id(), $new_msguid, $this->folder_id, $msguid
View file
roundcubemail-plugins-kolab-3.1.7.tar.gz/plugins/libkolab/lib/kolab_storage_folder.php -> roundcubemail-plugins-kolab-3.1.8.tar.gz/plugins/libkolab/lib/kolab_storage_folder.php
Changed
@@ -280,7 +280,7 @@ } // generate a folder UID and set it to IMAP - $uid = rtrim(chunk_split(md5($this->name . $this->get_owner()), 12, '-'), '-'); + $uid = rtrim(chunk_split(md5($this->name . $this->get_owner() . uniqid('-', true)), 12, '-'), '-'); $this->set_uid($uid); return $uid;
View file
roundcubemail-plugins-kolab-3.1.7.tar.gz/plugins/odfviewer/odfviewer.php -> roundcubemail-plugins-kolab-3.1.8.tar.gz/plugins/odfviewer/odfviewer.php
Changed
@@ -74,7 +74,8 @@ { if (!$args['download'] && $args['mimetype'] && in_array($args['mimetype'], $this->odf_mimetypes)) { if (empty($_GET['_load'])) { - $suffix = preg_match('/(\.\w+)$/', $args['part']->filename, $m) ? $m[1] : '.odt'; + $exts = rcube_mime::get_mime_extensions($args['mimetype']); + $suffix = $exts ? '.'.$exts[0] : '.odt'; $fn = md5(session_id() . $_SERVER['REQUEST_URI']) . $suffix; // FIXME: copy file to disk because only apache can send the file correctly
View file
roundcubemail-plugins-kolab-3.1.7.tar.gz/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php -> roundcubemail-plugins-kolab-3.1.8.tar.gz/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php
Changed
@@ -85,7 +85,7 @@ // include virtual folders for a full folder tree if (!$this->rc->output->ajax_call && in_array($this->rc->action, array('index',''))) - $folders = $this->_folder_hierarchy($folders, $delim); + $folders = kolab_storage::folder_hierarchy($folders); foreach ($folders as $folder) { $utf7name = $folder->name; @@ -94,7 +94,7 @@ $editname = rcube_charset::convert(array_pop($path_imap), 'UTF7-IMAP'); // pop off raw name part $path_imap = join($delim, $path_imap); - $fullname = kolab_storage::object_name($utf7name); + $fullname = $folder->get_name(); $listname = kolab_storage::folder_displayname($fullname, $listnames); // special handling for virtual folders @@ -148,38 +148,6 @@ } /** - * Check the folder tree and add the missing parents as virtual folders - */ - private function _folder_hierarchy($folders, $delim) - { - $parents = array(); - $existing = array_map(function($folder){ return $folder->name; }, $folders); - foreach ($folders as $id => $folder) { - $path = explode($delim, $folder->name); - array_pop($path); - - // skip top folders or ones with a custom displayname - if (count($path) <= 1 || kolab_storage::custom_displayname($folder->name)) - continue; - - while (count($path) > 1 && ($parent = join($delim, $path))) { - if (!in_array($parent, $existing) && !$parents[$parent]) { - $parents[$parent] = new virtual_kolab_storage_folder($parent, $folder->get_namespace()); - } - array_pop($path); - } - } - - // add virtual parents to the list and sort again - if (count($parents)) { - $folders = kolab_storage::sort_folders(array_merge($folders, array_values($parents))); - } - - return $folders; - } - - - /** * Get a list of available task lists from this source */ public function get_lists() @@ -905,26 +873,3 @@ } } - -/** - * Helper class that represents a virtual IMAP folder - * with a subset of the kolab_storage_folder API. - */ -class virtual_kolab_storage_folder -{ - public $name; - public $namespace; - public $virtual = true; - - public function __construct($name, $ns) - { - $this->name = $name; - $this->namespace = $ns; - } - - public function get_namespace() - { - return $this->namespace; - } -} -
View file
roundcubemail-plugins-kolab-3.1.7.tar.gz/plugins/tasklist/skins/larry/tasklist.css -> roundcubemail-plugins-kolab-3.1.8.tar.gz/plugins/tasklist/skins/larry/tasklist.css
Changed
@@ -226,8 +226,7 @@ } #tasklists li.virtual { - padding-top: 4px; - height: 16px; + height: 12px; } #tasklists li label { @@ -293,6 +292,7 @@ #tasklists li.virtual span.listname { color: #aaa; + top: 2px; } #tasklists li.virtual span.handle {
View file
roundcubemail-plugins-kolab-3.1.7.tar.gz/plugins/tasklist/tasklist.php -> roundcubemail-plugins-kolab-3.1.8.tar.gz/plugins/tasklist/tasklist.php
Changed
@@ -71,13 +71,26 @@ // load plugin configuration $this->load_config(); + $this->timezone = $this->lib->timezone; + + // proceed initialization in startup hook + $this->add_hook('startup', array($this, 'startup')); + } + + /** + * Startup hook + */ + public function startup($args) + { + // the tasks module can be enabled/disabled by the kolab_auth plugin + if ($this->rc->config->get('tasklist_disabled', false) || !$this->rc->config->get('tasklist_enabled', true)) + return; + // load localizations - $this->add_texts('localization/', $this->rc->task == 'tasks' && (!$this->rc->action || $this->rc->action == 'print')); + $this->add_texts('localization/', $args['task'] == 'tasks' && (!$args['action'] || $args['action'] == 'print')); $this->rc->load_language($_SESSION['language'], array('tasks.tasks' => $this->gettext('navtitle'))); // add label for task title - $this->timezone = $this->lib->timezone; - - if ($this->rc->task == 'tasks' && $this->rc->action != 'save-pref') { + if ($args['task'] == 'tasks' && $args['action'] != 'save-pref') { $this->load_driver(); // register calendar actions @@ -94,9 +107,9 @@ $this->collapsed_tasks = array_filter(explode(',', $this->rc->config->get('tasklist_collapsed_tasks', ''))); } - else if ($this->rc->task == 'mail') { + else if ($args['task'] == 'mail') { // TODO: register hooks to catch ical/vtodo email attachments - if ($this->rc->action == 'show' || $this->rc->action == 'preview') { + if ($args['action'] == 'show' || $args['action'] == 'preview') { // $this->add_hook('message_load', array($this, 'mail_message_load')); // $this->add_hook('template_object_messagebody', array($this, 'mail_messagebody_html')); }
View file
roundcubemail-plugins-kolab.dsc
Changed
@@ -2,7 +2,7 @@ Source: roundcubemail-plugins-kolab Binary: roundcubemail-plugins-kolab Architecture: all -Version: 1:3.1.7-0~kolab2 +Version: 1:3.1.8-0~kolab1 Maintainer: Christoph Wickert <wickert@kolabsys.com> Uploaders: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com>, Paul Klos <kolab@klos2day.nl> Standards-Version: 3.9.3 @@ -10,5 +10,5 @@ Package-List: roundcubemail-plugins-kolab deb web extra Files: - 00000000000000000000000000000000 0 roundcubemail-plugins-kolab-3.1.7.tar.gz + 00000000000000000000000000000000 0 roundcubemail-plugins-kolab-3.1.8.tar.gz 00000000000000000000000000000000 0 debian.tar.gz
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.