Compare commits
187 Commits
debian/1.5
...
debian/lat
Author | SHA1 | Date |
---|---|---|
|
0ea9928830 | |
|
c270ddb719 | |
|
438d62ce7c | |
|
98cb3656e8 | |
|
572c919417 | |
|
c08bef0a7f | |
|
205941ae82 | |
|
8d1aee7be7 | |
|
49b48ca081 | |
|
e68e594824 | |
|
02633098cd | |
|
607d66eacf | |
|
4d1112fa6f | |
|
2fe6b6edbf | |
|
896b40a689 | |
|
46b5c47f1c | |
|
b317241f69 | |
|
46189709b2 | |
|
b1e9e28b21 | |
|
401b323d79 | |
|
d9ef53d5e4 | |
|
5793a37819 | |
|
97ba8ef723 | |
|
d3ea13e54e | |
|
83c95e2dd3 | |
|
96080d09ea | |
|
173347e839 | |
|
2fc7443c7e | |
|
990bd45fc2 | |
|
f04507e70d | |
|
dce6ad2b7e | |
|
ac0bc67fb0 | |
|
e9616bad84 | |
|
9672db0cd3 | |
|
e11228cf77 | |
|
1fdc215aff | |
|
0184c3385a | |
|
7ee81214af | |
|
00fd4dd934 | |
|
c42a2612fc | |
|
09a674a13f | |
|
0858593426 | |
|
e98850b7a5 | |
|
e35961252e | |
|
f8f0ddec27 | |
|
199ad5b24d | |
|
84102327d5 | |
|
96a4801af7 | |
|
fc19a86e83 | |
|
d3526b3a96 | |
|
cbdafe2783 | |
|
d72ec5241c | |
|
4fff221b94 | |
|
d9ffe16513 | |
|
629b069e0b | |
|
02d72e2fbe | |
|
0139dc3440 | |
|
4e50cab599 | |
|
73336f6a5a | |
|
be77943a00 | |
|
fd832ff9a2 | |
|
6674f63d2f | |
|
58a357cc52 | |
|
612b1d2d2a | |
|
da7996df58 | |
|
b986fd87e3 | |
|
e1df01ef96 | |
|
df08e36fc0 | |
|
04e752b84e | |
|
b62cbf7e60 | |
|
ff5dc93d5b | |
|
fac5c460cc | |
|
0ca2baaf33 | |
|
142ff5e66e | |
|
4ec6fd12db | |
|
73412b147f | |
|
59a2637307 | |
|
b0da99eb22 | |
|
979892df3a | |
|
015be34169 | |
|
b9c153ddf3 | |
|
693ba4c3fe | |
|
22449d72c0 | |
|
238f9368c2 | |
|
971da5408f | |
|
6fc5f4703b | |
|
9b7a9ed7ef | |
|
bf14e33977 | |
|
28ee02b0eb | |
|
d4ed6cae5b | |
|
3968562049 | |
|
e132410296 | |
|
0a64fbadcc | |
|
c656bc4a08 | |
|
dc88a596b3 | |
|
b4f8743bfc | |
|
420c44ea6b | |
|
2bc0535881 | |
|
90c3ca329d | |
|
54d5f08d76 | |
|
798c2f4d09 | |
|
7cf0dd5217 | |
|
64c62b53b4 | |
|
516d8258ca | |
|
57d357afee | |
|
a6b490ef83 | |
|
051b8ac8d2 | |
|
8f7fc79007 | |
|
f9ca9e34de | |
|
edb458dfcb | |
|
a3bb1fba4a | |
|
afd10b27e2 | |
|
b2b1f2f161 | |
|
0e5ee4f41a | |
|
e88bfa6214 | |
|
7d527c6dd8 | |
|
85edb458f4 | |
|
b8cbd5358f | |
|
02a711f143 | |
|
74f0d01f33 | |
|
ae4969cfa3 | |
|
6217ba0bd1 | |
|
67147853f7 | |
|
2fa3c3335a | |
|
d0c08bf0dd | |
|
bce7526da1 | |
|
623397c674 | |
|
e95ac67d4b | |
|
39bf3f1291 | |
|
3729a239fc | |
|
618e8b9d71 | |
|
8713809b35 | |
|
3dc1514ab9 | |
|
04f8ac0454 | |
|
2705d06fa6 | |
|
e3783d3039 | |
|
068e8d0ae3 | |
|
e773bc9a69 | |
|
25442ad2e6 | |
|
7014e5bb67 | |
|
9c00b725f9 | |
|
55cb5ad46f | |
|
d5a7d38029 | |
|
3cd62b3e41 | |
|
edf1314def | |
|
75dff12823 | |
|
3bd97cc795 | |
|
fb8e527afc | |
|
407f213a7f | |
|
c78bcbb076 | |
|
8378272412 | |
|
77a9a450d2 | |
|
1216bdaebc | |
|
b649bf454c | |
|
ba95bce198 | |
|
e39167a9d8 | |
|
749a889bf2 | |
|
1bf4ce81b1 | |
|
83fe101576 | |
|
c077579240 | |
|
b7dbeeac49 | |
|
3afdbaf651 | |
|
8d6d960153 | |
|
2747426b7c | |
|
1126b65b6a | |
|
0db56499c2 | |
|
d7a591dc73 | |
|
88619eb58c | |
|
52a3457037 | |
|
7e4bdb5b07 | |
|
60de1423aa | |
|
0abc7d8251 | |
|
b71ed933a8 | |
|
55c7eba954 | |
|
0c59f20b91 | |
|
62387107f9 | |
|
77335c8d82 | |
|
3a79a8d398 | |
|
f797987710 | |
|
bd6adff9a5 | |
|
11e5e94ac2 | |
|
4fe4b6dd14 | |
|
8ce962a3bd | |
|
705a5c66a8 | |
|
3325aebbff | |
|
7b7660af60 | |
|
d5ecc1b468 |
11
HACKING
11
HACKING
|
@ -44,9 +44,10 @@ The test framework also requires CPPUnit:
|
|||
|
||||
For the GUI and its D-Bus based service backend:
|
||||
apt-get install xsltproc \
|
||||
libdbus-glib-1-dev \
|
||||
libglib2.0-dev \
|
||||
libgtk2.0-dev libglade2-dev \
|
||||
libgnome-keyring-dev \
|
||||
libsecret-1-dev \
|
||||
libgconf2-dev libgnomevfs2-dev
|
||||
|
||||
Optional packages for GUI:
|
||||
|
@ -78,8 +79,8 @@ It depends on:
|
|||
Checking out the Source
|
||||
-----------------------
|
||||
|
||||
SyncEvolution is hosted on moblin.org. Anonymous access is via
|
||||
git clone git://git.moblin.org/syncevolution.git
|
||||
SyncEvolution is hosted on freedesktop.org. Anonymous access is via
|
||||
git clone git://anongit.freedesktop.org/SyncEvolution/syncevolution
|
||||
|
||||
Before using sources checked out from Subversion, invoke "sh
|
||||
autogen.sh" with appropriate autotools packages installed.
|
||||
|
@ -93,9 +94,9 @@ faster compilation) and will bundle the Synthesis sources in source
|
|||
|
||||
The upstream Synthesis source code is here:
|
||||
git://www.synthesis.ch/libsynthesis.git
|
||||
The staging area for patches developed as part of Moblin are
|
||||
The staging area for patches developed as part of SyncEvolution are
|
||||
in the following repository:
|
||||
git://git.moblin.org/libsynthesis.git
|
||||
git://anongit.freedesktop.org/SyncEvolution/libsynthesis
|
||||
|
||||
The intention is to include all these patches upstream to
|
||||
prevent forking the code. If you want to get patches included
|
||||
|
|
29
Makefile.am
29
Makefile.am
|
@ -16,14 +16,8 @@ endif
|
|||
|
||||
SUBDIRS += .
|
||||
|
||||
# choose D-Bus implementation
|
||||
if COND_GIO_GDBUS
|
||||
gdbus_dir = $(top_srcdir)/src/gdbusxx
|
||||
gdbus_build_dir = src/gdbusxx
|
||||
else
|
||||
gdbus_dir = $(top_srcdir)/src/gdbus
|
||||
gdbus_build_dir = src/gdbus
|
||||
endif
|
||||
|
||||
disted_docs =
|
||||
distbin_docs =
|
||||
|
@ -132,7 +126,7 @@ TYPE_rpm = -R
|
|||
# - same for kdepimlibs5 -> libakonadi-kde4
|
||||
# - kdebase-runtime became kde-runtime in Debian Wheezy
|
||||
REQUIRES_SED_KDE = -e 's/kdelibs5 ([^,]*),/kdelibs5 | libkdeui5,/g' -e 's/kdepimlibs5 ([^,]*),/kdepimlibs5 | libakonadi-kde4,/g' -e 's/kdebase-runtime/kdebase-runtime | kde-runtime/g'
|
||||
REQUIRES_deb = --requires="'$(shell set -x; cd checkinstall/dist; LD_LIBRARY_PATH=$(distdir)/usr/lib:$(distdir)/usr/lib/syncevolution dpkg-shlibdeps -L$(srcdir)/src/shlibs.local --ignore-missing-info -O $$(for i in $$(find $(distdir) -type f -perm /u+x | grep -v -e client-test -e lib/syncevolution/backends/); do if file $$i | grep ELF >/dev/null; then echo $$i; fi; done) | sed $(REQUIRES_SED_KDE) -e 's/[^=]*=//')$(REQUIRES_deb_neon)$(REQUIRES_deb_ical)'"
|
||||
REQUIRES_deb = --requires="'$(shell set -x; cd checkinstall/dist; LD_LIBRARY_PATH=$(distdir)/usr/lib:$(distdir)/usr/lib/syncevolution dpkg-shlibdeps -L$(EXTRA_SHLIBS_LOCAL) --ignore-missing-info -O $$(for i in $$(find $(distdir) -type f -perm /u+x | grep -v -e client-test -e lib/syncevolution/backends/); do if file $$i | grep ELF >/dev/null; then echo $$i; fi; done) | sed $(REQUIRES_SED_KDE) -e 's/[^=]*=//')$(REQUIRES_deb_neon)'"
|
||||
if NEON_COMPATIBILITY
|
||||
# --enable-neon-compatibility in src/backends/webdav:
|
||||
# replace dependencies from linking with hard-coded dlopen() dependencies
|
||||
|
@ -140,9 +134,6 @@ REQUIRES_deb_neon = , libneon27 (>= 0.29.0) | libneon27-gnutls (>= 0.29.0)
|
|||
else
|
||||
REQUIRES_deb_neon =
|
||||
endif
|
||||
if ENABLE_ICAL
|
||||
REQUIRES_deb_ical = , libical0 | libical1 | libical1a | libical2
|
||||
endif
|
||||
VERSION_deb = 1:$(STABLE_VERSION)$(VERSION)
|
||||
VERSION_rpm = `echo $(VERSION) | sed -e s/-/_/g`
|
||||
RELEASE = 2
|
||||
|
@ -179,6 +170,7 @@ deb rpm : checkinstall/dist/$(distdir) checkinstall/dist/debian/control
|
|||
$(TYPE_$@) \
|
||||
$(REQUIRES_$@) \
|
||||
--fstrans=yes \
|
||||
--install=no \
|
||||
--strip=no \
|
||||
--pkgversion=$(VERSION_$@) \
|
||||
--pkgrelease=$(RELEASE) \
|
||||
|
@ -200,7 +192,8 @@ deb rpm : checkinstall/dist/$(distdir) checkinstall/dist/debian/control
|
|||
PLATFORM_DEB_VERSION = $(VERSION_deb)
|
||||
PLATFORM_DEB_RELEASE = 1
|
||||
if ENABLE_MODULES
|
||||
deb : syncevolution-kde-deb
|
||||
# Not supported anymore.
|
||||
# deb : syncevolution-kde-deb
|
||||
deb : syncevolution-evolution-deb
|
||||
endif
|
||||
|
||||
|
@ -220,6 +213,7 @@ SYNCEVOLUTION_evolution_DEB_ARGS = \
|
|||
--conflicts=syncevolution-foobar \
|
||||
--replaces=syncevolution-foobar
|
||||
SYNCEVOLUTION_evolution_DEB_REQUIRES = \
|
||||
, evolution-data-server \
|
||||
, $(EXTRA_BACKENDS_EBOOK_REQUIRES) \
|
||||
, $(EXTRA_BACKENDS_ECAL_REQUIRES)
|
||||
|
||||
|
@ -238,7 +232,7 @@ syncevolution-%-deb: checkinstall/dist/$(distdir) checkinstall/dist/debian/contr
|
|||
$(SYNCEVOLUTION_$*_DEB_ARGS) \
|
||||
--pkgname=syncevolution-$* \
|
||||
--pkgarch=all \
|
||||
--requires="'$(shell set -x; cd checkinstall/dist; LD_LIBRARY_PATH=$(distdir)/usr/lib:$(distdir)/usr/lib/syncevolution dpkg-shlibdeps -L$(srcdir)/src/shlibs.local --ignore-missing-info -O $$(for i in $(patsubst %,$(distdir)/usr/lib/syncevolution/backends/%.so,$(PLATFORM_FILES_$*)); do if file $$i | grep ELF >/dev/null; then echo $$i; fi; done) | sed $(REQUIRES_SED_KDE) -e 's/[^=]*=//'), $(PKGNAME) (= $(VERSION_deb)-$(RELEASE))$(SYNCEVOLUTION_$*_DEB_REQUIRES)'" \
|
||||
--requires="'$(shell set -x; cd checkinstall/dist; LD_LIBRARY_PATH=$(distdir)/usr/lib:$(distdir)/usr/lib/syncevolution dpkg-shlibdeps -L$(EXTRA_SHLIBS_LOCAL) --ignore-missing-info -O $$(for i in $(patsubst %,$(distdir)/usr/lib/syncevolution/backends/%.so,$(PLATFORM_FILES_$*)); do if file $$i | grep ELF >/dev/null; then echo $$i; fi; done) | sed $(REQUIRES_SED_KDE) -e 's/[^=]*=//'), $(PKGNAME) (= $(VERSION_deb)-$(RELEASE))$(SYNCEVOLUTION_$*_DEB_REQUIRES)'" \
|
||||
--maintainer="'Patrick Ohly <patrick.ohly@gmx.de>'" \
|
||||
--pkgsource='http://syncevolution.org' \
|
||||
--pkggroup='$*' \
|
||||
|
@ -351,9 +345,10 @@ RUN_SYNCEVOLUTION_CHECK=die if $$?; return $$buffer;
|
|||
endif
|
||||
|
||||
# patch README.rst properties on-the-fly
|
||||
if COND_CMDLINE
|
||||
README.patched.rst: README.rst src/syncevolution
|
||||
$(AM_V_GEN)perl -e '$$syncfound=0; $$sourcefound=0; $$res=0;' \
|
||||
-e 'sub run { $$cmd = shift; $$buffer = `env LD_LIBRARY_PATH=src/syncevo/.libs:src/gdbus/.libs:src/gdbusxx/.libs:src/build-synthesis/src/.libs:$$ENV{LD_LIBRARY_PATH} $$cmd`; $(RUN_SYNCEVOLUTION_CHECK) }' \
|
||||
-e 'sub run { $$cmd = shift; $$buffer = `env LD_LIBRARY_PATH=src/syncevo/.libs:src/gdbusxx/.libs:src/build-synthesis/src/.libs:$$ENV{LD_LIBRARY_PATH} $$cmd`; $(RUN_SYNCEVOLUTION_CHECK) }' \
|
||||
-e 'while (<>) {' \
|
||||
-e 's/^:Version: .*/:Version: $(VERSION)/;' \
|
||||
-e 's/:Date: .*/":Date: " . `date +%Y-%m-%d`/e;' \
|
||||
|
@ -365,6 +360,14 @@ README.patched.rst: README.rst src/syncevolution
|
|||
-e 'die "<<source-property>> tag not in README.rst?!" unless $$sourcefound;' \
|
||||
-e 'exit $$res;' \
|
||||
$< >$@
|
||||
else
|
||||
# Simpler version without inserting the actual sync and datastore properties.
|
||||
README.patched.rst: README.rst
|
||||
$(AM_V_GEN)perl -p \
|
||||
-e 's/^:Version: .*/:Version: $(VERSION)/;' \
|
||||
-e 's/:Date: .*/":Date: " . `date +%Y-%m-%d`/e;' \
|
||||
$< >$@
|
||||
endif
|
||||
CLEANFILES += README.patched.rst
|
||||
|
||||
# produce man pages
|
||||
|
|
83
NEWS
83
NEWS
|
@ -1,3 +1,86 @@
|
|||
SyncEvolution 1.5.3 -> 2.0.0, 21.03.2021
|
||||
========================================
|
||||
|
||||
This release modernizes the code base and removes usage of out-dated
|
||||
libraries and APIs. All Python scripts require Python 3. The major
|
||||
version bump reflects that this release is not just a minor bug fix.
|
||||
However, no new features were added.
|
||||
|
||||
Binaries on syncevolution.org get built for distros >= Ubuntu Bionic
|
||||
and Debian Buster. Testing is now based on Docker containers instead
|
||||
of a custom schroot solution, so adding testing against other distros
|
||||
will be easier in the future. Compilation on Fedora Rawhide was
|
||||
already added.
|
||||
|
||||
Some features are no longer built and thus untested:
|
||||
- ActiveSync
|
||||
- KDE
|
||||
|
||||
The code is still there, but needs help from interested developers to
|
||||
ensure that it really works. It may get removed in a future version if
|
||||
there is no interest.
|
||||
|
||||
|
||||
SyncEvolution 1.5.2 -> 1.5.3, 03.01.2018
|
||||
========================================
|
||||
|
||||
Maintenance release. syncevolution.org binaries are now getting
|
||||
compiled for distros >= Ubuntu Xenial 16.04 LTS. Usage of deprecated
|
||||
libraries (GNOME keyring) and APIs (SoupAsyncSession) was
|
||||
replaced. libical v3 is supported.
|
||||
|
||||
The code now compiles more cleanly with recent compilers and depends
|
||||
on C++11 support.
|
||||
|
||||
Details:
|
||||
|
||||
* EDS: more generic open retry handling
|
||||
|
||||
Recent EDS started to exhibit race conditions when opening a database (for
|
||||
example, https://bugzilla.gnome.org/show_bug.cgi?id=791306). Opening was
|
||||
already tried again for a certain known error in some old EDS version. Now it
|
||||
is tried five times with a delay of one second for all errors.
|
||||
|
||||
* SoupTransportAgent: require libsoup 2.42, no deprecated methods
|
||||
|
||||
This allows us to get rid of deprecated function calls. We no longer
|
||||
need to set a default proxy either, the newer libsoup does that itself
|
||||
by default.
|
||||
|
||||
* C++: replace auto_ptr with unique_ptr, require C++11
|
||||
|
||||
auto_ptr has been deprecated for a while now. unique_ptr can
|
||||
be taken for granted now, so use that instead.
|
||||
|
||||
* testing: work around Google CalDAV RECURRENCE-ID
|
||||
|
||||
Stand-alone events with RECURRENCE-ID get mangled by the server:
|
||||
it converts the RECURRENCE-ID time to UTC. Reported in:
|
||||
https://stackoverflow.com/questions/47811670/detached-recurrence-without-parent-event
|
||||
|
||||
* GNOME: replace gnome-keyring with libsecret (FDO #104219)
|
||||
|
||||
The GNOME keyring library has been obsoleted for a long time now,
|
||||
long enough that the replacement libsecret is available on all
|
||||
supported distros. Therefore we can switch unconditionally.
|
||||
|
||||
* libical: support libical v3 (FDO #104220)
|
||||
|
||||
libical v3 removes some deprecated functions (like icaltime_from_timet)
|
||||
and removes the "is_utc" member from icaltimetype. The replacement
|
||||
code works with old and new libical and thus needs no ifdefs.
|
||||
|
||||
Original author: Milan Crha
|
||||
|
||||
* syncevolution.org: fixed packaging (FDO #98014, FDO #100549)
|
||||
|
||||
The activesyncd package missing dependencies on libgnome-keyring0 and
|
||||
libglib2.0-bin and therefore failed to work when installed on a minimal
|
||||
system without those.
|
||||
|
||||
* various build and test fixes/workarounds
|
||||
|
||||
|
||||
SyncEvolution 1.5.1 -> 1.5.2, 08.11.2016
|
||||
========================================
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ dist_noinst_SCRIPTS += build/gen-git-version.sh \
|
|||
|
||||
EXTRA_DIST += \
|
||||
build/export-foreign-git.sh \
|
||||
build/export-gdbus.sh \
|
||||
build/export-synthesis-xml.sh \
|
||||
build/gen-backends-am.sh \
|
||||
build/gen-backends.sh \
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
#! /bin/sh
|
||||
#
|
||||
# Run this inside the top level of a clean
|
||||
# syncevolution git repository. Pass the path
|
||||
# to a gdbus repository (default: ../libgdbus).
|
||||
#
|
||||
# The script generates .patch files for all changes
|
||||
# made in the current branch to files which are
|
||||
# shared with gdbus. The resulting files can
|
||||
# be imported with "git am".
|
||||
|
||||
set -e
|
||||
set -x
|
||||
|
||||
`dirname $0`/export-foreign-git.sh "${1:-../libgdbus}" src src/gdbus \
|
||||
src/gdbus/debug.c \
|
||||
src/gdbus/debug.h \
|
||||
src/gdbus/gdbus.h \
|
||||
src/gdbus/mainloop.c \
|
||||
src/gdbus/object.c \
|
||||
src/gdbus/watch.c
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/python
|
||||
#!/usr/bin/python3
|
||||
|
||||
"""
|
||||
Converts source code (first parameter, can be - for stdin) to HTML
|
||||
|
@ -29,8 +29,8 @@ try:
|
|||
pygments.highlight(code, lexer, formatter, out)
|
||||
except:
|
||||
import cgi
|
||||
print >>sys.stderr, "source2html.py failed with pygments:", sys.exc_info()
|
||||
print >>sys.stderr, "falling back to internal code"
|
||||
print("source2html.py failed with pygments:", sys.exc_info(), file=sys.stderr)
|
||||
print("falling back to internal code", file=sys.stderr)
|
||||
|
||||
out.write('''<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
|
|
145
configure.ac
145
configure.ac
|
@ -8,7 +8,7 @@ dnl Invoke autogen.sh to produce a configure script.
|
|||
#
|
||||
# Starting with the 1.1 release cycle, the rpm-style
|
||||
# .99 pseudo-version number is used to mark a pre-release.
|
||||
AC_INIT([syncevolution], [m4_esyscmd([build/gen-git-version.sh 1.5.2])])
|
||||
AC_INIT([syncevolution], [m4_esyscmd([build/gen-git-version.sh 2.0.0])])
|
||||
# STABLE_VERSION=1.0.1+
|
||||
AC_SUBST(STABLE_VERSION)
|
||||
|
||||
|
@ -62,6 +62,19 @@ dnl check for programs.
|
|||
AC_PROG_CXX
|
||||
AC_PROG_MAKE_SET
|
||||
|
||||
AC_PATH_PROGS(PYTHON, python3 python, "")
|
||||
if test "x$PYTHON" = "x" ; then
|
||||
AC_ERROR([python3 not found])
|
||||
fi
|
||||
|
||||
dnl Use the most recent C++ standard that is supported by the code.
|
||||
dnl We can fall back to older versions, but not below C++11.
|
||||
dnl Akonadi/Qt don't work with C++17 yet, so we can't enable that.
|
||||
AX_CXX_COMPILE_STDCXX_14(noext, optional)
|
||||
if test "$HAVE_CXX14" -ne 1; then
|
||||
AX_CXX_COMPILE_STDCXX_11(noext, mandatory)
|
||||
fi
|
||||
|
||||
# Boost headers: boost/foreach.hpp is needed (1.33/Debian Etch
|
||||
# doesn't have it, 1.34/Ubuntu 8.10 Hardy does). 1.35 is available
|
||||
# as Debian Etch backport.
|
||||
|
@ -70,8 +83,17 @@ AX_BOOST_BASE(1.34)
|
|||
# TODO: Fix code to pass with -pedantic -Wextra.
|
||||
# -Wno-unknown-pragmas needed because icalstrdup.h
|
||||
# currently uses the "#pragma }" trick. Should remove that.
|
||||
# Fix code to work without deprecated methods: G GDK GDK_PIXBUF CAIRO PANGO GTK
|
||||
# -Wno-deprecated-declarations is needed everywhere (i.e. not just in certain
|
||||
# modules, like SYNCEVO_WFLAGS_DEPRECATED) because EDS on Ubuntu Eon uses
|
||||
# the deprecated GDateTime in its header, which we included through our
|
||||
# EDS/libical wrapper even when not actually used.
|
||||
DK_ARG_ENABLE_WARNINGS([SYNCEVO_WFLAGS],
|
||||
[-Wall -Wno-unknown-pragmas],
|
||||
[-Wall -Wno-unknown-pragmas -Wno-deprecated-declarations],
|
||||
[])
|
||||
|
||||
# Fix code to work without deprecated methods: G GDK GDK_PIXBUF CAIRO PANGO GTK
|
||||
DK_ARG_ENABLE_WARNINGS([SYNCEVO_WFLAGS_DEPRECATED],
|
||||
[-Wall -Wno-unknown-pragmas -Wno-deprecated-declarations],
|
||||
[-Wall -Wno-unknown-pragmas -Wno-deprecated-declarations],
|
||||
[])
|
||||
|
@ -223,12 +245,9 @@ else
|
|||
have_libcurl="no"
|
||||
fi
|
||||
|
||||
PKG_CHECK_MODULES(LIBSOUP, libsoup-gnome-2.4,
|
||||
[have_libsoup="yes"
|
||||
AC_DEFINE(HAVE_LIBSOUP_SOUP_GNOME_FEATURES_H, 1, [enable GNOME specific libsoup])],
|
||||
[PKG_CHECK_MODULES(LIBSOUP, libsoup-2.4,
|
||||
have_libsoup="yes",
|
||||
have_libsoup="no")])
|
||||
PKG_CHECK_MODULES(LIBSOUP, libsoup-2.4 >= 2.42,
|
||||
have_libsoup="yes",
|
||||
have_libsoup="no")
|
||||
|
||||
PKG_CHECK_MODULES(LIBOPENOBEX, openobex, have_obex="yes", have_obex="no")
|
||||
have_bluetooth="no"
|
||||
|
@ -477,6 +496,18 @@ AC_ARG_ENABLE(core,
|
|||
enable_core="$enableval",
|
||||
enable_core="yes")
|
||||
AM_CONDITIONAL([COND_CORE], [test "$enable_core" = "yes"])
|
||||
AC_ARG_ENABLE(cmdline,
|
||||
AS_HELP_STRING([--enable-cmdline],
|
||||
[enables building the SyncEvolution command line tool, syncevolution]),
|
||||
enable_cmdline="$enableval",
|
||||
enable_cmdline="yes")
|
||||
AM_CONDITIONAL([COND_CMDLINE], [test "$enable_cmdline" = "yes"])
|
||||
AC_ARG_ENABLE(local-sync,
|
||||
AS_HELP_STRING([--enable-local-sync],
|
||||
[enables building the local synchronization support, in particular syncevo-local-sync]),
|
||||
enable_local_sync="$enableval",
|
||||
enable_local_sync="yes")
|
||||
AM_CONDITIONAL([COND_LOCAL_SYNC], [test "$enable_local_sync" = "yes"])
|
||||
|
||||
AC_ARG_ENABLE(dbus-service,
|
||||
AS_HELP_STRING([--enable-dbus-service=args],
|
||||
|
@ -498,33 +529,15 @@ if test "$enable_dbus_service" != "no" && test "$enable_dbus_service" != "yes";
|
|||
fi
|
||||
AC_SUBST(SYNCEVO_DBUS_SERVER_ARGS)
|
||||
|
||||
AC_ARG_WITH([gio-gdbus],
|
||||
AS_HELP_STRING([--with-gio-gdbus],
|
||||
[enables use of GIO's GDBus instead of the in-tree, Bluez gdbus.]),
|
||||
with_gio_gdbus="$withval",
|
||||
PKG_CHECK_EXISTS([gio-2.0 >= 2.30],
|
||||
[with_gio_gdbus="yes"],
|
||||
[with_gio_gdbus="no"]))
|
||||
AM_CONDITIONAL([COND_GIO_GDBUS], [test "x$with_gio_gdbus" = "xyes"])
|
||||
|
||||
# We only need to check for dbus-1 if gio-gdbus is not used.
|
||||
#
|
||||
# Local sync depends on D-Bus communication between parent
|
||||
# and child process (works without a D-Bus daemon), and local
|
||||
# sync is not an optional feature. Could be made one if
|
||||
# someone is interested enough.
|
||||
#
|
||||
# Therefore, at the moment, either libdbus or gio-gdbus are needed
|
||||
# Therefore, at the moment, gio-gdbus is needed
|
||||
# unconditionally. glib is needed in all cases now.
|
||||
need_glib=yes
|
||||
AS_IF([test "x$with_gio_gdbus" = "xyes"],
|
||||
[PKG_CHECK_MODULES([DBUS], [gio-2.0 >= 2.26])
|
||||
AC_DEFINE([WITH_GIO_GDBUS],[],[Set if using GIO GDBus])],
|
||||
[PKG_CHECK_MODULES(DBUS, dbus-1, dummy=yes,
|
||||
AC_MSG_ERROR(libdbus-1 is required))
|
||||
AC_CHECK_LIB(dbus-1, dbus_watch_get_unix_fd, dummy=yes,
|
||||
AC_DEFINE(NEED_DBUS_WATCH_GET_UNIX_FD, 1,
|
||||
[Define to 1 if you need the dbus_watch_get_unix_fd() function.]))])
|
||||
PKG_CHECK_MODULES([DBUS], [gio-2.0 >= 2.26])
|
||||
|
||||
if test "$enable_dbus_service" != "no"; then
|
||||
if test -z "$XSLT"; then
|
||||
|
@ -559,74 +572,7 @@ if test "$enable_dbus_service" != "no"; then
|
|||
MLITE_LIBS=
|
||||
fi
|
||||
AC_DEFINE(DBUS_SERVICE, 1, [define if dbus service is enabled])
|
||||
|
||||
AC_ARG_ENABLE(dbus-service-pim,
|
||||
AS_HELP_STRING([--enable-dbus-service-pim[=<locale>]],
|
||||
[Enable implementation of org._01.pim D-Bus APIs (depends on libfolks),
|
||||
using src/dbus/server/pim/locale-factory-<locale>.cpp to implement sorting
|
||||
and searching. The default is <locale>=boost, which uses boost::locale.]),
|
||||
[ enable_dbus_pim="$enableval" ],
|
||||
[ enable_dbus_pim="no" ])
|
||||
case "$enable_dbus_pim" in
|
||||
no) ;;
|
||||
*)
|
||||
if test "$enable_dbus_pim" = "yes"; then
|
||||
enable_dbus_pim=boost
|
||||
fi
|
||||
if ! test -r "$srcdir/src/dbus/server/pim/locale-factory-$enable_dbus_pim.cpp"; then
|
||||
AC_MSG_ERROR([invalid value '$enable_dbus_pim' for --enable-dbus-service-pim, $srcdir/src/dbus/server/pim/locale-factory-$enable_dbus_pim.cpp does not exist or is not readable])
|
||||
fi
|
||||
PKG_CHECK_MODULES(FOLKS, [folks folks-eds])
|
||||
AC_DEFINE(ENABLE_DBUS_PIM, 1, [org._01.pim D-Bus API enabled])
|
||||
DBUS_PIM_PLUGIN=$enable_dbus_pim
|
||||
AC_SUBST(DBUS_PIM_PLUGIN)
|
||||
|
||||
case "$enable_dbus_pim" in
|
||||
boost)
|
||||
AX_BOOST_LOCALE
|
||||
# AX_BOOST_LOCALE incorrectly puts -L/... into LDFLAGS.
|
||||
# That's broken because it then overrides the search path
|
||||
# for *all* libraries in a link, not just for boost. Fix
|
||||
# this by putting the LDFLAGS before the lib and leaving
|
||||
# DBUS_PIM_PLUGIN_LDFLAGS empty (for now - might have to
|
||||
# be revised if there ever are any boost flags which need
|
||||
# to go to the start of the link line).
|
||||
DBUS_PIM_PLUGIN_LIBS='$(BOOST_LDFLAGS) $(BOOST_LOCALE_LIB)'
|
||||
DBUS_PIM_PLUGIN_LDFLAGS=
|
||||
# We need to call ICU directly for the Han->Latin transformation.
|
||||
PKG_CHECK_MODULES(ICU, [icu-uc icu-i18n])
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(DBUS_PIM_PLUGIN_CFLAGS)
|
||||
AC_SUBST(DBUS_PIM_PLUGIN_LIBS)
|
||||
AC_SUBST(DBUS_PIM_PLUGIN_LDFLAGS)
|
||||
|
||||
# http://code.google.com/p/libphonenumber/
|
||||
AC_LANG(C++)
|
||||
SAVED_CPPFLAGS=$CPPFLAGS
|
||||
if test ! "$PHONENUMBERS_CFLAGS"; then
|
||||
PHONENUMBERS_CFLAGS=-DI18N_PHONENUMBERS_USE_BOOST
|
||||
fi
|
||||
CPPFLAGS="$CPPFLAGS ${PHONENUMBERS_CFLAGS}"
|
||||
AC_CHECK_HEADERS([phonenumbers/phonenumberutil.h])
|
||||
SAVED_LIBS=$LIBS
|
||||
if test ! "$PHONENUMBERS_LIBS"; then
|
||||
PHONENUMBERS_LIBS=-lphonenumber
|
||||
fi
|
||||
LIBS="$LIBS $PHONENUMBERS_LIBS"
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM([#include <phonenumbers/phonenumberutil.h>],
|
||||
[i18n::phonenumbers::PhoneNumberUtil::GetInstance()])],
|
||||
[true],
|
||||
[AC_ERROR([libphonebook not found, set PHONENUMBERS_CFLAGS and PHONENUMBERS_LIBS.])])
|
||||
AC_SUBST(PHONENUMBERS_CFLAGS)
|
||||
AC_SUBST(PHONENUMBERS_LIBS)
|
||||
LIBS=$SAVED_LIBS
|
||||
CPPFLAGS=$SAVED_CPPFLAGS
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
AM_CONDITIONAL([COND_DBUS_PIM], [test "$enable_dbus_pim" != "no"])
|
||||
|
||||
AC_SUBST(DBUS_CFLAGS)
|
||||
AC_SUBST(DBUS_LIBS)
|
||||
|
@ -718,14 +664,6 @@ AC_SUBST(GUI_LIBS)
|
|||
AC_SUBST(GUI_PROGRAMS)
|
||||
AC_SUBST(GUI_DESKTOP_FILES)
|
||||
|
||||
# C++ regular expression support is required often enough to make it
|
||||
# mandatory.
|
||||
PKG_CHECK_MODULES(PCRECPP, libpcrecpp,,
|
||||
AC_CHECK_LIB(pcrecpp,main,
|
||||
AC_SUBST(PCRECPP_LIBS,-lpcrecpp),
|
||||
AC_MSG_ERROR([pcrecpp not found])
|
||||
))
|
||||
|
||||
# need rst2man for man pages
|
||||
AC_ARG_WITH(rst2man,
|
||||
AS_HELP_STRING([--with-rst2man=<path to reStructuredText to man converter>],
|
||||
|
@ -1132,7 +1070,6 @@ echo "libical v1 timezone hack: $enable_icaltz_util"
|
|||
echo "DBus service: $enable_dbus_service"
|
||||
echo "org._01.pim support in DBus service: $enable_dbus_pim"
|
||||
echo "Notifications: $enable_notify"
|
||||
echo "GIO GDBus: $with_gio_gdbus"
|
||||
echo "GNOME keyring: $enable_gnome_keyring"
|
||||
if test "$enable_gui" = "no"; then
|
||||
echo "UI (DBus client): no"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
syncevolution (1.3.99.7-1) unstable; urgency=high
|
||||
|
||||
* Akonadi support for KDE is now enabled. The support for GNOME and KDE
|
||||
Akonadi support for KDE is now enabled. The support for GNOME and KDE
|
||||
has been split into new packages named syncevolution-libs-gnome and
|
||||
syncevolution-libs-kde. If you only want to use KDE, you can remove
|
||||
syncevolution-libs-gnome.
|
||||
|
@ -9,7 +9,7 @@ syncevolution (1.3.99.7-1) unstable; urgency=high
|
|||
|
||||
syncevolution (1.2.99.1-1) unstable; urgency=low
|
||||
|
||||
* The sync format of existing configurations for Mobical (aka Everdroid)
|
||||
The sync format of existing configurations for Mobical (aka Everdroid)
|
||||
must be updated manually, because the server has encoding problems when
|
||||
using vCard 3.0 (now the default for Evolution contacts):
|
||||
|
||||
|
@ -17,7 +17,7 @@ syncevolution (1.2.99.1-1) unstable; urgency=low
|
|||
syncFormat=text/x-vcard \
|
||||
mobical addressbook
|
||||
|
||||
* The Funambol template explicitly enables usage of the
|
||||
The Funambol template explicitly enables usage of the
|
||||
"refresh-from-server" sync mode to avoid getting throttled with 417
|
||||
'retry later' errors. The same must be added to existing configs
|
||||
manually:
|
||||
|
@ -30,11 +30,11 @@ syncevolution (1.2.99.1-1) unstable; urgency=low
|
|||
|
||||
syncevolution (1.1.99.5a-1) experimental; urgency=low
|
||||
|
||||
* This version of syncevolution introduces an irreversible change to the
|
||||
This version of syncevolution introduces an irreversible change to the
|
||||
config layout, see the --migrate option in the syncevolution man page.
|
||||
Migration happens automatically at first invocation.
|
||||
|
||||
* This version is only know to work with version 2.32.2 of evolution.
|
||||
This version is only know to work with version 2.32.2 of evolution.
|
||||
In particular, it probably won't work with the version of evolution in
|
||||
squeeze.
|
||||
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
Building syncevolution for Debian
|
||||
---------------------------------
|
||||
|
||||
The source package needs no special instructions; the discussion here
|
||||
is about working with the git repository.
|
||||
|
||||
Patches are exported based on debian/source/git-patches; each line is
|
||||
an argument to git-format-patch. The variables $DEB_VERSION and
|
||||
$UPSTREAM_VERSION are the Debian and upstream version being exported.
|
||||
You can either use git-format-patch manually, or install gitpkg
|
||||
version 0.17 or later.
|
||||
|
||||
1) To have the patches automatically exported at source package creation time
|
||||
|
||||
a) to setup gitpkg, run
|
||||
|
||||
% git config gitpkg.deb-export-hook /usr/share/gitpkg/hooks/quilt-patches-deb-export-hook
|
||||
|
||||
b) run
|
||||
|
||||
% gitpkg master
|
||||
|
||||
to make a source package.
|
||||
|
||||
2) To manually export patches, run
|
||||
|
||||
% ./debian/rules export-patches
|
||||
|
||||
The original source tarballs are stored in the git repo using
|
||||
pristine-tar. You can (optionally) check out the current tarball by
|
||||
|
||||
git branch pristine-tar origin/pristine-tar
|
||||
# UPSTREAM should be the current upstream version
|
||||
pristine-tar checkout ../syncevolution_$(UPSTREAM).orig.tar.gz
|
||||
|
||||
-- David Bremner <bremner@debian.org>, Tue, 8 Mar 2011 19:34:24 -0400
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
- add missing manpages for syncompare and syncevo-http-server
|
||||
- clean up src/syncevo/CmdLine.cpp(.orig|.rej)
|
||||
|
||||
-- David Bremner <bremner@debian.org>, Thu, 11 Nov 2010 11:48:32 -0400
|
||||
* add missing manpages for syncompare and syncevo-http-server
|
||||
* fix FTPFS with g++ 11 without CXXFLAG -std=c++14;
|
||||
see <https://gitlab.freedesktop.org/SyncEvolution/syncevolution/-/issues/167>
|
||||
|
|
|
@ -1,3 +1,109 @@
|
|||
syncevolution (2.0.0-2) experimental; urgency=medium
|
||||
|
||||
[ Jonas Smedegaard ]
|
||||
* update copyright info:
|
||||
+ fix consistently use field License-Grant (not Grant)
|
||||
+ fix consistently use field Files (not bogus File)
|
||||
+ fix add License section LGPL-2
|
||||
+ tighten license-related lintian overrides
|
||||
* fix have syncevolution-http depend on python3-gi
|
||||
(not bogus python3-gobject:
|
||||
earlier transitional package python-gobject pulled in python-gi)
|
||||
* fix drop depending on python3-twisted-web:
|
||||
bogus (transitioned to python3-twisted-core)
|
||||
and used only by exerimental unused script
|
||||
* tighten dh-missing to fail (not only warn) on missed files
|
||||
+ list unversioned symlinks to shared objects as not-installed
|
||||
+ list helper scripts for testing as not-installed
|
||||
* fix install XDG startup files in syncevolution-dbus
|
||||
* fix install SRV resolver script in syncevolution-common,
|
||||
recommend adns-utils (or simpler fallbacks),
|
||||
and have syncevolution-libs recommend syncevolution-common
|
||||
* work around FTPFS with g++ 11 by setting CXXFLAG -std=c++14
|
||||
|
||||
[ Joao Azevedo ]
|
||||
* list library syncactivesync.so as not installed
|
||||
(to match upstream intent in unconventional build target)
|
||||
* list TDEPIM libraries as not installed
|
||||
(we no longer link against KDE libraries so unlikely to be useful)
|
||||
* fix install libraries syncpbap providergoa
|
||||
|
||||
-- Jonas Smedegaard <dr@jones.dk> Wed, 03 Nov 2021 15:50:49 +0100
|
||||
|
||||
syncevolution (2.0.0-1) experimental; urgency=medium
|
||||
|
||||
[ upstream ]
|
||||
* new release
|
||||
|
||||
[ Jonas Smedegaard ]
|
||||
* isolate kfreebsd FTBFS fix as patch 1001,
|
||||
and track package source with patches unapplied
|
||||
* add git-buildpackage config:
|
||||
+ use pristine-tar
|
||||
+ sign tags
|
||||
+ avoid any .git* files
|
||||
+ use DEP-14 branches debian/latest upstream/latest
|
||||
+ add usage comment
|
||||
* drop obsolete *-dbg to *-dbgsym migration
|
||||
* simplify rules;
|
||||
stop explicitly build-depend on libtool automake pkg-config
|
||||
(pulled in via autoreconf since debhelper compatibility level 10)
|
||||
* use debhelper compatibility level 13 (not 11);
|
||||
build-depend on debhelper-compat (not debhelper)
|
||||
* relax to stop build-depend explicitly on g++:
|
||||
required version satisfied by default
|
||||
in all supported Debian releases
|
||||
* drop ancient Breaks/Replaces hints
|
||||
* stop link against KDE libraries (no longer supported upstream):
|
||||
+ drop binary package syncevolution-libs-kde
|
||||
+ stop build-depend on kdelibs5-dev kdepimlibs5-dev
|
||||
* stop install library to support ActiveSync
|
||||
(no longer supported upstream)
|
||||
* use Python 3.x libraries:
|
||||
+ build-depend on python3-docutils (not python-docutils)
|
||||
+ have syncevolution-http depend on python3 python3-dbus
|
||||
python3-gobject python3-openssl
|
||||
python3-pygments python3-twisted-web
|
||||
(not python python-dbus python-gobject
|
||||
python-openssl python-twisted-web)
|
||||
* stop build-depend on libpcre3-dev
|
||||
* build-depend on libecal2.0-dev (not libecal1.2-dev)
|
||||
* relax to build-depend unversioned on libsynthesis-dev:
|
||||
required version satisfied in all supported Debian releases
|
||||
* add patch 1002
|
||||
to adjust whitespace as required for recent autotools
|
||||
* fix install all pstream-provided gettext machine-object files
|
||||
* install all upstream-provided README.* files
|
||||
* install more example files
|
||||
* improve install tracking with dh_missing:
|
||||
package upstream-installed manpage (not source file)
|
||||
* explicitly list files deliberately not installed
|
||||
* stop install syncevolution-dbus example file dropped upstream
|
||||
* update install paths
|
||||
|
||||
[ João Azevedo ]
|
||||
* don't use install for syncevo-http-server.py
|
||||
|
||||
-- Jonas Smedegaard <dr@jones.dk> Tue, 05 Oct 2021 17:45:04 +0200
|
||||
|
||||
syncevolution (1.5.3-2) unstable; urgency=medium
|
||||
|
||||
* Remove libgconf2-dev build-dep (Closes: #897258)
|
||||
|
||||
-- Tino Mettler <tino+debian@tikei.de> Thu, 21 Jun 2018 21:19:04 +0200
|
||||
|
||||
syncevolution (1.5.3-1) unstable; urgency=medium
|
||||
|
||||
* New upstream release
|
||||
* Fix override_dh_makeshlibs to handle all packages with public shared libs
|
||||
(Closes: #887043)
|
||||
* Remove obsolete Conflicts:/Breaks:/Replaces: sync-ui (<<1.1+ds1-1~)
|
||||
* Change debhelper compatibility to 11, which is recommended
|
||||
* Bump standards version to 4.1.3, no changes needed
|
||||
* Fix several lintian warnings
|
||||
|
||||
-- Tino Mettler <tino+debian@tikei.de> Sat, 13 Jan 2018 22:47:44 +0100
|
||||
|
||||
syncevolution (1.5.2-3) unstable; urgency=medium
|
||||
|
||||
[ Patrick Ohly ]
|
||||
|
@ -7,12 +113,14 @@ syncevolution (1.5.2-3) unstable; urgency=medium
|
|||
[ Tino Mettler ]
|
||||
* Change build dependencies for libgtk and glade to use GTK3 for sync-ui
|
||||
(Closes: #884162)
|
||||
* Add Build-Dep on libjson-c-dev (Closes: #884170)
|
||||
* Add Build-Dep on libjson-c-dev, enable and include oauth2 backend
|
||||
(Closes: #884170)
|
||||
|
||||
* Handle C++ conversion operator name mangling in GCC 7 (Closes: #871284)
|
||||
* Build depend on libsecret-1-dev instead of deprecated libgnome-keyring-dev
|
||||
(Closes: #867944)
|
||||
|
||||
-- Tino Mettler <tino+debian@tikei.de> Thu, 04 Jan 2018 12:24:58 +0100
|
||||
-- Tino Mettler <tino+debian@tikei.de> Thu, 04 Jan 2018 22:21:57 +0100
|
||||
|
||||
syncevolution (1.5.2-2) unstable; urgency=medium
|
||||
|
||||
|
@ -208,7 +316,7 @@ syncevolution (1.1.99.4+ds1-1) experimental; urgency=low
|
|||
syncevolution (1.1.99.3+ds1-1) experimental; urgency=low
|
||||
|
||||
* New upstream (pre-release) version
|
||||
* Remove two s390 related patches, now contained in upstream
|
||||
* Remove two s390 related patches, now contained in upstream
|
||||
commit 63d76f874270cbafb2.
|
||||
|
||||
-- David Bremner <bremner@debian.org> Tue, 08 Mar 2011 16:05:30 -0400
|
||||
|
@ -224,7 +332,7 @@ syncevolution (1.1+ds1-5) unstable; urgency=low
|
|||
|
||||
syncevolution (1.1+ds1-4) experimental; urgency=low
|
||||
|
||||
* Remove build dependency on libopenobex1-dev on hurd-i386, because it is not
|
||||
* Remove build dependency on libopenobex1-dev on hurd-i386, because it is not
|
||||
available there. The package is already built without it on kfreebsd.
|
||||
* Explicitly translate between sysync::memSize and size_t. Thanks to
|
||||
Patrick Ohly for the patch.
|
||||
|
@ -254,7 +362,7 @@ syncevolution (1.1+ds1-1) experimental; urgency=low
|
|||
* Add -dbg package to hold debugging symbols
|
||||
* Recommend evolution-data-server instead of evolution
|
||||
* Update Standards-Version to 3.9.1 (No changes).
|
||||
|
||||
|
||||
[ Thomas Bechtold ]
|
||||
* Split source package into syncevolution-common, syncevolution and
|
||||
sync-ui.
|
||||
|
@ -276,7 +384,7 @@ syncevolution (1.0+ds1~beta2a-1) unstable; urgency=low
|
|||
syncevolution (1.0+ds1~a1-2) experimental; urgency=low
|
||||
|
||||
* Don't build depend on libopenobex1-dev on kfreebsd-*. This avoids
|
||||
trying to compile bluetooth support, which relies on bluez
|
||||
trying to compile bluetooth support, which relies on bluez
|
||||
(Closes: #566940)
|
||||
|
||||
-- David Bremner <bremner@unb.ca> Tue, 26 Jan 2010 23:28:44 -0400
|
||||
|
@ -304,6 +412,6 @@ syncevolution (0.9+ds1-2) unstable; urgency=low
|
|||
|
||||
syncevolution (0.9+ds1-1) unstable; urgency=low
|
||||
|
||||
* Initial release (Closes: #404942)
|
||||
* Initial release (Closes: #404942)
|
||||
|
||||
-- David Bremner <bremner@unb.ca> Sun, 16 Aug 2009 23:53:47 -0300
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
Makefile.in
|
||||
aclocal.m4
|
||||
config.guess
|
||||
config.h.in
|
||||
config.sub
|
||||
configure
|
||||
configure.in
|
||||
depcomp
|
||||
install-sh
|
||||
intltool-extract.in
|
||||
intltool-merge.in
|
||||
intltool-update.in
|
||||
ltmain.sh
|
||||
m4/intltool.m4
|
||||
m4/libtool.m4
|
||||
m4/ltoptions.m4
|
||||
m4/ltsugar.m4
|
||||
m4/ltversion.m4
|
||||
m4/lt~obsolete.m4
|
||||
missing
|
||||
mkinstalldirs
|
||||
po/Makefile.in.in
|
||||
src/Makefile.am
|
||||
src/Makefile.in
|
||||
src/backends/addressbook/Makefile.in
|
||||
src/backends/evolution/Makefile.in
|
||||
src/backends/file/Makefile.in
|
||||
src/backends/sqlite/Makefile.in
|
||||
src/core/Makefile.in
|
||||
src/dbus/Makefile.in
|
||||
src/dbus/interfaces/Makefile.in
|
||||
src/gtk-ui/Makefile.in
|
||||
test/Makefile.in
|
|
@ -1 +0,0 @@
|
|||
9
|
|
@ -1,32 +1,46 @@
|
|||
Source: syncevolution
|
||||
Section: utils
|
||||
Priority: optional
|
||||
Maintainer: Tino Mettler <tino+debian@tikei.de>
|
||||
Build-Depends: debhelper (>= 9), autotools-dev, libedataserver1.2-dev,
|
||||
libecal1.2-dev, libebook1.2-dev, libcurl4-gnutls-dev, libboost-dev,
|
||||
libsynthesis-dev (>=3.4.0.47.5),
|
||||
libtool, automake, intltool, pkg-config,
|
||||
libglib2.0-dev, libgladeui-dev, libdbus-glib-1-dev, libgtk-3-dev,
|
||||
libgconf2-dev,
|
||||
libsecret-1-dev,
|
||||
xsltproc,
|
||||
libopenobex2-dev [linux-any], libnotify-dev,
|
||||
python-docutils, libical-dev, libneon27-gnutls-dev, libpcre3-dev,
|
||||
libcppunit-dev, kdepimlibs5-dev, kdelibs5-dev,
|
||||
Maintainer: Jonas Smedegaard <dr@jones.dk>
|
||||
Build-Depends:
|
||||
debhelper-compat (= 13),
|
||||
intltool,
|
||||
libboost-dev,
|
||||
libcppunit-dev,
|
||||
libcurl4-gnutls-dev,
|
||||
libdbus-glib-1-dev,
|
||||
libebook1.2-dev,
|
||||
libecal2.0-dev,
|
||||
libedataserver1.2-dev,
|
||||
libgladeui-dev,
|
||||
libglib2.0-dev,
|
||||
libgtk-3-dev,
|
||||
libical-dev,
|
||||
libjson-c-dev,
|
||||
g++ (>= 4:7)
|
||||
Standards-Version: 3.9.8
|
||||
Homepage: http://www.syncevolution.org
|
||||
Vcs-Git: git://anonscm.debian.org/collab-maint/syncevolution
|
||||
Vcs-Browser: https://anonscm.debian.org/cgit/collab-maint/syncevolution.git
|
||||
libneon27-gnutls-dev,
|
||||
libnotify-dev,
|
||||
libopenobex2-dev [linux-any],
|
||||
libsecret-1-dev,
|
||||
libsynthesis-dev,
|
||||
python3-docutils,
|
||||
python3-pygments,
|
||||
xsltproc,
|
||||
Standards-Version: 4.6.0
|
||||
Homepage: https://www.syncevolution.org/
|
||||
Vcs-Git: https://salsa.debian.org/debian/syncevolution.git
|
||||
Vcs-Browser: https://salsa.debian.org/debian/syncevolution
|
||||
Rules-Requires-Root: no
|
||||
|
||||
Package: syncevolution
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends},
|
||||
syncevolution-common (= ${source:Version}),
|
||||
syncevolution-libs (= ${binary:Version})
|
||||
Recommends: bluez
|
||||
Description: Sync personal information data using SyncML and CalDAV/CardDAV (CLI)
|
||||
Depends:
|
||||
syncevolution-common (= ${source:Version}),
|
||||
syncevolution-libs (= ${binary:Version}),
|
||||
${misc:Depends},
|
||||
${shlibs:Depends},
|
||||
Recommends:
|
||||
bluez,
|
||||
Description: Sync personal information data via SyncML/CalDAV/CardDAV (CLI)
|
||||
SyncEvolution synchronizes contact, calendar and task items via SyncML and
|
||||
CalDAV/CardDAV with other servers or devices. It uses the Evolution Data Server
|
||||
to sync PIM data in Evolution, but a plain file storage is also supported.
|
||||
|
@ -38,10 +52,14 @@ Description: Sync personal information data using SyncML and CalDAV/CardDAV (CLI
|
|||
|
||||
Package: sync-ui
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, syncevolution-common (= ${source:Version}),
|
||||
syncevolution-dbus
|
||||
Recommends: bluez
|
||||
Description: Sync personal information data using SyncML and CalDAV/CardDAV (GTK+ GUI)
|
||||
Depends:
|
||||
syncevolution-common (= ${source:Version}),
|
||||
syncevolution-dbus,
|
||||
${misc:Depends},
|
||||
${shlibs:Depends},
|
||||
Recommends:
|
||||
bluez,
|
||||
Description: Sync personal information data via SyncML/CalDAV/CardDAV (GTK+ GUI)
|
||||
SyncEvolution synchronizes contact, calendar and task items via SyncML and
|
||||
CalDAV/CardDAV with other servers or devices. It uses the Evolution Data Server
|
||||
to sync PIM data in Evolution, but a plain file storage is also supported.
|
||||
|
@ -53,10 +71,12 @@ Description: Sync personal information data using SyncML and CalDAV/CardDAV (GTK
|
|||
|
||||
Package: syncevolution-common
|
||||
Architecture: all
|
||||
Depends: ${misc:Depends}, libsynthesis0v5 (>= 3.4.0.47.5)
|
||||
Conflicts: sync-ui (<<1.1+ds1-1~), syncevolution (<<1.1+ds1-1~)
|
||||
Replaces: sync-ui (<<1.1+ds1-1~), syncevolution (<<1.1+ds1-1~)
|
||||
Description: Sync personal information data using SyncML and CalDAV/CardDAV (common files)
|
||||
Depends:
|
||||
libsynthesis0v5 (>= 3.4.0.47.5),
|
||||
${misc:Depends},
|
||||
Recommends:
|
||||
adns-tools | host | dnsutils,
|
||||
Description: Sync personal information data via SyncML/CalDAV/CardDAV (common files)
|
||||
SyncEvolution synchronizes contact, calendar and task items via SyncML and
|
||||
CalDAV/CardDAV with other servers or devices. It uses the Evolution Data Server
|
||||
to sync PIM data in Evolution, but a plain file storage is also supported.
|
||||
|
@ -68,10 +88,13 @@ Description: Sync personal information data using SyncML and CalDAV/CardDAV (com
|
|||
|
||||
Package: syncevolution-libs
|
||||
Architecture: any
|
||||
Depends: syncevolution-libs-gnome (= ${binary:Version}) |
|
||||
syncevolution-libs-kde (= ${binary:Version}),
|
||||
${misc:Depends}, ${shlibs:Depends}
|
||||
Description: Sync personal information data using SyncML and CalDAV/CardDAV (backend libraries)
|
||||
Depends:
|
||||
syncevolution-libs-gnome (= ${binary:Version}),
|
||||
${misc:Depends},
|
||||
${shlibs:Depends},
|
||||
Recommends:
|
||||
syncevolution-common (= ${source:Version}),
|
||||
Description: Sync personal information data via SyncML/CalDAV/CardDAV (backend libraries)
|
||||
SyncEvolution synchronizes contact, calendar and task items via SyncML and
|
||||
CalDAV/CardDAV with other servers or devices. It uses the Evolution Data Server
|
||||
to sync PIM data in Evolution, but a plain file storage is also supported.
|
||||
|
@ -83,11 +106,12 @@ Description: Sync personal information data using SyncML and CalDAV/CardDAV (bac
|
|||
|
||||
Package: syncevolution-libs-gnome
|
||||
Architecture: any
|
||||
Depends: ${misc:Depends}, ${shlibs:Depends}
|
||||
Recommends: evolution-data-server
|
||||
Replaces: syncevolution-libs (<< 1.3.99.7)
|
||||
Breaks: syncevolution-libs (<< 1.3.99.7)
|
||||
Description: Sync personal information data using SyncML and CalDAV/CardDAV (GNOME backend)
|
||||
Depends:
|
||||
${misc:Depends},
|
||||
${shlibs:Depends},
|
||||
Recommends:
|
||||
evolution-data-server,
|
||||
Description: Sync personal information data via SyncML/CalDAV/CardDAV (GNOME backend)
|
||||
SyncEvolution synchronizes contact, calendar and task items via SyncML and
|
||||
CalDAV/CardDAV with other servers or devices. It uses the Evolution Data Server
|
||||
to sync PIM data in Evolution, but a plain file storage is also supported.
|
||||
|
@ -95,31 +119,17 @@ Description: Sync personal information data using SyncML and CalDAV/CardDAV (GNO
|
|||
incremental synchronization of items are supported. SyncEvolution can act as
|
||||
a SyncML/DAV client and SyncML server.
|
||||
.
|
||||
This package provides private libraries and plugins for Gnome.
|
||||
|
||||
Package: syncevolution-libs-kde
|
||||
Architecture: any
|
||||
Depends: ${misc:Depends}, ${shlibs:Depends}
|
||||
Replaces: syncevolution-libs (<< 1.3.99.7)
|
||||
Breaks: syncevolution-libs (<< 1.3.99.7)
|
||||
Description: Sync personal information data using SyncML and CalDAV/CardDAV (KDE backend)
|
||||
SyncEvolution synchronizes contact, calendar and task items via SyncML and
|
||||
CalDAV/CardDAV with other servers or devices. It uses the Evolution Data Server
|
||||
to sync PIM data in Evolution, but a plain file storage is also supported.
|
||||
Data exchange can happen via HTTP(S) and Bluetooth. Full, one-way and
|
||||
incremental synchronization of items are supported. SyncEvolution can act as
|
||||
a SyncML/DAV client and SyncML server.
|
||||
.
|
||||
This package provides private libraries and plugins for KDE.
|
||||
This package provides private libraries and plugins for GNOME.
|
||||
|
||||
Package: syncevolution-dbus
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends},
|
||||
syncevolution-common (= ${source:Version}),
|
||||
syncevolution-libs (= ${binary:Version}), dbus
|
||||
Replaces: sync-ui (<< 1.1+ds1-1)
|
||||
Breaks: sync-ui (<< 1.1+ds1-1)
|
||||
Description: Sync personal information data using SyncML and CalDAV/CardDAV (D-Bus support)
|
||||
Depends:
|
||||
dbus,
|
||||
syncevolution-common (= ${source:Version}),
|
||||
syncevolution-libs (= ${binary:Version}),
|
||||
${misc:Depends},
|
||||
${shlibs:Depends},
|
||||
Description: Sync personal information data via SyncML/CalDAV/CardDAV (D-Bus support)
|
||||
SyncEvolution synchronizes contact, calendar and task items via SyncML and
|
||||
CalDAV/CardDAV with other servers or devices. It uses the Evolution Data Server
|
||||
to sync PIM data in Evolution, but a plain file storage is also supported.
|
||||
|
@ -131,9 +141,15 @@ Description: Sync personal information data using SyncML and CalDAV/CardDAV (D-B
|
|||
|
||||
Package: syncevolution-http
|
||||
Architecture: all
|
||||
Depends: ${misc:Depends}, syncevolution-dbus (>= ${source:Version}), python,
|
||||
python-dbus, dbus-x11, python-twisted-web, python-gobject, python-openssl
|
||||
Description: Sync personal information data using SyncML and CalDAV/CardDAV (HTTP server)
|
||||
Depends:
|
||||
dbus-x11,
|
||||
python3,
|
||||
python3-dbus,
|
||||
python3-gi,
|
||||
python3-openssl,
|
||||
syncevolution-dbus (>= ${source:Version}),
|
||||
${misc:Depends},
|
||||
Description: Sync personal information data via SyncML/CalDAV/CardDAV (HTTP server)
|
||||
SyncEvolution synchronizes contact, calendar and task items via SyncML and
|
||||
CalDAV/CardDAV with other servers or devices. It uses the Evolution Data Server
|
||||
to sync PIM data in Evolution, but a plain file storage is also supported.
|
||||
|
@ -146,8 +162,12 @@ Description: Sync personal information data using SyncML and CalDAV/CardDAV (HTT
|
|||
|
||||
Package: libsyncevolution0
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, syncevolution-common (= ${source:Version}), dbus
|
||||
Description: Sync personal information data using SyncML and CalDAV/CardDAV (shared library)
|
||||
Depends:
|
||||
dbus,
|
||||
syncevolution-common (= ${source:Version}),
|
||||
${misc:Depends},
|
||||
${shlibs:Depends},
|
||||
Description: Sync personal information data via SyncML/CalDAV/CardDAV (shared library)
|
||||
SyncEvolution synchronizes contact, calendar and task items via SyncML and
|
||||
CalDAV/CardDAV with other servers or devices. It uses the Evolution Data Server
|
||||
to sync PIM data in Evolution, but a plain file storage is also supported.
|
||||
|
@ -159,8 +179,12 @@ Description: Sync personal information data using SyncML and CalDAV/CardDAV (sha
|
|||
|
||||
Package: libsyncevo-dbus0
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, syncevolution-common (= ${source:Version}), dbus
|
||||
Description: Sync personal information data using SyncML and CalDAV/CardDAV (shared D-Bus library)
|
||||
Depends:
|
||||
dbus,
|
||||
syncevolution-common (= ${source:Version}),
|
||||
${misc:Depends},
|
||||
${shlibs:Depends},
|
||||
Description: Sync personal information data via SyncML/CalDAV/CardDAV (shared D-Bus library)
|
||||
SyncEvolution synchronizes contact, calendar and task items via SyncML and
|
||||
CalDAV/CardDAV with other servers or devices. It uses the Evolution Data Server
|
||||
to sync PIM data in Evolution, but a plain file storage is also supported.
|
||||
|
@ -172,10 +196,12 @@ Description: Sync personal information data using SyncML and CalDAV/CardDAV (sha
|
|||
|
||||
Package: libgdbussyncevo0
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, syncevolution-common (= ${source:Version}), dbus
|
||||
Replaces: syncevolution-libs (<< 1.2.99.1)
|
||||
Breaks: syncevolution-libs (<< 1.2.99.1)
|
||||
Description: Sync personal information data using SyncML and CalDAV/CardDAV (shared gdbus library)
|
||||
Depends:
|
||||
dbus,
|
||||
syncevolution-common (= ${source:Version}),
|
||||
${misc:Depends},
|
||||
${shlibs:Depends},
|
||||
Description: Sync personal information data via SyncML/CalDAV/CardDAV (shared gdbus library)
|
||||
SyncEvolution synchronizes contact, calendar and task items via SyncML and
|
||||
CalDAV/CardDAV with other servers or devices. It uses the Evolution Data Server
|
||||
to sync PIM data in Evolution, but a plain file storage is also supported.
|
||||
|
|
|
@ -1,174 +1,280 @@
|
|||
Source: http://downloads.syncevolution.org/syncevolution/sources/
|
||||
git://git.moblin.org/syncevolution
|
||||
|
||||
Currently the tarball is built from a tag in the moblin repo to avoid the
|
||||
embedded copy of libsynthesis. For details, see the get-orig-source rule
|
||||
in debian/rules.
|
||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: SyncEvolution
|
||||
Upstream-Contact: https://gitlab.freedesktop.org/SyncEvolution/syncevolution/-/issues
|
||||
Source: https://gitlab.freedesktop.org/SyncEvolution/syncevolution/
|
||||
|
||||
Files: *
|
||||
Copyright: © 2005-2009 Patrick Ohly <patrick.ohly@gmx.de>
|
||||
License: LGPL2.1 | LGPL3
|
||||
Copyright:
|
||||
2012 BMW Car IT GmbH.
|
||||
2016 Emanoil Kotsev <emanoil.kotsev@fincom.at>
|
||||
2008 Funambol, Inc.
|
||||
2009, 2011-2012 Intel Corporation
|
||||
2009 m-otion communications GmbH <knipp@m-otion.com>
|
||||
2005-2009 Patrick Ohly <patrick.ohly@gmx.de>
|
||||
2011 Symbio, Ville Nummela
|
||||
2004-2008 Synthesis AG
|
||||
License-Grant:
|
||||
This library is free software;
|
||||
you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License
|
||||
as published by the Free Software Foundation;
|
||||
either version 2.1 of the License, or (at your option) version 3.
|
||||
License: LGPL-2.1 or LGPL-3
|
||||
Comment:
|
||||
Files below <src/backends/webdav/*> lack licensing.
|
||||
Licensing of those files is assumed same as generally for the project.
|
||||
|
||||
File: test/client-test.cpp
|
||||
Copyright: © 2008-2009 Patrick Ohly <patrick.ohly@gmx.de>
|
||||
© 2008 Funambol, Inc
|
||||
License: LGPL2.1 | LGPL3
|
||||
Files:
|
||||
build/xsl/*
|
||||
Copyright:
|
||||
2003 Jiří Kosek
|
||||
1999-2007 Norman Walsh
|
||||
2011-2012 O'Reilly Media
|
||||
2004-2007 Steve Ball
|
||||
2005-2008 The DocBook Project
|
||||
License: Expat~Docbook
|
||||
Reference: build/xsl/COPYING
|
||||
|
||||
Files: src/core/LogRedirect.h src/core/SoupTransportAgent.cpp
|
||||
src/core/TransportAgent.cpp src/core/TransportAgent.h
|
||||
src/core/SynthesisEngine.cpp src/DBusSyncClient.cpp
|
||||
src/syncevo-dbus-server.cpp src/core/CurlTransportAgent.h
|
||||
src/core/SoupTransportAgent.h src/core/CurlTransportAgent.cpp
|
||||
src/DBusSyncClient.h src/syncevo-dbus-server.h src/dbus/* src/gtk-ui/*
|
||||
test/test.cpp
|
||||
Copyright: © 2009 Intel Corporation
|
||||
License: LGPL2.1 | LGPL3
|
||||
Files: m4-repo/*.m4
|
||||
Copyright:
|
||||
2008 Benjamin Kosnik <bkoz@redhat.com>
|
||||
2014-2015 Google Inc.
|
||||
2008 John Darrington <j.darrington@elvis.murdoch.edu.au>
|
||||
2016 Krzesimir Nowak <qdlacz@gmail.com>
|
||||
2015 Moritz Klammler <moritz@klammler.eu>
|
||||
2015 Paul Norman <penorman@mac.com>
|
||||
2009 Peter Adolphs
|
||||
2013 Roy Stogner <roystgnr@ices.utexas.edu>
|
||||
2008 Thomas Porschberg <thomas@randspringer.de>
|
||||
2012 Xiyue Deng <manphiz@gmail.com>
|
||||
2012 Zack Weinberg <zackw@panix.com>
|
||||
License: FSFAP
|
||||
|
||||
Files: src/backends/addressbook/AddressBookSource.cpp
|
||||
src/backends/file/FileSyncSource.cpp src/core/EvolutionSyncSource.cpp
|
||||
src/client-test-app.cpp src/syncevolution.cpp
|
||||
src/core/EvolutionSyncClient.cpp src/core/EvolutionSmartPtr.h
|
||||
src/core/EvolutionSyncClient.h src/core/EvolutionSyncSource.h
|
||||
src/backends/evolution/EvolutionContactSource.h
|
||||
src/backends/evolution/EvolutionContactSource.cpp
|
||||
src/backends/evolution/EvolutionCalendarSource.cpp
|
||||
src/backends/evolution/EvolutionCalendarSource.h
|
||||
src/backends/evolution/EvolutionMemoSource.cpp
|
||||
src/backends/sqlite/SQLiteContactSource.cpp src/core/SynthesisEngine.h
|
||||
src/core/SyncEvolutionCmdline.cpp src/core/TrackingSyncSource.cpp
|
||||
src/core/SyncEvolutionUtil.cpp src/core/FileConfigNode.cpp
|
||||
src/core/SyncEvolutionUtil.h src/core/SyncEvolutionConfig.cpp
|
||||
src/core/TrackingSyncSource.h src/core/SyncEvolutionConfig.h
|
||||
src/core/SyncML.h src/core/Logging.cpp src/core/LogStdout.h
|
||||
src/core/Logging.h src/core/LogStdout.cpp src/core/SyncML.cpp
|
||||
src/core/LogRedirect.cpp
|
||||
Copyright: © 2009 Intel Corporation
|
||||
© 2005-2009 Patrick Ohly <patrick.ohly@gmx.de>
|
||||
License: LGPL2.1 | LGPL3
|
||||
|
||||
License: LGPL2.1 | LGPL3
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public License
|
||||
as published by the Free Software Foundation; either version 2.1
|
||||
of the License, or (at your option) version 3.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
Files: test/{ClientTest.cpp,ClientTest.h}
|
||||
test/client-test-main.cpp
|
||||
test/{test.h synccompare.pl}
|
||||
Copyright: © 2008-2009 Patrick Ohly
|
||||
© 2009 Intel Corporation
|
||||
© 2008 Funambol Inc.
|
||||
License: LGPL2.1 | LGPL3
|
||||
They were contributed to the Funambol C++ client library under the
|
||||
"docs/Sync4jContribution.pdf" agreement. They were maintained there by
|
||||
Patrick and on February 17th 2009 copied back to SyncEvolution,
|
||||
without any commits by other authors except for the license and
|
||||
copyright changes applied by Funambol.
|
||||
|
||||
On March 25 2009 they were relicensed by Patrick Ohly, executing
|
||||
the rights granted by the contributor agreement.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation; either version 2.1 of the License, or (at your option)
|
||||
version 3.
|
||||
|
||||
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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Files: test/Algorith/Diff.pm
|
||||
Copyright:© 2000-2004 Ned Konz, Tye McQueen.
|
||||
License: GPL-1+ | Artistic
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the same terms as Perl.
|
||||
|
||||
File: src/core/SynthesisDBPlugin.cpp
|
||||
Copyright: © 2009 Intel Corporation
|
||||
© 2004-2008 by Synthesis AG
|
||||
License: LGPL2.1 | LGPL3
|
||||
|
||||
File: src/backends/evolution/e-cal-check-timezones.c
|
||||
src/backends/evolution/e-cal-check-timezones.h
|
||||
Copyright: © 2008 Novell, Inc
|
||||
© 2009 Patrick Ohly <patrick.ohly@gmx.de>
|
||||
Files:
|
||||
src/backends/akonadi/akonadisyncsource.cpp
|
||||
src/backends/akonadi/akonadisyncsource.h
|
||||
src/backends/akonadi/contactssyncsource.cpp
|
||||
src/backends/akonadi/contactssyncsource.h
|
||||
src/backends/akonadi/eventssyncsource.cpp
|
||||
src/backends/akonadi/eventssyncsource.h
|
||||
src/backends/akonadi/notessyncsource.cpp
|
||||
src/backends/akonadi/notessyncsource.h
|
||||
src/backends/akonadi/todossyncsource.cpp
|
||||
src/backends/akonadi/todossyncsource.h
|
||||
Copyright:
|
||||
2009 Sascha Peilicke <sasch.pe@gmx.de>
|
||||
License-Grant:
|
||||
This application is free software;
|
||||
you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library General Public License
|
||||
as published by the Free Software Foundation;
|
||||
either version 2 of the License, or (at your option) any later version.
|
||||
License: LGPL-2+
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public License
|
||||
as published by the Free Software Foundation; either version 2 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
|
||||
Lesser General Public License for more details.
|
||||
Files:
|
||||
test/Algorith/Diff.pm
|
||||
Copyright:
|
||||
2000-2004 Ned Konz
|
||||
2000-2004 Tye McQueen
|
||||
License-Grant:
|
||||
This program is free software;
|
||||
you can redistribute it and/or modify it
|
||||
under the same terms as Perl.
|
||||
License: Artistic or GPL-1+
|
||||
Comment:
|
||||
Perl 5 is licensed under either the Artistic license
|
||||
or the GNU General Public License version 1 or later.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this program; if not, write to the Free
|
||||
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
Files:
|
||||
src/syncevo/icaltz-util.c
|
||||
src/syncevo/icaltz-util.h
|
||||
Copyright:
|
||||
2007 Novell, Inc.
|
||||
License-Grant:
|
||||
This program is free software;
|
||||
you can redistribute it and/or modify it
|
||||
under the terms of version 2
|
||||
of the GNU Lesser General Public License
|
||||
as published by the Free Software Foundation.
|
||||
License: LGPL-2
|
||||
|
||||
Foile: build/gen-changelog.pl
|
||||
Copyright: © 2009 Emmanuele Bassi
|
||||
License: GPL1+|Artistic
|
||||
This program is free software. It can be distributed and/or modified under
|
||||
the terms of Perl itself.
|
||||
Files:
|
||||
src/gtk-ui/gtkinfobar.c
|
||||
src/gtk-ui/gtkinfobar.h
|
||||
Copyright:
|
||||
2005 Paolo Maggi
|
||||
License-Grant:
|
||||
This library is free software;
|
||||
you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License
|
||||
as published by the Free Software Foundation;
|
||||
either version 2 of the License, or (at your option) any later version.
|
||||
License: LGPL-2+
|
||||
|
||||
Files: debian/*
|
||||
Copyright: © 2009 David Bremner
|
||||
License: same as upstream, LGPL2.1 or LGPL3
|
||||
Files:
|
||||
src/backends/tdepim/TDEPIMSyncSource.cpp
|
||||
src/backends/tdepim/TDEPIMSyncSource.h
|
||||
Copyright:
|
||||
2016 Emanoil Kotsev <emanoil.kotsev@fincom.at>
|
||||
License-Grant:
|
||||
This application is free software;
|
||||
you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library General Public License
|
||||
as published by the Free Software Foundation;
|
||||
either version 2 of the License, or (at your option) any later version.
|
||||
License: LGPL-2+
|
||||
|
||||
Files:
|
||||
src/backends/evolution/e-cal-check-timezones.c
|
||||
src/backends/evolution/e-cal-check-timezones.h
|
||||
Copyright:
|
||||
2008 Novell, Inc
|
||||
2009 Patrick Ohly <patrick.ohly@gmx.de>
|
||||
License-Grant:
|
||||
This program is free software;
|
||||
you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License
|
||||
as published by the Free Software Foundation;
|
||||
either version 2 of the License, or (at your option) any later version.
|
||||
License: LGPL-2+
|
||||
Comment:
|
||||
The granted license does not exist at described version.
|
||||
Licensing assumed to be GNU Library General Public License 2.0 or newer.
|
||||
|
||||
Files: src/gdbus/test/example.cpp
|
||||
Copyright: © 2009 Intel Corporation
|
||||
License: GPL-2
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2 as
|
||||
published by the Free Software Foundation.
|
||||
Files: src/dbus/interfaces/spec-to-docbook.xsl
|
||||
Copyright: 2007, William Jon McCann
|
||||
License-Grant:
|
||||
License: GPL
|
||||
License: GPL-1+
|
||||
|
||||
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 General Public License for more details.
|
||||
Files:
|
||||
m4-repo/dk-warn.m4
|
||||
Copyright:
|
||||
2004-2007 Daniel Elstner <daniel.kitta@gmail.com>
|
||||
License-Grant:
|
||||
danielk's Autostuff is free software;
|
||||
you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation;
|
||||
either version 2 of the License, or (at your option) any later version.
|
||||
License: GPL-2+
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Files:
|
||||
m4-repo/autotroll.m4
|
||||
autotroll.am
|
||||
Copyright:
|
||||
2006-2007, 2009-2010 Benoit Sigoure <benoit.sigoure@lrde.epita.fr>
|
||||
License-Grant:
|
||||
AutoTroll is free software;
|
||||
you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation;
|
||||
either version 2 of the License, or (at your option) any later version.
|
||||
License: GPL-2+ with Autoconf-2.0~AutoTroll exception
|
||||
In addition, as a special exception,
|
||||
the copyright holders of AutoTroll give you unlimited permission
|
||||
to copy, distribute and modify the configure scripts
|
||||
that are the output of Autoconf
|
||||
when processing the macros of AutoTroll.
|
||||
You need not follow the terms of the GNU General Public License
|
||||
when using or distributing such scripts,
|
||||
even though portions of the text of AutoTroll appear in them.
|
||||
The GNU General Public License (GPL) does govern
|
||||
all other use of the material that constitutes AutoTroll.
|
||||
.
|
||||
This special exception to the GPL applies
|
||||
to versions of AutoTroll released
|
||||
by the copyright holders of AutoTroll.
|
||||
Note that people who make
|
||||
modified versions of AutoTroll are not obligated
|
||||
to grant this special exception for their modified versions;
|
||||
it is their choice whether to do so.
|
||||
The GNU General Public License gives permission
|
||||
to release a modified version without this exception;
|
||||
this exception also makes it possible to release
|
||||
a modified version which carries forward this exception.
|
||||
|
||||
Files: src/gdbusxx/test/example.cpp
|
||||
Copyright: © 2009 Intel Corporation
|
||||
License: GPL-2
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2 as
|
||||
published by the Free Software Foundation.
|
||||
Files:
|
||||
build/gen-changelog.pl
|
||||
Copyright:
|
||||
2009 Emmanuele Bassi <ebassi@gnome.org>
|
||||
License-Grant:
|
||||
This program is free software.
|
||||
It can be distributed and/or modified
|
||||
under the terms of Perl itself.
|
||||
License: GPL-1+ or Artistic
|
||||
Comment:
|
||||
Perl 5 is licensed under either the Artistic license
|
||||
or the GNU General Public License version 1 or later.
|
||||
|
||||
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 General Public License for more details.
|
||||
Files:
|
||||
debian/*
|
||||
Copyright:
|
||||
2009 David Bremner
|
||||
2021 Jonas Smedegaard <dr@jones.dk>
|
||||
License-Grant:
|
||||
This packaging is free software;
|
||||
you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation;
|
||||
version 3.
|
||||
License: GPL-3
|
||||
Reference: debian/copyright
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
License: Artistic
|
||||
Reference: /usr/share/common-licenses/Artistic
|
||||
|
||||
On Debian systems, you can find the full license text for the LGPL2.1, LGPL3,
|
||||
GPL-2, GPL3 and Artistic Licenses at
|
||||
/usr/share/common-licenses/{LGPL-2.1,LGPL-3,GPL-2,GPL-3,Artistic}
|
||||
License: Expat~Docbook
|
||||
Permission is hereby granted, free of charge,
|
||||
to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction,
|
||||
including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
.
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions of the Software.
|
||||
.
|
||||
Except as contained in this notice,
|
||||
the names of individuals credited with contribution to this software
|
||||
shall not be used in advertising or otherwise
|
||||
to promote the sale, use or other dealings in this Software
|
||||
without prior written authorization from the individuals in question.
|
||||
.
|
||||
Any stylesheet derived from this Software
|
||||
that is publically distributed
|
||||
will be identified with a different name
|
||||
and the version strings in any derived Software will be changed
|
||||
so that no possibility of confusion
|
||||
between the derived package and this Software will exist.
|
||||
|
||||
License: FSFAP
|
||||
Copying and distribution of this file,
|
||||
with or without modification,
|
||||
are permitted in any medium without royalty
|
||||
provided the copyright notice and this notice are preserved
|
||||
This file is offered as-is, without any warranty.
|
||||
|
||||
License: GPL-1+
|
||||
Reference: /usr/share/common-licenses/GPL-1
|
||||
|
||||
License: GPL-2+
|
||||
Reference: /usr/share/common-licenses/GPL-2
|
||||
|
||||
License: GPL-3
|
||||
Reference: /usr/share/common-licenses/GPL-3
|
||||
|
||||
License: LGPL-2
|
||||
Reference: /usr/share/common-licenses/LGPL-2
|
||||
|
||||
License: LGPL-2+
|
||||
Reference: /usr/share/common-licenses/LGPL-2
|
||||
|
||||
License: LGPL-2.1
|
||||
Reference: /usr/share/common-licenses/LGPL-2.1
|
||||
|
||||
License: LGPL-3
|
||||
Reference: /usr/share/common-licenses/LGPL-3
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
licensecheck --check '.*' --recursive --copyright --deb-machine --ignore '^(debian/(changelog|copyright(_hints)?))$' --lines 0 -- * > debian/copyright_hints
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,14 @@
|
|||
# clone this source: gbp clone $PKG_GIT_URL
|
||||
# track upstream source: git remote add upstream-git $UPSTREAM_GIT_URL
|
||||
# update this source: gbp pull
|
||||
# update upstream source: git fetch upstream-git --tags
|
||||
# import upstream release: gbp import-orig --upstream-vcs-tag=$VERSION --uscan
|
||||
# build package: gbp buildpackage
|
||||
# publish source release: gbp tag && gbp push
|
||||
|
||||
[DEFAULT]
|
||||
pristine-tar = True
|
||||
sign-tags = True
|
||||
filter = */.git*
|
||||
debian-branch = debian/latest
|
||||
upstream-branch = upstream/latest
|
|
@ -0,0 +1,26 @@
|
|||
# we provide no -dev package
|
||||
usr/include/*/*.h
|
||||
usr/lib/*/*.a
|
||||
usr/lib/*/*.la
|
||||
usr/lib/*/*.so
|
||||
usr/lib/*/*/*/*.a
|
||||
usr/lib/*/*/*/*.la
|
||||
usr/lib/*/pkgconfig/*.pc
|
||||
|
||||
# covered in debian/copyright
|
||||
usr/share/doc/syncevolution/COPYING
|
||||
|
||||
# relates to unsupported KDE options --enable-kwallet --enable-akonadi
|
||||
usr/lib/*/syncevolution/backends/platformkde.so
|
||||
usr/lib/*/syncevolution/backends/syncakonadi.so
|
||||
usr/lib/*/syncevolution/backends/syncactivesync.so
|
||||
|
||||
# relates to unsupported KDE-derived Trinity Desktop Environment (TDE)
|
||||
usr/lib/*/syncevolution/backends/synctdepimabc.so
|
||||
usr/lib/*/syncevolution/backends/synctdepimcal.so
|
||||
usr/lib/*/syncevolution/backends/synctdepimnotes.so
|
||||
usr/lib/*/syncevolution/backends/platformtde.so
|
||||
|
||||
# helper scripts for testing
|
||||
usr/bin/syncevo-phone-config
|
||||
usr/bin/synclog2html
|
|
@ -1,48 +0,0 @@
|
|||
From aabb99048290c0662629fe88588a80a0544fd8c5 Mon Sep 17 00:00:00 2001
|
||||
From: Tino Mettler <tino+debian@tikei.de>
|
||||
Date: Sun, 26 Oct 2014 12:54:31 +0100
|
||||
Subject: [PATCH] Fix FTBFS on kfreebsd due to missing SOCK_CLOEXEC
|
||||
|
||||
Work around missing SOCK_CLOEXEC on kfreebsd by setting FD_CLOEXEC
|
||||
afterwards.
|
||||
---
|
||||
src/gdbusxx/gdbus-cxx-bridge.cpp | 19 +++++++++++++++++++
|
||||
1 file changed, 19 insertions(+)
|
||||
|
||||
diff --git a/src/gdbusxx/gdbus-cxx-bridge.cpp b/src/gdbusxx/gdbus-cxx-bridge.cpp
|
||||
index 238b52f0..4f259576 100644
|
||||
--- a/src/gdbusxx/gdbus-cxx-bridge.cpp
|
||||
+++ b/src/gdbusxx/gdbus-cxx-bridge.cpp
|
||||
@@ -276,6 +276,10 @@ void DBusConnectionPtr::setDisconnect(const Disconnect_t &func)
|
||||
true);
|
||||
}
|
||||
|
||||
+#ifndef SOCK_CLOEXEC
|
||||
+#define SOCK_CLOEXEC 0
|
||||
+#endif
|
||||
+
|
||||
boost::shared_ptr<DBusServerCXX> DBusServerCXX::listen(const NewConnection_t &newConnection, DBusErrorCXX *)
|
||||
{
|
||||
// Create two fds connected via a two-way stream. The parent
|
||||
@@ -286,6 +290,21 @@ boost::shared_ptr<DBusServerCXX> DBusServerCXX::listen(const NewConnection_t &ne
|
||||
if (retval) {
|
||||
SE_THROW(StringPrintf("socketpair: %s", strerror(errno)));
|
||||
}
|
||||
+
|
||||
+ if(SOCK_CLOEXEC == 0) {
|
||||
+ int flags;
|
||||
+ int i;
|
||||
+ for(i = 0; i < 2; i++) {
|
||||
+ flags = fcntl(fds[i], F_GETFD);
|
||||
+ if (flags == -1){
|
||||
+ SE_THROW(StringPrintf("fcntl: %s", strerror(errno)));
|
||||
+ }
|
||||
+ flags |= FD_CLOEXEC;
|
||||
+ if (fcntl(fds[i], F_SETFD, flags) == -1){
|
||||
+ SE_THROW(StringPrintf("fcntl: %s", strerror(errno)));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
GuardFD parentfd(fds[0]);
|
||||
GuardFD childfd(fds[1]);
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
From 110e57f32fcae67634f6d0edd626ccc64748047e Mon Sep 17 00:00:00 2001
|
||||
From: Patrick Ohly <patrick.ohly@intel.com>
|
||||
Date: Thu, 14 Dec 2017 07:46:32 -0800
|
||||
Subject: [PATCH] libical: support libical v3
|
||||
|
||||
libical v3 removes some deprecated functions (like icaltime_from_timet)
|
||||
and removes the "is_utc" member from icaltimetype. The replacement
|
||||
code works with old and new libical and thus needs no ifdefs.
|
||||
|
||||
However, that struct is part of the ABI, which impacts the tricks that
|
||||
syncevolution.org binaries use to get built against libical v2 and then
|
||||
run with more recent libs like libical v3.
|
||||
|
||||
Depending on the platform ABI, it may still be okay, because the calling code
|
||||
in SyncEvolution reserves and copies enough bytes for the icaltimetype
|
||||
instances and because that code never directly accesses any member (is_date,
|
||||
is_daylight, zone) whose offset changes.
|
||||
|
||||
Original author: Milan Crha <mcrha@redhat.com>
|
||||
|
||||
Slightly modified it so that icaltime_t.zone is not set.
|
||||
|
||||
Signed-off-by: Patrick Ohly <patrick.ohly@intel.com>
|
||||
---
|
||||
src/backends/webdav/CalDAVSource.cpp | 3 +--
|
||||
src/syncevo/icaltz-util.c | 10 +++++-----
|
||||
2 files changed, 6 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/src/backends/webdav/CalDAVSource.cpp b/src/backends/webdav/CalDAVSource.cpp
|
||||
index fa16935a..9c4a1c8d 100644
|
||||
--- a/src/backends/webdav/CalDAVSource.cpp
|
||||
+++ b/src/backends/webdav/CalDAVSource.cpp
|
||||
@@ -721,8 +721,7 @@ SubSyncSource::SubItemResult CalDAVSource::insertSubItem(const std::string &luid
|
||||
eptr<icalcomponent> fullcal = event.m_calendar;
|
||||
loadItem(event);
|
||||
event.m_sequence++;
|
||||
- lastmodtime = icaltime_from_timet(event.m_lastmodtime, false);
|
||||
- lastmodtime.is_utc = 1;
|
||||
+ lastmodtime = icaltime_from_timet_with_zone(event.m_lastmodtime, false, icaltimezone_get_utc_timezone());
|
||||
event.m_calendar = fullcal;
|
||||
for (icalcomponent *comp = icalcomponent_get_first_component(event.m_calendar, ICAL_VEVENT_COMPONENT);
|
||||
comp;
|
||||
diff --git a/src/syncevo/icaltz-util.c b/src/syncevo/icaltz-util.c
|
||||
index 202a2cd9..abb9a758 100644
|
||||
--- a/src/syncevo/icaltz-util.c
|
||||
+++ b/src/syncevo/icaltz-util.c
|
||||
@@ -224,7 +224,7 @@ find_transidx (time_t *transitions, ttinfo *types, int *trans_idx, long int num_
|
||||
struct icaltimetype itime;
|
||||
|
||||
now = time (NULL);
|
||||
- itime = icaltime_from_timet (now, 0);
|
||||
+ itime = icaltime_from_timet_with_zone (now, 0, NULL);
|
||||
itime.month = itime.day = 1;
|
||||
itime.hour = itime.minute = itime.second = 0;
|
||||
year_start = icaltime_as_timet(itime);
|
||||
@@ -304,13 +304,13 @@ adjust_dtstart_day_to_rrule (icalcomponent *comp, struct icalrecurrencetype rule
|
||||
icalrecur_iterator *iter;
|
||||
|
||||
now = time (NULL);
|
||||
- itime = icaltime_from_timet (now, 0);
|
||||
+ itime = icaltime_from_timet_with_zone (now, 0, NULL);
|
||||
itime.month = itime.day = 1;
|
||||
itime.hour = itime.minute = itime.second = 0;
|
||||
year_start = icaltime_as_timet(itime);
|
||||
|
||||
comp_start = icalcomponent_get_dtstart (comp);
|
||||
- start = icaltime_from_timet (year_start, 0);
|
||||
+ start = icaltime_from_timet_with_zone (year_start, 0, NULL);
|
||||
|
||||
iter = icalrecur_iterator_new (rule, start);
|
||||
iter_start = icalrecur_iterator_next (iter);
|
||||
@@ -478,7 +478,7 @@ icaltzutil_fetch_timezone (const char *location)
|
||||
trans = transitions [stdidx] + types [zp_idx].gmtoff;
|
||||
else
|
||||
trans = types [zp_idx].gmtoff;
|
||||
- icaltime = icaltime_from_timet (trans, 0);
|
||||
+ icaltime = icaltime_from_timet_with_zone (trans, 0, NULL);
|
||||
dtstart = icaltime;
|
||||
dtstart.year = 1970;
|
||||
dtstart.minute = dtstart.second = 0;
|
||||
@@ -520,7 +520,7 @@ icaltzutil_fetch_timezone (const char *location)
|
||||
trans = transitions [dstidx] + types [zp_idx].gmtoff;
|
||||
else
|
||||
trans = types [zp_idx].gmtoff;
|
||||
- icaltime = icaltime_from_timet (trans, 0);
|
||||
+ icaltime = icaltime_from_timet_with_zone (trans, 0, NULL);
|
||||
dtstart = icaltime;
|
||||
dtstart.year = 1970;
|
||||
dtstart.minute = dtstart.second = 0;
|
|
@ -1,255 +0,0 @@
|
|||
From e6dc389330b51c508d0fa25d8e9ad599756ec69b Mon Sep 17 00:00:00 2001
|
||||
From: Patrick Ohly <patrick.ohly@intel.com>
|
||||
Date: Thu, 16 Nov 2017 15:01:11 +0100
|
||||
Subject: [PATCH] GNOME: replace gnome-keyring with libsecret
|
||||
|
||||
The GNOME keyring library has been obsoleted for a long time now,
|
||||
long enough that the replacement libsecret is available on all
|
||||
supported distros. Therefore we can switch unconditionally.
|
||||
|
||||
Signed-off-by: Patrick Ohly <patrick.ohly@intel.com>
|
||||
---
|
||||
src/backends/gnome/GNOMEPlatform.cpp | 170 ++++++++++++++---------------------
|
||||
src/backends/gnome/configure-sub.in | 9 +-
|
||||
2 files changed, 73 insertions(+), 106 deletions(-)
|
||||
|
||||
diff --git a/src/backends/gnome/GNOMEPlatform.cpp b/src/backends/gnome/GNOMEPlatform.cpp
|
||||
index f2f7a1d3..37f9811a 100644
|
||||
--- a/src/backends/gnome/GNOMEPlatform.cpp
|
||||
+++ b/src/backends/gnome/GNOMEPlatform.cpp
|
||||
@@ -22,7 +22,7 @@
|
||||
#ifdef USE_GNOME_KEYRING
|
||||
|
||||
extern "C" {
|
||||
-#include <gnome-keyring.h>
|
||||
+#include <libsecret/secret.h>
|
||||
}
|
||||
|
||||
#include "GNOMEPlatform.h"
|
||||
@@ -30,46 +30,11 @@ extern "C" {
|
||||
#include <syncevo/Exception.h>
|
||||
#include <syncevo/UserInterface.h>
|
||||
#include <syncevo/SyncConfig.h>
|
||||
+#include <syncevo/GLibSupport.h>
|
||||
|
||||
#include <syncevo/declarations.h>
|
||||
SE_BEGIN_CXX
|
||||
|
||||
-// Occasionally, libgnome-keyring fails with the following error messages:
|
||||
-// Gkr: received an invalid, unencryptable, or non-utf8 secret
|
||||
-// Gkr: call to daemon returned an invalid response: (null).(null)
|
||||
-//
|
||||
-// We work around that by retrying the operation a few times, for at
|
||||
-// most this period of time. Didn't really help, so disable it for now
|
||||
-// by using a zero duration.
|
||||
-static const double GNOMEKeyringRetryDuration = 2; // seconds
|
||||
-static const double GNOMEKeyringRetryInterval = 0.1; // seconds
|
||||
-
|
||||
-/**
|
||||
- * libgnome-keyring has an internal gkr_reset_session()
|
||||
- * method which gets called when the "org.freedesktop.secrets"
|
||||
- * disconnects from the D-Bus session bus.
|
||||
- *
|
||||
- * We cannot call that method directly, but we can get it called by
|
||||
- * faking the "disconnect" signal. That works because
|
||||
- * on_connection_filter() in gkr-operation.c doesn't check who the
|
||||
- * sender of the signal is.
|
||||
- *
|
||||
- * Once gkr_reset_session() got called, the next operation will
|
||||
- * re-establish the connection. After the failure above, the second
|
||||
- * attempt usually works.
|
||||
- *
|
||||
- * Any other client using libgnome-keyring will also be tricked into
|
||||
- * disconnecting temporarily. That should be fine, any running
|
||||
- * operation will continue to run and complete (?).
|
||||
- */
|
||||
-static void FlushGNOMEKeyring()
|
||||
-{
|
||||
- // Invoking dbus-send is easier than writing this in C++.
|
||||
- // Besides, it ensures that the signal comes from some other
|
||||
- // process. Not sure whether signals are sent back to the sender.
|
||||
- system("dbus-send --session --type=signal /org/freedesktop/DBus org.freedesktop.DBus.NameOwnerChanged string:'org.freedesktop.secrets' string:':9.99' string:''");
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* GNOME keyring distinguishes between empty and unset
|
||||
* password keys. This function returns NULL for an
|
||||
@@ -97,6 +62,39 @@ static bool UseGNOMEKeyring(const InitStateTri &keyring)
|
||||
return true;
|
||||
}
|
||||
|
||||
+class LibSecretHash : public GHashTableCXX
|
||||
+{
|
||||
+ std::list<std::string> m_buffer;
|
||||
+
|
||||
+public:
|
||||
+ LibSecretHash(const ConfigPasswordKey &key) :
|
||||
+ GHashTableCXX(g_hash_table_new(g_str_hash, g_str_equal), TRANSFER_REF)
|
||||
+ {
|
||||
+ // see https://developer.gnome.org/libsecret/0.16/libsecret-SecretSchema.html#SECRET-SCHEMA-COMPAT-NETWORK:CAPS
|
||||
+ insert("user", key.user);
|
||||
+ insert("domain", key.domain);
|
||||
+ insert("server", key.server);
|
||||
+ insert("object", key.object);
|
||||
+ insert("protocol", key.protocol);
|
||||
+ insert("authtype", key.authtype);
|
||||
+ if (key.port) {
|
||||
+ std::string value = StringPrintf("%d", key.port);
|
||||
+ insert("port", value);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /** Keys are expected to be constants and not copied. Values are copied. */
|
||||
+ void insert(const char *key, const std::string &value)
|
||||
+ {
|
||||
+ if (!value.empty()) {
|
||||
+ m_buffer.push_back(value);
|
||||
+ g_hash_table_insert(get(),
|
||||
+ const_cast<char *>(key),
|
||||
+ const_cast<char *>(m_buffer.back().c_str()));
|
||||
+ }
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
bool GNOMELoadPasswordSlot(const InitStateTri &keyring,
|
||||
const std::string &passwordName,
|
||||
const std::string &descr,
|
||||
@@ -108,46 +106,24 @@ bool GNOMELoadPasswordSlot(const InitStateTri &keyring,
|
||||
return false;
|
||||
}
|
||||
|
||||
- GnomeKeyringResult result = GNOME_KEYRING_RESULT_OK;
|
||||
- GList* list;
|
||||
- Timespec start = Timespec::monotonic();
|
||||
- double sleepSecs = 0;
|
||||
- do {
|
||||
- if (sleepSecs != 0) {
|
||||
- SE_LOG_DEBUG(NULL, "%s: previous attempt to load password '%s' from GNOME keyring failed, will try again: %s",
|
||||
- key.description.c_str(),
|
||||
- key.toString().c_str(),
|
||||
- gnome_keyring_result_to_message(result));
|
||||
- FlushGNOMEKeyring();
|
||||
- Sleep(sleepSecs);
|
||||
- }
|
||||
- result = gnome_keyring_find_network_password_sync(passwdStr(key.user),
|
||||
- passwdStr(key.domain),
|
||||
- passwdStr(key.server),
|
||||
- passwdStr(key.object),
|
||||
- passwdStr(key.protocol),
|
||||
- passwdStr(key.authtype),
|
||||
- key.port,
|
||||
- &list);
|
||||
- sleepSecs = GNOMEKeyringRetryInterval;
|
||||
- } while (result != GNOME_KEYRING_RESULT_OK &&
|
||||
- (Timespec::monotonic() - start).duration() < GNOMEKeyringRetryDuration);
|
||||
+ GErrorCXX gerror;
|
||||
+ LibSecretHash hash(key);
|
||||
+ PlainGStr result(secret_password_lookupv_sync(SECRET_SCHEMA_COMPAT_NETWORK,
|
||||
+ hash,
|
||||
+ NULL,
|
||||
+ gerror));
|
||||
|
||||
// if find password stored in gnome keyring
|
||||
- if(result == GNOME_KEYRING_RESULT_OK && list && list->data ) {
|
||||
- GnomeKeyringNetworkPasswordData *key_data;
|
||||
- key_data = (GnomeKeyringNetworkPasswordData*)list->data;
|
||||
- password = std::string(key_data->password);
|
||||
- gnome_keyring_network_password_list_free(list);
|
||||
+ if (gerror) {
|
||||
+ gerror.throwError(SE_HERE, StringPrintf("looking up password '%s'", descr.c_str()));
|
||||
+ } else if (result) {
|
||||
SE_LOG_DEBUG(NULL, "%s: loaded password from GNOME keyring using %s",
|
||||
key.description.c_str(),
|
||||
key.toString().c_str());
|
||||
+ password = result;
|
||||
} else {
|
||||
- SE_LOG_DEBUG(NULL, "password not in GNOME keyring using %s: %s",
|
||||
- key.toString().c_str(),
|
||||
- result == GNOME_KEYRING_RESULT_NO_MATCH ? "no match" :
|
||||
- result != GNOME_KEYRING_RESULT_OK ? gnome_keyring_result_to_message(result) :
|
||||
- "empty result list");
|
||||
+ SE_LOG_DEBUG(NULL, "password not in GNOME keyring using %s",
|
||||
+ key.toString().c_str());
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -173,38 +149,26 @@ bool GNOMESavePasswordSlot(const InitStateTri &keyring,
|
||||
key.toString().c_str()));
|
||||
}
|
||||
|
||||
- guint32 itemId;
|
||||
- GnomeKeyringResult result = GNOME_KEYRING_RESULT_OK;
|
||||
- // write password to keyring
|
||||
- Timespec start = Timespec::monotonic();
|
||||
- double sleepSecs = 0;
|
||||
- do {
|
||||
- if (sleepSecs != 0) {
|
||||
- SE_LOG_DEBUG(NULL, "%s: previous attempt to save password '%s' in GNOME keyring failed, will try again: %s",
|
||||
- key.description.c_str(),
|
||||
- key.toString().c_str(),
|
||||
- gnome_keyring_result_to_message(result));
|
||||
- FlushGNOMEKeyring();
|
||||
- Sleep(sleepSecs);
|
||||
- }
|
||||
- result = gnome_keyring_set_network_password_sync(NULL,
|
||||
- passwdStr(key.user),
|
||||
- passwdStr(key.domain),
|
||||
- passwdStr(key.server),
|
||||
- passwdStr(key.object),
|
||||
- passwdStr(key.protocol),
|
||||
- passwdStr(key.authtype),
|
||||
- key.port,
|
||||
- password.c_str(),
|
||||
- &itemId);
|
||||
- sleepSecs = GNOMEKeyringRetryInterval;
|
||||
- } while (result != GNOME_KEYRING_RESULT_OK &&
|
||||
- (Timespec::monotonic() - start).duration() < GNOMEKeyringRetryDuration);
|
||||
- if (result != GNOME_KEYRING_RESULT_OK) {
|
||||
- Exception::throwError(SE_HERE, StringPrintf("%s: saving password '%s' in GNOME keyring failed: %s",
|
||||
- key.description.c_str(),
|
||||
- key.toString().c_str(),
|
||||
- gnome_keyring_result_to_message(result)));
|
||||
+ GErrorCXX gerror;
|
||||
+ LibSecretHash hash(key);
|
||||
+ std::string label;
|
||||
+ if (!key.user.empty() && !key.server.empty()) {
|
||||
+ // This emulates the behavior of libgnomekeyring.
|
||||
+ label = key.user + "@" + key.server;
|
||||
+ } else {
|
||||
+ label = passwordName;
|
||||
+ }
|
||||
+ gboolean result = secret_password_storev_sync(SECRET_SCHEMA_COMPAT_NETWORK,
|
||||
+ hash,
|
||||
+ NULL,
|
||||
+ label.c_str(),
|
||||
+ password.c_str(),
|
||||
+ NULL,
|
||||
+ gerror);
|
||||
+ if (!result) {
|
||||
+ gerror.throwError(SE_HERE, StringPrintf("%s: saving password '%s' in GNOME keyring",
|
||||
+ key.description.c_str(),
|
||||
+ key.toString().c_str()));
|
||||
}
|
||||
SE_LOG_DEBUG(NULL, "saved password in GNOME keyring using %s", key.toString().c_str());
|
||||
|
||||
diff --git a/src/backends/gnome/configure-sub.in b/src/backends/gnome/configure-sub.in
|
||||
index 199989e8..d02d52a6 100644
|
||||
--- a/src/backends/gnome/configure-sub.in
|
||||
+++ b/src/backends/gnome/configure-sub.in
|
||||
@@ -1,10 +1,13 @@
|
||||
-PKG_CHECK_MODULES(KEYRING, [gnome-keyring-1 >= 2.20], HAVE_KEYRING=yes, HAVE_KEYRING=no)
|
||||
+# According to https://developer.gnome.org/libsecret/0.16/libsecret-Password-storage.html#secret-password-store-sync
|
||||
+# the simple API was still considered unstable. All supported distros
|
||||
+# now have 0.18 where the API is stable.
|
||||
+PKG_CHECK_MODULES(KEYRING, [libsecret-1 >= 0.18], HAVE_KEYRING=yes, HAVE_KEYRING=no)
|
||||
AC_ARG_ENABLE(gnome-keyring,
|
||||
AS_HELP_STRING([--enable-gnome-keyring],
|
||||
- [enables or disables support for the GNOME keyring; default is on if development files are available]),
|
||||
+ [enables or disables support for the GNOME keyring via libsecret; default is on if development files are available]),
|
||||
[enable_gnome_keyring="$enableval"
|
||||
test "$enable_gnome_keyring" = "yes" || test "$enable_gnome_keyring" = "no" || AC_MSG_ERROR([invalid value for --enable-gnome-keyring: $enable_gnome_keyring])
|
||||
- test "$enable_gnome_keyring" = "no" || test "$HAVE_KEYRING" = "yes" || AC_MSG_ERROR([gnome-keyring-1 pkg >= 2.20 not found, needed for --enable-gnome-keyring])],
|
||||
+ test "$enable_gnome_keyring" = "no" || test "$HAVE_KEYRING" = "yes" || AC_MSG_ERROR([libsecret-1 >= 0.18 not found, needed for --enable-gnome-keyring])],
|
||||
enable_gnome_keyring="$HAVE_KEYRING")
|
||||
if test $enable_gnome_keyring = "yes"; then
|
||||
have_keyring=yes
|
|
@ -0,0 +1,42 @@
|
|||
Description: Fix FTBFS on kfreebsd due to missing SOCK_CLOEXEC
|
||||
Work around missing SOCK_CLOEXEC on kfreebsd
|
||||
by setting FD_CLOEXEC afterwards.
|
||||
Author: Tino Mettler <tino+debian@tikei.de>
|
||||
Last-Update: 2021-09-29
|
||||
---
|
||||
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
|
||||
--- a/src/gdbusxx/gdbus-cxx-bridge.cpp
|
||||
+++ b/src/gdbusxx/gdbus-cxx-bridge.cpp
|
||||
@@ -285,6 +285,10 @@
|
||||
true);
|
||||
}
|
||||
|
||||
+#ifndef SOCK_CLOEXEC
|
||||
+#define SOCK_CLOEXEC 0
|
||||
+#endif
|
||||
+
|
||||
std::shared_ptr<DBusServerCXX> DBusServerCXX::listen(const NewConnection_t &newConnection, DBusErrorCXX *)
|
||||
{
|
||||
// Create two fds connected via a two-way stream. The parent
|
||||
@@ -295,6 +299,21 @@
|
||||
if (retval) {
|
||||
SE_THROW(StringPrintf("socketpair: %s", strerror(errno)));
|
||||
}
|
||||
+
|
||||
+ if(SOCK_CLOEXEC == 0) {
|
||||
+ int flags;
|
||||
+ int i;
|
||||
+ for(i = 0; i < 2; i++) {
|
||||
+ flags = fcntl(fds[i], F_GETFD);
|
||||
+ if (flags == -1){
|
||||
+ SE_THROW(StringPrintf("fcntl: %s", strerror(errno)));
|
||||
+ }
|
||||
+ flags |= FD_CLOEXEC;
|
||||
+ if (fcntl(fds[i], F_SETFD, flags) == -1){
|
||||
+ SE_THROW(StringPrintf("fcntl: %s", strerror(errno)));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
GuardFD parentfd(fds[0]);
|
||||
GuardFD childfd(fds[1]);
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
Description: adjust whitespace as required for recent autotools
|
||||
Recent releases of autotools (possibly only autoreconf
|
||||
apparently only recognizes the macro IT_PROG_INTLTOOL
|
||||
when listed as the first word on a line.
|
||||
Otherwise autoreconf fails with the following error message:
|
||||
.
|
||||
autoreconf: running: intltoolize --copy --force
|
||||
ERROR: 'IT_PROG_INTLTOOL' must appear in configure.ac for intltool to work.
|
||||
Author: Jonas Smedegaard <dr@jones.dk>
|
||||
Last-Update: 2021-10-01
|
||||
---
|
||||
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -587,11 +587,11 @@
|
||||
AC_DEFINE_UNQUOTED(DBUS_SERVICES_DIR, "$DBUS_SERVICES_DIR", [Location of D-Bus services directory])
|
||||
|
||||
if test "$enable_gui" != "no" || test "$enable_dbus_service" != "no"; then
|
||||
- IT_PROG_INTLTOOL([0.37.1])
|
||||
- GETTEXT_PACKAGE=syncevolution
|
||||
- AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE", [The gettext package name])
|
||||
- AM_GLIB_GNU_GETTEXT
|
||||
- SYNCEVOLUTION_LOCALEDIR=[${datadir}/locale]
|
||||
+IT_PROG_INTLTOOL([0.37.1])
|
||||
+GETTEXT_PACKAGE=syncevolution
|
||||
+AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE", [The gettext package name])
|
||||
+AM_GLIB_GNU_GETTEXT
|
||||
+SYNCEVOLUTION_LOCALEDIR=[${datadir}/locale]
|
||||
fi
|
||||
|
||||
# decide which sync-ui(s) we are building:
|
|
@ -0,0 +1,3 @@
|
|||
0xxx: Grabbed from upstream development.
|
||||
1xxx: Possibly relevant for upstream adoption.
|
||||
2xxx: Only relevant for official Debian release.
|
|
@ -1,4 +1,2 @@
|
|||
# debian/source/git-patches exported from git by quilt-patches-deb-export-hook
|
||||
0001-Fix-FTBFS-on-kfreebsd-due-to-missing-SOCK_CLOEXEC.patch
|
||||
0002-libical-support-libical-v3.patch
|
||||
0003-GNOME-replace-gnome-keyring-with-libsecret.patch
|
||||
1001_SOCK_CLOEXEC.patch
|
||||
1002_intltool.patch
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
#!/usr/bin/make -f
|
||||
# -*- makefile -*-
|
||||
UPSTREAMTAG=upstream/1.5.2
|
||||
|
||||
SOURCEPKG=$(shell dpkg-parsechangelog | sed -n 's/^Source: \(.*\)/\1/p')
|
||||
UPSTREAM=$(shell dpkg-parsechangelog | sed -n 's/^Version: \(.*\)-[^-]*/\1/p')
|
||||
ORIG=${SOURCEPKG}_${UPSTREAM}.orig.tar.gz
|
||||
|
||||
DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
|
||||
export DEB_CXXFLAGS_APPEND = -std=c++14
|
||||
|
||||
export CONFIG_SHELL=/bin/bash
|
||||
|
||||
|
@ -14,44 +9,31 @@ export DEB_BUILD_MAINT_OPTIONS = hardening=+all
|
|||
export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic
|
||||
export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
|
||||
|
||||
%:
|
||||
dh $@ --parallel
|
||||
%:
|
||||
dh $@
|
||||
|
||||
override_dh_auto_install:
|
||||
make install DESTDIR=$(CURDIR)/debian/tmp
|
||||
install --mode=0755 --owner=root test/syncevo-http-server.py \
|
||||
$(CURDIR)/debian/tmp/usr/bin/syncevo-http-server
|
||||
override_dh_autoreconf:
|
||||
dh_autoreconf ./autogen.sh
|
||||
|
||||
override_dh_auto_configure:
|
||||
sh autogen.sh
|
||||
override_dh_auto_configure:
|
||||
dh_auto_configure -- --with-synthesis-src=none --prefix=/usr \
|
||||
--sysconfdir=/etc \
|
||||
--libexecdir=/usr/lib/$(DEB_HOST_MULTIARCH)/syncevolution \
|
||||
--enable-gui \
|
||||
--enable-kwallet --enable-akonadi \
|
||||
--with-rst2man --with-rst2html --enable-dav \
|
||||
--enable-oauth2
|
||||
|
||||
execute_after_dh_auto_install:
|
||||
cp test/syncevo-http-server.py \
|
||||
debian/tmp/usr/bin/syncevo-http-server
|
||||
|
||||
override_dh_install:
|
||||
dh_install -X"*.pl"
|
||||
|
||||
override_dh_strip:
|
||||
dh_strip --dbgsym-migration='syncevolution-dbg'
|
||||
|
||||
override_dh_auto_clean:
|
||||
rm -f INSTALL compile po/LINGUAS src/backends/backends.am \
|
||||
src/synthesis-includes/Makefile.in test-driver
|
||||
dh_auto_clean
|
||||
override_dh_missing:
|
||||
dh_missing
|
||||
|
||||
override_dh_makeshlibs:
|
||||
dh_makeshlibs -V'libsyncevolution0 (>= 1.5.2-3~)'
|
||||
|
||||
get-orig-source:
|
||||
git archive --format=tar ${UPSTREAMTAG} --prefix=${SOURCEPKG}_${UPSTREAM}/ | gzip -9 > ../${ORIG}
|
||||
|
||||
PATCH_EXPORT_SCRIPT=/usr/share/gitpkg/hooks/quilt-patches-deb-export-hook
|
||||
export-patches:
|
||||
[ ! -r debian/patches ] || \
|
||||
grep "^\#*$(notdir $(PATCH_EXPORT_SCRIPT))" debian/patches/series
|
||||
rm -rf debian/patches
|
||||
bash $(PATCH_EXPORT_SCRIPT)
|
||||
dh_makeshlibs -V'libsyncevolution0 (>= 1.5.2-3~)' -plibsyncevolution0
|
||||
dh_makeshlibs -V'libsyncevo-dbus0 (>= 1.5.2-3~)' -plibsyncevo-dbus0
|
||||
dh_makeshlibs -V'libgdbussyncevo0 (>= 1.5.2-3~)' -plibgdbussyncevo0
|
||||
dh_makeshlibs --remaining-packages
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
upstream/${UPSTREAM_REF}..patches/${DEB_REF}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# License is in Reference field (see bug#786450)
|
||||
missing-license-paragraph-in-dep5-copyright debian/copyright artistic *
|
||||
missing-license-paragraph-in-dep5-copyright debian/copyright gpl-1\+ *
|
||||
missing-license-paragraph-in-dep5-copyright debian/copyright gpl-2\+ *
|
||||
missing-license-paragraph-in-dep5-copyright debian/copyright gpl-3 *
|
||||
missing-license-paragraph-in-dep5-copyright debian/copyright lgpl-2 *
|
||||
missing-license-paragraph-in-dep5-copyright debian/copyright lgpl-2\+ *
|
||||
missing-license-paragraph-in-dep5-copyright debian/copyright lgpl-2\.1 *
|
||||
missing-license-paragraph-in-dep5-copyright debian/copyright lgpl-3 *
|
||||
missing-license-text-in-dep5-copyright debian/copyright Artistic *
|
||||
missing-license-text-in-dep5-copyright debian/copyright GPL-1\+ *
|
||||
missing-license-text-in-dep5-copyright debian/copyright GPL-2\+ *
|
||||
missing-license-text-in-dep5-copyright debian/copyright GPL-3 *
|
||||
missing-license-text-in-dep5-copyright debian/copyright LGPL-2 *
|
||||
missing-license-text-in-dep5-copyright debian/copyright LGPL-2\+ *
|
||||
missing-license-text-in-dep5-copyright debian/copyright LGPL-2\.1 *
|
||||
missing-license-text-in-dep5-copyright debian/copyright LGPL-3 *
|
|
@ -1,23 +1,4 @@
|
|||
usr/share/locale/ja/LC_MESSAGES/syncevolution.mo
|
||||
usr/share/locale/ro/LC_MESSAGES/syncevolution.mo
|
||||
usr/share/locale/fi/LC_MESSAGES/syncevolution.mo
|
||||
usr/share/locale/sv/LC_MESSAGES/syncevolution.mo
|
||||
usr/share/locale/ar/LC_MESSAGES/syncevolution.mo
|
||||
usr/share/locale/pt_BR/LC_MESSAGES/syncevolution.mo
|
||||
usr/share/locale/gl/LC_MESSAGES/syncevolution.mo
|
||||
usr/share/locale/hu/LC_MESSAGES/syncevolution.mo
|
||||
usr/share/locale/ko/LC_MESSAGES/syncevolution.mo
|
||||
usr/share/locale/zh_TW/LC_MESSAGES/syncevolution.mo
|
||||
usr/share/locale/de/LC_MESSAGES/syncevolution.mo
|
||||
usr/share/locale/zh_CN/LC_MESSAGES/syncevolution.mo
|
||||
usr/share/locale/es/LC_MESSAGES/syncevolution.mo
|
||||
usr/share/locale/pl/LC_MESSAGES/syncevolution.mo
|
||||
usr/share/locale/id/LC_MESSAGES/syncevolution.mo
|
||||
usr/share/locale/da/LC_MESSAGES/syncevolution.mo
|
||||
usr/share/locale/fr/LC_MESSAGES/syncevolution.mo
|
||||
usr/share/locale/nl/LC_MESSAGES/syncevolution.mo
|
||||
usr/share/locale/it/LC_MESSAGES/syncevolution.mo
|
||||
usr/share/locale/th/LC_MESSAGES/syncevolution.mo
|
||||
usr/share/locale/ca/LC_MESSAGES/syncevolution.mo
|
||||
usr/bin/synccompare
|
||||
usr/bin/syncevo-webdav-lookup
|
||||
usr/share/locale/*/LC_MESSAGES/syncevolution.mo
|
||||
usr/share/syncevolution
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
test/dbus-server-sync.py
|
|
@ -1,5 +1,6 @@
|
|||
usr/share/dbus-1/services/org.syncevolution.service
|
||||
etc/xdg/autostart/syncevo-dbus-server.desktop
|
||||
usr/libexec/syncevo-dbus-helper
|
||||
usr/libexec/syncevo-dbus-server
|
||||
usr/libexec/syncevo-dbus-server-startup.sh
|
||||
usr/lib/systemd/user/*.service
|
||||
usr/lib/*/syncevolution/syncevo-dbus-server
|
||||
usr/lib/*/syncevolution/syncevo-dbus-helper
|
||||
|
||||
usr/share/dbus-1/services/org.syncevolution.service
|
||||
|
|
|
@ -1 +1 @@
|
|||
usr/bin/syncevo-http-server
|
||||
usr/bin/syncevo-http-server
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
usr/lib/*/syncevolution/backends/platformkde.so
|
||||
usr/lib/*/syncevolution/backends/syncakonadi.so
|
|
@ -1,10 +1,12 @@
|
|||
usr/lib/*/syncevolution/backends/syncfile.so
|
||||
usr/lib/*/syncevolution/backends/syncdav.so
|
||||
usr/lib/*/syncevolution/backends/syncxmlrpc.so
|
||||
usr/lib/*/syncevolution/backends/synckcalextended.so
|
||||
usr/lib/*/syncevolution/backends/syncqtcontacts.so
|
||||
usr/lib/*/syncevolution/backends/syncmaemocal.so
|
||||
usr/lib/*/syncevolution/backends/syncactivesync.so
|
||||
usr/lib/*/syncevolution/backends/syncsqlite.so
|
||||
usr/lib/*/syncevolution/backends/providergoa.so
|
||||
usr/lib/*/syncevolution/backends/provideroauth2.so
|
||||
usr/lib/*/syncevolution/syncevo-local-sync
|
||||
usr/lib/*/syncevolution/backends/syncdav.so
|
||||
usr/lib/*/syncevolution/backends/syncfile.so
|
||||
usr/lib/*/syncevolution/backends/syncpbap.so
|
||||
usr/lib/*/syncevolution/backends/synckcalextended.so
|
||||
usr/lib/*/syncevolution/backends/syncmaemocal.so
|
||||
usr/lib/*/syncevolution/backends/syncqtcontacts.so
|
||||
usr/lib/*/syncevolution/backends/syncsqlite.so
|
||||
usr/lib/*/syncevolution/backends/syncxmlrpc.so
|
||||
|
||||
usr/libexec/syncevo-local-sync
|
||||
|
|
|
@ -1,9 +1,3 @@
|
|||
debian/tmp/usr/share/doc/syncevolution/README.nokia_7210c
|
||||
debian/tmp/usr/share/doc/syncevolution/README.scheduleworld
|
||||
debian/tmp/usr/share/doc/syncevolution/README.mobical
|
||||
debian/tmp/usr/share/doc/syncevolution/README
|
||||
debian/tmp/usr/share/doc/syncevolution/README.funambol
|
||||
debian/tmp/usr/share/doc/syncevolution/README.zyb
|
||||
debian/tmp/usr/share/doc/syncevolution/NEWS
|
||||
debian/tmp/usr/share/doc/syncevolution/README.google
|
||||
debian/tmp/usr/share/doc/syncevolution/README.memotoo
|
||||
debian/tmp/usr/share/doc/syncevolution/README
|
||||
debian/tmp/usr/share/doc/syncevolution/README.*
|
||||
|
|
|
@ -1,2 +1,5 @@
|
|||
debian/tmp/usr/share/doc/syncevolution/accounts
|
||||
debian/tmp/usr/share/doc/syncevolution/syncevo-http-server-logging.conf
|
||||
debian/tmp/usr/share/syncevolution/xml/update-samples.pl
|
||||
debian/tmp/usr/share/doc/syncevolution/accounts
|
||||
test/syncevo-phone-config.py
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
syncevolution.1
|
||||
|
||||
debian/tmp/usr/share/man/man1/syncevolution.1
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
version=3
|
||||
version=4
|
||||
# check: uscan --report
|
||||
# update: gbp import-orig --upstream-vcs-tag=vX.Y.Z --uscan
|
||||
|
||||
opts=dversionmangle=s/\+ds\d+$// \
|
||||
http://downloads.syncevolution.org/syncevolution/sources/syncevolution-(.*).tar.gz
|
||||
opts=\
|
||||
filenamemangle=s/.*?(@ANY_VERSION@@ARCHIVE_EXT@)/@PACKAGE@$1/,\
|
||||
uversionmangle=s/-(?=\d)/./g;s/-?pre/~pre/,\
|
||||
dversionmangle=auto \
|
||||
https://gitlab.freedesktop.org/SyncEvolution/syncevolution/-/tags \
|
||||
.*?@ANY_VERSION@@ARCHIVE_EXT@
|
||||
|
|
|
@ -0,0 +1,982 @@
|
|||
# ===========================================================================
|
||||
# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Check for baseline language coverage in the compiler for the specified
|
||||
# version of the C++ standard. If necessary, add switches to CXX and
|
||||
# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard)
|
||||
# or '14' (for the C++14 standard).
|
||||
#
|
||||
# The second argument, if specified, indicates whether you insist on an
|
||||
# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
|
||||
# -std=c++11). If neither is specified, you get whatever works, with
|
||||
# preference for an extended mode.
|
||||
#
|
||||
# The third argument, if specified 'mandatory' or if left unspecified,
|
||||
# indicates that baseline support for the specified C++ standard is
|
||||
# required and that the macro should error out if no mode with that
|
||||
# support is found. If specified 'optional', then configuration proceeds
|
||||
# regardless, after defining HAVE_CXX${VERSION} if and only if a
|
||||
# supporting mode is found.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
|
||||
# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
|
||||
# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
|
||||
# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>
|
||||
# Copyright (c) 2015 Paul Norman <penorman@mac.com>
|
||||
# Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
|
||||
# Copyright (c) 2016 Krzesimir Nowak <qdlacz@gmail.com>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 7
|
||||
|
||||
dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro
|
||||
dnl (serial version number 13).
|
||||
|
||||
AX_REQUIRE_DEFINED([AC_MSG_WARN])
|
||||
AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl
|
||||
m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"],
|
||||
[$1], [14], [ax_cxx_compile_alternatives="14 1y"],
|
||||
[$1], [17], [ax_cxx_compile_alternatives="17 1z"],
|
||||
[m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl
|
||||
m4_if([$2], [], [],
|
||||
[$2], [ext], [],
|
||||
[$2], [noext], [],
|
||||
[m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl
|
||||
m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true],
|
||||
[$3], [mandatory], [ax_cxx_compile_cxx$1_required=true],
|
||||
[$3], [optional], [ax_cxx_compile_cxx$1_required=false],
|
||||
[m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])])
|
||||
AC_LANG_PUSH([C++])dnl
|
||||
ac_success=no
|
||||
AC_CACHE_CHECK(whether $CXX supports C++$1 features by default,
|
||||
ax_cv_cxx_compile_cxx$1,
|
||||
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
|
||||
[ax_cv_cxx_compile_cxx$1=yes],
|
||||
[ax_cv_cxx_compile_cxx$1=no])])
|
||||
if test x$ax_cv_cxx_compile_cxx$1 = xyes; then
|
||||
ac_success=yes
|
||||
fi
|
||||
|
||||
m4_if([$2], [noext], [], [dnl
|
||||
if test x$ac_success = xno; then
|
||||
for alternative in ${ax_cxx_compile_alternatives}; do
|
||||
switch="-std=gnu++${alternative}"
|
||||
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
|
||||
AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
|
||||
$cachevar,
|
||||
[ac_save_CXX="$CXX"
|
||||
CXX="$CXX $switch"
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
|
||||
[eval $cachevar=yes],
|
||||
[eval $cachevar=no])
|
||||
CXX="$ac_save_CXX"])
|
||||
if eval test x\$$cachevar = xyes; then
|
||||
CXX="$CXX $switch"
|
||||
if test -n "$CXXCPP" ; then
|
||||
CXXCPP="$CXXCPP $switch"
|
||||
fi
|
||||
ac_success=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi])
|
||||
|
||||
m4_if([$2], [ext], [], [dnl
|
||||
if test x$ac_success = xno; then
|
||||
dnl HP's aCC needs +std=c++11 according to:
|
||||
dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf
|
||||
dnl Cray's crayCC needs "-h std=c++11"
|
||||
for alternative in ${ax_cxx_compile_alternatives}; do
|
||||
for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do
|
||||
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
|
||||
AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
|
||||
$cachevar,
|
||||
[ac_save_CXX="$CXX"
|
||||
CXX="$CXX $switch"
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
|
||||
[eval $cachevar=yes],
|
||||
[eval $cachevar=no])
|
||||
CXX="$ac_save_CXX"])
|
||||
if eval test x\$$cachevar = xyes; then
|
||||
CXX="$CXX $switch"
|
||||
if test -n "$CXXCPP" ; then
|
||||
CXXCPP="$CXXCPP $switch"
|
||||
fi
|
||||
ac_success=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test x$ac_success = xyes; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi])
|
||||
AC_LANG_POP([C++])
|
||||
if test x$ax_cxx_compile_cxx$1_required = xtrue; then
|
||||
if test x$ac_success = xno; then
|
||||
AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.])
|
||||
fi
|
||||
fi
|
||||
if test x$ac_success = xno; then
|
||||
HAVE_CXX$1=0
|
||||
AC_MSG_NOTICE([No compiler with C++$1 support was found])
|
||||
else
|
||||
HAVE_CXX$1=1
|
||||
AC_DEFINE(HAVE_CXX$1,1,
|
||||
[define if the compiler supports basic C++$1 syntax])
|
||||
fi
|
||||
AC_SUBST(HAVE_CXX$1)
|
||||
m4_if([$1], [17], [AC_MSG_WARN([C++17 is not yet standardized, so the checks may change in incompatible ways anytime])])
|
||||
])
|
||||
|
||||
|
||||
dnl Test body for checking C++11 support
|
||||
|
||||
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11],
|
||||
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
|
||||
)
|
||||
|
||||
|
||||
dnl Test body for checking C++14 support
|
||||
|
||||
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14],
|
||||
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
|
||||
_AX_CXX_COMPILE_STDCXX_testbody_new_in_14
|
||||
)
|
||||
|
||||
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17],
|
||||
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
|
||||
_AX_CXX_COMPILE_STDCXX_testbody_new_in_14
|
||||
_AX_CXX_COMPILE_STDCXX_testbody_new_in_17
|
||||
)
|
||||
|
||||
dnl Tests for new features in C++11
|
||||
|
||||
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[
|
||||
|
||||
// If the compiler admits that it is not ready for C++11, why torture it?
|
||||
// Hopefully, this will speed up the test.
|
||||
|
||||
#ifndef __cplusplus
|
||||
|
||||
#error "This is not a C++ compiler"
|
||||
|
||||
#elif __cplusplus < 201103L
|
||||
|
||||
#error "This is not a C++11 compiler"
|
||||
|
||||
#else
|
||||
|
||||
namespace cxx11
|
||||
{
|
||||
|
||||
namespace test_static_assert
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
struct check
|
||||
{
|
||||
static_assert(sizeof(int) <= sizeof(T), "not big enough");
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace test_final_override
|
||||
{
|
||||
|
||||
struct Base
|
||||
{
|
||||
virtual void f() {}
|
||||
};
|
||||
|
||||
struct Derived : public Base
|
||||
{
|
||||
virtual void f() override {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace test_double_right_angle_brackets
|
||||
{
|
||||
|
||||
template < typename T >
|
||||
struct check {};
|
||||
|
||||
typedef check<void> single_type;
|
||||
typedef check<check<void>> double_type;
|
||||
typedef check<check<check<void>>> triple_type;
|
||||
typedef check<check<check<check<void>>>> quadruple_type;
|
||||
|
||||
}
|
||||
|
||||
namespace test_decltype
|
||||
{
|
||||
|
||||
int
|
||||
f()
|
||||
{
|
||||
int a = 1;
|
||||
decltype(a) b = 2;
|
||||
return a + b;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_type_deduction
|
||||
{
|
||||
|
||||
template < typename T1, typename T2 >
|
||||
struct is_same
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
struct is_same<T, T>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template < typename T1, typename T2 >
|
||||
auto
|
||||
add(T1 a1, T2 a2) -> decltype(a1 + a2)
|
||||
{
|
||||
return a1 + a2;
|
||||
}
|
||||
|
||||
int
|
||||
test(const int c, volatile int v)
|
||||
{
|
||||
static_assert(is_same<int, decltype(0)>::value == true, "");
|
||||
static_assert(is_same<int, decltype(c)>::value == false, "");
|
||||
static_assert(is_same<int, decltype(v)>::value == false, "");
|
||||
auto ac = c;
|
||||
auto av = v;
|
||||
auto sumi = ac + av + 'x';
|
||||
auto sumf = ac + av + 1.0;
|
||||
static_assert(is_same<int, decltype(ac)>::value == true, "");
|
||||
static_assert(is_same<int, decltype(av)>::value == true, "");
|
||||
static_assert(is_same<int, decltype(sumi)>::value == true, "");
|
||||
static_assert(is_same<int, decltype(sumf)>::value == false, "");
|
||||
static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
|
||||
return (sumf > 0.0) ? sumi : add(c, v);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_noexcept
|
||||
{
|
||||
|
||||
int f() { return 0; }
|
||||
int g() noexcept { return 0; }
|
||||
|
||||
static_assert(noexcept(f()) == false, "");
|
||||
static_assert(noexcept(g()) == true, "");
|
||||
|
||||
}
|
||||
|
||||
namespace test_constexpr
|
||||
{
|
||||
|
||||
template < typename CharT >
|
||||
unsigned long constexpr
|
||||
strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
|
||||
{
|
||||
return *s ? strlen_c_r(s + 1, acc + 1) : acc;
|
||||
}
|
||||
|
||||
template < typename CharT >
|
||||
unsigned long constexpr
|
||||
strlen_c(const CharT *const s) noexcept
|
||||
{
|
||||
return strlen_c_r(s, 0UL);
|
||||
}
|
||||
|
||||
static_assert(strlen_c("") == 0UL, "");
|
||||
static_assert(strlen_c("1") == 1UL, "");
|
||||
static_assert(strlen_c("example") == 7UL, "");
|
||||
static_assert(strlen_c("another\0example") == 7UL, "");
|
||||
|
||||
}
|
||||
|
||||
namespace test_rvalue_references
|
||||
{
|
||||
|
||||
template < int N >
|
||||
struct answer
|
||||
{
|
||||
static constexpr int value = N;
|
||||
};
|
||||
|
||||
answer<1> f(int&) { return answer<1>(); }
|
||||
answer<2> f(const int&) { return answer<2>(); }
|
||||
answer<3> f(int&&) { return answer<3>(); }
|
||||
|
||||
void
|
||||
test()
|
||||
{
|
||||
int i = 0;
|
||||
const int c = 0;
|
||||
static_assert(decltype(f(i))::value == 1, "");
|
||||
static_assert(decltype(f(c))::value == 2, "");
|
||||
static_assert(decltype(f(0))::value == 3, "");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_uniform_initialization
|
||||
{
|
||||
|
||||
struct test
|
||||
{
|
||||
static const int zero {};
|
||||
static const int one {1};
|
||||
};
|
||||
|
||||
static_assert(test::zero == 0, "");
|
||||
static_assert(test::one == 1, "");
|
||||
|
||||
}
|
||||
|
||||
namespace test_lambdas
|
||||
{
|
||||
|
||||
void
|
||||
test1()
|
||||
{
|
||||
auto lambda1 = [](){};
|
||||
auto lambda2 = lambda1;
|
||||
lambda1();
|
||||
lambda2();
|
||||
}
|
||||
|
||||
int
|
||||
test2()
|
||||
{
|
||||
auto a = [](int i, int j){ return i + j; }(1, 2);
|
||||
auto b = []() -> int { return '0'; }();
|
||||
auto c = [=](){ return a + b; }();
|
||||
auto d = [&](){ return c; }();
|
||||
auto e = [a, &b](int x) mutable {
|
||||
const auto identity = [](int y){ return y; };
|
||||
for (auto i = 0; i < a; ++i)
|
||||
a += b--;
|
||||
return x + identity(a + b);
|
||||
}(0);
|
||||
return a + b + c + d + e;
|
||||
}
|
||||
|
||||
int
|
||||
test3()
|
||||
{
|
||||
const auto nullary = [](){ return 0; };
|
||||
const auto unary = [](int x){ return x; };
|
||||
using nullary_t = decltype(nullary);
|
||||
using unary_t = decltype(unary);
|
||||
const auto higher1st = [](nullary_t f){ return f(); };
|
||||
const auto higher2nd = [unary](nullary_t f1){
|
||||
return [unary, f1](unary_t f2){ return f2(unary(f1())); };
|
||||
};
|
||||
return higher1st(nullary) + higher2nd(nullary)(unary);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_variadic_templates
|
||||
{
|
||||
|
||||
template <int...>
|
||||
struct sum;
|
||||
|
||||
template <int N0, int... N1toN>
|
||||
struct sum<N0, N1toN...>
|
||||
{
|
||||
static constexpr auto value = N0 + sum<N1toN...>::value;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct sum<>
|
||||
{
|
||||
static constexpr auto value = 0;
|
||||
};
|
||||
|
||||
static_assert(sum<>::value == 0, "");
|
||||
static_assert(sum<1>::value == 1, "");
|
||||
static_assert(sum<23>::value == 23, "");
|
||||
static_assert(sum<1, 2>::value == 3, "");
|
||||
static_assert(sum<5, 5, 11>::value == 21, "");
|
||||
static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
|
||||
|
||||
}
|
||||
|
||||
// http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
|
||||
// Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
|
||||
// because of this.
|
||||
namespace test_template_alias_sfinae
|
||||
{
|
||||
|
||||
struct foo {};
|
||||
|
||||
template<typename T>
|
||||
using member = typename T::member_type;
|
||||
|
||||
template<typename T>
|
||||
void func(...) {}
|
||||
|
||||
template<typename T>
|
||||
void func(member<T>*) {}
|
||||
|
||||
void test();
|
||||
|
||||
void test() { func<foo>(0); }
|
||||
|
||||
}
|
||||
|
||||
} // namespace cxx11
|
||||
|
||||
#endif // __cplusplus >= 201103L
|
||||
|
||||
]])
|
||||
|
||||
|
||||
dnl Tests for new features in C++14
|
||||
|
||||
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[
|
||||
|
||||
// If the compiler admits that it is not ready for C++14, why torture it?
|
||||
// Hopefully, this will speed up the test.
|
||||
|
||||
#ifndef __cplusplus
|
||||
|
||||
#error "This is not a C++ compiler"
|
||||
|
||||
#elif __cplusplus < 201402L
|
||||
|
||||
#error "This is not a C++14 compiler"
|
||||
|
||||
#else
|
||||
|
||||
namespace cxx14
|
||||
{
|
||||
|
||||
namespace test_polymorphic_lambdas
|
||||
{
|
||||
|
||||
int
|
||||
test()
|
||||
{
|
||||
const auto lambda = [](auto&&... args){
|
||||
const auto istiny = [](auto x){
|
||||
return (sizeof(x) == 1UL) ? 1 : 0;
|
||||
};
|
||||
const int aretiny[] = { istiny(args)... };
|
||||
return aretiny[0];
|
||||
};
|
||||
return lambda(1, 1L, 1.0f, '1');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_binary_literals
|
||||
{
|
||||
|
||||
constexpr auto ivii = 0b0000000000101010;
|
||||
static_assert(ivii == 42, "wrong value");
|
||||
|
||||
}
|
||||
|
||||
namespace test_generalized_constexpr
|
||||
{
|
||||
|
||||
template < typename CharT >
|
||||
constexpr unsigned long
|
||||
strlen_c(const CharT *const s) noexcept
|
||||
{
|
||||
auto length = 0UL;
|
||||
for (auto p = s; *p; ++p)
|
||||
++length;
|
||||
return length;
|
||||
}
|
||||
|
||||
static_assert(strlen_c("") == 0UL, "");
|
||||
static_assert(strlen_c("x") == 1UL, "");
|
||||
static_assert(strlen_c("test") == 4UL, "");
|
||||
static_assert(strlen_c("another\0test") == 7UL, "");
|
||||
|
||||
}
|
||||
|
||||
namespace test_lambda_init_capture
|
||||
{
|
||||
|
||||
int
|
||||
test()
|
||||
{
|
||||
auto x = 0;
|
||||
const auto lambda1 = [a = x](int b){ return a + b; };
|
||||
const auto lambda2 = [a = lambda1(x)](){ return a; };
|
||||
return lambda2();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_digit_separators
|
||||
{
|
||||
|
||||
constexpr auto ten_million = 100'000'000;
|
||||
static_assert(ten_million == 100000000, "");
|
||||
|
||||
}
|
||||
|
||||
namespace test_return_type_deduction
|
||||
{
|
||||
|
||||
auto f(int& x) { return x; }
|
||||
decltype(auto) g(int& x) { return x; }
|
||||
|
||||
template < typename T1, typename T2 >
|
||||
struct is_same
|
||||
{
|
||||
static constexpr auto value = false;
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
struct is_same<T, T>
|
||||
{
|
||||
static constexpr auto value = true;
|
||||
};
|
||||
|
||||
int
|
||||
test()
|
||||
{
|
||||
auto x = 0;
|
||||
static_assert(is_same<int, decltype(f(x))>::value, "");
|
||||
static_assert(is_same<int&, decltype(g(x))>::value, "");
|
||||
return x;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace cxx14
|
||||
|
||||
#endif // __cplusplus >= 201402L
|
||||
|
||||
]])
|
||||
|
||||
|
||||
dnl Tests for new features in C++17
|
||||
|
||||
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[
|
||||
|
||||
// If the compiler admits that it is not ready for C++17, why torture it?
|
||||
// Hopefully, this will speed up the test.
|
||||
|
||||
#ifndef __cplusplus
|
||||
|
||||
#error "This is not a C++ compiler"
|
||||
|
||||
#elif __cplusplus <= 201402L
|
||||
|
||||
#error "This is not a C++17 compiler"
|
||||
|
||||
#else
|
||||
|
||||
#if defined(__clang__)
|
||||
#define REALLY_CLANG
|
||||
#else
|
||||
#if defined(__GNUC__)
|
||||
#define REALLY_GCC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <initializer_list>
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
|
||||
namespace cxx17
|
||||
{
|
||||
|
||||
#if !defined(REALLY_CLANG)
|
||||
namespace test_constexpr_lambdas
|
||||
{
|
||||
|
||||
// TODO: test it with clang++ from git
|
||||
|
||||
constexpr int foo = [](){return 42;}();
|
||||
|
||||
}
|
||||
#endif // !defined(REALLY_CLANG)
|
||||
|
||||
namespace test::nested_namespace::definitions
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
namespace test_fold_expression
|
||||
{
|
||||
|
||||
template<typename... Args>
|
||||
int multiply(Args... args)
|
||||
{
|
||||
return (args * ... * 1);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
bool all(Args... args)
|
||||
{
|
||||
return (args && ...);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_extended_static_assert
|
||||
{
|
||||
|
||||
static_assert (true);
|
||||
|
||||
}
|
||||
|
||||
namespace test_auto_brace_init_list
|
||||
{
|
||||
|
||||
auto foo = {5};
|
||||
auto bar {5};
|
||||
|
||||
static_assert(std::is_same<std::initializer_list<int>, decltype(foo)>::value);
|
||||
static_assert(std::is_same<int, decltype(bar)>::value);
|
||||
}
|
||||
|
||||
namespace test_typename_in_template_template_parameter
|
||||
{
|
||||
|
||||
template<template<typename> typename X> struct D;
|
||||
|
||||
}
|
||||
|
||||
namespace test_fallthrough_nodiscard_maybe_unused_attributes
|
||||
{
|
||||
|
||||
int f1()
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
|
||||
[[nodiscard]] int f2()
|
||||
{
|
||||
[[maybe_unused]] auto unused = f1();
|
||||
|
||||
switch (f1())
|
||||
{
|
||||
case 17:
|
||||
f1();
|
||||
[[fallthrough]];
|
||||
case 42:
|
||||
f1();
|
||||
}
|
||||
return f1();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_extended_aggregate_initialization
|
||||
{
|
||||
|
||||
struct base1
|
||||
{
|
||||
int b1, b2 = 42;
|
||||
};
|
||||
|
||||
struct base2
|
||||
{
|
||||
base2() {
|
||||
b3 = 42;
|
||||
}
|
||||
int b3;
|
||||
};
|
||||
|
||||
struct derived : base1, base2
|
||||
{
|
||||
int d;
|
||||
};
|
||||
|
||||
derived d1 {{1, 2}, {}, 4}; // full initialization
|
||||
derived d2 {{}, {}, 4}; // value-initialized bases
|
||||
|
||||
}
|
||||
|
||||
namespace test_general_range_based_for_loop
|
||||
{
|
||||
|
||||
struct iter
|
||||
{
|
||||
int i;
|
||||
|
||||
int& operator* ()
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
||||
const int& operator* () const
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
||||
iter& operator++()
|
||||
{
|
||||
++i;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
struct sentinel
|
||||
{
|
||||
int i;
|
||||
};
|
||||
|
||||
bool operator== (const iter& i, const sentinel& s)
|
||||
{
|
||||
return i.i == s.i;
|
||||
}
|
||||
|
||||
bool operator!= (const iter& i, const sentinel& s)
|
||||
{
|
||||
return !(i == s);
|
||||
}
|
||||
|
||||
struct range
|
||||
{
|
||||
iter begin() const
|
||||
{
|
||||
return {0};
|
||||
}
|
||||
|
||||
sentinel end() const
|
||||
{
|
||||
return {5};
|
||||
}
|
||||
};
|
||||
|
||||
void f()
|
||||
{
|
||||
range r {};
|
||||
|
||||
for (auto i : r)
|
||||
{
|
||||
[[maybe_unused]] auto v = i;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_lambda_capture_asterisk_this_by_value
|
||||
{
|
||||
|
||||
struct t
|
||||
{
|
||||
int i;
|
||||
int foo()
|
||||
{
|
||||
return [*this]()
|
||||
{
|
||||
return i;
|
||||
}();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace test_enum_class_construction
|
||||
{
|
||||
|
||||
enum class byte : unsigned char
|
||||
{};
|
||||
|
||||
byte foo {42};
|
||||
|
||||
}
|
||||
|
||||
namespace test_constexpr_if
|
||||
{
|
||||
|
||||
template <bool cond>
|
||||
int f ()
|
||||
{
|
||||
if constexpr(cond)
|
||||
{
|
||||
return 13;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_selection_statement_with_initializer
|
||||
{
|
||||
|
||||
int f()
|
||||
{
|
||||
return 13;
|
||||
}
|
||||
|
||||
int f2()
|
||||
{
|
||||
if (auto i = f(); i > 0)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
switch (auto i = f(); i + 4)
|
||||
{
|
||||
case 17:
|
||||
return 2;
|
||||
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if !defined(REALLY_CLANG)
|
||||
namespace test_template_argument_deduction_for_class_templates
|
||||
{
|
||||
|
||||
// TODO: test it with clang++ from git
|
||||
|
||||
template <typename T1, typename T2>
|
||||
struct pair
|
||||
{
|
||||
pair (T1 p1, T2 p2)
|
||||
: m1 {p1},
|
||||
m2 {p2}
|
||||
{}
|
||||
|
||||
T1 m1;
|
||||
T2 m2;
|
||||
};
|
||||
|
||||
void f()
|
||||
{
|
||||
[[maybe_unused]] auto p = pair{13, 42u};
|
||||
}
|
||||
|
||||
}
|
||||
#endif // !defined(REALLY_CLANG)
|
||||
|
||||
namespace test_non_type_auto_template_parameters
|
||||
{
|
||||
|
||||
template <auto n>
|
||||
struct B
|
||||
{};
|
||||
|
||||
B<5> b1;
|
||||
B<'a'> b2;
|
||||
|
||||
}
|
||||
|
||||
#if !defined(REALLY_CLANG)
|
||||
namespace test_structured_bindings
|
||||
{
|
||||
|
||||
// TODO: test it with clang++ from git
|
||||
|
||||
int arr[2] = { 1, 2 };
|
||||
std::pair<int, int> pr = { 1, 2 };
|
||||
|
||||
auto f1() -> int(&)[2]
|
||||
{
|
||||
return arr;
|
||||
}
|
||||
|
||||
auto f2() -> std::pair<int, int>&
|
||||
{
|
||||
return pr;
|
||||
}
|
||||
|
||||
struct S
|
||||
{
|
||||
int x1 : 2;
|
||||
volatile double y1;
|
||||
};
|
||||
|
||||
S f3()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
auto [ x1, y1 ] = f1();
|
||||
auto& [ xr1, yr1 ] = f1();
|
||||
auto [ x2, y2 ] = f2();
|
||||
auto& [ xr2, yr2 ] = f2();
|
||||
const auto [ x3, y3 ] = f3();
|
||||
|
||||
}
|
||||
#endif // !defined(REALLY_CLANG)
|
||||
|
||||
#if !defined(REALLY_CLANG)
|
||||
namespace test_exception_spec_type_system
|
||||
{
|
||||
|
||||
// TODO: test it with clang++ from git
|
||||
|
||||
struct Good {};
|
||||
struct Bad {};
|
||||
|
||||
void g1() noexcept;
|
||||
void g2();
|
||||
|
||||
template<typename T>
|
||||
Bad
|
||||
f(T*, T*);
|
||||
|
||||
template<typename T1, typename T2>
|
||||
Good
|
||||
f(T1*, T2*);
|
||||
|
||||
static_assert (std::is_same_v<Good, decltype(f(g1, g2))>);
|
||||
|
||||
}
|
||||
#endif // !defined(REALLY_CLANG)
|
||||
|
||||
namespace test_inline_variables
|
||||
{
|
||||
|
||||
template<class T> void f(T)
|
||||
{}
|
||||
|
||||
template<class T> inline T g(T)
|
||||
{
|
||||
return T{};
|
||||
}
|
||||
|
||||
template<> inline void f<>(int)
|
||||
{}
|
||||
|
||||
template<> int g<>(int)
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace cxx17
|
||||
|
||||
#endif // __cplusplus <= 201402L
|
||||
|
||||
]])
|
|
@ -0,0 +1,39 @@
|
|||
# =============================================================================
|
||||
# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html
|
||||
# =============================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_CXX_COMPILE_STDCXX_11([ext|noext], [mandatory|optional])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Check for baseline language coverage in the compiler for the C++11
|
||||
# standard; if necessary, add switches to CXX and CXXCPP to enable
|
||||
# support.
|
||||
#
|
||||
# This macro is a convenience alias for calling the AX_CXX_COMPILE_STDCXX
|
||||
# macro with the version set to C++11. The two optional arguments are
|
||||
# forwarded literally as the second and third argument respectively.
|
||||
# Please see the documentation for the AX_CXX_COMPILE_STDCXX macro for
|
||||
# more information. If you want to use this macro, you also need to
|
||||
# download the ax_cxx_compile_stdcxx.m4 file.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
|
||||
# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
|
||||
# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
|
||||
# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>
|
||||
# Copyright (c) 2015 Paul Norman <penorman@mac.com>
|
||||
# Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 18
|
||||
|
||||
AX_REQUIRE_DEFINED([AX_CXX_COMPILE_STDCXX])
|
||||
AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [AX_CXX_COMPILE_STDCXX([11], [$1], [$2])])
|
|
@ -0,0 +1,34 @@
|
|||
# =============================================================================
|
||||
# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_14.html
|
||||
# =============================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_CXX_COMPILE_STDCXX_14([ext|noext], [mandatory|optional])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Check for baseline language coverage in the compiler for the C++14
|
||||
# standard; if necessary, add switches to CXX and CXXCPP to enable
|
||||
# support.
|
||||
#
|
||||
# This macro is a convenience alias for calling the AX_CXX_COMPILE_STDCXX
|
||||
# macro with the version set to C++14. The two optional arguments are
|
||||
# forwarded literally as the second and third argument respectively.
|
||||
# Please see the documentation for the AX_CXX_COMPILE_STDCXX macro for
|
||||
# more information. If you want to use this macro, you also need to
|
||||
# download the ax_cxx_compile_stdcxx.m4 file.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 5
|
||||
|
||||
AX_REQUIRE_DEFINED([AX_CXX_COMPILE_STDCXX])
|
||||
AC_DEFUN([AX_CXX_COMPILE_STDCXX_14], [AX_CXX_COMPILE_STDCXX([14], [$1], [$2])])
|
|
@ -34,7 +34,7 @@ COPYRIGHT_HOLDER =
|
|||
# It can be your email address, or a mailing list address where translators
|
||||
# can write to without being subscribed, or the URL of a web page through
|
||||
# which the translators can contact you.
|
||||
MSGID_BUGS_ADDRESS = http://moblin.org/projects/syncevolution
|
||||
MSGID_BUGS_ADDRESS = https://syncevolution.org/
|
||||
|
||||
# This is the list of locale categories, beyond LC_MESSAGES, for which the
|
||||
# message catalogs shall be used. It is usually empty.
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
src/gtk-ui/ui.xml
|
||||
src/gtk-ui/gtkinfobar.c
|
||||
src/synthesis/src/pcre/pcre_compile.c
|
||||
src/dbus/server/pim/testpim.py
|
||||
|
|
2
po/ar.po
2
po/ar.po
|
@ -6,7 +6,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: syncevolution\n"
|
||||
"Report-Msgid-Bugs-To: http://moblin.org/projects/syncevolution\n"
|
||||
"Report-Msgid-Bugs-To: https://syncevolution.org/\n"
|
||||
"POT-Creation-Date: 2009-10-16 11:24+0000\n"
|
||||
"PO-Revision-Date: 2009-11-16 16:28+0200\n"
|
||||
"Last-Translator: Yousef Abu Al Naser <yousef@itsoftex.com>\n"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: syncevolution.master\n"
|
||||
"Report-Msgid-Bugs-To: http://moblin.org/projects/syncevolution\n"
|
||||
"Report-Msgid-Bugs-To: https://syncevolution.org/\n"
|
||||
"POT-Creation-Date: 2010-05-22 09:19+0000\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: astur <malditoastur@gmail.com>\n"
|
||||
|
|
2
po/ca.po
2
po/ca.po
|
@ -7,7 +7,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Syncevolution 2.x\n"
|
||||
"Report-Msgid-Bugs-To: http://moblin.org/projects/syncevolution\n"
|
||||
"Report-Msgid-Bugs-To: https://syncevolution.org/\n"
|
||||
"POT-Creation-Date: 2009-08-15 09:21+0000\n"
|
||||
"PO-Revision-Date: 2010-01-02 14:18+0100\n"
|
||||
"Last-Translator: Gil Forcada <gilforcada@guifi.net>\n"
|
||||
|
|
2
po/da.po
2
po/da.po
|
@ -7,7 +7,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: syncevolution\n"
|
||||
"Report-Msgid-Bugs-To: http://moblin.org/projects/syncevolution\n"
|
||||
"Report-Msgid-Bugs-To: https://syncevolution.org/\n"
|
||||
"POT-Creation-Date: 2009-11-19 18:24+0000\n"
|
||||
"PO-Revision-Date: 2009-11-24 22:25+0100\n"
|
||||
"Last-Translator: Kris Thomsen <lakristho@gmail.com>\n"
|
||||
|
|
2
po/gl.po
2
po/gl.po
|
@ -6,7 +6,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: http://moblin.org/projects/syncevolution\n"
|
||||
"Report-Msgid-Bugs-To: https://syncevolution.org/\n"
|
||||
"POT-Creation-Date: 2009-10-01 19:27+0000\n"
|
||||
"PO-Revision-Date: 2009-10-14 21:52+0200\n"
|
||||
"Last-Translator: Xosé <xosecalvo@gmail.com>\n"
|
||||
|
|
2
po/hu.po
2
po/hu.po
|
@ -6,7 +6,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: syncevolution\n"
|
||||
"Report-Msgid-Bugs-To: http://moblin.org/projects/syncevolution\n"
|
||||
"Report-Msgid-Bugs-To: https://syncevolution.org/\n"
|
||||
"POT-Creation-Date: 2009-12-21 18:45+0000\n"
|
||||
"PO-Revision-Date: 2010-01-26 16:07+0100\n"
|
||||
"Last-Translator: Gergely Lónyai <aleph@mandriva.org>\n"
|
||||
|
|
2
po/id.po
2
po/id.po
|
@ -2,7 +2,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: syncevolution\n"
|
||||
"Report-Msgid-Bugs-To: http://moblin.org/projects/syncevolution\n"
|
||||
"Report-Msgid-Bugs-To: https://syncevolution.org/\n"
|
||||
"POT-Creation-Date: 2009-10-01 19:27+0000\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Andika Triwidada <andika@gmail.com>\n"
|
||||
|
|
2
po/ro.po
2
po/ro.po
|
@ -7,7 +7,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: syncevolution\n"
|
||||
"Report-Msgid-Bugs-To: http://moblin.org/projects/syncevolution\n"
|
||||
"Report-Msgid-Bugs-To: https://syncevolution.org/\n"
|
||||
"POT-Creation-Date: 2009-10-01 19:27+0000\n"
|
||||
"PO-Revision-Date: 2009-10-03 20:23+0200\n"
|
||||
"Last-Translator: Cosmin Bordeianu <elloxar@gmail.com>\n"
|
||||
|
|
2
po/sk.po
2
po/sk.po
|
@ -6,7 +6,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: syncevolution.master\n"
|
||||
"Report-Msgid-Bugs-To: http://moblin.org/projects/syncevolution\n"
|
||||
"Report-Msgid-Bugs-To: https://syncevolution.org/\n"
|
||||
"POT-Creation-Date: 2010-04-21 09:23+0000\n"
|
||||
"PO-Revision-Date: 2010-04-20 23:45+0200\n"
|
||||
"Last-Translator: Tomáš Virgl <tomas@virgl.net>\n"
|
||||
|
|
2
po/th.po
2
po/th.po
|
@ -6,7 +6,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: syncevolution\n"
|
||||
"Report-Msgid-Bugs-To: http://moblin.org/projects/syncevolution\n"
|
||||
"Report-Msgid-Bugs-To: https://syncevolution.org/\n"
|
||||
"POT-Creation-Date: 2009-12-21 18:45+0000\n"
|
||||
"PO-Revision-Date: 2010-01-19 22:07+0700\n"
|
||||
"Last-Translator: Anuchit Chalothorn <anoochit@gmail.com>\n"
|
||||
|
|
2
po/tr.po
2
po/tr.po
|
@ -6,7 +6,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: http://moblin.org/projects/syncevolution\n"
|
||||
"Report-Msgid-Bugs-To: https://syncevolution.org/\n"
|
||||
"POT-Creation-Date: 2010-05-19 09:19+0000\n"
|
||||
"PO-Revision-Date: 2010-05-19 10:57-0500\n"
|
||||
"Last-Translator: Ahmet Özgür Erdemli <dbl2010@gmail.com>\n"
|
||||
|
|
532
src/async.patch
532
src/async.patch
|
@ -1,532 +0,0 @@
|
|||
This patch demonstrates how switching from the current, synchronous
|
||||
to the corresponding asynchronous API could work. This helps to
|
||||
avoid some timeouts with EDS-DBus, but not all: the e_book_async_get_changes()
|
||||
call still times out.
|
||||
|
||||
Index: src/EvolutionContactSource.cpp
|
||||
===================================================================
|
||||
RCS file: /cvsroot/sync4jevolution/sync4jevolution/src/EvolutionContactSource.cpp,v
|
||||
retrieving revision 1.50
|
||||
diff -c -r1.50 EvolutionContactSource.cpp
|
||||
*** src/EvolutionContactSource.cpp 3 Jan 2007 20:58:41 -0000 1.50
|
||||
--- src/EvolutionContactSource.cpp 22 Feb 2007 19:27:50 -0000
|
||||
***************
|
||||
*** 27,32 ****
|
||||
--- 27,33 ----
|
||||
#ifdef ENABLE_EBOOK
|
||||
|
||||
#include "EvolutionContactSource.h"
|
||||
+ #include <libebook/e-book-view.h>
|
||||
|
||||
#include <common/base/Log.h>
|
||||
#include "vocl/VConverter.h"
|
||||
***************
|
||||
*** 154,159 ****
|
||||
--- 155,207 ----
|
||||
}
|
||||
}
|
||||
|
||||
+ void EvolutionContactSource::addContacts(void *custom, GList *nextItem)
|
||||
+ {
|
||||
+ EvolutionContactSource *source = (EvolutionContactSource *)custom;
|
||||
+
|
||||
+ while (nextItem) {
|
||||
+ const char *uid = (const char *)e_contact_get_const(E_CONTACT(nextItem->data),
|
||||
+ E_CONTACT_UID);
|
||||
+ source->m_allItems.addItem(uid);
|
||||
+ nextItem = nextItem->next;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ void EvolutionContactSource::addChanges(EBook *book,
|
||||
+ EBookStatus status,
|
||||
+ GList *nextItem,
|
||||
+ gpointer custom)
|
||||
+ {
|
||||
+ EvolutionContactSource *source = (EvolutionContactSource *)custom;
|
||||
+ source->m_status = status;
|
||||
+
|
||||
+ while (nextItem) {
|
||||
+ EBookChange *ebc = (EBookChange *)nextItem->data;
|
||||
+
|
||||
+ if (ebc->contact) {
|
||||
+ const char *uid = (const char *)e_contact_get_const( ebc->contact, E_CONTACT_UID );
|
||||
+
|
||||
+ if (uid) {
|
||||
+ switch (ebc->change_type) {
|
||||
+ case E_BOOK_CHANGE_CARD_ADDED:
|
||||
+ source->m_newItems.addItem(uid);
|
||||
+ break;
|
||||
+ case E_BOOK_CHANGE_CARD_MODIFIED:
|
||||
+ source->m_updatedItems.addItem(uid);
|
||||
+ break;
|
||||
+ case E_BOOK_CHANGE_CARD_DELETED:
|
||||
+ source->m_deletedItems.addItem(uid);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ nextItem = nextItem->next;
|
||||
+ }
|
||||
+
|
||||
+ source->m_loop.quit();
|
||||
+ }
|
||||
+
|
||||
+
|
||||
void EvolutionContactSource::beginSyncThrow(bool needAll,
|
||||
bool needPartial,
|
||||
bool deleteLocal)
|
||||
***************
|
||||
*** 161,234 ****
|
||||
GError *gerror = NULL;
|
||||
|
||||
if (deleteLocal) {
|
||||
! eptr<EBookQuery> allItemsQuery( e_book_query_any_field_contains(""), "query" );
|
||||
! GList *nextItem;
|
||||
! if (!e_book_get_contacts( m_addressbook, allItemsQuery, &nextItem, &gerror )) {
|
||||
! throwError( "reading all items", gerror );
|
||||
! }
|
||||
! while (nextItem) {
|
||||
! const char *uid = (const char *)e_contact_get_const(E_CONTACT(nextItem->data),
|
||||
! E_CONTACT_UID);
|
||||
! if (!e_book_remove_contact( m_addressbook, uid, &gerror ) ) {
|
||||
! throwError( string( "deleting contact " ) + uid,
|
||||
gerror );
|
||||
}
|
||||
- nextItem = nextItem->next;
|
||||
}
|
||||
}
|
||||
|
||||
if (needAll) {
|
||||
! eptr<EBookQuery> allItemsQuery( e_book_query_any_field_contains(""), "query" );
|
||||
! GList *nextItem;
|
||||
! if (!e_book_get_contacts( m_addressbook, allItemsQuery, &nextItem, &gerror )) {
|
||||
! throwError( "reading all items", gerror );
|
||||
! }
|
||||
! while (nextItem) {
|
||||
! const char *uid = (const char *)e_contact_get_const(E_CONTACT(nextItem->data),
|
||||
! E_CONTACT_UID);
|
||||
! m_allItems.addItem(uid);
|
||||
! nextItem = nextItem->next;
|
||||
! }
|
||||
}
|
||||
|
||||
if (needPartial) {
|
||||
GList *nextItem;
|
||||
if (!e_book_get_changes( m_addressbook, (char *)m_changeId.c_str(), &nextItem, &gerror )) {
|
||||
throwError( "reading changes", gerror );
|
||||
}
|
||||
! while (nextItem) {
|
||||
! EBookChange *ebc = (EBookChange *)nextItem->data;
|
||||
!
|
||||
! if (ebc->contact) {
|
||||
! const char *uid = (const char *)e_contact_get_const( ebc->contact, E_CONTACT_UID );
|
||||
!
|
||||
! if (uid) {
|
||||
! switch (ebc->change_type) {
|
||||
! case E_BOOK_CHANGE_CARD_ADDED:
|
||||
! m_newItems.addItem(uid);
|
||||
! break;
|
||||
! case E_BOOK_CHANGE_CARD_MODIFIED:
|
||||
! m_updatedItems.addItem(uid);
|
||||
! break;
|
||||
! case E_BOOK_CHANGE_CARD_DELETED:
|
||||
! m_deletedItems.addItem(uid);
|
||||
! break;
|
||||
! }
|
||||
! }
|
||||
! }
|
||||
! nextItem = nextItem->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EvolutionContactSource::endSyncThrow()
|
||||
{
|
||||
if (m_isModified) {
|
||||
- GError *gerror = NULL;
|
||||
- GList *nextItem;
|
||||
// move change_id forward so that our own changes are not listed the next time
|
||||
! if (!e_book_get_changes( m_addressbook, (char *)m_changeId.c_str(), &nextItem, &gerror )) {
|
||||
! throwError( "reading changes", gerror );
|
||||
}
|
||||
}
|
||||
resetItems();
|
||||
--- 209,264 ----
|
||||
GError *gerror = NULL;
|
||||
|
||||
if (deleteLocal) {
|
||||
! m_allItems.clear();
|
||||
! listAllContacts(addContacts, this);
|
||||
!
|
||||
! EvolutionSyncSource::itemList::const_iterator it;
|
||||
! for (it = m_allItems.begin();
|
||||
! it != m_allItems.end();
|
||||
! ++it) {
|
||||
! if (!e_book_remove_contact( m_addressbook, it->c_str(), &gerror ) ) {
|
||||
! throwError( string( "deleting contact " ) + *it,
|
||||
gerror );
|
||||
}
|
||||
}
|
||||
+ m_allItems.clear();
|
||||
}
|
||||
|
||||
if (needAll) {
|
||||
! listAllContacts(addContacts, this);
|
||||
}
|
||||
|
||||
if (needPartial) {
|
||||
+ #if 0
|
||||
+ // times out on N770
|
||||
+ GError *gerror = NULL;
|
||||
GList *nextItem;
|
||||
if (!e_book_get_changes( m_addressbook, (char *)m_changeId.c_str(), &nextItem, &gerror )) {
|
||||
throwError( "reading changes", gerror );
|
||||
}
|
||||
! addChanges(m_addressbook, E_BOOK_ERROR_OK, nextItem, (gpointer)this);
|
||||
! #else
|
||||
! if (e_book_async_get_changes(m_addressbook, (char *)m_changeId.c_str(), addChanges, this)) {
|
||||
! throwError( "reading changes", gerror );
|
||||
}
|
||||
+ m_loop.run();
|
||||
+ if (m_status != E_BOOK_ERROR_OK) {
|
||||
+ throw runtime_error("reading changes stopped with an error");
|
||||
+ }
|
||||
+ #endif
|
||||
}
|
||||
}
|
||||
|
||||
void EvolutionContactSource::endSyncThrow()
|
||||
{
|
||||
if (m_isModified) {
|
||||
// move change_id forward so that our own changes are not listed the next time
|
||||
! if (e_book_async_get_changes(m_addressbook, (char *)m_changeId.c_str(), addChanges, this)) {
|
||||
! throw runtime_error("reading changes");
|
||||
! }
|
||||
! m_loop.run();
|
||||
! if (m_status != E_BOOK_ERROR_OK) {
|
||||
! throw runtime_error("reading changes stopped with an error");
|
||||
}
|
||||
}
|
||||
resetItems();
|
||||
***************
|
||||
*** 241,263 ****
|
||||
m_addressbook = NULL;
|
||||
}
|
||||
|
||||
! void EvolutionContactSource::exportData(ostream &out)
|
||||
{
|
||||
! eptr<EBookQuery> allItemsQuery( e_book_query_any_field_contains(""), "query" );
|
||||
! GList *nextItem;
|
||||
! GError *gerror = NULL;
|
||||
! if (!e_book_get_contacts( m_addressbook, allItemsQuery, &nextItem, &gerror )) {
|
||||
! throwError( "reading all items", gerror );
|
||||
! }
|
||||
while (nextItem) {
|
||||
eptr<char> vcardstr(e_vcard_to_string(&E_CONTACT(nextItem->data)->parent,
|
||||
EVC_FORMAT_VCARD_30));
|
||||
|
||||
! out << (const char *)vcardstr << "\r\n\r\n";
|
||||
nextItem = nextItem->next;
|
||||
}
|
||||
}
|
||||
|
||||
SyncItem *EvolutionContactSource::createItem( const string &uid, SyncState state )
|
||||
{
|
||||
logItem( uid, "extracting from EV" );
|
||||
--- 271,296 ----
|
||||
m_addressbook = NULL;
|
||||
}
|
||||
|
||||
!
|
||||
! static void dumpContacts(void *custom, GList *nextItem)
|
||||
{
|
||||
! ostream *out = (ostream *)custom;
|
||||
!
|
||||
while (nextItem) {
|
||||
eptr<char> vcardstr(e_vcard_to_string(&E_CONTACT(nextItem->data)->parent,
|
||||
EVC_FORMAT_VCARD_30));
|
||||
|
||||
! *out << (const char *)vcardstr << "\r\n\r\n";
|
||||
!
|
||||
nextItem = nextItem->next;
|
||||
}
|
||||
}
|
||||
|
||||
+ void EvolutionContactSource::exportData(ostream &out)
|
||||
+ {
|
||||
+ listAllContacts(dumpContacts, (void *)&out);
|
||||
+ }
|
||||
+
|
||||
SyncItem *EvolutionContactSource::createItem( const string &uid, SyncState state )
|
||||
{
|
||||
logItem( uid, "extracting from EV" );
|
||||
***************
|
||||
*** 773,776 ****
|
||||
--- 806,876 ----
|
||||
}
|
||||
}
|
||||
|
||||
+ class EvolutionContactListAll {
|
||||
+ public:
|
||||
+ EvolutionContactListAll(void (*processList)(void *custom, GList *list), void *custom, EvolutionContactSource &source):
|
||||
+ m_processList(processList),
|
||||
+ m_custom(custom),
|
||||
+ m_source(source),
|
||||
+ m_status(E_BOOK_VIEW_STATUS_OK)
|
||||
+ {}
|
||||
+
|
||||
+ static void contactsAdded(EBookView *ebookview,
|
||||
+ gpointer arg1,
|
||||
+ gpointer user_data) {
|
||||
+ EvolutionContactListAll *listAll = (EvolutionContactListAll *)user_data;
|
||||
+ listAll->m_processList(listAll->m_custom, (GList *)arg1);
|
||||
+ }
|
||||
+
|
||||
+ static void sequenceDone(EBookView *ebookview,
|
||||
+ gint arg1,
|
||||
+ gpointer user_data) {
|
||||
+ EvolutionContactListAll *listAll = (EvolutionContactListAll *)user_data;
|
||||
+ listAll->m_status = (EBookViewStatus)arg1;
|
||||
+ listAll->m_source.m_loop.quit();
|
||||
+ }
|
||||
+
|
||||
+ /** throw an error exception if an error occurred */
|
||||
+ void checkStatus() {
|
||||
+ if (m_status != E_BOOK_VIEW_STATUS_OK) {
|
||||
+ throw runtime_error("iterating over all contacts failed");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private:
|
||||
+ void (*m_processList)(void *custom, GList *list);
|
||||
+ void *m_custom;
|
||||
+ EvolutionContactSource &m_source;
|
||||
+ EBookViewStatus m_status;
|
||||
+ };
|
||||
+
|
||||
+
|
||||
+
|
||||
+
|
||||
+
|
||||
+ void EvolutionContactSource::listAllContacts(void (*processList)(void *custom, GList *list), void *custom)
|
||||
+ {
|
||||
+ eptr<EBookQuery> allItemsQuery( e_book_query_any_field_contains(""), "query" );
|
||||
+ GError *gerror = NULL;
|
||||
+ EBookView *viewptr;
|
||||
+
|
||||
+ if (e_book_get_book_view(m_addressbook, allItemsQuery, NULL, -1, &viewptr, &gerror)) {
|
||||
+ eptr<EBookView, GObject> view(viewptr);
|
||||
+ EvolutionContactListAll listAll(processList, custom, *this);
|
||||
+
|
||||
+ g_signal_connect(viewptr, "contacts-added", G_CALLBACK(listAll.contactsAdded), &listAll);
|
||||
+ g_signal_connect(viewptr, "sequence-complete", G_CALLBACK(listAll.sequenceDone), &listAll);
|
||||
+ e_book_view_start(view);
|
||||
+ m_loop.run();
|
||||
+ e_book_view_stop(view);
|
||||
+ // workaround for http://bugzilla.gnome.org/show_bug.cgi?id=399011
|
||||
+ // Without the sleep() EDS often (but not always) crashes in e_book_backend_get_book_views()
|
||||
+ // during one of the following calls.
|
||||
+ sleep(1);
|
||||
+ listAll.checkStatus();
|
||||
+ } else {
|
||||
+ throwError( "getting view on addressbook", gerror );
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
#endif /* ENABLE_EBOOK */
|
||||
Index: src/EvolutionContactSource.h
|
||||
===================================================================
|
||||
RCS file: /cvsroot/sync4jevolution/sync4jevolution/src/EvolutionContactSource.h,v
|
||||
retrieving revision 1.22
|
||||
diff -c -r1.22 EvolutionContactSource.h
|
||||
*** src/EvolutionContactSource.h 10 Dec 2006 17:35:18 -0000 1.22
|
||||
--- src/EvolutionContactSource.h 22 Feb 2007 19:27:50 -0000
|
||||
***************
|
||||
*** 32,37 ****
|
||||
--- 32,49 ----
|
||||
#include <set>
|
||||
|
||||
/**
|
||||
+ * callback used by EvolutionContactSource::listAll() and
|
||||
+ */
|
||||
+ class EvolutionCallback
|
||||
+ {
|
||||
+ public:
|
||||
+ /**
|
||||
+ * Called to iterate over data. Content of list depends on context.
|
||||
+ */
|
||||
+ virtual void processList(GList *list) = 0;
|
||||
+ };
|
||||
+
|
||||
+ /**
|
||||
* Implements access to Evolution address books.
|
||||
*/
|
||||
class EvolutionContactSource : public EvolutionSyncSource
|
||||
***************
|
||||
*** 81,87 ****
|
||||
// implementation of SyncSource
|
||||
//
|
||||
virtual ArrayElement *clone() { return new EvolutionContactSource(*this); }
|
||||
!
|
||||
protected:
|
||||
//
|
||||
// implementation of EvolutionSyncSource callbacks
|
||||
--- 93,102 ----
|
||||
// implementation of SyncSource
|
||||
//
|
||||
virtual ArrayElement *clone() { return new EvolutionContactSource(*this); }
|
||||
!
|
||||
! /** start and stop event processing on this source */
|
||||
! EvolutionAsync m_loop;
|
||||
!
|
||||
protected:
|
||||
//
|
||||
// implementation of EvolutionSyncSource callbacks
|
||||
***************
|
||||
*** 142,149 ****
|
||||
--- 157,191 ----
|
||||
insert("CALURI");
|
||||
}
|
||||
} m_uniqueProperties;
|
||||
+
|
||||
+ /**
|
||||
+ * extracts all contacts
|
||||
+ *
|
||||
+ * @param processList is fed the contacts, possibly in multiple chunks
|
||||
+ * @param custom pointer passed through to processList
|
||||
+ */
|
||||
+ void listAllContacts(void (*processList)(void *custom, GList *list), void *custom);
|
||||
+
|
||||
+ /**
|
||||
+ * callback for listAllContacts() which adds all contacts to m_allItems
|
||||
+ */
|
||||
+ static void addContacts(void *custom, GList *nextItem);
|
||||
+
|
||||
+ /**
|
||||
+ * EBookListCallback for beginSyncThrow()'s e_book_async_get_changes ()
|
||||
+ */
|
||||
+ static void addChanges(EBook *book,
|
||||
+ EBookStatus status,
|
||||
+ GList *nextItem,
|
||||
+ gpointer custom);
|
||||
+ /**
|
||||
+ * status passed to addChanges()
|
||||
+ */
|
||||
+ EBookStatus m_status;
|
||||
};
|
||||
|
||||
+
|
||||
+
|
||||
#endif // ENABLE_EBOOK
|
||||
|
||||
#endif // INCL_EVOLUTIONCONTACTSOURCE
|
||||
Index: src/EvolutionSmartPtr.h
|
||||
===================================================================
|
||||
RCS file: /cvsroot/sync4jevolution/sync4jevolution/src/EvolutionSmartPtr.h,v
|
||||
retrieving revision 1.8
|
||||
diff -c -r1.8 EvolutionSmartPtr.h
|
||||
*** src/EvolutionSmartPtr.h 10 Dec 2006 17:35:19 -0000 1.8
|
||||
--- src/EvolutionSmartPtr.h 22 Feb 2007 19:27:50 -0000
|
||||
***************
|
||||
*** 34,39 ****
|
||||
--- 34,40 ----
|
||||
|
||||
void inline unref( char *pointer ) { free( pointer ); }
|
||||
void inline unref( GObject *pointer ) { g_object_unref( pointer ); }
|
||||
+ void inline unref( GMainLoop *pointer ) { g_main_loop_unref( pointer ); }
|
||||
#ifdef ENABLE_EBOOK
|
||||
void inline unref( EBookQuery *pointer ) { e_book_query_unref( pointer ); }
|
||||
#endif
|
||||
Index: src/EvolutionSyncClient.cpp
|
||||
===================================================================
|
||||
RCS file: /cvsroot/sync4jevolution/sync4jevolution/src/EvolutionSyncClient.cpp,v
|
||||
retrieving revision 1.24
|
||||
diff -c -r1.24 EvolutionSyncClient.cpp
|
||||
*** src/EvolutionSyncClient.cpp 17 Dec 2006 16:33:45 -0000 1.24
|
||||
--- src/EvolutionSyncClient.cpp 22 Feb 2007 19:27:50 -0000
|
||||
***************
|
||||
*** 432,438 ****
|
||||
int res = DMTClientConfig::readDevInfoConfig(syncMLNode, syncMLNode);
|
||||
|
||||
// always read device ID from the traditional property "deviceId"
|
||||
! eptr<char> tmp(syncMLNode.readPropertyValue("deviceId"));
|
||||
deviceConfig.setDevID(tmp);
|
||||
|
||||
return res;
|
||||
--- 432,438 ----
|
||||
int res = DMTClientConfig::readDevInfoConfig(syncMLNode, syncMLNode);
|
||||
|
||||
// always read device ID from the traditional property "deviceId"
|
||||
! arrayptr<char> tmp(syncMLNode.readPropertyValue("deviceId"));
|
||||
deviceConfig.setDevID(tmp);
|
||||
|
||||
return res;
|
||||
***************
|
||||
*** 482,489 ****
|
||||
// redirect logging as soon as possible
|
||||
SourceList sourceList(m_server, m_doLogging);
|
||||
|
||||
! eptr<char> logdir(config.getSyncMLNode()->readPropertyValue("logdir"));
|
||||
! eptr<char> maxlogdirs(config.getSyncMLNode()->readPropertyValue("maxlogdirs"));
|
||||
sourceList.setLogdir(logdir, atoi(maxlogdirs));
|
||||
|
||||
SyncSourceConfig *sourceconfigs = config.getSyncSourceConfigs();
|
||||
--- 482,489 ----
|
||||
// redirect logging as soon as possible
|
||||
SourceList sourceList(m_server, m_doLogging);
|
||||
|
||||
! arrayptr<char> logdir(config.getSyncMLNode()->readPropertyValue("logdir"));
|
||||
! arrayptr<char> maxlogdirs(config.getSyncMLNode()->readPropertyValue("maxlogdirs"));
|
||||
sourceList.setLogdir(logdir, atoi(maxlogdirs));
|
||||
|
||||
SyncSourceConfig *sourceconfigs = config.getSyncSourceConfigs();
|
||||
Index: src/EvolutionSyncSource.h
|
||||
===================================================================
|
||||
RCS file: /cvsroot/sync4jevolution/sync4jevolution/src/EvolutionSyncSource.h,v
|
||||
retrieving revision 1.24
|
||||
diff -c -r1.24 EvolutionSyncSource.h
|
||||
*** src/EvolutionSyncSource.h 10 Dec 2006 17:35:19 -0000 1.24
|
||||
--- src/EvolutionSyncSource.h 22 Feb 2007 19:27:51 -0000
|
||||
***************
|
||||
*** 33,38 ****
|
||||
--- 33,40 ----
|
||||
#include <spdm/ManagementNode.h>
|
||||
#include <base/Log.h>
|
||||
|
||||
+ #include <EvolutionSmartPtr.h>
|
||||
+
|
||||
/**
|
||||
* This class implements the functionality shared by
|
||||
* both EvolutionCalenderSource and EvolutionContactSource:
|
||||
***************
|
||||
*** 371,374 ****
|
||||
--- 373,400 ----
|
||||
string m_user, m_passwd;
|
||||
};
|
||||
|
||||
+ /**
|
||||
+ * Utility class which hides the mechanisms needed to handle events
|
||||
+ * during asynchronous calls.
|
||||
+ */
|
||||
+ class EvolutionAsync {
|
||||
+ public:
|
||||
+ EvolutionAsync() :
|
||||
+ m_loop(g_main_loop_new(NULL, FALSE), "main loop")
|
||||
+ {}
|
||||
+
|
||||
+ /** start processing events */
|
||||
+ void run() {
|
||||
+ g_main_loop_run(m_loop);
|
||||
+ }
|
||||
+
|
||||
+ /** stop processing events, to be called inside run() by callback */
|
||||
+ void quit() {
|
||||
+ g_main_loop_quit(m_loop);
|
||||
+ }
|
||||
+
|
||||
+ private:
|
||||
+ eptr<GMainLoop> m_loop;
|
||||
+ };
|
||||
+
|
||||
#endif // INCL_EVOLUTIONSYNCSOURCE
|
|
@ -58,7 +58,7 @@ void ActiveSyncCalendarSource::beginSync(const std::string &lastToken, const std
|
|||
// re-populate cache from storage, without any item data
|
||||
ConfigProps props;
|
||||
m_trackingNode->readProperties(props);
|
||||
BOOST_FOREACH(const StringPair &prop, props) {
|
||||
for (const auto &prop: props) {
|
||||
const std::string &easid = prop.first;
|
||||
const std::string &value = prop.second;
|
||||
size_t pos = value.find('/');
|
||||
|
@ -70,9 +70,9 @@ void ActiveSyncCalendarSource::beginSync(const std::string &lastToken, const std
|
|||
size_t nextpos = value.find('/', pos + 1);
|
||||
if (nextpos != value.npos) {
|
||||
std::string uid = m_escape.unescape(value.substr(pos + 1, nextpos - pos - 1));
|
||||
boost::shared_ptr<Event> &eventptr = m_cache[easid];
|
||||
std::shared_ptr<Event> &eventptr = m_cache[easid];
|
||||
if (!eventptr) {
|
||||
eventptr = boost::shared_ptr<Event>(new Event);
|
||||
eventptr = std::make_shared<Event>();
|
||||
}
|
||||
eventptr->m_easid = easid;
|
||||
eventptr->m_uid = uid;
|
||||
|
@ -104,7 +104,7 @@ void ActiveSyncCalendarSource::beginSync(const std::string &lastToken, const std
|
|||
for (bool firstIteration = true;
|
||||
moreAvailable;
|
||||
firstIteration = false) {
|
||||
gchar *buffer = NULL;
|
||||
gchar *buffer = nullptr;
|
||||
GErrorCXX gerror;
|
||||
EASItemsCXX created, updated;
|
||||
EASIdsCXX deleted;
|
||||
|
@ -142,7 +142,7 @@ void ActiveSyncCalendarSource::beginSync(const std::string &lastToken, const std
|
|||
|
||||
|
||||
// populate ID lists and content cache
|
||||
BOOST_FOREACH(EasItemInfo *item, created) {
|
||||
for (EasItemInfo *item: created) {
|
||||
if (!item->server_id) {
|
||||
throwError(SE_HERE, "no server ID for new eas item");
|
||||
}
|
||||
|
@ -155,13 +155,13 @@ void ActiveSyncCalendarSource::beginSync(const std::string &lastToken, const std
|
|||
throwError(SE_HERE, StringPrintf("no body returned for new eas item %s", easid.c_str()));
|
||||
}
|
||||
Event &event = setItemData(easid, item->data);
|
||||
BOOST_FOREACH(const std::string &subid, event.m_subids) {
|
||||
for (const std::string &subid: event.m_subids) {
|
||||
SE_LOG_DEBUG(getDisplayName(), "new eas item %s = uid %s + rid %s",
|
||||
easid.c_str(), event.m_uid.c_str(), subid.c_str());
|
||||
addItem(createLUID(easid, subid), NEW);
|
||||
}
|
||||
}
|
||||
BOOST_FOREACH(EasItemInfo *item, updated) {
|
||||
for (EasItemInfo *item: updated) {
|
||||
if (!item->server_id) {
|
||||
throwError(SE_HERE, "no server ID for updated eas item");
|
||||
}
|
||||
|
@ -174,13 +174,13 @@ void ActiveSyncCalendarSource::beginSync(const std::string &lastToken, const std
|
|||
throwError(SE_HERE, StringPrintf("no body returned for updated eas item %s", easid.c_str()));
|
||||
}
|
||||
Event &event = setItemData(easid, item->data);
|
||||
BOOST_FOREACH(const std::string &subid, event.m_subids) {
|
||||
for (const std::string &subid: event.m_subids) {
|
||||
SE_LOG_DEBUG(getDisplayName(), "deleted eas item %s = uid %s + rid %s",
|
||||
easid.c_str(), event.m_uid.c_str(), subid.c_str());
|
||||
addItem(createLUID(easid, subid), UPDATED);
|
||||
}
|
||||
}
|
||||
BOOST_FOREACH(const char *serverID, deleted) {
|
||||
for (const char *serverID: deleted) {
|
||||
if (!serverID) {
|
||||
throwError(SE_HERE, "no server ID for deleted eas item");
|
||||
}
|
||||
|
@ -192,7 +192,7 @@ void ActiveSyncCalendarSource::beginSync(const std::string &lastToken, const std
|
|||
if (event.m_subids.empty()) {
|
||||
SE_LOG_DEBUG(getDisplayName(), "deleted eas item %s empty?!", easid.c_str());
|
||||
} else {
|
||||
BOOST_FOREACH(const std::string &subid, event.m_subids) {
|
||||
for (const std::string &subid: event.m_subids) {
|
||||
SE_LOG_DEBUG(getDisplayName(), "deleted eas item %s = uid %s + rid %s",
|
||||
easid.c_str(), event.m_uid.c_str(), subid.c_str());
|
||||
addItem(createLUID(easid, subid), DELETED);
|
||||
|
@ -218,10 +218,10 @@ void ActiveSyncCalendarSource::beginSync(const std::string &lastToken, const std
|
|||
|
||||
// now also generate full list of all current items:
|
||||
// old items + new (added to m_events above) - deleted (removed above)
|
||||
BOOST_FOREACH(const EventCache::value_type &entry, m_cache) {
|
||||
for (const auto &entry: m_cache) {
|
||||
const std::string &easid = entry.first;
|
||||
const boost::shared_ptr<Event> &eventptr = entry.second;
|
||||
BOOST_FOREACH(const std::string &subid, eventptr->m_subids) {
|
||||
const std::shared_ptr<Event> &eventptr = entry.second;
|
||||
for (const std::string &subid: eventptr->m_subids) {
|
||||
SE_LOG_DEBUG(getDisplayName(), "existing eas item %s = uid %s + rid %s",
|
||||
easid.c_str(), eventptr->m_uid.c_str(), subid.c_str());
|
||||
addItem(createLUID(easid, subid), ANY);
|
||||
|
@ -233,13 +233,13 @@ std::string ActiveSyncCalendarSource::endSync(bool success)
|
|||
{
|
||||
m_trackingNode->clear();
|
||||
if (success) {
|
||||
BOOST_FOREACH(const EventCache::value_type &entry, m_cache) {
|
||||
for (const auto &entry: m_cache) {
|
||||
const std::string &easid = entry.first;
|
||||
const boost::shared_ptr<Event> &eventptr = entry.second;
|
||||
const std::shared_ptr<Event> &eventptr = entry.second;
|
||||
std::stringstream buffer;
|
||||
buffer << "//"; // use same format as in MapSyncSource, just in case - was '/' << m_escape.escape(ids.m_revision) << '/';
|
||||
buffer << m_escape.escape(eventptr->m_uid) << '/';
|
||||
BOOST_FOREACH(const std::string &subid, eventptr->m_subids) {
|
||||
for (const std::string &subid: eventptr->m_subids) {
|
||||
buffer << m_escape.escape(subid) << '/';
|
||||
}
|
||||
m_trackingNode->setProperty(easid, buffer.str());
|
||||
|
@ -298,7 +298,7 @@ std::string ActiveSyncCalendarSource::getDescription(const string &luid)
|
|||
|
||||
ActiveSyncCalendarSource::Event &ActiveSyncCalendarSource::findItem(const std::string &easid)
|
||||
{
|
||||
EventCache::iterator it = m_cache.find(easid);
|
||||
auto it = m_cache.find(easid);
|
||||
if (it == m_cache.end()) {
|
||||
throwError(SE_HERE, STATUS_NOT_FOUND, "merged event not found: " + easid);
|
||||
}
|
||||
|
@ -324,12 +324,12 @@ ActiveSyncCalendarSource::Event &ActiveSyncCalendarSource::loadItem(Event &event
|
|||
|
||||
ActiveSyncCalendarSource::Event &ActiveSyncCalendarSource::setItemData(const std::string &easid, const std::string &data)
|
||||
{
|
||||
boost::shared_ptr<Event> &eventptr = m_cache[easid];
|
||||
std::shared_ptr<Event> &eventptr = m_cache[easid];
|
||||
if (eventptr) {
|
||||
eventptr->m_uid.clear();
|
||||
eventptr->m_subids.clear();
|
||||
} else {
|
||||
eventptr = boost::shared_ptr<Event>(new Event);
|
||||
eventptr = std::make_shared<Event>();
|
||||
}
|
||||
|
||||
Event &event = *eventptr;
|
||||
|
@ -408,10 +408,10 @@ SyncSourceRaw::InsertItemResult ActiveSyncCalendarSource::insertItem(const std::
|
|||
const std::string &callerSubID = ids.second;
|
||||
|
||||
// parse new event
|
||||
boost::shared_ptr<Event> newEvent(new Event);
|
||||
auto newEvent = std::make_shared<Event>();
|
||||
newEvent->m_calendar.set(icalcomponent_new_from_string((char *)item.c_str()), // hack for old libical
|
||||
"parsing iCalendar 2.0");
|
||||
icalcomponent *firstcomp = NULL;
|
||||
icalcomponent *firstcomp = nullptr;
|
||||
for (icalcomponent *comp = firstcomp = icalcomponent_get_first_component(newEvent->m_calendar, ICAL_VEVENT_COMPONENT);
|
||||
comp;
|
||||
comp = icalcomponent_get_next_component(newEvent->m_calendar, ICAL_VEVENT_COMPONENT)) {
|
||||
|
@ -444,7 +444,7 @@ SyncSourceRaw::InsertItemResult ActiveSyncCalendarSource::insertItem(const std::
|
|||
// our caller didn't.
|
||||
std::string knownSubID = callerSubID;
|
||||
if (easid.empty()) {
|
||||
EventCache::iterator it = m_cache.findByUID(newEvent->m_uid);
|
||||
auto it = m_cache.findByUID(newEvent->m_uid);
|
||||
if (it != m_cache.end()) {
|
||||
easid = it->first;
|
||||
knownSubID = subid;
|
||||
|
@ -458,7 +458,7 @@ SyncSourceRaw::InsertItemResult ActiveSyncCalendarSource::insertItem(const std::
|
|||
InsertItemResult res = ActiveSyncSource::insertItem("", item);
|
||||
easid = res.m_luid;
|
||||
|
||||
EventCache::iterator it = m_cache.find(res.m_luid);
|
||||
auto it = m_cache.find(res.m_luid);
|
||||
if (it != m_cache.end()) {
|
||||
// merge into existing Event
|
||||
Event &event = loadItem(*it->second);
|
||||
|
@ -499,7 +499,7 @@ SyncSourceRaw::InsertItemResult ActiveSyncCalendarSource::insertItem(const std::
|
|||
// the parent event or (if not found) the current event
|
||||
eptr<icalproperty> rid(icalproperty_new_recurrenceid(icaltime_from_string(knownSubID.c_str())),
|
||||
"new rid");
|
||||
icalproperty *dtstart = NULL;
|
||||
icalproperty *dtstart = nullptr;
|
||||
icalcomponent *comp;
|
||||
// look for parent first
|
||||
for (comp = icalcomponent_get_first_component(event.m_calendar, ICAL_VEVENT_COMPONENT);
|
||||
|
@ -541,7 +541,7 @@ SyncSourceRaw::InsertItemResult ActiveSyncCalendarSource::insertItem(const std::
|
|||
loadItem(event);
|
||||
|
||||
// update cache: find old VEVENT and remove it before adding new one
|
||||
icalcomponent *removeme = NULL;
|
||||
icalcomponent *removeme = nullptr;
|
||||
for (icalcomponent *comp = icalcomponent_get_first_component(event.m_calendar, ICAL_VEVENT_COMPONENT);
|
||||
comp;
|
||||
comp = icalcomponent_get_next_component(event.m_calendar, ICAL_VEVENT_COMPONENT)) {
|
||||
|
@ -653,7 +653,7 @@ void ActiveSyncCalendarSource::deleteItem(const string &luid)
|
|||
throwError(SE_HERE, STATUS_NOT_FOUND, "sub event not found: " + subid + " in " + easid);
|
||||
} else {
|
||||
event.m_subids.clear();
|
||||
event.m_calendar = NULL;
|
||||
event.m_calendar = nullptr;
|
||||
ActiveSyncSource::deleteItem(ids.first);
|
||||
}
|
||||
m_cache.erase(easid);
|
||||
|
@ -689,7 +689,7 @@ void ActiveSyncCalendarSource::deleteItem(const string &luid)
|
|||
|
||||
void ActiveSyncCalendarSource::removeAllItems()
|
||||
{
|
||||
BOOST_FOREACH(const EventCache::value_type &entry, m_cache) {
|
||||
for (const auto &entry: m_cache) {
|
||||
ActiveSyncSource::deleteItem(entry.first);
|
||||
}
|
||||
m_cache.clear();
|
||||
|
|
|
@ -29,8 +29,7 @@
|
|||
#include <syncevo/eds_abi_wrapper.h>
|
||||
#include <syncevo/SmartPtr.h>
|
||||
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <memory>
|
||||
|
||||
#include <syncevo/declarations.h>
|
||||
SE_BEGIN_CXX
|
||||
|
@ -100,7 +99,7 @@ class ActiveSyncCalendarSource : public ActiveSyncCalFormatSource
|
|||
/**
|
||||
* parsed VCALENDAR component representing the current
|
||||
* state of the item as it exists on the WebDAV server,
|
||||
* must be kept up-to-date as we make changes, may be NULL
|
||||
* must be kept up-to-date as we make changes, may be nullptr
|
||||
*/
|
||||
eptr<icalcomponent> m_calendar;
|
||||
|
||||
|
@ -119,7 +118,7 @@ class ActiveSyncCalendarSource : public ActiveSyncCalFormatSource
|
|||
* A cache of information about each merged item. Maps from
|
||||
* easid to Event.
|
||||
*/
|
||||
class EventCache : public std::map<std::string, boost::shared_ptr<Event> >
|
||||
class EventCache : public std::map<std::string, std::shared_ptr<Event> >
|
||||
{
|
||||
public:
|
||||
EventCache() : m_initialized(false) {}
|
||||
|
@ -141,7 +140,7 @@ class ActiveSyncCalendarSource : public ActiveSyncCalFormatSource
|
|||
* On-disk representation of m_cache (without the item data).
|
||||
* Format same as in MapSyncSource (code copied, refactor!).
|
||||
*/
|
||||
boost::shared_ptr<ConfigNode> m_trackingNode;
|
||||
std::shared_ptr<ConfigNode> m_trackingNode;
|
||||
};
|
||||
|
||||
SE_END_CXX
|
||||
|
|
|
@ -88,13 +88,13 @@ void ActiveSyncSource::findCollections(const std::string &account, const bool fo
|
|||
if (!eas_sync_handler_get_folder_list (handler,
|
||||
force_update,
|
||||
folders,
|
||||
NULL,
|
||||
nullptr,
|
||||
gerror)) {
|
||||
gerror.throwError(SE_HERE, "fetching folder list");
|
||||
}
|
||||
|
||||
/* Save the Collections */
|
||||
BOOST_FOREACH(EasFolder *folder, folders) {
|
||||
for (EasFolder *folder: folders) {
|
||||
m_collections[folder->folder_id].collectionId = folder->folder_id;
|
||||
m_collections[folder->folder_id].name = folder->display_name;
|
||||
m_collections[folder->folder_id].parentId = folder->parent_id;
|
||||
|
@ -103,7 +103,7 @@ void ActiveSyncSource::findCollections(const std::string &account, const bool fo
|
|||
}
|
||||
|
||||
/* Save the full paths */
|
||||
BOOST_FOREACH(std::string id, m_collections | boost::adaptors::map_keys) {
|
||||
for (std::string id: m_collections | boost::adaptors::map_keys) {
|
||||
m_folderPaths[m_collections[id].fullPath()] = id;
|
||||
}
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ ActiveSyncSource::Databases ActiveSyncSource::getDatabases()
|
|||
|
||||
findCollections(account, true);
|
||||
|
||||
BOOST_FOREACH(Collection coll, m_collections | boost::adaptors::map_values) {
|
||||
for (Collection coll: m_collections | boost::adaptors::map_values) {
|
||||
if (coll.getFolderType() == getEasType()) {
|
||||
result.push_back(Database(coll.pathName, coll.collectionId, coll.collectionIsDefault()));
|
||||
}
|
||||
|
@ -192,7 +192,7 @@ std::string ActiveSyncSource::lookupFolder(const std::string &folder) {
|
|||
}
|
||||
|
||||
// Lookup folder name
|
||||
FolderPaths::const_iterator entry = m_folderPaths.find(key);
|
||||
auto entry = m_folderPaths.find(key);
|
||||
if (entry != m_folderPaths.end()) {
|
||||
return entry->second;
|
||||
}
|
||||
|
@ -242,7 +242,7 @@ void ActiveSyncSource::open()
|
|||
void ActiveSyncSource::close()
|
||||
{
|
||||
// free handler if not done already
|
||||
m_handler.set(NULL);
|
||||
m_handler.set(nullptr);
|
||||
}
|
||||
|
||||
void ActiveSyncSource::beginSync(const std::string &lastToken, const std::string &resumeToken)
|
||||
|
@ -278,7 +278,7 @@ void ActiveSyncSource::beginSync(const std::string &lastToken, const std::string
|
|||
for (bool firstIteration = true;
|
||||
moreAvailable;
|
||||
firstIteration = false) {
|
||||
gchar *buffer = NULL;
|
||||
gchar *buffer = nullptr;
|
||||
GErrorCXX gerror;
|
||||
EASItemsCXX created, updated;
|
||||
EASIdsCXX deleted;
|
||||
|
@ -315,7 +315,7 @@ void ActiveSyncSource::beginSync(const std::string &lastToken, const std::string
|
|||
// will ask us for older, unmodified item content which we won't have.
|
||||
|
||||
// populate ID lists and content cache
|
||||
BOOST_FOREACH(EasItemInfo *item, created) {
|
||||
for (EasItemInfo *item: created) {
|
||||
if (!item->server_id) {
|
||||
throwError(SE_HERE, "no server ID for new eas item");
|
||||
}
|
||||
|
@ -331,7 +331,7 @@ void ActiveSyncSource::beginSync(const std::string &lastToken, const std::string
|
|||
}
|
||||
m_items[luid] = item->data;
|
||||
}
|
||||
BOOST_FOREACH(EasItemInfo *item, updated) {
|
||||
for (EasItemInfo *item: updated) {
|
||||
if (!item->server_id) {
|
||||
throwError(SE_HERE, "no server ID for updated eas item");
|
||||
}
|
||||
|
@ -347,7 +347,7 @@ void ActiveSyncSource::beginSync(const std::string &lastToken, const std::string
|
|||
}
|
||||
m_items[luid] = item->data;
|
||||
}
|
||||
BOOST_FOREACH(const char *serverID, deleted) {
|
||||
for (const char *serverID: deleted) {
|
||||
if (!serverID) {
|
||||
throwError(SE_HERE, "no server ID for deleted eas item");
|
||||
}
|
||||
|
@ -379,7 +379,7 @@ void ActiveSyncSource::beginSync(const std::string &lastToken, const std::string
|
|||
// old items + new (added to m_ids above) - deleted (removed above)
|
||||
ConfigProps props;
|
||||
m_ids->readProperties(props);
|
||||
BOOST_FOREACH(const StringPair &entry, props) {
|
||||
for (const auto &entry: props) {
|
||||
const std::string &luid = entry.first;
|
||||
SE_LOG_DEBUG(getDisplayName(), "existing item %s", luid.c_str());
|
||||
addItem(luid, ANY);
|
||||
|
@ -523,7 +523,7 @@ SyncSourceSerialize::InsertItemResult ActiveSyncSource::insertItem(const std::st
|
|||
void ActiveSyncSource::readItem(const std::string &luid, std::string &item)
|
||||
{
|
||||
// return straight from cache?
|
||||
std::map<std::string, std::string>::iterator it = m_items.find(luid);
|
||||
auto it = m_items.find(luid);
|
||||
if (it == m_items.end()) {
|
||||
// no, must fetch
|
||||
EASItemPtr tmp(eas_item_info_new(), "EasItem");
|
||||
|
|
|
@ -31,8 +31,6 @@
|
|||
#include <syncevo/SmartPtr.h>
|
||||
#include <syncevo/GLibSupport.h>
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
|
@ -135,7 +133,7 @@ class ActiveSyncSource :
|
|||
// that we use a common prefix, so that we can use the key/value store
|
||||
// also for other keys if the need ever arises).
|
||||
m_itemNode(new PrefixConfigNode("item-",
|
||||
boost::shared_ptr<ConfigNode>(new SafeConfigNode(params.m_nodes.getTrackingNode())))),
|
||||
std::static_pointer_cast<ConfigNode>(std::make_shared<SafeConfigNode>(params.m_nodes.getTrackingNode())))),
|
||||
m_context(params.m_context)
|
||||
{
|
||||
if (!m_context) {
|
||||
|
@ -143,7 +141,7 @@ class ActiveSyncSource :
|
|||
}
|
||||
}
|
||||
|
||||
/** sync config used by this instance, never NULL */
|
||||
/** sync config used by this instance, never nullptr */
|
||||
SyncConfig &getSyncConfig() { return *m_context; }
|
||||
|
||||
/* partial implementation of SyncSource */
|
||||
|
@ -183,11 +181,11 @@ class ActiveSyncSource :
|
|||
void findCollections(const std::string &account, bool force_update);
|
||||
std::string lookupFolder(const std::string &folder);
|
||||
|
||||
boost::shared_ptr<ConfigNode> m_itemNode;
|
||||
std::shared_ptr<ConfigNode> m_itemNode;
|
||||
|
||||
private:
|
||||
/** "target-config@<context>" instance which holds our username == ActiveSync account ID */
|
||||
boost::shared_ptr<SyncConfig> m_context;
|
||||
std::shared_ptr<SyncConfig> m_context;
|
||||
|
||||
/** account ID for libeas, must be set in "username" config property */
|
||||
std::string m_account;
|
||||
|
@ -206,9 +204,9 @@ class ActiveSyncSource :
|
|||
|
||||
/**
|
||||
* server-side IDs of all items, updated as changes are reported and/or are made;
|
||||
* NULL if not using change tracking
|
||||
* nullptr if not using change tracking
|
||||
*/
|
||||
boost::shared_ptr<ConfigNode> m_ids;
|
||||
std::shared_ptr<ConfigNode> m_ids;
|
||||
|
||||
/**
|
||||
* cache of all items, filled at begin of session and updated as
|
||||
|
@ -231,7 +229,7 @@ class ActiveSyncSource :
|
|||
Collection() :
|
||||
type(0),
|
||||
pathFound(false),
|
||||
source(NULL)
|
||||
source(nullptr)
|
||||
{}
|
||||
|
||||
int getFolderType();
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include <syncevo/declarations.h>
|
||||
SE_BEGIN_CXX
|
||||
|
||||
static SyncSource *createSource(const SyncSourceParams ¶ms)
|
||||
static std::unique_ptr<SyncSource> createSource(const SyncSourceParams ¶ms)
|
||||
{
|
||||
SourceType sourceType = SyncSource::getSourceType(params.m_nodes);
|
||||
bool isMe;
|
||||
|
@ -44,7 +44,7 @@ static SyncSource *createSource(const SyncSourceParams ¶ms)
|
|||
if (isMe) {
|
||||
return
|
||||
#ifdef ENABLE_ACTIVESYNC
|
||||
new ActiveSyncContactSource(params)
|
||||
std::make_unique<ActiveSyncContactSource>(params)
|
||||
#else
|
||||
RegisterSyncSource::InactiveSource(params)
|
||||
#endif
|
||||
|
@ -55,7 +55,7 @@ static SyncSource *createSource(const SyncSourceParams ¶ms)
|
|||
if (isMe) {
|
||||
return
|
||||
#ifdef ENABLE_ACTIVESYNC
|
||||
new ActiveSyncCalendarSource(params, EAS_ITEM_CALENDAR)
|
||||
std::make_unique<ActiveSyncCalendarSource>(params, EAS_ITEM_CALENDAR)
|
||||
#else
|
||||
RegisterSyncSource::InactiveSource(params)
|
||||
#endif
|
||||
|
@ -66,7 +66,7 @@ static SyncSource *createSource(const SyncSourceParams ¶ms)
|
|||
if (isMe) {
|
||||
return
|
||||
#ifdef ENABLE_ACTIVESYNC
|
||||
new ActiveSyncCalFormatSource(params, EAS_ITEM_TODO)
|
||||
std::make_unique<ActiveSyncCalFormatSource>(params, EAS_ITEM_TODO)
|
||||
#else
|
||||
RegisterSyncSource::InactiveSource(params)
|
||||
#endif
|
||||
|
@ -77,14 +77,14 @@ static SyncSource *createSource(const SyncSourceParams ¶ms)
|
|||
if (isMe) {
|
||||
return
|
||||
#ifdef ENABLE_ACTIVESYNC
|
||||
new ActiveSyncCalFormatSource(params, EAS_ITEM_JOURNAL)
|
||||
std::make_unique<ActiveSyncCalFormatSource>(params, EAS_ITEM_JOURNAL)
|
||||
#else
|
||||
RegisterSyncSource::InactiveSource(params)
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static RegisterSyncSource registerMe("ActiveSync",
|
||||
|
@ -114,11 +114,11 @@ class ActiveSyncsTest : public CppUnit::TestFixture {
|
|||
|
||||
protected:
|
||||
void testInstantiate() {
|
||||
boost::shared_ptr<SyncSource> source;
|
||||
source.reset(SyncSource::createTestingSource("contacts", "ActiveSync Address Book", true));
|
||||
source.reset(SyncSource::createTestingSource("events", "ActiveSync Events", true));
|
||||
source.reset(SyncSource::createTestingSource("todos", "ActiveSync Todos", true));
|
||||
source.reset(SyncSource::createTestingSource("memos", "ActiveSync Memos", true));
|
||||
std::unique_ptr<SyncSource> source;
|
||||
source = SyncSource::createTestingSource("contacts", "ActiveSync Address Book", true);
|
||||
source = SyncSource::createTestingSource("events", "ActiveSync Events", true);
|
||||
source = SyncSource::createTestingSource("todos", "ActiveSync Todos", true);
|
||||
source = SyncSource::createTestingSource("memos", "ActiveSync Memos", true);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -151,7 +151,7 @@ static int DumpItems(ClientTest &client, TestingSyncSource &source, const std::s
|
|||
// each server ID might appear multiple times, once for each
|
||||
// recurrence associated with it
|
||||
std::set<std::string> easids;
|
||||
BOOST_FOREACH (const std::string &luid, eassource.getAllItems()) {
|
||||
for (const std::string &luid: eassource.getAllItems()) {
|
||||
// slight hack: we know that luids in ActiveSyncSource base
|
||||
// class pass through this method unmodified, so no need to
|
||||
// avoid it
|
||||
|
@ -159,7 +159,7 @@ static int DumpItems(ClientTest &client, TestingSyncSource &source, const std::s
|
|||
easids.insert(ids.first);
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const std::string &easid, easids) {
|
||||
for (const std::string &easid: easids) {
|
||||
std::string item;
|
||||
if (forceBaseReadItem) {
|
||||
// This bypasses the more specialized
|
||||
|
@ -183,12 +183,12 @@ static int DumpItems(ClientTest &client, TestingSyncSource &source, const std::s
|
|||
return 0;
|
||||
}
|
||||
|
||||
static TestingSyncSource *createEASSource(const ClientTestConfig::createsource_t &create,
|
||||
ClientTest &client,
|
||||
const std::string &clientID,
|
||||
int source, bool isSourceA)
|
||||
static std::unique_ptr<TestingSyncSource> createEASSource(const ClientTestConfig::createsource_t &create,
|
||||
ClientTest &client,
|
||||
const std::string &clientID,
|
||||
int source, bool isSourceA)
|
||||
{
|
||||
std::auto_ptr<TestingSyncSource> res(create(client, clientID, source, isSourceA));
|
||||
std::unique_ptr<TestingSyncSource> res(create(client, clientID, source, isSourceA));
|
||||
|
||||
// Mangle username: if the base username in the config is account
|
||||
// "foo", then source B uses "foo_B", because otherwise it'll end
|
||||
|
@ -201,12 +201,12 @@ static TestingSyncSource *createEASSource(const ClientTestConfig::createsource_t
|
|||
}
|
||||
|
||||
if (res->getDatabaseID().empty()) {
|
||||
return res.release();
|
||||
return res;
|
||||
} else {
|
||||
// sorry, no database
|
||||
SE_LOG_ERROR(NULL, "cannot create EAS datastore for database %s, check config",
|
||||
res->getDatabaseID().c_str());
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -218,17 +218,20 @@ static void updateConfigEAS(const RegisterSyncSourceTest */* me */,
|
|||
// cannot run tests involving a second database:
|
||||
// wrap orginal source creation, set default database for
|
||||
// database #0 and refuse to return a source for database #1
|
||||
config.m_createSourceA = boost::bind(createEASSource, config.m_createSourceA,
|
||||
_1, _2, _3, _4);
|
||||
config.m_createSourceB = boost::bind(createEASSource, config.m_createSourceB,
|
||||
_1, _2, _3, _4);
|
||||
|
||||
config.m_dump = boost::bind(DumpItems, _1, _2, _3,
|
||||
type == EAS_ITEM_CONTACT ||
|
||||
// need to read from our cache for Google Calendar,
|
||||
// because it does not support Fetch
|
||||
strcmp(getEnv("CLIENT_TEST_SERVER", ""), "googleeas")
|
||||
);
|
||||
config.m_createSourceA = [create=config.m_createSourceA] (ClientTest &client, const std::string &clientID, int source, bool isSourceA) {
|
||||
return createEASSource(create, client, clientID, source, isSourceA);
|
||||
};
|
||||
config.m_createSourceB = [create=config.m_createSourceB] (ClientTest &client, const std::string &clientID, int source, bool isSourceA) {
|
||||
return createEASSource(create, client, clientID, source, isSourceA);
|
||||
};
|
||||
config.m_dump = [type] (ClientTest &client, TestingSyncSource &source, const std::string &file) {
|
||||
return DumpItems(client, source, file,
|
||||
type == EAS_ITEM_CONTACT ||
|
||||
// need to read from our cache for Google Calendar,
|
||||
// because it does not support Fetch
|
||||
strcmp(getEnv("CLIENT_TEST_SERVER", ""), "googleeas")
|
||||
);
|
||||
};
|
||||
config.m_sourceLUIDsAreVolatile = true;
|
||||
// TODO: find out how ActiveSync/Exchange handle children without parent;
|
||||
// at the moment, the child is stored as if it was a stand-alone event
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include <syncevo/declarations.h>
|
||||
SE_BEGIN_CXX
|
||||
|
||||
static SyncSource *createSource(const SyncSourceParams ¶ms)
|
||||
static std::unique_ptr<SyncSource> createSource(const SyncSourceParams ¶ms)
|
||||
{
|
||||
SourceType sourceType = SyncSource::getSourceType(params.m_nodes);
|
||||
bool isMe;
|
||||
|
@ -40,13 +40,13 @@ static SyncSource *createSource(const SyncSourceParams ¶ms)
|
|||
|| sourceType.m_format == "text/x-vcard") {
|
||||
return
|
||||
#ifdef ENABLE_AKONADI
|
||||
new AkonadiContactSource(params)
|
||||
std::make_unique<AkonadiContactSource>(params)
|
||||
#else
|
||||
isMe ? RegisterSyncSource::InactiveSource(params) : NULL
|
||||
isMe ? RegisterSyncSource::InactiveSource(params) : nullptr
|
||||
#endif
|
||||
;
|
||||
} else {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,13 +56,13 @@ static SyncSource *createSource(const SyncSourceParams ¶ms)
|
|||
|| sourceType.m_format == "text/x-vcalendar") {
|
||||
return
|
||||
#ifdef ENABLE_AKONADI
|
||||
new AkonadiTaskSource(params)
|
||||
std::make_unique<AkonadiTaskSource>(params)
|
||||
#else
|
||||
isMe ? RegisterSyncSource::InactiveSource(params) : NULL
|
||||
isMe ? RegisterSyncSource::InactiveSource(params) : nullptr
|
||||
#endif
|
||||
;
|
||||
} else {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,13 +71,13 @@ static SyncSource *createSource(const SyncSourceParams ¶ms)
|
|||
if (sourceType.m_format == "" || sourceType.m_format == "text/plain") {
|
||||
return
|
||||
#ifdef ENABLE_AKONADI
|
||||
new AkonadiMemoSource(params)
|
||||
std::make_unique<AkonadiMemoSource>(params)
|
||||
#else
|
||||
isMe ? RegisterSyncSource::InactiveSource(params) : NULL
|
||||
isMe ? RegisterSyncSource::InactiveSource(params) : nullptr
|
||||
#endif
|
||||
;
|
||||
} else {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,17 +87,17 @@ static SyncSource *createSource(const SyncSourceParams ¶ms)
|
|||
sourceType.m_format == "text/x-vcalendar" /* this is for backwards compatibility with broken configs */ ) {
|
||||
return
|
||||
#ifdef ENABLE_AKONADI
|
||||
new AkonadiCalendarSource(params)
|
||||
std::make_unique<AkonadiCalendarSource>(params)
|
||||
#else
|
||||
isMe ? RegisterSyncSource::InactiveSource(params) : NULL
|
||||
isMe ? RegisterSyncSource::InactiveSource(params) : nullptr
|
||||
#endif
|
||||
;
|
||||
} else {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static RegisterSyncSource registerMe("KDE Contact/Calendar/Task List/Memos",
|
||||
|
@ -147,59 +147,59 @@ class AkonadiTest : public CppUnit::TestFixture {
|
|||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
protected:
|
||||
static string addItem(boost::shared_ptr<TestingSyncSource> source,
|
||||
static string addItem(std::shared_ptr<TestingSyncSource> source,
|
||||
string &data) {
|
||||
SyncSourceRaw::InsertItemResult res = source->insertItemRaw("", data);
|
||||
return res.m_luid;
|
||||
}
|
||||
|
||||
void testInstantiate() {
|
||||
boost::shared_ptr<SyncSource> source;
|
||||
// source.reset(SyncSource::createTestingSource("addressbook", "addressbook", true));
|
||||
// source.reset(SyncSource::createTestingSource("addressbook", "contacts", true));
|
||||
source.reset(SyncSource::createTestingSource("addressbook", "kde-contacts", true));
|
||||
source.reset(SyncSource::createTestingSource("addressbook", "KDE Contacts", true));
|
||||
source.reset(SyncSource::createTestingSource("addressbook", "KDE Address Book:text/x-vcard", true));
|
||||
source.reset(SyncSource::createTestingSource("addressbook", "KDE Address Book:text/vcard", true));
|
||||
std::unique_ptr<SyncSource> source;
|
||||
// source = SyncSource::createTestingSource("addressbook", "addressbook", true);
|
||||
// source = SyncSource::createTestingSource("addressbook", "contacts", true);
|
||||
source = SyncSource::createTestingSource("addressbook", "kde-contacts", true);
|
||||
source = SyncSource::createTestingSource("addressbook", "KDE Contacts", true);
|
||||
source = SyncSource::createTestingSource("addressbook", "KDE Address Book:text/x-vcard", true);
|
||||
source = SyncSource::createTestingSource("addressbook", "KDE Address Book:text/vcard", true);
|
||||
|
||||
|
||||
// source.reset(SyncSource::createTestingSource("calendar", "calendar", true));
|
||||
source.reset(SyncSource::createTestingSource("calendar", "kde-calendar", true));
|
||||
source.reset(SyncSource::createTestingSource("calendar", "KDE Calendar:text/calendar", true));
|
||||
// source = SyncSource::createTestingSource("calendar", "calendar", true);
|
||||
source = SyncSource::createTestingSource("calendar", "kde-calendar", true);
|
||||
source = SyncSource::createTestingSource("calendar", "KDE Calendar:text/calendar", true);
|
||||
|
||||
// source.reset(SyncSource::createTestingSource("tasks", "tasks", true));
|
||||
source.reset(SyncSource::createTestingSource("tasks", "kde-tasks", true));
|
||||
source.reset(SyncSource::createTestingSource("tasks", "KDE Tasks", true));
|
||||
source.reset(SyncSource::createTestingSource("tasks", "KDE Task List:text/calendar", true));
|
||||
// source = SyncSource::createTestingSource("tasks", "tasks", true);
|
||||
source = SyncSource::createTestingSource("tasks", "kde-tasks", true);
|
||||
source = SyncSource::createTestingSource("tasks", "KDE Tasks", true);
|
||||
source = SyncSource::createTestingSource("tasks", "KDE Task List:text/calendar", true);
|
||||
|
||||
// source.reset(SyncSource::createTestingSource("memos", "memos", true));
|
||||
source.reset(SyncSource::createTestingSource("memos", "kde-memos", true));
|
||||
source.reset(SyncSource::createTestingSource("memos", "KDE Memos:text/plain", true));
|
||||
// source = SyncSource::createTestingSource("memos", "memos", true);
|
||||
source = SyncSource::createTestingSource("memos", "kde-memos", true);
|
||||
source = SyncSource::createTestingSource("memos", "KDE Memos:text/plain", true);
|
||||
}
|
||||
|
||||
// TODO: support default databases
|
||||
|
||||
// void testOpenDefaultAddressBook() {
|
||||
// boost::shared_ptr<TestingSyncSource> source;
|
||||
// source.reset((TestingSyncSource *)SyncSource::createTestingSource("contacts", "kde-contacts", true, NULL));
|
||||
// std::shared_ptr<TestingSyncSource> source;
|
||||
// source = (TestingSyncSource *)SyncSource::createTestingSource("contacts", "kde-contacts", true, nullptr);
|
||||
// CPPUNIT_ASSERT_NO_THROW(source->open());
|
||||
// }
|
||||
|
||||
// void testOpenDefaultCalendar() {
|
||||
// boost::shared_ptr<TestingSyncSource> source;
|
||||
// source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "kde-calendar", true, NULL));
|
||||
// std::shared_ptr<TestingSyncSource> source;
|
||||
// source = (TestingSyncSource *)SyncSource::createTestingSource("calendar", "kde-calendar", true, nullptr);
|
||||
// CPPUNIT_ASSERT_NO_THROW(source->open());
|
||||
// }
|
||||
|
||||
// void testOpenDefaultTodo() {
|
||||
// boost::shared_ptr<TestingSyncSource> source;
|
||||
// source.reset((TestingSyncSource *)SyncSource::createTestingSource("tasks", "kde-tasks", true, NULL));
|
||||
// std::shared_ptr<TestingSyncSource> source;
|
||||
// source = (TestingSyncSource *)SyncSource::createTestingSource("tasks", "kde-tasks", true, nullptr);
|
||||
// CPPUNIT_ASSERT_NO_THROW(source->open());
|
||||
// }
|
||||
|
||||
// void testOpenDefaultMemo() {
|
||||
// boost::shared_ptr<TestingSyncSource> source;
|
||||
// source.reset((TestingSyncSource *)SyncSource::createTestingSource("memos", "kde-memos", true, NULL));
|
||||
// std::shared_ptr<TestingSyncSource> source;
|
||||
// source = (TestingSyncSource *)SyncSource::createTestingSource("memos", "kde-memos", true, nullptr);
|
||||
// CPPUNIT_ASSERT_NO_THROW(source->open());
|
||||
// }
|
||||
|
||||
|
@ -209,8 +209,8 @@ protected:
|
|||
prefix = "SyncEvolution_Test_";
|
||||
}
|
||||
|
||||
boost::shared_ptr<TestingSyncSource> source;
|
||||
source.reset((TestingSyncSource *)SyncSource::createTestingSource("eds_event", "kde-calendar", true, prefix));
|
||||
std::shared_ptr<TestingSyncSource> source;
|
||||
source.reset((TestingSyncSource *)SyncSource::createTestingSource("eds_event", "kde-calendar", true, prefix).release());
|
||||
CPPUNIT_ASSERT_NO_THROW(source->open());
|
||||
|
||||
string newyork =
|
||||
|
|
|
@ -16,6 +16,6 @@ src_backends_akonadi_syncakonadi_la_SOURCES = \
|
|||
src/backends/akonadi/akonadisyncsource.cpp
|
||||
src_backends_akonadi_syncakonadi_la_LIBADD = $(KDEPIM_LIBS) $(SYNCEVOLUTION_LIBS)
|
||||
src_backends_akonadi_syncakonadi_la_LDFLAGS = -module -avoid-version
|
||||
src_backends_akonadi_syncakonadi_la_CXXFLAGS = $(SYNCEVOLUTION_CXXFLAGS) $(SYNCEVO_WFLAGS)
|
||||
src_backends_akonadi_syncakonadi_la_CXXFLAGS = $(SYNCEVOLUTION_CXXFLAGS) $(SYNCEVO_WFLAGS_DEPRECATED)
|
||||
src_backends_akonadi_syncakonadi_la_CPPFLAGS = $(SYNCEVOLUTION_CFLAGS) -I$(top_srcdir)/test $(BACKEND_CPPFLAGS)
|
||||
src_backends_akonadi_syncakonadi_la_DEPENDENCIES = src/syncevo/libsyncevolution.la
|
||||
|
|
|
@ -39,10 +39,6 @@
|
|||
|
||||
#include <syncevo/util.h>
|
||||
|
||||
#include <boost/lambda/lambda.hpp>
|
||||
#include <boost/lambda/bind.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
SE_BEGIN_CXX
|
||||
|
@ -56,7 +52,7 @@ using namespace Akonadi;
|
|||
*
|
||||
* To avoid double frees, we need to disable auto-deletion.
|
||||
* This method does that. Use like this:
|
||||
* std::auto_ptr<CollectionStatisticsJob> statisticsJob(DisableAutoDelete(new CollectionStatisticsJob(m_collection)));
|
||||
* std::unique_ptr<CollectionStatisticsJob> statisticsJob(DisableAutoDelete(new CollectionStatisticsJob(m_collection)));
|
||||
*/
|
||||
template<class J> J *DisableAutoDelete(J *job) { job->setAutoDelete(false); return job; }
|
||||
|
||||
|
@ -75,12 +71,12 @@ bool AkonadiSyncSource::isEmpty()
|
|||
{
|
||||
if (!GRunIsMain()) {
|
||||
bool result;
|
||||
GRunInMain(boost::lambda::var(result) = boost::lambda::bind(&AkonadiSyncSource::isEmpty, this));
|
||||
GRunInMain([this, &result] () { result = isEmpty(); });
|
||||
return result;
|
||||
}
|
||||
|
||||
//To Check if the respective collection is Empty, without actually loading the collections
|
||||
std::auto_ptr<CollectionStatisticsJob> statisticsJob(DisableAutoDelete(new CollectionStatisticsJob(m_collection)));
|
||||
std::unique_ptr<CollectionStatisticsJob> statisticsJob(DisableAutoDelete(new CollectionStatisticsJob(m_collection)));
|
||||
if (!statisticsJob->exec()) {
|
||||
throwError(SE_HERE, "Error fetching the collection stats");
|
||||
}
|
||||
|
@ -90,7 +86,7 @@ bool AkonadiSyncSource::isEmpty()
|
|||
void AkonadiSyncSource::start()
|
||||
{
|
||||
if (!GRunIsMain()) {
|
||||
GRunInMain(boost::bind(&AkonadiSyncSource::start, this));
|
||||
GRunInMain([this]() { start(); });
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -117,7 +113,7 @@ SyncSource::Databases AkonadiSyncSource::getDatabases()
|
|||
{
|
||||
if (!GRunIsMain()) {
|
||||
Databases result;
|
||||
GRunInMain(boost::lambda::var(result) = boost::lambda::bind(&AkonadiSyncSource::getDatabases, this));
|
||||
GRunInMain([this, &result] () { result = getDatabases(); });
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -129,8 +125,8 @@ SyncSource::Databases AkonadiSyncSource::getDatabases()
|
|||
// as the default one used by the source.
|
||||
// res.push_back("Contacts", "some-KDE-specific-ID", isDefault);
|
||||
|
||||
std::auto_ptr<CollectionFetchJob> fetchJob(DisableAutoDelete(new CollectionFetchJob(Collection::root(),
|
||||
CollectionFetchJob::Recursive)));
|
||||
std::unique_ptr<CollectionFetchJob> fetchJob(DisableAutoDelete(new CollectionFetchJob(Collection::root(),
|
||||
CollectionFetchJob::Recursive)));
|
||||
|
||||
fetchJob->fetchScope().setContentMimeTypes(m_mimeTypes);
|
||||
|
||||
|
@ -155,7 +151,7 @@ SyncSource::Databases AkonadiSyncSource::getDatabases()
|
|||
void AkonadiSyncSource::open()
|
||||
{
|
||||
if (!GRunIsMain()) {
|
||||
GRunInMain(boost::bind(&AkonadiSyncSource::open, this));
|
||||
GRunInMain([this] () { open(); });
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -193,8 +189,8 @@ void AkonadiSyncSource::open()
|
|||
// Verify that the collection exists and ensure that
|
||||
// m_collection.contentMimeTypes() returns valid information. The
|
||||
// collection constructed so far only contains the collection ID.
|
||||
std::auto_ptr<CollectionFetchJob> fetchJob(DisableAutoDelete(new CollectionFetchJob(m_collection,
|
||||
CollectionFetchJob::Base)));
|
||||
std::unique_ptr<CollectionFetchJob> fetchJob(DisableAutoDelete(new CollectionFetchJob(m_collection,
|
||||
CollectionFetchJob::Base)));
|
||||
if (!fetchJob->exec()) {
|
||||
throwError(SE_HERE, StringPrintf("cannot fetch collection %s", id.c_str()));
|
||||
}
|
||||
|
@ -223,16 +219,16 @@ void AkonadiSyncSource::open()
|
|||
void AkonadiSyncSource::listAllItems(SyncSourceRevisions::RevisionMap_t &revisions)
|
||||
{
|
||||
if (!GRunIsMain()) {
|
||||
GRunInMain(boost::bind(&AkonadiSyncSource::listAllItems, this, boost::ref(revisions)));
|
||||
GRunInMain([this, &revisions] () { listAllItems(revisions); });
|
||||
return;
|
||||
}
|
||||
|
||||
// copy all local IDs and the corresponding revision
|
||||
std::auto_ptr<ItemFetchJob> fetchJob(DisableAutoDelete(new ItemFetchJob(m_collection)));
|
||||
std::unique_ptr<ItemFetchJob> fetchJob(DisableAutoDelete(new ItemFetchJob(m_collection)));
|
||||
if (!fetchJob->exec()) {
|
||||
throwError(SE_HERE, "listing items");
|
||||
}
|
||||
BOOST_FOREACH (const Item &item, fetchJob->items()) {
|
||||
for (const Item &item: fetchJob->items()) {
|
||||
// Filter out items which don't have the right type (for example, VTODO when
|
||||
// syncing events)
|
||||
if (m_mimeTypes.contains(item.mimeType())) {
|
||||
|
@ -251,7 +247,7 @@ TrackingSyncSource::InsertItemResult AkonadiSyncSource::insertItem(const std::st
|
|||
{
|
||||
if (!GRunIsMain()) {
|
||||
InsertItemResult result;
|
||||
GRunInMain(boost::lambda::var(result) = boost::lambda::bind(&AkonadiSyncSource::insertItem, this, boost::cref(luid), boost::cref(data), raw));
|
||||
GRunInMain([this, &result, &luid, &data, raw] () { return insertItem(luid, data, raw); });
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -260,7 +256,7 @@ TrackingSyncSource::InsertItemResult AkonadiSyncSource::insertItem(const std::st
|
|||
if (luid.empty()) {
|
||||
item.setMimeType(m_mimeTypes.front());
|
||||
item.setPayloadFromData(QByteArray(data.c_str()));
|
||||
std::auto_ptr<ItemCreateJob> createJob(DisableAutoDelete(new ItemCreateJob(item, m_collection)));
|
||||
std::unique_ptr<ItemCreateJob> createJob(DisableAutoDelete(new ItemCreateJob(item, m_collection)));
|
||||
if (!createJob->exec()) {
|
||||
throwError(SE_HERE, string("storing new item ") + luid);
|
||||
return InsertItemResult("", "", ITEM_OKAY);
|
||||
|
@ -268,13 +264,13 @@ TrackingSyncSource::InsertItemResult AkonadiSyncSource::insertItem(const std::st
|
|||
item = createJob->item();
|
||||
} else {
|
||||
Entity::Id syncItemId = QByteArray(luid.c_str()).toLongLong();
|
||||
std::auto_ptr<ItemFetchJob> fetchJob(DisableAutoDelete(new ItemFetchJob(Item(syncItemId))));
|
||||
std::unique_ptr<ItemFetchJob> fetchJob(DisableAutoDelete(new ItemFetchJob(Item(syncItemId))));
|
||||
if (!fetchJob->exec()) {
|
||||
throwError(SE_HERE, string("checking item ") + luid);
|
||||
}
|
||||
item = fetchJob->items().first();
|
||||
item.setPayloadFromData(QByteArray(data.c_str()));
|
||||
std::auto_ptr<ItemModifyJob> modifyJob(DisableAutoDelete(new ItemModifyJob(item)));
|
||||
std::unique_ptr<ItemModifyJob> modifyJob(DisableAutoDelete(new ItemModifyJob(item)));
|
||||
// TODO: SyncEvolution must pass the known revision that
|
||||
// we are updating.
|
||||
// TODO: check that the item has not been updated in the meantime
|
||||
|
@ -296,7 +292,7 @@ TrackingSyncSource::InsertItemResult AkonadiSyncSource::insertItem(const std::st
|
|||
void AkonadiSyncSource::removeItem(const string &luid)
|
||||
{
|
||||
if (!GRunIsMain()) {
|
||||
GRunInMain(boost::bind(&AkonadiSyncSource::removeItem, this, boost::cref(luid)));
|
||||
GRunInMain([this, &luid] () { removeItem(luid); });
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -304,7 +300,7 @@ void AkonadiSyncSource::removeItem(const string &luid)
|
|||
|
||||
// Delete the item from our collection
|
||||
// TODO: check that the revision is right (need revision from SyncEvolution)
|
||||
std::auto_ptr<ItemDeleteJob> deleteJob(DisableAutoDelete(new ItemDeleteJob(Item(syncItemId))));
|
||||
std::unique_ptr<ItemDeleteJob> deleteJob(DisableAutoDelete(new ItemDeleteJob(Item(syncItemId))));
|
||||
if (!deleteJob->exec()) {
|
||||
throwError(SE_HERE, string("deleting item " ) + luid);
|
||||
}
|
||||
|
@ -313,13 +309,13 @@ void AkonadiSyncSource::removeItem(const string &luid)
|
|||
void AkonadiSyncSource::readItem(const std::string &luid, std::string &data, bool raw)
|
||||
{
|
||||
if (!GRunIsMain()) {
|
||||
GRunInMain(boost::bind(&AkonadiSyncSource::readItem, this, boost::cref(luid), boost::ref(data), raw));
|
||||
GRunInMain([this, &luid, &data, raw] () { readItem(luid, data, raw); });
|
||||
return;
|
||||
}
|
||||
|
||||
Entity::Id syncItemId = QByteArray(luid.c_str()).toLongLong();
|
||||
|
||||
std::auto_ptr<ItemFetchJob> fetchJob(DisableAutoDelete(new ItemFetchJob(Item(syncItemId))));
|
||||
std::unique_ptr<ItemFetchJob> fetchJob(DisableAutoDelete(new ItemFetchJob(Item(syncItemId))));
|
||||
fetchJob->fetchScope().fetchFullPayload();
|
||||
if (fetchJob->exec()) {
|
||||
if (fetchJob->items().empty()) {
|
||||
|
|
|
@ -14,7 +14,7 @@ if ! test "$KDEPIM_CFLAGS"; then
|
|||
fi
|
||||
fi
|
||||
if ! test "$KDEPIM_LIBS"; then
|
||||
KDEPIM_LIBS="-L`kde4-config --install lib` -lakonadi-kde `${PKG_CONFIG} --libs QtDBus` -lQtCore -lkdeui -lkdecore"
|
||||
KDEPIM_LIBS="-L`kde4-config --install lib` -lakonadi-kde `${PKG_CONFIG} --libs QtDBus` -lQtCore"
|
||||
fi
|
||||
AC_LANG_PUSH(C++)
|
||||
old_CPPFLAGS="$CPPFLAGS"
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
*/
|
||||
|
||||
#include <memory>
|
||||
using namespace std;
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
@ -36,9 +35,6 @@ using namespace std;
|
|||
#include "EvolutionMemoSource.h"
|
||||
#include "e-cal-check-timezones.h"
|
||||
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include <syncevo/declarations.h>
|
||||
SE_BEGIN_CXX
|
||||
|
||||
|
@ -62,7 +58,7 @@ void EvolutionCalendarSource::LUIDs::eraseLUID(const ItemID &id)
|
|||
{
|
||||
iterator it = find(id.m_uid);
|
||||
if (it != end()) {
|
||||
set<string>::iterator it2 = it->second.find(id.m_rid);
|
||||
auto it2 = it->second.find(id.m_rid);
|
||||
if (it2 != it->second.end()) {
|
||||
it->second.erase(it2);
|
||||
if (it->second.empty()) {
|
||||
|
@ -124,7 +120,7 @@ EvolutionCalendarSource::EvolutionCalendarSource(EvolutionCalendarSourceType typ
|
|||
// This is not available in older Evolution versions.
|
||||
// A configure check could detect that, but as this isn't
|
||||
// important the functionality is simply disabled.
|
||||
m_newSystem = NULL /* e_cal_new_system_memos */;
|
||||
m_newSystem = nullptr /* e_cal_new_system_memos */;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
|
@ -144,21 +140,21 @@ SyncSource::Databases EvolutionCalendarSource::getDatabases()
|
|||
m_type == EVOLUTION_CAL_SOURCE_TYPE_EVENTS ? e_source_registry_ref_default_calendar :
|
||||
m_type == EVOLUTION_CAL_SOURCE_TYPE_TASKS ? e_source_registry_ref_default_task_list :
|
||||
m_type == EVOLUTION_CAL_SOURCE_TYPE_MEMOS ? e_source_registry_ref_default_memo_list :
|
||||
NULL);
|
||||
nullptr);
|
||||
#else
|
||||
ESourceList *tmp = NULL;
|
||||
ESourceList *tmp = nullptr;
|
||||
if (!e_cal_get_sources(&tmp, sourceType(), gerror)) {
|
||||
// ignore unspecific errors (like on Maemo with no support for memos)
|
||||
// and continue with empty list (perhaps defaults work)
|
||||
if (!gerror) {
|
||||
tmp = NULL;
|
||||
tmp = nullptr;
|
||||
} else {
|
||||
throwError(SE_HERE, "unable to access backend databases", gerror);
|
||||
}
|
||||
}
|
||||
ESourceListCXX sources(tmp, TRANSFER_REF);
|
||||
bool first = true;
|
||||
for (GSList *g = sources ? e_source_list_peek_groups (sources) : NULL;
|
||||
for (GSList *g = sources ? e_source_list_peek_groups (sources) : nullptr;
|
||||
g;
|
||||
g = g->next) {
|
||||
ESourceGroup *group = E_SOURCE_GROUP (g->data);
|
||||
|
@ -184,14 +180,7 @@ SyncSource::Databases EvolutionCalendarSource::getDatabases()
|
|||
return result;
|
||||
}
|
||||
|
||||
#ifdef USE_EDS_CLIENT
|
||||
static EClient *newECalClient(ESource *source,
|
||||
ECalClientSourceType ecalSourceType,
|
||||
GError **gerror)
|
||||
{
|
||||
return E_CLIENT(e_cal_client_new(source, ecalSourceType, gerror));
|
||||
}
|
||||
#else
|
||||
#ifndef USE_EDS_CLIENT
|
||||
char *EvolutionCalendarSource::authenticate(const char *prompt,
|
||||
const char *key)
|
||||
{
|
||||
|
@ -200,7 +189,7 @@ char *EvolutionCalendarSource::authenticate(const char *prompt,
|
|||
SE_LOG_DEBUG(getDisplayName(), "authentication requested, prompt \"%s\", key \"%s\" => %s",
|
||||
prompt, key,
|
||||
!passwd.empty() ? "returning configured password" : "no password configured");
|
||||
return !passwd.empty() ? strdup(passwd.c_str()) : NULL;
|
||||
return !passwd.empty() ? strdup(passwd.c_str()) : nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -218,15 +207,18 @@ void EvolutionCalendarSource::open()
|
|||
// be others with similar problems and for local storage it is
|
||||
// a reasonably cheap operation (so no harm there).
|
||||
for (int retries = 0; retries < 2; retries++) {
|
||||
auto create = [type=sourceType()] (ESource *source, GError **gerror) {
|
||||
return E_CLIENT(e_cal_client_connect_sync(source, type,
|
||||
-1, // timeout in seconds
|
||||
nullptr, // cancellable
|
||||
gerror));
|
||||
};
|
||||
m_calendar.reset(E_CAL_CLIENT(openESource(sourceExtension(),
|
||||
m_type == EVOLUTION_CAL_SOURCE_TYPE_EVENTS ? e_source_registry_ref_builtin_calendar :
|
||||
m_type == EVOLUTION_CAL_SOURCE_TYPE_TASKS ? e_source_registry_ref_builtin_task_list :
|
||||
m_type == EVOLUTION_CAL_SOURCE_TYPE_MEMOS ? e_source_registry_ref_builtin_memo_list :
|
||||
NULL,
|
||||
boost::bind(newECalClient,
|
||||
_1,
|
||||
sourceType(),
|
||||
_2)).get()));
|
||||
nullptr,
|
||||
create).get()));
|
||||
}
|
||||
#else
|
||||
GErrorCXX gerror;
|
||||
|
@ -307,7 +299,7 @@ bool EvolutionCalendarSource::isEmpty()
|
|||
#ifdef USE_EDS_CLIENT
|
||||
class ECalClientViewSyncHandler {
|
||||
public:
|
||||
typedef boost::function<void(const GSList *list)> Process_t;
|
||||
typedef std::function<void(const GSList *list)> Process_t;
|
||||
|
||||
ECalClientViewSyncHandler(ECalClientViewCXX &view,
|
||||
const Process_t &process) :
|
||||
|
@ -318,12 +310,12 @@ class ECalClientViewSyncHandler {
|
|||
bool processSync(GErrorCXX &gerror)
|
||||
{
|
||||
// Listen for view signals
|
||||
m_view.connectSignal<void (ECalClientView *ebookview,
|
||||
const GSList *contacts)>("objects-added",
|
||||
boost::bind(m_process, _2));
|
||||
m_view.connectSignal<void (EBookClientView *ebookview,
|
||||
const GError *error)>("complete",
|
||||
boost::bind(&ECalClientViewSyncHandler::completed, this, _2));
|
||||
m_view.connectSignal<ECalClientView *,
|
||||
const GSList *>()("objects-added",
|
||||
[this] (ECalClientView *, const GSList *list) { m_process(list); });
|
||||
m_view.connectSignal<ECalClientView *,
|
||||
const GError *>()("complete",
|
||||
[this] (ECalClientView *, const GError *gerror) { completed(gerror); });
|
||||
|
||||
// Start the view
|
||||
e_cal_client_view_start (m_view, m_error);
|
||||
|
@ -334,7 +326,7 @@ class ECalClientViewSyncHandler {
|
|||
|
||||
// Async -> Sync
|
||||
m_loop.run();
|
||||
e_cal_client_view_stop (m_view, NULL);
|
||||
e_cal_client_view_stop (m_view, nullptr);
|
||||
|
||||
if (m_error) {
|
||||
std::swap(gerror, m_error);
|
||||
|
@ -364,21 +356,7 @@ class ECalClientViewSyncHandler {
|
|||
// Possible error while watching the view
|
||||
GErrorCXX m_error;
|
||||
};
|
||||
|
||||
static void list_revisions(const GSList *objects, EvolutionCalendarSource::RevisionMap_t *revisions)
|
||||
{
|
||||
const GSList *l;
|
||||
|
||||
for (l = objects; l; l = l->next) {
|
||||
icalcomponent *icomp = (icalcomponent*)l->data;
|
||||
EvolutionCalendarSource::ItemID id = EvolutionCalendarSource::getItemID(icomp);
|
||||
string luid = id.getLUID();
|
||||
string modTime = EvolutionCalendarSource::getItemModTime(icomp);
|
||||
|
||||
(*revisions)[luid] = modTime;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // USE_EDS_CLIENT
|
||||
|
||||
void EvolutionCalendarSource::listAllItems(RevisionMap_t &revisions)
|
||||
{
|
||||
|
@ -386,14 +364,29 @@ void EvolutionCalendarSource::listAllItems(RevisionMap_t &revisions)
|
|||
#ifdef USE_EDS_CLIENT
|
||||
ECalClientView *view;
|
||||
|
||||
if (!e_cal_client_get_view_sync (m_calendar, "#t", &view, NULL, gerror)) {
|
||||
if (!e_cal_client_get_view_sync (m_calendar, "#t", &view, nullptr, gerror)) {
|
||||
throwError(SE_HERE, "getting the view" , gerror);
|
||||
}
|
||||
ECalClientViewCXX viewPtr = ECalClientViewCXX::steal(view);
|
||||
|
||||
// TODO: Optimization: use set fields_of_interest (UID / REV / LAST-MODIFIED)
|
||||
|
||||
ECalClientViewSyncHandler handler(viewPtr, boost::bind(list_revisions, _1, &revisions));
|
||||
auto process = [&revisions] (const GSList *objects) {
|
||||
const GSList *l;
|
||||
|
||||
for (l = objects; l; l = l->next) {
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
ICalComponent *icomp = (ICalComponent*)l->data;
|
||||
#else
|
||||
icalcomponent *icomp = (icalcomponent*)l->data;
|
||||
#endif
|
||||
EvolutionCalendarSource::ItemID id = EvolutionCalendarSource::getItemID(icomp);
|
||||
string luid = id.getLUID();
|
||||
string modTime = EvolutionCalendarSource::getItemModTime(icomp);
|
||||
revisions[luid] = modTime;
|
||||
}
|
||||
};
|
||||
ECalClientViewSyncHandler handler(viewPtr, process);
|
||||
if (!handler.processSync(gerror)) {
|
||||
throwError(SE_HERE, "watching view", gerror);
|
||||
}
|
||||
|
@ -440,14 +433,26 @@ void EvolutionCalendarSource::readItem(const string &luid, std::string &item, bo
|
|||
}
|
||||
|
||||
#ifdef USE_EDS_CLIENT
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
ICalTimezone *
|
||||
#else /* HAVE_LIBECAL_2_0 */
|
||||
icaltimezone *
|
||||
#endif /* HAVE_LIBECAL_2_0 */
|
||||
my_tzlookup(const gchar *tzid,
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
gpointer ecalclient,
|
||||
#else
|
||||
gconstpointer ecalclient,
|
||||
#endif
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
icaltimezone *zone = NULL;
|
||||
GError *local_error = NULL;
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
ICalTimezone *zone = nullptr;
|
||||
#else
|
||||
icaltimezone *zone = nullptr;
|
||||
#endif
|
||||
GError *local_error = nullptr;
|
||||
|
||||
if (e_cal_client_get_timezone_sync((ECalClient *)ecalclient, tzid, &zone, cancellable, &local_error)) {
|
||||
return zone;
|
||||
|
@ -461,7 +466,7 @@ my_tzlookup(const gchar *tzid,
|
|||
g_propagate_error (error, local_error);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -504,7 +509,11 @@ EvolutionCalendarSource::InsertItemResult EvolutionCalendarSource::insertItem(co
|
|||
SE_LOG_DEBUG(getDisplayName(), "after replacing , with \\, in CATEGORIES:\n%s", data.c_str());
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
eptr<ICalComponent> icomp(i_cal_component_new_from_string((char *)data.c_str()));
|
||||
#else
|
||||
eptr<icalcomponent> icomp(icalcomponent_new_from_string((char *)data.c_str()));
|
||||
#endif
|
||||
|
||||
if( !icomp ) {
|
||||
throwError(SE_HERE, string("failure parsing ical") + data);
|
||||
|
@ -515,15 +524,24 @@ EvolutionCalendarSource::InsertItemResult EvolutionCalendarSource::insertItem(co
|
|||
// fix up TZIDs
|
||||
if (
|
||||
#ifdef USE_EDS_CLIENT
|
||||
!e_cal_client_check_timezones(icomp,
|
||||
NULL,
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
!e_cal_client_check_timezones_sync(
|
||||
#else
|
||||
!e_cal_client_check_timezones(
|
||||
#endif
|
||||
icomp,
|
||||
nullptr,
|
||||
my_tzlookup,
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
(gpointer)m_calendar.get(),
|
||||
#else
|
||||
(const void *)m_calendar.get(),
|
||||
NULL,
|
||||
#endif
|
||||
nullptr,
|
||||
gerror)
|
||||
#else
|
||||
!e_cal_check_timezones(icomp,
|
||||
NULL,
|
||||
nullptr,
|
||||
e_cal_tzlookup_ecal,
|
||||
(const void *)m_calendar.get(),
|
||||
gerror)
|
||||
|
@ -535,21 +553,35 @@ EvolutionCalendarSource::InsertItemResult EvolutionCalendarSource::insertItem(co
|
|||
|
||||
// insert before adding/updating the event so that the new VTIMEZONE is
|
||||
// immediately available should anyone want it
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
for (ICalComponent *tcomp = i_cal_component_get_first_component(icomp, I_CAL_VTIMEZONE_COMPONENT);
|
||||
tcomp;
|
||||
g_object_unref (tcomp), tcomp = i_cal_component_get_next_component(icomp, I_CAL_VTIMEZONE_COMPONENT)) {
|
||||
eptr<ICalTimezone> zone(i_cal_timezone_new(), "icaltimezone");
|
||||
i_cal_timezone_set_component(zone, tcomp);
|
||||
#else
|
||||
for (icalcomponent *tcomp = icalcomponent_get_first_component(icomp, ICAL_VTIMEZONE_COMPONENT);
|
||||
tcomp;
|
||||
tcomp = icalcomponent_get_next_component(icomp, ICAL_VTIMEZONE_COMPONENT)) {
|
||||
eptr<icaltimezone> zone(icaltimezone_new(), "icaltimezone");
|
||||
icaltimezone_set_component(zone, tcomp);
|
||||
#endif
|
||||
|
||||
GErrorCXX gerror;
|
||||
const char *tzid = icaltimezone_get_tzid(zone);
|
||||
const char *tzid;
|
||||
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
tzid = i_cal_timezone_get_tzid(zone);
|
||||
#else
|
||||
tzid = icaltimezone_get_tzid(zone);
|
||||
#endif
|
||||
if (!tzid || !tzid[0]) {
|
||||
// cannot add a VTIMEZONE without TZID
|
||||
SE_LOG_DEBUG(getDisplayName(), "skipping VTIMEZONE without TZID");
|
||||
} else {
|
||||
gboolean success =
|
||||
#ifdef USE_EDS_CLIENT
|
||||
e_cal_client_add_timezone_sync(m_calendar, zone, NULL, gerror)
|
||||
e_cal_client_add_timezone_sync(m_calendar, zone, nullptr, gerror)
|
||||
#else
|
||||
e_cal_add_timezone(m_calendar, zone, gerror)
|
||||
#endif
|
||||
|
@ -564,8 +596,14 @@ EvolutionCalendarSource::InsertItemResult EvolutionCalendarSource::insertItem(co
|
|||
// the component to update/add must be the
|
||||
// ICAL_VEVENT/VTODO_COMPONENT of the item,
|
||||
// e_cal_create/modify_object() fail otherwise
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
ICalComponent *subcomp = i_cal_component_get_first_component(icomp,
|
||||
getCompType());
|
||||
#else
|
||||
icalcomponent *subcomp = icalcomponent_get_first_component(icomp,
|
||||
getCompType());
|
||||
#endif
|
||||
|
||||
if (!subcomp) {
|
||||
throwError(SE_HERE, "extracting event");
|
||||
}
|
||||
|
@ -573,16 +611,20 @@ EvolutionCalendarSource::InsertItemResult EvolutionCalendarSource::insertItem(co
|
|||
// Remove LAST-MODIFIED: the Evolution Exchange Connector does not
|
||||
// properly update this property if it is already present in the
|
||||
// incoming data.
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
e_cal_util_component_remove_property_by_kind(subcomp, I_CAL_LASTMODIFIED_PROPERTY, TRUE);
|
||||
#else
|
||||
icalproperty *modprop;
|
||||
while ((modprop = icalcomponent_get_first_property(subcomp, ICAL_LASTMODIFIED_PROPERTY)) != NULL) {
|
||||
while ((modprop = icalcomponent_get_first_property(subcomp, ICAL_LASTMODIFIED_PROPERTY)) != nullptr) {
|
||||
icalcomponent_remove_property(subcomp, modprop);
|
||||
icalproperty_free(modprop);
|
||||
modprop = NULL;
|
||||
modprop = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!update) {
|
||||
ItemID id = getItemID(subcomp);
|
||||
const char *uid = NULL;
|
||||
const char *uid = nullptr;
|
||||
|
||||
// Trying to add a normal event which already exists leads to a
|
||||
// gerror->domain == E_CALENDAR_ERROR
|
||||
|
@ -628,8 +670,11 @@ EvolutionCalendarSource::InsertItemResult EvolutionCalendarSource::insertItem(co
|
|||
// creating new objects works for normal events and detached occurrences alike
|
||||
if (
|
||||
#ifdef USE_EDS_CLIENT
|
||||
e_cal_client_create_object_sync(m_calendar, subcomp, (gchar **)&uid,
|
||||
NULL, gerror)
|
||||
e_cal_client_create_object_sync(m_calendar, subcomp,
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
E_CAL_OPERATION_FLAG_NONE,
|
||||
#endif
|
||||
(gchar **)&uid, nullptr, gerror)
|
||||
#else
|
||||
e_cal_create_object(m_calendar, subcomp, (gchar **)&uid, gerror)
|
||||
#endif
|
||||
|
@ -650,12 +695,20 @@ EvolutionCalendarSource::InsertItemResult EvolutionCalendarSource::insertItem(co
|
|||
|
||||
// Recreate any children removed earlier: when we get here,
|
||||
// the parent exists and we must update it.
|
||||
BOOST_FOREACH(boost::shared_ptr< eptr<icalcomponent> > &icalcomp, children) {
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
for (std::shared_ptr< eptr<ICalComponent> > &icalcomp: children) {
|
||||
#else
|
||||
for (std::shared_ptr< eptr<icalcomponent> > &icalcomp: children) {
|
||||
#endif
|
||||
if (
|
||||
#ifdef USE_EDS_CLIENT
|
||||
!e_cal_client_modify_object_sync(m_calendar, *icalcomp,
|
||||
CALOBJ_MOD_THIS, NULL,
|
||||
gerror)
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
E_CAL_OBJ_MOD_THIS, E_CAL_OPERATION_FLAG_NONE,
|
||||
#else
|
||||
CALOBJ_MOD_THIS,
|
||||
#endif
|
||||
nullptr, gerror)
|
||||
#else
|
||||
!e_cal_modify_object(m_calendar, *icalcomp,
|
||||
CALOBJ_MOD_THIS,
|
||||
|
@ -679,13 +732,33 @@ EvolutionCalendarSource::InsertItemResult EvolutionCalendarSource::insertItem(co
|
|||
// RECURRENCE-ID
|
||||
if (update) {
|
||||
if (!id.m_uid.empty()) {
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
i_cal_component_set_uid(subcomp, id.m_uid.c_str());
|
||||
#else
|
||||
icalcomponent_set_uid(subcomp, id.m_uid.c_str());
|
||||
#endif
|
||||
}
|
||||
if (!id.m_rid.empty()) {
|
||||
// Reconstructing the RECURRENCE-ID is non-trivial,
|
||||
// because our luid only contains the date-time, but
|
||||
// not the time zone. Only do the work if the event
|
||||
// really doesn't have a RECURRENCE-ID.
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
ICalTime *rid;
|
||||
rid = i_cal_component_get_recurrenceid(subcomp);
|
||||
if (!rid || i_cal_time_is_null_time(rid)) {
|
||||
// Preserve the original RECURRENCE-ID, including
|
||||
// timezone, no matter what the update contains
|
||||
// (might have wrong timezone or UTC).
|
||||
eptr<ICalComponent> orig(retrieveItem(id));
|
||||
ICalProperty *orig_rid = i_cal_component_get_first_property(orig, I_CAL_RECURRENCEID_PROPERTY);
|
||||
if (orig_rid) {
|
||||
i_cal_component_take_property(subcomp, i_cal_property_clone(orig_rid));
|
||||
}
|
||||
g_clear_object(&orig_rid);
|
||||
}
|
||||
g_clear_object(&rid);
|
||||
#else
|
||||
struct icaltimetype rid;
|
||||
rid = icalcomponent_get_recurrenceid(subcomp);
|
||||
if (icaltime_is_null_time(rid)) {
|
||||
|
@ -698,6 +771,7 @@ EvolutionCalendarSource::InsertItemResult EvolutionCalendarSource::insertItem(co
|
|||
icalcomponent_add_property(subcomp, icalproperty_new_clone(orig_rid));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -708,9 +782,9 @@ EvolutionCalendarSource::InsertItemResult EvolutionCalendarSource::insertItem(co
|
|||
// Therefore we have to use CALOBJ_MOD_ALL, but that removes
|
||||
// children.
|
||||
bool hasChildren = false;
|
||||
LUIDs::const_iterator it = m_allLUIDs.find(id.m_uid);
|
||||
auto it = m_allLUIDs.find(id.m_uid);
|
||||
if (it != m_allLUIDs.end()) {
|
||||
BOOST_FOREACH(const string &rid, it->second) {
|
||||
for (const string &rid: it->second) {
|
||||
if (!rid.empty()) {
|
||||
hasChildren = true;
|
||||
break;
|
||||
|
@ -725,11 +799,14 @@ EvolutionCalendarSource::InsertItemResult EvolutionCalendarSource::insertItem(co
|
|||
ICalComps_t children = removeEvents(id.m_uid, true);
|
||||
|
||||
// Parent is gone, too, and needs to be recreated.
|
||||
const char *uid = NULL;
|
||||
const char *uid = nullptr;
|
||||
if (
|
||||
#ifdef USE_EDS_CLIENT
|
||||
!e_cal_client_create_object_sync(m_calendar, subcomp, (char **)&uid,
|
||||
NULL, gerror)
|
||||
!e_cal_client_create_object_sync(m_calendar, subcomp,
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
E_CAL_OPERATION_FLAG_NONE,
|
||||
#endif
|
||||
(char **)&uid, nullptr, gerror)
|
||||
#else
|
||||
!e_cal_create_object(m_calendar, subcomp, (char **)&uid, gerror)
|
||||
#endif
|
||||
|
@ -742,12 +819,20 @@ EvolutionCalendarSource::InsertItemResult EvolutionCalendarSource::insertItem(co
|
|||
|
||||
// Recreate any children removed earlier: when we get here,
|
||||
// the parent exists and we must update it.
|
||||
BOOST_FOREACH(boost::shared_ptr< eptr<icalcomponent> > &icalcomp, children) {
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
for (std::shared_ptr< eptr<ICalComponent> > &icalcomp: children) {
|
||||
#else
|
||||
for (std::shared_ptr< eptr<icalcomponent> > &icalcomp: children) {
|
||||
#endif
|
||||
if (
|
||||
#ifdef USE_EDS_CLIENT
|
||||
!e_cal_client_modify_object_sync(m_calendar, *icalcomp,
|
||||
CALOBJ_MOD_THIS, NULL,
|
||||
gerror)
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
E_CAL_OBJ_MOD_THIS, E_CAL_OPERATION_FLAG_NONE,
|
||||
#else
|
||||
CALOBJ_MOD_THIS,
|
||||
#endif
|
||||
nullptr, gerror)
|
||||
#else
|
||||
!e_cal_modify_object(m_calendar, *icalcomp,
|
||||
CALOBJ_MOD_THIS,
|
||||
|
@ -762,8 +847,12 @@ EvolutionCalendarSource::InsertItemResult EvolutionCalendarSource::insertItem(co
|
|||
if (
|
||||
#ifdef USE_EDS_CLIENT
|
||||
!e_cal_client_modify_object_sync(m_calendar, subcomp,
|
||||
CALOBJ_MOD_ALL, NULL,
|
||||
gerror)
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
E_CAL_OBJ_MOD_ALL, E_CAL_OPERATION_FLAG_NONE,
|
||||
#else
|
||||
CALOBJ_MOD_ALL,
|
||||
#endif
|
||||
nullptr, gerror)
|
||||
#else
|
||||
!e_cal_modify_object(m_calendar, subcomp,
|
||||
CALOBJ_MOD_ALL,
|
||||
|
@ -778,8 +867,12 @@ EvolutionCalendarSource::InsertItemResult EvolutionCalendarSource::insertItem(co
|
|||
if (
|
||||
#ifdef USE_EDS_CLIENT
|
||||
!e_cal_client_modify_object_sync(m_calendar, subcomp,
|
||||
CALOBJ_MOD_THIS, NULL,
|
||||
gerror)
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
E_CAL_OBJ_MOD_THIS, E_CAL_OPERATION_FLAG_NONE,
|
||||
#else
|
||||
CALOBJ_MOD_THIS,
|
||||
#endif
|
||||
nullptr, gerror)
|
||||
#else
|
||||
!e_cal_modify_object(m_calendar, subcomp,
|
||||
CALOBJ_MOD_THIS,
|
||||
|
@ -795,6 +888,11 @@ EvolutionCalendarSource::InsertItemResult EvolutionCalendarSource::insertItem(co
|
|||
modTime = getItemModTime(newid);
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
// TODO: this object leaks when an exception is thrown. Store in smart pointer.
|
||||
g_clear_object(&subcomp);
|
||||
#endif
|
||||
|
||||
return InsertItemResult(newluid, modTime, state);
|
||||
}
|
||||
|
||||
|
@ -802,16 +900,28 @@ EvolutionCalendarSource::ICalComps_t EvolutionCalendarSource::removeEvents(const
|
|||
{
|
||||
ICalComps_t events;
|
||||
|
||||
LUIDs::const_iterator it = m_allLUIDs.find(uid);
|
||||
auto it = m_allLUIDs.find(uid);
|
||||
if (it != m_allLUIDs.end()) {
|
||||
BOOST_FOREACH(const string &rid, it->second) {
|
||||
for (const string &rid: it->second) {
|
||||
ItemID id(uid, rid);
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
ICalComponent *icomp = retrieveItem(id);
|
||||
#else
|
||||
icalcomponent *icomp = retrieveItem(id);
|
||||
#endif
|
||||
if (icomp) {
|
||||
if (id.m_rid.empty() && returnOnlyChildren) {
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
g_clear_object(&icomp);
|
||||
#else
|
||||
icalcomponent_free(icomp);
|
||||
#endif
|
||||
} else {
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
events.push_back(ICalComps_t::value_type(new eptr<ICalComponent>(icomp)));
|
||||
#else
|
||||
events.push_back(ICalComps_t::value_type(new eptr<icalcomponent>(icomp)));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -821,9 +931,13 @@ EvolutionCalendarSource::ICalComps_t EvolutionCalendarSource::removeEvents(const
|
|||
GErrorCXX gerror;
|
||||
if (!uid.empty() && // e_cal_client_remove_object_sync() in EDS 3.8 aborts the process for empty UID, other versions cannot succeed, so skip the call.
|
||||
#ifdef USE_EDS_CLIENT
|
||||
!e_cal_client_remove_object_sync(m_calendar,
|
||||
uid.c_str(), NULL, CALOBJ_MOD_ALL,
|
||||
NULL, gerror)
|
||||
!e_cal_client_remove_object_sync(m_calendar, uid.c_str(), nullptr,
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
E_CAL_OBJ_MOD_ALL, E_CAL_OPERATION_FLAG_NONE,
|
||||
#else
|
||||
CALOBJ_MOD_ALL,
|
||||
#endif
|
||||
nullptr, gerror)
|
||||
|
||||
#else
|
||||
!e_cal_remove_object(m_calendar,
|
||||
|
@ -862,14 +976,21 @@ void EvolutionCalendarSource::removeItem(const string &luid)
|
|||
|
||||
// recreate children
|
||||
bool first = true;
|
||||
BOOST_FOREACH(boost::shared_ptr< eptr<icalcomponent> > &icalcomp, children) {
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
for (std::shared_ptr< eptr<ICalComponent> > &icalcomp: children) {
|
||||
#else
|
||||
for (std::shared_ptr< eptr<icalcomponent> > &icalcomp: children) {
|
||||
#endif
|
||||
if (first) {
|
||||
char *uid;
|
||||
|
||||
if (
|
||||
#ifdef USE_EDS_CLIENT
|
||||
!e_cal_client_create_object_sync(m_calendar, *icalcomp, &uid,
|
||||
NULL, gerror)
|
||||
!e_cal_client_create_object_sync(m_calendar, *icalcomp,
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
E_CAL_OPERATION_FLAG_NONE,
|
||||
#endif
|
||||
&uid, nullptr, gerror)
|
||||
#else
|
||||
!e_cal_create_object(m_calendar, *icalcomp, &uid, gerror)
|
||||
#endif
|
||||
|
@ -884,8 +1005,12 @@ void EvolutionCalendarSource::removeItem(const string &luid)
|
|||
if (
|
||||
#ifdef USE_EDS_CLIENT
|
||||
!e_cal_client_modify_object_sync(m_calendar, *icalcomp,
|
||||
CALOBJ_MOD_THIS, NULL,
|
||||
gerror)
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
E_CAL_OBJ_MOD_THIS, E_CAL_OPERATION_FLAG_NONE,
|
||||
#else
|
||||
CALOBJ_MOD_THIS,
|
||||
#endif
|
||||
nullptr, gerror)
|
||||
#else
|
||||
!e_cal_modify_object(m_calendar, *icalcomp,
|
||||
CALOBJ_MOD_THIS,
|
||||
|
@ -900,15 +1025,24 @@ void EvolutionCalendarSource::removeItem(const string &luid)
|
|||
// workaround for EDS 2.32 API semantic: succeeds even if
|
||||
// detached recurrence doesn't exist and adds EXDATE,
|
||||
// therefore we have to check for existence first
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
eptr<ICalComponent> item(retrieveItem(id));
|
||||
#else
|
||||
eptr<icalcomponent> item(retrieveItem(id));
|
||||
#endif
|
||||
gboolean success = !item ? false :
|
||||
#ifdef USE_EDS_CLIENT
|
||||
// TODO: is this necessary?
|
||||
e_cal_client_remove_object_sync(m_calendar,
|
||||
id.m_uid.c_str(),
|
||||
id.m_rid.c_str(),
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
E_CAL_OBJ_MOD_ONLY_THIS,
|
||||
E_CAL_OPERATION_FLAG_NONE,
|
||||
#else
|
||||
CALOBJ_MOD_ONLY_THIS,
|
||||
NULL,
|
||||
#endif
|
||||
nullptr,
|
||||
gerror)
|
||||
#else
|
||||
e_cal_remove_object_with_mod(m_calendar,
|
||||
|
@ -951,23 +1085,31 @@ void EvolutionCalendarSource::removeItem(const string &luid)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
ICalComponent *EvolutionCalendarSource::retrieveItem(const ItemID &id)
|
||||
#else
|
||||
icalcomponent *EvolutionCalendarSource::retrieveItem(const ItemID &id)
|
||||
#endif
|
||||
{
|
||||
GErrorCXX gerror;
|
||||
icalcomponent *comp = NULL;
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
ICalComponent *comp = nullptr;
|
||||
#else
|
||||
icalcomponent *comp = nullptr;
|
||||
#endif
|
||||
|
||||
if (
|
||||
#ifdef USE_EDS_CLIENT
|
||||
!e_cal_client_get_object_sync(m_calendar,
|
||||
id.m_uid.c_str(),
|
||||
!id.m_rid.empty() ? id.m_rid.c_str() : NULL,
|
||||
!id.m_rid.empty() ? id.m_rid.c_str() : nullptr,
|
||||
&comp,
|
||||
NULL,
|
||||
nullptr,
|
||||
gerror)
|
||||
#else
|
||||
!e_cal_get_object(m_calendar,
|
||||
id.m_uid.c_str(),
|
||||
!id.m_rid.empty() ? id.m_rid.c_str() : NULL,
|
||||
!id.m_rid.empty() ? id.m_rid.c_str() : nullptr,
|
||||
&comp,
|
||||
gerror)
|
||||
#endif
|
||||
|
@ -981,7 +1123,11 @@ icalcomponent *EvolutionCalendarSource::retrieveItem(const ItemID &id)
|
|||
if (!comp) {
|
||||
throwError(SE_HERE, string("retrieving item: ") + id.getLUID());
|
||||
}
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
eptr<ICalComponent> ptr(comp);
|
||||
#else
|
||||
eptr<icalcomponent> ptr(comp);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* EDS bug: if a parent doesn't exist while a child does, and we ask
|
||||
|
@ -989,8 +1135,15 @@ icalcomponent *EvolutionCalendarSource::retrieveItem(const ItemID &id)
|
|||
* turn it into a "not found" error.
|
||||
*/
|
||||
if (id.m_rid.empty()) {
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
ICalTime *rid = i_cal_component_get_recurrenceid(comp);
|
||||
if (!rid || i_cal_time_is_null_time(rid)) {
|
||||
g_clear_object(&rid);
|
||||
} else {
|
||||
#else
|
||||
struct icaltimetype rid = icalcomponent_get_recurrenceid(comp);
|
||||
if (!icaltime_is_null_time(rid)) {
|
||||
#endif
|
||||
throwError(SE_HERE, string("retrieving item: got child instead of parent: ") + id.m_uid);
|
||||
}
|
||||
}
|
||||
|
@ -1000,7 +1153,11 @@ icalcomponent *EvolutionCalendarSource::retrieveItem(const ItemID &id)
|
|||
|
||||
string EvolutionCalendarSource::retrieveItemAsString(const ItemID &id)
|
||||
{
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
eptr<ICalComponent> comp(retrieveItem(id));
|
||||
#else
|
||||
eptr<icalcomponent> comp(retrieveItem(id));
|
||||
#endif
|
||||
eptr<char> icalstr;
|
||||
|
||||
#ifdef USE_EDS_CLIENT
|
||||
|
@ -1015,6 +1172,15 @@ string EvolutionCalendarSource::retrieveItemAsString(const ItemID &id)
|
|||
// definition. Evolution GUI ignores the TZID and interprets
|
||||
// the times as local time. Do the same when exporting the
|
||||
// event by removing the bogus TZID.
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
ICalProperty *prop;
|
||||
for (prop = i_cal_component_get_first_property (comp, I_CAL_ANY_PROPERTY);
|
||||
prop;
|
||||
g_object_unref(prop), prop = i_cal_component_get_next_property (comp, I_CAL_ANY_PROPERTY)) {
|
||||
// removes only the *first* TZID - but there shouldn't be more than one
|
||||
i_cal_property_remove_parameter_by_kind(prop, I_CAL_TZID_PARAMETER);
|
||||
}
|
||||
#else
|
||||
icalproperty *prop = icalcomponent_get_first_property (comp,
|
||||
ICAL_ANY_PROPERTY);
|
||||
|
||||
|
@ -1024,6 +1190,7 @@ string EvolutionCalendarSource::retrieveItemAsString(const ItemID &id)
|
|||
prop = icalcomponent_get_next_property (comp,
|
||||
ICAL_ANY_PROPERTY);
|
||||
}
|
||||
#endif
|
||||
|
||||
// now try again
|
||||
#ifdef USE_EDS_CLIENT
|
||||
|
@ -1075,16 +1242,28 @@ string EvolutionCalendarSource::retrieveItemAsString(const ItemID &id)
|
|||
std::string EvolutionCalendarSource::getDescription(const string &luid)
|
||||
{
|
||||
try {
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
eptr<ICalComponent> comp(retrieveItem(ItemID(luid)));
|
||||
#else
|
||||
eptr<icalcomponent> comp(retrieveItem(ItemID(luid)));
|
||||
#endif
|
||||
std::string descr;
|
||||
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
const char *summary = i_cal_component_get_summary(comp);
|
||||
#else
|
||||
const char *summary = icalcomponent_get_summary(comp);
|
||||
#endif
|
||||
if (summary && summary[0]) {
|
||||
descr += summary;
|
||||
}
|
||||
|
||||
if (m_type == EVOLUTION_CAL_SOURCE_TYPE_EVENTS) {
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
const char *location = i_cal_component_get_location(comp);
|
||||
#else
|
||||
const char *location = icalcomponent_get_location(comp);
|
||||
#endif
|
||||
if (location && location[0]) {
|
||||
if (!descr.empty()) {
|
||||
descr += ", ";
|
||||
|
@ -1096,9 +1275,17 @@ std::string EvolutionCalendarSource::getDescription(const string &luid)
|
|||
if (m_type == EVOLUTION_CAL_SOURCE_TYPE_MEMOS &&
|
||||
descr.empty()) {
|
||||
// fallback to first line of body text
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
ICalProperty *desc = i_cal_component_get_first_property(comp, I_CAL_DESCRIPTION_PROPERTY);
|
||||
#else
|
||||
icalproperty *desc = icalcomponent_get_first_property(comp, ICAL_DESCRIPTION_PROPERTY);
|
||||
#endif
|
||||
if (desc) {
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
const char *text = i_cal_property_get_description(desc);
|
||||
#else
|
||||
const char *text = icalproperty_get_description(desc);
|
||||
#endif
|
||||
if (text) {
|
||||
const char *eol = strchr(text, '\n');
|
||||
if (eol) {
|
||||
|
@ -1107,6 +1294,9 @@ std::string EvolutionCalendarSource::getDescription(const string &luid)
|
|||
descr = text;
|
||||
}
|
||||
}
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
g_object_unref(desc);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1144,7 +1334,11 @@ EvolutionCalendarSource::ItemID::ItemID(const string &luid)
|
|||
|
||||
EvolutionCalendarSource::ItemID EvolutionCalendarSource::getItemID(ECalComponent *ecomp)
|
||||
{
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
ICalComponent *icomp = e_cal_component_get_icalcomponent(ecomp);
|
||||
#else
|
||||
icalcomponent *icomp = e_cal_component_get_icalcomponent(ecomp);
|
||||
#endif
|
||||
if (!icomp) {
|
||||
SE_THROW("internal error in getItemID(): ECalComponent without icalcomp");
|
||||
}
|
||||
|
@ -1162,15 +1356,38 @@ EvolutionCalendarSource::ItemID EvolutionCalendarSource::getItemID(icalcomponent
|
|||
icalTime2Str(rid));
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
EvolutionCalendarSource::ItemID EvolutionCalendarSource::getItemID(ICalComponent *icomp)
|
||||
{
|
||||
icalcomponent *native_icomp;
|
||||
|
||||
native_icomp = static_cast<icalcomponent *>(i_cal_object_get_native(I_CAL_OBJECT (icomp)));
|
||||
if (!native_icomp) {
|
||||
SE_THROW("internal error in getItemID(): ICalComponent without native icalcomp");
|
||||
}
|
||||
return getItemID(native_icomp);
|
||||
}
|
||||
#endif
|
||||
|
||||
string EvolutionCalendarSource::getItemModTime(ECalComponent *ecomp)
|
||||
{
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
ICalTime *modTime;
|
||||
modTime = e_cal_component_get_last_modified(ecomp);
|
||||
eptr<ICalTime, ICalTime, UnrefFree<ICalTime> > modTimePtr(modTime);
|
||||
#else
|
||||
struct icaltimetype *modTime;
|
||||
e_cal_component_get_last_modified(ecomp, &modTime);
|
||||
eptr<struct icaltimetype, struct icaltimetype, UnrefFree<struct icaltimetype> > modTimePtr(modTime);
|
||||
#endif
|
||||
if (!modTimePtr) {
|
||||
return "";
|
||||
} else {
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
return icalTime2Str(modTimePtr.get());
|
||||
#else
|
||||
return icalTime2Str(*modTimePtr.get());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1179,7 +1396,11 @@ string EvolutionCalendarSource::getItemModTime(const ItemID &id)
|
|||
if (!needChanges()) {
|
||||
return "";
|
||||
}
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
eptr<ICalComponent> icomp(retrieveItem(id));
|
||||
#else
|
||||
eptr<icalcomponent> icomp(retrieveItem(id));
|
||||
#endif
|
||||
return getItemModTime(icomp);
|
||||
}
|
||||
|
||||
|
@ -1194,6 +1415,15 @@ string EvolutionCalendarSource::getItemModTime(icalcomponent *icomp)
|
|||
return icalTime2Str(modTime);
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
string EvolutionCalendarSource::getItemModTime(ICalComponent *icomp)
|
||||
{
|
||||
icalcomponent *native_icomp = static_cast<icalcomponent *>(i_cal_object_get_native(I_CAL_OBJECT (icomp)));
|
||||
|
||||
return getItemModTime(native_icomp);
|
||||
}
|
||||
#endif
|
||||
|
||||
string EvolutionCalendarSource::icalTime2Str(const icaltimetype &tt)
|
||||
{
|
||||
static const struct icaltimetype null = { 0 };
|
||||
|
@ -1208,6 +1438,21 @@ string EvolutionCalendarSource::icalTime2Str(const icaltimetype &tt)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
string EvolutionCalendarSource::icalTime2Str(const ICalTime *tt)
|
||||
{
|
||||
if (tt || !i_cal_time_is_valid_time (tt) || i_cal_time_is_null_time (tt)) {
|
||||
return "";
|
||||
} else {
|
||||
eptr<char> timestr(i_cal_time_as_ical_string(tt));
|
||||
if (!timestr) {
|
||||
SE_THROW("cannot convert to time string");
|
||||
}
|
||||
return timestr.get();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
SE_END_CXX
|
||||
|
||||
#endif /* ENABLE_ECAL */
|
||||
|
|
|
@ -134,6 +134,9 @@ class EvolutionCalendarSource : public EvolutionSyncSource,
|
|||
*/
|
||||
static ItemID getItemID(ECalComponent *ecomp);
|
||||
static ItemID getItemID(icalcomponent *icomp);
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
static ItemID getItemID(ICalComponent *icomp);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Extract modification string from calendar item.
|
||||
|
@ -141,6 +144,9 @@ class EvolutionCalendarSource : public EvolutionSyncSource,
|
|||
*/
|
||||
static string getItemModTime(ECalComponent *ecomp);
|
||||
static string getItemModTime(icalcomponent *icomp);
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
static string getItemModTime(ICalComponent *icomp);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
//
|
||||
|
@ -182,8 +188,8 @@ class EvolutionCalendarSource : public EvolutionSyncSource,
|
|||
m_type == EVOLUTION_CAL_SOURCE_TYPE_EVENTS ? e_source_registry_ref_builtin_calendar :
|
||||
m_type == EVOLUTION_CAL_SOURCE_TYPE_TASKS ? e_source_registry_ref_builtin_task_list :
|
||||
m_type == EVOLUTION_CAL_SOURCE_TYPE_MEMOS ? e_source_registry_ref_builtin_memo_list :
|
||||
NULL;
|
||||
return ESourceCXX(ref ? ref(EDSRegistryLoader::getESourceRegistry()) : NULL, TRANSFER_REF);
|
||||
nullptr;
|
||||
return ESourceCXX(ref ? ref(EDSRegistryLoader::getESourceRegistry()) : nullptr, TRANSFER_REF);
|
||||
}
|
||||
#else
|
||||
ECalSourceType sourceType() const {
|
||||
|
@ -196,18 +202,30 @@ class EvolutionCalendarSource : public EvolutionSyncSource,
|
|||
*
|
||||
* caller has to free result
|
||||
*/
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
ICalComponent *retrieveItem(const ItemID &id);
|
||||
#else
|
||||
icalcomponent *retrieveItem(const ItemID &id);
|
||||
#endif
|
||||
|
||||
/** retrieve the item with the given luid as VCALENDAR string - may throw exception */
|
||||
string retrieveItemAsString(const ItemID &id);
|
||||
|
||||
|
||||
/** returns the type which the ical library uses for our components */
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
ICalComponentKind getCompType() {
|
||||
return m_type == EVOLUTION_CAL_SOURCE_TYPE_EVENTS ? I_CAL_VEVENT_COMPONENT :
|
||||
m_type == EVOLUTION_CAL_SOURCE_TYPE_MEMOS ? I_CAL_VJOURNAL_COMPONENT :
|
||||
I_CAL_VTODO_COMPONENT;
|
||||
}
|
||||
#else
|
||||
icalcomponent_kind getCompType() {
|
||||
return m_type == EVOLUTION_CAL_SOURCE_TYPE_EVENTS ? ICAL_VEVENT_COMPONENT :
|
||||
m_type == EVOLUTION_CAL_SOURCE_TYPE_MEMOS ? ICAL_VJOURNAL_COMPONENT :
|
||||
ICAL_VTODO_COMPONENT;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef USE_EDS_CLIENT
|
||||
/** ECalAuthFunc which calls the authenticate() methods */
|
||||
|
@ -239,6 +257,9 @@ class EvolutionCalendarSource : public EvolutionSyncSource,
|
|||
* Convert to string in canonical representation.
|
||||
*/
|
||||
static string icalTime2Str(const struct icaltimetype &tt);
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
static string icalTime2Str(const ICalTime *tt);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* A set of all existing objects. Initialized in the last call to
|
||||
|
@ -263,7 +284,11 @@ class EvolutionCalendarSource : public EvolutionSyncSource,
|
|||
* will destroy the smart pointer, which then calls
|
||||
* icalcomponent_free().
|
||||
*/
|
||||
typedef list< boost::shared_ptr< eptr<icalcomponent> > > ICalComps_t;
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
typedef list< std::shared_ptr< eptr<ICalComponent> > > ICalComps_t;
|
||||
#else
|
||||
typedef list< std::shared_ptr< eptr<icalcomponent> > > ICalComps_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Utility function which extracts all icalcomponents with
|
||||
|
|
|
@ -27,11 +27,13 @@
|
|||
#include <syncevo/declarations.h>
|
||||
SE_BEGIN_CXX
|
||||
|
||||
static SyncSource *createSource(const SyncSourceParams ¶ms)
|
||||
static std::unique_ptr<SyncSource> createSource(const SyncSourceParams ¶ms)
|
||||
{
|
||||
SourceType sourceType = SyncSource::getSourceType(params.m_nodes);
|
||||
bool isMe;
|
||||
#ifdef ENABLE_ECAL
|
||||
const bool enabled = true;
|
||||
#endif
|
||||
|
||||
EDSAbiWrapperInit();
|
||||
|
||||
|
@ -43,9 +45,9 @@ static SyncSource *createSource(const SyncSourceParams ¶ms)
|
|||
sourceType.m_format == "text/x-vcalendar") {
|
||||
return
|
||||
#ifdef ENABLE_ECAL
|
||||
enabled ? new EvolutionCalendarSource(EVOLUTION_CAL_SOURCE_TYPE_TASKS, params) :
|
||||
enabled ? std::make_unique<EvolutionCalendarSource>(EVOLUTION_CAL_SOURCE_TYPE_TASKS, params) :
|
||||
#endif
|
||||
isMe ? RegisterSyncSource::InactiveSource(params) : NULL;
|
||||
isMe ? RegisterSyncSource::InactiveSource(params) : nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,17 +56,17 @@ static SyncSource *createSource(const SyncSourceParams ¶ms)
|
|||
if (sourceType.m_format == "" || sourceType.m_format == "text/plain") {
|
||||
return
|
||||
#ifdef ENABLE_ECAL
|
||||
enabled ? new EvolutionMemoSource(params) :
|
||||
enabled ? std::make_unique<EvolutionMemoSource>(params) :
|
||||
#endif
|
||||
isMe ? RegisterSyncSource::InactiveSource(params) : NULL;
|
||||
isMe ? RegisterSyncSource::InactiveSource(params) : nullptr;
|
||||
} else if (sourceType.m_format == "text/calendar") {
|
||||
return
|
||||
#ifdef ENABLE_ECAL
|
||||
enabled ? new EvolutionCalendarSource(EVOLUTION_CAL_SOURCE_TYPE_MEMOS, params) :
|
||||
enabled ? std::make_unique<EvolutionCalendarSource>(EVOLUTION_CAL_SOURCE_TYPE_MEMOS, params) :
|
||||
#endif
|
||||
isMe ? RegisterSyncSource::InactiveSource(params) : NULL;
|
||||
isMe ? RegisterSyncSource::InactiveSource(params) : nullptr;
|
||||
} else {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,15 +78,15 @@ static SyncSource *createSource(const SyncSourceParams ¶ms)
|
|||
sourceType.m_format == "text/x-vcalendar") {
|
||||
return
|
||||
#ifdef ENABLE_ECAL
|
||||
enabled ? new EvolutionCalendarSource(EVOLUTION_CAL_SOURCE_TYPE_EVENTS, params) :
|
||||
enabled ? std::make_unique<EvolutionCalendarSource>(EVOLUTION_CAL_SOURCE_TYPE_EVENTS, params) :
|
||||
#endif
|
||||
isMe ? RegisterSyncSource::InactiveSource(params) : NULL;
|
||||
isMe ? RegisterSyncSource::InactiveSource(params) : nullptr;
|
||||
} else {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static RegisterSyncSource registerMe("Evolution Calendar/Task List/Memos",
|
||||
|
@ -124,44 +126,44 @@ class EvolutionCalendarTest : public CppUnit::TestFixture {
|
|||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
protected:
|
||||
static string addItem(boost::shared_ptr<TestingSyncSource> source,
|
||||
static string addItem(TestingSyncSource &source,
|
||||
string &data) {
|
||||
SyncSourceRaw::InsertItemResult res = source->insertItemRaw("", data);
|
||||
SyncSourceRaw::InsertItemResult res = source.insertItemRaw("", data);
|
||||
return res.m_luid;
|
||||
}
|
||||
|
||||
void testInstantiate() {
|
||||
boost::shared_ptr<TestingSyncSource> source;
|
||||
source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "calendar", true));
|
||||
source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "evolution-calendar", true));
|
||||
source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "Evolution Calendar:text/calendar", true));
|
||||
std::unique_ptr<TestingSyncSource> source;
|
||||
source = SyncSource::createTestingSource("calendar", "calendar", true);
|
||||
source = SyncSource::createTestingSource("calendar", "evolution-calendar", true);
|
||||
source = SyncSource::createTestingSource("calendar", "Evolution Calendar:text/calendar", true);
|
||||
|
||||
source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "tasks", true));
|
||||
source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "evolution-tasks", true));
|
||||
source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "Evolution Tasks", true));
|
||||
source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "Evolution Task List:text/calendar", true));
|
||||
source = SyncSource::createTestingSource("calendar", "tasks", true);
|
||||
source = SyncSource::createTestingSource("calendar", "evolution-tasks", true);
|
||||
source = SyncSource::createTestingSource("calendar", "Evolution Tasks", true);
|
||||
source = SyncSource::createTestingSource("calendar", "Evolution Task List:text/calendar", true);
|
||||
|
||||
source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "memos", true));
|
||||
source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "evolution-memos", true));
|
||||
source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "Evolution Memos:text/plain", true));
|
||||
source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "Evolution Memos:text/calendar", true));
|
||||
source = SyncSource::createTestingSource("calendar", "memos", true);
|
||||
source = SyncSource::createTestingSource("calendar", "evolution-memos", true);
|
||||
source = SyncSource::createTestingSource("calendar", "Evolution Memos:text/plain", true);
|
||||
source = SyncSource::createTestingSource("calendar", "Evolution Memos:text/calendar", true);
|
||||
}
|
||||
|
||||
void testOpenDefaultCalendar() {
|
||||
boost::shared_ptr<TestingSyncSource> source;
|
||||
source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "evolution-calendar", true, NULL));
|
||||
std::unique_ptr<TestingSyncSource> source;
|
||||
source = SyncSource::createTestingSource("calendar", "evolution-calendar", true, nullptr);
|
||||
CPPUNIT_ASSERT_NO_THROW(source->open());
|
||||
}
|
||||
|
||||
void testOpenDefaultTodo() {
|
||||
boost::shared_ptr<TestingSyncSource> source;
|
||||
source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "evolution-tasks", true, NULL));
|
||||
std::unique_ptr<TestingSyncSource> source;
|
||||
source = SyncSource::createTestingSource("calendar", "evolution-tasks", true, nullptr);
|
||||
CPPUNIT_ASSERT_NO_THROW(source->open());
|
||||
}
|
||||
|
||||
void testOpenDefaultMemo() {
|
||||
boost::shared_ptr<TestingSyncSource> source;
|
||||
source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "evolution-memos", true, NULL));
|
||||
std::unique_ptr<TestingSyncSource> source;
|
||||
source = SyncSource::createTestingSource("calendar", "evolution-memos", true, nullptr);
|
||||
CPPUNIT_ASSERT_NO_THROW(source->open());
|
||||
}
|
||||
|
||||
|
@ -171,8 +173,8 @@ protected:
|
|||
prefix = "SyncEvolution_Test_";
|
||||
}
|
||||
|
||||
boost::shared_ptr<TestingSyncSource> source;
|
||||
source.reset((TestingSyncSource *)SyncSource::createTestingSource("eds_event", "evolution-calendar", true, prefix));
|
||||
std::unique_ptr<TestingSyncSource> source;
|
||||
source = SyncSource::createTestingSource("eds_event", "evolution-calendar", true, prefix);
|
||||
CPPUNIT_ASSERT_NO_THROW(source->open());
|
||||
|
||||
string newyork =
|
||||
|
@ -212,7 +214,7 @@ protected:
|
|||
"END:VCALENDAR\n";
|
||||
|
||||
string luid;
|
||||
CPPUNIT_ASSERT_NO_THROW(luid = addItem(source, newyork));
|
||||
CPPUNIT_ASSERT_NO_THROW(luid = addItem(*source, newyork));
|
||||
|
||||
string newyork_suffix = newyork;
|
||||
boost::replace_first(newyork_suffix,
|
||||
|
@ -221,7 +223,7 @@ protected:
|
|||
boost::replace_all(newyork_suffix,
|
||||
"TZID:America/New_York",
|
||||
"TZID://FOOBAR/America/New_York-SUFFIX");
|
||||
CPPUNIT_ASSERT_NO_THROW(luid = addItem(source, newyork_suffix));
|
||||
CPPUNIT_ASSERT_NO_THROW(luid = addItem(*source, newyork_suffix));
|
||||
|
||||
|
||||
string notimezone =
|
||||
|
@ -242,7 +244,7 @@ protected:
|
|||
"LAST-MODIFIED:20060416T205301Z\n"
|
||||
"END:VEVENT\n"
|
||||
"END:VCALENDAR\n";
|
||||
CPPUNIT_ASSERT_NO_THROW(luid = addItem(source, notimezone));
|
||||
CPPUNIT_ASSERT_NO_THROW(luid = addItem(*source, notimezone));
|
||||
|
||||
// fake VTIMEZONE where daylight saving starts on first Sunday in March
|
||||
string fake_march =
|
||||
|
@ -279,7 +281,7 @@ protected:
|
|||
"LAST-MODIFIED:20060416T205301Z\n"
|
||||
"END:VEVENT\n"
|
||||
"END:VCALENDAR\n";
|
||||
CPPUNIT_ASSERT_NO_THROW(luid = addItem(source, fake_march));
|
||||
CPPUNIT_ASSERT_NO_THROW(luid = addItem(*source, fake_march));
|
||||
|
||||
string fake_may = fake_march;
|
||||
boost::replace_first(fake_may,
|
||||
|
@ -294,10 +296,10 @@ protected:
|
|||
boost::replace_first(fake_may,
|
||||
"TZNAME:EST MARCH",
|
||||
"TZNAME:EST MAY");
|
||||
CPPUNIT_ASSERT_NO_THROW(luid = addItem(source, fake_may));
|
||||
CPPUNIT_ASSERT_NO_THROW(luid = addItem(*source, fake_may));
|
||||
|
||||
// insert again, shouldn't re-add timezone
|
||||
CPPUNIT_ASSERT_NO_THROW(luid = addItem(source, fake_may));
|
||||
CPPUNIT_ASSERT_NO_THROW(luid = addItem(*source, fake_may));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include <map>
|
||||
#include <sstream>
|
||||
#include <list>
|
||||
using namespace std;
|
||||
|
||||
#include "config.h"
|
||||
#include "EvolutionSyncSource.h"
|
||||
|
@ -41,8 +40,6 @@ using namespace std;
|
|||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/algorithm/string/join.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/lambda/lambda.hpp>
|
||||
|
||||
#include <syncevo/declarations.h>
|
||||
|
||||
|
@ -121,8 +118,8 @@ EvolutionSyncSource::Databases EvolutionContactSource::getDatabases()
|
|||
E_SOURCE_EXTENSION_ADDRESS_BOOK,
|
||||
e_source_registry_ref_default_address_book);
|
||||
#else
|
||||
ESourceList *sources = NULL;
|
||||
if (!e_book_get_addressbooks(&sources, NULL)) {
|
||||
ESourceList *sources = nullptr;
|
||||
if (!e_book_get_addressbooks(&sources, nullptr)) {
|
||||
Exception::throwError(SE_HERE, "unable to access address books");
|
||||
}
|
||||
|
||||
|
@ -290,7 +287,7 @@ bool EvolutionContactSource::isEmpty()
|
|||
#ifdef USE_EDS_CLIENT
|
||||
class EBookClientViewSyncHandler {
|
||||
public:
|
||||
typedef boost::function<void (const GSList *list)> Process_t;
|
||||
typedef std::function<void (const GSList *list)> Process_t;
|
||||
|
||||
EBookClientViewSyncHandler(const EBookClientViewCXX &view,
|
||||
const Process_t &process) :
|
||||
|
@ -300,12 +297,12 @@ class EBookClientViewSyncHandler {
|
|||
|
||||
bool process(GErrorCXX &gerror) {
|
||||
// Listen for view signals
|
||||
m_view.connectSignal<void (EBookClientView *ebookview,
|
||||
const GSList *contacts)>("objects-added",
|
||||
boost::bind(m_process, _2));
|
||||
m_view.connectSignal<void (EBookClientView *ebookview,
|
||||
const GError *error)>("complete",
|
||||
boost::bind(&EBookClientViewSyncHandler::completed, this, _2));
|
||||
m_view.connectSignal<EBookClientView *,
|
||||
const GSList *>()("objects-added",
|
||||
[this] (EBookClientView *, const GSList *list) { m_process(list); } );
|
||||
m_view.connectSignal<EBookClientView *,
|
||||
const GError *>()("complete",
|
||||
[this] (EBookClientView *, const GError *gerror) { completed(gerror); });
|
||||
|
||||
// Start the view
|
||||
e_book_client_view_start (m_view, m_error);
|
||||
|
@ -316,7 +313,7 @@ class EBookClientViewSyncHandler {
|
|||
|
||||
// Async -> Sync
|
||||
m_loop.run();
|
||||
e_book_client_view_stop (m_view, NULL);
|
||||
e_book_client_view_stop (m_view, nullptr);
|
||||
|
||||
if (m_error) {
|
||||
std::swap(gerror, m_error);
|
||||
|
@ -337,39 +334,12 @@ class EBookClientViewSyncHandler {
|
|||
|
||||
private:
|
||||
// Process list callback
|
||||
boost::function<void (const GSList *list)> m_process;
|
||||
std::function<void (const GSList *list)> m_process;
|
||||
// View watched
|
||||
EBookClientViewCXX m_view;
|
||||
// Possible error while watching the view
|
||||
GErrorCXX m_error;
|
||||
};
|
||||
|
||||
static void list_revisions(const GSList *contacts, EvolutionContactSource::RevisionMap_t *revisions)
|
||||
{
|
||||
const GSList *l;
|
||||
|
||||
for (l = contacts; l; l = l->next) {
|
||||
EContact *contact = E_CONTACT(l->data);
|
||||
if (!contact) {
|
||||
SE_THROW("contact entry without data");
|
||||
}
|
||||
pair<string, string> revmapping;
|
||||
const char *uid = (const char *)e_contact_get_const(contact,
|
||||
E_CONTACT_UID);
|
||||
if (!uid || !uid[0]) {
|
||||
SE_THROW("contact entry without UID");
|
||||
}
|
||||
revmapping.first = uid;
|
||||
const char *rev = (const char *)e_contact_get_const(contact,
|
||||
E_CONTACT_REV);
|
||||
if (!rev || !rev[0]) {
|
||||
SE_THROW(string("contact entry without REV: ") + revmapping.first);
|
||||
}
|
||||
revmapping.second = rev;
|
||||
revisions->insert(revmapping);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void EvolutionContactSource::listAllItems(RevisionMap_t &revisions)
|
||||
|
@ -387,7 +357,7 @@ void EvolutionContactSource::listAllItems(RevisionMap_t &revisions)
|
|||
sexp = buffer;
|
||||
}
|
||||
|
||||
if (!e_book_client_get_view_sync(m_addressbook, sexp, &view, NULL, gerror)) {
|
||||
if (!e_book_client_get_view_sync(m_addressbook, sexp, &view, nullptr, gerror)) {
|
||||
throwError(SE_HERE, "getting the view" , gerror);
|
||||
}
|
||||
EBookClientViewCXX viewPtr = EBookClientViewCXX::steal(view);
|
||||
|
@ -402,7 +372,28 @@ void EvolutionContactSource::listAllItems(RevisionMap_t &revisions)
|
|||
gerror.clear();
|
||||
}
|
||||
|
||||
EBookClientViewSyncHandler handler(viewPtr, boost::bind(list_revisions, _1, &revisions));
|
||||
auto process = [&revisions] (const GSList *contacts) {
|
||||
const GSList *l;
|
||||
|
||||
for (l = contacts; l; l = l->next) {
|
||||
EContact *contact = E_CONTACT(l->data);
|
||||
if (!contact) {
|
||||
SE_THROW("contact entry without data");
|
||||
}
|
||||
const char *uid = (const char *)e_contact_get_const(contact,
|
||||
E_CONTACT_UID);
|
||||
if (!uid || !uid[0]) {
|
||||
SE_THROW("contact entry without UID");
|
||||
}
|
||||
const char *rev = (const char *)e_contact_get_const(contact,
|
||||
E_CONTACT_REV);
|
||||
if (!rev || !rev[0]) {
|
||||
SE_THROW(string("contact entry without REV: ") + uid);
|
||||
}
|
||||
revisions[uid] = rev;
|
||||
}
|
||||
};
|
||||
EBookClientViewSyncHandler handler(viewPtr, process);
|
||||
if (!handler.process(gerror)) {
|
||||
throwError(SE_HERE, "watching view", gerror);
|
||||
}
|
||||
|
@ -456,7 +447,7 @@ string EvolutionContactSource::getRevision(const string &luid)
|
|||
!e_book_client_get_contact_sync(m_addressbook,
|
||||
luid.c_str(),
|
||||
&contact,
|
||||
NULL,
|
||||
nullptr,
|
||||
gerror)
|
||||
#else
|
||||
!e_book_get_contact(m_addressbook,
|
||||
|
@ -528,7 +519,7 @@ void EvolutionContactSource::getReadAheadOrder(ReadAheadOrder &order,
|
|||
luids = m_nextLUIDs;
|
||||
}
|
||||
|
||||
void EvolutionContactSource::checkCacheForError(boost::shared_ptr<ContactCache> &cache)
|
||||
void EvolutionContactSource::checkCacheForError(std::shared_ptr<ContactCache> &cache)
|
||||
{
|
||||
if (cache->m_gerror) {
|
||||
GErrorCXX gerror;
|
||||
|
@ -544,10 +535,10 @@ void EvolutionContactSource::invalidateCachedContact(const std::string &luid)
|
|||
invalidateCachedContact(m_contactCacheNext, luid);
|
||||
}
|
||||
|
||||
void EvolutionContactSource::invalidateCachedContact(boost::shared_ptr<ContactCache> &cache, const std::string &luid)
|
||||
void EvolutionContactSource::invalidateCachedContact(std::shared_ptr<ContactCache> &cache, const std::string &luid)
|
||||
{
|
||||
if (cache) {
|
||||
ContactCache::iterator it = cache->find(luid);
|
||||
auto it = cache->find(luid);
|
||||
if (it != cache->end()) {
|
||||
SE_LOG_DEBUG(getDisplayName(), "reading: remove contact %s from cache because of remove or update", luid.c_str());
|
||||
// If we happen to read that contact (unlikely), it'll be
|
||||
|
@ -591,7 +582,7 @@ bool EvolutionContactSource::getContact(const string &luid, EContact **contact,
|
|||
return e_book_client_get_contact_sync(m_addressbook,
|
||||
luid.c_str(),
|
||||
contact,
|
||||
NULL,
|
||||
nullptr,
|
||||
gerror);
|
||||
} else {
|
||||
return getContactFromCache(luid, contact, gerror);
|
||||
|
@ -600,7 +591,7 @@ bool EvolutionContactSource::getContact(const string &luid, EContact **contact,
|
|||
|
||||
bool EvolutionContactSource::getContactFromCache(const string &luid, EContact **contact, GErrorCXX &gerror)
|
||||
{
|
||||
*contact = NULL;
|
||||
*contact = nullptr;
|
||||
|
||||
// Use ContactCache.
|
||||
if (m_contactCache) {
|
||||
|
@ -609,7 +600,7 @@ bool EvolutionContactSource::getContactFromCache(const string &luid, EContact **
|
|||
checkCacheForError(m_contactCache);
|
||||
|
||||
// Does the cache cover our item?
|
||||
ContactCache::const_iterator it = m_contactCache->find(luid);
|
||||
auto it = m_contactCache->find(luid);
|
||||
if (it == m_contactCache->end()) {
|
||||
if (m_contactCacheNext) {
|
||||
SE_LOG_DEBUG(getDisplayName(), "reading: not in cache, try cache %s",
|
||||
|
@ -628,7 +619,7 @@ bool EvolutionContactSource::getContactFromCache(const string &luid, EContact **
|
|||
SE_LOG_DEBUG(getDisplayName(), "reading: in %s cache", m_contactCache->m_running ? "running" : "loaded");
|
||||
if (m_contactCache->m_running) {
|
||||
m_cacheStalls++;
|
||||
GRunWhile(boost::lambda::var(m_contactCache->m_running));
|
||||
GRunWhile([this] () { return this->m_contactCache->m_running; });
|
||||
}
|
||||
// Problem?
|
||||
checkCacheForError(m_contactCache);
|
||||
|
@ -673,7 +664,7 @@ static int MaxBatchSize()
|
|||
return maxBatchSize;
|
||||
}
|
||||
|
||||
boost::shared_ptr<ContactCache> EvolutionContactSource::startReading(const std::string &luid, ReadingMode mode)
|
||||
std::shared_ptr<ContactCache> EvolutionContactSource::startReading(const std::string &luid, ReadingMode mode)
|
||||
{
|
||||
SE_LOG_DEBUG(getDisplayName(), "reading: %s contact %s",
|
||||
mode == START ? "must read" :
|
||||
|
@ -695,7 +686,7 @@ boost::shared_ptr<ContactCache> EvolutionContactSource::startReading(const std::
|
|||
const Items_t &items = getAllItems();
|
||||
const Items_t &newItems = getNewItems();
|
||||
const Items_t &updatedItems = getUpdatedItems();
|
||||
Items_t::const_iterator it = items.find(luid);
|
||||
auto it = items.find(luid);
|
||||
|
||||
// Always read the requested item, even if not found in item list?
|
||||
if (mode == START) {
|
||||
|
@ -727,7 +718,7 @@ boost::shared_ptr<ContactCache> EvolutionContactSource::startReading(const std::
|
|||
break;
|
||||
}
|
||||
case READ_SELECTED_ITEMS: {
|
||||
ReadAheadItems::const_iterator it = boost::find(std::make_pair(m_nextLUIDs.begin(), m_nextLUIDs.end()), luid);
|
||||
auto it = boost::find(std::make_pair(m_nextLUIDs.begin(), m_nextLUIDs.end()), luid);
|
||||
// Always read the requested item, even if not found in item list?
|
||||
if (mode == START) {
|
||||
uids[0] = &luid;
|
||||
|
@ -767,10 +758,10 @@ boost::shared_ptr<ContactCache> EvolutionContactSource::startReading(const std::
|
|||
m_readAheadOrder = READ_NONE;
|
||||
}
|
||||
|
||||
boost::shared_ptr<ContactCache> cache;
|
||||
std::shared_ptr<ContactCache> cache;
|
||||
if (size) {
|
||||
// Prepare parameter for EDS C call. Ownership of query instances is in uidQueries array.
|
||||
boost::scoped_array<EBookQuery *> queries(new EBookQuery *[size]);
|
||||
auto queries = std::make_unique<EBookQuery *[]>(size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
// This shouldn't compile because we don't specify how ownership is handled.
|
||||
// The reset() method always bumps the ref count, which is not what we want here!
|
||||
|
@ -787,52 +778,45 @@ boost::shared_ptr<ContactCache> EvolutionContactSource::startReading(const std::
|
|||
cache->m_running = true;
|
||||
cache->m_name = StringPrintf("%s-%s (%d)", uids[0]->c_str(), uids[size - 1]->c_str(), size);
|
||||
cache->m_lastLUID = *uids[size - 1];
|
||||
BOOST_FOREACH (const std::string *uid, std::make_pair(uids.begin(), uids.begin() + size)) {
|
||||
for (const std::string *uid: boost::make_iterator_range(uids.begin(), uids.begin() + size)) {
|
||||
(*cache)[*uid] = EContactCXX();
|
||||
}
|
||||
m_contactsFromDB += size;
|
||||
m_contactQueries++;
|
||||
SYNCEVO_GLIB_CALL_ASYNC(e_book_client_get_contacts,
|
||||
boost::bind(&EvolutionContactSource::completedRead,
|
||||
this,
|
||||
boost::weak_ptr<ContactCache>(cache),
|
||||
_1, _2, _3),
|
||||
m_addressbook, sexp, NULL);
|
||||
auto process = [this, cachePtr=std::weak_ptr<ContactCache>(cache)] (gboolean success, GSList *contactsPtr, const GError *gerror) noexcept {
|
||||
try {
|
||||
using ContactListCXX = GListCXX< EContact, GSList, GObjectDestructor<EContact> >;
|
||||
ContactListCXX contacts(contactsPtr); // transfers ownership
|
||||
std::shared_ptr<ContactCache> cache = cachePtr.lock();
|
||||
if (!cache) {
|
||||
SE_LOG_DEBUG(getDisplayName(), "reading: contact read finished, results no longer needed: %s", gerror ? gerror->message : "<<successful>>");
|
||||
return;
|
||||
}
|
||||
|
||||
SE_LOG_DEBUG(getDisplayName(), "reading: contact read %s finished: %s",
|
||||
cache->m_name.c_str(),
|
||||
gerror ? gerror->message : "<<successful>>");
|
||||
if (success) {
|
||||
for (EContact *contact: contacts) {
|
||||
const char *uid = (const char *)e_contact_get_const(contact, E_CONTACT_UID);
|
||||
SE_LOG_DEBUG(getDisplayName(), "reading: contact read %s got %s", cache->m_name.c_str(), uid);
|
||||
(*cache)[uid] = EContactCXX(contact, ADD_REF);
|
||||
}
|
||||
} else {
|
||||
cache->m_gerror = gerror;
|
||||
}
|
||||
cache->m_running = false;
|
||||
} catch (...) {
|
||||
Exception::handle(HANDLE_EXCEPTION_FATAL);
|
||||
}
|
||||
};
|
||||
SYNCEVO_GLIB_CALL_ASYNC(e_book_client_get_contacts, process,
|
||||
m_addressbook, sexp, nullptr);
|
||||
SE_LOG_DEBUG(getDisplayName(), "reading: started contact read %s", cache->m_name.c_str());
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
|
||||
typedef GListCXX< EContact, GSList, GObjectDestructor<EContact> > ContactListCXX;
|
||||
|
||||
void EvolutionContactSource::completedRead(const boost::weak_ptr<ContactCache> &cachePtr, gboolean success, GSList *contactsPtr, const GError *gerror) throw()
|
||||
{
|
||||
try {
|
||||
ContactListCXX contacts(contactsPtr); // transfers ownership
|
||||
boost::shared_ptr<ContactCache> cache = cachePtr.lock();
|
||||
if (!cache) {
|
||||
SE_LOG_DEBUG(getDisplayName(), "reading: contact read finished, results no longer needed: %s", gerror ? gerror->message : "<<successful>>");
|
||||
return;
|
||||
}
|
||||
|
||||
SE_LOG_DEBUG(getDisplayName(), "reading: contact read %s finished: %s",
|
||||
cache->m_name.c_str(),
|
||||
gerror ? gerror->message : "<<successful>>");
|
||||
if (success) {
|
||||
BOOST_FOREACH (EContact *contact, contacts) {
|
||||
const char *uid = (const char *)e_contact_get_const(contact, E_CONTACT_UID);
|
||||
SE_LOG_DEBUG(getDisplayName(), "reading: contact read %s got %s", cache->m_name.c_str(), uid);
|
||||
(*cache)[uid] = EContactCXX(contact, ADD_REF);
|
||||
}
|
||||
} else {
|
||||
cache->m_gerror = gerror;
|
||||
}
|
||||
cache->m_running = false;
|
||||
} catch (...) {
|
||||
Exception::handle(HANDLE_EXCEPTION_FATAL);
|
||||
}
|
||||
}
|
||||
|
||||
void EvolutionContactSource::logCacheStats(Logger::Level level)
|
||||
{
|
||||
SE_LOG(getDisplayName(), level,
|
||||
|
@ -873,7 +857,7 @@ void EvolutionContactSource::readItem(const string &luid, std::string &item, boo
|
|||
// Inline PHOTO data if exporting, leave VALUE=uri references unchanged
|
||||
// when processing inside engine (will be inlined by engine as needed).
|
||||
// The function for doing the inlining was added in EDS 3.4.
|
||||
// In compatibility mode, we must check the function pointer for non-NULL.
|
||||
// In compatibility mode, we must check the function pointer for non-nullptr.
|
||||
// In direct call mode, the existence check is done by configure.
|
||||
if (raw) {
|
||||
#if defined(HAVE_E_CONTACT_INLINE_LOCAL_PHOTOS)
|
||||
|
@ -893,11 +877,11 @@ void EvolutionContactSource::readItem(const string &luid, std::string &item, boo
|
|||
}
|
||||
|
||||
#ifdef USE_EDS_CLIENT
|
||||
TrackingSyncSource::InsertItemResult EvolutionContactSource::checkBatchedInsert(const boost::shared_ptr<Pending> &pending)
|
||||
TrackingSyncSource::InsertItemResult EvolutionContactSource::checkBatchedInsert(const std::shared_ptr<Pending> &pending)
|
||||
{
|
||||
SE_LOG_DEBUG(pending->m_name, "checking operation: %s", pending->m_status == MODIFYING ? "waiting" : "inserted");
|
||||
if (pending->m_status == MODIFYING) {
|
||||
return TrackingSyncSource::InsertItemResult(boost::bind(&EvolutionContactSource::checkBatchedInsert, this, pending));
|
||||
return TrackingSyncSource::InsertItemResult([this, pending] () { return checkBatchedInsert(pending); });
|
||||
}
|
||||
if (pending->m_gerror) {
|
||||
pending->m_gerror.throwError(SE_HERE, pending->m_name);
|
||||
|
@ -906,70 +890,6 @@ TrackingSyncSource::InsertItemResult EvolutionContactSource::checkBatchedInsert(
|
|||
return TrackingSyncSource::InsertItemResult(pending->m_uid, newrev, ITEM_OKAY);
|
||||
}
|
||||
|
||||
void EvolutionContactSource::completedAdd(const boost::shared_ptr<PendingContainer_t> &batched, gboolean success, GSList *uids, const GError *gerror) throw()
|
||||
{
|
||||
try {
|
||||
// The destructor ensures that the pending operations complete
|
||||
// before destructing the instance, so our "this" pointer is
|
||||
// always valid here.
|
||||
SE_LOG_DEBUG(getDisplayName(), "batch add of %d contacts completed", (int)batched->size());
|
||||
m_numRunningOperations--;
|
||||
PendingContainer_t::iterator it = (*batched).begin();
|
||||
GSList *uid = uids;
|
||||
while (it != (*batched).end() && uid) {
|
||||
SE_LOG_DEBUG((*it)->m_name, "completed: %s",
|
||||
success ? "<<successfully>>" :
|
||||
gerror ? gerror->message :
|
||||
"<<unknown failure>>");
|
||||
if (success) {
|
||||
(*it)->m_uid = static_cast<gchar *>(uid->data);
|
||||
// Get revision when engine checks the item.
|
||||
(*it)->m_status = REVISION;
|
||||
} else {
|
||||
(*it)->m_status = DONE;
|
||||
(*it)->m_gerror = gerror;
|
||||
}
|
||||
++it;
|
||||
uid = uid->next;
|
||||
}
|
||||
|
||||
while (it != (*batched).end()) {
|
||||
// Should never happen.
|
||||
SE_LOG_DEBUG((*it)->m_name, "completed: missing uid?!");
|
||||
(*it)->m_status = DONE;
|
||||
++it;
|
||||
}
|
||||
|
||||
g_slist_free_full(uids, g_free);
|
||||
} catch (...) {
|
||||
Exception::handle(HANDLE_EXCEPTION_FATAL);
|
||||
}
|
||||
}
|
||||
|
||||
void EvolutionContactSource::completedUpdate(const boost::shared_ptr<PendingContainer_t> &batched, gboolean success, const GError *gerror) throw()
|
||||
{
|
||||
try {
|
||||
SE_LOG_DEBUG(getDisplayName(), "batch update of %d contacts completed", (int)batched->size());
|
||||
m_numRunningOperations--;
|
||||
PendingContainer_t::iterator it = (*batched).begin();
|
||||
while (it != (*batched).end()) {
|
||||
SE_LOG_DEBUG((*it)->m_name, "completed: %s",
|
||||
success ? "<<successfully>>" :
|
||||
gerror ? gerror->message :
|
||||
"<<unknown failure>>");
|
||||
if (success) {
|
||||
(*it)->m_status = REVISION;
|
||||
} else {
|
||||
(*it)->m_status = DONE;
|
||||
(*it)->m_gerror = gerror;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
} catch (...) {
|
||||
Exception::handle(HANDLE_EXCEPTION_FATAL);
|
||||
}
|
||||
}
|
||||
|
||||
void EvolutionContactSource::flushItemChanges()
|
||||
{
|
||||
if (!m_batchedAdd.empty()) {
|
||||
|
@ -977,34 +897,94 @@ void EvolutionContactSource::flushItemChanges()
|
|||
m_numRunningOperations++;
|
||||
GListCXX<EContact, GSList> contacts;
|
||||
// Iterate backwards, push to front (cheaper for single-linked list) -> same order in the end.
|
||||
BOOST_REVERSE_FOREACH (const boost::shared_ptr<Pending> &pending, m_batchedAdd) {
|
||||
for (const auto &pending: reverse(m_batchedAdd)) {
|
||||
contacts.push_front(pending->m_contact.get());
|
||||
}
|
||||
// Transfer content without copying and then copy only the shared pointer.
|
||||
boost::shared_ptr<PendingContainer_t> batched(new PendingContainer_t);
|
||||
auto batched = std::make_shared<PendingContainer_t>();
|
||||
std::swap(*batched, m_batchedAdd);
|
||||
SYNCEVO_GLIB_CALL_ASYNC(e_book_client_add_contacts,
|
||||
boost::bind(&EvolutionContactSource::completedAdd,
|
||||
this,
|
||||
batched,
|
||||
_1, _2, _3),
|
||||
m_addressbook, contacts, NULL);
|
||||
auto process = [this, batched] (gboolean success, GSList *uids, const GError *gerror) noexcept {
|
||||
try {
|
||||
// The destructor ensures that the pending operations complete
|
||||
// before destructing the instance, so our "this" pointer is
|
||||
// always valid here.
|
||||
SE_LOG_DEBUG(getDisplayName(), "batch add of %d contacts completed", (int)batched->size());
|
||||
m_numRunningOperations--;
|
||||
auto it = (*batched).begin();
|
||||
GSList *uid = uids;
|
||||
while (it != (*batched).end() && uid) {
|
||||
SE_LOG_DEBUG((*it)->m_name, "completed: %s",
|
||||
success ? "<<successfully>>" :
|
||||
gerror ? gerror->message :
|
||||
"<<unknown failure>>");
|
||||
if (success) {
|
||||
(*it)->m_uid = static_cast<gchar *>(uid->data);
|
||||
// Get revision when engine checks the item.
|
||||
(*it)->m_status = REVISION;
|
||||
} else {
|
||||
(*it)->m_status = DONE;
|
||||
(*it)->m_gerror = gerror;
|
||||
}
|
||||
++it;
|
||||
uid = uid->next;
|
||||
}
|
||||
|
||||
while (it != (*batched).end()) {
|
||||
// Should never happen.
|
||||
SE_LOG_DEBUG((*it)->m_name, "completed: missing uid?!");
|
||||
(*it)->m_status = DONE;
|
||||
++it;
|
||||
}
|
||||
|
||||
g_slist_free_full(uids, g_free);
|
||||
} catch (...) {
|
||||
Exception::handle(HANDLE_EXCEPTION_FATAL);
|
||||
}
|
||||
};
|
||||
SYNCEVO_GLIB_CALL_ASYNC(e_book_client_add_contacts, process,
|
||||
m_addressbook, contacts,
|
||||
#ifdef HAVE_E_BOOK_OPERATION_FLAGS
|
||||
E_BOOK_OPERATION_FLAG_NONE,
|
||||
#endif
|
||||
nullptr);
|
||||
}
|
||||
if (!m_batchedUpdate.empty()) {
|
||||
SE_LOG_DEBUG(getDisplayName(), "batch update of %d contacts starting", (int)m_batchedUpdate.size());
|
||||
m_numRunningOperations++;
|
||||
GListCXX<EContact, GSList> contacts;
|
||||
BOOST_REVERSE_FOREACH (const boost::shared_ptr<Pending> &pending, m_batchedUpdate) {
|
||||
for (const auto &pending: reverse(m_batchedUpdate)) {
|
||||
contacts.push_front(pending->m_contact.get());
|
||||
}
|
||||
boost::shared_ptr<PendingContainer_t> batched(new PendingContainer_t);
|
||||
auto batched = std::make_shared<PendingContainer_t>();
|
||||
std::swap(*batched, m_batchedUpdate);
|
||||
SYNCEVO_GLIB_CALL_ASYNC(e_book_client_modify_contacts,
|
||||
boost::bind(&EvolutionContactSource::completedUpdate,
|
||||
this,
|
||||
batched,
|
||||
_1, _2),
|
||||
m_addressbook, contacts, NULL);
|
||||
auto process = [this, batched] (gboolean success, const GError *gerror) noexcept {
|
||||
try {
|
||||
SE_LOG_DEBUG(getDisplayName(), "batch update of %d contacts completed", (int)batched->size());
|
||||
m_numRunningOperations--;
|
||||
auto it = (*batched).begin();
|
||||
while (it != (*batched).end()) {
|
||||
SE_LOG_DEBUG((*it)->m_name, "completed: %s",
|
||||
success ? "<<successfully>>" :
|
||||
gerror ? gerror->message :
|
||||
"<<unknown failure>>");
|
||||
if (success) {
|
||||
(*it)->m_status = REVISION;
|
||||
} else {
|
||||
(*it)->m_status = DONE;
|
||||
(*it)->m_gerror = gerror;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
} catch (...) {
|
||||
Exception::handle(HANDLE_EXCEPTION_FATAL);
|
||||
}
|
||||
};
|
||||
SYNCEVO_GLIB_CALL_ASYNC(e_book_client_modify_contacts, process,
|
||||
m_addressbook, contacts,
|
||||
#ifdef HAVE_E_BOOK_OPERATION_FLAGS
|
||||
E_BOOK_OPERATION_FLAG_NONE,
|
||||
#endif
|
||||
nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1013,7 +993,7 @@ void EvolutionContactSource::finishItemChanges()
|
|||
if (m_numRunningOperations) {
|
||||
SE_LOG_DEBUG(getDisplayName(), "waiting for %d pending operations to complete", m_numRunningOperations.get());
|
||||
while (m_numRunningOperations) {
|
||||
g_main_context_iteration(NULL, true);
|
||||
g_main_context_iteration(nullptr, true);
|
||||
}
|
||||
SE_LOG_DEBUG(getDisplayName(), "pending operations completed");
|
||||
}
|
||||
|
@ -1028,7 +1008,7 @@ EvolutionContactSource::insertItem(const string &uid, const std::string &item, b
|
|||
if (contact) {
|
||||
e_contact_set(contact, E_CONTACT_UID,
|
||||
uid.empty() ?
|
||||
NULL :
|
||||
nullptr :
|
||||
const_cast<char *>(uid.c_str()));
|
||||
GErrorCXX gerror;
|
||||
#ifdef USE_EDS_CLIENT
|
||||
|
@ -1037,14 +1017,22 @@ EvolutionContactSource::insertItem(const string &uid, const std::string &item, b
|
|||
case SYNCHRONOUS:
|
||||
if (uid.empty()) {
|
||||
gchar* newuid;
|
||||
if (!e_book_client_add_contact_sync(m_addressbook, contact, &newuid, NULL, gerror)) {
|
||||
if (!e_book_client_add_contact_sync(m_addressbook, contact,
|
||||
#ifdef HAVE_E_BOOK_OPERATION_FLAGS
|
||||
E_BOOK_OPERATION_FLAG_NONE,
|
||||
#endif
|
||||
&newuid, nullptr, gerror)) {
|
||||
throwError(SE_HERE, "add new contact", gerror);
|
||||
}
|
||||
PlainGStr newuidPtr(newuid);
|
||||
string newrev = getRevision(newuid);
|
||||
return InsertItemResult(newuid, newrev, ITEM_OKAY);
|
||||
} else {
|
||||
if (!e_book_client_modify_contact_sync(m_addressbook, contact, NULL, gerror)) {
|
||||
if (!e_book_client_modify_contact_sync(m_addressbook, contact,
|
||||
#ifdef HAVE_E_BOOK_OPERATION_FLAGS
|
||||
E_BOOK_OPERATION_FLAG_NONE,
|
||||
#endif
|
||||
nullptr, gerror)) {
|
||||
throwError(SE_HERE, "updating contact "+ uid, gerror);
|
||||
}
|
||||
string newrev = getRevision(uid);
|
||||
|
@ -1058,7 +1046,7 @@ EvolutionContactSource::insertItem(const string &uid, const std::string &item, b
|
|||
uid.empty() ? "add" : ("insert " + uid).c_str(),
|
||||
m_asyncOpCounter++);
|
||||
SE_LOG_DEBUG(name, "queueing for batched %s", uid.empty() ? "add" : "update");
|
||||
boost::shared_ptr<Pending> pending(new Pending);
|
||||
auto pending = std::make_shared<Pending>();
|
||||
pending->m_name = name;
|
||||
pending->m_contact = contact;
|
||||
pending->m_uid = uid;
|
||||
|
@ -1069,7 +1057,7 @@ EvolutionContactSource::insertItem(const string &uid, const std::string &item, b
|
|||
}
|
||||
// SyncSource is going to live longer than Synthesis
|
||||
// engine, so using "this" is safe here.
|
||||
return InsertItemResult(boost::bind(&EvolutionContactSource::checkBatchedInsert, this, pending));
|
||||
return InsertItemResult([this, pending] () { return checkBatchedInsert(pending); });
|
||||
break;
|
||||
}
|
||||
#else
|
||||
|
@ -1102,7 +1090,11 @@ void EvolutionContactSource::removeItem(const string &uid)
|
|||
if (
|
||||
#ifdef USE_EDS_CLIENT
|
||||
(invalidateCachedContact(uid),
|
||||
!e_book_client_remove_contact_by_uid_sync(m_addressbook, uid.c_str(), NULL, gerror))
|
||||
!e_book_client_remove_contact_by_uid_sync(m_addressbook, uid.c_str(),
|
||||
#ifdef HAVE_E_BOOK_OPERATION_FLAGS
|
||||
E_BOOK_OPERATION_FLAG_NONE,
|
||||
#endif
|
||||
nullptr, gerror))
|
||||
#else
|
||||
!e_book_remove_contact(m_addressbook, uid.c_str(), gerror)
|
||||
#endif
|
||||
|
|
|
@ -137,7 +137,7 @@ class EvolutionContactSource : public EvolutionSyncSource,
|
|||
|
||||
Pending() : m_status(MODIFYING) {}
|
||||
};
|
||||
typedef std::list< boost::shared_ptr<Pending> >PendingContainer_t;
|
||||
typedef std::list< std::shared_ptr<Pending> >PendingContainer_t;
|
||||
|
||||
/**
|
||||
* Batched "contact add/update" operations.
|
||||
|
@ -148,14 +148,12 @@ class EvolutionContactSource : public EvolutionSyncSource,
|
|||
PendingContainer_t m_batchedUpdate;
|
||||
InitState<int> m_numRunningOperations;
|
||||
|
||||
InsertItemResult checkBatchedInsert(const boost::shared_ptr<Pending> &pending);
|
||||
void completedAdd(const boost::shared_ptr<PendingContainer_t> &batched, gboolean success, /* const GStringListFreeCXX &uids */ GSList *uids, const GError *gerror) throw ();
|
||||
void completedUpdate(const boost::shared_ptr<PendingContainer_t> &batched, gboolean success, const GError *gerror) throw ();
|
||||
InsertItemResult checkBatchedInsert(const std::shared_ptr<Pending> &pending);
|
||||
virtual void flushItemChanges();
|
||||
virtual void finishItemChanges();
|
||||
|
||||
// Read-ahead of item data.
|
||||
boost::shared_ptr<ContactCache> m_contactCache, m_contactCacheNext;
|
||||
std::shared_ptr<ContactCache> m_contactCache, m_contactCacheNext;
|
||||
int m_cacheMisses, m_cacheStalls;
|
||||
int m_contactReads; /**< number of readItemAsKey() calls */
|
||||
int m_contactsFromDB; /**< number of contacts requested from DB (including ones not found) */
|
||||
|
@ -164,9 +162,9 @@ class EvolutionContactSource : public EvolutionSyncSource,
|
|||
ReadAheadOrder m_readAheadOrder;
|
||||
ReadAheadItems m_nextLUIDs;
|
||||
|
||||
void checkCacheForError(boost::shared_ptr<ContactCache> &cache);
|
||||
void checkCacheForError(std::shared_ptr<ContactCache> &cache);
|
||||
void invalidateCachedContact(const std::string &luid);
|
||||
void invalidateCachedContact(boost::shared_ptr<ContactCache> &cache, const std::string &luid);
|
||||
void invalidateCachedContact(std::shared_ptr<ContactCache> &cache, const std::string &luid);
|
||||
bool getContact(const string &luid, EContact **contact, GErrorCXX &gerror);
|
||||
bool getContactFromCache(const string &luid, EContact **contact, GErrorCXX &gerror);
|
||||
enum ReadingMode
|
||||
|
@ -174,8 +172,7 @@ class EvolutionContactSource : public EvolutionSyncSource,
|
|||
START, /**< luid is needed, must be read */
|
||||
CONTINUE /**< luid is from old request, find next ones */
|
||||
};
|
||||
boost::shared_ptr<ContactCache> startReading(const std::string &luid, ReadingMode mode);
|
||||
void completedRead(const boost::weak_ptr<ContactCache> &cachePtr, gboolean success, GSList *contactsPtr, const GError *gerror) throw();
|
||||
std::shared_ptr<ContactCache> startReading(const std::string &luid, ReadingMode mode);
|
||||
void logCacheStats(Logger::Level level);
|
||||
|
||||
// Use the information provided to us to implement read-ahead efficiently.
|
||||
|
|
|
@ -24,12 +24,14 @@
|
|||
#include <syncevo/declarations.h>
|
||||
SE_BEGIN_CXX
|
||||
|
||||
static SyncSource *createSource(const SyncSourceParams ¶ms)
|
||||
static std::unique_ptr<SyncSource> createSource(const SyncSourceParams ¶ms)
|
||||
{
|
||||
SourceType sourceType = SyncSource::getSourceType(params.m_nodes);
|
||||
bool isMe = sourceType.m_backend == "Evolution Address Book";
|
||||
bool maybeMe = sourceType.m_backend == "addressbook";
|
||||
#ifdef ENABLE_EBOOK
|
||||
const bool enabled = true;
|
||||
#endif
|
||||
|
||||
EDSAbiWrapperInit();
|
||||
|
||||
|
@ -37,18 +39,18 @@ static SyncSource *createSource(const SyncSourceParams ¶ms)
|
|||
if (sourceType.m_format == "text/x-vcard") {
|
||||
return
|
||||
#ifdef ENABLE_EBOOK
|
||||
enabled ? new EvolutionContactSource(params, EVC_FORMAT_VCARD_21) :
|
||||
enabled ? std::make_unique<EvolutionContactSource>(params, EVC_FORMAT_VCARD_21) :
|
||||
#endif
|
||||
isMe ? RegisterSyncSource::InactiveSource(params) : NULL;
|
||||
isMe ? RegisterSyncSource::InactiveSource(params) : nullptr;
|
||||
} else if (sourceType.m_format == "" || sourceType.m_format == "text/vcard") {
|
||||
return
|
||||
#ifdef ENABLE_EBOOK
|
||||
enabled ? new EvolutionContactSource(params, EVC_FORMAT_VCARD_30) :
|
||||
enabled ? std::make_unique<EvolutionContactSource>(params, EVC_FORMAT_VCARD_30) :
|
||||
#endif
|
||||
isMe ? RegisterSyncSource::InactiveSource(params) : NULL;
|
||||
isMe ? RegisterSyncSource::InactiveSource(params) : nullptr;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static RegisterSyncSource registerMe("Evolution Address Book",
|
||||
|
@ -77,13 +79,13 @@ class EvolutionContactTest : public CppUnit::TestFixture {
|
|||
|
||||
protected:
|
||||
void testInstantiate() {
|
||||
boost::shared_ptr<SyncSource> source;
|
||||
source.reset(SyncSource::createTestingSource("addressbook", "addressbook", true));
|
||||
source.reset(SyncSource::createTestingSource("addressbook", "contacts", true));
|
||||
source.reset(SyncSource::createTestingSource("addressbook", "evolution-contacts", true));
|
||||
source.reset(SyncSource::createTestingSource("addressbook", "Evolution Contacts", true));
|
||||
source.reset(SyncSource::createTestingSource("addressbook", "Evolution Address Book:text/x-vcard", true));
|
||||
source.reset(SyncSource::createTestingSource("addressbook", "Evolution Address Book:text/vcard", true));
|
||||
std::unique_ptr<SyncSource> source;
|
||||
source = SyncSource::createTestingSource("addressbook", "addressbook", true);
|
||||
source = SyncSource::createTestingSource("addressbook", "contacts", true);
|
||||
source = SyncSource::createTestingSource("addressbook", "evolution-contacts", true);
|
||||
source = SyncSource::createTestingSource("addressbook", "Evolution Contacts", true);
|
||||
source = SyncSource::createTestingSource("addressbook", "Evolution Address Book:text/x-vcard", true);
|
||||
source = SyncSource::createTestingSource("addressbook", "Evolution Address Book:text/vcard", true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -93,47 +95,8 @@ protected:
|
|||
*/
|
||||
void testImport() {
|
||||
// this only tests that we can instantiate something under the type "addressbook";
|
||||
// it might not be an EvolutionContactSource
|
||||
boost::shared_ptr<EvolutionContactSource> source21(dynamic_cast<EvolutionContactSource *>(SyncSource::createTestingSource("evolutioncontactsource21", "evolution-contacts:text/x-vcard", true)));
|
||||
boost::shared_ptr<EvolutionContactSource> source30(dynamic_cast<EvolutionContactSource *>(SyncSource::createTestingSource("evolutioncontactsource30", "Evolution Address Book:text/vcard", true)));
|
||||
string parsed;
|
||||
|
||||
#if 0
|
||||
// TODO: enable testing of incoming items again. Right now preparse() doesn't
|
||||
// do anything and needs to be replaced with Synthesis mechanisms.
|
||||
|
||||
// SF bug 1796086: sync with EGW: lost or messed up telephones
|
||||
parsed = "BEGIN:VCARD\r\nVERSION:3.0\r\nTEL;CELL:cell\r\nEND:VCARD\r\n";
|
||||
CPPUNIT_ASSERT_EQUAL(parsed,
|
||||
preparse(*source21,
|
||||
"BEGIN:VCARD\nVERSION:2.1\nTEL;CELL:cell\nEND:VCARD\n",
|
||||
"text/x-vcard"));
|
||||
|
||||
parsed = "BEGIN:VCARD\r\nVERSION:3.0\r\nTEL;TYPE=CAR:car\r\nEND:VCARD\r\n";
|
||||
CPPUNIT_ASSERT_EQUAL(parsed,
|
||||
preparse(*source21,
|
||||
"BEGIN:VCARD\nVERSION:2.1\nTEL;TYPE=CAR:car\nEND:VCARD\n",
|
||||
"text/x-vcard"));
|
||||
|
||||
parsed = "BEGIN:VCARD\r\nVERSION:3.0\r\nTEL;TYPE=HOME:home\r\nEND:VCARD\r\n";
|
||||
CPPUNIT_ASSERT_EQUAL(parsed,
|
||||
preparse(*source21,
|
||||
"BEGIN:VCARD\nVERSION:2.1\nTEL:home\nEND:VCARD\n",
|
||||
"text/x-vcard"));
|
||||
|
||||
// TYPE=PARCEL not supported by Evolution, used to represent Evolutions TYPE=OTHER
|
||||
parsed = "BEGIN:VCARD\r\nVERSION:3.0\r\nTEL;TYPE=OTHER:other\r\nEND:VCARD\r\n";
|
||||
CPPUNIT_ASSERT_EQUAL(parsed,
|
||||
preparse(*source21,
|
||||
"BEGIN:VCARD\nVERSION:2.1\nTEL;TYPE=PARCEL:other\nEND:VCARD\n",
|
||||
"text/x-vcard"));
|
||||
|
||||
parsed = "BEGIN:VCARD\r\nVERSION:3.0\r\nTEL;TYPE=HOME;TYPE=VOICE:cell\r\nEND:VCARD\r\n";
|
||||
CPPUNIT_ASSERT_EQUAL(parsed,
|
||||
preparse(*source21,
|
||||
"BEGIN:VCARD\nVERSION:2.1\nTEL;TYPE=HOME,VOICE:cell\nEND:VCARD\n",
|
||||
"text/x-vcard"));
|
||||
#endif
|
||||
auto source21 = SyncSource::createTestingSource("evolutioncontactsource21", "evolution-contacts:text/x-vcard", true);
|
||||
auto source30 = SyncSource::createTestingSource("evolutioncontactsource30", "Evolution Address Book:text/vcard", true);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -41,9 +41,9 @@ void EvolutionSyncSource::getDatabasesFromRegistry(SyncSource::Databases &result
|
|||
{
|
||||
ESourceRegistryCXX registry = EDSRegistryLoader::getESourceRegistry();
|
||||
ESourceListCXX sources(e_source_registry_list_sources(registry, extension));
|
||||
ESourceCXX def(refDef ? refDef(registry) : NULL,
|
||||
ESourceCXX def(refDef ? refDef(registry) : nullptr,
|
||||
TRANSFER_REF);
|
||||
BOOST_FOREACH (ESource *source, sources) {
|
||||
for (ESource *source: sources) {
|
||||
result.push_back(Database(e_source_get_display_name(source),
|
||||
e_source_get_uid(source),
|
||||
e_source_equal(def, source)));
|
||||
|
@ -58,7 +58,7 @@ static void handleErrorCB(EClient */*client*/, const gchar *error_msg, gpointer
|
|||
|
||||
EClientCXX EvolutionSyncSource::openESource(const char *extension,
|
||||
ESource *(*refBuiltin)(ESourceRegistry *),
|
||||
const boost::function<EClient *(ESource *, GError **gerror)> &newClient)
|
||||
const std::function<EClient *(ESource *, GError **gerror)> &newClient)
|
||||
{
|
||||
EClientCXX client;
|
||||
GErrorCXX gerror;
|
||||
|
@ -66,7 +66,6 @@ EClientCXX EvolutionSyncSource::openESource(const char *extension,
|
|||
ESourceListCXX sources(e_source_registry_list_sources(registry, extension));
|
||||
string id = getDatabaseID();
|
||||
ESource *source = findSource(sources, id);
|
||||
bool created = false;
|
||||
|
||||
if (!source) {
|
||||
if (refBuiltin && (id.empty() || id == "<<system>>")) {
|
||||
|
@ -78,7 +77,6 @@ EClientCXX EvolutionSyncSource::openESource(const char *extension,
|
|||
} else {
|
||||
throwError(SE_HERE, string("database not found: '") + id + "'");
|
||||
}
|
||||
created = true;
|
||||
} else {
|
||||
client = EClientCXX::steal(newClient(source, gerror));
|
||||
}
|
||||
|
@ -95,19 +93,19 @@ EClientCXX EvolutionSyncSource::openESource(const char *extension,
|
|||
(void *)"Evolution Data Server has died unexpectedly.");
|
||||
|
||||
|
||||
int retries = 0;
|
||||
while (true) {
|
||||
// Always allow EDS to create the database. "only-if-exists =
|
||||
// true" does not make sense.
|
||||
if (!e_client_open_sync(client, false, NULL, gerror)) {
|
||||
if (gerror && g_error_matches(gerror, E_CLIENT_ERROR, E_CLIENT_ERROR_BUSY)) {
|
||||
if (!e_client_open_sync(client, false, nullptr, gerror)) {
|
||||
if (retries < 5) {
|
||||
// EDS 3.18 and 3.26 have various race conditions during startup.
|
||||
// Try a few times.
|
||||
// https://bugzilla.gnome.org/show_bug.cgi?id=791306
|
||||
SE_LOG_DEBUG(NULL, "Opening EDS source: ignoring error, trying again: %s", gerror->message);
|
||||
gerror.clear();
|
||||
sleep(1);
|
||||
} else if (created) {
|
||||
// Opening newly created address books often failed in
|
||||
// old EDS releases - try again. Probably covered by
|
||||
// more recently added E_CLIENT_ERROR_BUSY check above.
|
||||
gerror.clear();
|
||||
sleep(5);
|
||||
retries++;
|
||||
} else {
|
||||
throwError(SE_HERE, "opening database", gerror);
|
||||
}
|
||||
|
@ -155,7 +153,7 @@ SyncSource::Database EvolutionSyncSource::createDatabase(const Database &databas
|
|||
if (!g_key_file_load_from_data(keyfile, ini, len, G_KEY_FILE_NONE, gerror)) {
|
||||
gerror.throwError(SE_HERE, "parsing ESource .ini data");
|
||||
}
|
||||
PlainGStrArray keys(g_key_file_get_keys(keyfile, mainSection, NULL, gerror));
|
||||
PlainGStrArray keys(g_key_file_get_keys(keyfile, mainSection, nullptr, gerror));
|
||||
if (!keys) {
|
||||
gerror.throwError(SE_HERE, "listing keys in main section");
|
||||
}
|
||||
|
@ -168,7 +166,7 @@ SyncSource::Database EvolutionSyncSource::createDatabase(const Database &databas
|
|||
}
|
||||
g_key_file_set_string(keyfile, mainSection, "DisplayName", database.m_name.c_str());
|
||||
g_key_file_set_boolean(keyfile, mainSection, "Enabled", true);
|
||||
ini = g_key_file_to_data(keyfile, &len, NULL);
|
||||
ini = g_key_file_to_data(keyfile, &len, nullptr);
|
||||
const char *configDir = g_get_user_config_dir();
|
||||
int fd;
|
||||
std::string filename;
|
||||
|
@ -213,7 +211,7 @@ SyncSource::Database EvolutionSyncSource::createDatabase(const Database &databas
|
|||
while (!ESourceCXX(e_source_registry_ref_source(registry, uid.c_str()), TRANSFER_REF)) {
|
||||
// This will block forever if called from the non-main-thread.
|
||||
// Don't do that...
|
||||
g_main_context_iteration(NULL, true);
|
||||
g_main_context_iteration(nullptr, true);
|
||||
}
|
||||
SE_LOG_DEBUG(getDisplayName(), "ESourceRegistry has new ESource %s", uid.c_str());
|
||||
|
||||
|
@ -221,7 +219,7 @@ SyncSource::Database EvolutionSyncSource::createDatabase(const Database &databas
|
|||
// UUID. Does not work! evolution-source-registry simply overwrites the
|
||||
// file that we created earlier.
|
||||
// ESourceCXX source(e_source_new_with_uid(uid.c_str(),
|
||||
// NULL, gerror),
|
||||
// nullptr, gerror),
|
||||
// TRANSFER_REF);
|
||||
// e_source_set_display_name(source, "syncevolution-fake");
|
||||
// e_source_set_parent(source, "local-stub");
|
||||
|
@ -229,7 +227,7 @@ SyncSource::Database EvolutionSyncSource::createDatabase(const Database &databas
|
|||
// sources.push_back(source.ref()); // ESourceListCXX unrefs sources it points to
|
||||
// if (!e_source_registry_create_sources_sync(registry,
|
||||
// sources,
|
||||
// NULL,
|
||||
// nullptr,
|
||||
// gerror)) {
|
||||
// gerror.throwError(SE_HERE, StringPrintf("creating EDS database of type %s with name '%s'%s%s",
|
||||
// sourceExtension(),
|
||||
|
@ -252,7 +250,7 @@ void EvolutionSyncSource::deleteDatabase(const std::string &uri, RemoveData remo
|
|||
uri.c_str()));
|
||||
}
|
||||
GErrorCXX gerror;
|
||||
if (!e_source_remove_sync(source, NULL, gerror)) {
|
||||
if (!e_source_remove_sync(source, nullptr, gerror)) {
|
||||
throwError(SE_HERE, StringPrintf("deleting EDS database with URI '%s'", uri.c_str()),
|
||||
gerror);
|
||||
}
|
||||
|
@ -266,10 +264,10 @@ void EvolutionSyncSource::deleteDatabase(const std::string &uri, RemoveData remo
|
|||
// This is equivalent to "rm -rf $XDG_DATA_HOME/evolution/*/<uuid>".
|
||||
std::string basedir = StringPrintf("%s/evolution", g_get_user_data_dir());
|
||||
if (isDir(basedir)) {
|
||||
BOOST_FOREACH (const std::string &kind, ReadDir(basedir)) {
|
||||
for (const std::string &kind: ReadDir(basedir)) {
|
||||
std::string subdir = basedir + "/" + kind;
|
||||
if (isDir(subdir)) {
|
||||
BOOST_FOREACH (const std::string &source, ReadDir(subdir)) {
|
||||
for (const std::string &source: ReadDir(subdir)) {
|
||||
// We assume that the UUID of the database
|
||||
// consists only of characters which can be
|
||||
// used in the directory name, i.e., no
|
||||
|
@ -296,7 +294,7 @@ ESource *EvolutionSyncSource::findSource(const ESourceListCXX &list, const strin
|
|||
finalID = id;
|
||||
} else {
|
||||
// Nothing selected specifically, use the one marked as default.
|
||||
BOOST_FOREACH(const Database &db, getDatabases()) {
|
||||
for (const Database &db: getDatabases()) {
|
||||
if (db.m_isDefault) {
|
||||
finalID = db.m_uri;
|
||||
break;
|
||||
|
@ -305,7 +303,7 @@ ESource *EvolutionSyncSource::findSource(const ESourceListCXX &list, const strin
|
|||
}
|
||||
|
||||
#ifdef USE_EDS_CLIENT
|
||||
BOOST_FOREACH (ESource *source, list) {
|
||||
for (ESource *source: list) {
|
||||
bool found =
|
||||
!finalID.compare(e_source_get_display_name(source)) ||
|
||||
!finalID.compare(e_source_get_uid(source));
|
||||
|
@ -329,7 +327,7 @@ ESource *EvolutionSyncSource::findSource(const ESourceListCXX &list, const strin
|
|||
}
|
||||
}
|
||||
#endif
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void EvolutionSyncSource::throwError(const SourceLocation &where, const string &action, GErrorCXX &gerror)
|
||||
|
|
|
@ -71,7 +71,7 @@ class EvolutionSyncSource : public TrackingSyncSource
|
|||
ESource *(*getDef)(ESourceRegistry *));
|
||||
EClientCXX openESource(const char *extension,
|
||||
ESource *(*refBuiltin)(ESourceRegistry *),
|
||||
const boost::function<EClient *(ESource *, GError **gerror)> &newClient);
|
||||
const std::function<EClient *(ESource *, GError **gerror)> &newClient);
|
||||
|
||||
// Implementation of SyncSource calls which only works when using EDS Client API
|
||||
// and EDS > 3.4. Older EDS has no way of creating sources easily (or at all).
|
||||
|
@ -90,7 +90,7 @@ class EvolutionSyncSource : public TrackingSyncSource
|
|||
*
|
||||
* @param list a list previously obtained from Gnome
|
||||
* @param id a string identifying the data source: either its name or uri
|
||||
* @return pointer to source (caller owns reference) or NULL if not found
|
||||
* @return pointer to source (caller owns reference) or nullptr if not found
|
||||
*/
|
||||
ESource *findSource(const ESourceListCXX &list,
|
||||
const string &id);
|
||||
|
@ -124,7 +124,7 @@ class EvolutionAsync {
|
|||
public:
|
||||
EvolutionAsync()
|
||||
{
|
||||
m_loop = GMainLoopStealCXX(g_main_loop_new(NULL, TRUE));
|
||||
m_loop = GMainLoopStealCXX(g_main_loop_new(nullptr, TRUE));
|
||||
}
|
||||
|
||||
/** start processing events */
|
||||
|
|
|
@ -15,13 +15,23 @@ $anymissing"
|
|||
|
||||
dnl check for Evolution packages
|
||||
PKG_CHECK_MODULES(EPACKAGE, libedataserver-1.2, EDSFOUND=yes, [EDSFOUND=no])
|
||||
PKG_CHECK_MODULES(ECAL, libecal-1.2, ECALFOUND=yes, [ECALFOUND=no])
|
||||
PKG_CHECK_MODULES(ECAL, libecal-2.0, ECALFOUND=yes, [ECALFOUND=no])
|
||||
PKG_CHECK_MODULES(EBOOK, libebook-1.2, EBOOKFOUND=yes, [EBOOKFOUND=no])
|
||||
|
||||
if test "$ECALFOUND" = "yes"; then
|
||||
AC_DEFINE(HAVE_LIBECAL_2_0, 1, [libecal 2.0])
|
||||
else
|
||||
PKG_CHECK_MODULES(ECAL, libecal-1.2, ECALFOUND=yes, [ECALFOUND=no])
|
||||
fi
|
||||
|
||||
PKG_CHECK_MODULES(EBOOK_VERSION, [libebook-1.2 >= 3.3],
|
||||
[AC_DEFINE(HAVE_E_CONTACT_INLINE_LOCAL_PHOTOS, 1, [have e_contact_inline_local_photos()])],
|
||||
[true])
|
||||
|
||||
PKG_CHECK_MODULES(EBOOK_VERSION_3_33, [libebook-1.2 >= 3.33.2],
|
||||
[AC_DEFINE(HAVE_E_BOOK_OPERATION_FLAGS, 1, [have EBookOperationFlags])],
|
||||
[true])
|
||||
|
||||
SE_ARG_ENABLE_BACKEND(ebook, evolution,
|
||||
[AS_HELP_STRING([--disable-ebook],
|
||||
[disable access to Evolution addressbooks (must be used to compile without it)])],
|
||||
|
|
|
@ -414,7 +414,11 @@ gboolean e_cal_check_timezones(icalcomponent *comp,
|
|||
goto done;
|
||||
nomem:
|
||||
/* set gerror for "out of memory" if possible, otherwise abort via g_error() */
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
*error = g_error_new(E_CLIENT_ERROR, E_CLIENT_ERROR_OTHER_ERROR, "out of memory");
|
||||
#else
|
||||
*error = g_error_new(E_CALENDAR_ERROR, E_CALENDAR_STATUS_OTHER_ERROR, "out of memory");
|
||||
#endif
|
||||
if (!*error) {
|
||||
g_error("e_cal_check_timezones(): out of memory, cannot proceed - sorry!");
|
||||
}
|
||||
|
@ -451,6 +455,10 @@ icaltimezone *e_cal_tzlookup_ecal(const char *tzid,
|
|||
const void *custom,
|
||||
GError **error)
|
||||
{
|
||||
#ifdef HAVE_LIBECAL_2_0
|
||||
g_propagate_error(error, e_client_error_create(E_CLIENT_ERROR_NOT_SUPPORTED, NULL));
|
||||
return NULL;
|
||||
#else
|
||||
ECal *ecal = (ECal *)custom;
|
||||
icaltimezone *zone = NULL;
|
||||
|
||||
|
@ -470,6 +478,7 @@ icaltimezone *e_cal_tzlookup_ecal(const char *tzid,
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -137,7 +137,7 @@ void FileSyncSource::open()
|
|||
|
||||
bool FileSyncSource::isEmpty()
|
||||
{
|
||||
DIR *dir = NULL;
|
||||
DIR *dir = nullptr;
|
||||
bool empty = true;
|
||||
|
||||
try {
|
||||
|
@ -197,7 +197,7 @@ void FileSyncSource::listAllItems(RevisionMap_t &revisions)
|
|||
SE_LOG_DEBUG(getDisplayName(), "continue listing items in file source");
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const string &entry, dirContent) {
|
||||
for (const string &entry: dirContent) {
|
||||
string filename = createFilename(entry);
|
||||
string revision = getATimeString(filename);
|
||||
long entrynum = atoll(entry.c_str());
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include <syncevo/declarations.h>
|
||||
SE_BEGIN_CXX
|
||||
|
||||
static SyncSource *createSource(const SyncSourceParams ¶ms)
|
||||
static std::unique_ptr<SyncSource> createSource(const SyncSourceParams ¶ms)
|
||||
{
|
||||
SourceType sourceType = SyncSource::getSourceType(params.m_nodes);
|
||||
// The string returned by getSourceType() is always the one
|
||||
|
@ -34,7 +34,7 @@ static SyncSource *createSource(const SyncSourceParams ¶ms)
|
|||
#ifndef ENABLE_FILE
|
||||
// tell SyncEvolution if the user wanted to use a disabled sync source,
|
||||
// otherwise let it continue searching
|
||||
return isMe ? RegisterSyncSource::InactiveSource(params) : NULL;
|
||||
return isMe ? RegisterSyncSource::InactiveSource(params) : nullptr;
|
||||
#else
|
||||
// Also recognize one of the standard types?
|
||||
// Not in the FileSyncSource!
|
||||
|
@ -43,12 +43,12 @@ static SyncSource *createSource(const SyncSourceParams ¶ms)
|
|||
if (isMe || maybeMe) {
|
||||
// The FileSyncSource always needs the database format.
|
||||
if (!sourceType.m_localFormat.empty()) {
|
||||
return new FileSyncSource(params, sourceType.m_localFormat);
|
||||
return std::make_unique<FileSyncSource>(params, sourceType.m_localFormat);
|
||||
} else {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -88,10 +88,10 @@ class FileSyncSourceUnitTest : public CppUnit::TestFixture {
|
|||
|
||||
protected:
|
||||
void testInstantiate() {
|
||||
boost::shared_ptr<SyncSource> source;
|
||||
source.reset(SyncSource::createTestingSource("file", "file:text/vcard:3.0", true));
|
||||
source.reset(SyncSource::createTestingSource("file", "file:text/plain:1.0", true));
|
||||
source.reset(SyncSource::createTestingSource("file", "Files in one directory:text/x-vcard:2.1", true));
|
||||
std::unique_ptr<SyncSource> source;
|
||||
source = SyncSource::createTestingSource("file", "file:text/vcard:3.0", true);
|
||||
source = SyncSource::createTestingSource("file", "file:text/plain:1.0", true);
|
||||
source = SyncSource::createTestingSource("file", "Files in one directory:text/x-vcard:2.1", true);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -21,63 +21,26 @@
|
|||
|
||||
#ifdef USE_GNOME_KEYRING
|
||||
|
||||
extern "C" {
|
||||
#include <gnome-keyring.h>
|
||||
}
|
||||
#include <libsecret/secret.h>
|
||||
|
||||
#include "GNOMEPlatform.h"
|
||||
|
||||
#include <syncevo/Exception.h>
|
||||
#include <syncevo/UserInterface.h>
|
||||
#include <syncevo/SyncConfig.h>
|
||||
#include <syncevo/GLibSupport.h>
|
||||
|
||||
#include <syncevo/declarations.h>
|
||||
SE_BEGIN_CXX
|
||||
|
||||
// Occasionally, libgnome-keyring fails with the following error messages:
|
||||
// Gkr: received an invalid, unencryptable, or non-utf8 secret
|
||||
// Gkr: call to daemon returned an invalid response: (null).(null)
|
||||
//
|
||||
// We work around that by retrying the operation a few times, for at
|
||||
// most this period of time. Didn't really help, so disable it for now
|
||||
// by using a zero duration.
|
||||
static const double GNOMEKeyringRetryDuration = 2; // seconds
|
||||
static const double GNOMEKeyringRetryInterval = 0.1; // seconds
|
||||
|
||||
/**
|
||||
* libgnome-keyring has an internal gkr_reset_session()
|
||||
* method which gets called when the "org.freedesktop.secrets"
|
||||
* disconnects from the D-Bus session bus.
|
||||
*
|
||||
* We cannot call that method directly, but we can get it called by
|
||||
* faking the "disconnect" signal. That works because
|
||||
* on_connection_filter() in gkr-operation.c doesn't check who the
|
||||
* sender of the signal is.
|
||||
*
|
||||
* Once gkr_reset_session() got called, the next operation will
|
||||
* re-establish the connection. After the failure above, the second
|
||||
* attempt usually works.
|
||||
*
|
||||
* Any other client using libgnome-keyring will also be tricked into
|
||||
* disconnecting temporarily. That should be fine, any running
|
||||
* operation will continue to run and complete (?).
|
||||
*/
|
||||
static void FlushGNOMEKeyring()
|
||||
{
|
||||
// Invoking dbus-send is easier than writing this in C++.
|
||||
// Besides, it ensures that the signal comes from some other
|
||||
// process. Not sure whether signals are sent back to the sender.
|
||||
system("dbus-send --session --type=signal /org/freedesktop/DBus org.freedesktop.DBus.NameOwnerChanged string:'org.freedesktop.secrets' string:':9.99' string:''");
|
||||
}
|
||||
|
||||
/**
|
||||
* GNOME keyring distinguishes between empty and unset
|
||||
* password keys. This function returns NULL for an
|
||||
* password keys. This function returns nullptr for an
|
||||
* empty std::string.
|
||||
*/
|
||||
inline const char *passwdStr(const std::string &str)
|
||||
{
|
||||
return str.empty() ? NULL : str.c_str();
|
||||
return str.empty() ? nullptr : str.c_str();
|
||||
}
|
||||
|
||||
static bool UseGNOMEKeyring(const InitStateTri &keyring)
|
||||
|
@ -97,6 +60,56 @@ static bool UseGNOMEKeyring(const InitStateTri &keyring)
|
|||
return true;
|
||||
}
|
||||
|
||||
class LibSecretHash : public GHashTableCXX
|
||||
{
|
||||
std::list<std::string> m_buffer;
|
||||
|
||||
public:
|
||||
LibSecretHash(const ConfigPasswordKey &key) :
|
||||
GHashTableCXX(g_hash_table_new(g_str_hash, g_str_equal), TRANSFER_REF)
|
||||
{
|
||||
// see https://developer.gnome.org/libsecret/0.16/libsecret-SecretSchema.html#SECRET-SCHEMA-COMPAT-NETWORK:CAPS
|
||||
insert("user", key.user);
|
||||
insert("domain", key.domain);
|
||||
insert("server", key.server);
|
||||
insert("object", key.object);
|
||||
insert("protocol", key.protocol);
|
||||
insert("authtype", key.authtype);
|
||||
if (key.port) {
|
||||
std::string value = StringPrintf("%d", key.port);
|
||||
insert("port", value);
|
||||
}
|
||||
}
|
||||
|
||||
/** Keys are expected to be constants and not copied. Values are copied. */
|
||||
void insert(const char *key, const std::string &value)
|
||||
{
|
||||
if (!value.empty()) {
|
||||
m_buffer.push_back(value);
|
||||
g_hash_table_insert(get(),
|
||||
const_cast<char *>(key),
|
||||
const_cast<char *>(m_buffer.back().c_str()));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sometimes libsecret and GNOME Keyring fail to initialize
|
||||
* the encryption: https://bugzilla.gnome.org/show_bug.cgi?id=778357
|
||||
* If that happens, then trying with a new SecretService instance
|
||||
* may work.
|
||||
*
|
||||
* When libsecret detects that, we get a well-defined error.
|
||||
* When GNOME Keyring detects it, the error is less obvious.
|
||||
*/
|
||||
static bool IsSharedSecretError(const GErrorCXX &gerror)
|
||||
{
|
||||
bool result = gerror.matches(SECRET_ERROR, SECRET_ERROR_PROTOCOL) /* = "received an invalid or unencryptable secret" */ ||
|
||||
strstr(gerror->message, "The secret was transferred or encrypted in an invalid way");
|
||||
SE_LOG_DEBUG(NULL, "IsSharedSecretError: %d/%d/%s: %s", (int)gerror->domain, (int)gerror->code, gerror->message, result ? "yes" : "no");
|
||||
return result;
|
||||
}
|
||||
|
||||
bool GNOMELoadPasswordSlot(const InitStateTri &keyring,
|
||||
const std::string &passwordName,
|
||||
const std::string &descr,
|
||||
|
@ -108,46 +121,49 @@ bool GNOMELoadPasswordSlot(const InitStateTri &keyring,
|
|||
return false;
|
||||
}
|
||||
|
||||
GnomeKeyringResult result = GNOME_KEYRING_RESULT_OK;
|
||||
GList* list;
|
||||
Timespec start = Timespec::monotonic();
|
||||
double sleepSecs = 0;
|
||||
do {
|
||||
if (sleepSecs != 0) {
|
||||
SE_LOG_DEBUG(NULL, "%s: previous attempt to load password '%s' from GNOME keyring failed, will try again: %s",
|
||||
key.description.c_str(),
|
||||
key.toString().c_str(),
|
||||
gnome_keyring_result_to_message(result));
|
||||
FlushGNOMEKeyring();
|
||||
Sleep(sleepSecs);
|
||||
}
|
||||
result = gnome_keyring_find_network_password_sync(passwdStr(key.user),
|
||||
passwdStr(key.domain),
|
||||
passwdStr(key.server),
|
||||
passwdStr(key.object),
|
||||
passwdStr(key.protocol),
|
||||
passwdStr(key.authtype),
|
||||
key.port,
|
||||
&list);
|
||||
sleepSecs = GNOMEKeyringRetryInterval;
|
||||
} while (result != GNOME_KEYRING_RESULT_OK &&
|
||||
(Timespec::monotonic() - start).duration() < GNOMEKeyringRetryDuration);
|
||||
LibSecretHash hash(key);
|
||||
for (int i = 0; ; i++ ) {
|
||||
GErrorCXX gerror;
|
||||
PlainGStr result(secret_password_lookupv_sync(SECRET_SCHEMA_COMPAT_NETWORK,
|
||||
hash,
|
||||
nullptr,
|
||||
gerror));
|
||||
|
||||
// if find password stored in gnome keyring
|
||||
if(result == GNOME_KEYRING_RESULT_OK && list && list->data ) {
|
||||
GnomeKeyringNetworkPasswordData *key_data;
|
||||
key_data = (GnomeKeyringNetworkPasswordData*)list->data;
|
||||
password = std::string(key_data->password);
|
||||
gnome_keyring_network_password_list_free(list);
|
||||
SE_LOG_DEBUG(NULL, "%s: loaded password from GNOME keyring using %s",
|
||||
key.description.c_str(),
|
||||
key.toString().c_str());
|
||||
} else {
|
||||
SE_LOG_DEBUG(NULL, "password not in GNOME keyring using %s: %s",
|
||||
key.toString().c_str(),
|
||||
result == GNOME_KEYRING_RESULT_NO_MATCH ? "no match" :
|
||||
result != GNOME_KEYRING_RESULT_OK ? gnome_keyring_result_to_message(result) :
|
||||
"empty result list");
|
||||
// if find password stored in gnome keyring
|
||||
if (gerror) {
|
||||
/* It is uncertain whether we end up here at all when such
|
||||
an error occurs. Check just in case. */
|
||||
if (IsSharedSecretError(gerror) &&
|
||||
i < 3) {
|
||||
SE_LOG_DEBUG(NULL, "disconnecting secret service: %u/%d = %s", gerror->domain, gerror->code, gerror->message);
|
||||
secret_service_disconnect();
|
||||
} else {
|
||||
gerror.throwError(SE_HERE, StringPrintf("looking up password '%s'", descr.c_str()));
|
||||
}
|
||||
} else if (result.get()) {
|
||||
SE_LOG_DEBUG(NULL, "%s: loaded password from GNOME keyring using %s",
|
||||
key.description.c_str(),
|
||||
key.toString().c_str());
|
||||
password = result;
|
||||
break;
|
||||
} else {
|
||||
/*
|
||||
* There have been cases where "received an invalid or
|
||||
* unencryptable secret" was printed to the console right
|
||||
* before we end up here. Apparently the error doesn't
|
||||
* get propagated properly to us.
|
||||
*
|
||||
* To cope with that, we try to disconnect and check again.
|
||||
*/
|
||||
if (i < 3) {
|
||||
SE_LOG_DEBUG(NULL, "disconnecting secret service: password not found");
|
||||
secret_service_disconnect();
|
||||
} else {
|
||||
SE_LOG_DEBUG(NULL, "password not in GNOME keyring using %s",
|
||||
key.toString().c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -173,40 +189,38 @@ bool GNOMESavePasswordSlot(const InitStateTri &keyring,
|
|||
key.toString().c_str()));
|
||||
}
|
||||
|
||||
guint32 itemId;
|
||||
GnomeKeyringResult result = GNOME_KEYRING_RESULT_OK;
|
||||
// write password to keyring
|
||||
Timespec start = Timespec::monotonic();
|
||||
double sleepSecs = 0;
|
||||
do {
|
||||
if (sleepSecs != 0) {
|
||||
SE_LOG_DEBUG(NULL, "%s: previous attempt to save password '%s' in GNOME keyring failed, will try again: %s",
|
||||
key.description.c_str(),
|
||||
key.toString().c_str(),
|
||||
gnome_keyring_result_to_message(result));
|
||||
FlushGNOMEKeyring();
|
||||
Sleep(sleepSecs);
|
||||
}
|
||||
result = gnome_keyring_set_network_password_sync(NULL,
|
||||
passwdStr(key.user),
|
||||
passwdStr(key.domain),
|
||||
passwdStr(key.server),
|
||||
passwdStr(key.object),
|
||||
passwdStr(key.protocol),
|
||||
passwdStr(key.authtype),
|
||||
key.port,
|
||||
password.c_str(),
|
||||
&itemId);
|
||||
sleepSecs = GNOMEKeyringRetryInterval;
|
||||
} while (result != GNOME_KEYRING_RESULT_OK &&
|
||||
(Timespec::monotonic() - start).duration() < GNOMEKeyringRetryDuration);
|
||||
if (result != GNOME_KEYRING_RESULT_OK) {
|
||||
Exception::throwError(SE_HERE, StringPrintf("%s: saving password '%s' in GNOME keyring failed: %s",
|
||||
key.description.c_str(),
|
||||
key.toString().c_str(),
|
||||
gnome_keyring_result_to_message(result)));
|
||||
LibSecretHash hash(key);
|
||||
std::string label;
|
||||
if (!key.user.empty() && !key.server.empty()) {
|
||||
// This emulates the behavior of libgnomekeyring.
|
||||
label = key.user + "@" + key.server;
|
||||
} else {
|
||||
label = passwordName;
|
||||
}
|
||||
for (int i = 0; ; i++) {
|
||||
GErrorCXX gerror;
|
||||
gboolean result = secret_password_storev_sync(SECRET_SCHEMA_COMPAT_NETWORK,
|
||||
hash,
|
||||
nullptr,
|
||||
label.c_str(),
|
||||
password.c_str(),
|
||||
nullptr,
|
||||
gerror);
|
||||
if (result) {
|
||||
SE_LOG_DEBUG(NULL, "saved password in GNOME keyring using %s", key.toString().c_str());
|
||||
break;
|
||||
}
|
||||
|
||||
if (IsSharedSecretError(gerror) &&
|
||||
i < 3) {
|
||||
SE_LOG_DEBUG(NULL, "disconnecting secret service: %u/%d = %s", gerror->domain, gerror->code, gerror->message);
|
||||
secret_service_disconnect();
|
||||
} else {
|
||||
gerror.throwError(SE_HERE, StringPrintf("%s: saving password '%s' in GNOME keyring",
|
||||
key.description.c_str(),
|
||||
key.toString().c_str()));
|
||||
}
|
||||
}
|
||||
SE_LOG_DEBUG(NULL, "saved password in GNOME keyring using %s", key.toString().c_str());
|
||||
|
||||
// handled
|
||||
return true;
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
PKG_CHECK_MODULES(KEYRING, [gnome-keyring-1 >= 2.20], HAVE_KEYRING=yes, HAVE_KEYRING=no)
|
||||
# According to https://developer.gnome.org/libsecret/0.16/libsecret-Password-storage.html#secret-password-store-sync
|
||||
# the simple API was still considered unstable. All supported distros
|
||||
# now have 0.18 where the API is stable.
|
||||
PKG_CHECK_MODULES(KEYRING, [libsecret-1 >= 0.18], HAVE_KEYRING=yes, HAVE_KEYRING=no)
|
||||
AC_ARG_ENABLE(gnome-keyring,
|
||||
AS_HELP_STRING([--enable-gnome-keyring],
|
||||
[enables or disables support for the GNOME keyring; default is on if development files are available]),
|
||||
[enables or disables support for the GNOME keyring via libsecret; default is on if development files are available]),
|
||||
[enable_gnome_keyring="$enableval"
|
||||
test "$enable_gnome_keyring" = "yes" || test "$enable_gnome_keyring" = "no" || AC_MSG_ERROR([invalid value for --enable-gnome-keyring: $enable_gnome_keyring])
|
||||
test "$enable_gnome_keyring" = "no" || test "$HAVE_KEYRING" = "yes" || AC_MSG_ERROR([gnome-keyring-1 pkg >= 2.20 not found, needed for --enable-gnome-keyring])],
|
||||
test "$enable_gnome_keyring" = "no" || test "$HAVE_KEYRING" = "yes" || AC_MSG_ERROR([libsecret-1 >= 0.18 not found, needed for --enable-gnome-keyring])],
|
||||
enable_gnome_keyring="$HAVE_KEYRING")
|
||||
if test $enable_gnome_keyring = "yes"; then
|
||||
have_keyring=yes
|
||||
|
|
|
@ -36,11 +36,11 @@ public:
|
|||
" using an account created and managed with GNOME Control Center.")
|
||||
{}
|
||||
|
||||
virtual boost::shared_ptr<AuthProvider> create(const InitStateString &username,
|
||||
virtual std::shared_ptr<AuthProvider> create(const InitStateString &username,
|
||||
const InitStateString &password)
|
||||
{
|
||||
// Returning NULL if not enabled...
|
||||
boost::shared_ptr<AuthProvider> provider;
|
||||
// Returning nullptr if not enabled...
|
||||
std::shared_ptr<AuthProvider> provider;
|
||||
#ifdef USE_GOA
|
||||
provider = createGOAAuthProvider(username, password);
|
||||
#endif
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include <gdbus-cxx-bridge.h>
|
||||
|
||||
#include <boost/algorithm/string/join.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
@ -65,7 +64,7 @@ class GOAManager : private GDBusCXX::DBusRemoteObject
|
|||
Properties
|
||||
> Interfaces;
|
||||
typedef std::map<GDBusCXX::DBusObject_t, Interfaces> ManagedObjects;
|
||||
GDBusCXX::DBusClientCall1<ManagedObjects> m_getManagedObjects;
|
||||
GDBusCXX::DBusClientCall<ManagedObjects> m_getManagedObjects;
|
||||
|
||||
public:
|
||||
GOAManager(const GDBusCXX::DBusConnectionPtr &conn);
|
||||
|
@ -75,7 +74,7 @@ class GOAManager : private GDBusCXX::DBusRemoteObject
|
|||
* (the unique user visible string). The account must support OAuth2,
|
||||
* otherwise an error is thrown.
|
||||
*/
|
||||
boost::shared_ptr<GOAAccount> lookupAccount(const std::string &representationID);
|
||||
std::shared_ptr<GOAAccount> lookupAccount(const std::string &representationID);
|
||||
};
|
||||
|
||||
class GOAAccount
|
||||
|
@ -88,8 +87,8 @@ public:
|
|||
GOAAccount(const GDBusCXX::DBusConnectionPtr &conn,
|
||||
const std::string &path);
|
||||
|
||||
GDBusCXX::DBusClientCall1<int32_t> m_ensureCredentials;
|
||||
GDBusCXX::DBusClientCall1<std::string> m_getAccessToken;
|
||||
GDBusCXX::DBusClientCall<int32_t> m_ensureCredentials;
|
||||
GDBusCXX::DBusClientCall<std::string> m_getAccessToken;
|
||||
};
|
||||
|
||||
GOAManager::GOAManager(const GDBusCXX::DBusConnectionPtr &conn) :
|
||||
|
@ -98,7 +97,7 @@ GOAManager::GOAManager(const GDBusCXX::DBusConnectionPtr &conn) :
|
|||
{
|
||||
}
|
||||
|
||||
boost::shared_ptr<GOAAccount> GOAManager::lookupAccount(const std::string &username)
|
||||
std::shared_ptr<GOAAccount> GOAManager::lookupAccount(const std::string &username)
|
||||
{
|
||||
SE_LOG_DEBUG(NULL, "Looking up all accounts in GNOME Online Accounts, searching for '%s'.", username.c_str());
|
||||
ManagedObjects objects = m_getManagedObjects();
|
||||
|
@ -107,26 +106,26 @@ boost::shared_ptr<GOAAccount> GOAManager::lookupAccount(const std::string &usern
|
|||
bool unique = true;
|
||||
bool hasOAuth2 = false;
|
||||
std::vector<std::string> accounts;
|
||||
BOOST_FOREACH (const ManagedObjects::value_type &object, objects) {
|
||||
for (const auto &object: objects) {
|
||||
const GDBusCXX::DBusObject_t &path = object.first;
|
||||
const Interfaces &interfaces = object.second;
|
||||
// boost::adaptors::keys() would be nicer, but is not available on Ubuntu Lucid.
|
||||
std::list<std::string> interfaceKeys;
|
||||
BOOST_FOREACH (const Interfaces::value_type &entry, interfaces) {
|
||||
for (const auto &entry: interfaces) {
|
||||
interfaceKeys.push_back(entry.first);
|
||||
}
|
||||
SE_LOG_DEBUG(NULL, "GOA object %s implements %s", path.c_str(),
|
||||
boost::join(interfaceKeys, ", ").c_str());
|
||||
Interfaces::const_iterator it = interfaces.find(GOA_ACCOUNT_INTERFACE);
|
||||
auto it = interfaces.find(GOA_ACCOUNT_INTERFACE);
|
||||
if (it != interfaces.end()) {
|
||||
const Properties &properties = it->second;
|
||||
Properties::const_iterator id = properties.find(GOA_ACCOUNT_ID);
|
||||
Properties::const_iterator presentationID = properties.find(GOA_ACCOUNT_PRESENTATION_IDENTITY);
|
||||
auto id = properties.find(GOA_ACCOUNT_ID);
|
||||
auto presentationID = properties.find(GOA_ACCOUNT_PRESENTATION_IDENTITY);
|
||||
if (id != properties.end() &&
|
||||
presentationID != properties.end()) {
|
||||
const std::string &idStr = boost::get<std::string>(id->second);
|
||||
const std::string &presentationIDStr = boost::get<std::string>(presentationID->second);
|
||||
Properties::const_iterator provider = properties.find(GOA_ACCOUNT_PROVIDER_NAME);
|
||||
auto provider = properties.find(GOA_ACCOUNT_PROVIDER_NAME);
|
||||
std::string description = StringPrintf("%s, %s = %s",
|
||||
provider == properties.end() ? "???" : boost::get<std::string>(provider->second).c_str(),
|
||||
presentationIDStr.c_str(),
|
||||
|
@ -173,7 +172,7 @@ boost::shared_ptr<GOAAccount> GOAManager::lookupAccount(const std::string &usern
|
|||
username.c_str()));
|
||||
}
|
||||
|
||||
boost::shared_ptr<GOAAccount> account(new GOAAccount(getConnection(), accountPath));
|
||||
auto account = std::make_shared<GOAAccount>(getConnection(), accountPath);
|
||||
return account;
|
||||
}
|
||||
|
||||
|
@ -188,10 +187,10 @@ GOAAccount::GOAAccount(const GDBusCXX::DBusConnectionPtr &conn,
|
|||
|
||||
class GOAAuthProvider : public AuthProvider
|
||||
{
|
||||
boost::shared_ptr<GOAAccount> m_account;
|
||||
std::shared_ptr<GOAAccount> m_account;
|
||||
|
||||
public:
|
||||
GOAAuthProvider(const boost::shared_ptr<GOAAccount> &account) :
|
||||
GOAAuthProvider(const std::shared_ptr<GOAAccount> &account) :
|
||||
m_account(account)
|
||||
{}
|
||||
|
||||
|
@ -209,13 +208,13 @@ public:
|
|||
virtual std::string getUsername() const { return ""; }
|
||||
};
|
||||
|
||||
boost::shared_ptr<AuthProvider> createGOAAuthProvider(const InitStateString &username,
|
||||
std::shared_ptr<AuthProvider> createGOAAuthProvider(const InitStateString &username,
|
||||
const InitStateString &password)
|
||||
{
|
||||
// Because we share the connection, hopefully this won't be too expensive.
|
||||
GDBusCXX::DBusErrorCXX err;
|
||||
GDBusCXX::DBusConnectionPtr conn = dbus_get_bus_connection("SESSION",
|
||||
NULL,
|
||||
nullptr,
|
||||
false,
|
||||
&err);
|
||||
if (!conn) {
|
||||
|
@ -223,8 +222,8 @@ boost::shared_ptr<AuthProvider> createGOAAuthProvider(const InitStateString &use
|
|||
}
|
||||
|
||||
GOAManager manager(conn);
|
||||
boost::shared_ptr<GOAAccount> account = manager.lookupAccount(username);
|
||||
boost::shared_ptr<AuthProvider> provider(new GOAAuthProvider(account));
|
||||
std::shared_ptr<GOAAccount> account = manager.lookupAccount(username);
|
||||
auto provider = std::make_shared<GOAAuthProvider>(account);
|
||||
return provider;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,13 +21,13 @@
|
|||
|
||||
#include <syncevo/util.h>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <memory>
|
||||
|
||||
#include <syncevo/declarations.h>
|
||||
SE_BEGIN_CXX
|
||||
|
||||
class AuthProvider;
|
||||
boost::shared_ptr<AuthProvider> createGOAAuthProvider(const InitStateString &username,
|
||||
std::shared_ptr<AuthProvider> createGOAAuthProvider(const InitStateString &username,
|
||||
const InitStateString &password);
|
||||
|
||||
SE_END_CXX
|
||||
|
|
|
@ -216,7 +216,7 @@ KCalExtendedSource::KCalExtendedSource(const SyncSourceParams ¶ms, Type type
|
|||
break;
|
||||
}
|
||||
|
||||
m_data = NULL;
|
||||
m_data = nullptr;
|
||||
m_type = type;
|
||||
m_delete_run = 0;
|
||||
m_insert_run = 0;
|
||||
|
@ -311,8 +311,8 @@ void KCalExtendedSource::open()
|
|||
mKCal::Notebook::List notebookList = m_data->m_storage->notebooks();
|
||||
mKCal::Notebook::List::Iterator it;
|
||||
|
||||
for ( it = notebookList.begin(); it != notebookList.end(); ++it ) {
|
||||
if ( name == (*it)->name() ) {
|
||||
for (auto notebook: notebookList) {
|
||||
if ( name == notebook->name() ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -388,19 +388,19 @@ KCalExtendedSource::Databases KCalExtendedSource::getDatabases()
|
|||
}
|
||||
mKCal::Notebook::List notebookList = m_data->m_storage->notebooks();
|
||||
mKCal::Notebook::List::Iterator it;
|
||||
for ( it = notebookList.begin(); it != notebookList.end(); ++it ) {
|
||||
for (auto notebook: notebookList) {
|
||||
#ifdef ENABLE_MAEMO
|
||||
string name = (*it)->name().toStdString();
|
||||
string uid = (*it)->uid().toStdString();
|
||||
string name = notebook->name().toStdString();
|
||||
string uid = notebook->uid().toStdString();
|
||||
// For notes, we need a different default database:
|
||||
// Notes (uid:66666666-7777-8888-9999-000000000000)
|
||||
bool isDefault = (m_type != Journal) ?
|
||||
(*it)->isDefault() :
|
||||
notebook->isDefault() :
|
||||
(uid == "66666666-7777-8888-9999-000000000000");
|
||||
result.push_back(Database( name, "uid:" + uid, isDefault ));
|
||||
#else
|
||||
bool isDefault = (*it)->isDefault();
|
||||
result.push_back(Database( (*it)->name().toStdString(),
|
||||
bool isDefault = notebook->isDefault();
|
||||
result.push_back(Database( notebook->name().toStdString(),
|
||||
(m_data->m_storage).staticCast<mKCal::SqliteStorage>()->databaseName().toStdString(),
|
||||
isDefault));
|
||||
#endif
|
||||
|
@ -447,7 +447,7 @@ std::string KCalExtendedSource::endSync(bool success)
|
|||
if (!m_data->m_storage->save()) {
|
||||
throwError(SE_HERE, "could not save calendar");
|
||||
}
|
||||
time_t modtime = time(NULL);
|
||||
time_t modtime = time(nullptr);
|
||||
// Saving set the modified time stamps of all items needed
|
||||
// saving, so ensure that we sleep for one second starting now.
|
||||
// Must sleep before taking the time stamp for the anchor,
|
||||
|
@ -456,7 +456,7 @@ std::string KCalExtendedSource::endSync(bool success)
|
|||
time_t current = modtime;
|
||||
do {
|
||||
sleep(1 - (current - modtime));
|
||||
current = time(NULL);
|
||||
current = time(nullptr);
|
||||
} while (current - modtime < 1);
|
||||
m_delete_run = 0;
|
||||
m_insert_run = 0;
|
||||
|
@ -531,7 +531,7 @@ TestingSyncSource::InsertItemResult KCalExtendedSource::insertItem(const string
|
|||
if (source) {
|
||||
KCalCore::ICalTimeZones *target = m_data->m_calendar->timeZones();
|
||||
if (target) {
|
||||
BOOST_FOREACH(const KCalCore::ICalTimeZone &zone, source->zones().values()) {
|
||||
for (const auto &zone: source->zones().values()) {
|
||||
target->add(zone);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include <syncevo/declarations.h>
|
||||
SE_BEGIN_CXX
|
||||
|
||||
static SyncSource *createSource(const SyncSourceParams ¶ms)
|
||||
static std::unique_ptr<SyncSource> createSource(const SyncSourceParams ¶ms)
|
||||
{
|
||||
SourceType sourceType = SyncSource::getSourceType(params.m_nodes);
|
||||
bool isMe = sourceType.m_backend == "mkcal-events";
|
||||
|
@ -39,7 +39,7 @@ static SyncSource *createSource(const SyncSourceParams ¶ms)
|
|||
#ifdef ENABLE_KCALEXTENDED
|
||||
true ? new KCalExtendedSource(params, KCalExtendedSource::Event) :
|
||||
#endif
|
||||
isMe ? RegisterSyncSource::InactiveSource(params) : NULL;
|
||||
isMe ? RegisterSyncSource::InactiveSource(params) : nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,7 @@ static SyncSource *createSource(const SyncSourceParams ¶ms)
|
|||
#ifdef ENABLE_KCALEXTENDED
|
||||
true ? new KCalExtendedSource(params, KCalExtendedSource::Todo) :
|
||||
#endif
|
||||
isMe ? RegisterSyncSource::InactiveSource(params) : NULL;
|
||||
isMe ? RegisterSyncSource::InactiveSource(params) : nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,11 +71,11 @@ static SyncSource *createSource(const SyncSourceParams ¶ms)
|
|||
#ifdef ENABLE_KCALEXTENDED
|
||||
true ? new KCalExtendedSource(params, KCalExtendedSource::Journal) :
|
||||
#endif
|
||||
isMe ? RegisterSyncSource::InactiveSource(params) : NULL;
|
||||
isMe ? RegisterSyncSource::InactiveSource(params) : nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static RegisterSyncSource registerMe("KCalExtended",
|
||||
|
@ -126,8 +126,8 @@ class KCalExtendedSourceUnitTest : public CppUnit::TestFixture {
|
|||
|
||||
protected:
|
||||
void testInstantiate() {
|
||||
boost::shared_ptr<SyncSource> source;
|
||||
source.reset(SyncSource::createTestingSource("KCalExtended", "KCalExtended:text/calendar:2.0", true));
|
||||
std::unique_ptr<SyncSource> source;
|
||||
source = SyncSource::createTestingSource("KCalExtended", "KCalExtended:text/calendar:2.0", true);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ void KDEInitMainSlot(const char *appname)
|
|||
|
||||
//QCoreApplication *app;
|
||||
int argc = 1;
|
||||
static char *argv[] = { const_cast<char *>(appname), NULL };
|
||||
static char *argv[] = { const_cast<char *>(appname), nullptr };
|
||||
KAboutData aboutData(// The program name used internally.
|
||||
"syncevolution",
|
||||
// The message catalog name
|
||||
|
@ -99,8 +99,8 @@ void KDEInitMainSlot(const char *appname)
|
|||
// Don't allow KApplication to mess with SIGINT/SIGTERM.
|
||||
// Restore current behavior after construction.
|
||||
struct sigaction oldsigint, oldsigterm;
|
||||
sigaction(SIGINT, NULL, &oldsigint);
|
||||
sigaction(SIGTERM, NULL, &oldsigterm);
|
||||
sigaction(SIGINT, nullptr, &oldsigint);
|
||||
sigaction(SIGTERM, nullptr, &oldsigterm);
|
||||
|
||||
// Explicitly disable GUI mode in the KApplication. Otherwise
|
||||
// the whole binary will fail to run when there is no X11
|
||||
|
@ -109,8 +109,8 @@ void KDEInitMainSlot(const char *appname)
|
|||
//To stop KApplication from spawning it's own DBus Service ... Will have to patch KApplication about this
|
||||
QDBusConnection::sessionBus().unregisterService("org.syncevolution.syncevolution-"+QString::number(getpid()));
|
||||
|
||||
sigaction(SIGINT, &oldsigint, NULL);
|
||||
sigaction(SIGTERM, &oldsigterm, NULL);
|
||||
sigaction(SIGINT, &oldsigint, nullptr);
|
||||
sigaction(SIGTERM, &oldsigterm, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -67,8 +67,8 @@ MaemoCalendarSource::MaemoCalendarSource(int EntryType, int EntryFormat,
|
|||
break;
|
||||
}
|
||||
mc = CMulticalendar::MCInstance();
|
||||
cal = NULL;
|
||||
conv = NULL;
|
||||
cal = nullptr;
|
||||
conv = nullptr;
|
||||
if (!mc) {
|
||||
throwError(SE_HERE, "Could not connect to Maemo Calendar backend");
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ std::string MaemoCalendarSource::getMimeType() const
|
|||
"text/calendar+plain" :
|
||||
"text/calendar";
|
||||
case VCAL_TYPE: return "text/x-calendar";
|
||||
default: return NULL;
|
||||
default: return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,7 +99,7 @@ std::string MaemoCalendarSource::getMimeVersion() const
|
|||
case -1: return "1.0";
|
||||
case ICAL_TYPE: return "2.0";
|
||||
case VCAL_TYPE: return "1.0";
|
||||
default: return NULL;
|
||||
default: return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,9 +155,9 @@ bool MaemoCalendarSource::isEmpty()
|
|||
void MaemoCalendarSource::close()
|
||||
{
|
||||
delete conv;
|
||||
conv = NULL;
|
||||
conv = nullptr;
|
||||
delete cal;
|
||||
cal = NULL;
|
||||
cal = nullptr;
|
||||
}
|
||||
|
||||
MaemoCalendarSource::Databases MaemoCalendarSource::getDatabases()
|
||||
|
@ -170,7 +170,7 @@ MaemoCalendarSource::Databases MaemoCalendarSource::getDatabases()
|
|||
vector< CCalendar * > calendars = mc->getListCalFromMc();
|
||||
Databases result;
|
||||
|
||||
BOOST_FOREACH(CCalendar * c, calendars) {
|
||||
for (CCalendar * c: calendars) {
|
||||
int id = c->getCalendarId();
|
||||
ostringstream uri;
|
||||
uri << "id:" << id;
|
||||
|
@ -204,7 +204,7 @@ void MaemoCalendarSource::listAllItems(RevisionMap_t &revisions)
|
|||
// components of the specified type, so just ignore it for now
|
||||
if (!comps.size())
|
||||
break;
|
||||
BOOST_FOREACH(CComponent * c, comps) {
|
||||
for (CComponent * c: comps) {
|
||||
revisions[c->getId()] = get_revision(c);
|
||||
// Testing shows that the backend doesn't free the memory itself
|
||||
delete c;
|
||||
|
@ -219,7 +219,7 @@ void MaemoCalendarSource::listAllItems(RevisionMap_t &revisions)
|
|||
// desirable, given the N900's limited memory.
|
||||
int err;
|
||||
vector< string > ids = cal->getIdList(entry_type, err);
|
||||
BOOST_FOREACH(std::string& id, ids) {
|
||||
for (std::string& id: ids) {
|
||||
CComponent *c = cal->getEntry(id, entry_type, err);
|
||||
if (!c)
|
||||
{
|
||||
|
@ -278,7 +278,7 @@ TrackingSyncSource::InsertItemResult MaemoCalendarSource::insertItem(const strin
|
|||
throwError(SE_HERE, string("no events in ical: ") + item);
|
||||
}
|
||||
}
|
||||
vector< CComponent * >::iterator it = comps.begin();
|
||||
vector< CComponent * auto it = comps.begin();
|
||||
if (comps.size() > 1) {
|
||||
for (; it != comps.end(); ++it) {
|
||||
delete (*it);
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include <syncevo/declarations.h>
|
||||
SE_BEGIN_CXX
|
||||
|
||||
static SyncSource *createSource(const SyncSourceParams ¶ms)
|
||||
static std::unique_ptr<SyncSource> createSource(const SyncSourceParams ¶ms)
|
||||
{
|
||||
SourceType sourceType = SyncSource::getSourceType(params.m_nodes);
|
||||
bool isMe = sourceType.m_backend == "Maemo Calendar";
|
||||
|
@ -35,11 +35,11 @@ static SyncSource *createSource(const SyncSourceParams ¶ms)
|
|||
|
||||
if (isMe || maybeMe) {
|
||||
if (sourceType.m_format == "" || sourceType.m_format == "text/calendar") {
|
||||
return new MaemoCalendarSource(EVENT, ICAL_TYPE, params);
|
||||
return std::make_unique<MaemoCalendarSource>(EVENT, ICAL_TYPE, params);
|
||||
} else if (sourceType.m_format == "text/x-vcalendar") {
|
||||
return new MaemoCalendarSource(EVENT, VCAL_TYPE, params);
|
||||
return std::make_unique<MaemoCalendarSource>(EVENT, VCAL_TYPE, params);
|
||||
} else {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -52,11 +52,11 @@ static SyncSource *createSource(const SyncSourceParams ¶ms)
|
|||
|
||||
if (isMe || maybeMe) {
|
||||
if (sourceType.m_format == "" || sourceType.m_format == "text/calendar") {
|
||||
return new MaemoCalendarSource(TODO, ICAL_TYPE, params);
|
||||
return std::make_unique<MaemoCalendarSource>(TODO, ICAL_TYPE, params);
|
||||
} else if (sourceType.m_format == "text/x-vcalendar") {
|
||||
return new MaemoCalendarSource(TODO, VCAL_TYPE, params);
|
||||
return std::make_unique<MaemoCalendarSource>(TODO, VCAL_TYPE, params);
|
||||
} else {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -69,18 +69,18 @@ static SyncSource *createSource(const SyncSourceParams ¶ms)
|
|||
|
||||
if (isMe || maybeMe) {
|
||||
if (sourceType.m_format == "" || sourceType.m_format == "text/calendar") {
|
||||
return new MaemoCalendarSource(JOURNAL, ICAL_TYPE, params);
|
||||
return std::make_unique<MaemoCalendarSource>(JOURNAL, ICAL_TYPE, params);
|
||||
} else if (sourceType.m_format == "text/x-vcalendar") {
|
||||
return new MaemoCalendarSource(JOURNAL, VCAL_TYPE, params);
|
||||
return std::make_unique<MaemoCalendarSource>(JOURNAL, VCAL_TYPE, params);
|
||||
} else if (sourceType.m_format == "text/plain") {
|
||||
return new MaemoCalendarSource(JOURNAL, -1, params);
|
||||
return std::make_unique<MaemoCalendarSource>(JOURNAL, -1, params);
|
||||
} else {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static RegisterSyncSource registerMe("Maemo Calendar/Tasks/Notes",
|
||||
|
@ -115,10 +115,10 @@ class MaemoCalendarSourceUnitTest : public CppUnit::TestFixture {
|
|||
|
||||
protected:
|
||||
void testInstantiate() {
|
||||
boost::shared_ptr<SyncSource> source;
|
||||
source.reset(SyncSource::createTestingSource("calendar", "calendar", true));
|
||||
source.reset(SyncSource::createTestingSource("calendar", "maemo-events", true));
|
||||
source.reset(SyncSource::createTestingSource("calendar", "Maemo Calendar:text/calendar", true));
|
||||
std::unique_ptr<SyncSource> source;
|
||||
source = SyncSource::createTestingSource("calendar", "calendar", true);
|
||||
source = SyncSource::createTestingSource("calendar", "maemo-events", true);
|
||||
source = SyncSource::createTestingSource("calendar", "Maemo Calendar:text/calendar", true);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -23,14 +23,17 @@
|
|||
#include <syncevo/GLibSupport.h>
|
||||
#include <syncevo/GVariantSupport.h>
|
||||
#include <syncevo/SoupTransportAgent.h>
|
||||
#include <syncevo/CurlTransportAgent.h>
|
||||
#include <json.h>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include <syncevo/declarations.h>
|
||||
SE_BEGIN_CXX
|
||||
|
||||
class RefreshTokenAuthProvider : public AuthProvider
|
||||
{
|
||||
boost::shared_ptr<HTTPTransportAgent> m_agent;
|
||||
std::shared_ptr<HTTPTransportAgent> m_agent;
|
||||
std::string m_tokenHost;
|
||||
std::string m_tokenPath;
|
||||
std::string m_scope;
|
||||
|
@ -46,6 +49,13 @@ public:
|
|||
const char* clientID,
|
||||
const char* clientSecret,
|
||||
const char* refreshToken) :
|
||||
m_agent(
|
||||
#ifdef ENABLE_LIBSOUP
|
||||
make_weak_shared::make<SoupTransportAgent>(static_cast<GMainLoop *>(nullptr))
|
||||
#elif defined(ENABLE_LIBCURL)
|
||||
std::make_shared<CurlTransportAgent>()
|
||||
#endif
|
||||
),
|
||||
m_tokenHost(tokenHost),
|
||||
m_tokenPath(tokenPath),
|
||||
m_scope(scope),
|
||||
|
@ -53,12 +63,6 @@ public:
|
|||
m_clientSecret(clientSecret),
|
||||
m_refreshToken(refreshToken)
|
||||
{
|
||||
#ifdef ENABLE_LIBSOUP
|
||||
boost::shared_ptr<SoupTransportAgent> agent(new SoupTransportAgent(static_cast<GMainLoop *>(NULL)));
|
||||
m_agent = agent;
|
||||
#elif defined(ENABLE_LIBCURL)
|
||||
m_agent = new CurlTransportAgent();
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual bool methodIsSupported(AuthMethod method) const { return method == AUTH_METHOD_OAUTH2; }
|
||||
|
@ -157,15 +161,15 @@ public:
|
|||
virtual std::string getUsername() const { return ""; }
|
||||
};
|
||||
|
||||
boost::shared_ptr<AuthProvider> createOAuth2AuthProvider(const InitStateString &username,
|
||||
std::shared_ptr<AuthProvider> createOAuth2AuthProvider(const InitStateString &username,
|
||||
const InitStateString &password)
|
||||
{
|
||||
// Expected content of parameter GVariant.
|
||||
boost::shared_ptr<GVariantType> hashtype(g_variant_type_new("a{ss}"), g_variant_type_free);
|
||||
std::shared_ptr<GVariantType> hashtype(g_variant_type_new("a{ss}"), g_variant_type_free);
|
||||
|
||||
// 'username' is the part after oauth2: which we can parse directly.
|
||||
GErrorCXX gerror;
|
||||
GVariantStealCXX parametersVar(g_variant_parse(hashtype.get(), username.c_str(), NULL, NULL, gerror));
|
||||
GVariantStealCXX parametersVar(g_variant_parse(hashtype.get(), username.c_str(), nullptr, nullptr, gerror));
|
||||
if (!parametersVar) {
|
||||
gerror.throwError(SE_HERE, "parsing 'oauth2:' username");
|
||||
}
|
||||
|
@ -206,7 +210,7 @@ boost::shared_ptr<AuthProvider> createOAuth2AuthProvider(const InitStateString &
|
|||
if (password.empty()) {
|
||||
SE_THROW("need refresh token provided as password");
|
||||
}
|
||||
boost::shared_ptr<AuthProvider> provider(new RefreshTokenAuthProvider(tokenHost, tokenPath, scope, clientID, clientSecret, password.c_str()));
|
||||
auto provider = std::make_shared<RefreshTokenAuthProvider>(tokenHost, tokenPath, scope, clientID, clientSecret, password.c_str());
|
||||
return provider;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,13 +21,13 @@
|
|||
|
||||
#include <syncevo/util.h>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <memory>
|
||||
|
||||
#include <syncevo/declarations.h>
|
||||
SE_BEGIN_CXX
|
||||
|
||||
class AuthProvider;
|
||||
boost::shared_ptr<AuthProvider> createOAuth2AuthProvider(const InitStateString &username,
|
||||
std::shared_ptr<AuthProvider> createOAuth2AuthProvider(const InitStateString &username,
|
||||
const InitStateString &password);
|
||||
|
||||
SE_END_CXX
|
||||
|
|
|
@ -41,10 +41,10 @@ public:
|
|||
" 'Scope', 'ClientID', 'ClientSecret'\n")
|
||||
{}
|
||||
|
||||
virtual boost::shared_ptr<AuthProvider> create(const InitStateString &username,
|
||||
virtual std::shared_ptr<AuthProvider> create(const InitStateString &username,
|
||||
const InitStateString &password)
|
||||
{
|
||||
boost::shared_ptr<AuthProvider> provider;
|
||||
std::shared_ptr<AuthProvider> provider;
|
||||
provider = createOAuth2AuthProvider(username, password);
|
||||
return provider;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
#include "PbapSyncSource.h"
|
||||
|
||||
#include <boost/assign/list_of.hpp>
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
#include <boost/tokenizer.hpp>
|
||||
|
||||
|
@ -33,8 +32,8 @@
|
|||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <pcrecpp.h>
|
||||
#include <algorithm>
|
||||
#include <regex>
|
||||
|
||||
#include <syncevo/GLibSupport.h> // PBAP backend does not compile without GLib.
|
||||
#include <syncevo/util.h>
|
||||
|
@ -45,7 +44,6 @@
|
|||
#include "gdbus-cxx-bridge.h"
|
||||
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include <synthesis/SDK_util.h>
|
||||
|
||||
|
@ -64,7 +62,7 @@ SE_BEGIN_CXX
|
|||
#define OBC_TRANSFER_INTERFACE_NEW "org.bluez.obex.Transfer"
|
||||
#define OBC_TRANSFER_INTERFACE_NEW5 "org.bluez.obex.Transfer1"
|
||||
|
||||
typedef std::map<int, pcrecpp::StringPiece> Content;
|
||||
typedef std::map<int, StringPiece> Content;
|
||||
typedef std::list<std::string> ContactQueue;
|
||||
typedef std::list<std::string> Properties;
|
||||
typedef boost::variant< std::string, Properties, uint16_t > Bluez5Values;
|
||||
|
@ -146,7 +144,7 @@ struct PullParams
|
|||
*
|
||||
* Note that GetSize() is specified as returning the number of entries in
|
||||
* the selected phonebook object that are actually used (i.e. indexes that
|
||||
* correspond to non-NULL entries). This is relevant if contacts get
|
||||
* correspond to non-nullptr entries). This is relevant if contacts get
|
||||
* deleted after starting the session. In that case, the algorithm above
|
||||
* will not necessarily read all contacts. Here's an example:
|
||||
* offsets #0 till #99, with contacts #10 till #19 deleted
|
||||
|
@ -226,7 +224,7 @@ class PullAll
|
|||
|
||||
uint16_t m_numContacts; // Number of existing contacts, according to GetSize() or after downloading.
|
||||
uint16_t m_currentContact; // Numbered starting with zero according to discovery in addVCards.
|
||||
boost::shared_ptr<PbapSession> m_session; // Only set when there is a transfer ongoing.
|
||||
std::shared_ptr<PbapSession> m_session; // Only set when there is a transfer ongoing.
|
||||
size_t m_tmpFileOffset; // Number of bytes already parsed.
|
||||
uint16_t m_transferOffset; // First contact requested as part of current transfer.
|
||||
uint16_t m_initialOffset; // First contact request by first transfer.
|
||||
|
@ -247,8 +245,8 @@ public:
|
|||
~PullAll();
|
||||
|
||||
std::string getNextID();
|
||||
bool getContact(const char *id, pcrecpp::StringPiece &vcard);
|
||||
const char *addVCards(int startIndex, const pcrecpp::StringPiece &content);
|
||||
bool getContact(const char *id, StringPiece &vcard);
|
||||
const char *addVCards(int startIndex, const StringPiece &content, bool eof);
|
||||
};
|
||||
|
||||
PullAll::PullAll() :
|
||||
|
@ -269,15 +267,16 @@ PullAll::~PullAll()
|
|||
{
|
||||
}
|
||||
|
||||
class PbapSession : private boost::noncopyable {
|
||||
class PbapSession : private boost::noncopyable, public enable_weak_from_this<PbapSession> {
|
||||
public:
|
||||
static boost::shared_ptr<PbapSession> create(PbapSyncSource &parent);
|
||||
// Construct via make_weak_shared.
|
||||
friend make_weak_shared;
|
||||
|
||||
void initSession(const std::string &address, const std::string &format);
|
||||
|
||||
typedef std::map<std::string, pcrecpp::StringPiece> Content;
|
||||
typedef std::map<std::string, StringPiece> Content;
|
||||
|
||||
boost::shared_ptr<PullAll> startPullAll(const PullParams &pullParams);
|
||||
std::shared_ptr<PullAll> startPullAll(const PullParams &pullParams);
|
||||
void continuePullAll(PullAll &state);
|
||||
void checkForError(); // Throws exception if transfer failed.
|
||||
Timespec transferComplete() const;
|
||||
|
@ -290,8 +289,7 @@ private:
|
|||
PbapSession(PbapSyncSource &parent);
|
||||
|
||||
PbapSyncSource &m_parent;
|
||||
boost::weak_ptr<PbapSession> m_self;
|
||||
std::auto_ptr<GDBusCXX::DBusRemoteObject> m_client;
|
||||
std::unique_ptr<GDBusCXX::DBusRemoteObject> m_client;
|
||||
bool m_frozen;
|
||||
enum {
|
||||
OBEXD_OLD, // obexd < 0.47
|
||||
|
@ -333,28 +331,25 @@ private:
|
|||
Transfers m_transfers;
|
||||
std::string m_currentTransfer;
|
||||
|
||||
std::auto_ptr<GDBusCXX::SignalWatch3<GDBusCXX::Path_t, std::string, std::string> >
|
||||
std::unique_ptr<GDBusCXX::SignalWatch<GDBusCXX::Path_t, std::string, std::string> >
|
||||
m_errorSignal;
|
||||
void errorCb(const GDBusCXX::Path_t &path, const std::string &error,
|
||||
const std::string &msg);
|
||||
|
||||
// Bluez 5
|
||||
typedef GDBusCXX::SignalWatch4<GDBusCXX::Path_t, std::string, Params, std::vector<std::string> > PropChangedSignal_t;
|
||||
std::auto_ptr<PropChangedSignal_t> m_propChangedSignal;
|
||||
typedef GDBusCXX::SignalWatch<GDBusCXX::Path_t, std::string, Params, std::vector<std::string> > PropChangedSignal_t;
|
||||
std::unique_ptr<PropChangedSignal_t> m_propChangedSignal;
|
||||
void propChangedCb(const GDBusCXX::Path_t &path,
|
||||
const std::string &interface,
|
||||
const Params &changed,
|
||||
const std::vector<std::string> &invalidated);
|
||||
|
||||
// new obexd API
|
||||
typedef GDBusCXX::SignalWatch1<GDBusCXX::Path_t> CompleteSignal_t;
|
||||
std::auto_ptr<CompleteSignal_t> m_completeSignal;
|
||||
void completeCb(const GDBusCXX::Path_t &path);
|
||||
typedef GDBusCXX::SignalWatch3<GDBusCXX::Path_t, std::string, boost::variant<int64_t> > PropertyChangedSignal_t;
|
||||
std::auto_ptr<PropertyChangedSignal_t> m_propertyChangedSignal;
|
||||
typedef GDBusCXX::SignalWatch<GDBusCXX::Path_t> CompleteSignal_t;
|
||||
std::unique_ptr<CompleteSignal_t> m_completeSignal;
|
||||
typedef GDBusCXX::SignalWatch<GDBusCXX::Path_t, std::string, boost::variant<int64_t> > PropertyChangedSignal_t;
|
||||
std::unique_ptr<PropertyChangedSignal_t> m_propertyChangedSignal;
|
||||
void propertyChangedCb(const GDBusCXX::Path_t &path, const std::string &name, const boost::variant<int64_t> &value);
|
||||
|
||||
std::auto_ptr<GDBusCXX::DBusRemoteObject> m_session;
|
||||
std::unique_ptr<GDBusCXX::DBusRemoteObject> m_session;
|
||||
};
|
||||
|
||||
PbapSession::PbapSession(PbapSyncSource &parent) :
|
||||
|
@ -363,13 +358,6 @@ PbapSession::PbapSession(PbapSyncSource &parent) :
|
|||
{
|
||||
}
|
||||
|
||||
boost::shared_ptr<PbapSession> PbapSession::create(PbapSyncSource &parent)
|
||||
{
|
||||
boost::shared_ptr<PbapSession> session(new PbapSession(parent));
|
||||
session->m_self = session;
|
||||
return session;
|
||||
}
|
||||
|
||||
void PbapSession::propChangedCb(const GDBusCXX::Path_t &path,
|
||||
const std::string &interface,
|
||||
const Params &changed,
|
||||
|
@ -377,7 +365,7 @@ void PbapSession::propChangedCb(const GDBusCXX::Path_t &path,
|
|||
{
|
||||
// Called for a path which matches the current session, so we know
|
||||
// that the signal is for our transfer. Only need to check the status.
|
||||
Params::const_iterator it = changed.find("Status");
|
||||
auto it = changed.find("Status");
|
||||
if (it != changed.end()) {
|
||||
std::string status = boost::get<std::string>(it->second);
|
||||
SE_LOG_DEBUG(NULL, "OBEXD transfer %s: %s",
|
||||
|
@ -399,7 +387,7 @@ void PbapSession::propChangedCb(const GDBusCXX::Path_t &path,
|
|||
OBC_TRANSFER_INTERFACE_NEW5,
|
||||
OBC_SERVICE_NEW5,
|
||||
true);
|
||||
GDBusCXX::DBusClientCall0(transfer, "Suspend")();
|
||||
GDBusCXX::DBusClientCall<>(transfer, "Suspend")();
|
||||
SE_LOG_DEBUG(NULL, "successfully suspended transfer when it became active");
|
||||
} catch (...) {
|
||||
// Ignore all errors here. The worst that can happen is that
|
||||
|
@ -413,24 +401,6 @@ void PbapSession::propChangedCb(const GDBusCXX::Path_t &path,
|
|||
}
|
||||
}
|
||||
|
||||
void PbapSession::completeCb(const GDBusCXX::Path_t &path)
|
||||
{
|
||||
SE_LOG_DEBUG(NULL, "obexd transfer %s completed", path.c_str());
|
||||
m_transfers[path] = Completion::now();
|
||||
}
|
||||
|
||||
void PbapSession::errorCb(const GDBusCXX::Path_t &path,
|
||||
const std::string &error,
|
||||
const std::string &msg)
|
||||
{
|
||||
SE_LOG_DEBUG(NULL, "obexd transfer %s failed: %s %s",
|
||||
path.c_str(), error.c_str(), msg.c_str());
|
||||
Completion &completion = m_transfers[path];
|
||||
completion.m_transferComplete = Timespec::monotonic();
|
||||
completion.m_transferErrorCode = error;
|
||||
completion.m_transferErrorMsg = msg;
|
||||
}
|
||||
|
||||
void PbapSession::propertyChangedCb(const GDBusCXX::Path_t &path,
|
||||
const std::string &name,
|
||||
const boost::variant<int64_t> &value)
|
||||
|
@ -448,35 +418,36 @@ void PbapSession::propertyChangedCb(const GDBusCXX::Path_t &path,
|
|||
Properties PbapSession::supportedProperties() const
|
||||
{
|
||||
Properties props;
|
||||
static const std::set<std::string> supported =
|
||||
boost::assign::list_of("VERSION")
|
||||
("FN")
|
||||
("N")
|
||||
("PHOTO")
|
||||
("BDAY")
|
||||
("ADR")
|
||||
("LABEL")
|
||||
("TEL")
|
||||
("EMAIL")
|
||||
("MAILER")
|
||||
("TZ")
|
||||
("GEO")
|
||||
("TITLE")
|
||||
("ROLE")
|
||||
("LOGO")
|
||||
("AGENT")
|
||||
("ORG")
|
||||
("NOTE")
|
||||
("REV")
|
||||
("SOUND")
|
||||
("URL")
|
||||
("UID")
|
||||
("KEY")
|
||||
("NICKNAME")
|
||||
("CATEGORIES")
|
||||
("CLASS");
|
||||
static const std::set<std::string> supported = {
|
||||
"VERSION",
|
||||
"FN",
|
||||
"N",
|
||||
"PHOTO",
|
||||
"BDAY",
|
||||
"ADR",
|
||||
"LABEL",
|
||||
"TEL",
|
||||
"EMAIL",
|
||||
"MAILER",
|
||||
"TZ",
|
||||
"GEO",
|
||||
"TITLE",
|
||||
"ROLE",
|
||||
"LOGO",
|
||||
"AGENT",
|
||||
"ORG",
|
||||
"NOTE",
|
||||
"REV",
|
||||
"SOUND",
|
||||
"URL",
|
||||
"UID",
|
||||
"KEY",
|
||||
"NICKNAME",
|
||||
"CATEGORIES",
|
||||
"CLASS"
|
||||
};
|
||||
|
||||
BOOST_FOREACH (const std::string &prop, m_filterFields) {
|
||||
for (const std::string &prop: m_filterFields) {
|
||||
// Be conservative and only ask for properties that we
|
||||
// really know how to use. obexd also lists the bit field
|
||||
// strings ("BIT01") but phones have been seen to reject
|
||||
|
@ -500,14 +471,15 @@ void PbapSession::initSession(const std::string &address, const std::string &for
|
|||
// 3.0:^PHOTO = download in vCard 3.0 format, excluding PHOTO
|
||||
// 2.1:PHOTO = download in vCard 2.1 format, only the PHOTO
|
||||
|
||||
std::string version;
|
||||
std::string tmp;
|
||||
std::string properties;
|
||||
const pcrecpp::RE re("(?:(2\\.1|3\\.0):?)?(\\^?)([-a-zA-Z,]*)");
|
||||
if (!re.FullMatch(format, &version, &tmp, &properties)) {
|
||||
const static std::regex re(R"del((?:(2\.1|3\.0):?)?(\^?)([-a-zA-Z,]*))del");
|
||||
std::smatch match;
|
||||
if (!std::regex_match(format, match, re)) {
|
||||
m_parent.throwError(SE_HERE, StringPrintf("invalid specification of PBAP vCard format (databaseFormat): %s",
|
||||
format.c_str()));
|
||||
}
|
||||
std::string version = match[1];
|
||||
std::string tmp = match[2];
|
||||
std::string properties = match[3];
|
||||
char negated = tmp.c_str()[0];
|
||||
if (version.empty()) {
|
||||
// same default as in obexd
|
||||
|
@ -525,7 +497,7 @@ void PbapSession::initSession(const std::string &address, const std::string &for
|
|||
params["Target"] = std::string("PBAP");
|
||||
|
||||
std::string session;
|
||||
GDBusCXX::DBusConnectionPtr conn = GDBusCXX::dbus_get_bus_connection("SESSION", NULL, true, NULL);
|
||||
GDBusCXX::DBusConnectionPtr conn = GDBusCXX::dbus_get_bus_connection("SESSION", nullptr, true, nullptr);
|
||||
|
||||
// We must attempt to use the new interface(s), otherwise we won't know whether
|
||||
// the daemon exists or can be started.
|
||||
|
@ -537,7 +509,7 @@ void PbapSession::initSession(const std::string &address, const std::string &for
|
|||
try {
|
||||
SE_LOG_DEBUG(NULL, "trying to use bluez 5 obexd service %s", OBC_SERVICE_NEW5);
|
||||
session =
|
||||
GDBusCXX::DBusClientCall1<GDBusCXX::DBusObject_t>(*m_client, "CreateSession")(address, params);
|
||||
GDBusCXX::DBusClientCall<GDBusCXX::DBusObject_t>(*m_client, "CreateSession")(address, params);
|
||||
} catch (const std::exception &error) {
|
||||
if (!strstr(error.what(), "org.freedesktop.DBus.Error.ServiceUnknown") &&
|
||||
!strstr(error.what(), "org.freedesktop.DBus.Error.UnknownObject")) {
|
||||
|
@ -556,7 +528,7 @@ void PbapSession::initSession(const std::string &address, const std::string &for
|
|||
try {
|
||||
SE_LOG_DEBUG(NULL, "trying to use new obexd service %s", OBC_SERVICE_NEW);
|
||||
session =
|
||||
GDBusCXX::DBusClientCall1<GDBusCXX::DBusObject_t>(*m_client, "CreateSession")(address, params);
|
||||
GDBusCXX::DBusClientCall<GDBusCXX::DBusObject_t>(*m_client, "CreateSession")(address, params);
|
||||
} catch (const std::exception &error) {
|
||||
if (!strstr(error.what(), "org.freedesktop.DBus.Error.ServiceUnknown")) {
|
||||
throw;
|
||||
|
@ -573,7 +545,7 @@ void PbapSession::initSession(const std::string &address, const std::string &for
|
|||
m_client.reset(new GDBusCXX::DBusRemoteObject(conn, "/", OBC_CLIENT_INTERFACE,
|
||||
OBC_SERVICE, true));
|
||||
params["Destination"] = std::string(address);
|
||||
session = GDBusCXX::DBusClientCall1<GDBusCXX::DBusObject_t>(*m_client, "CreateSession")(params);
|
||||
session = GDBusCXX::DBusClientCall<GDBusCXX::DBusObject_t>(*m_client, "CreateSession")(params);
|
||||
}
|
||||
|
||||
if (session.empty()) {
|
||||
|
@ -598,7 +570,7 @@ void PbapSession::initSession(const std::string &address, const std::string &for
|
|||
// pointer and ignore callback when the instance is already gone.
|
||||
// Should not happen with signals (destructing the class unregisters
|
||||
// the watch), but very well may happen in asynchronous method
|
||||
// calls. Therefore maintain m_self and show how to use it here.
|
||||
// calls.
|
||||
if (m_obexAPI == BLUEZ5) {
|
||||
// Bluez 5
|
||||
m_propChangedSignal.reset(new PropChangedSignal_t
|
||||
|
@ -607,7 +579,12 @@ void PbapSession::initSession(const std::string &address, const std::string &for
|
|||
"org.freedesktop.DBus.Properties",
|
||||
"PropertiesChanged",
|
||||
GDBusCXX::SignalFilter::SIGNAL_FILTER_PATH_PREFIX)));
|
||||
m_propChangedSignal->activate(boost::bind(&PbapSession::propChangedCb, m_self, _1, _2, _3, _4));
|
||||
m_propChangedSignal->activate([self=weak_from_this()] (const GDBusCXX::Path_t &path, const std::string &interface, const Params &changed, const std::vector<std::string> &invalidated) {
|
||||
auto lock = self.lock();
|
||||
if (lock) {
|
||||
lock->propChangedCb(path, interface, changed, invalidated);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// obexd >= 0.47
|
||||
m_completeSignal.reset(new CompleteSignal_t
|
||||
|
@ -616,16 +593,32 @@ void PbapSession::initSession(const std::string &address, const std::string &for
|
|||
OBC_TRANSFER_INTERFACE_NEW,
|
||||
"Complete",
|
||||
GDBusCXX::SignalFilter::SIGNAL_FILTER_PATH_PREFIX)));
|
||||
m_completeSignal->activate(boost::bind(&PbapSession::completeCb, m_self, _1));
|
||||
m_completeSignal->activate([self=weak_from_this()] (const GDBusCXX::Path_t &path) {
|
||||
auto lock = self.lock();
|
||||
SE_LOG_DEBUG(NULL, "obexd transfer %s completed", path.c_str());
|
||||
if (lock) {
|
||||
lock->m_transfers[path] = Completion::now();
|
||||
}
|
||||
});
|
||||
|
||||
// same for error
|
||||
m_errorSignal.reset(new GDBusCXX::SignalWatch3<GDBusCXX::Path_t, std::string, std::string>
|
||||
m_errorSignal.reset(new GDBusCXX::SignalWatch<GDBusCXX::Path_t, std::string, std::string>
|
||||
(GDBusCXX::SignalFilter(m_client->getConnection(),
|
||||
session,
|
||||
OBC_TRANSFER_INTERFACE_NEW,
|
||||
"Error",
|
||||
GDBusCXX::SignalFilter::SIGNAL_FILTER_PATH_PREFIX)));
|
||||
m_errorSignal->activate(boost::bind(&PbapSession::errorCb, m_self, _1, _2, _3));
|
||||
m_errorSignal->activate([self=weak_from_this()] (const GDBusCXX::Path_t &path, const std::string &error, const std::string &msg) {
|
||||
auto lock = self.lock();
|
||||
SE_LOG_DEBUG(NULL, "obexd transfer %s failed: %s %s",
|
||||
path.c_str(), error.c_str(), msg.c_str());
|
||||
if (lock) {
|
||||
Completion &completion = lock->m_transfers[path];
|
||||
completion.m_transferComplete = Timespec::monotonic();
|
||||
completion.m_transferErrorCode = error;
|
||||
completion.m_transferErrorMsg = msg;
|
||||
}
|
||||
});
|
||||
|
||||
// and property changes
|
||||
m_propertyChangedSignal.reset(new PropertyChangedSignal_t(GDBusCXX::SignalFilter(m_client->getConnection(),
|
||||
|
@ -633,7 +626,12 @@ void PbapSession::initSession(const std::string &address, const std::string &for
|
|||
OBC_TRANSFER_INTERFACE_NEW,
|
||||
"PropertyChanged",
|
||||
GDBusCXX::SignalFilter::SIGNAL_FILTER_PATH_PREFIX)));
|
||||
m_propertyChangedSignal->activate(boost::bind(&PbapSession::propertyChangedCb, m_self, _1, _2, _3));
|
||||
m_propertyChangedSignal->activate([self=weak_from_this()] (const GDBusCXX::Path_t &path, const std::string &interface , const boost::variant<int64_t> &value) {
|
||||
auto lock = self.lock();
|
||||
if (lock) {
|
||||
lock->propertyChangedCb(path, interface, value);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// obexd < 0.47
|
||||
|
@ -647,7 +645,7 @@ void PbapSession::initSession(const std::string &address, const std::string &for
|
|||
SE_LOG_DEBUG(NULL, "PBAP session created: %s", m_session->getPath());
|
||||
|
||||
// get filter list so that we can continue validating our format specifier
|
||||
m_filterFields = GDBusCXX::DBusClientCall1< Properties >(*m_session, "ListFilterFields")();
|
||||
m_filterFields = GDBusCXX::DBusClientCall< Properties >(*m_session, "ListFilterFields")();
|
||||
SE_LOG_DEBUG(NULL, "supported PBAP filter fields:\n %s",
|
||||
boost::join(m_filterFields, "\n ").c_str());
|
||||
|
||||
|
@ -658,15 +656,15 @@ void PbapSession::initSession(const std::string &address, const std::string &for
|
|||
}
|
||||
|
||||
// validate parameters and update filter
|
||||
BOOST_FOREACH (const std::string &prop, keywords) {
|
||||
for (const std::string &prop: keywords) {
|
||||
if (prop.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Properties::const_iterator entry =
|
||||
auto entry =
|
||||
std::find_if(m_filterFields.begin(),
|
||||
m_filterFields.end(),
|
||||
boost::bind(&boost::iequals<std::string,std::string>, _1, prop, std::locale()));
|
||||
[&prop] (const std::string &other) { return boost::iequals(other, prop, std::locale()); });
|
||||
|
||||
if (entry == m_filterFields.end()) {
|
||||
m_parent.throwError(SE_HERE, StringPrintf("invalid property name in PBAP vCard format specification (databaseFormat): %s",
|
||||
|
@ -680,14 +678,14 @@ void PbapSession::initSession(const std::string &address, const std::string &for
|
|||
}
|
||||
}
|
||||
|
||||
GDBusCXX::DBusClientCall0(*m_session, "Select")(std::string("int"), std::string("PB"));
|
||||
GDBusCXX::DBusClientCall<>(*m_session, "Select")(std::string("int"), std::string("PB"));
|
||||
m_filter5["Format"] = version == "2.1" ? "vcard21" : "vcard30";
|
||||
m_filter5["Fields"] = filter;
|
||||
|
||||
SE_LOG_DEBUG(NULL, "PBAP session initialized");
|
||||
}
|
||||
|
||||
boost::shared_ptr<PullAll> PbapSession::startPullAll(const PullParams &pullParams)
|
||||
std::shared_ptr<PullAll> PbapSession::startPullAll(const PullParams &pullParams)
|
||||
{
|
||||
resetTransfer();
|
||||
blockOnFreeze();
|
||||
|
@ -717,7 +715,7 @@ boost::shared_ptr<PullAll> PbapSession::startPullAll(const PullParams &pullParam
|
|||
if (filter.empty()) {
|
||||
filter = supportedProperties();
|
||||
}
|
||||
for (Properties::iterator it = filter.begin();
|
||||
for (auto it = filter.begin();
|
||||
it != filter.end();
|
||||
++it) {
|
||||
if (*it == "PHOTO") {
|
||||
|
@ -734,8 +732,8 @@ boost::shared_ptr<PullAll> PbapSession::startPullAll(const PullParams &pullParam
|
|||
if (m_obexAPI == OBEXD_OLD ||
|
||||
m_obexAPI == OBEXD_NEW) {
|
||||
try {
|
||||
GDBusCXX::DBusClientCall0(*m_session, "SetFilter")(filter);
|
||||
GDBusCXX::DBusClientCall0(*m_session, "SetFormat")(format);
|
||||
GDBusCXX::DBusClientCall<>(*m_session, "SetFilter")(filter);
|
||||
GDBusCXX::DBusClientCall<>(*m_session, "SetFormat")(format);
|
||||
} catch (...) {
|
||||
// Ignore failure, can happen with 0.48. Instead send filter together
|
||||
// with PullAll method call.
|
||||
|
@ -744,7 +742,7 @@ boost::shared_ptr<PullAll> PbapSession::startPullAll(const PullParams &pullParam
|
|||
}
|
||||
}
|
||||
|
||||
boost::shared_ptr<PullAll> state(new PullAll);
|
||||
auto state = std::make_shared<PullAll>();
|
||||
state->m_pullParams = pullParams;
|
||||
state->m_contentStartIndex = 0;
|
||||
state->m_currentContact = 0;
|
||||
|
@ -759,7 +757,7 @@ boost::shared_ptr<PullAll> PbapSession::startPullAll(const PullParams &pullParam
|
|||
// Beware, this will lead to a "Complete" signal in obexd
|
||||
// 0.47. We need to be careful with looking at the right
|
||||
// transfer to determine whether PullAll completed.
|
||||
state->m_numContacts = GDBusCXX::DBusClientCall1<uint16_t>(*m_session, "GetSize")();
|
||||
state->m_numContacts = GDBusCXX::DBusClientCall<uint16_t>(*m_session, "GetSize")();
|
||||
SE_LOG_DEBUG(NULL, "Expecting %d contacts.", state->m_numContacts);
|
||||
|
||||
state->m_tmpFile.create(TmpFile::FILE);
|
||||
|
@ -791,12 +789,12 @@ boost::shared_ptr<PullAll> PbapSession::startPullAll(const PullParams &pullParam
|
|||
Bluez5PullAllResult tuple =
|
||||
pullAllWithFiltersFallback ?
|
||||
// 0.48
|
||||
GDBusCXX::DBusClientCall1<std::pair<GDBusCXX::DBusObject_t, Params> >(*m_session, "PullAll")(state->m_tmpFile.filename(), currentFilter) :
|
||||
GDBusCXX::DBusClientCall<std::pair<GDBusCXX::DBusObject_t, Params> >(*m_session, "PullAll")(state->m_tmpFile.filename(), currentFilter) :
|
||||
m_obexAPI == OBEXD_NEW ?
|
||||
// 0.47
|
||||
GDBusCXX::DBusClientCall1<std::pair<GDBusCXX::DBusObject_t, Params> >(*m_session, "PullAll")(state->m_tmpFile.filename()) :
|
||||
GDBusCXX::DBusClientCall<std::pair<GDBusCXX::DBusObject_t, Params> >(*m_session, "PullAll")(state->m_tmpFile.filename()) :
|
||||
// 5.x
|
||||
GDBusCXX::DBusClientCall2<GDBusCXX::DBusObject_t, Params>(*m_session, "PullAll")(state->m_tmpFile.filename(), currentFilter);
|
||||
GDBusCXX::DBusClientCall<GDBusCXX::DBusObject_t, Params>(*m_session, "PullAll")(state->m_tmpFile.filename(), currentFilter);
|
||||
const GDBusCXX::DBusObject_t &transfer = tuple.first;
|
||||
const Params &properties = tuple.second;
|
||||
m_currentTransfer = transfer;
|
||||
|
@ -812,7 +810,7 @@ boost::shared_ptr<PullAll> PbapSession::startPullAll(const PullParams &pullParam
|
|||
// and the Synthesis engine will ignore the ID (src/sysync/binfileimplds.cpp:
|
||||
// "Record does not exist any more in database%s -> ignore").
|
||||
state->m_tmpFileOffset = 0;
|
||||
state->m_session = m_self.lock();
|
||||
state->m_session = shared_from_this();
|
||||
state->m_filter = currentFilter;
|
||||
} else {
|
||||
// < 0.47
|
||||
|
@ -823,28 +821,66 @@ boost::shared_ptr<PullAll> PbapSession::startPullAll(const PullParams &pullParam
|
|||
// of obex-client < 0.47. Not sure what we should do about
|
||||
// this: disable incremental sync for old obex-client? Reject
|
||||
// it? Catch the error and add a better exlanation?
|
||||
GDBusCXX::DBusClientCall1<std::string> pullall(*m_session, "PullAll");
|
||||
GDBusCXX::DBusClientCall<std::string> pullall(*m_session, "PullAll");
|
||||
state->m_buffer = pullall();
|
||||
state->addVCards(0, state->m_buffer);
|
||||
state->addVCards(0, state->m_buffer, true);
|
||||
state->m_numContacts = state->m_content.size();
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
const char *PullAll::addVCards(int startIndex, const pcrecpp::StringPiece &vcards)
|
||||
const char *findLine(const StringPiece &hay, const StringPiece &needle, bool eof)
|
||||
{
|
||||
pcrecpp::StringPiece vcarddata;
|
||||
pcrecpp::StringPiece tmp = vcards;
|
||||
int count = startIndex;
|
||||
pcrecpp::RE re("[\\r\\n]*(^BEGIN:VCARD.*?^END:VCARD)",
|
||||
pcrecpp::RE_Options().set_dotall(true).set_multiline(true));
|
||||
while (re.Consume(&tmp, &vcarddata)) {
|
||||
m_content[count] = vcarddata;
|
||||
++count;
|
||||
const char *current = hay.begin();
|
||||
const char *end = hay.end();
|
||||
size_t size = needle.size();
|
||||
while (current < end) {
|
||||
// Skip line break(s).
|
||||
while (current < end && (*current == '\n' || *current == '\r')) {
|
||||
current++;
|
||||
}
|
||||
const char *next = current + size;
|
||||
if (next <= end &&
|
||||
!memcmp(current, needle.begin(), size) &&
|
||||
((eof && next == end) ||
|
||||
(next + 1 < end && (*next == '\n' || *next == '\r')))) {
|
||||
// Found a matching line.
|
||||
return current;
|
||||
}
|
||||
// Skip line.
|
||||
while (current < end && *current != '\n' && *current != '\r') {
|
||||
current++;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char *PullAll::addVCards(int startIndex, const StringPiece &vcards, bool eof)
|
||||
{
|
||||
const char *current = vcards.begin();
|
||||
const char *end = vcards.end();
|
||||
const static StringPiece BEGIN_VCARD("BEGIN:VCARD");
|
||||
const static StringPiece END_VCARD("END:VCARD");
|
||||
int count = startIndex;
|
||||
while (true) {
|
||||
StringPiece remaining(current, end - current);
|
||||
const char *begin_vcard = findLine(remaining, BEGIN_VCARD, eof);
|
||||
if (begin_vcard) {
|
||||
const char *end_vcard = findLine(StringPiece(remaining), END_VCARD, eof);
|
||||
if (end_vcard) {
|
||||
const char *next = end_vcard + END_VCARD.size();
|
||||
StringPiece vcarddata(begin_vcard, next - begin_vcard);
|
||||
m_content[count] = vcarddata;
|
||||
++count;
|
||||
current = next;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// No further vcard found, try again when we have more data.
|
||||
break;
|
||||
}
|
||||
SE_LOG_DEBUG(NULL, "PBAP content parsed: %d contacts starting at ID %d", count - startIndex, startIndex);
|
||||
return tmp.data();
|
||||
return current;
|
||||
}
|
||||
|
||||
void PbapSession::continuePullAll(PullAll &state)
|
||||
|
@ -855,9 +891,9 @@ void PbapSession::continuePullAll(PullAll &state)
|
|||
|
||||
Bluez5PullAllResult tuple =
|
||||
m_obexAPI == BLUEZ5 ?
|
||||
GDBusCXX::DBusClientCall2<GDBusCXX::DBusObject_t, Params>(*m_session, "PullAll")(state.m_tmpFile.filename(), state.m_filter) :
|
||||
GDBusCXX::DBusClientCall<GDBusCXX::DBusObject_t, Params>(*m_session, "PullAll")(state.m_tmpFile.filename(), state.m_filter) :
|
||||
// must be 0.48
|
||||
GDBusCXX::DBusClientCall1<std::pair<GDBusCXX::DBusObject_t, Params> >(*m_session, "PullAll")(state.m_tmpFile.filename(), state.m_filter);
|
||||
GDBusCXX::DBusClientCall<std::pair<GDBusCXX::DBusObject_t, Params> >(*m_session, "PullAll")(state.m_tmpFile.filename(), state.m_filter);
|
||||
|
||||
const GDBusCXX::DBusObject_t &transfer = tuple.first;
|
||||
const Params &properties = tuple.second;
|
||||
|
@ -871,7 +907,7 @@ void PbapSession::continuePullAll(PullAll &state)
|
|||
|
||||
void PbapSession::checkForError()
|
||||
{
|
||||
Transfers::const_iterator it = m_transfers.find(m_currentTransfer);
|
||||
auto it = m_transfers.find(m_currentTransfer);
|
||||
if (it != m_transfers.end()) {
|
||||
if (!it->second.m_transferErrorCode.empty()) {
|
||||
m_parent.throwError(SE_HERE, StringPrintf("%s: %s",
|
||||
|
@ -884,7 +920,7 @@ void PbapSession::checkForError()
|
|||
Timespec PbapSession::transferComplete() const
|
||||
{
|
||||
Timespec res;
|
||||
Transfers::const_iterator it = m_transfers.find(m_currentTransfer);
|
||||
auto it = m_transfers.find(m_currentTransfer);
|
||||
if (it != m_transfers.end()) {
|
||||
res = it->second.m_transferComplete;
|
||||
}
|
||||
|
@ -906,7 +942,7 @@ std::string PullAll::getNextID()
|
|||
return id;
|
||||
}
|
||||
|
||||
bool PullAll::getContact(const char *id, pcrecpp::StringPiece &vcard)
|
||||
bool PullAll::getContact(const char *id, StringPiece &vcard)
|
||||
{
|
||||
int contactNumber = atoi(id);
|
||||
SE_LOG_DEBUG(NULL, "get PBAP contact ID %s", id);
|
||||
|
@ -932,7 +968,7 @@ bool PullAll::getContact(const char *id, pcrecpp::StringPiece &vcard)
|
|||
// now).
|
||||
while (!m_session->transferComplete() && m_tmpFile.moreData() < 128 * 1024) {
|
||||
s.checkForNormal();
|
||||
g_main_context_iteration(NULL, true);
|
||||
g_main_context_iteration(nullptr, true);
|
||||
}
|
||||
m_session->checkForError();
|
||||
|
||||
|
@ -940,13 +976,13 @@ bool PullAll::getContact(const char *id, pcrecpp::StringPiece &vcard)
|
|||
if (m_tmpFile.moreData()) {
|
||||
// Remap. This shifts all addresses already stored in
|
||||
// m_content, so beware and update those.
|
||||
pcrecpp::StringPiece oldMem = m_tmpFile.stringPiece();
|
||||
StringPiece oldMem = m_tmpFile.stringPiece();
|
||||
m_tmpFile.unmap();
|
||||
m_tmpFile.map();
|
||||
pcrecpp::StringPiece newMem = m_tmpFile.stringPiece();
|
||||
StringPiece newMem = m_tmpFile.stringPiece();
|
||||
ssize_t delta = newMem.data() - oldMem.data();
|
||||
BOOST_FOREACH (Content::value_type &entry, m_content) {
|
||||
pcrecpp::StringPiece &vcard = entry.second;
|
||||
for (auto &entry: m_content) {
|
||||
StringPiece &vcard = entry.second;
|
||||
vcard.set(vcard.data() + delta, vcard.size());
|
||||
}
|
||||
|
||||
|
@ -955,15 +991,15 @@ bool PullAll::getContact(const char *id, pcrecpp::StringPiece &vcard)
|
|||
m_tmpFile.remove();
|
||||
|
||||
// Continue parsing where we stopped before.
|
||||
pcrecpp::StringPiece next(newMem.data() + m_tmpFileOffset,
|
||||
newMem.size() - m_tmpFileOffset);
|
||||
const char *end = addVCards(m_contentStartIndex + m_content.size(), next);
|
||||
StringPiece next(newMem.data() + m_tmpFileOffset,
|
||||
newMem.size() - m_tmpFileOffset);
|
||||
const char *end = addVCards(m_contentStartIndex + m_content.size(), next, completed);
|
||||
size_t newTmpFileOffset = end - newMem.data();
|
||||
SE_LOG_DEBUG(NULL, "PBAP content parsed: %ld out of %d (total), %d out of %d (last update)",
|
||||
SE_LOG_DEBUG(NULL, "PBAP content parsed: %ld out of %ld (total), %d out of %ld (last update)",
|
||||
(long)newTmpFileOffset,
|
||||
newMem.size(),
|
||||
(long)newMem.size(),
|
||||
(int)(end - next.data()),
|
||||
next.size());
|
||||
(long)next.size());
|
||||
m_tmpFileOffset = newTmpFileOffset;
|
||||
|
||||
if (completed) {
|
||||
|
@ -1039,7 +1075,7 @@ bool PullAll::getContact(const char *id, pcrecpp::StringPiece &vcard)
|
|||
|
||||
void PbapSession::shutdown(void)
|
||||
{
|
||||
GDBusCXX::DBusClientCall0 removeSession(*m_client, "RemoveSession");
|
||||
GDBusCXX::DBusClientCall<> removeSession(*m_client, "RemoveSession");
|
||||
|
||||
// always clear pointer, even if method call fails
|
||||
GDBusCXX::DBusObject_t path(m_session->getPath());
|
||||
|
@ -1075,9 +1111,9 @@ void PbapSession::setFreeze(bool freeze)
|
|||
true);
|
||||
try {
|
||||
if (freeze) {
|
||||
GDBusCXX::DBusClientCall0(transfer, "Suspend")();
|
||||
GDBusCXX::DBusClientCall<>(transfer, "Suspend")();
|
||||
} else {
|
||||
GDBusCXX::DBusClientCall0(transfer, "Resume")();
|
||||
GDBusCXX::DBusClientCall<>(transfer, "Resume")();
|
||||
}
|
||||
} catch (...) {
|
||||
std::string explanation;
|
||||
|
@ -1101,7 +1137,7 @@ void PbapSession::setFreeze(bool freeze)
|
|||
SE_LOG_DEBUG(NULL, "must retry Suspend(), got error at the moment: %s", explanation.c_str());
|
||||
} else {
|
||||
// Have to abort.
|
||||
GDBusCXX::DBusClientCall0(transfer, "Cancel")();
|
||||
GDBusCXX::DBusClientCall<>(transfer, "Cancel")();
|
||||
|
||||
// Bluez does not change the transfer status when cancelling it,
|
||||
// so our propChangedCb() doesn't get called. We need to record
|
||||
|
@ -1127,7 +1163,7 @@ void PbapSession::blockOnFreeze()
|
|||
SuspendFlags &s = SuspendFlags::getSuspendFlags();
|
||||
while (m_frozen) {
|
||||
s.checkForNormal();
|
||||
g_main_context_iteration(NULL, true);
|
||||
g_main_context_iteration(nullptr, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1135,12 +1171,17 @@ PbapSyncSource::PbapSyncSource(const SyncSourceParams ¶ms) :
|
|||
SyncSource(params)
|
||||
{
|
||||
SyncSourceSession::init(m_operations);
|
||||
m_operations.m_readNextItem = boost::bind(&PbapSyncSource::readNextItem, this, _1, _2, _3);
|
||||
m_operations.m_readItemAsKey = boost::bind(&PbapSyncSource::readItemAsKey,
|
||||
this, _1, _2);
|
||||
m_session = PbapSession::create(*this);
|
||||
m_operations.m_readNextItem = [this] (sysync::ItemID aID,
|
||||
sysync::sInt32 *aStatus,
|
||||
bool aFirst) {
|
||||
return readNextItem(aID, aStatus, aFirst);
|
||||
};
|
||||
m_operations.m_readItemAsKey = [this] (sysync::cItemID aID, sysync::KeyH aItemKey) {
|
||||
return readItemAsKey(aID, aItemKey);
|
||||
};
|
||||
m_session = make_weak_shared::make<PbapSession>(*this);
|
||||
const char *PBAPSyncMode = getenv("SYNCEVOLUTION_PBAP_SYNC");
|
||||
m_PBAPSyncMode = !PBAPSyncMode ? PBAP_SYNC_NORMAL :
|
||||
m_PBAPSyncMode = !PBAPSyncMode ? PBAP_SYNC_INCREMENTAL :
|
||||
boost::iequals(PBAPSyncMode, "incremental") ? PBAP_SYNC_INCREMENTAL :
|
||||
boost::iequals(PBAPSyncMode, "text") ? PBAP_SYNC_TEXT :
|
||||
boost::iequals(PBAPSyncMode, "all") ? PBAP_SYNC_NORMAL :
|
||||
|
@ -1273,13 +1314,13 @@ sysync::TSyError PbapSyncSource::readNextItem(sysync::ItemID aID,
|
|||
PULL_AS_CONFIGURED;
|
||||
|
||||
const char *env;
|
||||
if ((env = getenv("SYNCEVOLUTION_PBAP_CHUNK_TRANSFER_TIME")) != NULL) {
|
||||
if ((env = getenv("SYNCEVOLUTION_PBAP_CHUNK_TRANSFER_TIME")) != nullptr) {
|
||||
params.m_timePerChunk = atof(env);
|
||||
} else {
|
||||
params.m_timePerChunk = 30;
|
||||
}
|
||||
static const double LAMBDA_DEF = 0.1;
|
||||
if ((env = getenv("SYNCEVOLUTION_PBAP_CHUNK_TIME_LAMBDA")) != NULL) {
|
||||
if ((env = getenv("SYNCEVOLUTION_PBAP_CHUNK_TIME_LAMBDA")) != nullptr) {
|
||||
params.m_timeLambda = atof(env);
|
||||
} else {
|
||||
params.m_timeLambda = LAMBDA_DEF;
|
||||
|
@ -1288,13 +1329,13 @@ sysync::TSyError PbapSyncSource::readNextItem(sysync::ItemID aID,
|
|||
params.m_timeLambda > 1) {
|
||||
params.m_timeLambda = LAMBDA_DEF;
|
||||
}
|
||||
if ((env = getenv("SYNCEVOLUTION_PBAP_CHUNK_MAX_COUNT_PHOTO")) != NULL) {
|
||||
if ((env = getenv("SYNCEVOLUTION_PBAP_CHUNK_MAX_COUNT_PHOTO")) != nullptr) {
|
||||
params.m_startMaxCount[true] = atoi(env);
|
||||
}
|
||||
if ((env = getenv("SYNCEVOLUTION_PBAP_CHUNK_MAX_COUNT_NO_PHOTO")) != NULL) {
|
||||
if ((env = getenv("SYNCEVOLUTION_PBAP_CHUNK_MAX_COUNT_NO_PHOTO")) != nullptr) {
|
||||
params.m_startMaxCount[false] = atoi(env);
|
||||
}
|
||||
if ((env = getenv("SYNCEVOLUTION_PBAP_CHUNK_OFFSET")) != NULL) {
|
||||
if ((env = getenv("SYNCEVOLUTION_PBAP_CHUNK_OFFSET")) != nullptr) {
|
||||
params.m_startOffset = atoi(env);
|
||||
} else {
|
||||
unsigned int seed = (unsigned int)Timespec::system().seconds();
|
||||
|
@ -1319,7 +1360,7 @@ sysync::TSyError PbapSyncSource::readNextItem(sysync::ItemID aID,
|
|||
} else {
|
||||
*aStatus = sysync::ReadNextItem_Unchanged;
|
||||
aID->item = StrAlloc(id.c_str());
|
||||
aID->parent = NULL;
|
||||
aID->parent = nullptr;
|
||||
m_hadContacts = true;
|
||||
}
|
||||
return sysync::LOCERR_OK;
|
||||
|
@ -1330,7 +1371,7 @@ sysync::TSyError PbapSyncSource::readItemAsKey(sysync::cItemID aID, sysync::KeyH
|
|||
if (!m_pullAll) {
|
||||
throwError(SE_HERE, "logic error: readItemAsKey() without preceeding readNextItem()");
|
||||
}
|
||||
pcrecpp::StringPiece vcard;
|
||||
StringPiece vcard;
|
||||
if (m_pullAll->getContact(aID->item, vcard)) {
|
||||
return getSynthesisAPI()->setValue(aItemKey, "itemdata", vcard.data(), vcard.size());
|
||||
} else {
|
||||
|
@ -1349,7 +1390,7 @@ void PbapSyncSource::readItemRaw(const std::string &luid, std::string &item)
|
|||
if (!m_pullAll) {
|
||||
throwError(SE_HERE, "logic error: readItemRaw() without preceeding readNextItem()");
|
||||
}
|
||||
pcrecpp::StringPiece vcard;
|
||||
StringPiece vcard;
|
||||
if (m_pullAll->getContact(luid.c_str(), vcard)) {
|
||||
item.assign(vcard.data(), vcard.size());
|
||||
} else {
|
||||
|
|
|
@ -28,8 +28,6 @@
|
|||
#include <memory>
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
#include <pcrecpp.h>
|
||||
|
||||
#include <syncevo/declarations.h>
|
||||
#include <syncevo/TmpFile.h>
|
||||
SE_BEGIN_CXX
|
||||
|
@ -65,8 +63,8 @@ class PbapSyncSource : virtual public SyncSource, virtual public SyncSourceSessi
|
|||
virtual void readItemRaw(const std::string &luid, std::string &item);
|
||||
|
||||
private:
|
||||
boost::shared_ptr<PbapSession> m_session;
|
||||
boost::shared_ptr<PullAll> m_pullAll;
|
||||
std::shared_ptr<PbapSession> m_session;
|
||||
std::shared_ptr<PullAll> m_pullAll;
|
||||
enum PBAPSyncMode {
|
||||
PBAP_SYNC_NORMAL, ///< Read contact data according to filter.
|
||||
PBAP_SYNC_TEXT, ///< Sync without reading photo data from phone and keeping local photos instead.
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include <syncevo/declarations.h>
|
||||
SE_BEGIN_CXX
|
||||
|
||||
static SyncSource *createSource(const SyncSourceParams ¶ms)
|
||||
static std::unique_ptr<SyncSource> createSource(const SyncSourceParams ¶ms)
|
||||
{
|
||||
SourceType sourceType = SyncSource::getSourceType(params.m_nodes);
|
||||
// The string returned by getSourceType() is always the one
|
||||
|
@ -35,16 +35,16 @@ static SyncSource *createSource(const SyncSourceParams ¶ms)
|
|||
#ifndef ENABLE_PBAP
|
||||
// tell SyncEvolution if the user wanted to use a disabled sync source,
|
||||
// otherwise let it continue searching
|
||||
return isMe ? RegisterSyncSource::InactiveSource(params) : NULL;
|
||||
return isMe ? RegisterSyncSource::InactiveSource(params) : nullptr;
|
||||
#else
|
||||
// Also recognize one of the standard types?
|
||||
// Not in the PbapSyncSource!
|
||||
bool maybeMe = false /* sourceType.m_backend == "addressbook" */;
|
||||
|
||||
if (isMe || maybeMe) {
|
||||
return new PbapSyncSource(params);
|
||||
return std::make_unique<PbapSyncSource>(params);
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ src_backends_pbap_src = \
|
|||
src/backends/pbap/PbapSyncSource.cpp
|
||||
|
||||
src_backends_pbap_syncpbap_la_SOURCES = $(src_backends_pbap_src)
|
||||
src_backends_pbap_syncpbap_la_LIBADD = $(PBAP_LIBS) $(PCRECPP_LIBS) $(SYNCEVOLUTION_LIBS) $(DBUS_LIBS) $(gdbus_build_dir)/libgdbussyncevo.la
|
||||
src_backends_pbap_syncpbap_la_LIBADD = $(PBAP_LIBS) $(SYNCEVOLUTION_LIBS) $(DBUS_LIBS) $(gdbus_build_dir)/libgdbussyncevo.la
|
||||
src_backends_pbap_syncpbap_la_LDFLAGS = -module -avoid-version $(DBUS_LIBS)
|
||||
src_backends_pbap_syncpbap_la_CXXFLAGS = $(SYNCEVOLUTION_CXXFLAGS) $(SYNCEVO_WFLAGS) $(DBUS_CFLAGS)
|
||||
src_backends_pbap_syncpbap_la_CPPFLAGS = $(SYNCEVOLUTION_CFLAGS) -I$(gdbus_dir) -I$(top_srcdir)/test $(BACKEND_CPPFLAGS)
|
||||
|
|
|
@ -154,7 +154,7 @@ public:
|
|||
QStringList content;
|
||||
content << detail.definitionName(); // <detail>
|
||||
QVariantMap fields = detail.variantValues();
|
||||
for (QVariantMap::const_iterator entry = fields.begin();
|
||||
for (auto entry = fields.begin();
|
||||
entry != fields.end();
|
||||
++entry) {
|
||||
const QString &fieldName = entry.key();
|
||||
|
@ -198,7 +198,7 @@ public:
|
|||
#else
|
||||
StringEscape escape('|', "^");
|
||||
std::list<std::string> strings;
|
||||
BOOST_FOREACH(const QString &str, content) {
|
||||
for (const QString &str: content) {
|
||||
strings.push_back(escape.escape(string(str.toUtf8().constData())));
|
||||
}
|
||||
prop.setValue(QVariant(QString::fromUtf8(boost::join(strings, "^").c_str())));
|
||||
|
@ -237,7 +237,7 @@ public:
|
|||
// detail name available?
|
||||
if (content.size() > 0) {
|
||||
const QString &detailName = content[0];
|
||||
QMap<QString, QContactDetailDefinition>::const_iterator it = m_details.constFind(detailName);
|
||||
auto it = m_details.constFind(detailName);
|
||||
// detail still exists?
|
||||
if (it != m_details.constEnd()) {
|
||||
const QContactDetailDefinition &definition = *it;
|
||||
|
@ -273,9 +273,8 @@ public:
|
|||
}
|
||||
|
||||
// skip fields which are (no longer) valid, have wrong type or wrong value
|
||||
QMap<QString, QContactDetailFieldDefinition> fields = definition.fields();
|
||||
QMap<QString, QContactDetailFieldDefinition>::const_iterator it2 =
|
||||
fields.constFind(fieldName);
|
||||
auto fields = definition.fields();
|
||||
auto it2 = fields.constFind(fieldName);
|
||||
if (it2 != fields.constEnd()) {
|
||||
if (it2->dataType() == value.type()) {
|
||||
QVariantList allowed = it2->allowableValues();
|
||||
|
@ -376,7 +375,7 @@ public:
|
|||
QtContactsSource::QtContactsSource(const SyncSourceParams ¶ms) :
|
||||
TrackingSyncSource(params)
|
||||
{
|
||||
m_data = NULL;
|
||||
m_data = nullptr;
|
||||
SyncSourceLogging::init(InitList<std::string>("N_FIRST") + "N_MIDDLE" + "N_LAST",
|
||||
" ",
|
||||
m_operations);
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include <syncevo/declarations.h>
|
||||
SE_BEGIN_CXX
|
||||
|
||||
static SyncSource *createSource(const SyncSourceParams ¶ms)
|
||||
static std::unique_ptr<SyncSource> createSource(const SyncSourceParams ¶ms)
|
||||
{
|
||||
SourceType sourceType = SyncSource::getSourceType(params.m_nodes);
|
||||
bool isMe = sourceType.m_backend == "QtContacts";
|
||||
|
@ -44,10 +44,10 @@ static SyncSource *createSource(const SyncSourceParams ¶ms)
|
|||
#ifdef ENABLE_QTCONTACTS
|
||||
true ? new QtContactsSource(params) :
|
||||
#endif
|
||||
isMe ? RegisterSyncSource::InactiveSource(params) : NULL;
|
||||
isMe ? RegisterSyncSource::InactiveSource(params) : nullptr;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static RegisterSyncSource registerMe("QtContacts",
|
||||
|
@ -76,9 +76,9 @@ class QtContactsSourceUnitTest : public CppUnit::TestFixture {
|
|||
|
||||
protected:
|
||||
void testInstantiate() {
|
||||
boost::shared_ptr<SyncSource> source;
|
||||
source.reset(SyncSource::createTestingSource("qtcontacts", "qtcontacts:text/vcard:3.0", true));
|
||||
source.reset(SyncSource::createTestingSource("qtcontacts", "QtContacts", true));
|
||||
std::unique_ptr<SyncSource> source;
|
||||
source = SyncSource::createTestingSource("qtcontacts", "qtcontacts:text/vcard:3.0", true);
|
||||
source = SyncSource::createTestingSource("qtcontacts", "QtContacts", true);
|
||||
}
|
||||
|
||||
void testHandler() {
|
||||
|
|
|
@ -38,9 +38,8 @@
|
|||
|
||||
#include <syncevo/GLibSupport.h>
|
||||
#include <syncevo/GVariantSupport.h>
|
||||
#include <pcrecpp.h>
|
||||
|
||||
#include <boost/lambda/core.hpp>
|
||||
#include <regex>
|
||||
|
||||
SE_GOBJECT_TYPE(SignonAuthService)
|
||||
SE_GOBJECT_TYPE(SignonAuthSession)
|
||||
|
@ -111,8 +110,8 @@ public:
|
|||
SE_THROW("Username or password missing");
|
||||
}
|
||||
Credentials credentials;
|
||||
credentials.m_username = g_variant_get_string(usernameVar, NULL);
|
||||
credentials.m_password = g_variant_get_string(passwordVar, NULL);
|
||||
credentials.m_username = g_variant_get_string(usernameVar, nullptr);
|
||||
credentials.m_password = g_variant_get_string(passwordVar, nullptr);
|
||||
if (credentials.m_password.empty()) {
|
||||
SE_THROW("Got an empty password");
|
||||
} else if (m_invalidateCache &&
|
||||
|
@ -145,7 +144,7 @@ public:
|
|||
if (!tokenVar) {
|
||||
SE_THROW("no AccessToken in OAuth2 response");
|
||||
}
|
||||
std::string newToken = g_variant_get_string(tokenVar, NULL);
|
||||
std::string newToken = g_variant_get_string(tokenVar, nullptr);
|
||||
if (newToken.empty()) {
|
||||
SE_THROW("AccessToken did not contain a string value");
|
||||
} else if (m_invalidateCache && newToken == m_accessToken) {
|
||||
|
@ -175,8 +174,8 @@ private:
|
|||
|
||||
#define signon_auth_session_process_async_finish signon_auth_session_process_finish
|
||||
SYNCEVO_GLIB_CALL_SYNC(resultData, gerror, signon_auth_session_process_async,
|
||||
m_authSession, sessionData, mechanism, NULL);
|
||||
buffer.reset(resultData ? g_variant_print(resultData, true) : NULL);
|
||||
m_authSession, sessionData, mechanism, nullptr);
|
||||
buffer.reset(resultData ? g_variant_print(resultData, true) : nullptr);
|
||||
SE_LOG_DEBUG(NULL, "authentication result: %s, %s",
|
||||
buffer.get() ? buffer.get() : "<<null>>",
|
||||
gerror ? gerror->message : "???");
|
||||
|
@ -210,21 +209,22 @@ static void StoreIdentityCB(SignonIdentity *self,
|
|||
data->m_gerror = error;
|
||||
}
|
||||
|
||||
boost::shared_ptr<AuthProvider> createSignonAuthProvider(const InitStateString &username,
|
||||
std::shared_ptr<AuthProvider> createSignonAuthProvider(const InitStateString &username,
|
||||
const InitStateString &password)
|
||||
{
|
||||
boost::shared_ptr<AuthProvider> provider;
|
||||
std::shared_ptr<AuthProvider> provider;
|
||||
|
||||
// Split username into <account ID> and <service name>.
|
||||
// Be flexible and allow leading/trailing white space.
|
||||
// Comma is optional.
|
||||
static const pcrecpp::RE re("^\\s*(\\d+)\\s*,?\\s*(.*)\\s*$");
|
||||
AgAccountId accountID;
|
||||
std::string serviceName;
|
||||
if (!re.FullMatch(username, &accountID, &serviceName)) {
|
||||
static const std::regex re(R"del(\s*(\d+)\s*,?\s*(.*)\s*)del");
|
||||
std::smatch match;
|
||||
if (!std::regex_match(username, match, re)) {
|
||||
SE_THROW(StringPrintf("username must have the format " SE_SIGNON_PROVIDER_ID ":<account ID>,<service name>: %s",
|
||||
username.c_str()));
|
||||
}
|
||||
AgAccountId accountID = std::stol(match[1].str());
|
||||
std::string serviceName = match[2].str();
|
||||
SE_LOG_DEBUG(NULL, "looking up account ID %d and service '%s'",
|
||||
accountID,
|
||||
serviceName.c_str());
|
||||
|
@ -243,10 +243,10 @@ boost::shared_ptr<AuthProvider> createSignonAuthProvider(const InitStateString &
|
|||
}
|
||||
AgAccountServiceCXX accountService;
|
||||
if (serviceName.empty()) {
|
||||
accountService = AgAccountServiceCXX::steal(ag_account_service_new(account, NULL));
|
||||
accountService = AgAccountServiceCXX::steal(ag_account_service_new(account, nullptr));
|
||||
} else {
|
||||
ServiceListCXX services(ag_account_list_enabled_services(account));
|
||||
BOOST_FOREACH (AgService *service, services) {
|
||||
for (AgService *service: services) {
|
||||
const char *name = ag_service_get_name(service);
|
||||
SE_LOG_DEBUG(NULL, "enabled service: %s", name);
|
||||
if (serviceName == name) {
|
||||
|
|
|
@ -49,9 +49,9 @@ else
|
|||
noinst_LTLIBRARIES += $(src_backends_signon_libs)
|
||||
endif
|
||||
|
||||
src_backends_signon_common_libadd = $(SYNCEVOLUTION_LIBS)
|
||||
src_backends_signon_common_libadd = $(SYNCEVOLUTION_LIBS) $(PCRECPP_LIBS)
|
||||
src_backends_signon_common_ldflags = -module -avoid-version
|
||||
src_backends_signon_common_cxxflags = $(SYNCEVOLUTION_CFLAGS)
|
||||
src_backends_signon_common_cxxflags = $(SYNCEVOLUTION_CFLAGS) $(PCRECPP_CFLAGS)
|
||||
src_backends_signon_common_cppflags = -DUSE_SIGNON -I$(top_srcdir)/test $(BACKEND_CPPFLAGS)
|
||||
src_backends_signon_common_dependencies = src/syncevo/libsyncevolution.la
|
||||
|
||||
|
|
|
@ -32,9 +32,6 @@
|
|||
|
||||
#include <syncevo/GLibSupport.h>
|
||||
#include <syncevo/GVariantSupport.h>
|
||||
#include <pcrecpp.h>
|
||||
|
||||
#include <boost/lambda/core.hpp>
|
||||
|
||||
SE_GOBJECT_TYPE(SignonAuthService)
|
||||
SE_GOBJECT_TYPE(SignonAuthSession)
|
||||
|
@ -94,8 +91,8 @@ public:
|
|||
|
||||
#define signon_auth_session_process_async_finish signon_auth_session_process_finish
|
||||
SYNCEVO_GLIB_CALL_SYNC(resultDataVar, gerror, signon_auth_session_process_async,
|
||||
m_authSession, sessionDataVar, m_mechanism.c_str(), NULL);
|
||||
buffer.reset(resultDataVar ? g_variant_print(resultDataVar, true) : NULL);
|
||||
m_authSession, sessionDataVar, m_mechanism.c_str(), nullptr);
|
||||
buffer.reset(resultDataVar ? g_variant_print(resultDataVar, true) : nullptr);
|
||||
SE_LOG_DEBUG(NULL, "OAuth2 token result: %s, %s",
|
||||
buffer.get() ? buffer.get() : "<<null>>",
|
||||
gerror ? gerror->message : "???");
|
||||
|
@ -109,7 +106,7 @@ public:
|
|||
if (!tokenVar) {
|
||||
SE_THROW("no AccessToken in OAuth2 response");
|
||||
}
|
||||
std::string newToken = g_variant_get_string(tokenVar, NULL);
|
||||
std::string newToken = g_variant_get_string(tokenVar, nullptr);
|
||||
if (newToken.empty()) {
|
||||
SE_THROW("AccessToken did not contain a string value");
|
||||
} else if (m_invalidateCache && newToken == m_accessToken) {
|
||||
|
@ -124,15 +121,15 @@ public:
|
|||
virtual std::string getUsername() const { return ""; }
|
||||
};
|
||||
|
||||
boost::shared_ptr<AuthProvider> createSignonAuthProvider(const InitStateString &username,
|
||||
std::shared_ptr<AuthProvider> createSignonAuthProvider(const InitStateString &username,
|
||||
const InitStateString &password)
|
||||
{
|
||||
// Expected content of parameter GVariant.
|
||||
boost::shared_ptr<GVariantType> hashtype(g_variant_type_new("a{sv}"), g_variant_type_free);
|
||||
std::shared_ptr<GVariantType> hashtype(g_variant_type_new("a{sv}"), g_variant_type_free);
|
||||
|
||||
// 'username' is the part after signon: which we can parse directly.
|
||||
GErrorCXX gerror;
|
||||
GVariantCXX parametersVar(g_variant_parse(hashtype.get(), username.c_str(), NULL, NULL, gerror),
|
||||
GVariantCXX parametersVar(g_variant_parse(hashtype.get(), username.c_str(), nullptr, nullptr, gerror),
|
||||
TRANSFER_REF);
|
||||
if (!parametersVar) {
|
||||
gerror.throwError(SE_HERE, "parsing 'signon:' username");
|
||||
|
@ -157,14 +154,14 @@ boost::shared_ptr<AuthProvider> createSignonAuthProvider(const InitStateString &
|
|||
!g_variant_type_equal(G_VARIANT_TYPE_STRING, g_variant_get_type(value))) {
|
||||
SE_THROW("need 'method: <string>' in 'signon:' parameters");
|
||||
}
|
||||
method = g_variant_get_string(value, NULL);
|
||||
method = g_variant_get_string(value, nullptr);
|
||||
|
||||
value = (GVariant *)g_hash_table_lookup(parameters, "mechanism");
|
||||
if (!value ||
|
||||
!g_variant_type_equal(G_VARIANT_TYPE_STRING, g_variant_get_type(value))) {
|
||||
SE_THROW("need 'mechanism: <string>' in 'signon:' parameters");
|
||||
}
|
||||
mechanism = g_variant_get_string(value, NULL);
|
||||
mechanism = g_variant_get_string(value, nullptr);
|
||||
|
||||
value = (GVariant *)g_hash_table_lookup(parameters, "session");
|
||||
if (!value ||
|
||||
|
@ -179,7 +176,7 @@ boost::shared_ptr<AuthProvider> createSignonAuthProvider(const InitStateString &
|
|||
SE_LOG_DEBUG(NULL, "using signond identity %d", signonID);
|
||||
SignonAuthSessionCXX authSession(signon_identity_create_session(identity, method, gerror), TRANSFER_REF);
|
||||
|
||||
boost::shared_ptr<AuthProvider> provider(new SignonAuthProvider(authSession, sessionData, mechanism));
|
||||
auto provider = std::make_shared<SignonAuthProvider>(authSession, sessionData, mechanism);
|
||||
return provider;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
#include <syncevo/util.h>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <memory>
|
||||
|
||||
#include <syncevo/declarations.h>
|
||||
SE_BEGIN_CXX
|
||||
|
@ -35,7 +35,7 @@ SE_BEGIN_CXX
|
|||
#endif
|
||||
|
||||
class AuthProvider;
|
||||
boost::shared_ptr<AuthProvider> createSignonAuthProvider(const InitStateString &username,
|
||||
std::shared_ptr<AuthProvider> createSignonAuthProvider(const InitStateString &username,
|
||||
const InitStateString &password);
|
||||
|
||||
SE_END_CXX
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue