Hello community, here is the log from the commit of package offlineimap for openSUSE:Factory checked in at 2017-06-02 10:34:08 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/offlineimap (Old) and /work/SRC/openSUSE:Factory/.offlineimap.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "offlineimap" Fri Jun 2 10:34:08 2017 rev:39 rq:500455 version:7.1.1 Changes: -------- --- /work/SRC/openSUSE:Factory/offlineimap/offlineimap.changes 2017-04-28 09:14:49.849158305 +0200 +++ /work/SRC/openSUSE:Factory/.offlineimap.new/offlineimap.changes 2017-06-02 10:34:20.595334733 +0200 @@ -1,0 +2,16 @@ +Thu Jun 1 16:42:06 UTC 2017 - [email protected] + +- update to 7.1.1 +* Env info (used by -V and banner): add openssl version. +* Acquire lock before updating the CursesLogHandler window +* maxage: use the remote folder first to compute min_uid. +* Fix systemd.timer: initialize timer after boot. +* XOAUTH2: don't try this authentication method when not configured. +* mbnames: don't duplicate entries in autorefresh mode. +* docs: update the instructions for creating OAuth projects for GMail. +* IMAP: UIDPLUS: correctly warn about weird responses from some servers +* IMAP: UIDPLUS: improve error message on response error for new UID. +* Display the imaplib and python versions for each normal run +* imapserver: provide some SSL info while in imap debug mode + +------------------------------------------------------------------- Old: ---- offlineimap-7.1.0.tar.gz New: ---- offlineimap-7.1.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ offlineimap.spec ++++++ --- /var/tmp/diff_new_pack.EZtQ3D/_old 2017-06-02 10:34:21.379223975 +0200 +++ /var/tmp/diff_new_pack.EZtQ3D/_new 2017-06-02 10:34:21.383223409 +0200 @@ -19,7 +19,7 @@ %{!?_userunitdir:%define _userunitdir /usr/lib/systemd/user} Name: offlineimap -Version: 7.1.0 +Version: 7.1.1 Release: 0 Summary: Powerful IMAP/Maildir Synchronization Tool License: GPL-2.0+ ++++++ offlineimap-7.1.0.tar.gz -> offlineimap-7.1.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.1.0/Changelog.md new/offlineimap-7.1.1/Changelog.md --- old/offlineimap-7.1.0/Changelog.md 2017-04-16 00:40:54.000000000 +0200 +++ new/offlineimap-7.1.1/Changelog.md 2017-05-28 18:08:54.000000000 +0200 @@ -15,6 +15,60 @@ * The following excerpt is only usefull when rendered in the website. {:toc} +### OfflineIMAP v7.1.1 (2017-05-28) + +#### Notes + +This release has some interesting fixes, including one for the Blinkenlights UI. + +Otherwise, there is no big change since the previous version. + +Furthermore, this release was tested by: + +- Remi Locherer + +#### Authors + + 17 Nicolas Sebrecht + 1 Chris Coleman + 1 Ilias Tsitsimpis + 1 Maximilian Kaul + 1 benutzer193 + 1 Ævar Arnfjörð Bjarmason + +#### Features + +- contrib: introduce a tool to produce the "upcoming notes". [Nicolas Sebrecht] +- contrib: secure HTTPS test internet is connected.. [Chris Coleman] +- Env info (used by -V and banner): add openssl version. [Nicolas Sebrecht] +- docs: learn to build html files for the manual pages. [Nicolas Sebrecht] + +#### Fixes + +- Acquire lock before updating the CursesLogHandler window. [Ilias Tsitsimpis] +- maxage: use the remote folder first to compute min_uid. [Nicolas Sebrecht] +- Fix systemd.timer: initialize timer after boot. [benutzer193] +- XOAUTH2: don't try this authentication method when not configured. [Nicolas Sebrecht] +- mbnames: don't duplicate entries in autorefresh mode. [Nicolas Sebrecht] +- docs: update the instructions for creating OAuth projects for GMail. [Ævar Arnfjörð Bjarmason] +- Fixed typo in doc: tls_1_2 => tls1_2. [Maximilian Kaul] +- IMAP: UIDPLUS: correctly warn about weird responses from some servers. [Nicolas Sebrecht] +- website-doc: force copy of the new HTML generated man pages. [Nicolas Sebrecht] +- Makefile: fix clean target. [Nicolas Sebrecht] + +#### Changes + +- MAINTAINERS: benutzer193 joins the testers team. [Nicolas Sebrecht] +- IMAP: UIDPLUS: improve error message on response error for new UID. [Nicolas Sebrecht] +- Display the imaplib and python versions for each normal run. [Nicolas Sebrecht] +- imapserver: provide some SSL info while in imap debug mode. [Nicolas Sebrecht] +- manual: improve the documentation about sqlite migration. [Nicolas Sebrecht] +- documentation: add entry for faulting folders with Microsoft servers. [Nicolas Sebrecht] +- website-doc.sh: add hint on API removal. [Nicolas Sebrecht] +- README: refactorize sections. [Nicolas Sebrecht] + + + ### OfflineIMAP v7.1.0 (2017-04-16) #### Notes diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.1.0/MAINTAINERS.rst new/offlineimap-7.1.1/MAINTAINERS.rst --- old/offlineimap-7.1.0/MAINTAINERS.rst 2017-04-16 00:40:54.000000000 +0200 +++ new/offlineimap-7.1.1/MAINTAINERS.rst 2017-05-28 18:08:54.000000000 +0200 @@ -11,6 +11,10 @@ - email: mathstuf at gmail.com - github: mathstuf +- benutzer193 + - email: registerbn at gmail.com + - github: benutzer193 + - Chris Coleman - email: christocoleman at yahoo.com - github: chris001 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.1.0/Makefile new/offlineimap-7.1.1/Makefile --- old/offlineimap-7.1.0/Makefile 2017-04-16 00:40:54.000000000 +0200 +++ new/offlineimap-7.1.1/Makefile 2017-05-28 18:08:54.000000000 +0200 @@ -38,7 +38,7 @@ -find . -name '.cache*' -exec rm -f {} \; -rm -f manpage.links manpage.refs 2>/dev/null -find . -name auth -exec rm -vf {}/password {}/username \; - @$(MAKE) -C clean + -$(MAKE) -C docs clean .PHONY: docs docs: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.1.0/README.md new/offlineimap-7.1.1/README.md --- old/offlineimap-7.1.0/README.md 2017-04-16 00:40:54.000000000 +0200 +++ new/offlineimap-7.1.1/README.md 2017-05-28 18:08:54.000000000 +0200 @@ -15,6 +15,8 @@ OfflineIMAP is software that downloads your email mailbox(es) as **local Maildirs**. OfflineIMAP will synchronize both sides via *IMAP*. +## Why should I use OfflineIMAP? + IMAP's main downside is that you have to **trust** your email provider to not lose your email. While certainly unlikely, it's not impossible. With OfflineIMAP, you can download your Mailboxes and make you own backups of @@ -50,14 +52,6 @@ GNU General Public License v2. -## Why should I use OfflineIMAP? - -* It is **fast**. -* It is **reliable**. -* It is **flexible**. -* It is **safe**. - - ## Downloads You should first check if your distribution already packages OfflineIMAP for you. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.1.0/contrib/internet-urllib3.py new/offlineimap-7.1.1/contrib/internet-urllib3.py --- old/offlineimap-7.1.0/contrib/internet-urllib3.py 1970-01-01 01:00:00.000000000 +0100 +++ new/offlineimap-7.1.1/contrib/internet-urllib3.py 2017-05-28 18:08:54.000000000 +0200 @@ -0,0 +1,19 @@ +#!/usr/bin/env python + +import urllib3 +import certifi + +def isInternetConnected(url="www.ietf.org"): + result = False + http = urllib3.PoolManager( + cert_reqs='CERT_REQUIRED', # Force certificate check. + ca_certs=certifi.where(), # Path to the Certifi bundle. + ) + try: + r = http.request('HEAD', 'https://' + url) + result = True + except Exception as e: # urllib3.exceptions.SSLError + result = False + return result + +print isInternetConnected() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.1.0/contrib/systemd/offlineimap.timer new/offlineimap-7.1.1/contrib/systemd/offlineimap.timer --- old/offlineimap-7.1.0/contrib/systemd/offlineimap.timer 2017-04-16 00:40:54.000000000 +0200 +++ new/offlineimap-7.1.1/contrib/systemd/offlineimap.timer 2017-05-28 18:08:54.000000000 +0200 @@ -2,6 +2,7 @@ Description=Offlineimap Query Timer [Timer] +OnBootSec=1m OnUnitInactiveSec=15m Unit=offlineimap-oneshot.service diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.1.0/contrib/systemd/[email protected] new/offlineimap-7.1.1/contrib/systemd/[email protected] --- old/offlineimap-7.1.0/contrib/systemd/[email protected] 2017-04-16 00:40:54.000000000 +0200 +++ new/offlineimap-7.1.1/contrib/systemd/[email protected] 2017-05-28 18:08:54.000000000 +0200 @@ -2,6 +2,7 @@ Description=Offlineimap Query Timer for account %i [Timer] +OnBootSec=1m OnUnitInactiveSec=15m Unit=offlineimap-oneshot@%i.service diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.1.0/contrib/upcoming.py new/offlineimap-7.1.1/contrib/upcoming.py --- old/offlineimap-7.1.0/contrib/upcoming.py 1970-01-01 01:00:00.000000000 +0100 +++ new/offlineimap-7.1.1/contrib/upcoming.py 2017-05-28 18:08:54.000000000 +0200 @@ -0,0 +1,199 @@ +#!/usr/bin/python3 + +""" + +Put into Public Domain, by Nicolas Sebrecht. + +Produce the "upcoming release" notes. + +""" + +from os import chdir, system +from os.path import expanduser +import shlex +from subprocess import check_output + + +__VERSION__ = "0.1" + +FS_ENCODING = 'UTF-8' +ENCODING = 'UTF-8' + +MAILING_LIST = '[email protected]' +CACHEDIR = '.git/offlineimap-release' +UPCOMING_FILE = "{}/upcoming.txt".format(CACHEDIR) +EDITOR = 'vim' +MAILALIASES_FILE = expanduser('~/.mutt/mail_aliases') + +UPCOMING_HEADER = """ +Message-Id: <{messageId}> +Date: {date} +From: {name} <{email}> +To: {mailinglist} +Cc: {ccList} +Subject: [ANNOUNCE] upcoming offlineimap v{expectedVersion} + +# Notes + +I think it's time for a new release. + +I aim to make the new release in one week, approximately. If you'd like more +time, please let me know. ,-) + + +# Authors + +""" + + +def run(cmd): + return check_output(cmd, timeout=5).rstrip() + + +def getTesters(): + """Returns a list of emails extracted from my mailaliases file.""" + + cmd = shlex.split("grep offlineimap-testers {}".format(MAILALIASES_FILE)) + output = run(cmd).decode(ENCODING) + emails = output.lstrip("alias offlineimap-testers ").split(', ') + return emails + + +class Author(object): + def __init__(self, name, count, email): + self.name = name + self.count = count + self.email = email + + def getName(self): + return self.name + + def getCount(self): + return self.count + + def getEmail(self): + return self.email + + +class Git(object): + @staticmethod + def getShortlog(ref): + shortlog = "" + + cmd = shlex.split("git shortlog --no-merges -n v{}..".format(ref)) + output = run(cmd).decode(ENCODING) + + for line in output.split("\n"): + if len(line) > 0: + if line[0] != " ": + line = " {}\n".format(line) + else: + line = " {}\n".format(line.lstrip()) + else: + line = "\n" + + shortlog += line + + return shortlog + + @staticmethod + def getDiffstat(ref): + cmd = shlex.split("git diff --stat v{}..".format(ref)) + return run(cmd).decode(ENCODING) + + @staticmethod + def buildMessageId(): + cmd = shlex.split( + "git log HEAD~1.. --oneline --pretty='%H.%t.upcoming.%ce'") + return run(cmd).decode(ENCODING) + + @staticmethod + def getLocalUser(): + cmd = shlex.split("git config --get user.name") + name = run(cmd).decode(ENCODING) + cmd = shlex.split("git config --get user.email") + email = run(cmd).decode(ENCODING) + return name, email + + @staticmethod + def buildDate(): + cmd = shlex.split("git log HEAD~1.. --oneline --pretty='%cD'") + return run(cmd).decode(ENCODING) + + @staticmethod + def getAuthors(ref): + authors = [] + + cmd = shlex.split("git shortlog --no-merges -sne v{}..".format(ref)) + output = run(cmd).decode(ENCODING) + + for line in output.split("\n"): + count, full = line.strip().split("\t") + full = full.split(' ') + name = ' '.join(full[:-1]) + email = full[-1] + + authors.append(Author(name, count, email)) + + return authors + + @staticmethod + def chdirToRepositoryTopLevel(): + cmd = shlex.split("git rev-parse --show-toplevel") + topLevel = run(cmd) + + chdir(topLevel) + + +class OfflineimapInfo(object): + def __init__(self): + self.version = None + + def getCurrentVersion(self): + if self.version is None: + cmd = shlex.split("./offlineimap.py --version") + self.version = run(cmd).rstrip().decode(FS_ENCODING) + return self.version + + +class User(object): + """Interact with the user.""" + + prompt = '-> ' + + @staticmethod + def request(msg): + print(msg) + return input(User.prompt) + + +if __name__ == '__main__': + offlineimapInfo = OfflineimapInfo() + + Git.chdirToRepositoryTopLevel() + oVersion = offlineimapInfo.getCurrentVersion() + ccList = getTesters() + authors = Git.getAuthors(oVersion) + for author in authors: + email = author.getEmail() + if email not in ccList: + ccList.append(email) + + with open(UPCOMING_FILE, 'w') as upcoming: + header = {} + + header['messageId'] = Git.buildMessageId() + header['date'] = Git.buildDate() + header['name'], header['email'] = Git.getLocalUser() + header['mailinglist'] = MAILING_LIST + header['expectedVersion'] = User.request("Expected new version?") + header['ccList'] = ", ".join(ccList) + + upcoming.write(UPCOMING_HEADER.format(**header).lstrip()) + upcoming.write(Git.getShortlog(oVersion)) + + upcoming.write("\n\n# Diffstat\n\n") + upcoming.write(Git.getDiffstat(oVersion)) + upcoming.write("\n\n\n-- \n{}\n".format(Git.getLocalUser()[0])) + + system("{} {}".format(EDITOR, UPCOMING_FILE)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.1.0/docs/Makefile new/offlineimap-7.1.1/docs/Makefile --- old/offlineimap-7.1.0/docs/Makefile 2017-04-16 00:40:54.000000000 +0200 +++ new/offlineimap-7.1.1/docs/Makefile 2017-05-28 18:08:54.000000000 +0200 @@ -16,6 +16,15 @@ $(HTML_TARGETS): %.html : %.rst $(RST2HTML) $? $@ +manhtml: offlineimap.html offlineimapui.html + +offlineimap.html: offlineimap.txt offlineimap.known_issues.txt + a2x -v -d manpage -D manhtml -f xhtml $< + +offlineimapui.html: offlineimapui.txt + a2x -v -d manpage -D manhtml -f xhtml $< + + man: offlineimap.1 offlineimapui.7 offlineimap.1: offlineimap.txt offlineimap.known_issues.txt @@ -30,13 +39,15 @@ websitedoc: ./website-doc.sh releases ./website-doc.sh api + ./website-doc.sh html ./website-doc.sh contrib clean: $(RM) -f $(HTML_TARGETS) $(RM) -f offlineimap.1 $(RM) -f offlineimap.7 + $(RM) -f manhtml/* $(RM) -rf html/* - -find ./docs -name '*.html' -exec rm -f {} \; + -find . -name '*.html' -exec rm -f {} \; .PHONY: clean doc diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.1.0/docs/offlineimap.known_issues.txt new/offlineimap-7.1.1/docs/offlineimap.known_issues.txt --- old/offlineimap-7.1.0/docs/offlineimap.known_issues.txt 2017-04-16 00:40:54.000000000 +0200 +++ new/offlineimap-7.1.1/docs/offlineimap.known_issues.txt 2017-05-28 18:08:54.000000000 +0200 @@ -151,3 +151,12 @@ and <https://developers.google.com/identity/protocols/OAuth2#expiration> to know more. +* "does not have message with UID" with Microsoft servers ++ + `ERROR: IMAP server 'Server ### Remote' does not have a message with UID 'xxx'` ++ +Microsoft IMAP servers are not compliant with the RFC. It is currently required +to folderfilter some faulting folders. See +http://www.offlineimap.org/doc/FAQ.html#exchange-and-office365 for a detailed +list. + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.1.0/docs/offlineimap.txt new/offlineimap-7.1.1/docs/offlineimap.txt --- old/offlineimap-7.1.0/docs/offlineimap.txt 2017-04-16 00:40:54.000000000 +0200 +++ new/offlineimap-7.1.1/docs/offlineimap.txt 2017-05-28 18:08:54.000000000 +0200 @@ -225,17 +225,17 @@ OfflineImap caches the state of the synchronisation to e.g. be able to determine if a mail has been added or deleted on either side. + -The historical status cache is a plain text file that writes out the complete -file for each single new message (or even changed flag) to a temporary file. If -you have plenty of files in a folder, this is a few hundred kilo to megabytes -for each mail and is bound to make things slow. The latest status cache -is sqlite. This saves plenty of disk activity. The sqlite engine and the Python -sqlite module must be installed. The historical plain status cache is not -supported anymore. +The historical status cache was a plain text file that was writing out the +complete file for each single new message (or even changed flag) to a temporary +file. If there was plenty of files in a folder this was bound to make things +slow. The latest status cache is sqlite. This saves plenty of disk activity. + -If you switch the backend from plain to sqlite, you may want to delete the old -cache directory in '<metadata>/Account-<account>/LocalStatus' manually (the -sqlite cache stands in the 'LocalStatus-sqlite' folder). +The historical plain status cache is not supported anymore but migrating from a +very old installation using the plain text cache is still supported. In this +case, you may want to delete the old cache directory in +'<metadata>/Account-<account>/LocalStatus' manually (the sqlite cache stands in +the 'LocalStatus-sqlite' folder). First, make sure you have run the new version +of offlineimap for all your accounts so that the status cache was migrated. 4. Use quick sync. + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.1.0/docs/website-doc.sh new/offlineimap-7.1.1/docs/website-doc.sh --- old/offlineimap-7.1.0/docs/website-doc.sh 2017-04-16 00:40:54.000000000 +0200 +++ new/offlineimap-7.1.1/docs/website-doc.sh 2017-05-28 18:08:54.000000000 +0200 @@ -55,6 +55,8 @@ echo "Building Jekyll data: $VERSIONS_YML" # Erase previous content. echo "$HEADER" > "$VERSIONS_YML" + echo "# However, it's correct to /remove/ old API docs here." + echo "# While at it, don't forget to adjust the _doc/versions directory." for version in $(ls "$DESTBASE" -1 | sort -nr) do echo "- $version" @@ -124,6 +126,15 @@ rm -f "$ANNOUNCES_YML_TMP" } +function manhtml () { + set -e + + cd ./docs + make manhtml + cd .. + cp -afv ./docs/manhtml/* "$DOCBASE" +} + exit_code=0 test "n$ARGS" = 'n' && ARGS='usage' # no option passed @@ -137,6 +148,9 @@ "napi") api ;; + "nhtml") + manhtml + ;; "ncontrib") contrib ;; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.1.0/offlineimap/__init__.py new/offlineimap-7.1.1/offlineimap/__init__.py --- old/offlineimap-7.1.0/offlineimap/__init__.py 2017-04-16 00:40:54.000000000 +0200 +++ new/offlineimap-7.1.1/offlineimap/__init__.py 2017-05-28 18:08:54.000000000 +0200 @@ -2,7 +2,7 @@ __productname__ = 'OfflineIMAP' # Expecting trailing "-rcN" or "" for stable releases. -__version__ = "7.1.0" +__version__ = "7.1.1" __copyright__ = "Copyright 2002-2017 John Goerzen & contributors" __author__ = "John Goerzen" __author_email__= "[email protected]" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.1.0/offlineimap/accounts.py new/offlineimap-7.1.1/offlineimap/accounts.py --- old/offlineimap-7.1.0/offlineimap/accounts.py 2017-04-16 00:40:54.000000000 +0200 +++ new/offlineimap-7.1.1/offlineimap/accounts.py 2017-05-28 18:08:54.000000000 +0200 @@ -309,6 +309,9 @@ remotefolder.getvisiblename(). replace(self.remoterepos.getsep(), self.localrepos.getsep())) + + # The syncrunner will loop on this method. This means it is called more than + # once during the run. def __sync(self): """Synchronize the account once, then return. @@ -486,23 +489,21 @@ def cachemessagelists_upto_date(date): """Returns messages with uid > min(uids of messages newer than date).""" - # Warning: this makes sense only if the cached list is empty. - localfolder.cachemessagelist(min_date=date) - check_uid_validity() - # Local messagelist had date restriction applied already. Restrict - # sync to messages with UIDs >= min_uid from this list. - # - # Local messagelist might contain new messages (with uid's < 0). - positive_uids = [uid for uid in localfolder.getmessageuidlist() if uid > 0] - if len(positive_uids) > 0: - remotefolder.cachemessagelist(min_uid=min(positive_uids)) + remotefolder.cachemessagelist( + min_date=time.gmtime(time.mktime(date) + 24*60*60)) + uids = remotefolder.getmessageuidlist() + localfolder.dropmessagelistcache() + if len(uids) > 0: + localfolder.cachemessagelist(min_uid=min(uids)) else: - # No messages with UID > 0 in range in localfolder. - # date restriction was applied with respect to local dates but - # remote folder timezone might be different from local, so be - # safe and make sure the range isn't bigger than in local. - remotefolder.cachemessagelist( - min_date=time.gmtime(time.mktime(date) + 24*60*60)) + # Remote folder UIDs list is empty for the given range. We still + # might have valid local UIDs for this range (e.g.: new local + # emails). + localfolder.cachemessagelist(min_date=date) + uids = localfolder.getmessageuidlist() + if len(uids) > 0: + # Update the remote cache list for this new min(uids). + remotefolder.cachemessagelist(min_uid=min(uids)) def cachemessagelists_startdate(new, partial, date): """Retrieve messagelists when startdate has been set for diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.1.0/offlineimap/folder/IMAP.py new/offlineimap-7.1.1/offlineimap/folder/IMAP.py --- old/offlineimap-7.1.0/offlineimap/folder/IMAP.py 2017-04-16 00:40:54.000000000 +0200 +++ new/offlineimap-7.1.1/offlineimap/folder/IMAP.py 2017-05-28 18:08:54.000000000 +0200 @@ -682,9 +682,15 @@ resp = imapobj._get_untagged_response('APPENDUID') if resp == [None] or resp is None: self.ui.warn("Server supports UIDPLUS but got no APPENDUID " - "appending a message.") + "appending a message. Got: %s."% str(resp)) return 0 - uid = int(resp[-1].split(' ')[1]) + try: + uid = int(resp[-1].split(' ')[1]) + except ValueError as e: + uid = 0 # Definetly not what we should have. + except Exception as e: + raise OfflineImapError("Unexpected response: %s"% str(resp), + OfflineImapError.ERROR.MESSAGE) if uid == 0: self.ui.warn("savemessage: Server supports UIDPLUS, but" " we got no usable uid back. APPENDUID reponse was " @@ -706,7 +712,7 @@ if imapobj: self.imapserver.releaseconnection(imapobj) - if uid: # Avoid UID FETCH 0 crash happening later on + if uid: # Avoid UID FETCH 0 crash happening later on. self.messagelist[uid] = self.msglist_item_initializer(uid) self.messagelist[uid]['flags'] = flags diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.1.0/offlineimap/imapserver.py new/offlineimap-7.1.1/offlineimap/imapserver.py --- old/offlineimap-7.1.0/offlineimap/imapserver.py 2017-04-16 00:40:54.000000000 +0200 +++ new/offlineimap-7.1.1/offlineimap/imapserver.py 2017-05-28 18:08:54.000000000 +0200 @@ -221,10 +221,6 @@ return retval def __xoauth2handler(self, response): - if self.oauth2_refresh_token is None \ - and self.oauth2_access_token is None: - return None - if self.oauth2_access_token is None: if self.oauth2_request_url is None: raise OfflineImapError("No remote oauth2_request_url for " @@ -353,6 +349,10 @@ return True def __authn_xoauth2(self, imapobj): + if self.oauth2_refresh_token is None \ + and self.oauth2_access_token is None: + return False + imapobj.authenticate('XOAUTH2', self.__xoauth2handler) return True @@ -527,6 +527,8 @@ elif self.usessl: self.ui.connecting( self.repos.getname(), self.hostname, self.port) + self.ui.debug('imap', "%s: level '%s', version '%s'"% + (self.repos.getname(), self.tlslevel, self.sslversion)) imapobj = imaplibutil.WrappedIMAP4_SSL( host=self.hostname, port=self.port, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.1.0/offlineimap/init.py new/offlineimap-7.1.1/offlineimap/init.py --- old/offlineimap-7.1.0/offlineimap/init.py 2017-04-16 00:40:54.000000000 +0200 +++ new/offlineimap-7.1.1/offlineimap/init.py 2017-05-28 18:08:54.000000000 +0200 @@ -1,5 +1,5 @@ # OfflineIMAP initialization code -# Copyright (C) 2002-2016 John Goerzen & contributors +# Copyright (C) 2002-2017 John Goerzen & contributors # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -72,6 +72,17 @@ oi.run() """ + def get_env_info(self): + info = "imaplib2 v%s (%s), Python v%s"% ( + imaplib.__version__, imaplib.DESC, PYTHON_VERSION + ) + try: + import ssl + info = "%s, %s"% (info, ssl.OPENSSL_VERSION) + except: + pass + return info + def run(self): """Parse the commandline and invoke everything""" # next line also sets self.config and self.ui @@ -180,9 +191,8 @@ glob.set_options(options) if options.version: - print("offlineimap v%s, imaplib2 v%s (%s), Python v%s"% ( - offlineimap.__version__, imaplib.__version__, imaplib.DESC, - PYTHON_VERSION) + print("offlineimap v%s, %s"% ( + offlineimap.__version__, self.get_env_info()) ) sys.exit(0) @@ -273,6 +283,7 @@ # Welcome blurb. self.ui.init_banner() + self.ui.info(self.get_env_info()) if options.debugtype: self.ui.logger.setLevel(logging.DEBUG) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.1.0/offlineimap/mbnames.py new/offlineimap-7.1.1/offlineimap/mbnames.py --- old/offlineimap-7.1.0/offlineimap/mbnames.py 2017-04-16 00:40:54.000000000 +0200 +++ new/offlineimap-7.1.1/offlineimap/mbnames.py 2017-05-28 18:08:54.000000000 +0200 @@ -32,6 +32,7 @@ _mbnames = None +# Called at sync time for each folder. def add(accountname, folder_root, foldername): global _mbnames if _mbnames.is_enabled() is not True: @@ -41,12 +42,14 @@ _mbnames.addAccountFolder(accountname, folder_root, foldername) +# Called once. def init(conf, ui, dry_run): global _mbnames if _mbnames is None: _mbnames = _Mbnames(conf, ui, dry_run) +# Called once. def prune(accounts): global _mbnames if _mbnames.is_enabled() is True: @@ -55,6 +58,7 @@ _mbnames.pruneAll() +# Called once. def write(): """Write the mbnames file.""" @@ -66,6 +70,7 @@ _mbnames.write() +# Called as soon as all the folders are synced for the account. def writeIntermediateFile(accountname): """Write intermediate mbnames file.""" @@ -93,7 +98,8 @@ self._dryrun = dry_run def add(self, foldername): - self._foldernames.append(foldername) + if foldername not in self._foldernames: + self._foldernames.append(foldername) def get_folder_root(self): return self._folder_root diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.1.0/offlineimap/ui/Curses.py new/offlineimap-7.1.1/offlineimap/ui/Curses.py --- old/offlineimap-7.1.0/offlineimap/ui/Curses.py 2017-04-16 00:40:54.000000000 +0200 +++ new/offlineimap-7.1.1/offlineimap/ui/Curses.py 2017-05-28 18:08:54.000000000 +0200 @@ -315,11 +315,11 @@ y,x = self.ui.logwin.getyx() if y or x: self.ui.logwin.addch(10) # no \n before 1st item self.ui.logwin.addstr(log_str, color) + self.ui.logwin.noutrefresh() + self.ui.stdscr.refresh() finally: self.ui.unlock() self.ui.tframe_lock.release() - self.ui.logwin.noutrefresh() - self.ui.stdscr.refresh() class Blinkenlights(UIBase, CursesUtil): """Curses-cased fancy UI. @@ -611,11 +611,12 @@ color = curses.A_REVERSE self.bannerwin.clear() # Delete old content (eg before resizes) self.bannerwin.bkgd(' ', color) # Fill background with that color - string = "%s %s"% (offlineimap.__productname__, - offlineimap.__version__) - self.bannerwin.addstr(0, 0, string, color) - self.bannerwin.addstr(0, self.width -len(offlineimap.__copyright__) -1, - offlineimap.__copyright__, color) + string = "%s %s" % (offlineimap.__productname__, + offlineimap.__version__) + spaces = " " * max(1, (self.width - len(offlineimap.__copyright__) + - len(string) - 1)) + string = "%s%s%s" % (string, spaces, offlineimap.__copyright__) + self.bannerwin.addnstr(0, 0, string, self.width - 1, color) self.bannerwin.noutrefresh() def draw_logwin(self): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.1.0/offlineimap.conf new/offlineimap-7.1.1/offlineimap.conf --- old/offlineimap-7.1.0/offlineimap.conf 2017-04-16 00:40:54.000000000 +0200 +++ new/offlineimap-7.1.1/offlineimap.conf 2017-05-28 18:08:54.000000000 +0200 @@ -228,6 +228,9 @@ # return foldername in allowed[accountname] # return False # +# For correct folderfilter with Microsoft servers, please see +# http://www.offlineimap.org/doc/FAQ.html#exchange-and-office365 +# #folderfilter = mbnames_folderfilter @@ -739,7 +742,7 @@ # # It is best to leave this unset, in which case the correct version will be # automatically detected. In rare cases, it may be necessary to specify a -# particular version from: tls1, tls1_1, tls_1_2, ssl3, ssl23. +# particular version from: tls1, tls1_1, tls1_2, ssl3, ssl23. # # tls1_1 and tls1_2 are available with OpenSSL since v1.0.1. # @@ -853,15 +856,25 @@ # See below to learn how to get those. # # Specify the OAuth2 client id and secret to use for the connection.. -# Here's how to register an OAuth2 client for Gmail, as of 10-2-2016: -# - Go to the Google developer console -# https://console.developers.google.com/project -# - Create a new project +# Here's how to register an OAuth2 client for Gmail, as of 2017-05-15: +# - Go to the Gmail API overview console +# https://console.developers.google.com/apis/api/gmail.googleapis.com/overview +# - Create a new project, name doesn't matter, e.g. 'gmail-sync-bob' # - In API & Auth, select Credentials -# - Setup the OAuth Consent Screen -# - Then add Credentials of type OAuth 2.0 Client ID -# - Choose application type Other; type in a name for your client -# - You now have a client ID and client secret +# - Once created, click 'Enable' +# - Click 'Create credentials' in the enabled API overview + +# - In 'Add credentials to your project' select 'Gmail API' as the +# API type, and 'Other UI ...' (not 'Other non-UI ...') for +# 'Where will you be calling the API from?'. For 'What data will +# you be accessing?' select 'User data'. +# - Click 'What credentials do I need?' +# - Create an arbitrary 'Create an OAuth 2.0 client ID', +# e.g. 'gmail-sync-bob-client'. For 'Set up the OAuth 2.0 consent +# screen' select an arbitrary 'Product name shown to users', +# e.g. 'gmail-sync-bob-client' & click 'Continue'. +# - This gives you your client ID displayed on the screen. Click +# 'Download' to get a JSON file that also has the client secret. # #oauth2_client_id = YOUR_CLIENT_ID #oauth2_client_secret = YOUR_CLIENT_SECRET
