Projects
Kolab:16
pykolab
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 23
View file
pykolab.spec
Changed
@@ -29,7 +29,7 @@ Summary: Kolab Groupware Solution Name: pykolab -Version: 0.8.9 +Version: 0.8.10 Release: 1%{?dist} License: GPLv3+ Group: Applications/System @@ -584,6 +584,9 @@ %attr(0700,%{kolab_user},%{kolab_group}) %dir %{_var}/spool/pykolab/wallace %changelog +* Fri Jul 27 2018 Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> - 0.8.10-1 +- Release of version 0.8.10 + * Thu May 17 2018 Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> - 0.8.9-1 - Release of version 0.8.9
View file
debian.changelog
Changed
@@ -1,4 +1,16 @@ -pykolab (0.8.8-0~kolab1) unstable; urgency=low +pykolab (0.8.10-0~kolab2) unstable; urgency=low + + * Correct dependencies for Ubuntu 18.04 + + -- Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> Wed, 3 Oct 2018 01:49:00 +0100 + +pykolab (0.8.10-0~kolab1) unstable; urgency=low + + * Upstream release of version 0.8.10 + + -- Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> Fri, 27 Jul 2018 01:49:00 +0100 + +pykolab (0.8.9-0~kolab1) unstable; urgency=low * Upstream release of version 0.8.9
View file
debian.control
Changed
@@ -15,7 +15,7 @@ libglib2.0-dev, libpcre3, libssl-dev, - libunistring0, + libunistring2 | libunistring0, libxml-parser-perl, libxml2, mime-support,
View file
pykolab-0.8.9.tar.gz/bin/kolab_smtp_access_policy.py -> pykolab-0.8.10.tar.gz/bin/kolab_smtp_access_policy.py
Changed
@@ -89,8 +89,8 @@ Column('id', Integer, Sequence('seq_id_result'), primary_key=True), Column('key', String(16), nullable=False), Column('value', Boolean, nullable=False), - Column('sender', String(64), nullable=True), - Column('recipient', String(64), nullable=False), + Column('sender', String(254), nullable=True), + Column('recipient', String(254), nullable=False), Column('sasl_username', String(64)), Column('sasl_sender', String(64)), Column('created', Integer, nullable=False), @@ -133,8 +133,8 @@ statistic_table = Table( 'statistic', metadata, Column('id', Integer, Sequence('seq_id_statistic'), primary_key=True), - Column('sender', String(64), nullable=False), - Column('recipient', String(64), nullable=False), + Column('sender', String(254), nullable=False), + Column('recipient', String(254), nullable=False), Column('date', Date, nullable=False), Column('count', Integer, nullable=False), ) @@ -1219,6 +1219,12 @@ else: engine = create_engine(cache_uri, echo=False) + if conf.drop_tables: + log.info(_("Dropping caching tables from database")) + policy_result_table.drop(engine, checkfirst=True) + statistic_table.drop(engine, checkfirst=True) + return False + try: metadata.create_all(engine) except sqlalchemy.exc.OperationalError, e: @@ -1594,6 +1600,13 @@ _("Access Policy Options") ) + access_policy_group.add_option( "--drop-tables", + dest = "drop_tables", + action = "store_true", + default = False, + help = _("Drop the caching tables from the " + \ + "database and exit.")) + access_policy_group.add_option( "--timeout", dest = "timeout", action = "store", @@ -1626,6 +1639,9 @@ policy_requests = {} + if conf.drop_tables: + sys.exit(0) + # Start the work while True: policy_request = read_request_input()
View file
pykolab-0.8.9.tar.gz/configure.ac -> pykolab-0.8.10.tar.gz/configure.ac
Changed
@@ -1,4 +1,4 @@ -AC_INIT([pykolab], 0.8.9) +AC_INIT([pykolab], 0.8.10) AC_SUBST([RELEASE], 1) AC_CONFIG_SRCDIR(pykolab/constants.py.in)
View file
pykolab-0.8.9.tar.gz/pykolab/imap/cyrus.py -> pykolab-0.8.10.tar.gz/pykolab/imap/cyrus.py
Changed
@@ -195,7 +195,7 @@ ) # TODO: Workaround for undelete - if len(self.lm(mailfolder)) < 1 and _mailfolder['hex_timestamp']: + if len(self.lm(mailfolder)) < 1 and 'hex_timestamp' in _mailfolder: mailfolder = self.folder_utf7("DELETED/%s%s%s@%s" % ( self.separator.join(_mailfolder['path_parts']), self.separator,
View file
pykolab-0.8.9.tar.gz/pykolab/itip/__init__.py -> pykolab-0.8.10.tar.gz/pykolab/itip/__init__.py
Changed
@@ -106,9 +106,12 @@ itip['duration'] = c['duration'].dt itip['end'] = itip['start'] + c['duration'].dt - itip['organizer'] = c['organizer'] + # Outlook can send itip replies with no organizer property + if c.has_key('organizer'): + itip['organizer'] = c['organizer'] - itip['attendees'] = c['attendee'] + if c.has_key('attendee'): + itip['attendees'] = c['attendee'] if itip.has_key('attendees') and not isinstance(itip['attendees'], list): itip['attendees'] = [c['attendee']]
View file
pykolab-0.8.9.tar.gz/pykolab/xml/event.py -> pykolab-0.8.10.tar.gz/pykolab/xml/event.py
Changed
@@ -19,6 +19,7 @@ from attendee import Attendee from contact_reference import ContactReference from recurrence_rule import RecurrenceRule +from collections import OrderedDict log = pykolab.getLogger('pykolab.xml_event') @@ -367,7 +368,8 @@ self.set_from_ical(attr.lower(), ical_event[attr]) # NOTE: Make sure to list(set()) or duplicates may arise - for attr in list(set(ical_event.singletons)): + # NOTE: Keep the original order e.g. to read DTSTART before RECURRENCE-ID + for attr in list(OrderedDict.fromkeys(ical_event.singletons)): if ical_event.has_key(attr): if isinstance(ical_event[attr], list): ical_event[attr] = ical_event[attr][0]; @@ -815,7 +817,7 @@ if classification in self.classification_map.keys(): self.event.setClassification(self.classification_map[classification]) elif classification in self.classification_map.values(): - self.event.setClassification(status) + self.event.setClassification(classification) else: raise ValueError, _("Invalid classification %r") % (classification)
View file
pykolab-0.8.9.tar.gz/share/templates/freshclam.conf.tpl -> pykolab-0.8.10.tar.gz/share/templates/freshclam.conf.tpl
Changed
@@ -49,7 +49,7 @@ # By default when started freshclam drops privileges and switches to the # "clamav" user. This directive allows you to change the database owner. # Default: clamav (may depend on installation options) -DatabaseOwner clam +DatabaseOwner clamupdate # Initialize supplementary group access (freshclam must be started by root). # Default: no
View file
pykolab-0.8.9.tar.gz/tests/unit/test-011-wallace_resources.py -> pykolab-0.8.10.tar.gz/tests/unit/test-011-wallace_resources.py
Changed
@@ -109,6 +109,7 @@ import smtplib self.patch(smtplib.SMTP, "__init__", self._mock_smtp_init) self.patch(smtplib.SMTP, "quit", self._mock_nop) + self.patch(smtplib.SMTP, "connect", self._mock_smtp_init) self.patch(smtplib.SMTP, "sendmail", self._mock_smtp_sendmail) self.smtplog = [] @@ -139,6 +140,7 @@ def _mock_smtp_sendmail(self, from_addr, to_addr, message, mail_options=None, rcpt_options=None): self.smtplog.append((from_addr, to_addr, message)) + return [] def _get_ics_part(self, message): ics_part = None
View file
pykolab-0.8.9.tar.gz/tests/unit/test-012-wallace_invitationpolicy.py -> pykolab-0.8.10.tar.gz/tests/unit/test-012-wallace_invitationpolicy.py
Changed
@@ -85,6 +85,7 @@ import smtplib self.patch(smtplib.SMTP, "__init__", self._mock_smtp_init) self.patch(smtplib.SMTP, "quit", self._mock_nop) + self.patch(smtplib.SMTP, "connect", self._mock_smtp_init) self.patch(smtplib.SMTP, "sendmail", self._mock_smtp_sendmail) self.smtplog = [] @@ -108,7 +109,7 @@ def _mock_smtp_sendmail(self, from_addr, to_addr, message, mail_options=None, rcpt_options=None): self.smtplog.append((from_addr, to_addr, message)) - return True + return [] def test_001_itip_events_from_message(self): itips = pykolab.itip.events_from_message(message_from_string(itip_multipart))
View file
pykolab-0.8.9.tar.gz/wallace/__init__.py -> pykolab-0.8.10.tar.gz/wallace/__init__.py
Changed
@@ -29,6 +29,7 @@ import struct import sys import tempfile +from threading import _Timer import time import traceback @@ -99,6 +100,15 @@ def worker_process(*args, **kw): log.debug(_("Worker process %s initializing") % (multiprocessing.current_process().name), level=1) +class Timer(_Timer): + def run(self): + while True: + while not self.finished.is_set(): + self.finished.wait(self.interval) + self.function(*self.args, **self.kwargs) + + self.finished.set() + class WallaceDaemon(object): def __init__(self): self.current_connections = 0 @@ -190,6 +200,8 @@ else: self.pool = multiprocessing.Pool(conf.max_threads, worker_process, ()) + self.pickup_spool_messages(sync=True) + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) @@ -226,54 +238,8 @@ s.listen(5) - # Mind you to include the trailing slash - pickup_path = '/var/spool/pykolab/wallace/' - for root, directory, files in os.walk(pickup_path): - for filename in files: - filepath = os.path.join(root, filename) - - if not root == pickup_path: - module = os.path.dirname(root).replace(pickup_path, '') - - # Compare uppercase status (specifically, DEFER) with - # lowercase (plugin names). - # - # The messages in DEFER are supposed to be picked up by - # another thread, whereas the messages in other directories - # are pending being handled by their respective plugins. - # - # TODO: Handle messages in spool directories for which a - # plugin had been enabled, but is not enabled any longer. - # - - if module.lower() == "defer": - # Wallace was unable to deliver to re-injection smtpd. - # Skip it, another thread is picking up the deferred - # messages. - continue - - stage = root.replace(pickup_path, '').split('/') - if len(stage) < 2: - stage = None - else: - stage = stage[1] - - if stage.lower() == "hold": - continue - - # Do not handle messages in a defer state. - if stage.lower() == "defer": - continue - - self.current_connections += 1 - self.pool.apply_async(pickup_message, (filepath, (self.modules), {'module': module, 'stage': stage})) - self.current_connections -= 1 - - continue - - self.current_connections += 1 - self.pool.apply_async(pickup_message, (filepath, (self.modules))) - self.current_connections -= 1 + self.timer = Timer(180, self.pickup_spool_messages) + self.timer.start() # start background process to run periodic jobs in active modules self.heartbeat = multiprocessing.Process(target=modules_heartbeat, args=[self.modules]) @@ -306,6 +272,88 @@ return "X-Kolab-From: " + mailfrom + "\r\n" + \ "X-Kolab-To: " + COMMASPACE.join(rcpttos) + "\r\n" + def pickup_spool_messages(self, sync=False): + # Mind you to include the trailing slash + pickup_path = '/var/spool/pykolab/wallace/' + + messages = [] + for root, directory, files in os.walk(pickup_path): + for filename in files: + messages.append((root, filename)) + + + for root, filename in messages: + filepath = os.path.join(root, filename) + + try: + if os.stat(filepath).st_mtime + 150 > time.time(): + log.debug("Skipping %s" % (filepath), level=8) + continue + + except: + continue + + if not root == pickup_path: + module = os.path.dirname(root).replace(pickup_path, '') + + # Compare uppercase status (specifically, DEFER) with + # lowercase (plugin names). + # + # The messages in DEFER are supposed to be picked up by + # another thread, whereas the messages in other directories + # are pending being handled by their respective plugins. + # + # TODO: Handle messages in spool directories for which a + # plugin had been enabled, but is not enabled any longer. + # + + if module.lower() == "defer": + # Wallace was unable to deliver to re-injection smtpd. + # Skip it, another thread is picking up the deferred + # messages. + continue + + stage = root.replace(pickup_path, '').split('/') + + if len(stage) < 2: + stage = None + else: + stage = stage[1] + + if stage.lower() == "hold": + continue + + # Do not handle messages in a defer state. + if stage.lower() == "defer": + continue + + self.current_connections += 1 + + if sync: + pickup_message(filepath, self.modules, module=module, stage=stage) + else: + self.pool.apply_async( + pickup_message, + ( + filepath, + (self.modules), + {'module': module, 'stage': stage} + ) + ) + + self.current_connections -= 1 + + continue + + self.current_connections += 1 + + if sync: + pickup_message(filepath, self.modules) + else: + self.pool.apply_async(pickup_message, (filepath, (self.modules))) + + self.current_connections -= 1 + def process_message(self, peer, mailfrom, rcpttos, data): """ We have retrieved the message. This should be as fast as possible,
View file
pykolab-0.8.9.tar.gz/wallace/module_invitationpolicy.py -> pykolab-0.8.10.tar.gz/wallace/module_invitationpolicy.py
Changed
@@ -19,6 +19,7 @@ import datetime import os +import signal import tempfile import time from urlparse import urlparse @@ -319,8 +320,12 @@ # for replies, the organizer is the recipient if itip_event['method'] == 'REPLY': - organizer_mailto = str(itip_event['organizer']).split(':')[-1] - user_attendees = [organizer_mailto] if organizer_mailto in recipient_emails else [] + # Outlook can send iTip replies without an organizer property + if itip_event.has_key('organizer'): + organizer_mailto = str(itip_event['organizer']).split(':')[-1] + user_attendees = [organizer_mailto] if organizer_mailto in recipient_emails else [] + else: + user_attendees = [recipient_email] else: # Limit the attendees to the one that is actually invited with the current message. @@ -399,7 +404,7 @@ try: receiving_attendee = itip_event['xml'].get_attendee_by_email(recipient_email) - log.debug(_("Receiving Attendee: %r") % (receiving_attendee), level=8) + log.debug(_("Receiving attendee: %r") % (receiving_attendee.to_dict()), level=8) except Exception, errmsg: log.error("Could not find envelope attendee: %r" % (errmsg)) return MESSAGE_FORWARD @@ -1161,7 +1166,6 @@ """ global auth - import smtplib from email.MIMEText import MIMEText from email.Utils import formatdate from email.header import Header @@ -1175,6 +1179,9 @@ orgname = organizer.name() itip_comment = None + if comment is not None: + comment = comment.strip() + if sender is not None and not comment == '': itip_comment = _("%s commented: %s") % (_attendee_name(sender), comment) @@ -1284,14 +1291,19 @@ msg['From'] = Header(utils.str2unicode('%s' % orgname) if orgname else '') msg['From'].append("<%s>" % orgemail) - modules._sendmail(orgemail, receiving_user['mail'], msg.as_string()) - log.debug(_("Sent update notification to %r: %r") % (receiving_user['mail'], success), level=8) + seed = random.randint(0, 6) + alarm_after = (seed * 10) + 60 + log.debug(_("Set alarm to %s seconds") % (alarm_after), level=8) + signal.alarm(alarm_after) + + result = modules._sendmail(orgemail, receiving_user['mail'], msg.as_string()) + log.debug(_("Sent update notification to %r: %r") % (receiving_user['mail'], result), level=8) + signal.alarm(0) def send_cancel_notification(object, receiving_user, deleted=False, sender=None, comment=None): """ Send a notification about event/task cancellation """ - import smtplib from email.MIMEText import MIMEText from email.Utils import formatdate from email.header import Header @@ -1329,6 +1341,9 @@ else: message_text += " " + _("The copy in your calendar has been marked as cancelled accordingly.") + if comment is not None: + comment = comment.strip() + if sender is not None and not comment == '': message_text += "\n" + _("%s commented: %s") % (_attendee_name(sender), comment) @@ -1346,8 +1361,14 @@ msg['From'] = Header(utils.str2unicode('%s' % orgname) if orgname else '') msg['From'].append("<%s>" % orgemail) - modules._sendmail(orgemail, receiving_user['mail'], msg.as_string()) - log.debug(_("Sent cancel notification to %r: %r") % (receiving_user['mail'], success), level=8) + seed = random.randint(0, 6) + alarm_after = (seed * 10) + 60 + log.debug(_("Set alarm to %s seconds") % (alarm_after), level=8) + signal.alarm(alarm_after) + + result = modules._sendmail(orgemail, receiving_user['mail'], msg.as_string()) + log.debug(_("Sent cancel notification to %r: %r") % (receiving_user['mail'], result), level=8) + signal.alarm(0) def is_auto_reply(user, sender_email, type): accept_available = False
View file
pykolab-0.8.9.tar.gz/wallace/module_resources.py -> pykolab-0.8.10.tar.gz/wallace/module_resources.py
Changed
@@ -22,6 +22,7 @@ import os import pytz import random +import signal import tempfile import time from urlparse import urlparse @@ -1312,7 +1313,6 @@ """ Send a reservation notification to the resource owner """ - import smtplib from pykolab import utils from email.MIMEText import MIMEText from email.Utils import formatdate @@ -1356,17 +1356,14 @@ resource['cn'], participant_status_label(status) if success else _('failed') )) - smtp = smtplib.SMTP("localhost", 10027) + seed = random.randint(0, 6) + alarm_after = (seed * 10) + 60 + log.debug(_("Set alarm to %s seconds") % (alarm_after), level=8) + signal.alarm(alarm_after) - if conf.debuglevel > 8: - smtp.set_debuglevel(True) - - try: - smtp.sendmail(resource['mail'], owner['mail'], msg.as_string()) - except Exception, e: - log.error(_("SMTP sendmail error: %r") % (e)) - - smtp.quit() + result = modules._sendmail(resource['mail'], owner['mail'], msg.as_string()) + log.debug(_("Owner notification was sent successfully: %r") % result, level=8) + signal.alarm(0) def owner_notification_text(resource, owner, event, success): organizer = event.get_organizer()
View file
pykolab-0.8.9.tar.gz/wallace/modules.py -> pykolab-0.8.10.tar.gz/wallace/modules.py
Changed
@@ -132,17 +132,17 @@ sl = pykolab.logger.StderrToLogger(log) smtplib.stderr = sl - smtp = smtplib.SMTP(timeout=5) + smtp = smtplib.SMTP(timeout=15) if conf.debuglevel > 8: smtp.set_debuglevel(1) success = False - retries = 5 + attempt = 1 - while not success and retries > 0: + while not success and attempt <= 5: try: - log.debug(_("Trying to send email via smtplib from %r, to %r") % (sender, recipients), level=8) + log.debug(_("Sending email via smtplib from %r, to %r (Attempt %r)") % (sender, recipients, attempt), level=8) smtp.connect("127.0.0.1", 10027) _response = smtp.sendmail(sender, recipients, msg) @@ -182,9 +182,13 @@ except Exception, errmsg: log.exception(_("smtplib - Unknown error occurred: %r") % (errmsg)) - smtp.quit() + try: + smtp.quit() + except Exception, errmsg: + log.error("smtplib quit() error - %r" % errmsg) + time.sleep(10) - retries -= 1 + attempt += 1 return success @@ -237,6 +241,8 @@ def cb_action_REJECT(module, filepath): log.info(_("Rejecting message in %s (by module %s)") % (filepath, module)) + log.debug(_("Rejecting message in: %r") %(filepath), level=8) + # parse message headers message = Parser().parse(open(filepath, 'r'), True) @@ -311,8 +317,12 @@ msg.as_string() ) + log.debug(_("Rejection message was sent successfully: %r") % result) if result: os.unlink(filepath) + else: + log.debug(_("Message %r was not removed from spool") % filepath) + def cb_action_ACCEPT(module, filepath): log.info(_("Accepting message in %s (by module %s)") % (filepath, module)) @@ -342,8 +352,11 @@ message.as_string() ) + log.debug(_("Message was sent successfully: %r") % result) if result: os.unlink(filepath) + else: + log.debug(_("Message %r was not removed from spool") % filepath) def register_group(dirname, module): modules_base_path = os.path.join(os.path.dirname(__file__), module)
View file
pykolab.dsc
Changed
@@ -2,7 +2,7 @@ Source: pykolab Binary: pykolab, kolab-cli, kolab-conf, kolab-saslauthd, kolab-server, kolab-telemetry, kolab-xml, wallace Architecture: all -Version: 0.8.9-0~kolab1 +Version: 0.8.10-0~kolab2 Maintainer: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> Uploaders: Paul Klos <kolab@klos2day.nl> Homepage: http://www.kolab.org @@ -20,7 +20,7 @@ libglib2.0-dev, libpcre3, libssl-dev, - libunistring0, + libunistring2 | libunistring0, libxml-parser-perl, libxml2, mime-support, @@ -40,5 +40,5 @@ pykolab deb python optional wallace deb python optional Files: - 00000000000000000000000000000000 0 pykolab-0.8.9.tar.gz + 00000000000000000000000000000000 0 pykolab-0.8.10.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
.