Comparar commits
14 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| 942136167a | |||
| 2c6324e3e5 | |||
| e442ba863a | |||
| e5471d8318 | |||
| 902bb7a198 | |||
| 4fc044d368 | |||
| bb32831a60 | |||
| ea690c285b | |||
| 28879712e9 | |||
| 3c2e43d883 | |||
| 5041880854 | |||
| 2c904afd04 | |||
| 2cc13fb74a | |||
| df3c3bca02 |
+1
-1
@@ -2,4 +2,4 @@
|
||||
.gitignore export-ignore
|
||||
.gitattributes export-ignore
|
||||
.commit-template export-ignore
|
||||
binary/ export-ignore
|
||||
/binary export-ignore
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
language: cpp
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
|
||||
env:
|
||||
- QT=qt4
|
||||
- QT=qt5 PATH=/opt/Qt/5.3/gcc_64/bin:/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin
|
||||
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
before_install:
|
||||
- sh -c "if [ '$QT' = 'qt4' ]; then wget http://download.opensuse.org/repositories/isv:ownCloud:desktop/xUbuntu_12.04/Release.key; sudo apt-key add - < Release.key; fi"
|
||||
- sudo sh -c "if [ '$QT' = 'qt4' ]; then echo 'deb http://download.opensuse.org/repositories/isv:/ownCloud:/desktop/xUbuntu_12.04/ /' > /etc/apt/sources.list.d/qtkeychain.list; fi"
|
||||
- sh -c "if [ '$QT' = 'qt4' ]; then sudo apt-get update -qq; sudo apt-get install -qq libqt4-dev qt4-dev-tools libqtkeychain-dev; fi"
|
||||
- sh -c "if [ '$QT' = 'qt5' ]; then sudo apt-add-repository -y ppa:canonical-qt5-edgers/qt5-daily; sudo apt-get update -qq; sudo apt-get install -qq qtdeclarative5-dev libqt5webkit5-dev qttools5-dev; fi"
|
||||
- sh -c "if [ '$QT' = 'qt5' ]; then wget http://download.opensuse.org/repositories/home:/DeepDiver1975:/branches:/isv:/ownCloud:/desktop/xUbuntu_13.10/Release.key; sudo apt-key add - < Release.key; fi"
|
||||
- sudo sh -c "if [ '$QT' = 'qt5' ]; then echo 'deb http://download.opensuse.org/repositories/home:/DeepDiver1975:/branches:/isv:/ownCloud:/desktop/xUbuntu_13.10/ /' > /etc/apt/sources.list.d/qt5keychain.list; fi"
|
||||
- sh -c "if [ '$QT' = 'qt5' ]; then wget http://download.owncloud.com/download/qt-5.3-travis.tar.xz; fi"
|
||||
- sh -c "if [ '$QT' = 'qt5' ]; then sudo tar xif -C /opt ~/qt-5.3-travis.tar.xz; fi"
|
||||
- sudo apt-get update -qq
|
||||
- sudo apt-get install -qq cmake sqlite3 libneon27-gnutls-dev
|
||||
|
||||
before_script:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake -DUNIT_TESTING=1 ..
|
||||
|
||||
script:
|
||||
- make
|
||||
- ctest --output-on-failure
|
||||
|
||||
+3
-11
@@ -20,7 +20,6 @@ if (NOT DEFINED APPLICATION_SHORTNAME)
|
||||
endif()
|
||||
|
||||
include(${CMAKE_SOURCE_DIR}/VERSION.cmake)
|
||||
configure_file( ${CMAKE_SOURCE_DIR}/src/mirall/version.h.in "${CMAKE_CURRENT_BINARY_DIR}/src/mirall/version.h" )
|
||||
include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR} "${CMAKE_CURRENT_BINARY_DIR}/src/mirall/")
|
||||
|
||||
#####
|
||||
@@ -62,9 +61,9 @@ set(DATADIR ${DATA_INSTALL_DIR})
|
||||
# BUILD_OWNCLOUD_OSX_BUNDLE was not initialized OR set to true on OSX
|
||||
if(APPLE AND (NOT DEFINED BUILD_OWNCLOUD_OSX_BUNDLE OR BUILD_OWNCLOUD_OSX_BUNDLE))
|
||||
set(BUILD_OWNCLOUD_OSX_BUNDLE ON)
|
||||
set(OWNCLOUD_OSX_BUNDLE "${APPLICATION_EXECUTABLE}.app")
|
||||
set(LIB_INSTALL_DIR "${APPLICATION_EXECUTABLE}.app/Contents/MacOS")
|
||||
set(BIN_INSTALL_DIR "${APPLICATION_EXECUTABLE}.app/Contents/MacOS")
|
||||
set(OWNCLOUD_OSX_BUNDLE "bin/${APPLICATION_EXECUTABLE}.app")
|
||||
set(LIB_INSTALL_DIR "bin/${APPLICATION_EXECUTABLE}.app/Contents/MacOS")
|
||||
set(BIN_INSTALL_DIR "bin/${APPLICATION_EXECUTABLE}.app/Contents/MacOS")
|
||||
|
||||
# BUILD_OWNCLOUD_OSX_BUNDLE was disabled on OSX
|
||||
elseif(APPLE AND NOT BUILD_OWNCLOUD_OSX_BUNDLE)
|
||||
@@ -128,11 +127,6 @@ configure_file(config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
|
||||
|
||||
configure_file(test/test_journal.db "${CMAKE_BINARY_DIR}/test/test_journal.db" COPYONLY)
|
||||
|
||||
# Copy that logo, the installer uses it later
|
||||
if(BUILD_OWNCLOUD_OSX_BUNDLE)
|
||||
install(FILES resources/owncloud_logo_blue.png DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/Resources/)
|
||||
endif()
|
||||
|
||||
include(OwnCloudCPack.cmake)
|
||||
|
||||
add_definitions(-DUNICODE)
|
||||
@@ -149,7 +143,6 @@ add_subdirectory(csync)
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(shell_integration)
|
||||
add_subdirectory(doc)
|
||||
add_subdirectory(admin)
|
||||
|
||||
if(UNIT_TESTING)
|
||||
include(CTest)
|
||||
@@ -161,5 +154,4 @@ if(BUILD_OWNCLOUD_OSX_BUNDLE)
|
||||
configure_file(sync-exclude.lst ${OWNCLOUD_OSX_BUNDLE}/Contents/Resources/sync-exclude.lst COPYONLY)
|
||||
else()
|
||||
install( FILES sync-exclude.lst DESTINATION ${SYSCONFDIR}/${APPLICATION_SHORTNAME} )
|
||||
configure_file(sync-exclude.lst bin/sync-exclude.lst COPYONLY)
|
||||
endif()
|
||||
|
||||
+1
-2
@@ -1,7 +1,6 @@
|
||||
ChangeLog
|
||||
=========
|
||||
version 1.6.2 (release 2014-07-28 )
|
||||
* Limit the HTTP buffer size when downloading to limit memory consumption.
|
||||
version 1.6.2 (release 2014-07-x )
|
||||
* Another small mem leak fixed in HTTP Credentials.
|
||||
* Fix local file name clash detection for MacOSX.
|
||||
* Limit maximum wait time to ten seconds in network limiting.
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ set( MIRALL_VERSION_PATCH 0 )
|
||||
set( MIRALL_SOVERSION 0 )
|
||||
|
||||
if ( NOT DEFINED MIRALL_VERSION_SUFFIX )
|
||||
set( MIRALL_VERSION_SUFFIX "beta3") #e.g. beta1, beta2, rc1
|
||||
set( MIRALL_VERSION_SUFFIX "beta1") #e.g. beta1, beta2, rc1
|
||||
endif( NOT DEFINED MIRALL_VERSION_SUFFIX )
|
||||
|
||||
if( NOT DEFINED MIRALL_VERSION_BUILD )
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
# traverse into osx subdirectory to install and patch the create-pack script
|
||||
add_subdirectory(osx)
|
||||
@@ -1,3 +0,0 @@
|
||||
|
||||
configure_file(create_mac_pkg.sh.cmake ${CMAKE_CURRENT_BINARY_DIR}/create_mac.sh)
|
||||
configure_file(macosx.pkgproj ${CMAKE_CURRENT_BINARY_DIR}/macosx.pkgproj)
|
||||
Arquivo executável
+45
@@ -0,0 +1,45 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script to create the Mac installer using the packages tool from
|
||||
# http://s.sudre.free.fr/Software/Packages/about.html
|
||||
#
|
||||
|
||||
# the path of installation must be given as parameter
|
||||
if [ -z "$1" ]; then
|
||||
echo "ERROR: Provide the CMAKE_INSTALL_DIR to this script."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
prjfile="admin/osx/macosx.pkgproj"
|
||||
if [ ! -f $prjfile ]; then
|
||||
echo "ERROR: macosx.pkgproj not in admin dir, start from CMAKE_SOURCE_DIR!"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
pack="admin/ownCloud Installer.pkg"
|
||||
rm -f $pack
|
||||
|
||||
install_path=$1
|
||||
|
||||
# The name of the installer package
|
||||
installer=ownCloud\ Installer.pkg
|
||||
|
||||
# The command line tool of the "Packages" tool, see link above.
|
||||
pkgbuild=/usr/local/bin/packagesbuild
|
||||
|
||||
$pkgbuild -F $install_path $prjfile
|
||||
rc=$?
|
||||
|
||||
if [ $rc == 0 ]; then
|
||||
echo "Successfully created $pack"
|
||||
else
|
||||
echo "Failed to create $pack"
|
||||
exit 3
|
||||
fi
|
||||
|
||||
# FIXME: Sign the finished package.
|
||||
# See http://s.sudre.free.fr/Software/documentation/Packages/en/Project_Configuration.html#5
|
||||
# certname=gdbsign
|
||||
# productsign --cert $certname admin/$installer ./$installer
|
||||
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script to create the Mac installer using the packages tool from
|
||||
# http://s.sudre.free.fr/Software/Packages/about.html
|
||||
#
|
||||
|
||||
[ "$#" -lt 2 ] && echo "Usage: create_mac_pkg.sh <CMAKE_INSTALL_DIR> <build dir> <installer sign identity>" && exit
|
||||
|
||||
# the path of installation must be given as parameter
|
||||
if [ -z "$1" ]; then
|
||||
echo "ERROR: Provide the path to CMAKE_INSTALL_DIR to this script as first parameter."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$2" ]; then
|
||||
echo "ERROR: Provide the path to build directory as second parameter."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
install_path="$1"
|
||||
build_path="$2"
|
||||
identity="$3"
|
||||
prjfile=$build_path/admin/osx/macosx.pkgproj
|
||||
|
||||
# The name of the installer package
|
||||
installer="@APPLICATION_NAME@-@MIRALL_VERSION_FULL@@MIRALL_VERSION_SUFFIX@"
|
||||
installer_file="$installer.pkg"
|
||||
installer_file_tar="$installer.pkg.tar"
|
||||
installer_file_tar_bz2="$installer.pkg.tar.bz2"
|
||||
installer_file_tbz="$installer.pkg.tbz"
|
||||
|
||||
# set the installer name to the copied prj config file
|
||||
/usr/local/bin/packagesutil --file $prjfile set project name "$installer"
|
||||
|
||||
# The command line tool of the "Packages" tool, see link above.
|
||||
pkgbuild=/usr/local/bin/packagesbuild
|
||||
|
||||
$pkgbuild -F $install_path $prjfile
|
||||
rc=$?
|
||||
|
||||
if [ $rc == 0 ]; then
|
||||
echo "Successfully created $installer_file"
|
||||
else
|
||||
echo "Failed to create $installer_file"
|
||||
exit 3
|
||||
fi
|
||||
|
||||
# Sign the finished package if desired.
|
||||
if [ ! -z "$identity" ]; then
|
||||
echo "Will try to sign the installer"
|
||||
pushd $install_path
|
||||
productsign --sign "$identity" "$installer_file" "$installer_file.new"
|
||||
mv "$installer_file".new $installer_file
|
||||
popd
|
||||
else
|
||||
echo "No certificate given, will not sign the pkg"
|
||||
fi
|
||||
|
||||
# FIXME: OEMs?
|
||||
# they will need to do their own signing..
|
||||
|
||||
|
||||
# Sparkle wants a tbz, it cannot install raw pkg
|
||||
cd $install_path
|
||||
tar cf "$installer_file_tar" "$installer_file"
|
||||
bzip2 -9 "$installer_file_tar"
|
||||
mv "$installer_file_tar_bz2" "$installer_file_tbz"
|
||||
rc=$?
|
||||
if [ $rc == 0 ]; then
|
||||
echo "Successfully created $installer_file"
|
||||
else
|
||||
echo "Failed to create $installer_file"
|
||||
exit 3
|
||||
fi
|
||||
@@ -1,330 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
# This file is part of ownCloud.
|
||||
# It was inspired in large part by the macdeploy script in Clementine
|
||||
# and Tomahawk
|
||||
#
|
||||
# ownCloud 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 2 of the License.
|
||||
#
|
||||
# ownCLoud 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with ownCloud. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import commands
|
||||
import sys
|
||||
from glob import glob
|
||||
|
||||
def QueryQMake(attrib):
|
||||
return subprocess.check_output(['qmake', '-query', attrib]).rstrip('\n')
|
||||
|
||||
FRAMEWORK_SEARCH_PATH=[
|
||||
'/Library/Frameworks',
|
||||
os.path.join(os.environ['HOME'], 'Library/Frameworks')
|
||||
]
|
||||
|
||||
LIBRARY_SEARCH_PATH=['/usr/local/lib', '.']
|
||||
|
||||
QT_PLUGINS = [
|
||||
'accessible/libqtaccessiblewidgets.dylib',
|
||||
'sqldrivers/libqsqlite.dylib',
|
||||
'platforms/libqcocoa.dylib',
|
||||
'imageformats/libqgif.dylib',
|
||||
'imageformats/libqico.dylib',
|
||||
'imageformats/libqjpeg.dylib',
|
||||
'imageformats/libqsvg.dylib',
|
||||
'imageformats/libqmng.dylib',
|
||||
]
|
||||
|
||||
QT_PLUGINS_SEARCH_PATH=[
|
||||
# os.path.join(os.environ['QTDIR'], 'plugins'),
|
||||
'/usr/local/Cellar/qt/5.2.1/plugins',
|
||||
]
|
||||
|
||||
|
||||
class Error(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class CouldNotFindQtPluginErrorFindFrameworkError(Error):
|
||||
pass
|
||||
|
||||
|
||||
class InstallNameToolError(Error):
|
||||
pass
|
||||
|
||||
|
||||
class CouldNotFindQtPluginError(Error):
|
||||
pass
|
||||
|
||||
|
||||
class CouldNotFindScriptPluginError(Error):
|
||||
pass
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print 'Usage: %s <bundle.app>' % sys.argv[0]
|
||||
exit()
|
||||
|
||||
def is_exe(fpath):
|
||||
return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
|
||||
|
||||
bundle_dir = sys.argv[1]
|
||||
|
||||
bundle_name = os.path.basename(bundle_dir).split('.')[0]
|
||||
|
||||
commands = []
|
||||
|
||||
binary_dir = os.path.join(bundle_dir, 'Contents', 'MacOS')
|
||||
frameworks_dir = os.path.join(bundle_dir, 'Contents', 'Frameworks')
|
||||
commands.append(['mkdir', '-p', frameworks_dir])
|
||||
resources_dir = os.path.join(bundle_dir, 'Contents', 'Resources')
|
||||
commands.append(['mkdir', '-p', resources_dir])
|
||||
plugins_dir = os.path.join(bundle_dir, 'Contents', 'PlugIns')
|
||||
binaries = [i for i in glob(os.path.join(bundle_dir, 'Contents', 'MacOS', "*")) if is_exe(i)];
|
||||
|
||||
|
||||
fixed_libraries = []
|
||||
fixed_frameworks = []
|
||||
|
||||
def WriteQtConf():
|
||||
print "Writing qt.conf..."
|
||||
with open(os.path.join(resources_dir, 'qt.conf'), 'w') as f:
|
||||
f.write("[Paths]\nPlugins = PlugIns\n");
|
||||
f.close()
|
||||
|
||||
def GetBrokenLibraries(binary):
|
||||
#print "Checking libs for binary: %s" % binary
|
||||
output = subprocess.Popen(['otool', '-L', binary], stdout=subprocess.PIPE).communicate()[0]
|
||||
broken_libs = {
|
||||
'frameworks': [],
|
||||
'libs': []}
|
||||
for line in [x.split(' ')[0].lstrip() for x in output.split('\n')[1:]]:
|
||||
#print "Checking line: %s" % line
|
||||
if not line: # skip empty lines
|
||||
continue
|
||||
if os.path.basename(binary) == os.path.basename(line):
|
||||
#print "mnope %s-%s" % (os.path.basename(binary), os.path.basename(line))
|
||||
continue
|
||||
if re.match(r'^\s*/System/', line):
|
||||
continue # System framework
|
||||
elif re.match(r'^\s*/usr/lib/', line):
|
||||
#print "unix style system lib"
|
||||
continue # unix style system library
|
||||
elif re.match(r'Breakpad', line):
|
||||
continue # Manually added by cmake.
|
||||
elif re.match(r'^\s*@executable_path', line) or re.match(r'^\s*@loader_path', line):
|
||||
# Potentially already fixed library
|
||||
if '.framework' in line:
|
||||
relative_path = os.path.join(*line.split('/')[3:])
|
||||
if not os.path.exists(os.path.join(frameworks_dir, relative_path)):
|
||||
broken_libs['frameworks'].append(relative_path)
|
||||
else:
|
||||
relative_path = os.path.join(*line.split('/')[1:])
|
||||
#print "RELPATH %s %s" % (relative_path, os.path.join(binary_dir, relative_path))
|
||||
if not os.path.exists(os.path.join(binary_dir, relative_path)):
|
||||
broken_libs['libs'].append(relative_path)
|
||||
elif re.search(r'\w+\.framework', line):
|
||||
broken_libs['frameworks'].append(line)
|
||||
else:
|
||||
broken_libs['libs'].append(line)
|
||||
|
||||
return broken_libs
|
||||
|
||||
def FindFramework(path):
|
||||
search_pathes = FRAMEWORK_SEARCH_PATH
|
||||
search_pathes.insert(0, QueryQMake('QT_INSTALL_LIBS'))
|
||||
for search_path in search_pathes:
|
||||
abs_path = os.path.join(search_path, path)
|
||||
if os.path.exists(abs_path):
|
||||
return abs_path
|
||||
|
||||
raise CouldNotFindFrameworkError(path)
|
||||
|
||||
def FindLibrary(path):
|
||||
if os.path.exists(path):
|
||||
return path
|
||||
search_pathes = LIBRARY_SEARCH_PATH
|
||||
search_pathes.insert(0, QueryQMake('QT_INSTALL_LIBS'))
|
||||
for search_path in search_pathes:
|
||||
abs_path = os.path.join(search_path, path)
|
||||
if os.path.exists(abs_path):
|
||||
return abs_path
|
||||
else: # try harder---look for lib name in library folders
|
||||
newpath = os.path.join(search_path,os.path.basename(path))
|
||||
if os.path.exists(newpath):
|
||||
return newpath
|
||||
|
||||
return ""
|
||||
#raise CouldNotFindFrameworkError(path)
|
||||
|
||||
def FixAllLibraries(broken_libs):
|
||||
for framework in broken_libs['frameworks']:
|
||||
FixFramework(framework)
|
||||
for lib in broken_libs['libs']:
|
||||
FixLibrary(lib)
|
||||
|
||||
def FixFramework(path):
|
||||
if path in fixed_libraries:
|
||||
return
|
||||
else:
|
||||
fixed_libraries.append(path)
|
||||
abs_path = FindFramework(path)
|
||||
broken_libs = GetBrokenLibraries(abs_path)
|
||||
FixAllLibraries(broken_libs)
|
||||
|
||||
new_path = CopyFramework(abs_path)
|
||||
id = os.sep.join(new_path.split(os.sep)[3:])
|
||||
FixFrameworkId(new_path, id)
|
||||
for framework in broken_libs['frameworks']:
|
||||
FixFrameworkInstallPath(framework, new_path)
|
||||
for library in broken_libs['libs']:
|
||||
FixLibraryInstallPath(library, new_path)
|
||||
|
||||
def FixLibrary(path):
|
||||
if path in fixed_libraries or FindSystemLibrary(os.path.basename(path)) is not None:
|
||||
return
|
||||
else:
|
||||
fixed_libraries.append(path)
|
||||
abs_path = FindLibrary(path)
|
||||
if abs_path == "":
|
||||
print "Could not resolve %s, not fixing!" % path
|
||||
return
|
||||
broken_libs = GetBrokenLibraries(abs_path)
|
||||
FixAllLibraries(broken_libs)
|
||||
|
||||
new_path = CopyLibrary(abs_path)
|
||||
FixLibraryId(new_path)
|
||||
for framework in broken_libs['frameworks']:
|
||||
FixFrameworkInstallPath(framework, new_path)
|
||||
for library in broken_libs['libs']:
|
||||
FixLibraryInstallPath(library, new_path)
|
||||
|
||||
def FixPlugin(abs_path, subdir):
|
||||
broken_libs = GetBrokenLibraries(abs_path)
|
||||
FixAllLibraries(broken_libs)
|
||||
|
||||
new_path = CopyPlugin(abs_path, subdir)
|
||||
for framework in broken_libs['frameworks']:
|
||||
FixFrameworkInstallPath(framework, new_path)
|
||||
for library in broken_libs['libs']:
|
||||
FixLibraryInstallPath(library, new_path)
|
||||
|
||||
def FixBinary(path):
|
||||
broken_libs = GetBrokenLibraries(path)
|
||||
FixAllLibraries(broken_libs)
|
||||
for framework in broken_libs['frameworks']:
|
||||
FixFrameworkInstallPath(framework, path)
|
||||
for library in broken_libs['libs']:
|
||||
FixLibraryInstallPath(library, path)
|
||||
|
||||
def CopyLibrary(path):
|
||||
new_path = os.path.join(binary_dir, os.path.basename(path))
|
||||
args = ['ditto', '--arch=x86_64', path, new_path]
|
||||
commands.append(args)
|
||||
args = ['chmod', 'u+w', new_path]
|
||||
commands.append(args)
|
||||
return new_path
|
||||
|
||||
def CopyPlugin(path, subdir):
|
||||
new_path = os.path.join(plugins_dir, subdir, os.path.basename(path))
|
||||
args = ['mkdir', '-p', os.path.dirname(new_path)]
|
||||
commands.append(args)
|
||||
args = ['ditto', '--arch=x86_64', path, new_path]
|
||||
commands.append(args)
|
||||
args = ['chmod', 'u+w', new_path]
|
||||
commands.append(args)
|
||||
return new_path
|
||||
|
||||
def CopyFramework(path):
|
||||
parts = path.split(os.sep)
|
||||
print "CopyFramework:", path
|
||||
for i, part in enumerate(parts):
|
||||
if re.match(r'\w+\.framework', part):
|
||||
full_path = os.path.join(frameworks_dir, *parts[i:-1])
|
||||
break
|
||||
args = ['mkdir', '-p', full_path]
|
||||
commands.append(args)
|
||||
args = ['ditto', '--arch=x86_64', path, full_path]
|
||||
commands.append(args)
|
||||
args = ['chmod', 'u+w', os.path.join(full_path, parts[-1])]
|
||||
commands.append(args)
|
||||
|
||||
info_plist = os.path.join(os.path.split(path)[0], '..', '..', 'Contents', 'Info.plist')
|
||||
if os.path.exists(info_plist):
|
||||
args = ['cp', '-r', info_plist, resources_dir]
|
||||
commands.append(args)
|
||||
|
||||
return os.path.join(full_path, parts[-1])
|
||||
|
||||
def FixId(path, library_name):
|
||||
id = '@executable_path/../Frameworks/%s' % library_name
|
||||
args = ['install_name_tool', '-id', id, path]
|
||||
commands.append(args)
|
||||
|
||||
def FixLibraryId(path):
|
||||
library_name = os.path.basename(path)
|
||||
FixId(path, library_name)
|
||||
|
||||
def FixFrameworkId(path, id):
|
||||
FixId(path, id)
|
||||
|
||||
def FixInstallPath(library_path, library, new_path):
|
||||
args = ['install_name_tool', '-change', library_path, new_path, library]
|
||||
commands.append(args)
|
||||
|
||||
def FindSystemLibrary(library_name):
|
||||
for path in ['/lib', '/usr/lib']:
|
||||
full_path = os.path.join(path, library_name)
|
||||
if os.path.exists(full_path):
|
||||
return full_path
|
||||
return None
|
||||
|
||||
def FixLibraryInstallPath(library_path, library):
|
||||
system_library = FindSystemLibrary(os.path.basename(library_path))
|
||||
if system_library is None:
|
||||
new_path = '@executable_path/../MacOS/%s' % os.path.basename(library_path)
|
||||
FixInstallPath(library_path, library, new_path)
|
||||
else:
|
||||
FixInstallPath(library_path, library, system_library)
|
||||
|
||||
def FixFrameworkInstallPath(library_path, library):
|
||||
parts = library_path.split(os.sep)
|
||||
for i, part in enumerate(parts):
|
||||
if re.match(r'\w+\.framework', part):
|
||||
full_path = os.path.join(*parts[i:])
|
||||
break
|
||||
new_path = '@executable_path/../Frameworks/%s' % full_path
|
||||
FixInstallPath(library_path, library, new_path)
|
||||
|
||||
def FindQtPlugin(name):
|
||||
search_path = QT_PLUGINS_SEARCH_PATH
|
||||
search_path.insert(0, QueryQMake('QT_INSTALL_PLUGINS'))
|
||||
for path in search_path:
|
||||
if os.path.exists(path):
|
||||
if os.path.exists(os.path.join(path, name)):
|
||||
return os.path.join(path, name)
|
||||
raise CouldNotFindQtPluginError(name)
|
||||
|
||||
for binary in binaries:
|
||||
FixBinary(binary)
|
||||
|
||||
for plugin in QT_PLUGINS:
|
||||
FixPlugin(FindQtPlugin(plugin), os.path.dirname(plugin))
|
||||
|
||||
if len(sys.argv) <= 2:
|
||||
print 'Will run %d commands:' % len(commands)
|
||||
for command in commands:
|
||||
print ' '.join(command)
|
||||
|
||||
for command in commands:
|
||||
p = subprocess.Popen(command)
|
||||
os.waitpid(p.pid, 0)
|
||||
|
||||
WriteQtConf()
|
||||
@@ -22,7 +22,7 @@
|
||||
<key>GID</key>
|
||||
<integer>80</integer>
|
||||
<key>PATH</key>
|
||||
<string>@APPLICATION_EXECUTABLE@.app</string>
|
||||
<string>owncloud.app</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>3</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
@@ -1054,10 +1054,10 @@
|
||||
<integer>6</integer>
|
||||
<key>BACKGROUND_PATH</key>
|
||||
<dict>
|
||||
<key>PATH</key>
|
||||
<string>./@APPLICATION_EXECUTABLE@.app/Contents/Resources/owncloud_logo_blue.png</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>3</integer>
|
||||
<key>PATH</key>
|
||||
<string>/Users/mackie/owncloud.com/mirall/resources/owncloud_logo_blue.png</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<key>CUSTOM</key>
|
||||
<integer>1</integer>
|
||||
@@ -1240,9 +1240,9 @@
|
||||
<key>BUILD_PATH</key>
|
||||
<dict>
|
||||
<key>PATH</key>
|
||||
<string>../install/.</string>
|
||||
<string>/Users/mackie/owncloud.com/mirall/admin</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>3</integer>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<key>EXCLUDED_FILES</key>
|
||||
<array>
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
#!/bin/sh -x
|
||||
|
||||
[ "$#" -lt 2 ] && echo "Usage: sign_app.sh <app> <identity>" && exit
|
||||
|
||||
src_app="$1"
|
||||
identity="$2"
|
||||
|
||||
QT_FMWK_VERSION="5"
|
||||
|
||||
fix_frameworks() {
|
||||
TMP_APP=$1
|
||||
QT_FMWK_PATH=$2
|
||||
QT_FMWKS=$3/Qt*.framework
|
||||
|
||||
echo "Patching Qt frameworks..."
|
||||
for FMWK in $QT_FMWKS; do
|
||||
FMWK_NAME=`basename -s .framework $FMWK`
|
||||
FMWK=`basename $FMWK`
|
||||
FMWK_PATH="${TMP_APP}/Contents/Frameworks/${FMWK}"
|
||||
mkdir -p "${FMWK_PATH}/Versions/${QT_FMWK_VERSION}/Resources/"
|
||||
cp -avf "${QT_FMWK_PATH}/${FMWK}/Contents/Info.plist" "${FMWK_PATH}/Versions/${QT_FMWK_VERSION}/Resources"
|
||||
(cd "${FMWK_PATH}" && ln -sf "Versions/${QT_FMWK_VERSION}/Resources" "Resources")
|
||||
perl -pi -e "s/${FMWK_NAME}_debug/${FMWK_NAME}/" "${FMWK_PATH}/Resources/Info.plist"
|
||||
done
|
||||
}
|
||||
|
||||
fix_frameworks "$src_app" `qmake -query QT_INSTALL_LIBS` "$src_app"/Contents/Frameworks
|
||||
codesign -s "$identity" --force --verbose=4 --deep "$src_app"
|
||||
|
||||
# Just for our debug purposes:
|
||||
spctl -a -t exec -vv $src_app
|
||||
codesign -dv $src_app
|
||||
@@ -1,7 +1,3 @@
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
# Always include srcdir and builddir in include path
|
||||
# This saves typing ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY} in
|
||||
# about every subdir
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
# define system dependent compiler flags
|
||||
|
||||
include(CheckCCompilerFlag)
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
if (UNIX)
|
||||
# Suffix for Linux
|
||||
SET(LIB_SUFFIX
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
# Set system vars
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
# This module defines
|
||||
# INOTIFY_INCLUDE_DIR, where to find inotify.h, etc.
|
||||
# INOTIFY_FOUND, If false, do not try to use inotify.
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
# FIND_PACKAGE_VERSION_CHECK(NAME (DEFAULT_MSG|"Custom failure message"))
|
||||
# This function is intended to be used in FindXXX.cmake modules files.
|
||||
# It handles NAME_FIND_VERSION and NAME_VERSION variables in a Module.
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
find_program(PDFLATEX_EXECUTABLE NAMES pdflatex
|
||||
HINTS
|
||||
$ENV{PDFLATEX_DIR}
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
# - Try to find QtKeychain
|
||||
# Once done this will define
|
||||
# QTKEYCHAIN_FOUND - System has QtKeychain
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
# - Try to find QtKeychain
|
||||
# Once done this will define
|
||||
# QTKEYCHAIN_FOUND - System has QtKeychain
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
find_program(SPHINX_EXECUTABLE NAMES sphinx-build
|
||||
HINTS
|
||||
$ENV{SPHINX_DIR}
|
||||
|
||||
@@ -30,8 +30,6 @@
|
||||
<string>(C) 2014 @APPLICATION_VENDOR@</string>
|
||||
<key>SUShowReleaseNotes</key>
|
||||
<false/>
|
||||
<key>LSMinimumBundleVersion</key>
|
||||
<string>10.7.0</string>
|
||||
<key>SUPublicDSAKeyFile</key>
|
||||
<string>dsa_pub.pem</string>
|
||||
</dict>
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
# - macro_copy_file(_src _dst)
|
||||
# Copies a file to ${_dst} only if ${_src} is different (newer) than ${_dst}
|
||||
#
|
||||
|
||||
@@ -384,10 +384,10 @@ Section "${APPLICATION_NAME}" SEC_APPLICATION
|
||||
File "${BUILD_PATH}\bin\${APPLICATION_EXECUTABLE}"
|
||||
File "${BUILD_PATH}\bin\${APPLICATION_CMD_EXECUTABLE}"
|
||||
File "${BUILD_PATH}\bin\socketapiclient.exe"
|
||||
File "${BUILD_PATH}\src\lib${APPLICATION_SHORTNAME}sync.dll"
|
||||
File "${BUILD_PATH}\src\libsync\lib${APPLICATION_SHORTNAME}sync.dll"
|
||||
File "${BUILD_PATH}\csync\src\libocsync.dll"
|
||||
|
||||
File "${BUILD_PATH}\src\mirall_*.qm"
|
||||
File "${BUILD_PATH}\src\gui\mirall_*.qm"
|
||||
; Make sure only to copy qt, not qt_help, etc
|
||||
File "${MING_SHARE}\qt5\translations\qt_??.qm"
|
||||
File "${MING_SHARE}\qt5\translations\qt_??_??.qm"
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
include (MacroOptionalFindPackage)
|
||||
include (MacroLogFeature)
|
||||
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
# -helper macro to add a "doc" target with CMake build system.
|
||||
# and configure doxy.config.in to doxy.config
|
||||
#
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
|
||||
OUTPUT_VARIABLE GCC_VERSION)
|
||||
|
||||
@@ -522,6 +522,8 @@ static void _tree_destructor(void *data) {
|
||||
* used by csync_commit and csync_destroy */
|
||||
static void _csync_clean_ctx(CSYNC *ctx)
|
||||
{
|
||||
c_list_t * walk;
|
||||
|
||||
/* destroy the rbtrees */
|
||||
if (c_rbtree_size(ctx->local.tree) > 0) {
|
||||
c_rbtree_destroy(ctx->local.tree, _tree_destructor);
|
||||
@@ -533,14 +535,25 @@ static void _csync_clean_ctx(CSYNC *ctx)
|
||||
|
||||
csync_rename_destroy(ctx);
|
||||
|
||||
for (walk = c_list_last(ctx->local.ignored_cleanup); walk != NULL; walk = c_list_prev(walk)) {
|
||||
SAFE_FREE(walk->data);
|
||||
}
|
||||
for (walk = c_list_last(ctx->remote.ignored_cleanup); walk != NULL; walk = c_list_prev(walk)) {
|
||||
SAFE_FREE(walk->data);
|
||||
}
|
||||
|
||||
/* free memory */
|
||||
c_rbtree_free(ctx->local.tree);
|
||||
c_list_free(ctx->local.list);
|
||||
c_list_free(ctx->local.ignored_cleanup);
|
||||
c_rbtree_free(ctx->remote.tree);
|
||||
c_list_free(ctx->remote.list);
|
||||
c_list_free(ctx->remote.ignored_cleanup);
|
||||
|
||||
ctx->remote.list = 0;
|
||||
ctx->local.list = 0;
|
||||
ctx->remote.ignored_cleanup = 0;
|
||||
ctx->local.ignored_cleanup = 0;
|
||||
|
||||
SAFE_FREE(ctx->statedb.file);
|
||||
}
|
||||
|
||||
@@ -94,7 +94,6 @@ enum csync_status_codes_e {
|
||||
CSYNC_STATUS_ABORTED,
|
||||
/* Codes for file individual status: */
|
||||
CSYNC_STATUS_INDIVIDUAL_IS_SYMLINK,
|
||||
CSYNC_STATUS_INDIVIDUAL_IS_HARDLINK,
|
||||
CSYNC_STATUS_INDIVIDUAL_IGNORE_LIST,
|
||||
CSYNC_STATUS_INDIVIDUAL_IS_INVALID_CHARS,
|
||||
CYSNC_STATUS_FILE_LOCKED_OR_OPEN
|
||||
|
||||
@@ -40,10 +40,7 @@
|
||||
#define CSYNC_LOG_CATEGORY_NAME "csync.exclude"
|
||||
#include "csync_log.h"
|
||||
|
||||
#ifndef NDEBUG
|
||||
static
|
||||
#endif
|
||||
int _csync_exclude_add(c_strlist_t **inList, const char *string) {
|
||||
static int _csync_exclude_add(c_strlist_t **inList, const char *string) {
|
||||
c_strlist_t *list;
|
||||
|
||||
if (*inList == NULL) {
|
||||
@@ -153,6 +150,12 @@ CSYNC_EXCLUDE_TYPE csync_excluded(CSYNC *ctx, const char *path, int filetype) {
|
||||
|
||||
match = csync_excluded_no_ctx( ctx->excludes, path, filetype );
|
||||
|
||||
if (match == CSYNC_NOT_EXCLUDED && ctx->checkBlackListHook) {
|
||||
if (ctx->checkBlackListHook(ctx->checkBlackListData, path)) {
|
||||
match = CSYNC_FILE_EXCLUDE_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
@@ -202,20 +205,6 @@ CSYNC_EXCLUDE_TYPE csync_excluded_no_ctx(c_strlist_t *excludes, const char *path
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
// Windows cannot sync files ending in spaces (#2176). It also cannot
|
||||
// distinguish files ending in '.' from files without an ending,
|
||||
// as '.' is a separator that is not stored internally, so let's
|
||||
// not allow to sync those to avoid file loss/ambiguities (#416)
|
||||
size_t blen = strlen(bname);
|
||||
if (blen > 1 && (bname[blen-1]== ' ' || bname[blen-1]== '.' )) {
|
||||
match = CSYNC_FILE_EXCLUDE_INVALID_CHAR;
|
||||
SAFE_FREE(bname);
|
||||
SAFE_FREE(dname);
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
rc = csync_fnmatch(".owncloudsync.log*", bname, 0);
|
||||
if (rc == 0) {
|
||||
match = CSYNC_FILE_SILENTLY_EXCLUDED;
|
||||
|
||||
@@ -29,11 +29,6 @@ enum csync_exclude_type_e {
|
||||
CSYNC_FILE_EXCLUDE_INVALID_CHAR
|
||||
};
|
||||
typedef enum csync_exclude_type_e CSYNC_EXCLUDE_TYPE;
|
||||
|
||||
#ifdef NDEBUG
|
||||
int _csync_exclude_add(c_strlist_t **inList, const char *string);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Load exclude list
|
||||
*
|
||||
|
||||
@@ -339,8 +339,6 @@ void fill_webdav_properties_into_resource(struct resource* newres, const ne_prop
|
||||
file_id = ne_propset_value( set, &ls_props[4] );
|
||||
directDownloadUrl = ne_propset_value( set, &ls_props[5] );
|
||||
directDownloadCookies = ne_propset_value( set, &ls_props[6] );
|
||||
|
||||
// permission flags: Defined in https://github.com/owncloud/core/issues/8322
|
||||
perm = ne_propset_value( set, &ls_props[7] );
|
||||
|
||||
if( resourcetype && strncmp( resourcetype, "<DAV:collection>", 16 ) == 0) {
|
||||
|
||||
@@ -107,6 +107,7 @@ struct csync_s {
|
||||
c_rbtree_t *tree;
|
||||
c_list_t *list;
|
||||
enum csync_replica_e type;
|
||||
c_list_t *ignored_cleanup;
|
||||
} local;
|
||||
|
||||
struct {
|
||||
@@ -115,6 +116,7 @@ struct csync_s {
|
||||
c_list_t *list;
|
||||
enum csync_replica_e type;
|
||||
int read_from_db;
|
||||
c_list_t *ignored_cleanup;
|
||||
} remote;
|
||||
|
||||
#if defined(HAVE_ICONV) && defined(WITH_ICONV)
|
||||
@@ -165,7 +167,6 @@ struct csync_file_stat_s {
|
||||
int type; /* u32 */
|
||||
int child_modified;/*bool*/
|
||||
int should_update_etag; /*bool */
|
||||
int has_ignored_files; /*bool: specify that a directory, or child directory contains ignored files */
|
||||
|
||||
char *destpath; /* for renames */
|
||||
const char *etag;
|
||||
|
||||
@@ -134,10 +134,6 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
|
||||
break;
|
||||
/* file has been removed on the opposite replica */
|
||||
case CSYNC_INSTRUCTION_NONE:
|
||||
if (cur->has_ignored_files) {
|
||||
/* Do not remove a directory that has ignored files */
|
||||
break;
|
||||
}
|
||||
cur->instruction = CSYNC_INSTRUCTION_REMOVE;
|
||||
break;
|
||||
case CSYNC_INSTRUCTION_EVAL_RENAME:
|
||||
|
||||
+17
-35
@@ -146,21 +146,21 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
if (excluded != CSYNC_NOT_EXCLUDED) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "%s excluded (%d)", path, excluded);
|
||||
if (excluded == CSYNC_FILE_EXCLUDE_AND_REMOVE) {
|
||||
return 1;
|
||||
switch (ctx->current) {
|
||||
case LOCAL_REPLICA:
|
||||
ctx->local.ignored_cleanup = c_list_append(ctx->local.ignored_cleanup, c_strdup(path));
|
||||
break;
|
||||
case REMOTE_REPLICA:
|
||||
ctx->remote.ignored_cleanup = c_list_append(ctx->remote.ignored_cleanup, c_strdup(path));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (excluded == CSYNC_FILE_SILENTLY_EXCLUDED) {
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ctx->current_fs) {
|
||||
ctx->current_fs->has_ignored_files = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->current == REMOTE_REPLICA && ctx->checkBlackListHook) {
|
||||
if (ctx->checkBlackListHook(ctx->checkBlackListData, path)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
h = _hash_of_file(ctx, file );
|
||||
@@ -179,13 +179,11 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
st->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
st->etag = NULL;
|
||||
st->child_modified = 0;
|
||||
st->has_ignored_files = 0;
|
||||
|
||||
/* check hardlink count */
|
||||
if (type == CSYNC_FTW_TYPE_FILE ) {
|
||||
if( fs->nlink > 1) {
|
||||
st->instruction = CSYNC_INSTRUCTION_IGNORE;
|
||||
st->error_status = CSYNC_STATUS_INDIVIDUAL_IS_HARDLINK;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -230,16 +228,14 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
|
||||
if(tmp && tmp->phash == h ) { /* there is an entry in the database */
|
||||
/* we have an update! */
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Database entry found, compare: %" PRId64 " <-> %" PRId64 ", etag: %s <-> %s, inode: %" PRId64 " <-> %" PRId64 ", size: %" PRId64 " <-> %" PRId64,
|
||||
((int64_t) fs->mtime), ((int64_t) tmp->modtime), fs->etag, tmp->etag, (uint64_t) fs->inode, (uint64_t) tmp->inode, (uint64_t) fs->size, (uint64_t) tmp->size);
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Database entry found, compare: %" PRId64 " <-> %" PRId64 ", etag: %s <-> %s, inode: %" PRId64 " <-> %" PRId64,
|
||||
((int64_t) fs->mtime), ((int64_t) tmp->modtime), fs->etag, tmp->etag, (uint64_t) fs->inode, (uint64_t) tmp->inode);
|
||||
if( !fs->etag) {
|
||||
st->instruction = CSYNC_INSTRUCTION_EVAL;
|
||||
goto out;
|
||||
}
|
||||
if((ctx->current == REMOTE_REPLICA && !c_streq(fs->etag, tmp->etag ))
|
||||
|| (ctx->current == LOCAL_REPLICA && (fs->mtime != tmp->modtime
|
||||
// zero size in statedb can happen during migration
|
||||
|| (tmp->size != 0 && fs->size != tmp->size)
|
||||
#if 0
|
||||
|| fs->inode != tmp->inode
|
||||
#endif
|
||||
@@ -435,19 +431,11 @@ int csync_walker(CSYNC *ctx, const char *file, const csync_vio_file_stat_t *fs,
|
||||
|
||||
switch (flag) {
|
||||
case CSYNC_FTW_FLAG_FILE:
|
||||
if (ctx->current == REMOTE_REPLICA) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file: %s [file_id=%s size=%" PRIu64 "]", file, fs->file_id, fs->size);
|
||||
} else {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file: %s [inode=%" PRIu64 " size=%" PRIu64 "]", file, fs->inode, fs->size);
|
||||
}
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file: %s [file_id=%s]", file, fs->file_id);
|
||||
type = CSYNC_FTW_TYPE_FILE;
|
||||
break;
|
||||
case CSYNC_FTW_FLAG_DIR: /* enter directory */
|
||||
if (ctx->current == REMOTE_REPLICA) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "directory: %s [file_id=%s]", file, fs->file_id);
|
||||
} else {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "directory: %s [inode=%" PRIu64 "]", file, fs->inode);
|
||||
}
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "directory: %s [file_id=%s]", file, fs->file_id);
|
||||
type = CSYNC_FTW_TYPE_DIR;
|
||||
break;
|
||||
case CSYNC_FTW_FLAG_NSTAT: /* not statable file */
|
||||
@@ -672,7 +660,6 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
|
||||
/* this function may update ctx->current and ctx->read_from_db */
|
||||
|
||||
if (ctx->current_fs && previous_fs && ctx->current_fs->child_modified) {
|
||||
/* If a directory has modified files, put the flag on the parent directory as well */
|
||||
previous_fs->child_modified = ctx->current_fs->child_modified;
|
||||
}
|
||||
|
||||
@@ -690,7 +677,7 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (flag == CSYNC_FTW_FLAG_DIR && depth && rc == 0
|
||||
if (flag == CSYNC_FTW_FLAG_DIR && depth
|
||||
&& (!ctx->current_fs || ctx->current_fs->instruction != CSYNC_INSTRUCTION_IGNORE)) {
|
||||
rc = csync_ftw(ctx, filename, fn, depth - 1);
|
||||
if (rc < 0) {
|
||||
@@ -703,11 +690,6 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
|
||||
ctx->current_fs->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
ctx->current_fs->should_update_etag = true;
|
||||
}
|
||||
|
||||
if (ctx->current_fs && previous_fs && ctx->current_fs->has_ignored_files) {
|
||||
/* If a directory has ignored files, put the flag on the parent directory as well */
|
||||
previous_fs->has_ignored_files = ctx->current_fs->has_ignored_files;
|
||||
}
|
||||
}
|
||||
|
||||
if (flag == CSYNC_FTW_FLAG_DIR && ctx->current_fs
|
||||
|
||||
@@ -237,7 +237,7 @@ int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) {
|
||||
/* printf("Index: %I64i\n", FileIndex.QuadPart); */
|
||||
buf->inode = FileIndex.QuadPart;
|
||||
|
||||
buf->size = (fileInfo.nFileSizeHigh * ((int64_t)(MAXDWORD)+1)) + fileInfo.nFileSizeLow;
|
||||
buf->size = (fileInfo.nFileSizeHigh * (int64_t)(MAXDWORD+1)) + fileInfo.nFileSizeLow;
|
||||
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE;
|
||||
|
||||
/* Get the file time with a win32 call rather than through stat. See
|
||||
|
||||
@@ -141,38 +141,6 @@ static void check_csync_excluded(void **state)
|
||||
|
||||
}
|
||||
|
||||
static void check_csync_pathes(void **state)
|
||||
{
|
||||
CSYNC *csync = *state;
|
||||
int rc;
|
||||
|
||||
_csync_exclude_add( &(csync->excludes), "/exclude" );
|
||||
|
||||
/* Check toplevel dir, the pattern only works for toplevel dir. */
|
||||
rc = csync_excluded(csync, "/exclude", CSYNC_FTW_TYPE_DIR);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
|
||||
rc = csync_excluded(csync, "/foo/exclude", CSYNC_FTW_TYPE_DIR);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
|
||||
/* check for a file called exclude. Must still work */
|
||||
rc = csync_excluded(csync, "/exclude", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
|
||||
rc = csync_excluded(csync, "/foo/exclude", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
|
||||
/* Add an exclude for directories only: excl/ */
|
||||
_csync_exclude_add( &(csync->excludes), "excl/" );
|
||||
rc = csync_excluded(csync, "/excl", CSYNC_FTW_TYPE_DIR);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
|
||||
rc = csync_excluded(csync, "meep/excl", CSYNC_FTW_TYPE_DIR);
|
||||
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
|
||||
|
||||
rc = csync_excluded(csync, "/excl", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||
}
|
||||
|
||||
int torture_run_tests(void)
|
||||
{
|
||||
@@ -180,7 +148,6 @@ int torture_run_tests(void)
|
||||
unit_test_setup_teardown(check_csync_exclude_add, setup, teardown),
|
||||
unit_test_setup_teardown(check_csync_exclude_load, setup, teardown),
|
||||
unit_test_setup_teardown(check_csync_excluded, setup_init, teardown),
|
||||
unit_test_setup_teardown(check_csync_pathes, setup_init, teardown),
|
||||
};
|
||||
|
||||
return run_tests(tests);
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
t1.cfg
|
||||
@@ -1,7 +1,12 @@
|
||||
t1 - an integration test script for csync syncing to ownCloud.
|
||||
|
||||
Note: This test script uses perl HTTP::DAV. This package needs to
|
||||
be in version 0.47 at least. Many distros deliver older versions.
|
||||
be in version 0.46 at least. Many distros deliver older versions.
|
||||
A working version is part of the github checkout.
|
||||
|
||||
Note: This test script uses perl HTTP::DAV. This package needs to
|
||||
be in version 0.46 at least. Many distros deliver older versions.
|
||||
Update than.
|
||||
|
||||
t1 uses a perl WebDAV client lib to sync to an existing instance of
|
||||
ownCloud. For that, various files are copied around, synced and the
|
||||
@@ -15,6 +20,10 @@ First, configure the script. For that, create a file t1.cfg. There
|
||||
is t1.cfg.in as an example. Yeah, this test script is not secure,
|
||||
make sure to run it with a weak account and in a save environment.
|
||||
|
||||
Second, unpack the test file collection with
|
||||
tar xf testfiles.tar.xz
|
||||
in the directory where the tarball can be found.
|
||||
|
||||
To start the script, call ./t1.pl on the commandline. A lot of
|
||||
output is generated. If the script does not fail, everything works.
|
||||
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
*.part
|
||||
]*.directory
|
||||
|
||||
*_conflict-*
|
||||
|
||||
@@ -27,6 +27,7 @@ use Exporter;
|
||||
use HTTP::DAV 0.47;
|
||||
use Data::Dumper;
|
||||
use File::Glob ':glob';
|
||||
use Carp::Assert;
|
||||
use Digest::MD5;
|
||||
use Unicode::Normalize;
|
||||
use LWP::UserAgent;
|
||||
@@ -35,7 +36,6 @@ use HTTP::Request::Common qw( POST GET DELETE );
|
||||
use File::Basename;
|
||||
use IO::Handle;
|
||||
use POSIX qw/strftime/;
|
||||
use Carp;
|
||||
|
||||
use Encode qw(from_to);
|
||||
use utf8;
|
||||
@@ -66,7 +66,7 @@ our %config;
|
||||
assertLocalDirs assertLocalAndRemoteDir glob_put put_to_dir
|
||||
putToDirLWP localDir remoteDir localCleanup createLocalFile md5OfFile
|
||||
remoteCleanup server initLocalDir initRemoteDir moveRemoteFile
|
||||
printInfo remoteFileId createShare removeShare assert
|
||||
printInfo remoteFileId createShare removeShare
|
||||
configValue testDirUrl getToFileLWP getToFileCurl);
|
||||
|
||||
sub server
|
||||
@@ -115,8 +115,6 @@ sub initTesting(;$)
|
||||
|
||||
$owncloud .= "/" unless( $owncloud =~ /\/$/ );
|
||||
|
||||
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0;
|
||||
|
||||
print "Connecting to ownCloud at ". $owncloud ."\n";
|
||||
|
||||
# For SSL set the environment variable needed by the LWP module for SSL
|
||||
@@ -168,9 +166,7 @@ sub testDirUrl()
|
||||
# the global var $remoteDir;
|
||||
sub initRemoteDir
|
||||
{
|
||||
$d->open( $owncloud )
|
||||
or die("Couldn't open $owncloud: " .$d->message . "\n");
|
||||
|
||||
$d->open( $owncloud );
|
||||
my $url = testDirUrl();
|
||||
|
||||
my $re = $d->mkcol( $url );
|
||||
@@ -309,7 +305,7 @@ sub csync( ;$ )
|
||||
|
||||
print "CSync URL: $url\n";
|
||||
|
||||
my $args = "--trust --exclude exclude.cfg"; # Trust crappy SSL certificates
|
||||
my $args = "--trust"; # Trust crappy SSL certificates
|
||||
my $cmd = "LD_LIBRARY_PATH=$ld_libpath $csync $args $localDir $url";
|
||||
print "Starting: $cmd\n";
|
||||
|
||||
@@ -549,7 +545,7 @@ sub putToDirLWP($$)
|
||||
my $string = <FILE>;
|
||||
close FILE;
|
||||
|
||||
my $ua = LWP::UserAgent->new( ssl_opts => { verify_hostname => 0 });
|
||||
my $ua = LWP::UserAgent->new();
|
||||
$ua->agent( "ownCloudTest_$localDir");
|
||||
my $req = PUT $puturl, Content_Type => 'application/octet-stream',
|
||||
Content => $string;
|
||||
@@ -583,7 +579,7 @@ sub getToFileLWP( $$ )
|
||||
my $geturl = testDirUrl() . $file;
|
||||
print "GETting $geturl to $localFile\n";
|
||||
|
||||
my $ua = LWP::UserAgent->new( ssl_opts => { verify_hostname => 0 });
|
||||
my $ua = LWP::UserAgent->new();
|
||||
$ua->agent( "ownCloudTest_$localDir");
|
||||
$ua->credentials( server(), "foo", $user, $passwd);
|
||||
my $req = $ua->get($geturl, ":content_file" => $localFile);
|
||||
@@ -725,7 +721,7 @@ sub createShare($$)
|
||||
|
||||
}
|
||||
|
||||
my $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 0 } );
|
||||
my $ua = LWP::UserAgent->new();
|
||||
$ua->agent( "ownCloudTest_sharing");
|
||||
# http://localhost/ocm/ocs/v1.php/apps/files_sharing/api/v1/shares
|
||||
my $puturl = $ocs_url . "apps/files_sharing/api/v1/shares";
|
||||
@@ -761,7 +757,7 @@ sub removeShare($$)
|
||||
-pass => $share_passwd );
|
||||
$dd->open( $owncloud);
|
||||
|
||||
my $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 0 });
|
||||
my $ua = LWP::UserAgent->new();
|
||||
$ua->agent( "ownCloudTest_sharing");
|
||||
# http://localhost/ocm/ocs/v1.php/apps/files_sharing/api/v1/shares
|
||||
my $url = $ocs_url . "apps/files_sharing/api/v1/shares/" . $shareId;
|
||||
@@ -787,12 +783,4 @@ sub removeShare($$)
|
||||
my $response = $ua->request($req);
|
||||
}
|
||||
|
||||
sub assert($;$)
|
||||
{
|
||||
unless( $_[0] ) {
|
||||
print Carp::confess(@_);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
user => "joe",
|
||||
passwd => "secret",
|
||||
url => "http://localhost/ocm/remote.php/webdav/",
|
||||
ld_libpath => "/home/joe/owncloud/mirall-install/lib",
|
||||
csync => "/home/joe/owncloud/mirall-install/bin/owncloudcmd",
|
||||
ld_libpath => "/home/joe/owncloud/csync/csync-build/modules",
|
||||
csync => "/home/joe/owncloud/csync/csync-build/client/csync",
|
||||
ocs_url => "http://localhost/owncloud/ocs/v1.php/",
|
||||
share_user => "jenny",
|
||||
share_passwd => "also_secret"
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
use lib ".";
|
||||
|
||||
use Carp::Assert;
|
||||
use File::Copy;
|
||||
use ownCloud::Test;
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
use lib ".";
|
||||
|
||||
|
||||
use Carp::Assert;
|
||||
use File::Copy;
|
||||
use ownCloud::Test;
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
use lib ".";
|
||||
|
||||
|
||||
use Carp::Assert;
|
||||
use File::Copy;
|
||||
use ownCloud::Test;
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
use lib ".";
|
||||
|
||||
|
||||
use Carp::Assert;
|
||||
use File::Copy;
|
||||
use ownCloud::Test;
|
||||
|
||||
@@ -38,10 +38,6 @@ printInfo( "Copy some files to the remote location" );
|
||||
mkdir( localDir() . 'test_stat' );
|
||||
system( "echo foobar > " . localDir() . 'test_stat/file.txt' );
|
||||
|
||||
mkdir( localDir() . 'test_ignored' );
|
||||
mkdir( localDir() . 'test_ignored/sub' );
|
||||
system( "echo foobarfoo > " . localDir() . 'test_ignored/sub/file.txt' );
|
||||
|
||||
# call csync, sync local t1 to remote t1
|
||||
csync();
|
||||
|
||||
@@ -95,25 +91,15 @@ my $realMD5 = md5OfFile( '/tmp/kernelcrash.txt' );
|
||||
print "MD5 compare $localMD5 <-> $realMD5\n";
|
||||
assert( $localMD5 eq $realMD5 );
|
||||
|
||||
|
||||
printInfo("Added a file that is on the ignore list");
|
||||
# (*.directory is in the ignored list that needs cleanup)
|
||||
# (it is names with _conflict) because i want the conflicft detection of assertLocalAndRemoteDir to work
|
||||
system( "echo dir >> " . localDir() . 'test_stat/file_conflict.directory' );
|
||||
# this one should retain the directory
|
||||
system( "echo foobarfoo > " . localDir() . 'test_ignored/sub/ignored_conflict.part' );
|
||||
csync();
|
||||
# The file_conflict.directory is seen as a conflict
|
||||
assertLocalAndRemoteDir( '', 1 );
|
||||
# TODO: check that the file_conflict.directory is indeed NOT on the server
|
||||
# TODO: check that test_ignored/sub/ignored_conflict.part is NOT on the server
|
||||
assert(-e localDir() . 'test_ignored/sub/ignored_conflict.part');
|
||||
|
||||
printInfo("Remove a directory containing an ignored file that should not be removed\n");
|
||||
remoteCleanup('test_ignored');
|
||||
csync();
|
||||
assert(-e localDir() . 'test_ignored/sub/ignored_conflict.part');
|
||||
#remove the file so next sync allow the directory to be removed
|
||||
system( "rm " . localDir() . 'test_ignored/sub/ignored_conflict.part' );
|
||||
|
||||
printInfo("Remove a directory containing a local file\n");
|
||||
remoteCleanup('test_stat');
|
||||
@@ -164,8 +150,6 @@ printInfo("Now remove the symlink\n");
|
||||
system( "rm -f " . localDir() . 'anotherdir' );
|
||||
csync();
|
||||
assertLocalAndRemoteDir( '', 0 );
|
||||
assert(! -e localDir(). 'anotherdir' );
|
||||
|
||||
|
||||
cleanup();
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
use lib ".";
|
||||
|
||||
|
||||
use Carp::Assert;
|
||||
use File::Copy;
|
||||
use ownCloud::Test;
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
use lib ".";
|
||||
|
||||
|
||||
use Carp::Assert;
|
||||
use File::Copy;
|
||||
use ownCloud::Test;
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
use lib ".";
|
||||
|
||||
|
||||
use Carp::Assert;
|
||||
use File::Copy;
|
||||
use ownCloud::Test;
|
||||
|
||||
@@ -176,6 +176,8 @@ system("sqlite3 " . localDir().'.csync_journal.db .dump');
|
||||
#new directory should be uploaded
|
||||
system("mv " . localDir().'readonlyDirectory_PERM_M_/subdir_PERM_CK_ ' . localDir().'normalDirectory_PERM_CKDNV_/subdir_PERM_CKDNV_' );
|
||||
|
||||
# two syncs may be necessary for now: https://github.com/owncloud/mirall/issues/2038
|
||||
csync();
|
||||
csync();
|
||||
system("sqlite3 " . localDir().'.csync_journal.db .dump');
|
||||
assertCsyncJournalOk(localDir());
|
||||
@@ -207,6 +209,8 @@ system("mv " . localDir().'readonlyDirectory_PERM_M_/subdir_PERM_CK_ ' . localDi
|
||||
#2. move a directory from read to read only (move the directory from previous step)
|
||||
system("mv " . localDir().'normalDirectory_PERM_CKDNV_/subdir_PERM_CKDNV_ ' . localDir().'readonlyDirectory_PERM_M_/moved_PERM_CK_' );
|
||||
|
||||
# two syncs may be necessary for now: https://github.com/owncloud/mirall/issues/2038
|
||||
csync();
|
||||
csync();
|
||||
assertCsyncJournalOk(localDir());
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
use lib ".";
|
||||
|
||||
|
||||
use Carp::Assert;
|
||||
use File::Copy;
|
||||
use ownCloud::Test;
|
||||
|
||||
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
The ownCloud Client reads a configuration file. You can locate this configuration files as follows:
|
||||
|
||||
On Linux distributions:
|
||||
- On Linux distributions:
|
||||
``$HOME/.local/share/data/ownCloud/owncloud.cfg``
|
||||
|
||||
On Microsoft Windows systems:
|
||||
- In Microsoft Windows systems:
|
||||
``%LOCALAPPDATA%\ownCloud\owncloud.cfg``
|
||||
|
||||
On MAC OS X systems:
|
||||
- In MAC OS X systems:
|
||||
``$HOME/Library/Application Support/ownCloud``
|
||||
|
||||
|
||||
|
||||
+3
-17
@@ -29,24 +29,12 @@ the server URL.
|
||||
|
||||
OPTIONS
|
||||
=======
|
||||
``--user``, ``-u`` ``[user]``
|
||||
Use ``user`` as the login name.
|
||||
``--confdir`` `PATH`
|
||||
Specifies the configuration directory where `csync.conf` is located.
|
||||
|
||||
``--password``, ``-p`` ``[password]``
|
||||
Use ``password`` as the password.
|
||||
|
||||
``-n``
|
||||
Use ``netrc (5)`` for login.
|
||||
|
||||
``--non-interactive``
|
||||
Do not prompt for questions.
|
||||
|
||||
``--silent``, ``--s``
|
||||
``--silent``
|
||||
Inhibits verbose log output.
|
||||
|
||||
``--trust``
|
||||
Trust any SSL certificate, including invalid ones.
|
||||
|
||||
``--httpproxy http://[user@pass:]<server>:<port>``
|
||||
Uses ``server`` as HTTP proxy.
|
||||
|
||||
@@ -60,8 +48,6 @@ the command line would be::
|
||||
$HOME/media/music \
|
||||
https://server/owncloud/remote.php/webdav/Music
|
||||
|
||||
``owncloudcmd`` will enquire user name and password, unless they have
|
||||
been specified on the command line or ``-n`` (see `netrc(5)`) has been passed.
|
||||
|
||||
Using the legacy scheme, it would be::
|
||||
|
||||
|
||||
+7
-20
@@ -22,25 +22,13 @@ the server URL.
|
||||
|
||||
Other comand line switches supported by owncloudcmd include the following:
|
||||
|
||||
``--user``, ``-u`` ``[user]``
|
||||
Use ``user`` as the login name.
|
||||
- ``--silent``
|
||||
Supresses verbose log output.
|
||||
|
||||
``--password``, ``-p`` ``[password]``
|
||||
Use ``password`` as the password.
|
||||
- ``--confdir`` `PATH`
|
||||
Fetches or stores configuration in the specified configuration directory.
|
||||
|
||||
``-n``
|
||||
Use ``netrc (5)`` for login.
|
||||
|
||||
``--non-interactive``
|
||||
Do not prompt for questions.
|
||||
|
||||
``--silent``, ``-s``
|
||||
Inhibits verbose log output.
|
||||
|
||||
``--trust``
|
||||
Trust any SSL certificate, including invalid ones.
|
||||
|
||||
``--httpproxy http://[user@pass:]<server>:<port>``
|
||||
- ``--httpproxy http://[user@pass:]<server>:<port>``
|
||||
Uses the specified ``server`` as the HTTP proxy.
|
||||
|
||||
Credential Handling
|
||||
@@ -53,19 +41,18 @@ setting with the usual URL pattern. For example::
|
||||
|
||||
https://user:secret@192.168.178.2/remote.php/webdav
|
||||
|
||||
|
||||
Example
|
||||
~~~~~~~
|
||||
|
||||
To synchronize the ownCloud directory ``Music`` to the local directory
|
||||
``media/music``, through a proxy listening on port ``8080``, and on a gateway
|
||||
``media/music`, through a proxy listening on port ``8080``, and on a gateway
|
||||
machine using IP address ``192.168.178.1``, the command line would be::
|
||||
|
||||
$ owncloudcmd --httpproxy http://192.168.178.1:8080 \
|
||||
$HOME/media/music \
|
||||
https://server/owncloud/remote.php/webdav/Music
|
||||
|
||||
``owncloudcmd`` will enquire user name and password, unless they have
|
||||
been specified on the command line or ``-n`` has been passed.
|
||||
|
||||
Using the legacy scheme, the command line would be::
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ Categories=Utility;X-SuSE-SyncUtility;
|
||||
Type=Application
|
||||
Exec=@APPLICATION_EXECUTABLE@
|
||||
Name=@APPLICATION_NAME@ desktop sync client
|
||||
Comment=@APPLICATION_NAME@ desktop synchronization client
|
||||
GenericName=Folder Sync
|
||||
Icon=@APPLICATION_EXECUTABLE@
|
||||
Keywords=@APPLICATION_NAME@;syncing;file;sharing;
|
||||
|
||||
@@ -3,7 +3,7 @@ if(APPLE)
|
||||
add_custom_target( mac_overlayplugin ALL
|
||||
xcodebuild -workspace ${CMAKE_SOURCE_DIR}/shell_integration/MacOSX/OwnCloud.xcworkspace
|
||||
-scheme OwnCloudFinder.osax SYMROOT=${CMAKE_CURRENT_BINARY_DIR} archive
|
||||
COMMENT building Mac Overlay icons)
|
||||
COMMENT building Mac Overlay iccons)
|
||||
|
||||
INSTALL( DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Release/OwnCloudFinder.osax/Contents
|
||||
DESTINATION ${CMAKE_INSTALL_PREFIX}/Library/ScriptingAdditions/OwnCloudFinder.osax/ )
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
{
|
||||
NSMutableDictionary* _fileNamesCache;
|
||||
BOOL _fileIconsEnabled;
|
||||
BOOL _hasChangedContent;
|
||||
|
||||
NSNumber *_icnOk;
|
||||
NSNumber *_icnSync;
|
||||
@@ -39,9 +38,6 @@
|
||||
- (void)setIcons:(NSDictionary*)iconDictionary filterByFolder:(NSString*)filterFolder;
|
||||
- (void)setResultForPath:(NSString*)path result:(NSString*)result;
|
||||
- (void)clearFileNameCacheForPath:(NSString*)path;
|
||||
- (void)reFetchFileNameCacheForPath:(NSString*)path;
|
||||
- (void)repaintAllWindows;
|
||||
|
||||
- (void)loadIconResourcePath:(NSString*)path;
|
||||
|
||||
@end
|
||||
@@ -31,7 +31,19 @@ static ContentManager* sharedInstance = nil;
|
||||
{
|
||||
_fileNamesCache = [[NSMutableDictionary alloc] init];
|
||||
_fileIconsEnabled = TRUE;
|
||||
_hasChangedContent = TRUE;
|
||||
|
||||
NSString *base = @"/Applications/owncloud.app/Contents/Resources/icons/";
|
||||
|
||||
_icnOk = [[IconCache sharedInstance] registerIcon:[base stringByAppendingString:@"ok.icns"]];
|
||||
_icnSync = [[IconCache sharedInstance] registerIcon:[base stringByAppendingString:@"sync.icns"]];
|
||||
_icnWarn = [[IconCache sharedInstance] registerIcon:[base stringByAppendingString:@"warning.icns"]];
|
||||
_icnErr = [[IconCache sharedInstance] registerIcon:[base stringByAppendingString:@"error.icns"]];
|
||||
_icnOkSwm = [[IconCache sharedInstance] registerIcon:[base stringByAppendingString:@"ok_swm.icns"]];
|
||||
_icnSyncSwm = [[IconCache sharedInstance] registerIcon:[base stringByAppendingString:@"sync_swm.icns"]];
|
||||
_icnWarnSwm = [[IconCache sharedInstance] registerIcon:[base stringByAppendingString:@"warning_swm.icns"]];
|
||||
_icnErrSwm = [[IconCache sharedInstance] registerIcon:[base stringByAppendingString:@"error_swm.icns"]];
|
||||
|
||||
NSLog(@"Icon ok identifier: %d", [_icnOk intValue]);
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -59,22 +71,6 @@ static ContentManager* sharedInstance = nil;
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
- (void)loadIconResourcePath:(NSString*)path
|
||||
{
|
||||
NSString *base = path;
|
||||
|
||||
_icnOk = [[IconCache sharedInstance] registerIcon:[base stringByAppendingString:@"ok.icns"]];
|
||||
_icnSync = [[IconCache sharedInstance] registerIcon:[base stringByAppendingString:@"sync.icns"]];
|
||||
_icnWarn = [[IconCache sharedInstance] registerIcon:[base stringByAppendingString:@"warning.icns"]];
|
||||
_icnErr = [[IconCache sharedInstance] registerIcon:[base stringByAppendingString:@"error.icns"]];
|
||||
_icnOkSwm = [[IconCache sharedInstance] registerIcon:[base stringByAppendingString:@"ok_swm.icns"]];
|
||||
_icnSyncSwm = [[IconCache sharedInstance] registerIcon:[base stringByAppendingString:@"sync_swm.icns"]];
|
||||
_icnWarnSwm = [[IconCache sharedInstance] registerIcon:[base stringByAppendingString:@"warning_swm.icns"]];
|
||||
_icnErrSwm = [[IconCache sharedInstance] registerIcon:[base stringByAppendingString:@"error_swm.icns"]];
|
||||
|
||||
NSLog(@"Icon ok identifier: %d from %@", [_icnOk intValue], [base stringByAppendingString:@"ok.icns"]);
|
||||
}
|
||||
|
||||
- (void)enableFileIcons:(BOOL)enable
|
||||
{
|
||||
_fileIconsEnabled = enable;
|
||||
@@ -84,10 +80,6 @@ static ContentManager* sharedInstance = nil;
|
||||
|
||||
- (void)setResultForPath:(NSString*)path result:(NSString*)result
|
||||
{
|
||||
if (_icnOk == nil) {
|
||||
// no icon resource path registered yet
|
||||
return;
|
||||
}
|
||||
|
||||
NSNumber *res;
|
||||
res = [NSNumber numberWithInt:0];
|
||||
@@ -115,18 +107,14 @@ static ContentManager* sharedInstance = nil;
|
||||
}
|
||||
|
||||
NSString* normalizedPath = [path decomposedStringWithCanonicalMapping];
|
||||
|
||||
if (![_fileNamesCache objectForKey:normalizedPath] || ![[_fileNamesCache objectForKey:normalizedPath] isEqualTo:res]) {
|
||||
[_fileNamesCache setObject:res forKey:normalizedPath];
|
||||
//NSLog(@"SET value %d %@", [res intValue], normalizedPath);
|
||||
_hasChangedContent = YES;
|
||||
[self performSelector:@selector(repaintAllWindowsIfNeeded) withObject:0 afterDelay:1.0]; // 1 sec
|
||||
}
|
||||
[_fileNamesCache setObject:res forKey:normalizedPath];
|
||||
// NSLog(@"SET value %d", [res intValue]);
|
||||
|
||||
[self repaintAllWindows];
|
||||
}
|
||||
|
||||
- (NSNumber*)iconByPath:(NSString*)path isDirectory:(BOOL)isDir
|
||||
{
|
||||
//NSLog(@"%@ %@", NSStringFromSelector(_cmd), path);
|
||||
if (!_fileIconsEnabled)
|
||||
{
|
||||
NSLog(@"Icons are NOT ENABLED!");
|
||||
@@ -138,13 +126,9 @@ static ContentManager* sharedInstance = nil;
|
||||
return res;
|
||||
}
|
||||
NSString* normalizedPath = [path decomposedStringWithCanonicalMapping];
|
||||
|
||||
if (![[RequestManager sharedInstance] isRegisteredPath:normalizedPath isDirectory:isDir]) {
|
||||
return [NSNumber numberWithInt:0];
|
||||
}
|
||||
|
||||
NSNumber* result = [_fileNamesCache objectForKey:normalizedPath];
|
||||
// NSLog(@"XXXXXXX Asking for icon for path %@ = %d",normalizedPath, [result intValue]);
|
||||
// NSLog(@"XXXXXXX Asking for icon for path %@ = %d",path, [result intValue]);
|
||||
|
||||
if( result == nil ) {
|
||||
// start the async call
|
||||
@@ -167,7 +151,6 @@ static ContentManager* sharedInstance = nil;
|
||||
// it clears the entries from the hash to make it call again home to mirall.
|
||||
- (void)clearFileNameCacheForPath:(NSString*)path
|
||||
{
|
||||
NSLog(@"%@", NSStringFromSelector(_cmd));
|
||||
NSMutableArray *keysToDelete = [NSMutableArray array];
|
||||
|
||||
if( path != nil ) {
|
||||
@@ -187,30 +170,12 @@ static ContentManager* sharedInstance = nil;
|
||||
if( [keysToDelete count] > 0 ) {
|
||||
NSLog( @"Entries to delete: %d", [keysToDelete count]);
|
||||
[_fileNamesCache removeObjectsForKeys:keysToDelete];
|
||||
|
||||
[self repaintAllWindows];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
- (void)reFetchFileNameCacheForPath:(NSString*)path
|
||||
{
|
||||
NSLog(@"%@", NSStringFromSelector(_cmd));
|
||||
|
||||
for (id p in [_fileNamesCache keyEnumerator]) {
|
||||
if ( path && [p hasPrefix:path] ) {
|
||||
[[RequestManager sharedInstance] askForIcon:p isDirectory:false]; // FIXME isDirectory parameter
|
||||
//[_fileNamesCache setObject:askState forKey:p]; We don't do this since we want to keep the old icon meanwhile
|
||||
//NSLog(@"%@ %@", NSStringFromSelector(_cmd), p);
|
||||
}
|
||||
}
|
||||
|
||||
// Ask for directory itself
|
||||
if ([path hasSuffix:@"/"]) {
|
||||
path = [path substringToIndex:path.length - 1];
|
||||
}
|
||||
[[RequestManager sharedInstance] askForIcon:path isDirectory:true];
|
||||
//NSLog(@"%@ %@", NSStringFromSelector(_cmd), path);
|
||||
}
|
||||
|
||||
|
||||
- (void)removeAllIcons
|
||||
{
|
||||
[_fileNamesCache removeAllObjects];
|
||||
@@ -230,20 +195,8 @@ static ContentManager* sharedInstance = nil;
|
||||
[self repaintAllWindows];
|
||||
}
|
||||
|
||||
- (void)repaintAllWindowsIfNeeded
|
||||
{
|
||||
if (!_hasChangedContent) {
|
||||
NSLog(@"%@ Repaint scheduled but not needed", NSStringFromSelector(_cmd));
|
||||
return;
|
||||
}
|
||||
|
||||
_hasChangedContent = NO;
|
||||
[self repaintAllWindows];
|
||||
}
|
||||
|
||||
- (void)repaintAllWindows
|
||||
{
|
||||
NSLog(@"%@", NSStringFromSelector(_cmd));
|
||||
NSArray* windows = [[NSApplication sharedApplication] windows];
|
||||
|
||||
for (int i = 0; i < [windows count]; i++)
|
||||
@@ -333,7 +286,7 @@ static ContentManager* sharedInstance = nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"OwnCloudFinder: refreshing icon badges failed");
|
||||
NSLog(@"LiferayNativityFinder: refreshing icon badges failed");
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -344,7 +297,6 @@ static ContentManager* sharedInstance = nil;
|
||||
|
||||
- (void)setIcons:(NSDictionary*)iconDictionary filterByFolder:(NSString*)filterFolder
|
||||
{
|
||||
NSLog(@"%@", NSStringFromSelector(_cmd));
|
||||
for (NSString* path in iconDictionary)
|
||||
{
|
||||
if (filterFolder && ![path hasPrefix:filterFolder])
|
||||
|
||||
@@ -3,77 +3,25 @@
|
||||
//
|
||||
// This class is in the public domain.
|
||||
// Originally created by Robbie Hanson in Q3 2010.
|
||||
// Updated and maintained by Deusty LLC and the Apple development community.
|
||||
// Updated and maintained by Deusty LLC and the Mac development community.
|
||||
//
|
||||
// https://github.com/robbiehanson/CocoaAsyncSocket
|
||||
// http://code.google.com/p/cocoaasyncsocket/
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Security/Security.h>
|
||||
#import <Security/SecureTransport.h>
|
||||
#import <dispatch/dispatch.h>
|
||||
|
||||
@class GCDAsyncReadPacket;
|
||||
@class GCDAsyncWritePacket;
|
||||
@class GCDAsyncSocketPreBuffer;
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
// Compiling for iOS
|
||||
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 50000 // iOS 5.0 supported
|
||||
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 50000 // iOS 5.0 supported and required
|
||||
|
||||
#define IS_SECURE_TRANSPORT_AVAILABLE YES
|
||||
#define SECURE_TRANSPORT_MAYBE_AVAILABLE 1
|
||||
#define SECURE_TRANSPORT_MAYBE_UNAVAILABLE 0
|
||||
|
||||
#else // iOS 5.0 supported but not required
|
||||
|
||||
#ifndef NSFoundationVersionNumber_iPhoneOS_5_0
|
||||
#define NSFoundationVersionNumber_iPhoneOS_5_0 881.00
|
||||
#endif
|
||||
|
||||
#define IS_SECURE_TRANSPORT_AVAILABLE (NSFoundationVersionNumber >= NSFoundationVersionNumber_iPhoneOS_5_0)
|
||||
#define SECURE_TRANSPORT_MAYBE_AVAILABLE 1
|
||||
#define SECURE_TRANSPORT_MAYBE_UNAVAILABLE 1
|
||||
|
||||
#endif
|
||||
|
||||
#else // iOS 5.0 not supported
|
||||
|
||||
#define IS_SECURE_TRANSPORT_AVAILABLE NO
|
||||
#define SECURE_TRANSPORT_MAYBE_AVAILABLE 0
|
||||
#define SECURE_TRANSPORT_MAYBE_UNAVAILABLE 1
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
// Compiling for Mac OS X
|
||||
|
||||
#define IS_SECURE_TRANSPORT_AVAILABLE YES
|
||||
#define SECURE_TRANSPORT_MAYBE_AVAILABLE 1
|
||||
#define SECURE_TRANSPORT_MAYBE_UNAVAILABLE 0
|
||||
|
||||
#endif
|
||||
|
||||
extern NSString *const GCDAsyncSocketException;
|
||||
extern NSString *const GCDAsyncSocketErrorDomain;
|
||||
|
||||
extern NSString *const GCDAsyncSocketQueueName;
|
||||
extern NSString *const GCDAsyncSocketThreadName;
|
||||
|
||||
#if SECURE_TRANSPORT_MAYBE_AVAILABLE
|
||||
#if !TARGET_OS_IPHONE
|
||||
extern NSString *const GCDAsyncSocketSSLCipherSuites;
|
||||
#if TARGET_OS_IPHONE
|
||||
extern NSString *const GCDAsyncSocketSSLProtocolVersionMin;
|
||||
extern NSString *const GCDAsyncSocketSSLProtocolVersionMax;
|
||||
#else
|
||||
extern NSString *const GCDAsyncSocketSSLDiffieHellmanParameters;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
enum GCDAsyncSocketError
|
||||
{
|
||||
@@ -94,6 +42,51 @@ typedef enum GCDAsyncSocketError GCDAsyncSocketError;
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@interface GCDAsyncSocket : NSObject
|
||||
{
|
||||
uint32_t flags;
|
||||
uint16_t config;
|
||||
|
||||
id delegate;
|
||||
dispatch_queue_t delegateQueue;
|
||||
|
||||
int socket4FD;
|
||||
int socket6FD;
|
||||
int connectIndex;
|
||||
NSData * connectInterface4;
|
||||
NSData * connectInterface6;
|
||||
|
||||
dispatch_queue_t socketQueue;
|
||||
|
||||
dispatch_source_t accept4Source;
|
||||
dispatch_source_t accept6Source;
|
||||
dispatch_source_t connectTimer;
|
||||
dispatch_source_t readSource;
|
||||
dispatch_source_t writeSource;
|
||||
dispatch_source_t readTimer;
|
||||
dispatch_source_t writeTimer;
|
||||
|
||||
NSMutableArray *readQueue;
|
||||
NSMutableArray *writeQueue;
|
||||
|
||||
GCDAsyncReadPacket *currentRead;
|
||||
GCDAsyncWritePacket *currentWrite;
|
||||
|
||||
unsigned long socketFDBytesAvailable;
|
||||
|
||||
NSMutableData *partialReadBuffer;
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
CFStreamClientContext streamContext;
|
||||
CFReadStreamRef readStream;
|
||||
CFWriteStreamRef writeStream;
|
||||
#else
|
||||
SSLContextRef sslContext;
|
||||
NSMutableData *sslReadBuffer;
|
||||
size_t sslWriteCachedLength;
|
||||
#endif
|
||||
|
||||
id userData;
|
||||
}
|
||||
|
||||
/**
|
||||
* GCDAsyncSocket uses the standard delegate paradigm,
|
||||
@@ -106,8 +99,6 @@ typedef enum GCDAsyncSocketError GCDAsyncSocketError;
|
||||
* The socket queue is optional.
|
||||
* If you pass NULL, GCDAsyncSocket will automatically create it's own socket queue.
|
||||
* If you choose to provide a socket queue, the socket queue must not be a concurrent queue.
|
||||
* If you choose to provide a socket queue, and the socket queue has a configured target queue,
|
||||
* then please see the discussion for the method markSocketQueueTargetQueue.
|
||||
*
|
||||
* The delegate queue and socket queue can optionally be the same.
|
||||
**/
|
||||
@@ -130,6 +121,39 @@ typedef enum GCDAsyncSocketError GCDAsyncSocketError;
|
||||
- (void)setDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue;
|
||||
- (void)synchronouslySetDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue;
|
||||
|
||||
/**
|
||||
* Traditionally sockets are not closed until the conversation is over.
|
||||
* However, it is technically possible for the remote enpoint to close its write stream.
|
||||
* Our socket would then be notified that there is no more data to be read,
|
||||
* but our socket would still be writeable and the remote endpoint could continue to receive our data.
|
||||
*
|
||||
* The argument for this confusing functionality stems from the idea that a client could shut down its
|
||||
* write stream after sending a request to the server, thus notifying the server there are to be no further requests.
|
||||
* In practice, however, this technique did little to help server developers.
|
||||
*
|
||||
* To make matters worse, from a TCP perspective there is no way to tell the difference from a read stream close
|
||||
* and a full socket close. They both result in the TCP stack receiving a FIN packet. The only way to tell
|
||||
* is by continuing to write to the socket. If it was only a read stream close, then writes will continue to work.
|
||||
* Otherwise an error will be occur shortly (when the remote end sends us a RST packet).
|
||||
*
|
||||
* In addition to the technical challenges and confusion, many high level socket/stream API's provide
|
||||
* no support for dealing with the problem. If the read stream is closed, the API immediately declares the
|
||||
* socket to be closed, and shuts down the write stream as well. In fact, this is what Apple's CFStream API does.
|
||||
* It might sound like poor design at first, but in fact it simplifies development.
|
||||
*
|
||||
* The vast majority of the time if the read stream is closed it's because the remote endpoint closed its socket.
|
||||
* Thus it actually makes sense to close the socket at this point.
|
||||
* And in fact this is what most networking developers want and expect to happen.
|
||||
* However, if you are writing a server that interacts with a plethora of clients,
|
||||
* you might encounter a client that uses the discouraged technique of shutting down its write stream.
|
||||
* If this is the case, you can set this property to NO,
|
||||
* and make use of the socketDidCloseReadStream delegate method.
|
||||
*
|
||||
* The default value is YES.
|
||||
**/
|
||||
- (BOOL)autoDisconnectOnClosedReadStream;
|
||||
- (void)setAutoDisconnectOnClosedReadStream:(BOOL)flag;
|
||||
|
||||
/**
|
||||
* By default, both IPv4 and IPv6 are enabled.
|
||||
*
|
||||
@@ -187,15 +211,6 @@ typedef enum GCDAsyncSocketError GCDAsyncSocketError;
|
||||
**/
|
||||
- (BOOL)acceptOnInterface:(NSString *)interface port:(uint16_t)port error:(NSError **)errPtr;
|
||||
|
||||
/**
|
||||
* Tells the socket to begin listening and accepting connections on the unix domain at the given url.
|
||||
* When a connection is accepted, a new instance of GCDAsyncSocket will be spawned to handle it,
|
||||
* and the socket:didAcceptNewSocket: delegate method will be invoked.
|
||||
*
|
||||
* The socket will listen on all available interfaces (e.g. wifi, ethernet, etc)
|
||||
**/
|
||||
- (BOOL)acceptOnUrl:(NSURL *)url error:(NSError **)errPtr;
|
||||
|
||||
#pragma mark Connecting
|
||||
|
||||
/**
|
||||
@@ -311,10 +326,6 @@ typedef enum GCDAsyncSocketError GCDAsyncSocketError;
|
||||
viaInterface:(NSString *)interface
|
||||
withTimeout:(NSTimeInterval)timeout
|
||||
error:(NSError **)errPtr;
|
||||
/**
|
||||
* Connects to the unix domain socket at the given url, using the specified timeout.
|
||||
*/
|
||||
- (BOOL)connectToUrl:(NSURL *)url withTimeout:(NSTimeInterval)timeout error:(NSError **)errPtr;
|
||||
|
||||
#pragma mark Disconnecting
|
||||
|
||||
@@ -378,7 +389,6 @@ typedef enum GCDAsyncSocketError GCDAsyncSocketError;
|
||||
**/
|
||||
- (NSString *)connectedHost;
|
||||
- (uint16_t)connectedPort;
|
||||
- (NSURL *)connectedUrl;
|
||||
|
||||
- (NSString *)localHost;
|
||||
- (uint16_t)localPort;
|
||||
@@ -636,12 +646,6 @@ typedef enum GCDAsyncSocketError GCDAsyncSocketError;
|
||||
maxLength:(NSUInteger)length
|
||||
tag:(long)tag;
|
||||
|
||||
/**
|
||||
* Returns progress of the current read, from 0.0 to 1.0, or NaN if no current read (use isnan() to check).
|
||||
* The parameters "tag", "done" and "total" will be filled in if they aren't NULL.
|
||||
**/
|
||||
- (float)progressOfReadReturningTag:(long *)tagPtr bytesDone:(NSUInteger *)donePtr total:(NSUInteger *)totalPtr;
|
||||
|
||||
#pragma mark Writing
|
||||
|
||||
/**
|
||||
@@ -663,12 +667,6 @@ typedef enum GCDAsyncSocketError GCDAsyncSocketError;
|
||||
**/
|
||||
- (void)writeData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
|
||||
|
||||
/**
|
||||
* Returns progress of the current write, from 0.0 to 1.0, or NaN if no current write (use isnan() to check).
|
||||
* The parameters "tag", "done" and "total" will be filled in if they aren't NULL.
|
||||
**/
|
||||
- (float)progressOfWriteReturningTag:(long *)tagPtr bytesDone:(NSUInteger *)donePtr total:(NSUInteger *)totalPtr;
|
||||
|
||||
#pragma mark Security
|
||||
|
||||
/**
|
||||
@@ -680,8 +678,7 @@ typedef enum GCDAsyncSocketError GCDAsyncSocketError;
|
||||
* Any reads or writes scheduled after this method is called will occur over the secured connection.
|
||||
*
|
||||
* The possible keys and values for the TLS settings are well documented.
|
||||
* Standard keys are:
|
||||
*
|
||||
* Some possible keys are:
|
||||
* - kCFStreamSSLLevel
|
||||
* - kCFStreamSSLAllowsExpiredCertificates
|
||||
* - kCFStreamSSLAllowsExpiredRoots
|
||||
@@ -691,18 +688,6 @@ typedef enum GCDAsyncSocketError GCDAsyncSocketError;
|
||||
* - kCFStreamSSLCertificates
|
||||
* - kCFStreamSSLIsServer
|
||||
*
|
||||
* If SecureTransport is available on iOS:
|
||||
*
|
||||
* - GCDAsyncSocketSSLCipherSuites
|
||||
* - GCDAsyncSocketSSLProtocolVersionMin
|
||||
* - GCDAsyncSocketSSLProtocolVersionMax
|
||||
*
|
||||
* If SecureTransport is available on Mac OS X:
|
||||
*
|
||||
* - GCDAsyncSocketSSLCipherSuites
|
||||
* - GCDAsyncSocketSSLDiffieHellmanParameters;
|
||||
*
|
||||
*
|
||||
* Please refer to Apple's documentation for associated values, as well as other possible keys.
|
||||
*
|
||||
* If you pass in nil or an empty dictionary, the default settings will be used.
|
||||
@@ -727,114 +712,6 @@ typedef enum GCDAsyncSocketError GCDAsyncSocketError;
|
||||
|
||||
#pragma mark Advanced
|
||||
|
||||
/**
|
||||
* Traditionally sockets are not closed until the conversation is over.
|
||||
* However, it is technically possible for the remote enpoint to close its write stream.
|
||||
* Our socket would then be notified that there is no more data to be read,
|
||||
* but our socket would still be writeable and the remote endpoint could continue to receive our data.
|
||||
*
|
||||
* The argument for this confusing functionality stems from the idea that a client could shut down its
|
||||
* write stream after sending a request to the server, thus notifying the server there are to be no further requests.
|
||||
* In practice, however, this technique did little to help server developers.
|
||||
*
|
||||
* To make matters worse, from a TCP perspective there is no way to tell the difference from a read stream close
|
||||
* and a full socket close. They both result in the TCP stack receiving a FIN packet. The only way to tell
|
||||
* is by continuing to write to the socket. If it was only a read stream close, then writes will continue to work.
|
||||
* Otherwise an error will be occur shortly (when the remote end sends us a RST packet).
|
||||
*
|
||||
* In addition to the technical challenges and confusion, many high level socket/stream API's provide
|
||||
* no support for dealing with the problem. If the read stream is closed, the API immediately declares the
|
||||
* socket to be closed, and shuts down the write stream as well. In fact, this is what Apple's CFStream API does.
|
||||
* It might sound like poor design at first, but in fact it simplifies development.
|
||||
*
|
||||
* The vast majority of the time if the read stream is closed it's because the remote endpoint closed its socket.
|
||||
* Thus it actually makes sense to close the socket at this point.
|
||||
* And in fact this is what most networking developers want and expect to happen.
|
||||
* However, if you are writing a server that interacts with a plethora of clients,
|
||||
* you might encounter a client that uses the discouraged technique of shutting down its write stream.
|
||||
* If this is the case, you can set this property to NO,
|
||||
* and make use of the socketDidCloseReadStream delegate method.
|
||||
*
|
||||
* The default value is YES.
|
||||
**/
|
||||
- (BOOL)autoDisconnectOnClosedReadStream;
|
||||
- (void)setAutoDisconnectOnClosedReadStream:(BOOL)flag;
|
||||
|
||||
/**
|
||||
* GCDAsyncSocket maintains thread safety by using an internal serial dispatch_queue.
|
||||
* In most cases, the instance creates this queue itself.
|
||||
* However, to allow for maximum flexibility, the internal queue may be passed in the init method.
|
||||
* This allows for some advanced options such as controlling socket priority via target queues.
|
||||
* However, when one begins to use target queues like this, they open the door to some specific deadlock issues.
|
||||
*
|
||||
* For example, imagine there are 2 queues:
|
||||
* dispatch_queue_t socketQueue;
|
||||
* dispatch_queue_t socketTargetQueue;
|
||||
*
|
||||
* If you do this (pseudo-code):
|
||||
* socketQueue.targetQueue = socketTargetQueue;
|
||||
*
|
||||
* Then all socketQueue operations will actually get run on the given socketTargetQueue.
|
||||
* This is fine and works great in most situations.
|
||||
* But if you run code directly from within the socketTargetQueue that accesses the socket,
|
||||
* you could potentially get deadlock. Imagine the following code:
|
||||
*
|
||||
* - (BOOL)socketHasSomething
|
||||
* {
|
||||
* __block BOOL result = NO;
|
||||
* dispatch_block_t block = ^{
|
||||
* result = [self someInternalMethodToBeRunOnlyOnSocketQueue];
|
||||
* }
|
||||
* if (is_executing_on_queue(socketQueue))
|
||||
* block();
|
||||
* else
|
||||
* dispatch_sync(socketQueue, block);
|
||||
*
|
||||
* return result;
|
||||
* }
|
||||
*
|
||||
* What happens if you call this method from the socketTargetQueue? The result is deadlock.
|
||||
* This is because the GCD API offers no mechanism to discover a queue's targetQueue.
|
||||
* Thus we have no idea if our socketQueue is configured with a targetQueue.
|
||||
* If we had this information, we could easily avoid deadlock.
|
||||
* But, since these API's are missing or unfeasible, you'll have to explicitly set it.
|
||||
*
|
||||
* IF you pass a socketQueue via the init method,
|
||||
* AND you've configured the passed socketQueue with a targetQueue,
|
||||
* THEN you should pass the end queue in the target hierarchy.
|
||||
*
|
||||
* For example, consider the following queue hierarchy:
|
||||
* socketQueue -> ipQueue -> moduleQueue
|
||||
*
|
||||
* This example demonstrates priority shaping within some server.
|
||||
* All incoming client connections from the same IP address are executed on the same target queue.
|
||||
* And all connections for a particular module are executed on the same target queue.
|
||||
* Thus, the priority of all networking for the entire module can be changed on the fly.
|
||||
* Additionally, networking traffic from a single IP cannot monopolize the module.
|
||||
*
|
||||
* Here's how you would accomplish something like that:
|
||||
* - (dispatch_queue_t)newSocketQueueForConnectionFromAddress:(NSData *)address onSocket:(GCDAsyncSocket *)sock
|
||||
* {
|
||||
* dispatch_queue_t socketQueue = dispatch_queue_create("", NULL);
|
||||
* dispatch_queue_t ipQueue = [self ipQueueForAddress:address];
|
||||
*
|
||||
* dispatch_set_target_queue(socketQueue, ipQueue);
|
||||
* dispatch_set_target_queue(iqQueue, moduleQueue);
|
||||
*
|
||||
* return socketQueue;
|
||||
* }
|
||||
* - (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket
|
||||
* {
|
||||
* [clientConnections addObject:newSocket];
|
||||
* [newSocket markSocketQueueTargetQueue:moduleQueue];
|
||||
* }
|
||||
*
|
||||
* Note: This workaround is ONLY needed if you intend to execute code directly on the ipQueue or moduleQueue.
|
||||
* This is often NOT the case, as such queues are used solely for execution shaping.
|
||||
**/
|
||||
- (void)markSocketQueueTargetQueue:(dispatch_queue_t)socketQueuesPreConfiguredTargetQueue;
|
||||
- (void)unmarkSocketQueueTargetQueue:(dispatch_queue_t)socketQueuesPreviouslyConfiguredTargetQueue;
|
||||
|
||||
/**
|
||||
* It's not thread-safe to access certain variables from outside the socket's internal queue.
|
||||
*
|
||||
@@ -928,9 +805,7 @@ typedef enum GCDAsyncSocketError GCDAsyncSocketError;
|
||||
**/
|
||||
- (BOOL)enableBackgroundingOnSocket;
|
||||
|
||||
#endif
|
||||
|
||||
#if SECURE_TRANSPORT_MAYBE_AVAILABLE
|
||||
#else
|
||||
|
||||
/**
|
||||
* This method is only available from within the context of a performBlock: invocation.
|
||||
@@ -1006,12 +881,6 @@ typedef enum GCDAsyncSocketError GCDAsyncSocketError;
|
||||
**/
|
||||
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port;
|
||||
|
||||
/**
|
||||
* Called when a socket connects and is ready for reading and writing.
|
||||
* The host parameter will be an IP address, not a DNS name.
|
||||
**/
|
||||
- (void)socket:(GCDAsyncSocket *)sock didConnectToUrl:(NSURL *)url;
|
||||
|
||||
/**
|
||||
* Called when a socket has completed reading the requested data into memory.
|
||||
* Not called if there is an error.
|
||||
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -71,7 +71,6 @@ static IconCache* sharedInstance = nil;
|
||||
|
||||
if (image == nil)
|
||||
{
|
||||
NSLog(@"%@ Could not load %@", NSStringFromSelector(_cmd), path);
|
||||
return [NSNumber numberWithInt:-1];
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
NSNumber* imageIndex = [[ContentManager sharedInstance] iconByPath:[url path] isDirectory:isDir];
|
||||
|
||||
//NSLog(@"1 The icon index is %d", [imageIndex intValue]);
|
||||
NSLog(@"1 The icon index is %d", [imageIndex intValue]);
|
||||
if ([imageIndex intValue] > 0)
|
||||
{
|
||||
NSImage* image = [[IconCache sharedInstance] getIcon:imageIndex];
|
||||
@@ -77,7 +77,7 @@
|
||||
}
|
||||
|
||||
NSNumber* imageIndex = [[ContentManager sharedInstance] iconByPath:[url path] isDirectory:isDir];
|
||||
//NSLog(@"2 The icon index is %d %@ %@", [imageIndex intValue], [url path], isDir ? @"isDir" : @"");
|
||||
// NSLog(@"2 The icon index is %d", [imageIndex intValue]);
|
||||
|
||||
if ([imageIndex intValue] > 0)
|
||||
{
|
||||
@@ -145,7 +145,7 @@
|
||||
}
|
||||
|
||||
NSNumber* imageIndex = [[ContentManager sharedInstance] iconByPath:[url path] isDirectory:isDir];
|
||||
//NSLog(@"3 The icon index is %d", [imageIndex intValue]);
|
||||
NSLog(@"3 The icon index is %d", [imageIndex intValue]);
|
||||
|
||||
if ([imageIndex intValue] > 0)
|
||||
{
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>OWNC</string>
|
||||
<string>NVTY</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>CFPlugInDynamicRegisterFunction</key>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
0B13ECAE173C687400548DA1 /* GCDAsyncSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = 0B13ECAD173C686A00548DA1 /* GCDAsyncSocket.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
|
||||
0B13ECAE173C687400548DA1 /* GCDAsyncSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = 0B13ECAD173C686A00548DA1 /* GCDAsyncSocket.m */; };
|
||||
0B13ECAF173C687900548DA1 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BFC9ACB173C57E400CDD329 /* Security.framework */; };
|
||||
0BFAF21C16F8E6C10017EA7E /* JSONKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 0BFAF21B16F8E6C10017EA7E /* JSONKit.m */; };
|
||||
692C18A516660C4700BF6A53 /* ContextMenuHandlers.m in Sources */ = {isa = PBXBuildFile; fileRef = 692C18A416660C4600BF6A53 /* ContextMenuHandlers.m */; };
|
||||
@@ -302,9 +302,8 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
COPY_PHASE_STRIP = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
+ (RequestManager*)sharedInstance;
|
||||
|
||||
- (BOOL)isRegisteredPath:(NSString*)path isDirectory:(BOOL)isDir;
|
||||
- (BOOL)isRegisteredPath:(NSString*)path;
|
||||
- (void)askOnSocket:(NSString*)path query:(NSString*)verb;
|
||||
- (NSNumber*)askForIcon:(NSString*)path isDirectory:(BOOL)isDir;
|
||||
- (void)menuItemClicked:(NSDictionary*)actionDictionary;
|
||||
|
||||
@@ -77,20 +77,14 @@ static RequestManager* sharedInstance = nil;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)isRegisteredPath:(NSString*)path isDirectory:(BOOL)isDir
|
||||
- (BOOL)isRegisteredPath:(NSString*)path
|
||||
{
|
||||
// check if the file in question is underneath a registered directory
|
||||
NSArray *regPathes = [_registeredPathes allKeys];
|
||||
BOOL registered = NO;
|
||||
|
||||
NSString* checkPath = [[NSString alloc] initWithString:path];
|
||||
if (isDir) {
|
||||
// append a slash
|
||||
checkPath = [path stringByAppendingString:@"/"];
|
||||
}
|
||||
|
||||
for( NSString *regPath in regPathes ) {
|
||||
if( [checkPath hasPrefix:regPath]) {
|
||||
if( [path hasPrefix:regPath]) {
|
||||
// the path was registered
|
||||
registered = YES;
|
||||
break;
|
||||
@@ -105,7 +99,7 @@ static RequestManager* sharedInstance = nil;
|
||||
NSString *verb = @"RETRIEVE_FILE_STATUS";
|
||||
NSNumber *res = [NSNumber numberWithInt:0];
|
||||
|
||||
if( [self isRegisteredPath:path isDirectory:isDir] ) {
|
||||
if( [self isRegisteredPath:path] ) {
|
||||
if( _isConnected ) {
|
||||
if(isDir) {
|
||||
verb = @"RETRIEVE_FOLDER_STATUS";
|
||||
@@ -139,32 +133,24 @@ static RequestManager* sharedInstance = nil;
|
||||
|
||||
if( [chunks count] > 0 && tag == READ_TAG ) {
|
||||
if( [[chunks objectAtIndex:0] isEqualToString:@"STATUS"] ) {
|
||||
NSString *path = [chunks objectAtIndex:2];
|
||||
if( [chunks count] > 3 ) {
|
||||
for( int i = 2; i < [chunks count]-1; i++ ) {
|
||||
path = [NSString stringWithFormat:@"%@:%@",
|
||||
path, [chunks objectAtIndex:i+1] ];
|
||||
}
|
||||
}
|
||||
[contentman setResultForPath:path result:[chunks objectAtIndex:1]];
|
||||
[contentman setResultForPath:[chunks objectAtIndex:2] result:[chunks objectAtIndex:1]];
|
||||
} else if( [[chunks objectAtIndex:0] isEqualToString:@"UPDATE_VIEW"] ) {
|
||||
NSString *path = [chunks objectAtIndex:1];
|
||||
[contentman reFetchFileNameCacheForPath:path];
|
||||
[contentman clearFileNameCacheForPath:path];
|
||||
|
||||
[contentman repaintAllWindows];
|
||||
} else if( [[chunks objectAtIndex:0 ] isEqualToString:@"REGISTER_PATH"] ) {
|
||||
NSNumber *one = [NSNumber numberWithInt:1];
|
||||
NSString *path = [chunks objectAtIndex:1];
|
||||
NSLog(@"Registering path: %@", path);
|
||||
[_registeredPathes setObject:one forKey:path];
|
||||
|
||||
[contentman repaintAllWindows];
|
||||
} else if( [[chunks objectAtIndex:0 ] isEqualToString:@"UNREGISTER_PATH"] ) {
|
||||
NSNumber *one = [NSNumber numberWithInt:1];
|
||||
NSString *path = [chunks objectAtIndex:1];
|
||||
[_registeredPathes removeObjectForKey:path];
|
||||
|
||||
[contentman repaintAllWindows];
|
||||
} else if( [[chunks objectAtIndex:0 ] isEqualToString:@"ICON_PATH"] ) {
|
||||
NSString *path = [chunks objectAtIndex:1];
|
||||
[[ContentManager sharedInstance] loadIconResourcePath:path];
|
||||
} else {
|
||||
NSLog(@"Unknown command %@", [chunks objectAtIndex:0]);
|
||||
}
|
||||
@@ -183,19 +169,9 @@ static RequestManager* sharedInstance = nil;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
-(void)socket:(GCDAsyncSocket*)socket didConnectToUrl:(NSURL *)url {
|
||||
NSLog(@"didConnectToUrl %@", url);
|
||||
[self socketDidConnect:socket];
|
||||
}
|
||||
|
||||
- (void)socket:(GCDAsyncSocket*)socket didConnectToHost:(NSString*)host port:(UInt16)port
|
||||
{
|
||||
[self socketDidConnect:socket];
|
||||
}
|
||||
|
||||
// Our impl
|
||||
- (void)socketDidConnect:(GCDAsyncSocket*)socket {
|
||||
NSLog( @"Connected to sync client successfully!");
|
||||
NSLog( @"Connected to host successfully!");
|
||||
_isConnected = YES;
|
||||
_isRunning = NO;
|
||||
|
||||
@@ -205,10 +181,6 @@ static RequestManager* sharedInstance = nil;
|
||||
[self askOnSocket:path];
|
||||
}
|
||||
}
|
||||
|
||||
ContentManager *contentman = [ContentManager sharedInstance];
|
||||
[contentman clearFileNameCacheForPath:nil];
|
||||
[contentman repaintAllWindows];
|
||||
|
||||
// Read for the UPDATE_VIEW requests
|
||||
NSData* stop = [@"\n" dataUsingEncoding:NSUTF8StringEncoding];
|
||||
@@ -233,7 +205,6 @@ static RequestManager* sharedInstance = nil;
|
||||
// clear the caches in conent manager
|
||||
ContentManager *contentman = [ContentManager sharedInstance];
|
||||
[contentman clearFileNameCacheForPath:nil];
|
||||
[contentman repaintAllWindows];
|
||||
|
||||
[NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(start) userInfo:nil repeats:NO];
|
||||
|
||||
@@ -244,27 +215,12 @@ static RequestManager* sharedInstance = nil;
|
||||
{
|
||||
if (!_isRunning)
|
||||
{
|
||||
NSLog(@"Connect Socket!");
|
||||
NSError *err = nil;
|
||||
BOOL useTcp = NO;
|
||||
if (useTcp) {
|
||||
NSLog(@"Connect Socket");
|
||||
if (![_socket connectToHost:@"localhost" onPort:34001 withTimeout:5 error:&err]) {
|
||||
// If there was an error, it's likely something like "already connected" or "no delegate set"
|
||||
NSLog(@"I goofed: %@", err);
|
||||
}
|
||||
} else if (!useTcp) {
|
||||
NSURL *url;
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
|
||||
if ([paths count])
|
||||
{
|
||||
// file:///Users/guruz/Library/Caches/SyncStateHelper/ownCloud.socket
|
||||
// FIXME Generify this and support all sockets there since multiple sync clients might be running
|
||||
url =[NSURL fileURLWithPath:[[[paths objectAtIndex:0] stringByAppendingPathComponent:@"SyncStateHelper"] stringByAppendingPathComponent:@"ownCloud.socket"]];
|
||||
}
|
||||
if (url) {
|
||||
NSLog(@"Connect Socket to %@", url);
|
||||
[_socket connectToUrl:url withTimeout:5 error:&err];
|
||||
}
|
||||
if (![_socket connectToHost:@"localhost" onPort:34001 withTimeout:5 error:&err]) // Asynchronous!
|
||||
{
|
||||
// If there was an error, it's likely something like "already connected" or "no delegate set"
|
||||
NSLog(@"I goofed: %@", err);
|
||||
}
|
||||
|
||||
_isRunning = YES;
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<dict>
|
||||
<key>Events</key>
|
||||
<dict>
|
||||
<key>OWNClded</key>
|
||||
<key>NVTYlded</key>
|
||||
<dict>
|
||||
<key>Context</key>
|
||||
<string>Process</string>
|
||||
@@ -35,7 +35,7 @@
|
||||
<key>ThreadSafe</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<key>OWNCload</key>
|
||||
<key>NVTYload</key>
|
||||
<dict>
|
||||
<key>Context</key>
|
||||
<string>Process</string>
|
||||
@@ -44,7 +44,7 @@
|
||||
<key>ThreadSafe</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<key>OWNCunld</key>
|
||||
<key>NVTYunld</key>
|
||||
<dict>
|
||||
<key>Context</key>
|
||||
<string>Process</string>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
tell application "Finder"
|
||||
try
|
||||
«event OWNClded»
|
||||
«event NVTYlded»
|
||||
set the result to 0
|
||||
on error msg number code
|
||||
set the result to code
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
tell application "Finder"
|
||||
try
|
||||
«event OWNCload»
|
||||
«event NVTYload»
|
||||
end try
|
||||
end tell
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
osascript -e 'tell application "Finder" \
|
||||
try \
|
||||
«event OWNCload» \
|
||||
«event NVTYload» \
|
||||
end try \
|
||||
end tell'
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
tell application "Finder"
|
||||
try
|
||||
«event OWNCunld»
|
||||
«event NVTYunld»
|
||||
end try
|
||||
end tell
|
||||
|
||||
|
||||
@@ -13,12 +13,7 @@ if( UNIX AND NOT APPLE )
|
||||
|
||||
FOREACH(size 128x128 16x16 256x256 32x32 48x48 64x64 72x72)
|
||||
file(GLOB files "${size}/*.png")
|
||||
FOREACH( file ${files} )
|
||||
# the GLOB returns a absolute path. Make it relative by replacing the current src dir by nothing
|
||||
STRING(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/${size}/" "" shortFile ${file})
|
||||
STRING(REPLACE "oC" ${APPLICATION_NAME} brandedName ${shortFile})
|
||||
install(FILES ${file} DESTINATION ${ICON_DIR}/${size}/apps RENAME ${brandedName})
|
||||
ENDFOREACH(file)
|
||||
install(FILES ${files} DESTINATION ${ICON_DIR}/${size}/apps)
|
||||
ENDFOREACH(size)
|
||||
|
||||
endif()
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
|
||||
install(FILES syncstate.py DESTINATION ${DATADIR}/nautilus-python/extensions)
|
||||
install(FILES ownCloud.py DESTINATION ${DATADIR}/nautilus-python/extensions)
|
||||
|
||||
Arquivo executável
+168
@@ -0,0 +1,168 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import os
|
||||
import urllib
|
||||
import socket
|
||||
|
||||
from gi.repository import GObject, Nautilus
|
||||
|
||||
class ownCloudExtension(GObject.GObject, Nautilus.ColumnProvider, Nautilus.InfoProvider):
|
||||
|
||||
nautilusVFSFile_table = {}
|
||||
registered_paths = {}
|
||||
remainder = ''
|
||||
connected = False
|
||||
watch_id = 0
|
||||
|
||||
def __init__(self):
|
||||
self.connectToOwnCloud
|
||||
if not self.connected:
|
||||
# try again in 5 seconds - attention, logic inverted!
|
||||
GObject.timeout_add(5000, self.connectToOwnCloud)
|
||||
|
||||
def port(self):
|
||||
return 34001 # Fixme, read from config file.
|
||||
|
||||
def connectToOwnCloud(self):
|
||||
try:
|
||||
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
|
||||
self.sock.connect(("localhost", self.port()))
|
||||
self.sock.settimeout(5)
|
||||
self.connected = True
|
||||
self.watch_id = GObject.io_add_watch(self.sock, GObject.IO_IN, self.handle_notify)
|
||||
except:
|
||||
print "Connect could not be established, try again later!"
|
||||
self.sock.close()
|
||||
return not self.connected
|
||||
|
||||
def sendCommand(self, cmd):
|
||||
if self.connected:
|
||||
try:
|
||||
self.sock.send(cmd)
|
||||
except:
|
||||
print "Sending failed."
|
||||
GObject.source_remove( self.watch_id )
|
||||
self.connected = False
|
||||
GObject.timeout_add(5000, self.connectToOwnCloud)
|
||||
|
||||
def find_item_for_file( self, path ):
|
||||
if path in self.nautilusVFSFile_table:
|
||||
return self.nautilusVFSFile_table[path]
|
||||
else:
|
||||
return None
|
||||
|
||||
def askForOverlay(self, file):
|
||||
if os.path.isdir(file):
|
||||
folderStatus = self.sendCommand("RETRIEVE_FOLDER_STATUS:"+file+"\n");
|
||||
|
||||
if os.path.isfile(file):
|
||||
fileStatus = self.sendCommand("RETRIEVE_FILE_STATUS:"+file+"\n");
|
||||
|
||||
def invalidate_items_underneath( self, path ):
|
||||
update_items = []
|
||||
for p in self.nautilusVFSFile_table:
|
||||
if p == path or p.startswith( path ):
|
||||
item = self.nautilusVFSFile_table[p]
|
||||
update_items.append(item)
|
||||
|
||||
for item in update_items:
|
||||
item.invalidate_extension_info()
|
||||
# self.update_file_info(item)
|
||||
|
||||
# Handles a single line of server respoonse and sets the emblem
|
||||
def handle_server_response(self, l):
|
||||
Emblems = { 'OK' : 'oC_ok',
|
||||
'SYNC' : 'oC_sync',
|
||||
'NEW' : 'oC_sync',
|
||||
'IGNORE' : 'oC_warn',
|
||||
'ERROR' : 'oC_error',
|
||||
'OK+SWM' : 'oC_ok_shared',
|
||||
'SYNC+SWM' : 'oC_sync_shared',
|
||||
'NEW+SWM' : 'oC_sync_shared',
|
||||
'IGNORE+SWM': 'oC_warn_shared',
|
||||
'ERROR+SWM' : 'oC_error_shared',
|
||||
'NOP' : 'oC_error'
|
||||
}
|
||||
|
||||
print "Server response: "+l
|
||||
parts = l.split(':')
|
||||
if len(parts) > 0:
|
||||
action = parts[0]
|
||||
|
||||
# file = parts[1]
|
||||
# print "Action for " + file + ": "+parts[0]
|
||||
if action == 'STATUS':
|
||||
emblem = Emblems[parts[1]]
|
||||
if emblem:
|
||||
item = self.find_item_for_file(parts[2])
|
||||
if item:
|
||||
item.add_emblem(emblem)
|
||||
|
||||
elif action == 'UPDATE_VIEW':
|
||||
# Search all items underneath this path and invalidate them
|
||||
if parts[1] in self.registered_paths:
|
||||
self.invalidate_items_underneath( parts[1] )
|
||||
|
||||
elif action == 'REGISTER_PATH':
|
||||
self.registered_paths[parts[1]] = 1
|
||||
self.invalidate_items_underneath( parts[1] )
|
||||
elif action == 'UNREGISTER_PATH':
|
||||
del self.registered_paths[parts[1]]
|
||||
self.invalidate_items_underneath( parts[1] )
|
||||
|
||||
# check if there are non pathes any more, if so, its usual
|
||||
# that mirall went away. Try reconnect.
|
||||
if not self.registered_paths:
|
||||
self.sock.close()
|
||||
self.connected = False
|
||||
GObject.source_remove( self.watch_id )
|
||||
GObject.timeout_add(5000, self.connectToOwnCloud)
|
||||
|
||||
else:
|
||||
# print "We got unknown action " + action
|
||||
1
|
||||
|
||||
# notify is the raw answer from the socket
|
||||
def handle_notify(self, source, condition):
|
||||
|
||||
data = source.recv(1024)
|
||||
# prepend the remaining data from last call
|
||||
if len(self.remainder) > 0:
|
||||
data = self.remainder+data
|
||||
self.remainder = ''
|
||||
|
||||
if len(data) > 0:
|
||||
# remember the remainder for next round
|
||||
lastNL = data.rfind('\n');
|
||||
if lastNL > -1 and lastNL < len(data):
|
||||
self.remainder = data[lastNL+1:]
|
||||
data = data[:lastNL]
|
||||
|
||||
for l in data.split('\n'):
|
||||
self.handle_server_response( l )
|
||||
else:
|
||||
return False
|
||||
|
||||
return True # run again
|
||||
|
||||
def get_local_path(self, path):
|
||||
return path.replace("file://", "")
|
||||
|
||||
def update_file_info(self, item):
|
||||
if item.get_uri_scheme() != 'file':
|
||||
return
|
||||
|
||||
filename = urllib.unquote(item.get_uri()[7:])
|
||||
if item.is_directory():
|
||||
filename += '/'
|
||||
|
||||
for reg_path in self.registered_paths:
|
||||
if filename.startswith(reg_path):
|
||||
self.nautilusVFSFile_table[filename] = item
|
||||
|
||||
# item.add_string_attribute('share_state', "share state")
|
||||
self.askForOverlay(filename)
|
||||
break
|
||||
else:
|
||||
print "Not in scope:"+filename
|
||||
@@ -1,194 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
#
|
||||
# Copyright (C) by Klaas Freitag <freitag@owncloud.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# 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 General Public License
|
||||
# for more details.
|
||||
|
||||
import os
|
||||
import urllib
|
||||
import socket
|
||||
|
||||
from gi.repository import GObject, Nautilus
|
||||
|
||||
class syncStateExtension(GObject.GObject, Nautilus.ColumnProvider, Nautilus.InfoProvider):
|
||||
|
||||
nautilusVFSFile_table = {}
|
||||
registered_paths = {}
|
||||
remainder = ''
|
||||
connected = False
|
||||
watch_id = 0
|
||||
appname = 'ownCloud'
|
||||
|
||||
def __init__(self):
|
||||
self.connectToSocketServer
|
||||
if not self.connected:
|
||||
# try again in 5 seconds - attention, logic inverted!
|
||||
GObject.timeout_add(5000, self.connectToSocketServer)
|
||||
|
||||
def connectToSocketServer(self):
|
||||
try:
|
||||
self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
postfix = "/"+self.appname+"/socket"
|
||||
sock_file = os.environ["XDG_RUNTIME_DIR"]+postfix
|
||||
print ("XXXX " + sock_file + " <=> " + postfix)
|
||||
if sock_file != postfix:
|
||||
try:
|
||||
print("Socket File: "+sock_file)
|
||||
self.sock.connect(sock_file)
|
||||
self.connected = True
|
||||
self.watch_id = GObject.io_add_watch(self.sock, GObject.IO_IN, self.handle_notify)
|
||||
except:
|
||||
print("Could not connect to unix socket.")
|
||||
else:
|
||||
print("Sock-File not valid: "+sock_file)
|
||||
except:
|
||||
print("Connect could not be established, try again later!")
|
||||
self.sock.close()
|
||||
return not self.connected
|
||||
|
||||
def sendCommand(self, cmd):
|
||||
if self.connected:
|
||||
try:
|
||||
self.sock.send(cmd)
|
||||
except:
|
||||
print("Sending failed.")
|
||||
GObject.source_remove(self.watch_id)
|
||||
self.connected = False
|
||||
GObject.timeout_add(5000, self.connectToSocketServer)
|
||||
|
||||
def find_item_for_file(self, path):
|
||||
if path in self.nautilusVFSFile_table:
|
||||
return self.nautilusVFSFile_table[path]
|
||||
else:
|
||||
return None
|
||||
|
||||
def askForOverlay(self, file):
|
||||
# print("Asking for overlay for "+file)
|
||||
if os.path.isdir(file):
|
||||
folderStatus = self.sendCommand("RETRIEVE_FOLDER_STATUS:"+file+"\n");
|
||||
|
||||
if os.path.isfile(file):
|
||||
fileStatus = self.sendCommand("RETRIEVE_FILE_STATUS:"+file+"\n");
|
||||
|
||||
def invalidate_items_underneath(self, path):
|
||||
update_items = []
|
||||
if not self.nautilusVFSFile_table:
|
||||
self.askForOverlay(path)
|
||||
else:
|
||||
for p in self.nautilusVFSFile_table:
|
||||
if p == path or p.startswith(path):
|
||||
item = self.nautilusVFSFile_table[p]['item']
|
||||
update_items.append(item)
|
||||
|
||||
for item in update_items:
|
||||
item.invalidate_extension_info()
|
||||
|
||||
# Handles a single line of server respoonse and sets the emblem
|
||||
def handle_server_response(self, l):
|
||||
Emblems = { 'OK' : self.appname +'_ok',
|
||||
'SYNC' : self.appname +'_sync',
|
||||
'NEW' : self.appname +'_sync',
|
||||
'IGNORE' : self.appname +'_warn',
|
||||
'ERROR' : self.appname +'_error',
|
||||
'OK+SWM' : self.appname +'_ok_shared',
|
||||
'SYNC+SWM' : self.appname +'_sync_shared',
|
||||
'NEW+SWM' : self.appname +'_sync_shared',
|
||||
'IGNORE+SWM': self.appname +'_warn_shared',
|
||||
'ERROR+SWM' : self.appname +'_error_shared',
|
||||
'NOP' : self.appname +'_error'
|
||||
}
|
||||
|
||||
print("Server response: "+l)
|
||||
parts = l.split(':')
|
||||
if len(parts) > 0:
|
||||
action = parts[0]
|
||||
|
||||
# file = parts[1]
|
||||
# print "Action for " + file + ": "+parts[0]
|
||||
if action == 'STATUS':
|
||||
newState = parts[1]
|
||||
emblem = Emblems[newState]
|
||||
if emblem:
|
||||
itemStore = self.find_item_for_file(parts[2])
|
||||
if itemStore:
|
||||
if( not itemStore['state'] or newState != itemStore['state'] ):
|
||||
item = itemStore['item']
|
||||
item.add_emblem(emblem)
|
||||
# print "Setting emblem on " + parts[2]
|
||||
self.nautilusVFSFile_table[parts[2]] = {'item': item, 'state':newState}
|
||||
|
||||
elif action == 'UPDATE_VIEW':
|
||||
# Search all items underneath this path and invalidate them
|
||||
if parts[1] in self.registered_paths:
|
||||
self.invalidate_items_underneath(parts[1])
|
||||
|
||||
elif action == 'REGISTER_PATH':
|
||||
self.registered_paths[parts[1]] = 1
|
||||
self.invalidate_items_underneath(parts[1])
|
||||
elif action == 'UNREGISTER_PATH':
|
||||
del self.registered_paths[parts[1]]
|
||||
self.invalidate_items_underneath(parts[1])
|
||||
|
||||
# check if there are non pathes any more, if so, its usual
|
||||
# that mirall went away. Try reconnect.
|
||||
if not self.registered_paths:
|
||||
self.sock.close()
|
||||
self.connected = False
|
||||
GObject.source_remove(self.watch_id)
|
||||
GObject.timeout_add(5000, self.connectToSocketServer)
|
||||
|
||||
else:
|
||||
# print "We got unknown action " + action
|
||||
1
|
||||
|
||||
# notify is the raw answer from the socket
|
||||
def handle_notify(self, source, condition):
|
||||
|
||||
data = source.recv(1024)
|
||||
# prepend the remaining data from last call
|
||||
if len(self.remainder) > 0:
|
||||
data = self.remainder+data
|
||||
self.remainder = ''
|
||||
|
||||
if len(data) > 0:
|
||||
# remember the remainder for next round
|
||||
lastNL = data.rfind('\n');
|
||||
if lastNL > -1 and lastNL < len(data):
|
||||
self.remainder = data[lastNL+1:]
|
||||
data = data[:lastNL]
|
||||
|
||||
for l in data.split('\n'):
|
||||
self.handle_server_response(l)
|
||||
else:
|
||||
return False
|
||||
|
||||
return True # run again
|
||||
|
||||
def get_local_path(self, path):
|
||||
return path.replace("file://", "")
|
||||
|
||||
def update_file_info(self, item):
|
||||
if item.get_uri_scheme() != 'file':
|
||||
return
|
||||
|
||||
filename = urllib.unquote(item.get_uri()[7:])
|
||||
if item.is_directory():
|
||||
filename += '/'
|
||||
|
||||
for reg_path in self.registered_paths:
|
||||
if filename.startswith(reg_path):
|
||||
self.nautilusVFSFile_table[filename] = {'item': item, 'state':''}
|
||||
|
||||
# item.add_string_attribute('share_state', "share state")
|
||||
self.askForOverlay(filename)
|
||||
break
|
||||
else:
|
||||
print("Not in scope:"+filename)
|
||||
externo
+1
-1
Submodule src/3rdparty/qtmacgoodies updated: fa06775714...cf09d34dc7
+15
-439
@@ -1,449 +1,25 @@
|
||||
set(CMAKE_AUTOMOC TRUE)
|
||||
include(GenerateExportHeader)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
qt_add_resources(MIRALL_RC_SRC ../mirall.qrc)
|
||||
if ( IS_DIRECTORY ${OEM_THEME_DIR} )
|
||||
qt_add_resources(MIRALL_RC_SRC ${OEM_THEME_DIR}/theme.qrc)
|
||||
set(theme_dir ${OEM_THEME_DIR}/theme)
|
||||
else()
|
||||
qt_add_resources(MIRALL_RC_SRC ../theme.qrc)
|
||||
set(theme_dir ${CMAKE_CURRENT_SOURCE_DIR}/../theme)
|
||||
endif()
|
||||
# TODO: OSX and LIB_ONLY seem to require this to go to binary dir only
|
||||
set(BIN_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
|
||||
|
||||
set(synclib_NAME ${APPLICATION_EXECUTABLE}sync)
|
||||
|
||||
if ( APPLE )
|
||||
list(APPEND OS_SPECIFIC_LINK_LIBRARIES
|
||||
/System/Library/Frameworks/CoreServices.framework
|
||||
/System/Library/Frameworks/Foundation.framework
|
||||
/System/Library/Frameworks/AppKit.framework
|
||||
)
|
||||
endif()
|
||||
|
||||
IF(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
||||
list(APPEND OS_SPECIFIC_LINK_LIBRARIES
|
||||
inotify
|
||||
)
|
||||
ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
||||
|
||||
if(SPARKLE_FOUND AND NOT BUILD_LIBRARIES_ONLY)
|
||||
list (APPEND OS_SPECIFIC_LINK_LIBRARIES ${SPARKLE_LIBRARY})
|
||||
endif()
|
||||
|
||||
set(3rdparty_SRC
|
||||
3rdparty/qtsingleapplication/qtsingleapplication.cpp
|
||||
3rdparty/qtsingleapplication/qtlocalpeer.cpp
|
||||
3rdparty/qtsingleapplication/qtsinglecoreapplication.cpp
|
||||
3rdparty/qtlockedfile/qtlockedfile.cpp
|
||||
3rdparty/fancylineedit/fancylineedit.cpp
|
||||
3rdparty/QProgressIndicator/QProgressIndicator.cpp
|
||||
)
|
||||
|
||||
if (APPLE)
|
||||
list(APPEND 3rdparty_SRC
|
||||
3rdparty/qtmacgoodies/src/macpreferenceswindow.mm
|
||||
3rdparty/qtmacgoodies/src/macstandardicon.mm
|
||||
3rdparty/qtmacgoodies/src/macwindow.mm
|
||||
)
|
||||
endif()
|
||||
|
||||
if(NOT WIN32)
|
||||
list(APPEND 3rdparty_SRC 3rdparty/qtlockedfile/qtlockedfile_unix.cpp)
|
||||
else()
|
||||
list(APPEND 3rdparty_SRC 3rdparty/qtlockedfile/qtlockedfile_win.cpp )
|
||||
endif()
|
||||
|
||||
set(3rdparty_INC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/qtlockedfile
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/qtsingleapplication
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/QProgressIndicator
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/fancylineedit
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/qjson
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/qtmacgoodies/src
|
||||
)
|
||||
|
||||
set(libsync_SRCS
|
||||
mirall/authenticationdialog.cpp
|
||||
mirall/syncresult.cpp
|
||||
mirall/mirallconfigfile.cpp
|
||||
mirall/syncengine.cpp
|
||||
mirall/owncloudpropagator.cpp
|
||||
mirall/propagatorjobs.cpp
|
||||
mirall/propagator_qnam.cpp
|
||||
mirall/propagator_legacy.cpp
|
||||
mirall/syncjournalfilerecord.cpp
|
||||
mirall/syncjournaldb.cpp
|
||||
mirall/theme.cpp
|
||||
mirall/owncloudtheme.cpp
|
||||
mirall/logger.cpp
|
||||
mirall/utility.cpp
|
||||
mirall/filesystem.cpp
|
||||
mirall/connectionvalidator.cpp
|
||||
mirall/progressdispatcher.cpp
|
||||
mirall/mirallaccessmanager.cpp
|
||||
mirall/networkjobs.cpp
|
||||
mirall/account.cpp
|
||||
mirall/quotainfo.cpp
|
||||
mirall/clientproxy.cpp
|
||||
mirall/cookiejar.cpp
|
||||
mirall/syncfilestatus.cpp
|
||||
mirall/discoveryphase.cpp
|
||||
creds/dummycredentials.cpp
|
||||
creds/abstractcredentials.cpp
|
||||
creds/credentialsfactory.cpp
|
||||
creds/http/httpconfigfile.cpp
|
||||
creds/credentialscommon.cpp
|
||||
3rdparty/qjson/json.cpp
|
||||
)
|
||||
if(TOKEN_AUTH_ONLY)
|
||||
set (libsync_SRCS
|
||||
${libsync_SRCS}
|
||||
creds/tokencredentials.cpp
|
||||
)
|
||||
else()
|
||||
set (libsync_SRCS
|
||||
${libsync_SRCS}
|
||||
creds/httpcredentials.cpp
|
||||
creds/shibbolethcredentials.cpp
|
||||
creds/shibboleth/shibbolethwebview.cpp
|
||||
creds/shibboleth/shibbolethrefresher.cpp
|
||||
creds/shibboleth/shibbolethuserjob.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
# These headers are installed for libowncloudsync to be used by 3rd party apps
|
||||
set(owncloudsync_HEADERS
|
||||
mirall/account.h
|
||||
mirall/syncengine.h
|
||||
mirall/mirallconfigfile.h
|
||||
mirall/networkjobs.h
|
||||
mirall/progressdispatcher.h
|
||||
mirall/syncfileitem.h
|
||||
mirall/syncjournaldb.h
|
||||
mirall/syncresult.h
|
||||
)
|
||||
|
||||
set(creds_HEADERS
|
||||
creds/abstractcredentials.h
|
||||
creds/httpcredentials.h
|
||||
)
|
||||
|
||||
IF (NOT APPLE)
|
||||
INSTALL(
|
||||
FILES ${owncloudsync_HEADERS}
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/${synclib_NAME}/mirall
|
||||
)
|
||||
INSTALL(
|
||||
FILES ${creds_HEADERS}
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/${synclib_NAME}/creds
|
||||
)
|
||||
ENDIF(NOT APPLE)
|
||||
|
||||
list(APPEND libsync_LINK_TARGETS
|
||||
${QT_LIBRARIES}
|
||||
ocsync
|
||||
httpbf
|
||||
${OS_SPECIFIC_LINK_LIBRARIES}
|
||||
)
|
||||
|
||||
if(QTKEYCHAIN_FOUND OR QT5KEYCHAIN_FOUND)
|
||||
list(APPEND libsync_LINK_TARGETS ${QTKEYCHAIN_LIBRARY})
|
||||
include_directories(${QTKEYCHAIN_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
if(NEON_FOUND)
|
||||
list(APPEND libsync_LINK_TARGETS ${NEON_LIBRARIES})
|
||||
include_directories(${NEON_INCLUDE_DIRS})
|
||||
|
||||
if(NEON_WITH_LFS)
|
||||
add_definitions(-DNE_LFS)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
add_library(${synclib_NAME} SHARED ${libsync_SRCS} ${syncMoc})
|
||||
GENERATE_EXPORT_HEADER( ${synclib_NAME}
|
||||
BASE_NAME ${synclib_NAME}
|
||||
EXPORT_MACRO_NAME OWNCLOUDSYNC_EXPORT
|
||||
EXPORT_FILE_NAME owncloudlib.h
|
||||
STATIC_DEFINE OWNCLOUD_BUILT_AS_STATIC
|
||||
)
|
||||
|
||||
|
||||
if(TOKEN_AUTH_ONLY)
|
||||
qt5_use_modules(${synclib_NAME} Network Xml Sql)
|
||||
else()
|
||||
qt5_use_modules(${synclib_NAME} Widgets Network Xml WebKitWidgets Sql)
|
||||
endif()
|
||||
|
||||
set_target_properties( ${synclib_NAME} PROPERTIES
|
||||
VERSION ${MIRALL_VERSION}
|
||||
SOVERSION ${MIRALL_SOVERSION}
|
||||
)
|
||||
set_target_properties( ${synclib_NAME} PROPERTIES
|
||||
INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}/${APPLICATION_EXECUTABLE}" )
|
||||
|
||||
target_link_libraries(${synclib_NAME} ${libsync_LINK_TARGETS} )
|
||||
|
||||
if(BUILD_LIBRARIES_ONLY)
|
||||
#add_library(${synclib_NAME}_static STATIC ${libsync_SRCS} ${syncMoc})
|
||||
#qt5_use_modules(${synclib_NAME}_static Widgets Network Xml Sql)
|
||||
|
||||
#set_target_properties( ${synclib_NAME}_static PROPERTIES
|
||||
# VERSION ${MIRALL_VERSION}
|
||||
# SOVERSION ${MIRALL_SOVERSION}
|
||||
#)
|
||||
|
||||
#target_link_libraries(${synclib_NAME}_static ${libsync_LINK_TARGETS} )
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
if(NOT BUILD_OWNCLOUD_OSX_BUNDLE)
|
||||
install(TARGETS ${synclib_NAME}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
)
|
||||
if(NOT WIN32)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/mirall.desktop.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${APPLICATION_EXECUTABLE}.desktop)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${APPLICATION_EXECUTABLE}.desktop DESTINATION share/applications )
|
||||
endif()
|
||||
else()
|
||||
install(TARGETS ${synclib_NAME} DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/MacOS)
|
||||
if (SPARKLE_FOUND)
|
||||
install(DIRECTORY "${SPARKLE_LIBRARY}"
|
||||
DESTINATION "${OWNCLOUD_OSX_BUNDLE}/Contents/Frameworks" USE_SOURCE_PERMISSIONS)
|
||||
endif (SPARKLE_FOUND)
|
||||
|
||||
endif()
|
||||
|
||||
set(mirall_UI
|
||||
mirall/folderwizardsourcepage.ui
|
||||
mirall/folderwizardtargetpage.ui
|
||||
mirall/sslerrordialog.ui
|
||||
mirall/settingsdialog.ui
|
||||
mirall/generalsettings.ui
|
||||
mirall/networksettings.ui
|
||||
mirall/accountsettings.ui
|
||||
mirall/ignorelisteditor.ui
|
||||
mirall/protocolwidget.ui
|
||||
wizard/owncloudsetupnocredspage.ui
|
||||
wizard/owncloudhttpcredspage.ui
|
||||
wizard/owncloudwizardresultpage.ui
|
||||
wizard/owncloudadvancedsetuppage.ui
|
||||
)
|
||||
|
||||
qt_wrap_ui(mirall_UI_SRCS ${mirall_UI})
|
||||
|
||||
set(mirall_SRCS
|
||||
mirall/application.cpp
|
||||
mirall/systray.cpp
|
||||
mirall/folderman.cpp
|
||||
mirall/folder.cpp
|
||||
mirall/folderwatcher.cpp
|
||||
mirall/folderwizard.cpp
|
||||
mirall/folderstatusmodel.cpp
|
||||
mirall/protocolwidget.cpp
|
||||
mirall/openfilemanager.cpp
|
||||
wizard/owncloudwizard.cpp
|
||||
wizard/owncloudsetuppage.cpp
|
||||
wizard/owncloudhttpcredspage.cpp
|
||||
wizard/abstractcredswizardpage.cpp
|
||||
wizard/owncloudwizardresultpage.cpp
|
||||
wizard/owncloudwizardcommon.cpp
|
||||
wizard/owncloudshibbolethcredspage.cpp
|
||||
wizard/owncloudadvancedsetuppage.cpp
|
||||
mirall/owncloudsetupwizard.cpp
|
||||
mirall/sslerrordialog.cpp
|
||||
mirall/logbrowser.cpp
|
||||
mirall/settingsdialog.cpp
|
||||
mirall/generalsettings.cpp
|
||||
mirall/networksettings.cpp
|
||||
mirall/accountsettings.cpp
|
||||
mirall/ignorelisteditor.cpp
|
||||
mirall/owncloudgui.cpp
|
||||
mirall/socketapi.cpp
|
||||
mirall/sslbutton.cpp
|
||||
mirall/syncrunfilelog.cpp
|
||||
mirall/selectivesyncdialog.cpp
|
||||
mirall/accountmigrator.cpp
|
||||
)
|
||||
|
||||
|
||||
set(updater_SRCS
|
||||
updater/updateinfo.cpp
|
||||
updater/updater.cpp
|
||||
updater/ocupdater.cpp
|
||||
)
|
||||
|
||||
IF( APPLE )
|
||||
list(APPEND mirall_SRCS mirall/cocoainitializer_mac.mm)
|
||||
|
||||
list(APPEND mirall_SRCS mirall/settingsdialogmac.cpp)
|
||||
|
||||
if(SPARKLE_FOUND)
|
||||
# Define this, we need to check in updater.cpp
|
||||
add_definitions( -DHAVE_SPARKLE )
|
||||
list(APPEND updater_SRCS updater/sparkleupdater_mac.mm)
|
||||
endif()
|
||||
ENDIF()
|
||||
|
||||
IF( NOT WIN32 AND NOT APPLE )
|
||||
set(mirall_SRCS ${mirall_SRCS} mirall/folderwatcher_linux.cpp)
|
||||
ENDIF()
|
||||
IF( WIN32 )
|
||||
set(mirall_SRCS ${mirall_SRCS} mirall/folderwatcher_win.cpp)
|
||||
ENDIF()
|
||||
IF( APPLE )
|
||||
list(APPEND mirall_SRCS mirall/folderwatcher_mac.cpp)
|
||||
ENDIF()
|
||||
|
||||
# csync is required.
|
||||
include_directories(../csync/src ../csync/src/httpbf/src ${CMAKE_CURRENT_BINARY_DIR}/../csync ${CMAKE_CURRENT_BINARY_DIR}/../csync/src )
|
||||
include_directories(${3rdparty_INC})
|
||||
|
||||
qt_add_translation(mirall_I18N ${TRANSLATIONS})
|
||||
|
||||
set( final_src
|
||||
${MIRALL_RC_SRC}
|
||||
${mirall_SRCS}
|
||||
${mirall_UI_SRCS}
|
||||
${mirallMoc}
|
||||
${mirall_I18N}
|
||||
${3rdparty_SRC}
|
||||
${3rdparty_MOC}
|
||||
)
|
||||
|
||||
# add executable icon on windows and osx
|
||||
include( AddAppIconMacro )
|
||||
set(ownCloud_old ${ownCloud})
|
||||
|
||||
# set an icon_app_name. For historical reasons we can not use the
|
||||
# application_shortname for ownCloud but must rather set it manually.
|
||||
if ( EXISTS ${OEM_THEME_DIR}/OEM.cmake )
|
||||
set(ICON_APP_NAME ${APPLICATION_SHORTNAME})
|
||||
else()
|
||||
set(ICON_APP_NAME "owncloud")
|
||||
endif()
|
||||
|
||||
kde4_add_app_icon( ownCloud "${theme_dir}/colored/${ICON_APP_NAME}-icon*.png")
|
||||
list(APPEND final_src ${ownCloud})
|
||||
set(ownCloud ${ownCloud_old})
|
||||
|
||||
if (WITH_DBUS)
|
||||
set(ADDITIONAL_APP_MODULES DBus)
|
||||
endif(WITH_DBUS)
|
||||
|
||||
if(NOT BUILD_OWNCLOUD_OSX_BUNDLE AND NOT BUILD_LIBRARIES_ONLY)
|
||||
set(BIN_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
|
||||
|
||||
if(NOT WIN32)
|
||||
file( GLOB _icons "${theme_dir}/colored/${ICON_APP_NAME}-icon-*.png" )
|
||||
foreach( _file ${_icons} )
|
||||
string( REPLACE "${theme_dir}/colored/${ICON_APP_NAME}-icon-" "" _res ${_file} )
|
||||
string( REPLACE ".png" "" _res ${_res} )
|
||||
install( FILES ${_file} RENAME ${ICON_APP_NAME}.png DESTINATION ${DATADIR}/icons/hicolor/${_res}x${_res}/apps )
|
||||
endforeach( _file )
|
||||
endif(NOT WIN32)
|
||||
|
||||
install(FILES ${mirall_I18N} DESTINATION share/${APPLICATION_EXECUTABLE}/i18n)
|
||||
|
||||
# we may not add MACOSX_BUNDLE here, if not building one
|
||||
|
||||
# add_executable( ${APPLICATION_EXECUTABLE} main.cpp ${final_src})
|
||||
add_executable( ${APPLICATION_EXECUTABLE} WIN32 main.cpp ${final_src})
|
||||
qt5_use_modules(${APPLICATION_EXECUTABLE} Widgets Network Xml WebKitWidgets Sql ${ADDITIONAL_APP_MODULES})
|
||||
elseif(NOT BUILD_LIBRARIES_ONLY)
|
||||
set(BIN_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
|
||||
# set(CMAKE_INSTALL_PREFIX ".") # Examples use /Applications. hurmpf.
|
||||
set(MACOSX_BUNDLE_ICON_FILE "ownCloud.icns")
|
||||
|
||||
# we must add MACOSX_BUNDLE only if building a bundle
|
||||
add_executable( ${APPLICATION_EXECUTABLE} WIN32 MACOSX_BUNDLE main.cpp ${final_src})
|
||||
qt5_use_modules(${APPLICATION_EXECUTABLE} Widgets Network Xml WebKitWidgets Sql ${ADDITIONAL_APP_MODULES})
|
||||
|
||||
set (QM_DIR ${OWNCLOUD_OSX_BUNDLE}/Contents/Resources/Translations)
|
||||
install(FILES ${mirall_I18N} DESTINATION ${QM_DIR})
|
||||
file(GLOB qt_I18N ${QT_TRANSLATIONS_DIR}/qt_??.qm ${QT_TRANSLATIONS_DIR}/qt_??_??.qm)
|
||||
install(FILES ${qt_I18N} DESTINATION ${QM_DIR})
|
||||
file(GLOB qtkeychain_I18N ${QT_TRANSLATIONS_DIR}/qtkeychain*.qm)
|
||||
install(FILES ${qtkeychain_I18N} DESTINATION ${QM_DIR})
|
||||
endif()
|
||||
|
||||
if(NOT BUILD_LIBRARIES_ONLY)
|
||||
add_library(updater STATIC ${updater_SRCS} ${updaterMoc})
|
||||
target_link_libraries(updater ${synclib_NAME})
|
||||
qt5_use_modules(updater Widgets Network Xml)
|
||||
|
||||
set_target_properties( ${APPLICATION_EXECUTABLE} PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY}
|
||||
)
|
||||
set_target_properties( ${APPLICATION_EXECUTABLE} PROPERTIES
|
||||
INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}/${APPLICATION_EXECUTABLE}" )
|
||||
|
||||
target_link_libraries( ${APPLICATION_EXECUTABLE} ${QT_LIBRARIES} )
|
||||
target_link_libraries( ${APPLICATION_EXECUTABLE} ${synclib_NAME} )
|
||||
target_link_libraries( ${APPLICATION_EXECUTABLE} updater )
|
||||
target_link_libraries( ${APPLICATION_EXECUTABLE} ${OS_SPECIFIC_LINK_LIBRARIES} )
|
||||
|
||||
install(TARGETS ${APPLICATION_EXECUTABLE}
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib
|
||||
BUNDLE DESTINATION "."
|
||||
)
|
||||
endif()
|
||||
add_subdirectory(libsync)
|
||||
if (NOT BUILD_LIBRARIES_ONLY)
|
||||
add_subdirectory(gui)
|
||||
add_subdirectory(cmd)
|
||||
endif(NOT BUILD_LIBRARIES_ONLY)
|
||||
|
||||
find_program(KRAZY2_EXECUTABLE krazy2)
|
||||
if(KRAZY2_EXECUTABLE)
|
||||
# s/y k/y ALL k/ for building this target always
|
||||
add_custom_target( krazy krazy2 --check-sets c++,qt4,foss
|
||||
${PROJECT_SOURCE_DIR}/src/mirall/*.ui
|
||||
${PROJECT_SOURCE_DIR}/src/mirall/*.h
|
||||
${PROJECT_SOURCE_DIR}/src/mirall/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/libsync/*.ui
|
||||
${PROJECT_SOURCE_DIR}/src/libsync/*.h
|
||||
${PROJECT_SOURCE_DIR}/src/libsync/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/gui/*.ui
|
||||
${PROJECT_SOURCE_DIR}/src/gui/*.h
|
||||
${PROJECT_SOURCE_DIR}/src/gui/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/cmd/*.h
|
||||
${PROJECT_SOURCE_DIR}/src/cmd/*.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
set(owncloudcmd_NAME ${APPLICATION_EXECUTABLE}cmd)
|
||||
set(OWNCLOUDCMD_SRC owncloudcmd/simplesslerrorhandler.cpp owncloudcmd/owncloudcmd.cpp owncloudcmd/netrcparser.cpp)
|
||||
if(NOT BUILD_LIBRARIES_ONLY)
|
||||
|
||||
add_executable(${owncloudcmd_NAME} ${OWNCLOUDCMD_SRC})
|
||||
qt5_use_modules(${owncloudcmd_NAME} Network Sql)
|
||||
set_target_properties(${owncloudcmd_NAME} PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY} )
|
||||
set_target_properties(${owncloudcmd_NAME} PROPERTIES
|
||||
INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}/${APPLICATION_EXECUTABLE}" )
|
||||
|
||||
target_link_libraries(${owncloudcmd_NAME} ${synclib_NAME})
|
||||
endif()
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/mirall)
|
||||
if(BUILD_OWNCLOUD_OSX_BUNDLE AND NOT BUILD_LIBRARIES_ONLY)
|
||||
install(TARGETS ${owncloudcmd_NAME} DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/MacOS)
|
||||
if (SPARKLE_FOUND)
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/admin/osx/deny_autoupdate_com.owncloud.desktopclient.plist
|
||||
DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/Resources)
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/admin/osx/sparkle/dsa_pub.pem
|
||||
DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/Resources)
|
||||
endif()
|
||||
elseif(NOT BUILD_LIBRARIES_ONLY)
|
||||
install(TARGETS ${owncloudcmd_NAME}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
endif()
|
||||
|
||||
#FIXME: find a nice solution to make the second if(BUILD_OWNCLOUD_OSX_BUNDLE) unnecessary
|
||||
# currently it needs to be done because the code right above needs to be executed no matter
|
||||
# if building a bundle or not and the install_qt4_executable needs to be called afterwards
|
||||
if(BUILD_OWNCLOUD_OSX_BUNDLE AND NOT BUILD_LIBRARIES_ONLY)
|
||||
install(CODE "
|
||||
message(STATUS \"Deploying (Qt) dependencies and fixing library pathes...\")
|
||||
execute_process(COMMAND \"${CMAKE_SOURCE_DIR}/admin/osx/macdeployqt.py\" ${CMAKE_INSTALL_PREFIX}/${OWNCLOUD_OSX_BUNDLE})
|
||||
" COMPONENT RUNTIME)
|
||||
endif()
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
project(cmd)
|
||||
set(CMAKE_AUTOMOC TRUE)
|
||||
|
||||
set(cmd_NAME ${APPLICATION_EXECUTABLE}cmd)
|
||||
set(cmd_SRC
|
||||
cmd.cpp
|
||||
simplesslerrorhandler.cpp
|
||||
)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/src/libsync
|
||||
${CMAKE_BINARY_DIR}/src/libsync
|
||||
)
|
||||
|
||||
# csync is required.
|
||||
include_directories(${CMAKE_SOURCE_DIR}/csync/src
|
||||
${CMAKE_SOURCE_DIR}/csync/src/httpbf/src
|
||||
${CMAKE_BINARY_DIR}/csync
|
||||
${CMAKE_BINARY_DIR}/csync/src
|
||||
)
|
||||
include_directories(${NEON_INCLUDE_DIRS})
|
||||
|
||||
if(NOT BUILD_LIBRARIES_ONLY)
|
||||
add_executable(${cmd_NAME} ${cmd_SRC})
|
||||
qt5_use_modules(${cmd_NAME} Network Sql)
|
||||
set_target_properties(${cmd_NAME} PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY} )
|
||||
set_target_properties(${cmd_NAME} PROPERTIES
|
||||
INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}/${APPLICATION_EXECUTABLE}" )
|
||||
|
||||
target_link_libraries(${cmd_NAME} ${synclib_NAME})
|
||||
endif()
|
||||
|
||||
if(BUILD_OWNCLOUD_OSX_BUNDLE)
|
||||
install(TARGETS ${cmd_NAME} DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/MacOS)
|
||||
elseif(NOT BUILD_LIBRARIES_ONLY)
|
||||
install(TARGETS ${cmd_NAME}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
endif()
|
||||
|
||||
@@ -22,22 +22,16 @@
|
||||
|
||||
#include <neon/ne_socket.h>
|
||||
|
||||
#include "mirall/syncengine.h"
|
||||
#include "mirall/syncjournaldb.h"
|
||||
#include "csync.h"
|
||||
#include "mirall/clientproxy.h"
|
||||
#include "mirall/account.h"
|
||||
#include "account.h"
|
||||
#include "clientproxy.h"
|
||||
#include "creds/httpcredentials.h"
|
||||
#include "owncloudcmd.h"
|
||||
#include "csync.h"
|
||||
#include "simplesslerrorhandler.h"
|
||||
#include "syncengine.h"
|
||||
#include "syncjournaldb.h"
|
||||
#include "config.h"
|
||||
|
||||
#include "netrcparser.h"
|
||||
|
||||
#ifdef Q_OS_WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <termios.h>
|
||||
#endif
|
||||
#include "cmd.h"
|
||||
|
||||
using namespace Mirall;
|
||||
|
||||
@@ -45,93 +39,46 @@ struct CmdOptions {
|
||||
QString source_dir;
|
||||
QString target_url;
|
||||
QString config_directory;
|
||||
QString user;
|
||||
QString password;
|
||||
QString proxy;
|
||||
bool silent;
|
||||
bool trustSSL;
|
||||
bool useNetrc;
|
||||
bool interactive;
|
||||
QString exclude;
|
||||
};
|
||||
|
||||
// we can't use csync_set_userdata because the SyncEngine sets it already.
|
||||
// So we have to use a global variable
|
||||
CmdOptions *opts = 0;
|
||||
|
||||
class EchoDisabler
|
||||
int getauth(const char* prompt, char* buf, size_t len, int a, int b, void *userdata)
|
||||
{
|
||||
public:
|
||||
EchoDisabler()
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
hStdin = GetStdHandle(STD_INPUT_HANDLE);
|
||||
GetConsoleMode(hStdin, &mode);
|
||||
SetConsoleMode(hStdin, mode & (~ENABLE_ECHO_INPUT));
|
||||
#else
|
||||
tcgetattr(STDIN_FILENO, &tios);
|
||||
termios tios_new = tios;
|
||||
tios_new.c_lflag &= ~ECHO;
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &tios_new);
|
||||
#endif
|
||||
}
|
||||
Q_UNUSED(a) Q_UNUSED(b) Q_UNUSED(userdata)
|
||||
|
||||
~EchoDisabler()
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
SetConsoleMode(hStdin, mode);
|
||||
#else
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &tios);
|
||||
#endif
|
||||
}
|
||||
private:
|
||||
#ifdef Q_OS_WIN
|
||||
DWORD mode = 0;
|
||||
HANDLE hStdin;
|
||||
#else
|
||||
termios tios;
|
||||
#endif
|
||||
};
|
||||
|
||||
QString queryPassword(const QString &user)
|
||||
{
|
||||
EchoDisabler disabler;
|
||||
std::cout << "Password for user " << qPrintable(user) << ": ";
|
||||
std::cout << "** Authentication required: \n" << prompt << std::endl;
|
||||
std::string s;
|
||||
std::getline(std::cin, s);
|
||||
return QString::fromStdString(s);
|
||||
}
|
||||
|
||||
class HttpCredentialsText : public HttpCredentials {
|
||||
public:
|
||||
HttpCredentialsText(const QString& user, const QString& password) : HttpCredentials(user, password) {}
|
||||
QString queryPassword(bool *ok) {
|
||||
if (ok) {
|
||||
*ok = true;
|
||||
}
|
||||
return ::queryPassword(user());
|
||||
if(opts && opts->trustSSL) {
|
||||
s = "yes";
|
||||
} else {
|
||||
std::getline(std::cin, s);
|
||||
}
|
||||
};
|
||||
strncpy( buf, s.c_str(), len );
|
||||
return 0;
|
||||
}
|
||||
|
||||
void help()
|
||||
{
|
||||
std::cout << "owncloudcmd - command line ownCloud client tool." << std::endl;
|
||||
const char* appName = APPLICATION_EXECUTABLE "cmd";
|
||||
std::cout << appName << " - command line " APPLICATION_NAME " client tool." << std::endl;
|
||||
std::cout << "" << std::endl;
|
||||
std::cout << "Usage: owncloudcmd <sourcedir> <owncloudurl>" << std::endl;
|
||||
std::cout << "Usage: " << appName << " <source_dir> <server_url>" << std::endl;
|
||||
std::cout << "" << std::endl;
|
||||
std::cout << "A proxy can either be set manually using --httpproxy or it" << std::endl;
|
||||
std::cout << "uses the setting from a configured sync client." << std::endl;
|
||||
std::cout << "A proxy can either be set manually using --httpproxy." << std::endl;
|
||||
std::cout << "Otherwise, the setting from a configured sync client will be used." << std::endl;
|
||||
std::cout << std::endl;
|
||||
std::cout << "Options:" << std::endl;
|
||||
std::cout << " --silent, -s Don't be so verbose" << std::endl;
|
||||
std::cout << " --httpproxy [proxy] Specify a http proxy to use." << std::endl;
|
||||
std::cout << " --silent Don't be so verbose" << std::endl;
|
||||
std::cout << " --confdir = configdir: Read config from there." << std::endl;
|
||||
std::cout << " --httpproxy = proxy: Specify a http proxy to use." << std::endl;
|
||||
std::cout << " Proxy is http://server:port" << std::endl;
|
||||
std::cout << " --trust Trust the SSL certification." << std::endl;
|
||||
std::cout << " --exclude [file] exclude list file" << std::endl;
|
||||
std::cout << " --user, -u [name] Use [name] as the login name" << std::endl;
|
||||
std::cout << " --password, -p [pass] Use [pass] as password" << std::endl;
|
||||
std::cout << " -n Use netrc (5) for login" << std::endl;
|
||||
std::cout << " --non-interactive Do not block execution with interaction" << std::endl;
|
||||
std::cout << "" << std::endl;
|
||||
exit(1);
|
||||
|
||||
@@ -151,7 +98,7 @@ void parseOptions( const QStringList& app_args, CmdOptions *options )
|
||||
if(!options->target_url.endsWith("/")) {
|
||||
options->target_url.append("/");
|
||||
}
|
||||
options->target_url.append("remote.php/webdav");
|
||||
options->target_url.append("remote.php/webdav/");
|
||||
}
|
||||
if (options->target_url.startsWith("http"))
|
||||
options->target_url.replace(0, 4, "owncloud");
|
||||
@@ -168,22 +115,14 @@ void parseOptions( const QStringList& app_args, CmdOptions *options )
|
||||
while(it.hasNext()) {
|
||||
const QString option = it.next();
|
||||
|
||||
if( option == "--httpproxy" && !it.peekNext().startsWith("-")) {
|
||||
if( option == "--confdir" && !it.peekNext().startsWith("-") ) {
|
||||
options->config_directory = it.next();
|
||||
} else if( option == "--httpproxy" && !it.peekNext().startsWith("-")) {
|
||||
options->proxy = it.next();
|
||||
} else if( option == "-s" || option == "--silent") {
|
||||
} else if( option == "--silent") {
|
||||
options->silent = true;
|
||||
} else if( option == "--trust") {
|
||||
options->trustSSL = true;
|
||||
} else if( option == "-n") {
|
||||
options->useNetrc = true;
|
||||
} else if( option == "--non-interactive") {
|
||||
options->interactive = false;
|
||||
} else if( (option == "-u" || option == "--user") && !it.peekNext().startsWith("-") ) {
|
||||
options->user = it.next();
|
||||
} else if( (option == "-p" || option == "--password") && !it.peekNext().startsWith("-") ) {
|
||||
options->user = it.next();
|
||||
} else if( option == "--exclude" && !it.peekNext().startsWith("-") ) {
|
||||
options->exclude = it.next();
|
||||
} else {
|
||||
help();
|
||||
}
|
||||
@@ -200,58 +139,12 @@ int main(int argc, char **argv) {
|
||||
CmdOptions options;
|
||||
options.silent = false;
|
||||
options.trustSSL = false;
|
||||
options.useNetrc = false;
|
||||
options.interactive = true;
|
||||
ClientProxy clientProxy;
|
||||
|
||||
parseOptions( app.arguments(), &options );
|
||||
|
||||
|
||||
QUrl url = QUrl::fromUserInput(options.target_url);
|
||||
|
||||
// Fetch username and password. If empty, try to retrieve
|
||||
// from URL and strip URL
|
||||
QString user;
|
||||
QString password;
|
||||
|
||||
if (options.useNetrc) {
|
||||
NetrcParser parser;
|
||||
if (parser.parse()) {
|
||||
NetrcParser::LoginPair pair = parser.find(url.host());
|
||||
user = pair.first;
|
||||
password = pair.second;
|
||||
}
|
||||
} else {
|
||||
user = options.user;
|
||||
if (user.isEmpty()) {
|
||||
user = url.userName();
|
||||
}
|
||||
password = options.password;
|
||||
if (password.isEmpty()) {
|
||||
password = url.password();
|
||||
}
|
||||
|
||||
if (options.interactive) {
|
||||
if (user.isEmpty()) {
|
||||
std::cout << "Please enter user name: ";
|
||||
std::string s;
|
||||
std::getline(std::cin, s);
|
||||
user = QString::fromStdString(s);
|
||||
}
|
||||
if (password.isEmpty()) {
|
||||
password = queryPassword(user);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ### ensure URL is free of credentials
|
||||
if (url.userName().isEmpty()) {
|
||||
url.setUserName(user);
|
||||
}
|
||||
if (url.password().isEmpty()) {
|
||||
url.setPassword(password);
|
||||
}
|
||||
|
||||
QUrl url(options.target_url.toUtf8());
|
||||
Account account;
|
||||
|
||||
// Find the folder and the original owncloud url
|
||||
@@ -262,19 +155,14 @@ int main(int argc, char **argv) {
|
||||
|
||||
SimpleSslErrorHandler *sslErrorHandler = new SimpleSslErrorHandler;
|
||||
|
||||
HttpCredentials *cred = new HttpCredentialsText(user, password);
|
||||
|
||||
account.setUrl(url);
|
||||
account.setCredentials(cred);
|
||||
account.setCredentials(new HttpCredentials(url.userName(), url.password()));
|
||||
account.setSslErrorHandler(sslErrorHandler);
|
||||
|
||||
AccountManager::instance()->setAccount(&account);
|
||||
|
||||
restart_sync:
|
||||
|
||||
CSYNC *_csync_ctx;
|
||||
if( csync_create( &_csync_ctx, options.source_dir.toUtf8(),
|
||||
url.toEncoded().constData()) < 0 ) {
|
||||
options.target_url.toUtf8()) < 0 ) {
|
||||
qFatal("Unable to create csync-context!");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
@@ -286,7 +174,7 @@ restart_sync:
|
||||
csync_set_log_level(options.silent ? 1 : 11);
|
||||
|
||||
opts = &options;
|
||||
cred->syncContextPreInit(_csync_ctx);
|
||||
csync_set_auth_callback( _csync_ctx, getauth );
|
||||
|
||||
if( csync_init( _csync_ctx ) < 0 ) {
|
||||
qFatal("Could not initialize csync!");
|
||||
@@ -329,17 +217,12 @@ restart_sync:
|
||||
clientProxy.setCSyncProxy(QUrl(url), _csync_ctx);
|
||||
}
|
||||
|
||||
if (!options.exclude.isEmpty()) {
|
||||
csync_add_exclude_list(_csync_ctx, options.exclude.toLocal8Bit());
|
||||
}
|
||||
Cmd cmd;
|
||||
|
||||
cred->syncContextPreStart(_csync_ctx);
|
||||
|
||||
OwncloudCmd owncloudCmd;
|
||||
SyncJournalDb db(options.source_dir);
|
||||
SyncEngine engine(_csync_ctx, options.source_dir, QUrl(options.target_url).path(), folder, &db);
|
||||
QObject::connect(&engine, SIGNAL(finished()), &app, SLOT(quit()));
|
||||
QObject::connect(&engine, SIGNAL(transmissionProgress(Progress::Info)), &owncloudCmd, SLOT(transmissionProgressSlot()));
|
||||
QObject::connect(&engine, SIGNAL(transmissionProgress(Progress::Info)), &cmd, SLOT(transmissionProgressSlot()));
|
||||
|
||||
// Have to be done async, else, an error before exec() does not terminate the event loop.
|
||||
QMetaObject::invokeMethod(&engine, "startSync", Qt::QueuedConnection);
|
||||
@@ -350,11 +233,6 @@ restart_sync:
|
||||
|
||||
ne_sock_exit();
|
||||
|
||||
if (engine.isAnotherSyncNeeded()) {
|
||||
qDebug() << "Restarting Sync, because another sync is needed";
|
||||
goto restart_sync;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -13,16 +13,16 @@
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef OWNCLOUDCMD_H
|
||||
#define OWNCLOUDCMD_H
|
||||
#ifndef CMD_H
|
||||
#define CMD_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
|
||||
class OwncloudCmd : public QObject {
|
||||
class Cmd : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
OwncloudCmd() : QObject() { }
|
||||
Cmd() : QObject() { }
|
||||
public slots:
|
||||
void transmissionProgressSlot() {
|
||||
}
|
||||
@@ -10,9 +10,9 @@
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
#include "mirall/mirallconfigfile.h"
|
||||
#include "mirall/utility.h"
|
||||
#include "mirall/account.h"
|
||||
#include "mirallconfigfile.h"
|
||||
#include "utility.h"
|
||||
#include "account.h"
|
||||
#include "simplesslerrorhandler.h"
|
||||
|
||||
bool SimpleSslErrorHandler::handleErrors(QList<QSslError> errors, QList<QSslCertificate> *certs, Mirall::Account *account)
|
||||
@@ -13,7 +13,7 @@
|
||||
#ifndef SIMPLESSLERRORHANDLER_H
|
||||
#define SIMPLESSLERRORHANDLER_H
|
||||
|
||||
#include "mirall/account.h"
|
||||
#include "account.h"
|
||||
|
||||
class QSslError;
|
||||
class QSslCertificate;
|
||||
@@ -0,0 +1,254 @@
|
||||
project(gui)
|
||||
set(CMAKE_AUTOMOC TRUE)
|
||||
|
||||
add_subdirectory(updater)
|
||||
|
||||
#TODO Move resources files
|
||||
qt_add_resources(MIRALL_RC_SRC ../../mirall.qrc)
|
||||
if ( IS_DIRECTORY ${OEM_THEME_DIR} )
|
||||
qt_add_resources(MIRALL_RC_SRC ${OEM_THEME_DIR}/theme.qrc)
|
||||
set(theme_dir ${OEM_THEME_DIR}/theme)
|
||||
else()
|
||||
qt_add_resources(MIRALL_RC_SRC ../../theme.qrc)
|
||||
set(theme_dir ${CMAKE_SOURCE_DIR}/theme)
|
||||
endif()
|
||||
|
||||
set(mirall_UI
|
||||
accountsettings.ui
|
||||
folderwizardsourcepage.ui
|
||||
folderwizardtargetpage.ui
|
||||
generalsettings.ui
|
||||
ignorelisteditor.ui
|
||||
networksettings.ui
|
||||
protocolwidget.ui
|
||||
settingsdialog.ui
|
||||
sslerrordialog.ui
|
||||
wizard/owncloudadvancedsetuppage.ui
|
||||
wizard/owncloudhttpcredspage.ui
|
||||
wizard/owncloudsetupnocredspage.ui
|
||||
wizard/owncloudwizardresultpage.ui
|
||||
)
|
||||
|
||||
qt_wrap_ui(mirall_UI_SRCS ${mirall_UI})
|
||||
|
||||
set(mirall_SRCS
|
||||
accountsettings.cpp
|
||||
application.cpp
|
||||
folder.cpp
|
||||
folderman.cpp
|
||||
folderstatusmodel.cpp
|
||||
folderwatcher.cpp
|
||||
folderwizard.cpp
|
||||
generalsettings.cpp
|
||||
ignorelisteditor.cpp
|
||||
logbrowser.cpp
|
||||
networksettings.cpp
|
||||
openfilemanager.cpp
|
||||
owncloudgui.cpp
|
||||
owncloudsetupwizard.cpp
|
||||
protocolwidget.cpp
|
||||
selectivesyncdialog.cpp
|
||||
settingsdialog.cpp
|
||||
socketapi.cpp
|
||||
sslbutton.cpp
|
||||
sslerrordialog.cpp
|
||||
syncrunfilelog.cpp
|
||||
systray.cpp
|
||||
wizard/abstractcredswizardpage.cpp
|
||||
wizard/owncloudadvancedsetuppage.cpp
|
||||
wizard/owncloudhttpcredspage.cpp
|
||||
wizard/owncloudsetuppage.cpp
|
||||
wizard/owncloudshibbolethcredspage.cpp
|
||||
wizard/owncloudwizardcommon.cpp
|
||||
wizard/owncloudwizard.cpp
|
||||
wizard/owncloudwizardresultpage.cpp
|
||||
)
|
||||
|
||||
|
||||
set(updater_SRCS
|
||||
updater/ocupdater.cpp
|
||||
updater/updateinfo.cpp
|
||||
updater/updater.cpp
|
||||
)
|
||||
|
||||
IF( APPLE )
|
||||
list(APPEND mirall_SRCS cocoainitializer_mac.mm)
|
||||
|
||||
list(APPEND mirall_SRCS settingsdialogmac.cpp)
|
||||
|
||||
if(SPARKLE_FOUND)
|
||||
# Define this, we need to check in updater.cpp
|
||||
add_definitions( -DHAVE_SPARKLE )
|
||||
list(APPEND updater_SRCS updater/sparkleupdater_mac.mm)
|
||||
endif()
|
||||
ENDIF()
|
||||
|
||||
IF( NOT WIN32 AND NOT APPLE )
|
||||
set(mirall_SRCS ${mirall_SRCS} folderwatcher_linux.cpp)
|
||||
ENDIF()
|
||||
IF( WIN32 )
|
||||
set(mirall_SRCS ${mirall_SRCS} folderwatcher_win.cpp)
|
||||
ENDIF()
|
||||
IF( APPLE )
|
||||
list(APPEND mirall_SRCS folderwatcher_mac.cpp)
|
||||
ENDIF()
|
||||
|
||||
set(3rdparty_SRC
|
||||
../3rdparty/fancylineedit/fancylineedit.cpp
|
||||
../3rdparty/QProgressIndicator/QProgressIndicator.cpp
|
||||
../3rdparty/qtlockedfile/qtlockedfile.cpp
|
||||
../3rdparty/qtsingleapplication/qtlocalpeer.cpp
|
||||
../3rdparty/qtsingleapplication/qtsingleapplication.cpp
|
||||
../3rdparty/qtsingleapplication/qtsinglecoreapplication.cpp
|
||||
)
|
||||
|
||||
if (APPLE)
|
||||
list(APPEND 3rdparty_SRC
|
||||
../3rdparty/qtmacgoodies/src/macpreferenceswindow.mm
|
||||
../3rdparty/qtmacgoodies/src/macstandardicon.mm
|
||||
)
|
||||
endif()
|
||||
|
||||
if(NOT WIN32)
|
||||
list(APPEND 3rdparty_SRC ../3rdparty/qtlockedfile/qtlockedfile_unix.cpp)
|
||||
else()
|
||||
list(APPEND 3rdparty_SRC ../3rdparty/qtlockedfile/qtlockedfile_win.cpp )
|
||||
endif()
|
||||
|
||||
set(3rdparty_INC
|
||||
${CMAKE_SOURCE_DIR}/src/3rdparty/fancylineedit
|
||||
${CMAKE_SOURCE_DIR}/src/3rdparty/qjson
|
||||
${CMAKE_SOURCE_DIR}/src/3rdparty/QProgressIndicator
|
||||
${CMAKE_SOURCE_DIR}/src/3rdparty/qtlockedfile
|
||||
${CMAKE_SOURCE_DIR}/src/3rdparty/qtmacgoodies/src
|
||||
${CMAKE_SOURCE_DIR}/src/3rdparty/qtsingleapplication
|
||||
)
|
||||
|
||||
include_directories(${3rdparty_INC})
|
||||
|
||||
# csync is required.
|
||||
include_directories(${CMAKE_SOURCE_DIR}/csync/src
|
||||
${CMAKE_SOURCE_DIR}/csync/src/httpbf/src
|
||||
${CMAKE_BINARY_DIR}/csync
|
||||
${CMAKE_BINARY_DIR}/csync/src
|
||||
)
|
||||
include_directories(${NEON_INCLUDE_DIRS})
|
||||
|
||||
include_directories(../libsync ${CMAKE_CURRENT_BINARY_DIR}/../libsync)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
||||
|
||||
qt_add_translation(mirall_I18N ${TRANSLATIONS})
|
||||
|
||||
set( final_src
|
||||
${MIRALL_RC_SRC}
|
||||
${mirall_SRCS}
|
||||
${mirall_UI_SRCS}
|
||||
${mirallMoc}
|
||||
${mirall_I18N}
|
||||
${3rdparty_SRC}
|
||||
${3rdparty_MOC}
|
||||
)
|
||||
|
||||
# add executable icon on windows and osx
|
||||
include( AddAppIconMacro )
|
||||
set(ownCloud_old ${ownCloud})
|
||||
|
||||
# set an icon_app_name. For historical reasons we can not use the
|
||||
# application_shortname for ownCloud but must rather set it manually.
|
||||
if ( EXISTS ${OEM_THEME_DIR}/OEM.cmake )
|
||||
set(ICON_APP_NAME ${APPLICATION_SHORTNAME})
|
||||
else()
|
||||
set(ICON_APP_NAME "owncloud")
|
||||
endif()
|
||||
|
||||
kde4_add_app_icon( ownCloud "${theme_dir}/colored/${ICON_APP_NAME}-icon*.png")
|
||||
list(APPEND final_src ${ownCloud})
|
||||
set(ownCloud ${ownCloud_old})
|
||||
|
||||
if (WITH_DBUS)
|
||||
set(ADDITIONAL_APP_MODULES DBus)
|
||||
endif(WITH_DBUS)
|
||||
|
||||
if(NOT BUILD_OWNCLOUD_OSX_BUNDLE)
|
||||
|
||||
if(NOT WIN32)
|
||||
file( GLOB _icons "${theme_dir}/colored/${ICON_APP_NAME}-icon-*.png" )
|
||||
foreach( _file ${_icons} )
|
||||
string( REPLACE "${theme_dir}/colored/${ICON_APP_NAME}-icon-" "" _res ${_file} )
|
||||
string( REPLACE ".png" "" _res ${_res} )
|
||||
install( FILES ${_file} RENAME ${ICON_APP_NAME}.png DESTINATION ${DATADIR}/icons/hicolor/${_res}x${_res}/apps )
|
||||
endforeach( _file )
|
||||
endif(NOT WIN32)
|
||||
|
||||
install(FILES ${mirall_I18N} DESTINATION share/${APPLICATION_EXECUTABLE}/i18n)
|
||||
|
||||
# we may not add MACOSX_BUNDLE here, if not building one
|
||||
|
||||
# add_executable( ${APPLICATION_EXECUTABLE} main.cpp ${final_src})
|
||||
add_executable( ${APPLICATION_EXECUTABLE} WIN32 main.cpp ${final_src})
|
||||
qt5_use_modules(${APPLICATION_EXECUTABLE} Widgets Network Xml WebKitWidgets Sql ${ADDITIONAL_APP_MODULES})
|
||||
elseif()
|
||||
if (Qt5Core_FOUND)
|
||||
include(DeployQt5)
|
||||
else(Qt5Core_FOUND)
|
||||
include(DeployQt4)
|
||||
endif(Qt5Core_FOUND)
|
||||
|
||||
set(CMAKE_INSTALL_PREFIX ".") # Examples use /Applications. hurmpf.
|
||||
set(MACOSX_BUNDLE_ICON_FILE "ownCloud.icns")
|
||||
|
||||
# we must add MACOSX_BUNDLE only if building a bundle
|
||||
add_executable( ${APPLICATION_EXECUTABLE} WIN32 MACOSX_BUNDLE main.cpp ${final_src})
|
||||
qt5_use_modules(${APPLICATION_EXECUTABLE} Widgets Network Xml WebKitWidgets Sql ${ADDITIONAL_APP_MODULES})
|
||||
|
||||
set (QM_DIR ${OWNCLOUD_OSX_BUNDLE}/Contents/Resources/Translations)
|
||||
install(FILES ${mirall_I18N} DESTINATION ${QM_DIR})
|
||||
file(GLOB qt_I18N ${QT_TRANSLATIONS_DIR}/qt_??.qm ${QT_TRANSLATIONS_DIR}/qt_??_??.qm)
|
||||
install(FILES ${qt_I18N} DESTINATION ${QM_DIR})
|
||||
file(GLOB qtkeychain_I18N ${QT_TRANSLATIONS_DIR}/qtkeychain*.qm)
|
||||
install(FILES ${qtkeychain_I18N} DESTINATION ${QM_DIR})
|
||||
endif()
|
||||
|
||||
add_library(updater STATIC ${updater_SRCS} ${updaterMoc})
|
||||
target_link_libraries(updater ${synclib_NAME})
|
||||
qt5_use_modules(updater Widgets Network Xml)
|
||||
|
||||
set_target_properties( ${APPLICATION_EXECUTABLE} PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY}
|
||||
)
|
||||
set_target_properties( ${APPLICATION_EXECUTABLE} PROPERTIES
|
||||
INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}/${APPLICATION_EXECUTABLE}" )
|
||||
|
||||
target_link_libraries( ${APPLICATION_EXECUTABLE} ${QT_LIBRARIES} )
|
||||
target_link_libraries( ${APPLICATION_EXECUTABLE} ${synclib_NAME} )
|
||||
target_link_libraries( ${APPLICATION_EXECUTABLE} updater )
|
||||
target_link_libraries( ${APPLICATION_EXECUTABLE} ${OS_SPECIFIC_LINK_LIBRARIES} )
|
||||
|
||||
install(TARGETS ${APPLICATION_EXECUTABLE}
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib
|
||||
BUNDLE DESTINATION "."
|
||||
)
|
||||
|
||||
|
||||
#FIXME: find a nice solution to make the second if(BUILD_OWNCLOUD_OSX_BUNDLE) unnecessary
|
||||
# currently it needs to be done because the code right above needs to be executed no matter
|
||||
# if building a bundle or not and the install_qt4_executable needs to be called afterwards
|
||||
if(BUILD_OWNCLOUD_OSX_BUNDLE)
|
||||
if(Qt5Core_FOUND)
|
||||
install_qt5_executable(${OWNCLOUD_OSX_BUNDLE} "qtaccessiblewidgets;qsqlite;qcocoa")
|
||||
else(Qt5Core_FOUND)
|
||||
install_qt4_executable(${OWNCLOUD_OSX_BUNDLE} "qtaccessiblewidgets;qsqlite")
|
||||
endif(Qt5Core_FOUND)
|
||||
endif()
|
||||
|
||||
if(NOT BUILD_OWNCLOUD_OSX_BUNDLE AND NOT WIN32)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/mirall.desktop.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${APPLICATION_EXECUTABLE}.desktop)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${APPLICATION_EXECUTABLE}.desktop DESTINATION share/applications )
|
||||
endif()
|
||||
|
||||
@@ -15,17 +15,17 @@
|
||||
#include "accountsettings.h"
|
||||
#include "ui_accountsettings.h"
|
||||
|
||||
#include "mirall/theme.h"
|
||||
#include "mirall/folderman.h"
|
||||
#include "mirall/folderwizard.h"
|
||||
#include "mirall/folderstatusmodel.h"
|
||||
#include "mirall/utility.h"
|
||||
#include "mirall/application.h"
|
||||
#include "mirall/owncloudsetupwizard.h"
|
||||
#include "mirall/mirallconfigfile.h"
|
||||
#include "mirall/ignorelisteditor.h"
|
||||
#include "mirall/account.h"
|
||||
#include "mirall/quotainfo.h"
|
||||
#include "theme.h"
|
||||
#include "folderman.h"
|
||||
#include "folderwizard.h"
|
||||
#include "folderstatusmodel.h"
|
||||
#include "utility.h"
|
||||
#include "application.h"
|
||||
#include "owncloudsetupwizard.h"
|
||||
#include "mirallconfigfile.h"
|
||||
#include "ignorelisteditor.h"
|
||||
#include "account.h"
|
||||
#include "quotainfo.h"
|
||||
#include "selectivesyncdialog.h"
|
||||
#include "creds/abstractcredentials.h"
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
#include <QIcon>
|
||||
#include <QVariant>
|
||||
|
||||
#include "mirall/account.h"
|
||||
#include "account.h"
|
||||
|
||||
namespace Mirall {
|
||||
|
||||
@@ -398,9 +398,10 @@ void AccountSettings::slotSelectiveSync()
|
||||
FolderMan *folderMan = FolderMan::instance();
|
||||
Folder *f = folderMan->folder(alias);
|
||||
if (f) {
|
||||
(new SelectiveSyncDialog(AccountManager::instance()->account(), f, this))->open();
|
||||
(new SelectiveSyncDialog(f, this))->open();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void AccountSettings::slotDoubleClicked( const QModelIndex& indx )
|
||||
@@ -642,18 +643,12 @@ void AccountSettings::slotSetProgress(const QString& folder, const Progress::Inf
|
||||
if (Progress::isSizeDependent(curItem._instruction)) {
|
||||
QString s1 = Utility::octetsToString( curItemProgress );
|
||||
QString s2 = Utility::octetsToString( curItem._size );
|
||||
quint64 estimatedBw = progress.getFileEstimate(curItem).getEstimatedBandwidth();
|
||||
if (estimatedBw) {
|
||||
//: Example text: "uploading foobar.png (1MB of 2MB) time left 2 minutes at a rate of 24Kb/s"
|
||||
fileProgressString = tr("%1 %2 (%3 of %4) %5 left at a rate of %6/s")
|
||||
.arg(kindString, itemFileName, s1, s2,
|
||||
Utility::timeToDescriptiveString(progress.getFileEstimate(curItem).getEtaEstimate(), 3, " ", true),
|
||||
Utility::octetsToString(estimatedBw) );
|
||||
} else {
|
||||
//: Example text: "uploading foobar.png (2MB of 2MB)"
|
||||
fileProgressString = tr("%1 %2 (%3 of %4)") .arg(kindString, itemFileName, s1, s2);
|
||||
}
|
||||
} else if (!kindString.isEmpty()) {
|
||||
//: Example text: "uploading foobar.png (1MB of 2MB) time left 2 minutes at a rate of 24Kb/s"
|
||||
fileProgressString = tr("%1 %2 (%3 of %4) %5 left at a rate of %6/s")
|
||||
.arg(kindString, itemFileName, s1, s2,
|
||||
Utility::timeToDescriptiveString(progress.getFileEstimate(curItem).getEtaEstimate(), 3, " ", true),
|
||||
Utility::octetsToString(progress.getFileEstimate(curItem).getEstimatedBandwidth()) );
|
||||
} else {
|
||||
//: Example text: "uploading foobar.png"
|
||||
fileProgressString = tr("%1 %2").arg(kindString, itemFileName);
|
||||
}
|
||||
@@ -662,18 +657,12 @@ void AccountSettings::slotSetProgress(const QString& folder, const Progress::Inf
|
||||
// overall progress
|
||||
quint64 completedSize = progress.completedSize();
|
||||
quint64 currentFile = progress._completedFileCount + progress._currentItems.count();
|
||||
QString overallSyncString;
|
||||
if (progress._totalSize > 0) {
|
||||
QString s1 = Utility::octetsToString( completedSize );
|
||||
QString s2 = Utility::octetsToString( progress._totalSize );
|
||||
overallSyncString = tr("%1 of %2, file %3 of %4\nTotal time left %5")
|
||||
.arg(s1, s2)
|
||||
.arg(currentFile).arg(progress._totalFileCount)
|
||||
.arg( Utility::timeToDescriptiveString(progress.totalEstimate().getEtaEstimate(), 3, " ", true) );
|
||||
} else if (progress._totalFileCount > 0) {
|
||||
// Don't attemt to estimate the time left if there is no kb to transfer.
|
||||
overallSyncString = tr("file %1 of %2") .arg(currentFile).arg(progress._totalFileCount);
|
||||
}
|
||||
QString s1 = Utility::octetsToString( completedSize );
|
||||
QString s2 = Utility::octetsToString( progress._totalSize );
|
||||
QString overallSyncString = tr("%1 of %2, file %3 of %4\nTotal time left %5")
|
||||
.arg(s1, s2)
|
||||
.arg(currentFile).arg(progress._totalFileCount)
|
||||
.arg( Utility::timeToDescriptiveString(progress.totalEstimate().getEtaEstimate(), 3, " ", true) );
|
||||
|
||||
item->setData( overallSyncString, FolderStatusDelegate::SyncProgressOverallString );
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
#include <QTimer>
|
||||
#include <QStandardItem>
|
||||
|
||||
#include "mirall/folder.h"
|
||||
#include "mirall/progressdispatcher.h"
|
||||
#include "folder.h"
|
||||
#include "progressdispatcher.h"
|
||||
|
||||
class QStandardItemModel;
|
||||
class QModelIndex;
|
||||
@@ -73,7 +73,7 @@
|
||||
<item>
|
||||
<widget class="QPushButton" name="_buttonSelectiveSync">
|
||||
<property name="text">
|
||||
<string>Choose What to Sync</string>
|
||||
<string>Selective Sync...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -19,18 +19,18 @@
|
||||
#include "config.h"
|
||||
|
||||
|
||||
#include "mirall/account.h"
|
||||
#include "mirall/application.h"
|
||||
#include "mirall/connectionvalidator.h"
|
||||
#include "mirall/folder.h"
|
||||
#include "mirall/folderman.h"
|
||||
#include "mirall/logger.h"
|
||||
#include "mirall/mirallconfigfile.h"
|
||||
#include "mirall/socketapi.h"
|
||||
#include "mirall/sslerrordialog.h"
|
||||
#include "mirall/theme.h"
|
||||
#include "mirall/utility.h"
|
||||
#include "mirall/clientproxy.h"
|
||||
#include "account.h"
|
||||
#include "application.h"
|
||||
#include "connectionvalidator.h"
|
||||
#include "folder.h"
|
||||
#include "folderman.h"
|
||||
#include "logger.h"
|
||||
#include "mirallconfigfile.h"
|
||||
#include "socketapi.h"
|
||||
#include "sslerrordialog.h"
|
||||
#include "theme.h"
|
||||
#include "utility.h"
|
||||
#include "clientproxy.h"
|
||||
|
||||
#include "updater/updater.h"
|
||||
#include "creds/abstractcredentials.h"
|
||||
@@ -22,13 +22,13 @@
|
||||
|
||||
#include "qtsingleapplication.h"
|
||||
|
||||
#include "mirall/syncresult.h"
|
||||
#include "mirall/logbrowser.h"
|
||||
#include "mirall/owncloudgui.h"
|
||||
#include "mirall/connectionvalidator.h"
|
||||
#include "mirall/progressdispatcher.h"
|
||||
#include "mirall/clientproxy.h"
|
||||
#include "mirall/folderman.h"
|
||||
#include "syncresult.h"
|
||||
#include "logbrowser.h"
|
||||
#include "owncloudgui.h"
|
||||
#include "connectionvalidator.h"
|
||||
#include "progressdispatcher.h"
|
||||
#include "clientproxy.h"
|
||||
#include "folderman.h"
|
||||
|
||||
class QMessageBox;
|
||||
class QSystemTrayIcon;
|
||||
@@ -11,7 +11,7 @@
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "mirall/cocoainitializer.h"
|
||||
#include "cocoainitializer.h"
|
||||
|
||||
#import <Foundation/NSAutoreleasePool.h>
|
||||
#import <AppKit/NSApplication.h>
|
||||
@@ -15,19 +15,18 @@
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include "mirall/account.h"
|
||||
#include "mirall/folder.h"
|
||||
#include "mirall/folderman.h"
|
||||
#include "mirall/logger.h"
|
||||
#include "mirall/mirallconfigfile.h"
|
||||
#include "mirall/networkjobs.h"
|
||||
#include "mirall/syncjournalfilerecord.h"
|
||||
#include "mirall/syncresult.h"
|
||||
#include "mirall/utility.h"
|
||||
#include "mirall/clientproxy.h"
|
||||
#include "mirall/syncengine.h"
|
||||
#include "mirall/syncrunfilelog.h"
|
||||
#include "mirall/theme.h"
|
||||
#include "account.h"
|
||||
#include "folder.h"
|
||||
#include "folderman.h"
|
||||
#include "logger.h"
|
||||
#include "mirallconfigfile.h"
|
||||
#include "networkjobs.h"
|
||||
#include "syncjournalfilerecord.h"
|
||||
#include "syncresult.h"
|
||||
#include "utility.h"
|
||||
#include "clientproxy.h"
|
||||
#include "syncengine.h"
|
||||
#include "syncrunfilelog.h"
|
||||
|
||||
#include "creds/abstractcredentials.h"
|
||||
|
||||
@@ -221,11 +220,11 @@ bool Folder::syncPaused() const
|
||||
return _paused;
|
||||
}
|
||||
|
||||
void Folder::setSyncPaused( bool paused )
|
||||
void Folder::setSyncPaused( bool doit )
|
||||
{
|
||||
_paused = paused;
|
||||
_paused = doit;
|
||||
|
||||
if( !paused ) {
|
||||
if( doit ) {
|
||||
// qDebug() << "Syncing enabled on folder " << name();
|
||||
} else {
|
||||
// do not stop or start the watcher here, that is done internally by
|
||||
@@ -256,27 +255,13 @@ void Folder::slotPollTimerTimeout()
|
||||
{
|
||||
qDebug() << "* Polling" << alias() << "for changes. (time since last sync:" << (_timeSinceLastSync.elapsed() / 1000) << "s)";
|
||||
|
||||
|
||||
Account *account = AccountManager::instance()->account();
|
||||
|
||||
if (!account) {
|
||||
qDebug() << Q_FUNC_INFO << "No valid account object";
|
||||
return;
|
||||
}
|
||||
|
||||
if (_paused || account->state() != Account::Connected) {
|
||||
qDebug() << "Not syncing. :" << _paused << account->state();
|
||||
return;
|
||||
}
|
||||
|
||||
if (quint64(_timeSinceLastSync.elapsed()) > MirallConfigFile().forceSyncInterval() ||
|
||||
_lastEtag.isNull() ||
|
||||
!(_syncResult.status() == SyncResult::Success ||_syncResult.status() == SyncResult::Problem)) {
|
||||
qDebug() << "** Force Sync now, state is " << _syncResult.statusString();
|
||||
emit scheduleToSync(alias());
|
||||
} else {
|
||||
// do the ordinary etag check for the root folder.
|
||||
RequestEtagJob* job = new RequestEtagJob(account, remotePath(), this);
|
||||
// do the ordinary etag chech for the root folder.
|
||||
RequestEtagJob* job = new RequestEtagJob(AccountManager::instance()->account(), remotePath(), this);
|
||||
// check if the etag is different
|
||||
QObject::connect(job, SIGNAL(etagRetreived(QString)), this, SLOT(etagRetreived(QString)));
|
||||
QObject::connect(job, SIGNAL(networkError(QNetworkReply*)), this, SLOT(slotNetworkUnavailable()));
|
||||
@@ -314,13 +299,12 @@ void Folder::bubbleUpSyncResult()
|
||||
int updatedItems = 0;
|
||||
int ignoredItems = 0;
|
||||
int renamedItems = 0;
|
||||
int errorItems = 0;
|
||||
|
||||
SyncFileItem firstItemNew;
|
||||
SyncFileItem firstItemDeleted;
|
||||
SyncFileItem firstItemUpdated;
|
||||
SyncFileItem firstItemRenamed;
|
||||
SyncFileItem firstItemError;
|
||||
Logger *logger = Logger::instance();
|
||||
|
||||
SyncRunFileLog syncFileLog;
|
||||
|
||||
@@ -336,10 +320,7 @@ void Folder::bubbleUpSyncResult()
|
||||
// and process the item to the gui
|
||||
if( item._status == SyncFileItem::FatalError || item._status == SyncFileItem::NormalError ) {
|
||||
slotSyncError( tr("%1: %2").arg(item._file, item._errorString) );
|
||||
errorItems++;
|
||||
if (firstItemError.isEmpty()) {
|
||||
firstItemError = item;
|
||||
}
|
||||
logger->postOptionalGuiLog(item._file, item._errorString);
|
||||
} else {
|
||||
// add new directories or remove gone away dirs to the watcher
|
||||
if (item._isDirectory && item._instruction == CSYNC_INSTRUCTION_NEW ) {
|
||||
@@ -392,9 +373,9 @@ void Folder::bubbleUpSyncResult()
|
||||
qDebug() << "Processing result list and logging took " << timer.elapsed() << " Milliseconds.";
|
||||
_syncResult.setWarnCount(ignoredItems);
|
||||
|
||||
createGuiLog( firstItemNew._file, SyncFileStatus::STATUS_NEW, newItems );
|
||||
createGuiLog( firstItemDeleted._file, SyncFileStatus::STATUS_REMOVE, removedItems );
|
||||
createGuiLog( firstItemUpdated._file, SyncFileStatus::STATUS_UPDATED, updatedItems );
|
||||
createGuiLog( firstItemNew._file, SyncFileStatus(SyncFileStatus::STATUS_NEW), newItems );
|
||||
createGuiLog( firstItemDeleted._file, SyncFileStatus(SyncFileStatus::STATUS_REMOVE), removedItems );
|
||||
createGuiLog( firstItemUpdated._file, SyncFileStatus(SyncFileStatus::STATUS_UPDATED), updatedItems );
|
||||
|
||||
if( !firstItemRenamed.isEmpty() ) {
|
||||
SyncFileStatus status(SyncFileStatus::STATUS_RENAME);
|
||||
@@ -407,8 +388,6 @@ void Folder::bubbleUpSyncResult()
|
||||
createGuiLog( firstItemRenamed._file, status, renamedItems, firstItemRenamed._renameTarget );
|
||||
}
|
||||
|
||||
createGuiLog( firstItemError._file, SyncFileStatus::STATUS_ERROR, errorItems );
|
||||
|
||||
qDebug() << "OO folder slotSyncFinished: result: " << int(_syncResult.status());
|
||||
}
|
||||
|
||||
@@ -459,13 +438,6 @@ void Folder::createGuiLog( const QString& filename, SyncFileStatus status, int c
|
||||
text = tr("%1 has been moved to %2.").arg(file).arg(renameTarget);
|
||||
}
|
||||
break;
|
||||
case SyncFileStatus::STATUS_ERROR:
|
||||
if( count > 1 ) {
|
||||
text = tr("%1 and %2 other files could not be synced due to errors. See the log for details.", "%1 names a file.").arg(file).arg(count-1);
|
||||
} else {
|
||||
text = tr("%1 could not be synced due to an error. See the log for details.").arg(file);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -511,7 +483,9 @@ void Folder::slotTerminateSync()
|
||||
// Do not display an error message, user knows his own actions.
|
||||
// _errors.append( tr("The CSync thread terminated.") );
|
||||
// _csyncError = true;
|
||||
FolderMan::instance()->slotSetFolderPaused(alias(), true);
|
||||
setSyncState(SyncResult::SyncAbortRequested);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -542,27 +516,20 @@ void Folder::wipe()
|
||||
}
|
||||
}
|
||||
|
||||
bool Folder::setIgnoredFiles()
|
||||
void Folder::setIgnoredFiles()
|
||||
{
|
||||
bool ok = false;
|
||||
|
||||
MirallConfigFile cfgFile;
|
||||
csync_clear_exclude_list( _csync_ctx );
|
||||
QString excludeList = cfgFile.excludeFile( MirallConfigFile::SystemScope );
|
||||
if( !excludeList.isEmpty() ) {
|
||||
qDebug() << "==== added system ignore list to csync:" << excludeList.toUtf8();
|
||||
if (csync_add_exclude_list( _csync_ctx, excludeList.toUtf8() ) == 0) {
|
||||
ok = true;
|
||||
}
|
||||
csync_add_exclude_list( _csync_ctx, excludeList.toUtf8() );
|
||||
}
|
||||
excludeList = cfgFile.excludeFile( MirallConfigFile::UserScope );
|
||||
if( !excludeList.isEmpty() ) {
|
||||
qDebug() << "==== added user defined ignore list to csync:" << excludeList.toUtf8();
|
||||
csync_add_exclude_list( _csync_ctx, excludeList.toUtf8() );
|
||||
// reading the user exclude file is optional
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
void Folder::setProxyDirty(bool value)
|
||||
@@ -585,7 +552,7 @@ void Folder::startSync(const QStringList &pathList)
|
||||
if (!_csync_ctx) {
|
||||
qDebug() << Q_FUNC_INFO << "init failed.";
|
||||
// the error should already be set
|
||||
QMetaObject::invokeMethod(this, "slotSyncFinished", Qt::QueuedConnection);
|
||||
QMetaObject::invokeMethod(this, "slotCSyncFinished", Qt::QueuedConnection);
|
||||
return;
|
||||
}
|
||||
_clientProxy.setCSyncProxy(AccountManager::instance()->account()->url(), _csync_ctx);
|
||||
@@ -606,16 +573,9 @@ void Folder::startSync(const QStringList &pathList)
|
||||
_syncResult.setStatus( SyncResult::SyncPrepare );
|
||||
emit syncStateChange();
|
||||
|
||||
qDebug() << "*** Start syncing - client version"
|
||||
<< qPrintable(Theme::instance()->version());
|
||||
|
||||
if (! setIgnoredFiles())
|
||||
{
|
||||
slotSyncError(tr("Could not read system exclude file"));
|
||||
QMetaObject::invokeMethod(this, "slotSyncFinished", Qt::QueuedConnection);
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "*** Start syncing";
|
||||
setIgnoredFiles();
|
||||
_engine.reset(new SyncEngine( _csync_ctx, path(), remoteUrl().path(), _remotePath, &_journal));
|
||||
|
||||
qRegisterMetaType<SyncFileItemVector>("SyncFileItemVector");
|
||||
@@ -635,7 +595,6 @@ void Folder::startSync(const QStringList &pathList)
|
||||
connect(_engine.data(), SIGNAL(folderDiscovered(bool,QString)), this, SLOT(slotFolderDiscovered(bool,QString)));
|
||||
connect(_engine.data(), SIGNAL(transmissionProgress(Progress::Info)), this, SLOT(slotTransmissionProgress(Progress::Info)));
|
||||
connect(_engine.data(), SIGNAL(jobCompleted(SyncFileItem)), this, SLOT(slotJobCompleted(SyncFileItem)));
|
||||
connect(_engine.data(), SIGNAL(syncItemDiscovered(SyncFileItem)), this, SLOT(slotSyncItemDiscovered(SyncFileItem)));
|
||||
|
||||
setDirtyNetworkLimits();
|
||||
_engine->setSelectiveSyncBlackList(selectiveSyncBlackList());
|
||||
@@ -693,13 +652,10 @@ void Folder::slotSyncFinished()
|
||||
|
||||
bubbleUpSyncResult();
|
||||
|
||||
bool anotherSyncNeeded = false;
|
||||
if (_engine) {
|
||||
anotherSyncNeeded = _engine->isAnotherSyncNeeded();
|
||||
_engine.reset(0);
|
||||
}
|
||||
_engine.reset(0);
|
||||
// _watcher->setEventsEnabledDelayed(2000);
|
||||
|
||||
_pollTimer.start();
|
||||
_timeSinceLastSync.restart();
|
||||
|
||||
|
||||
if (_csyncError) {
|
||||
@@ -727,16 +683,6 @@ void Folder::slotSyncFinished()
|
||||
// all come in.
|
||||
QTimer::singleShot(200, this, SLOT(slotEmitFinishedDelayed() ));
|
||||
|
||||
if (!anotherSyncNeeded) {
|
||||
_pollTimer.start();
|
||||
_timeSinceLastSync.restart();
|
||||
} else {
|
||||
// Another sync is required. We will make sure that the poll timer occurs soon enough
|
||||
// and we clear the etag to force a sync
|
||||
_lastEtag.clear();
|
||||
QTimer::singleShot(1000, this, SLOT(slotPollTimerTimeout() ));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Folder::slotEmitFinishedDelayed()
|
||||
@@ -774,11 +720,6 @@ void Folder::slotJobCompleted(const SyncFileItem &item)
|
||||
emit ProgressDispatcher::instance()->jobCompleted(alias(), item);
|
||||
}
|
||||
|
||||
void Folder::slotSyncItemDiscovered(const SyncFileItem & item)
|
||||
{
|
||||
emit ProgressDispatcher::instance()->syncItemDiscovered(alias(), item);
|
||||
}
|
||||
|
||||
|
||||
void Folder::slotAboutToRemoveAllFiles(SyncFileItem::Direction, bool *cancel)
|
||||
{
|
||||
@@ -17,11 +17,11 @@
|
||||
#ifndef MIRALL_FOLDER_H
|
||||
#define MIRALL_FOLDER_H
|
||||
|
||||
#include "mirall/syncresult.h"
|
||||
#include "mirall/progressdispatcher.h"
|
||||
#include "mirall/syncjournaldb.h"
|
||||
#include "mirall/clientproxy.h"
|
||||
#include "mirall/syncfilestatus.h"
|
||||
#include "syncresult.h"
|
||||
#include "progressdispatcher.h"
|
||||
#include "syncjournaldb.h"
|
||||
#include "clientproxy.h"
|
||||
#include "syncfilestatus.h"
|
||||
|
||||
#include <csync.h>
|
||||
|
||||
@@ -164,7 +164,6 @@ private slots:
|
||||
void slotFolderDiscovered(bool local, QString folderName);
|
||||
void slotTransmissionProgress(const Progress::Info& pi);
|
||||
void slotJobCompleted(const SyncFileItem&);
|
||||
void slotSyncItemDiscovered(const SyncFileItem & item);
|
||||
|
||||
void slotPollTimerTimeout();
|
||||
void etagRetreived(const QString &);
|
||||
@@ -177,7 +176,7 @@ private slots:
|
||||
private:
|
||||
bool init();
|
||||
|
||||
bool setIgnoredFiles();
|
||||
void setIgnoredFiles();
|
||||
|
||||
void bubbleUpSyncResult();
|
||||
|
||||
@@ -12,15 +12,12 @@
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "mirall/folderman.h"
|
||||
#include "mirall/account.h"
|
||||
|
||||
#include "mirall/mirallconfigfile.h"
|
||||
#include "mirall/folder.h"
|
||||
#include "mirall/syncresult.h"
|
||||
#include "mirall/theme.h"
|
||||
#include "mirall/socketapi.h"
|
||||
#include "mirall/accountmigrator.h"
|
||||
#include "folderman.h"
|
||||
#include "mirallconfigfile.h"
|
||||
#include "folder.h"
|
||||
#include "syncresult.h"
|
||||
#include "theme.h"
|
||||
#include "socketapi.h"
|
||||
|
||||
#include <neon/ne_socket.h>
|
||||
|
||||
@@ -39,15 +36,6 @@ namespace Mirall {
|
||||
|
||||
FolderMan* FolderMan::_instance = 0;
|
||||
|
||||
/**
|
||||
* The minimum time between a sync being requested and it
|
||||
* being executed in milliseconds.
|
||||
*
|
||||
* This delay must be larger than the minFileAgeForUpload in
|
||||
* the propagator.
|
||||
*/
|
||||
static int msBetweenRequestAndSync = 2000;
|
||||
|
||||
FolderMan::FolderMan(QObject *parent) :
|
||||
QObject(parent),
|
||||
_syncEnabled( true )
|
||||
@@ -193,15 +181,6 @@ int FolderMan::setupFolders()
|
||||
dir.setFilter(QDir::Files | QDir::Hidden);
|
||||
QStringList list = dir.entryList();
|
||||
|
||||
if( list.count() == 0 ) {
|
||||
// maybe the account was just migrated.
|
||||
Account *acc = AccountManager::instance()->account();
|
||||
if ( acc && acc->wasMigrated() ) {
|
||||
AccountMigrator accMig;
|
||||
list = accMig.migrateFolderDefinitons();
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( const QString& alias, list ) {
|
||||
Folder *f = setupFolderFromConfigFile( alias );
|
||||
if( f ) {
|
||||
@@ -235,6 +214,14 @@ bool FolderMan::ensureJournalGone(const QString &localPath)
|
||||
return true;
|
||||
}
|
||||
|
||||
void FolderMan::terminateCurrentSync()
|
||||
{
|
||||
if( !_currentSyncFolder.isEmpty() ) {
|
||||
qDebug() << "Terminating syncing on folder " << _currentSyncFolder;
|
||||
terminateSyncProcess( _currentSyncFolder );
|
||||
}
|
||||
}
|
||||
|
||||
#define SLASH_TAG QLatin1String("__SLASH__")
|
||||
#define BSLASH_TAG QLatin1String("__BSLASH__")
|
||||
#define QMARK_TAG QLatin1String("__QMARK__")
|
||||
@@ -437,35 +424,31 @@ void FolderMan::slotScheduleAllFolders()
|
||||
*/
|
||||
void FolderMan::slotScheduleSync( const QString& alias )
|
||||
{
|
||||
if( alias.isEmpty() || ! _folderMap.contains(alias) ) {
|
||||
qDebug() << "Not scheduling sync for empty or unknown folder" << alias;
|
||||
if( alias.isEmpty() ) return;
|
||||
|
||||
if( _currentSyncFolder == alias ) {
|
||||
qDebug() << "folder " << alias << " is currently syncing. NOT scheduling.";
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "Schedule folder " << alias << " to sync!";
|
||||
|
||||
if( ! _scheduleQueue.contains(alias) ) {
|
||||
if( ! _scheduleQueue.contains(alias ) && _folderMap.contains(alias) ) {
|
||||
Folder *f = _folderMap[alias];
|
||||
if ( !f )
|
||||
return;
|
||||
if( !f->syncPaused() ) {
|
||||
f->prepareToSync();
|
||||
} else {
|
||||
qDebug() << "Folder is not enabled, not scheduled!";
|
||||
if( _socketApi ) {
|
||||
if( f ) {
|
||||
if( !f->syncPaused() ) {
|
||||
f->prepareToSync();
|
||||
} else {
|
||||
qDebug() << "Folder is not enabled, not scheduled!";
|
||||
_socketApi->slotUpdateFolderView(f->alias());
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
_scheduleQueue.enqueue(alias);
|
||||
} else {
|
||||
qDebug() << " II> Sync for folder " << alias << " already scheduled, do not enqueue!";
|
||||
}
|
||||
|
||||
// Look at the scheduleQueue in a bit to see if the sync is ready to start.
|
||||
// The delay here is essential as the sync will not upload files that were
|
||||
// changed too recently.
|
||||
QTimer::singleShot(msBetweenRequestAndSync, this, SLOT(slotStartScheduledFolderSync()));
|
||||
// wait a moment until the syncing starts
|
||||
QTimer::singleShot(500, this, SLOT(slotScheduleFolderSync()));
|
||||
}
|
||||
|
||||
// only enable or disable foldermans will to schedule and do syncs.
|
||||
@@ -474,7 +457,7 @@ void FolderMan::setSyncEnabled( bool enabled )
|
||||
{
|
||||
if (!_syncEnabled && enabled && !_scheduleQueue.isEmpty()) {
|
||||
// We have things in our queue that were waiting the the connection to go back on.
|
||||
QTimer::singleShot(200, this, SLOT(slotStartScheduledFolderSync()));
|
||||
QTimer::singleShot(200, this, SLOT(slotScheduleFolderSync()));
|
||||
}
|
||||
_syncEnabled = enabled;
|
||||
// force a redraw in case the network connect status changed
|
||||
@@ -486,7 +469,7 @@ void FolderMan::setSyncEnabled( bool enabled )
|
||||
* It is either called from the slot where folders enqueue themselves for
|
||||
* syncing or after a folder sync was finished.
|
||||
*/
|
||||
void FolderMan::slotStartScheduledFolderSync()
|
||||
void FolderMan::slotScheduleFolderSync()
|
||||
{
|
||||
if( !_currentSyncFolder.isEmpty() ) {
|
||||
qDebug() << "Currently folder " << _currentSyncFolder << " is running, wait for finish!";
|
||||
@@ -498,25 +481,18 @@ void FolderMan::slotStartScheduledFolderSync()
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to start the top scheduled sync.
|
||||
qDebug() << "XX slotScheduleFolderSync: folderQueue size: " << _scheduleQueue.count();
|
||||
if( !_scheduleQueue.isEmpty() ) {
|
||||
if( ! _scheduleQueue.isEmpty() ) {
|
||||
const QString alias = _scheduleQueue.dequeue();
|
||||
if( !_folderMap.contains( alias ) ) {
|
||||
qDebug() << "FolderMan: Not syncing queued folder" << alias << ": not in folder map anymore";
|
||||
return;
|
||||
}
|
||||
if( _folderMap.contains( alias ) ) {
|
||||
Folder *f = _folderMap[alias];
|
||||
if( f && !f->syncPaused() ) {
|
||||
_currentSyncFolder = alias;
|
||||
|
||||
// Start syncing this folder!
|
||||
Folder *f = _folderMap[alias];
|
||||
if( f && !f->syncPaused() ) {
|
||||
_currentSyncFolder = alias;
|
||||
f->startSync( QStringList() );
|
||||
|
||||
f->startSync( QStringList() );
|
||||
|
||||
// reread the excludes of the socket api
|
||||
// FIXME: the excludes need rework.
|
||||
if( _socketApi ) {
|
||||
// reread the excludes of the socket api
|
||||
// FIXME: the excludes need rework.
|
||||
_socketApi->slotClearExcludesList();
|
||||
_socketApi->slotReadExcludes();
|
||||
}
|
||||
@@ -539,7 +515,7 @@ void FolderMan::slotFolderSyncFinished( const SyncResult& )
|
||||
|
||||
_currentSyncFolder.clear();
|
||||
|
||||
QTimer::singleShot(200, this, SLOT(slotStartScheduledFolderSync()));
|
||||
QTimer::singleShot(200, this, SLOT(slotScheduleFolderSync()));
|
||||
}
|
||||
|
||||
void FolderMan::addFolderDefinition(const QString& alias, const QString& sourceFolder,
|
||||
@@ -633,11 +609,8 @@ void FolderMan::removeFolder( const QString& alias )
|
||||
}
|
||||
}
|
||||
|
||||
QString FolderMan::getBackupName( QString fullPathName ) const
|
||||
QString FolderMan::getBackupName( const QString& fullPathName ) const
|
||||
{
|
||||
if (fullPathName.endsWith("/"))
|
||||
fullPathName.chop(1);
|
||||
|
||||
if( fullPathName.isEmpty() ) return QString::null;
|
||||
|
||||
QString newName = fullPathName + QLatin1String(".oC_bak");
|
||||
@@ -655,41 +628,27 @@ QString FolderMan::getBackupName( QString fullPathName ) const
|
||||
|
||||
bool FolderMan::startFromScratch( const QString& localFolder )
|
||||
{
|
||||
if( localFolder.isEmpty() ) {
|
||||
return false;
|
||||
}
|
||||
if( localFolder.isEmpty() ) return false;
|
||||
|
||||
QFileInfo fi( localFolder );
|
||||
QDir parentDir( fi.dir() );
|
||||
QString folderName = fi.fileName();
|
||||
if( fi.exists() && fi.isDir() ) {
|
||||
QDir file = fi.dir();
|
||||
|
||||
// Adjust for case where localFolder ends with a /
|
||||
if ( fi.isDir() ) {
|
||||
folderName = parentDir.dirName();
|
||||
parentDir.cdUp();
|
||||
}
|
||||
|
||||
if( fi.exists() ) {
|
||||
// It exists, but is empty -> just reuse it.
|
||||
if( fi.isDir() && fi.dir().count() == 0 ) {
|
||||
// check if there are files in the directory.
|
||||
if( file.count() == 0 ) {
|
||||
// directory is existing, but its empty. Use it.
|
||||
qDebug() << "startFromScratch: Directory is empty!";
|
||||
return true;
|
||||
}
|
||||
// Make a backup of the folder/file.
|
||||
QString newName = getBackupName( parentDir.absoluteFilePath( folderName ) );
|
||||
if( !parentDir.rename( fi.absoluteFilePath(), newName ) ) {
|
||||
qDebug() << "startFromScratch: Could not rename" << fi.absoluteFilePath()
|
||||
<< "to" << newName;
|
||||
return false;
|
||||
QString newName = getBackupName( fi.absoluteFilePath() );
|
||||
|
||||
if( file.rename( fi.absoluteFilePath(), newName )) {
|
||||
if( file.mkdir( fi.absoluteFilePath() ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !parentDir.mkdir( fi.absoluteFilePath() ) ) {
|
||||
qDebug() << "startFromScratch: Could not mkdir" << fi.absoluteFilePath();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void FolderMan::setDirtyProxy(bool value)
|
||||
@@ -21,9 +21,9 @@
|
||||
#include <QList>
|
||||
#include <QPointer>
|
||||
|
||||
#include "mirall/folder.h"
|
||||
#include "mirall/folderwatcher.h"
|
||||
#include "mirall/syncfileitem.h"
|
||||
#include "folder.h"
|
||||
#include "folderwatcher.h"
|
||||
#include "syncfileitem.h"
|
||||
|
||||
class QSignalMapper;
|
||||
|
||||
@@ -107,11 +107,6 @@ public slots:
|
||||
void slotFolderSyncStarted();
|
||||
void slotFolderSyncFinished( const SyncResult& );
|
||||
|
||||
/**
|
||||
* Terminates the specified folder sync (or the current one).
|
||||
*
|
||||
* It does not switch the folder to paused state.
|
||||
*/
|
||||
void terminateSyncProcess( const QString& alias = QString::null );
|
||||
|
||||
/* unload and delete on folder object */
|
||||
@@ -134,12 +129,13 @@ public slots:
|
||||
private slots:
|
||||
|
||||
// slot to take the next folder from queue and start syncing.
|
||||
void slotStartScheduledFolderSync();
|
||||
void slotScheduleFolderSync();
|
||||
|
||||
private:
|
||||
// finds all folder configuration files
|
||||
// and create the folders
|
||||
QString getBackupName( QString fullPathName ) const;
|
||||
void terminateCurrentSync();
|
||||
QString getBackupName( const QString& ) const;
|
||||
void registerFolderMonitor( Folder *folder );
|
||||
|
||||
QString unescapeAlias( const QString& ) const;
|
||||
@@ -153,12 +149,10 @@ private:
|
||||
QSignalMapper *_folderWatcherSignalMapper;
|
||||
QString _currentSyncFolder;
|
||||
bool _syncEnabled;
|
||||
QQueue<QString> _scheduleQueue;
|
||||
QMap<QString, FolderWatcher*> _folderWatchers;
|
||||
QPointer<SocketApi> _socketApi;
|
||||
|
||||
/** The aliases of folders that shall be synced. */
|
||||
QQueue<QString> _scheduleQueue;
|
||||
|
||||
static FolderMan *_instance;
|
||||
explicit FolderMan(QObject *parent = 0);
|
||||
~FolderMan();
|
||||
@@ -12,8 +12,8 @@
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "mirall/folderstatusmodel.h"
|
||||
#include "mirall/utility.h"
|
||||
#include "folderstatusmodel.h"
|
||||
#include "utility.h"
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtGui>
|
||||
@@ -12,7 +12,7 @@
|
||||
*/
|
||||
|
||||
// event masks
|
||||
#include "mirall/folderwatcher.h"
|
||||
#include "folderwatcher.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -25,11 +25,11 @@
|
||||
#include <QTimer>
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
#include "mirall/folderwatcher_win.h"
|
||||
#include "folderwatcher_win.h"
|
||||
#elif defined(Q_OS_MAC)
|
||||
#include "mirall/folderwatcher_mac.h"
|
||||
#include "folderwatcher_mac.h"
|
||||
#elif defined(Q_OS_UNIX)
|
||||
#include "mirall/folderwatcher_linux.h"
|
||||
#include "folderwatcher_linux.h"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
|
||||
#include <sys/inotify.h>
|
||||
|
||||
#include "mirall/folder.h"
|
||||
#include "mirall/folderwatcher_linux.h"
|
||||
#include "folder.h"
|
||||
#include "folderwatcher_linux.h"
|
||||
|
||||
#include <cerrno>
|
||||
#include <QDebug>
|
||||
@@ -20,7 +20,7 @@
|
||||
#include <QHash>
|
||||
#include <QDir>
|
||||
|
||||
#include "mirall/folderwatcher.h"
|
||||
#include "folderwatcher.h"
|
||||
|
||||
namespace Mirall
|
||||
{
|
||||
Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais
Referência em uma Nova Issue
Bloquear um usuário