Comparar commits

...

441 Commits

Autor SHA1 Mensagem Data
Klaas Freitag 22e31b2232 Bump version to 2.1.0 beta1 2015-11-17 15:33:22 +01:00
Klaas Freitag 5ec4fd94e0 ActivityWidget: No progress indic. for non connected accounts. 2015-11-17 15:05:54 +01:00
Klaas Freitag c9ef4d5fa0 ActivityWidget: Detect new items in the list to refetch the activities.
On refresh, remove the activity list object from the models list.
2015-11-17 14:46:25 +01:00
Klaas Freitag 1cdf0e8597 ActivityWidget: Always combine the final activity list.
In cases where the activity app is not activated on the server, the
returned list of activities is empty, so it is better this way.
2015-11-17 14:46:25 +01:00
Daniel Molkentin 7ba88cc9e3 Merge remote-tracking branch 'origin/2.0' 2015-11-17 12:57:31 +01:00
Daniel Molkentin 914df32587 Documentation: Fix PDF logo, version number 2015-11-17 12:55:41 +01:00
Olivier Goffart e0f54428d0 ShareDialog: softer line separator (#3737) 2015-11-17 12:02:20 +01:00
Markus Goetz 52a11b0835 Activities: Fix on Mac #4083 2015-11-17 11:53:49 +01:00
Markus Goetz ef17dc6482 Connectivity: Improve log output 2015-11-17 11:02:53 +01:00
Markus Goetz 9978dc3f6c QNAM: Use invalid configuration instead of default configuration
For #3969 and others.
2015-11-17 11:02:53 +01:00
Olivier Goffart f618ed3dfb gui: Fix some icons in highdpi
QIcon does not need to use Theme::hidpiFileName because QIcon takes care
of the @2x images
2015-11-17 10:48:45 +01:00
Olivier Goffart ef915fb2e5 SharedDialog: Fix the delete icon on windows and mac (#3737) 2015-11-17 10:40:45 +01:00
Olivier Goffart 6e42405113 ShareDialog: remove the search button (#3737) 2015-11-17 10:24:35 +01:00
Olivier Goffart 11ef07c74a ActivityWidget: fix compiler warnings 2015-11-17 09:54:38 +01:00
Jenkins for ownCloud 486d7690c4 [tx-robot] updated from transifex 2015-11-17 02:19:08 -05:00
Klaas Freitag 8852911f67 Merge branch 'master' of github.com:owncloud/mirall 2015-11-16 18:16:58 +01:00
Klaas Freitag e38bc6eab8 AcitivityWidget: Moved timespan-in-words method to utility.
Also added a second parameter, fixed plural translation and added
a less-than-a-minute-ago term.
2015-11-16 18:08:25 +01:00
Olivier Goffart 459e200ac0 ShareDialog: add a QScrollArea (issue #4125 ) 2015-11-16 18:01:11 +01:00
Klaas Freitag c781155b60 General Settings page: Remove the add account button.
It is now in the toolbox on the account page.
2015-11-16 17:07:05 +01:00
Klaas Freitag 87aa1de67a Merge branch 'newactivity' 2015-11-16 17:02:05 +01:00
Klaas Freitag ccb871c30b ActivityWidget: Show the subject in the Tooltip.
the original text might be elided.
2015-11-16 16:44:52 +01:00
Klaas Freitag 74ed0b4f09 Merge pull request #4139 from owncloud/account_toolbox
AccountSettings: Add a toolbox button for the account specific actions.
2015-11-16 15:53:30 +01:00
Klaas Freitag becbb7b284 AccountSettings: Address jans suggestions in #4139
- Changed sequence of menu items
- lowercased entries
- removed the "Account" from entries, its in the toolbox button already
- added a little space between toolbox button label and the rectangle.
2015-11-16 15:50:32 +01:00
Klaas Freitag ff76a842d0 Added some documentation. 2015-11-16 15:38:08 +01:00
Klaas Freitag a56926b8d9 ActivityWidget: open local file in file manager if exists. 2015-11-16 15:31:24 +01:00
Olivier Goffart 0d21503ee5 ShareDialog: fix auto completion to actualy auto complete 2015-11-16 15:23:02 +01:00
Klaas Freitag 631cb095dd ActivityWidget: Show the local path in a tooltip.
Note that the activity has also entries of files that are not synced so
that not every activity entry has to have a local pendant.

Also, one activity entry can reference multiple files, so only the first
one is shown.
2015-11-16 15:07:02 +01:00
Klaas Freitag caba719950 Folderman: Added method to find local files for a rel. server path. 2015-11-16 15:04:59 +01:00
Roeland Douma 786b602c26 Merge pull request #4133 from owncloud/sharedialog_uit_improvements
[Sharedialog] Fix UI stuff
2015-11-16 13:36:00 +01:00
Jenkins for ownCloud f4bfce153d [tx-robot] updated from transifex 2015-11-16 02:18:48 -05:00
Jenkins for ownCloud e1ab50b17c [tx-robot] updated from transifex 2015-11-14 02:19:03 -05:00
Klaas Freitag 7e4c0bd515 AccountSettings: Add a toolbox button for the account specific actions.
Also move the 'Add Account' button from the General Tab, where it
is not properly found, to the new account toolbox.
2015-11-13 14:50:07 +01:00
Klaas Freitag ddcec2971e ActivityDelegate: Gray out font if account is not connected.
This gives a visual indication of the account not being connected
and as a result maybe outdated activity data.
2015-11-13 12:48:25 +01:00
Roeland Jago Douma 72d119a05f [Sharing] Delete animation when share is removed 2015-11-13 11:03:51 +01:00
Roeland Jago Douma d423cf2c7f [Sharedialog] Fix UI stuff
Implemented suggestions form
https://github.com/owncloud/client/issues/3737#issuecomment-156036279

* Removed Shares text
* Permissions now next to username
* Simplified permissions by default
* Button to get more detailed permissions
2015-11-13 10:27:26 +01:00
Jenkins for ownCloud 3d847b50cf [tx-robot] updated from transifex 2015-11-13 02:19:01 -05:00
Klaas Freitag 731a13cfd1 ActivityWidget: Take the account state (connected or not) in account.
Display the activity entries in a different mode if the account is not
longer connected.
2015-11-12 17:52:00 +01:00
Klaas Freitag 81296fae9d AccountManager: new method to return AccountStatePtr from the name.
It uses the Account displayName to destinguish.
2015-11-12 17:50:00 +01:00
Klaas Freitag aa38f7a4f2 ActivityWidget: implement removeAccount. 2015-11-12 15:39:07 +01:00
Jenkins for ownCloud bac69f9984 [tx-robot] updated from transifex 2015-11-12 02:19:14 -05:00
Klaas Freitag c46547592c sync excludes: Add .directory files to be ignored 2015-11-11 17:27:01 +01:00
Markus Goetz fd4a5100a6 NSIS: Include Qt bearer management DLLs #3969 2015-11-11 15:19:15 +01:00
Klaas Freitag ff4a8c9202 GeneralSettings: Remove references to protocolwidget.
The ProtocolWidget is now the Activitytab Widget
2015-11-11 14:49:11 +01:00
Christian Kamm c871d721fd Tray tooltip: Use aliasGui #4096 2015-11-11 14:35:56 +01:00
Christian Kamm 05d1cc9a94 Sharing: Fix crash with share deletion #4111
The problem was that Share could be deleted *before*
the OcsShareJob itself finished. Since Share was the
parent of the network job, its object would be deleted
too early.

In general, it's unnecessary to assign parents to the OcsJobs
because they delete themselves when finished.
2015-11-11 13:28:20 +01:00
Christian Kamm 196ee05fcc Share dialog: Initialize expected expire date #4075 2015-11-11 13:01:12 +01:00
Christian Kamm e50cfa4e1b Recent Activity: Don't reset for no reason #3889 2015-11-11 12:48:15 +01:00
Daniel Molkentin 3224a959a4 Forward-declare QModelIndex. Fixes Qt4 builds. 2015-11-11 11:52:10 +01:00
Christian Kamm 2ccb3648c7 Recent Activity: Filter metadata updates #3963 2015-11-11 11:19:04 +01:00
Christian Kamm 01aa647527 FolderMan: Fix infinite wait on pause #4093
If a folder was paused while being the next item in the scheduling
queue, the whole scheduling could get stuck.

This also fixes the progress information of paused folders possibly
getting stuck.
2015-11-11 10:59:04 +01:00
Christian Kamm eb3388de68 Fix OwnSql test
3993a7f636 added asserts for failing
prepare() calls
2015-11-11 09:42:31 +01:00
Christian Kamm beb970646b Fix csync_exclude test
The exclude file was reorganized in
b6aa18bfbc
2015-11-11 09:42:31 +01:00
Christian Kamm 25c177ca3b SyncJournalFileRecord: Remove unused mode field 2015-11-11 09:42:31 +01:00
Daniel Molkentin 1d9c591c08 Fix OS X compilation: use mode_t instead of __mode_t 2015-11-11 09:36:17 +01:00
Jenkins for ownCloud f753960add [tx-robot] updated from transifex 2015-11-11 02:19:02 -05:00
Klaas Freitag 5e98894a97 ActivityView: Add a progress indicator widget to indicate action. 2015-11-10 18:10:58 +01:00
Markus Goetz 15fe3b569b Merge pull request #4100 from mnutt/credentials-from-url
Populate account setup credentials from server URL
2015-11-10 16:12:34 +01:00
Klaas Freitag 0e0b6026fc Activity: Unify the GUI, and reactivate copy to clipboard for all. 2015-11-10 15:12:35 +01:00
Christian Kamm 17dd199cba Checksums: Treat more carefully in db #4034
In particular, preserve them on local rename or remote move.
2015-11-10 15:05:00 +01:00
Christian Kamm 8f7dbe71a1 CleanupPollsJobs: Preserve more journal data 2015-11-10 14:26:25 +01:00
Christian Kamm 4b5c3d8f09 Tray: Show settings dialog on click if it's not active
Before, you often had to click twice to bring the window
to the front, because the first click would close it.
2015-11-10 12:33:36 +01:00
Christian Kamm 9955b0756a Settings: Show first account page on startup #4036 2015-11-10 12:20:08 +01:00
Christian Kamm 76d9b9c0e2 Rename env variables to include unit #2939 2015-11-10 12:07:10 +01:00
Christian Kamm 175ad6fb77 Reflect read-only permissions in filesystem #3244 2015-11-10 10:14:25 +01:00
Christian Kamm 51896902e3 Silence warning by removing extra semicolon 2015-11-10 10:06:49 +01:00
Jenkins for ownCloud b55220905e [tx-robot] updated from transifex 2015-11-10 02:19:10 -05:00
Michael Nutt bd65eb32b7 SetupWizard: populate credentials from HTTP server URL
If a user enters a server URL in the form of
https://user:pass@example.com/, pre-populate the following credentials
page with those values.
2015-11-09 18:21:33 -05:00
Olivier Goffart b29d1e94b5 ShareDialog: fix autocompletion took the wrong user 2015-11-09 17:22:17 +01:00
Olivier Goffart b74e812671 Share dialog: a few layout adjustements 2015-11-09 17:22:17 +01:00
Olivier Goffart aa27b5db14 Discovery: silent static analysis warning
We do a check one line earlier that the size is smaller than the buffer
Then we don't need to call strncpy,  strcpy is enough
2015-11-09 17:22:17 +01:00
Markus Goetz 81e3a62360 Account: Show local path in tooltip 2015-11-09 16:39:08 +01:00
Jenkins for ownCloud b0dc264369 [tx-robot] updated from transifex 2015-11-09 02:22:38 -05:00
Jenkins for ownCloud ac3f179420 [tx-robot] updated from transifex 2015-11-08 02:18:58 -05:00
Jenkins for ownCloud d9af837974 [tx-robot] updated from transifex 2015-11-07 02:19:09 -05:00
Markus Goetz 4784b327e7 Folder Status: Use same fat ... icon as web 2015-11-06 16:10:50 +01:00
Markus Goetz 1a1541ecd6 macdeployqt: Forgot comma 2015-11-06 15:18:14 +01:00
Klaas Freitag cf9fec73cf ActivityView: Add a second treeview for sync issues.
So there are three views now: One displaying the server activities, one for
the sync protocol and a third one for ignored files and issues.
2015-11-06 11:43:43 +01:00
Klaas Freitag a1551ef6ab ActivityDelegate: Make the row height public accessible.
Now it can be used to be set on the other two treeviews.
2015-11-06 11:41:32 +01:00
Markus Goetz 0163839cfb OS X: Fix toolbar oddity #3719 2015-11-06 10:18:09 +01:00
Roeland Douma 914a942e33 Merge pull request #4055 from owncloud/user_group_sharing
User group sharing
2015-11-06 09:35:42 +01:00
Jenkins for ownCloud 5e482ad4f7 [tx-robot] updated from transifex 2015-11-06 02:19:01 -05:00
Markus Goetz 6901fc9e38 macdeployqt: Also copy bearer plugins
See #3449
2015-11-05 18:15:45 +01:00
Markus Goetz 0070835330 macdeployqt: Hack to make Qt 5.5 work 2015-11-05 17:19:49 +01:00
Roeland Jago Douma 6431a2aa46 [Sharing] Build sharee list on every search 2015-11-05 15:01:29 +01:00
Roeland Jago Douma 4cf2422a83 [Sharing] Clear completer on activation 2015-11-05 13:16:52 +01:00
Roeland Jago Douma 806ec98eab [Sharing] Properly delete widget 2015-11-05 13:10:32 +01:00
Roeland Jago Douma 20fd349e17 [Sharing] Filter sharee list properly
You can't share with a user/group that you've already shared with
You can't share with yourself
2015-11-05 12:30:34 +01:00
Markus Goetz dae724b21c QtVersionAbstraction: Quick not neeed on OS X 2015-11-05 11:35:42 +01:00
Roeland Jago Douma 3e4612a1f0 [Sharing] Reorganized sharedialog code
Now we have 1 simple dialog that includes 2 widgets.
* ShareLinkWidget (for link shares)
* ShareUserGroupWidget (for user/group shares)

The ShareUserGroupWidget is only included if the server version is >=
8.2.0

For <8.2.0 the old behavior is preserved
2015-11-05 09:58:16 +01:00
Jenkins for ownCloud 6052e49bcc [tx-robot] updated from transifex 2015-11-05 02:19:06 -05:00
Roeland Jago Douma 90cbd461ab [Sharing] Allow sharing with users/groups from desktop 2015-11-04 22:00:35 +01:00
Lukas Reschke 517f2ed03d Add coverity badge 2015-11-04 21:06:48 +01:00
Daniel Molkentin 5fccc25f36 Fix Qt4 build 2015-11-04 19:28:54 +01:00
Klaas Freitag cb1571c6c5 ActivityWidget: Rather use accountState pointer directly.
Do not use it via a smart pointer class.
2015-11-04 16:40:22 +01:00
Markus Goetz 99b0d659bd Merge pull request #4073 from RealRancor/backport_4052_2.0
Backport #4052 to 2.0
2015-11-04 16:32:34 +01:00
RealRancor 854264c3d2 Backport #4052 to 2.0 2015-11-04 15:55:07 +01:00
Markus Goetz d2a6cae695 Merge pull request #4052 from RealRancor/fix_autoupdate
Make registry key a code block in autoupdate docs.
2015-11-04 15:11:45 +01:00
Markus Goetz be9ed2f6a9 Merge pull request #4058 from owncloud/client-updates
some doc fixes & updates
2015-11-04 15:11:28 +01:00
Markus Goetz 3ee8beb8a3 Exclude: Add .nfs*
From eltrai at #4017
2015-11-04 15:06:05 +01:00
Jenkins for ownCloud f816e5e2af [tx-robot] updated from transifex 2015-11-04 08:32:32 -05:00
Jenkins for ownCloud 448d8bff18 [tx-robot] updated from transifex 2015-11-04 08:30:20 -05:00
Daniel Molkentin b82ffb52c7 Merge remote-tracking branch 'origin/2.0' 2015-11-04 14:25:14 +01:00
Klaas Freitag 3bccfb8993 ActivityView: Add information about the account. 2015-11-04 13:22:03 +01:00
Roeland Jago Douma 6fb4e59120 [Sharing] First step towards proper group sharing 2015-11-04 12:56:06 +01:00
Roeland Jago Douma 309be57a12 [Sharing] Add user/group sharing dialog
Dialog can now retrive current shares for path, set the permissions on
those shares and delete the share.
2015-11-04 12:53:07 +01:00
Roeland Jago Douma 37098c96f9 [Sharing] Add setpermission to sharing code
For user/group/remote shares we were just missing the setPermissions
functionality
2015-11-04 12:53:02 +01:00
Jenkins for ownCloud 03cc67a2b1 [tx-robot] updated from transifex 2015-11-04 02:19:04 -05:00
Klaas Freitag cb4fba7658 ActivityWidget: Created a delegate for prettier display of the activities 2015-11-03 17:54:37 +01:00
Jenkins for ownCloud 89734b95c4 [tx-robot] updated from transifex 2015-11-03 02:19:04 -05:00
Carla Schroder a59c3ef278 some doc fixes & updates 2015-11-02 11:18:31 -08:00
Klaas Freitag b600ac882a ActivityListModel: Add method to refresh one Account (WIP) 2015-11-02 17:52:04 +01:00
Klaas Freitag 71849c4372 ActivityListModel: Add the page and pagesize parameter to ocs query. 2015-11-02 17:51:12 +01:00
Klaas Freitag 9545af0d43 JSONApiJob: Add method to add additional query parameter. 2015-11-02 17:37:23 +01:00
Klaas Freitag 6c6ee358d4 ActivityListModel: Check if the account is connected when fetching more. 2015-11-02 16:39:33 +01:00
Klaas Freitag 060f4f291b SettingsDialog: Add a tab with the SyncProtocol to ActivityWidget. 2015-11-02 15:46:00 +01:00
Klaas Freitag 3fb43d2322 ActivityWidget UI: Remove the preconfigured tabs from the tabwidget.
It is better to create the tabs from the code in SettingsDialog.
2015-11-02 15:45:17 +01:00
Klaas Freitag 4895683bab ActivityWidget: Do a proper asynchronous model to display the activity. 2015-11-02 15:44:13 +01:00
Klaas Freitag 43800e3d1c Merge pull request #4049 from Naereen/patch-1
Reviewing, improved style, and a initializing message
2015-11-02 10:14:07 +01:00
Klaas Freitag 3b8e1dcd89 SettingsDialog: Make ActivityWidget a member. 2015-11-01 22:30:46 +01:00
Klaas Freitag 302d6b321e ActivityWidget: Add a job to fetch activities, Activity object added 2015-11-01 22:30:37 +01:00
Jenkins for ownCloud 3f85694394 [tx-robot] updated from transifex 2015-11-01 02:18:55 -05:00
RealRancor 8c5ef2f1c3 Make registry key a code block in autoupdate docs. 2015-10-31 19:05:21 +01:00
Lilian Besson aa1a2d1247 Reviewing, improved style, and a initializing message
- Add an "Initializing owncloud-client-nautilus extension" message
2015-10-31 13:07:18 +01:00
Olivier Goffart 3993a7f636 OwnSQL: add asserts in case of error that should not happen 2015-10-30 14:05:58 +01:00
Olivier Goffart aaf16ff0e8 SyncJournalDB, clear all the queries before closing the database 2015-10-30 14:03:08 +01:00
Olivier Goffart 16c078963b owncloudcmd: add --max-sync-retries #4037
And limit by default to 3 retries
2015-10-30 13:36:31 +01:00
Klaas Freitag 9279bcdba4 Add a tabwidget to Settings dialog for activity. 2015-10-30 13:26:27 +01:00
Olivier Goffart 0c467ef5b4 Sync engine: fix signal/slot connection 2015-10-30 13:21:34 +01:00
Olivier Goffart 49cd53ee44 FolderStatusModel: attempt to detect removed undecided files #3612 2015-10-30 12:43:33 +01:00
Olivier Goffart 0e6a463564 Discovery: Don't leak DiscoveryDirectoryResult in case of error
Also remove redundent Q_FUNC_INFO
2015-10-30 12:43:33 +01:00
Roeland Douma d38b190317 Merge pull request #4033 from owncloud/share_object
Add share manager and the share objects
2015-10-30 11:01:03 +01:00
Klaas Freitag 29558cb7bb Merge pull request #4040 from owncloud/phil-davis-changelog-master
ChangeLog typos that reverted in merge from 2.0
2015-10-30 10:36:38 +01:00
Jenkins for ownCloud d2cd237e25 [tx-robot] updated from transifex 2015-10-30 02:19:00 -04:00
Roeland Jago Douma c7b814337a Use proper QFlags
Now the ShareTypes and Permissions are part of the Share class (which is
a bit better abstracted away).
2015-10-29 21:47:47 +01:00
Phil Davis ced51813c7 ChangeLog typos that reverted in merge from 2.0
Hopefully the last place I need to submit this again :)
2015-10-29 23:35:48 +05:45
Roeland Jago Douma dd8d02b8ef Act properly if OCS endpoint returned an error (OCS error)
For now pass it on to the gui. So at least they know something is wrong.
2015-10-29 16:56:23 +01:00
Olivier Goffart c3cf6aef7d SyncEngine: Don't whipe the white list if the sync was aborted
Issue #4018
2015-10-29 16:47:39 +01:00
Olivier Goffart 38a8e5ee03 Discovery: conding style: use const references for function parameters 2015-10-29 16:47:36 +01:00
Klaas Freitag 46269dac4e Merge branch '2.0'
Conflicts:
	ChangeLog
2015-10-29 16:34:15 +01:00
Roeland Jago Douma 8c0297f688 Use QLatin1Char 2015-10-29 16:03:47 +01:00
Klaas Freitag bc5890d8b5 Add version suffix git. 2015-10-29 15:46:02 +01:00
Klaas Freitag ee65315520 Merge branch '2.0.2' into 2.0
Conflicts:
	ChangeLog
2015-10-29 15:44:56 +01:00
Roeland Jago Douma 12f7cfde87 Shares do not have parents
Also some pointer cleanups
2015-10-29 15:42:25 +01:00
Roeland Jago Douma 6d80f3d756 Proper foreach 2015-10-29 15:42:25 +01:00
Roeland Jago Douma b32f752d31 Properly cleanup OCS jobs 2015-10-29 15:42:25 +01:00
Roeland Jago Douma cf8be7de91 Proper const usage 2015-10-29 15:42:25 +01:00
Roeland Jago Douma 30a3498c22 Fix typos 2015-10-29 15:42:25 +01:00
Roeland Jago Douma 239603e24c Make sure enforced passwords are properly respected
Fixes for old and new servers
2015-10-29 15:42:25 +01:00
Roeland Jago Douma 390daed3de Added getPublicUpload to LinkShare
so the gui does not have to know abou the internal permissions
2015-10-29 15:42:25 +01:00
Roeland Jago Douma 918c06aba3 Add share manager and the share objects 2015-10-29 15:42:20 +01:00
Klaas Freitag 726be08917 Revert "Config: Use monochrome icons per default on MacOSX."
This reverts commit 546cab3f62.
For OEMs this patch causes an empty tray icon set.
2015-10-29 15:37:31 +01:00
Olivier Goffart a127debc54 Quota: handle special negative value for the quota #3940
Don't show a progress bar if there is an unkown or unlimited total
2015-10-29 14:33:29 +01:00
Olivier Goffart 6aa26654f6 Merge remote-tracking branch 'origin/2.0' 2015-10-29 12:44:28 +01:00
Olivier Goffart 0fde7f0e6b Propagator: Keep a meaningfull error with old server and invalid file names
We changed the discovery code not to ignore files whose filename contains
charachter invalid on windows. (Because newer versions of the server
supports them)
Servers older than 8.1 will just say "Bad Request" as an error and it's a
regression against previous client version. So keep nice error even with
older server.

Relates to #3736
2015-10-29 12:44:08 +01:00
Christian Kamm d9f8edd259 Hidden files: Consider .* hidden everywhere #4023
This seems to be the only place where we did this only on
non-windows OSes.
2015-10-29 11:59:46 +01:00
ckamm 251679253a Merge pull request #3951 from ckamm/checksum
Checksums stored in database #3735
2015-10-29 10:40:24 +01:00
Christian Kamm 64756c5dce --version also shows Qt version
That makes it much easier for people reporting bugs.
2015-10-29 09:48:36 +01:00
Christian Kamm 9788055147 Propagator: Add blacklisting of disk space errors #2939 2015-10-29 09:36:59 +01:00
Jenkins for ownCloud 4d7fde59c2 [tx-robot] updated from transifex 2015-10-29 02:18:59 -04:00
Daniel Molkentin 4737c16996 State application name in update notification
Fixes #4020
2015-10-28 20:45:57 +01:00
Markus Goetz c97dfbf60c ChangeLog: Mention propagator removal 2015-10-28 17:03:47 +01:00
Christian Kamm 496b1e907d Checksum: Don't lose it on metadata update #3735
Also improve tests.
2015-10-28 14:49:55 +01:00
Christian Kamm 566131209d Checksum: Fixes after review 2015-10-28 14:46:20 +01:00
Christian Kamm b7823dc648 Checksum: Put checksum type into separate column #3735 2015-10-28 14:46:20 +01:00
Olivier Goffart 6d28a1b645 Fix Qt4 compilation 2015-10-28 13:26:35 +01:00
Markus Goetz b6aa18bfbc sync-exclude.lst: More likely matching files first 2015-10-28 11:25:02 +01:00
Markus Goetz d91ffc216a Exclude: Add .fuse_hidden #3999
No matter if we sync hidden files or not, those are files we should not sync
2015-10-28 11:18:44 +01:00
Markus Goetz a6c9e8c5b4 Merge branch 'kill_legacy_propagator' 2015-10-28 11:06:50 +01:00
Markus Goetz 9337927722 legacy propagator: Remove more code 2015-10-28 10:59:02 +01:00
Christian Kamm c81b02c7d9 csync tests: Remove unused function 2015-10-28 10:04:15 +01:00
Christian Kamm 5ea09d2668 Checksum: Disallow ADLER32, use Adler32 #3735 2015-10-28 09:59:33 +01:00
Christian Kamm b9fc4c5994 Checksum: Fix recomputation when forced in cfg file #3735
Don't recompute the checksum on each upload when the server does not
advertise supporting checksums.
2015-10-28 09:56:39 +01:00
Christian Kamm f1b500d3e0 Checksum: Add env variables to disable #3735 2015-10-28 09:56:39 +01:00
Christian Kamm dff37e11eb Propagate: Store computed checksums in db during upload #3735 2015-10-28 09:56:39 +01:00
Christian Kamm b1387f801b Propagate: On download store checksum header in db #3735 2015-10-28 09:56:39 +01:00
Christian Kamm 60b2312ab6 SyncJournal: Add checksumHeader column to metadata table #3735 2015-10-28 09:56:39 +01:00
Christian Kamm 0354289795 Checksums: Improvement in async computation and validation #3735 2015-10-28 09:56:39 +01:00
Christian Kamm c11c35c459 Revert "In case of empty checksum type, emit validated."
This reverts commit b05ca526a4.

The checksum type setting should not matter for downloads.
2015-10-28 09:56:39 +01:00
Christian Kamm 7c5e70ac3c PropagateUpload: Fix double-emission of finished #3844 2015-10-28 09:53:54 +01:00
Christian Kamm d2e5ba123d Fix compile after pull request merge
It conflicted with the optimization in
f18b40f7e7
2015-10-28 09:53:06 +01:00
Klaas Freitag 0c9568f6dc Merge pull request #4004 from owncloud/fix_hidden_detection
Fix hidden detection
2015-10-28 09:28:35 +01:00
Olivier Goffart f1d48a9356 Folder Model: The item needs to be selectable for the currenIndex to appear selected
And we set the current index in AccountSettings::slotLinkActivated
2015-10-27 17:37:12 +01:00
Olivier Goffart 89f2a9e6dc Account Settings: A link should make sure all the parents are expanded 2015-10-27 17:37:12 +01:00
Klaas Freitag a203da3919 FolderStatusModel: Check for null argument at start. 2015-10-27 17:37:12 +01:00
Klaas Freitag 1c1ef52cf1 AccountSettings: Display a link for undecided dirs in the sub text.
This only works in case the index is known. If not, no link is
shown, but we wait for the next update of the model.
2015-10-27 17:37:12 +01:00
Klaas Freitag 40c82c5c36 AccountSettings: Add index to undecided folder to be able to select it. 2015-10-27 17:37:12 +01:00
Klaas Freitag 81f0c6535e Enable external links in the label. 2015-10-27 17:37:12 +01:00
Klaas Freitag 46558d79a5 Add slot to handle clicks on folder names. 2015-10-27 17:37:12 +01:00
Olivier Goffart e86b4203b9 IgnoreFiles: Fix the socket API would not load the new custom ignored files #3496
We did not flush or closed the file after having modified it from the UI.
So when the socket api was reloading it, it wouldn't be able to load
the newly added rules
2015-10-27 16:07:59 +01:00
Olivier Goffart 05dd9554f9 SocketApi: Fix returning ignore for the root item all the time 2015-10-27 16:06:38 +01:00
Olivier Goffart 30a0423f81 Dolphin integration: fix error icons 2015-10-27 15:19:10 +01:00
Olivier Goffart 26e1223f9a FolderStatusModel: reset also if a folder was renamed #4011 2015-10-27 13:51:56 +01:00
Olivier Goffart 84a04de7be Settings Dialog: don't put padding on the toolbar extension
Otherwise the extension just disapear with some styles (see Issue #3795)
2015-10-27 13:42:25 +01:00
Olivier Goffart 3ff7fa0092 Merge pull request #3997 from owncloud/phil-davis-patch-1
ChangeLog 2.0.2 minor typos for 2.0 branch
2015-10-27 12:58:59 +01:00
Olivier Goffart 3f2a2cb14b FolderDelegate: put the progressbar in place of the remote or local folder #3403 #3569
So the size of the delegate does not change
2015-10-27 12:52:33 +01:00
Olivier Goffart fac00348d9 Use the term folder sync connection in more places #3757 2015-10-27 12:12:21 +01:00
Olivier Goffart 3c93fd4fb7 AccountSettings: don't disable pause when offline (#4010) 2015-10-27 10:32:33 +01:00
Klaas Freitag 6b71273380 Discovery: Fix detection of hidden files.
In the discovery phase we want to detect that dot-files are hidden
on Linux and Mac.

This fixes strange behaviour seen in issue #3980
2015-10-26 14:24:05 +01:00
Olivier Goffart dccf4e9c34 Download: Soft errors for error while resuming (#4000) 2015-10-26 12:31:07 +01:00
Olivier Goffart 39289a3164 SocketAPI: don't trim the command #3297 2015-10-26 10:15:50 +01:00
Jenkins for ownCloud 6611d878ea [tx-robot] updated from transifex 2015-10-25 02:19:01 -04:00
Jenkins for ownCloud c3fc711095 [tx-robot] updated from transifex 2015-10-24 02:18:59 -04:00
Olivier Goffart 84f1bdbc87 Folder::wipe: We need to shut the socket API down before removing the DB
Because the DB stays open and locked.

Should fix #3824
2015-10-23 17:43:01 +02:00
Phil Davis 2eb5715599 ChangeLog 2.0.2 minor typos for 2.0 branch
These changes were committed to 2.0.2-rc1 branch https://github.com/owncloud/client/pull/3957/files https://github.com/owncloud/client/commit/6da2139a1bc4069f1cd1dfb017502f089c3af26f but that branch was never merged up into 2.0 (or 2.0.2-rc2) so the changes never went anywhere.

These changes could also be applied on 2.0.2-rc2 and 2.0.2 branch for completeness - then they would be in every branch in which they have appeared.
2015-10-23 21:21:31 +05:45
Olivier Goffart c93defc82d SyncEngine: remove unused functions 2015-10-23 17:11:19 +02:00
Olivier Goffart bd39c64798 Delete all files: make the 'Keep' on by default
On windows, we need to specify at least one AcceptRole.
Otherwise the DestructiveRole might become the default

Issue #3824
2015-10-23 17:06:14 +02:00
Olivier Goffart 42a6b242c7 SettingsDialog: use QWidgetAction for the toolbar so the extension works
When the toolbar is full because there is no enough room, make the extension
of the toolbar work, by using QWidgetAction::createWidget instead of
QToolBar::insertWidget

There should not be prolem when the window is too narrow.

Relates #3832
2015-10-23 16:23:37 +02:00
Markus Goetz e5570c24f2 Merge pull request #3995 from owncloud/return-code-of-version-and-help
owncloudcmd: Make returncode 0 for --version and --help
2015-10-23 15:36:01 +02:00
Joas Schilling 6d87bd15cd Make returncode 0 for --version and --help 2015-10-23 15:17:29 +02:00
Olivier Goffart d657c00b11 FolderStatusModel: fix getting the size of the folder in the selective sync (#3986)
Regressed since d610693af1. The problem
is that the _size vector contains the pathToRemove and that it was removed
before.
Reorganize a bit the code so there is only one loop that has still all the
 information.
2015-10-23 15:13:15 +02:00
Jenkins for ownCloud 6fae06f1d0 [tx-robot] updated from transifex 2015-10-23 02:19:00 -04:00
Olivier Goffart f18b40f7e7 csync_vio: reuse the information from readdir in stat
On unix we don't safe much (otherwise csync would have been
designed differently).
On windows however, the readdir already fetch all the info, so we
can as well use it.

We still have to query for the file id but we might optimize that later
2015-10-22 18:46:41 +02:00
Olivier Goffart 6a0633083d Network Settings: Adjust the bandwidth limit option with old Qt
- Disable the whole group box
- Add a tooltip explaining why it is disabled
- Make sure it is disabled in the settings in case of upgrade
- Do a runtime check in case the running Qt is greater
2015-10-22 17:57:34 +02:00
Daniel Molkentin 899f52be4f Revert "Settings dialog: remove the close button #3713"
This reverts commit ebee6f0bc2.

Unix window managers do not have a reliable way of hinting buttons,
so we need the close button.
2015-10-22 16:20:59 +02:00
Olivier Goffart 91525a7d33 csync_exclude: Don't ignore invalid char client side (#3736)
If the server does not support it, then the server will reply with an error
2015-10-22 12:32:53 +02:00
Olivier Goffart 455c3ae57d test/CMakeLists.txt: remove comments 2015-10-22 12:32:53 +02:00
Jenkins for ownCloud b5390b5aa2 [tx-robot] updated from transifex 2015-10-22 02:19:02 -04:00
Olivier Goffart a608b4e9e0 Folder: set csync verbosity to 0 if the Logger is not there
csync_log was still accounting for 8% of the local discovery (because
of vsnprintf and asprintf)
2015-10-22 01:13:35 +02:00
Olivier Goffart f6a543ada3 Logger: speedup the sync discovery when the log is innactive
The sync throw a lot of log message, and QDateTime::fromCurrentTime is
quite expensive. So don't call it if it's not needed.
2015-10-22 00:22:25 +02:00
Daniel Molkentin c7bf09c3d4 Merge remote-tracking branch 'origin/2.0' 2015-10-21 18:49:58 +02:00
Daniel Molkentin c8ae54d9e8 Merge pull request #3982 from owncloud/20-update
update 3-dot menu
2015-10-21 18:49:38 +02:00
Carla Schroder daf6d8772f update 3-dot menu 2015-10-21 09:44:38 -07:00
Olivier Goffart c80e72da83 Sharing: change coding style of enum
From all upper case to camel case

This hopefully fix the Windows build which fails because DELETE seems
to be a macro
2015-10-21 18:40:04 +02:00
Roeland Douma ec351e00ad Merge pull request #3773 from owncloud/split_sharedialog
Split sharedialog code
2015-10-21 16:55:59 +02:00
Olivier Goffart cf242871ea SyncEngine: keep a static pointer to the codec
The QTextCodec for UTF-8 is not going to change during the application life time.
So no need to look it up for every file
2015-10-21 16:38:26 +02:00
Olivier Goffart 597d36dcf2 csync_statedb: Use the index in csync_statedb_get_below_path
Make an index from the path, and make a query that uses the index
2015-10-21 16:38:26 +02:00
Olivier Goffart 9c388787bb csync_update: Don't fetch the etag in the local discovery from the DB
We don't need it, and it's slow.
This saves a lot of DB queries

(Also replaced a strlen>0 with a faster check)
2015-10-21 16:38:26 +02:00
Markus Goetz f739d8fdd3 sqlite: Update to version 3.9.1
For OS X and Windows.
This is in line with the tests/benchmarks Olivier is doing on ArchLinux.
2015-10-21 15:55:41 +02:00
Daniel Molkentin 78d782601e 2.0.2 final 2015-10-21 09:54:02 +02:00
Daniel Molkentin 86a83dc32c Finalize ChangeLog, adjust formatting 2015-10-21 09:53:34 +02:00
Daniel Molkentin c67e53c7b2 set version suffix back to git 2015-10-21 09:48:18 +02:00
Jenkins for ownCloud 5659e04e89 [tx-robot] updated from transifex 2015-10-21 02:19:02 -04:00
Olivier Goffart 8ff3055b47 sync-exclude.lst: Remove entries that are hardcoded anyway
The more item in the sync-exclude.lst, the slower is the sync.
Many items are already hardcoded. Some are files that no longer
exist.
2015-10-20 18:38:47 +02:00
Olivier Goffart 71827549d6 csync_exclude: Use PathMatchSpecA instead of PathMatchSpecW
So we avoid lots of memory allocation.
We can work with char* directly since both the pattern and the file
name are in UTF-8 and there is no need to understand unicode for
such pattern.

(In fact, '?' would not match anyore non-ascii characters, but I
don't think that's a problem. I don't think anyone use '?' in its
exclude list. And the two allocations per call to csync_fnmatch are
really worth getting rid of)
2015-10-20 18:38:47 +02:00
Olivier Goffart de5de7acc5 csync_exclude: Optimize
Avoid alocations as much as possible
2015-10-20 18:38:47 +02:00
Markus Goetz c8590c4468 Remove legacy propagator and neon
The code was already uneeded/unbuilt on Windows and OS X.
2015-10-20 17:57:43 +02:00
Markus Goetz 5f43c9cfad Merge tag 'v2.0.2-rc2' into 2.0
Second RC of ownCloud Client 2.0.2
2015-10-20 15:46:09 +02:00
Markus Goetz 98b966d274 OS X: Use Cocoa Pasteboard instead of QClipBoard #3300 2015-10-20 15:42:43 +02:00
Olivier Goffart 674b6f2373 Account Settings: clear the focus of the "Sign In" button when clicked
So that the focus does not go to the "Remove Account" button instead
which would be wierd
2015-10-20 13:56:35 +02:00
Olivier Goffart 407ff0a99d Theme: cache the QIcon::fromTheme
We are calling that every time we draw the folder delegate.
Which is a lot when the sync is runing and the progress bar is moving
2015-10-20 13:24:11 +02:00
Olivier Goffart 0b6d21e3d5 Logger: don't call qFormatLog when unessesary
That's a lot of string operations that can be avoided if the log window
is not shown
2015-10-20 13:22:48 +02:00
Markus Goetz 4c9bc42b69 Revert libqsqlite changes for now
QtWebKit depends on it unfortunately
2015-10-20 13:04:33 +02:00
Olivier Goffart 557b704069 Fix compilation warning
shibbolethcredentials.h:59:10: warning: 'askFromUser' overrides a member
function but is not marked 'override' [-Winconsistent-missing-override]
2015-10-20 11:35:25 +02:00
Klaas Freitag d09de79491 Bump version to RC2 2015-10-20 11:30:00 +02:00
Olivier Goffart 4369e31a49 Folder Model: don't try to fetch data if the account is disconnected
Now that it expands automatically, it would do lots of query to the
server when the account is disconnected. (all resulting in 401)
2015-10-19 18:32:34 +02:00
Olivier Goffart 23b5a74c17 Account Settings: Don't expand while clicking on the '...' button 2015-10-19 18:23:56 +02:00
Olivier Goffart ee69ab2021 Account Settings: Don't disable double click expanding for sub folders
The root folder open on simple click,  but the sub folder don't, so keep
this behaviour which is the native behaviour
2015-10-19 18:12:49 +02:00
Olivier Goffart 374f29c4d3 Account Settings: Fix crash for acocunts withour folder
Was broken by  027a865fbc
2015-10-19 18:08:11 +02:00
Markus Goetz 67910e7d60 Discovery: Call it "Checking for changes in" in UI
For #3431
2015-10-19 15:59:16 +02:00
Markus Goetz c80b033466 VERSION.cmake: fixup 2015-10-19 15:57:13 +02:00
Olivier Goffart 671af9f8fe Merge branch 'master' 2015-10-19 15:53:58 +02:00
Olivier Goffart 6ea05ff6e3 Dolphin shell integration: use the owncloud icons 2015-10-19 15:53:40 +02:00
Markus Goetz 00485e133f VERSION.cmake: This is git not rc1 2015-10-19 15:51:33 +02:00
Olivier Goffart c520ee4eab Dolphin Shell Extension: renamove the kf5 in the name 2015-10-19 15:43:42 +02:00
Olivier Goffart 5408ec79f7 Dolphin shell extention: Remove the KDE4 based plugin 2015-10-19 15:42:41 +02:00
Olivier Goffart f8e68ae823 Merge branch 'dolphin-plugin' 2015-10-19 15:41:47 +02:00
Olivier Goffart 184412d88e Dolphin shell integration: Renames the plugins
And put the helper in a shared library so it is shared accross both plugins
2015-10-19 15:40:11 +02:00
Olivier Goffart 82d1d04774 Dolphin shell integration: share code between two plugins 2015-10-19 15:40:11 +02:00
Olivier Goffart 731d4b3d4d Dolphin shell extention: adapt to the change in KDE Frameworks 2015-10-19 15:39:51 +02:00
Markus Goetz ccec186b98 ETagJob: Depth 0 for server >= 8.1 #3730 2015-10-19 15:31:27 +02:00
Klaas Freitag c66c259447 SettingsDialog: Add new widet called ActivityWidget.
This is the new widget to display server activity.
2015-10-19 14:41:53 +02:00
Klaas Freitag 4ad165ce26 Utility: add method fileNameForGuiUse(), pimp up filename for GUI
Currently, this one only replaces colons by / on Mac platform. This makes
the function resuseable.
2015-10-19 14:36:55 +02:00
Markus Goetz 24a801dfd3 CMake/NSIS: We don't need QtSql (more) 2015-10-19 13:56:36 +02:00
Markus Goetz af79bc9211 CMake/NSIS: We don't need QtSql
The NSIS change also had a redundant libsqlite3 DLL entry
2015-10-19 13:46:46 +02:00
Klaas Freitag a3904f4d32 Theme: Revert logic of singleAccount switch.
To use the same logic as the other clients and unify ownBrander
implementations, the switch is now called multiAccount() rather
than singleAccount() with a reverse logic.
Desktop Client stays with the default of having multiaacount
enabled.

Note that existing brandings need to rename the switch.

https://github.com/owncloud/ownbrander/issues/443
2015-10-19 12:26:42 +02:00
Olivier Goffart 5cac90b3eb SelectiveSyncTreeView: show the size for the root item (#3755) 2015-10-19 10:58:54 +02:00
Olivier Goffart df135a0bb2 Merge branch '2.0'
Conflicts:
	src/gui/folder.cpp
2015-10-19 10:57:37 +02:00
Olivier Goffart b7c927f349 csync: Fix warning the bit field need to be unsigned 2015-10-19 10:13:11 +02:00
Jenkins for ownCloud 64718fe567 [tx-robot] updated from transifex 2015-10-19 01:15:39 -04:00
Jenkins for ownCloud 79f14e0933 [tx-robot] updated from transifex 2015-10-18 01:15:40 -04:00
Jenkins for ownCloud 3ad8c692a4 [tx-robot] updated from transifex 2015-10-17 02:19:01 -04:00
Klaas Freitag 546cab3f62 Config: Use monochrome icons per default on MacOSX. 2015-10-16 18:55:07 +02:00
Roeland Jago Douma 4a04dc1a3e Typos 2015-10-16 12:51:24 +02:00
Roeland Jago Douma 0e97fbb730 Use overloaded functions 2015-10-16 12:48:48 +02:00
Olivier Goffart 83edb7fb8a csync: fix compilation error with -pedentic 2015-10-16 11:45:36 +02:00
Olivier Goffart 0c59c85127 SyncEngine: Folders with ignored files should not count when counting none files
If there is a any none files, we do not show the dialog saying that all
files have been removed. If a directory contiains ignored files, we still
want to show this message box even if the directory will not be deleted
2015-10-16 11:43:52 +02:00
Klaas Freitag d6098c39dc Update Changelog and bump version to 2.0.2rc1 2015-10-16 11:12:50 +02:00
Klaas Freitag af721118cd Merge branch '2.0' of github.com:owncloud/mirall into 2.0 2015-10-16 10:08:27 +02:00
Markus Goetz 0d5f2b5d31 Propagator: Reset upload blacklist if a chunk suceeds
For #3934
2015-10-16 10:06:45 +02:00
Klaas Freitag 1790a128aa Merge tag 'v2.0.1' into 2.0
Version 2.0.1
2015-10-16 10:06:38 +02:00
Olivier Goffart 87fa1794a1 Updater: remove unused function
It was even throwing a warning because it is an infinite recursion
2015-10-16 09:56:26 +02:00
Olivier Goffart 4df828d0b0 csync_file_stat_s: Save a bit of memory 2015-10-16 09:56:26 +02:00
Hugo Gonzalez Labrador 4d1d6dff3b Increased fileID size to 36 bytes
This is the size used by UUIDs
2015-10-16 09:27:19 +02:00
Olivier Goffart 81e30cd8d2 Merge pull request #3695 from owncloud/nomkpath3692
Folder: Do not create the sync folder if it does not exist #3692
2015-10-16 09:21:15 +02:00
Markus Goetz 983671c8cb Shibboleth: Add our base user agent to WebKit
For #3913
2015-10-16 09:15:47 +02:00
Roeland Jago Douma 40ab3ee751 Now only 1 constructor to ocssharejob
* Pass the share_id to the functions that need it
2015-10-16 08:28:13 +02:00
Jenkins for ownCloud eb6b254dc5 [tx-robot] updated from transifex 2015-10-16 02:19:02 -04:00
Roeland Jago Douma f95fea9866 Move permissions to OcsShareJob 2015-10-16 08:09:57 +02:00
Roeland Jago Douma 03719334ea Remove unused members 2015-10-15 22:27:55 +02:00
Roeland Jago Douma 4441053b1c Thumbnailjob fixes
* Comments
* Use the path of the abstractnetworkjob
2015-10-15 22:18:22 +02:00
Roeland Jago Douma a34b663828 Now add parameters in a less crappy way 2015-10-15 21:58:16 +02:00
Roeland Jago Douma db1f4d4016 OCSJob -> OcsJob and more docs 2015-10-15 20:54:52 +02:00
Roeland Jago Douma 3ea944d1b3 Added setPublicUpload to OcsShareJob 2015-10-15 20:34:56 +02:00
Roeland Jago Douma b293aa762c Split sharing code
There is now a generic OCSJob which must be inherited by other jobs. This is in
prepartion for the other OCS job that will come (for the Sharee API endpoint
for example).

More logic is moved from the sharedialog to the OcsShareJob. So in the GUI code
we now only say what we want (a new share, set the password etc). And the code
in libsync will make that happen. Error handling is for now still done in the
GUI part.

For now the ocsjob and ocssharejob live in gui but probabaly we should
create a libshare or libocs at some point.
2015-10-15 20:05:47 +02:00
Markus Goetz b5e75afc17 General settings: Align checkbox #3758 2015-10-15 19:15:50 +02:00
Markus Goetz 027a865fbc Account Settings: Show selective sync buttons after list load
Especially nice when having a slower network.
For #3839
2015-10-15 18:52:16 +02:00
Markus Goetz 132b5f5130 Account Settings: Expand selective sync on show #3585 2015-10-15 17:27:38 +02:00
Markus Goetz c3754e1fdd folderstatusmodel.h: Fix warning 2015-10-15 17:27:29 +02:00
Markus Goetz 963eb1f29b VERSION.cmake: master is 2.1 2015-10-15 16:51:29 +02:00
Christian Kamm c418d67920 Merge remote-tracking branch 'origin/2.0' 2015-10-15 15:54:09 +02:00
Christian Kamm 6e09e3af86 Fix test compile
I regularly fix errors in the copies of the test sources that are
made in build/. Refactoring how these tests work could be worthwhile.
2015-10-15 15:52:58 +02:00
Christian Kamm 67e9a06d30 Progress estimation: Adjust low-transfer detection #3942
Progress estimation is usually based on transfer speed. That makes no
sense when we're doing operations like deletes, that need very little
data transfer but nevertheless take a long time.

This hack attempts to detect this case better and switches to a
different estimate.

We should rewrite this to maintain and update estimates for the
transfer speed, per-file overhead and chunk-assembly overhead each
time an item finishes. Then we could provide more consistent progress
estimates without ad-hoc fixes like this one.

Also, there's an issue where resuming a partial download will lead
to exaggerated transfer speed estimates.
2015-10-15 15:04:11 +02:00
Christian Kamm abd63035c1 ETag: Allow parsing of weak tags #3946 2015-10-15 14:57:34 +02:00
Markus Goetz 745cf55abb SelectiveSync: Increase folder list timeout to 60
Already done for 2.1 in 05eee16959
For #3524
2015-10-15 14:43:11 +02:00
Olivier Goffart e1c634d000 Don't show the settings if another instance is started less than 10 secs after the apps.
Issue #3273

isSessionRestored was not set correctlty so ignore it
2015-10-15 14:25:23 +02:00
Jenkins for ownCloud 49a3a3ba7b [tx-robot] updated from transifex 2015-10-15 02:19:02 -04:00
Carla Schroder 9982211ced Merge pull request #3950 from owncloud/revert-3931-phil-davis-3dot-menu-doc-20
Revert "Update "..." menu documentation for 2.0"
2015-10-14 09:04:06 -07:00
Carla Schroder 10f59bf3ad Revert "Update "..." menu documentation for 2.0" 2015-10-14 09:03:08 -07:00
Roeland Douma df2418d9c5 Merge pull request #3661 from rullzer/public_upload
Allow setting of public upload on link shares
2015-10-14 15:34:25 +02:00
Roeland Jago Douma 2fdae6d72f Allow setting op public upload on link shares 2015-10-14 15:30:28 +02:00
Roeland Jago Douma 05471d0acd Also parse capabilitie for public uploads 2015-10-14 15:30:23 +02:00
Christian Kamm 05eee16959 SelectiveSync: Show in-progress label #3524
We now show 'Fetching data...' after a second.

This also increased the timeout to 60s, making the error
condition much less likely.
2015-10-14 13:05:53 +02:00
Roeland Douma a752eadd0f Merge pull request #3923 from owncloud/check_shareapi_available
Provide information about share availablity for files
2015-10-14 12:38:03 +02:00
Roeland Jago Douma 028dc8d6c3 Add SHARE_STATUS socketAPI command
This command allows to retrieve the share status of a file. In other
words if it can be shared.
2015-10-14 12:36:32 +02:00
Roeland Jago Douma 4a7242c8f9 Extended capabilities API
* Naming of capabilities is now a bit more consistent
2015-10-14 11:45:34 +02:00
Christian Kamm efdb29d2f9 AccountSettings: Show disabled 'Add Folder' tooltip on click #3645 2015-10-14 11:34:30 +02:00
Jenkins for ownCloud 7487d02a70 [tx-robot] updated from transifex 2015-10-14 02:19:00 -04:00
Christian Kamm 225da68832 ExcludedFiles: Add test 2015-10-13 15:01:59 +02:00
Christian Kamm 51a2e6c580 Exclusion: Fix confusion with relative and absolute paths 2015-10-13 12:53:38 +02:00
Christian Kamm 7fe03c715d SelectiveSync: Don't adjust removed path 2015-10-13 12:37:27 +02:00
Jenkins for ownCloud c39f6c3fae [tx-robot] updated from transifex 2015-10-13 02:19:01 -04:00
Jenkins for ownCloud f4365dcca0 [tx-robot] updated from transifex 2015-10-12 02:18:57 -04:00
Jenkins for ownCloud fd75d5c679 [tx-robot] updated from transifex 2015-10-11 02:18:57 -04:00
Jenkins for ownCloud 014a53f990 [tx-robot] updated from transifex 2015-10-10 02:19:00 -04:00
Klaas Freitag 419d18c128 FileSystem: Reuse the FileInfo object that is created in the caller.
With that, a lot of stats can be avoided, ie. in SocketAPI
2015-10-09 13:02:02 +02:00
Jenkins for ownCloud da76ba6c64 [tx-robot] updated from transifex 2015-10-09 02:18:57 -04:00
Jenkins for ownCloud afeb9e07e2 [tx-robot] updated from transifex 2015-10-09 01:15:36 -04:00
Klaas Freitag 74a7755ad9 SocketAPI: String concat optimization as learned on QtWS. 2015-10-08 18:26:30 +02:00
Klaas Freitag c1ba927b37 Propagatorjobs: Removed superflous semicolon. 2015-10-08 16:20:42 +02:00
Daniel Molkentin f22535e18a Merge pull request #3931 from owncloud/phil-davis-3dot-menu-doc-20
Update "..." menu documentation for 2.0
2015-10-08 08:53:41 +02:00
Phil Davis 0f4e88eeaa Update "..." menu documentation for 2.0
This menu in 2.0.* now has 4 options.
The small screenshot needs updating also. @carlaschroder it is probably best if you take a new screen shot from whatever client version you have been using for screen shots. That way they will all have a consistent look.
2015-10-08 12:28:15 +05:45
Jenkins for ownCloud 70476c332a [tx-robot] updated from transifex 2015-10-08 02:18:57 -04:00
Klaas Freitag a8eb913535 SyncLogDialog: Do not delete SyncLogDialog after close.
Keep one instance for the lifetime of the generalsettings widget.
2015-10-07 18:59:48 +02:00
Jenkins for ownCloud 79145ff9fd [tx-robot] updated from transifex 2015-10-07 02:19:00 -04:00
Jenkins for ownCloud a0eb4b9c85 [tx-robot] updated from transifex 2015-10-07 01:15:35 -04:00
Klaas Freitag cb3a301f2c Merge pull request #3899 from sebasje/sebas/cmake
fix multiarch library path for Debian/Ubuntu
2015-10-06 15:36:43 +02:00
Klaas Freitag 6d6903ef62 Merge pull request #3919 from phil-davis/libsynctypos
libsync comment and message typos for master
2015-10-06 14:49:54 +02:00
Klaas Freitag f5daf50dc4 Merge pull request #3920 from phil-davis/guitypos
GUI comment and message typos for master
2015-10-06 14:46:00 +02:00
Klaas Freitag f6631443a1 Merge pull request #3922 from RealRancor/backport_3916_2.0
Backport #3916 to 2.0 - thanks
2015-10-06 14:42:40 +02:00
Jenkins for ownCloud 87ad4dd264 [tx-robot] updated from transifex 2015-10-06 02:18:57 -04:00
Jenkins for ownCloud bb289f63f1 [tx-robot] updated from transifex 2015-10-06 01:15:38 -04:00
RealRancor 67a71ff10f Backport #3916 to 2.0 2015-10-05 16:22:11 +02:00
Phil Davis b8ccbbc72a GUI comment and message typos for master 2015-10-05 10:06:19 +05:45
Phil Davis f0e17fd9c0 libtypos comment and message typos for master 2015-10-05 09:05:09 +05:45
Klaas Freitag b09f1d591c Merge pull request #3916 from RealRancor/fix_rst_syntax
Fix linkname in architecture.rst.
2015-10-04 17:59:45 +02:00
Jenkins for ownCloud 6b1bfb4474 [tx-robot] updated from transifex 2015-10-04 02:18:56 -04:00
RealRancor 8fd2b8d829 Fix linkname in architecture.rst. 2015-10-03 21:42:23 +02:00
Jenkins for ownCloud 8158984ad6 [tx-robot] updated from transifex 2015-10-03 02:19:01 -04:00
Jenkins for ownCloud 7b61bcfe10 [tx-robot] updated from transifex 2015-10-03 01:15:41 -04:00
Christian Kamm d610693af1 SelectiveSync: Apply excludes #3876 2015-10-02 15:56:39 +02:00
Christian Kamm 7d1886684e FolderWatcher: Use csync exclude code #3805
Introduce a global ExcludedFiles instance to avoid loading the global
exclude lists several times.

One could still add per-folder exclude lists by checking these after
the global ones.
2015-10-02 15:56:39 +02:00
Christian Kamm 95fc792745 Tray: Change texts #3657 2015-10-02 15:48:44 +02:00
Christian Kamm efefc2d986 Merge branch '2.0'
Conflicts:
	doc/images/menu.png
	doc/images/settings_network.png
2015-10-02 15:44:50 +02:00
Christian Kamm 9f8d109a7e Network errors: Use exception name, if message is empty #2718 2015-10-02 15:25:34 +02:00
Christian Kamm cf9e5ffb0b Remove dead code
no_recursive_propfind does not exist anymore.
2015-10-02 15:17:19 +02:00
Christian Kamm 3cbd63a77a Propagation: Try another sync on 423 Locked #3387
(cherry picked from commit 24c41ed0da)
2015-10-02 14:49:38 +02:00
Christian Kamm 62eeed5201 Propagation: Make 423 Locked a soft error #3387
(cherry picked from commit 20ea9015ca)
2015-10-02 14:49:30 +02:00
Christian Kamm 1383023b2e Fix the Qt4 build. 2015-10-02 11:05:15 +02:00
Jenkins for ownCloud 9558822a7c [tx-robot] updated from transifex 2015-10-02 02:19:01 -04:00
Klaas Freitag afd081f40b Settings: Move synclog widget to a seperate dialog.
This a first step to integrate the server activity view, see #3732
2015-10-01 16:57:37 +02:00
Christian Kamm 7bf31e56ab Ignores: Sync after update #3876 2015-10-01 15:39:28 +02:00
Christian Kamm 3812fd0866 Checksums: Prepare 'supported checksums' capability #3735
It currently always returns the empty list and thus has no effect.
2015-10-01 15:00:33 +02:00
Christian Kamm 24c41ed0da Propagation: Try another sync on 423 Locked #3387 2015-10-01 13:05:07 +02:00
Christian Kamm 36e8e9ebf5 Propagator: Download disk space checks #2939
* There's a critical 50 MB threshold under which syncs abort
  (OWNCLOUD_CRITICAL_FREE_SPACE)
* The sync client always keeps 250 MB free
  (OWNCLOUD_FREE_SPACE)
2015-10-01 12:59:05 +02:00
Christian Kamm 12dc372b21 Sync: An initial diskspace check #2939
* Before each sync, check that there are at least
  250 MB of space available and abort otherwise.
* Can be overridden with OWNCLOUD_MIN_FREE_SPACE
2015-10-01 10:25:35 +02:00
Jenkins for ownCloud d8c5e58fa1 [tx-robot] updated from transifex 2015-10-01 02:18:59 -04:00
Christian Kamm 20ea9015ca Propagation: Make 423 Locked a soft error #3387 2015-09-30 14:00:53 +02:00
Klaas Freitag 0c148025a3 SyncLog Dialog WIP 2015-09-30 12:02:05 +02:00
Christian Kamm d0c2ce276a Application: Fix crash on early shutdown #3898 2015-09-30 11:40:33 +02:00
Jenkins for ownCloud 9e813c7dcf [tx-robot] updated from transifex 2015-09-30 02:19:15 -04:00
Klaas Freitag 440687af21 AccountSettings: Disable context menu of sync folders when not connected.
This is the second part to fix #3860
2015-09-29 18:19:26 +02:00
Klaas Freitag 77a9b28e14 SetupWizard: Removed unused member variables. 2015-09-29 09:30:40 +02:00
Jenkins for ownCloud f84654c9b3 [tx-robot] updated from transifex 2015-09-29 02:19:10 -04:00
Sebastian Kügler a7cf1b04ad Simplify creating the library path
Instead of checking whether the library path ends up somewhere in /usr,
set the architecture prefix, anyway. The library path mechanism is also
used in custom prefixes, without this change, the library gets installed
globally on Debian and Ubuntu, leading to non-standard behaviour and
cross-build problems, as multiple architecture builds of this library
can't be installed alongside each other.

This is the minimal change to correct this behaviour from upstream cmake.
2015-09-29 00:15:39 +02:00
Markus Goetz 641dece89a Linux: Don't show settings dialog always when launched twice
For #3273 #3771 #3485
See also d503221b2e
2015-09-28 23:00:19 +02:00
RealRancor 2c9d418423 Fix registry key syntax in FAQ. 2015-09-27 20:38:53 +02:00
Daniel Molkentin a08a90a718 Merge pull request #3892 from RealRancor/fix_faq
Fix registry key syntax in FAQ.
2015-09-27 20:38:13 +02:00
RealRancor 1cb518cb13 Fix registry key syntax in FAQ. 2015-09-27 20:19:06 +02:00
Jenkins for ownCloud a897a1805e [tx-robot] updated from transifex 2015-09-26 02:19:01 -04:00
Jenkins for ownCloud fe88b48fb1 [tx-robot] updated from transifex 2015-09-26 01:15:34 -04:00
Markus Goetz 574c699382 GUI: Change tray menu order #3657 2015-09-26 00:25:06 +02:00
Klaas Freitag 7b97b96115 Merge pull request #3884 from owncloud/fix_3860
AccountSettings: Do not allow to expand folder list when disconnected.
2015-09-25 17:52:39 +02:00
Klaas Freitag e7e0e5b57f win32 vio: Add the OPEN_REPARSE_POINTS flag to the CreateFileW call.
Otherwise win32 api simply does not open reparse points at all,
such as junctions.

This will improve the user experience of #3813 as we now identify
the junctions as symlinks.... and ignore them properly.
2015-09-25 17:36:41 +02:00
Klaas Freitag b72e2b146d AccountSettings: only expand root elements on single click.
Also, toggle expanding on single click for root elements.
2015-09-25 13:57:44 +02:00
Klaas Freitag a1421ff74f AccountSettings: Do not allow to expand the folder list when disconnected.
This is supposed to fix #3860
2015-09-25 12:22:51 +02:00
Klaas Freitag 57f10c0c8e Use application SHORT name for the name of the MacOSX pkg file.
THis is because of https://github.com/owncloud/ownbrander/issues/445
2015-09-24 16:02:08 +02:00
Jenkins for ownCloud 1f5834b74a [tx-robot] updated from transifex 2015-09-23 02:19:00 -04:00
Jenkins for ownCloud 836d7e1e5d [tx-robot] updated from transifex 2015-09-23 01:15:36 -04:00
Carla Schroder 48df009cea Merge pull request #3868 from owncloud/moardocupdates
perty new screenies and updates
2015-09-22 08:22:55 -07:00
Jenkins for ownCloud 6343417def [tx-robot] updated from transifex 2015-09-22 02:19:03 -04:00
Carla Schroder 8c02034838 corrections 2015-09-21 10:19:49 -07:00
Jenkins for ownCloud 290cc58a63 [tx-robot] updated from transifex 2015-09-21 02:18:40 -04:00
Jenkins for ownCloud 5274b2485f [tx-robot] updated from transifex 2015-09-20 02:18:33 -04:00
Jenkins for ownCloud fc95e47790 [tx-robot] updated from transifex 2015-09-19 02:19:12 -04:00
Carla Schroder caaf8c841e perty new screenies and updates 2015-09-18 14:36:00 -07:00
Carla Schroder 6816cdd1c3 Merge pull request #3866 from owncloud/fixpr
restore missing image to fix build failure of PR 3838
2015-09-18 09:09:26 -07:00
Carla Schroder 5f857a49b8 restore missing image to fix build failure of PR 3838 2015-09-18 09:03:32 -07:00
Carla Schroder 70ab7f04b3 Merge pull request #3838 from owncloud/docfixes
move new features to introduction, fix missing images
2015-09-18 08:09:11 -07:00
Christian Kamm c1045af500 FolderMan: Fix for removing a syncing folder #3843
We can't schedule the next folder if we aren't notified that
the removed folder has finished syncing...
2015-09-18 14:34:40 +02:00
Christian Kamm c5c1a7a1c3 ConnectionMethodDialog: Don't be insecure on close #3863 2015-09-18 12:12:53 +02:00
Christian Kamm 4144d4672f Updater: Ensure folders are not removed #3747 2015-09-18 11:59:49 +02:00
Jenkins for ownCloud 9cfa63eed8 [tx-robot] updated from transifex 2015-09-18 02:19:38 -04:00
Carla Schroder 68ed64e11d remove ugly images 2015-09-17 17:44:21 -07:00
Carla Schroder 043655bd7a nice new screenshots from windows pc 2015-09-17 17:41:22 -07:00
Carla Schroder 3ba4e38693 new screenshots and revised installation page 2015-09-16 09:45:50 -07:00
Carla Schroder 25d1defd73 move new features to introduction, fix missing images 2015-09-15 16:34:45 -07:00
Olivier Goffart cac219aca8 Dolphin shell integration: Add a Share with owncloud action 2015-09-10 13:41:45 +02:00
Olivier Goffart a159dfc7ec Dolphin shell integration: Make it work with dolphin master 2015-09-10 13:41:45 +02:00
Daniel Molkentin b7061618b1 Merge pull request #3789 from hh-lohmann/Terminology
/doc/autoupdate.rst: "32-/64-bit" => "32-/64-bit-Windows"
2015-09-10 01:37:10 +02:00
Daniel Molkentin d823809021 Merge pull request #3781 from phil-davis/FSC
Coin the term 'folder sync connection'
2015-09-10 01:35:25 +02:00
hh.lohmann 0329a8be2e /doc/autoupdate.rst: "Migrate to the following directory" => "Edit this Registry key"
Registry keys are no directories; you would not "migrate" to keys if you are just about to switch to them; resembling formulas as "Edit these / this Registry key/s" ease fast reading, for that also ":" instead of "::" at the end (formatting what follows)
2015-09-09 12:33:25 +02:00
hh.lohmann 79f64abfc3 /doc/autoupdate.rst: "32-/64-bit" => "32-/64-bit-Windows"
Should be stated clearly that there are no alternative 32- / 64-bit-ownCloud-Clients, but just a 32-bit-ownCloud-Client that is treated differently in 32- / 64-bit-Windows
2015-09-09 12:10:10 +02:00
Markus Goetz 63636aca9b Merge pull request #3777 from owncloud/individual-it-utf8-patch
fix unicode issue #3753
2015-09-08 16:06:42 +02:00
Phil Davis fdfab07d07 Coin the term 'folder sync connection'
Proposed wording for issue
https://github.com/owncloud/client/issues/3757
2015-09-08 17:22:57 +05:45
Individual IT Services cc5f8e5122 fix unicode issue #3753
fixes the unicode issue #3753

I don't know much CPP and Qt but after some google research I found this http://wiki.qt.io/Strings_and_encodings_in_Qt
it does mention trUtf8() that has done the trick for me on Linux with Gnome 3.16.
Haven't tested it on other systems
2015-09-08 13:59:43 +05:45
Olivier Goffart 21dbf97a02 Merge remote-tracking branch 'origin/2.0' 2015-09-07 10:32:16 +02:00
Olivier Goffart 39bff056a6 Merge remote-tracking branch 'origin/2.0' 2015-09-05 18:14:30 +02:00
Jocelyn Turcotte 128d46e19a Remove *Credentials::_fetchJobInProgress
Now that fetchFromKeychain is solely called from AccountState::slotInvalidCredentials
and that this one already protects the fetch call using _waitingForNewCredentials,
we can remove that extra check.
2015-09-05 16:00:45 +02:00
Jocelyn Turcotte 6d027ebd40 Separate the credential dialog from their fetch #3350
This moves the responsibility of asking the user or not for
credentials from the Credentials classes back to the AccountState.
fetch() now only extract credentials from the keychain, reports
the result to the AccountState which then decides if askFromUser()
should be called or not. The result is once more reported to the
AccounState.

This also replaces the HttpCredentials::queryPassword virtual
which now lets HttpCredentialsGui and HttpCredentialsText do it
the way that they prefer.
2015-09-05 16:00:45 +02:00
Jocelyn Turcotte 89f69209dd Simplify the authentication code paths #3350
The AccountState is now the only class responsible for triggering credentials
fetching from the keychain or from the user.

With the ShibbolethRefresher out of the question it's possible
to remove the invalidateAndFetch virtual and manually call invalidateToken.
This also allows us to move that code from Account to AccountState.
In the end this also allows us to move the fetch() call from the
ConnectionValidator and use the same code path as for invalid credentials.
2015-09-05 16:00:45 +02:00
Jocelyn Turcotte 94a57fe8d5 Get rid of ShibbolethRefresher
This is only for neon and not necessary if we want to show a notification
instead of a login window when the network reports invalid credentials.
2015-09-05 15:45:54 +02:00
Jocelyn Turcotte dcb687929f Show a notification instead of a login window on startup #3350
The original problem is that showing a popup not originated
from the main settings window while it's focused won't be
shown in front to the user.

This try not to highjack the user's attention of the user
by showing a notification when checking the connection for
valid credentials, and require the user to sign in through
the UI. There are still issues with showing that popup from
the tray icon, but the user will most likely be looking for
the popup in that case. The new sign in button directly in
the settings account works properly.
2015-09-01 18:40:20 +02:00
Jocelyn Turcotte 628957de21 Remove the _readPwdFromDeprecatedPlace codepath
This was introduced in 1.6.2 to read the password from earlier versions.
People upgrading from 1.5 to 2.1 will sadly need to re-enter their password.
2015-09-01 18:40:20 +02:00
Jocelyn Turcotte bcfc16c0f6 Add a sign in button in the settings window
It's not obvious for users that they should sign in through
the tray icon, especially if they were automatically signed out.
2015-09-01 18:40:20 +02:00
Olivier Goffart 3ba5e27d02 Merge branch '2.0' 2015-09-01 17:57:56 +02:00
Klaas Freitag 58ea498a62 Update changelogs date and version. 2015-09-01 15:50:21 +02:00
Daniel Molkentin 322288bf6c 2.0.1rc1 2015-08-31 16:39:37 +02:00
Daniel Molkentin 6b7bfc75a8 Update ChangeLog 2015-08-31 16:39:17 +02:00
Daniel Molkentin abe96135ff Bump to 2.0.1 2015-08-31 16:37:22 +02:00
Olivier Goffart 8bf2db27dd AccountWizard: fix when the theme specify a override URL #3699 2015-08-31 16:37:00 +02:00
Olivier Goffart 950bc578d0 Merge branch '2.0' 2015-08-31 14:34:04 +02:00
Olivier Goffart 1f43c47861 Folder: Do not create the sync folder if it does not exist #3692 2015-08-28 14:40:45 +02:00
Carla Schroder ccfcdff190 Merge pull request #3665 from owncloud/2-0updates
1st batch of updates for 2.0
2015-08-27 10:28:03 +02:00
Carla Schroder 45835f1cf9 Update navigating.rst 2015-08-27 10:25:19 +02:00
Carla Schroder cf543d1eb0 Update navigating.rst 2015-08-27 10:20:15 +02:00
Carla Schroder 9f24f10186 Update installing.rst 2015-08-27 10:07:54 +02:00
Carla Schroder bc37668e9f 1st batch of updates for 2.0 2015-08-21 13:19:15 -07:00
Daniel Molkentin 22d87218b7 Merge pull request #3601 from individual-it/master
checking if file or folder is to be shared to fix issue #3556
2015-08-18 11:45:31 +02:00
Markus Goetz 62d64acd7b Merge pull request #3589 from owncloud/sharedir
Use SHAREDIR for i18n dir
2015-08-13 16:02:11 +02:00
Individual IT Services c6ff73f3e5 checking if file or folder is to be shared to fix issue #3556 2015-08-12 21:48:04 +05:45
hefee a87602af3f use SHAREDIR for i18n
SHAREDIR is used in src/gui/application.cpp and should also use that in
CMakeLists.txt.
2015-08-11 15:14:59 +02:00
303 arquivos alterados com 71912 adições e 34987 exclusões
-7
Ver Arquivo
@@ -133,13 +133,9 @@ endif()
#endif()
set(USE_NEON TRUE)
if(HAVE_QT5)
message(STATUS "Using Qt ${Qt5Core_VERSION_MAJOR}.${Qt5Core_VERSION_MINOR}.x")
if (${Qt5Core_VERSION_MAJOR} EQUAL "5")
if (${Qt5Core_VERSION_MINOR} EQUAL "4" OR ${Qt5Core_VERSION_MINOR} GREATER 4)
message(STATUS "We do not require Neon in this setup, compile without!")
set(USE_NEON FALSE)
else()
message(STATUS "If possible compile me with Qt 5.4 or higher.")
endif()
@@ -148,9 +144,6 @@ else()
message(STATUS "If possible compile me with Qt 5.4 or higher.")
endif()
if (USE_NEON)
find_package(Neon REQUIRED)
endif(USE_NEON)
find_package(OpenSSL 1.0.0 REQUIRED)
if(NOT TOKEN_AUTH_ONLY)
+54
Ver Arquivo
@@ -1,5 +1,59 @@
ChangeLog
=========
version 2.1 (release 2015-yy-zz)
* We removed the old libneon-based propagator.
It was already disabled on OS X and Windows and only used on
Linux when building with Qt < 5.4 and having bandwidth limiting enabled.
So now you need Qt 5.4 on Linux if you want bandwidth limiting.
version 2.0.2 (release 2015-10-21)
* csync_file_stat_s: Save a bit of memory
* Shibboleth: Add our base user agent to WebKit
* SelectiveSync: Increase folder list timeout to 60
* Propagation: Try another sync on 423 Locked (#3387)
* Propagation: Make 423 Locked a soft error (#3387)
* Propagation: Reset upload blacklist if a chunk succeeds
* Application: Fix crash on early shutdown (#3898)
* Linux: Don't show settings dialog always when launched twice (#3273, #3771, #3485)
* win32 vio: Add the OPEN_REPARSE_POINTS flag to the CreateFileW call. (#3813)
* AccountSettings: only expand root elements on single click.
* AccountSettings: Do not allow to expand the folder list when disconnected.
* Use application SHORT name for the name of the MacOSX pkg file (ownBrander).
* FolderMan: Fix for removing a syncing folder (#3843)
* ConnectionMethodDialog: Don't be insecure on close (#3863)
* Updater: Ensure folders are not removed (#3747)
* Folder settings: Ensure path is cleaned (#3811)
* Propagator: Simplify sub job finished counting (#3844)
* Share dialog: Hide settings dialog before showing (#3783)
* UI: Only expand 1 level in folder list (#3585)
* UI: Allow folder expanding from button click (#3585)
* UI: Expand folder treeview on single click (#3585)
* GUI: Change tray menu order (#3657)
* GUI: Replace term "sign in" with "Log in" and friends.
* SetupPage: Fix crash caused by uninitialized Account object.
* Use a themable WebDAV path all over.
* Units: Back to the "usual" mix units (JEDEC standard).
* csync io: Full UNC path support on Win (#3748)
* Tray: Don't use the tray workaround with the KDE theme (#3706, #3765)
* ShareDialog: Fix folder display (#3659)
* AccountSettings: Restore from legacy only once (#3565)
* SSL Certificate Error Dialog: show account name (#3729)
* Tray notification: Don't show a message about modified folder (#3613)
* PropagateLocalRemove: remove entries from the DB even if there was an error.
* Settings UI improvements (eg. #3713, #3721, #3619 and others)
* Folder: Do not create the sync folder if it does not exist (#3692)
* Shell integration: don't show share menu item for top level folders
* Tray: Hide while modifying menus (#3656, #3672)
* AddFolder: Improve remote path selection error handling (#3573)
* csync_update: Use excluded_traversal() to improve performance (#3638)
* csync_excluded: Add fast _traversal() function (#3638)
* csync_exclude: Speed up significantly (#3638)
* AccountSettings: Adjust quota info design (#3644, #3651)
* Adjust buttons on remove folder/account questions (#3654)
version 2.0.1 (release 2015-09-01)
* AccountWizard: fix when the theme specify a override URL (#3699)
version 2.0.0 (release 2015-08-25)
* Add support for multiple accounts (#3084)
* Do not sync down new big folders from server without users consent (#3148)
+1 -1
Ver Arquivo
@@ -4,7 +4,7 @@
|-----------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| client-build-matrix | [![Build Status](https://ci.owncloud.org/job/client-build-matrix-linux/badge/icon)](https://ci.owncloud.org/job/client-build-matrix-linux/) |
| client-test-matrix-linux-no-build | [![Build Status](https://ci.owncloud.org/buildStatus/icon?job=client-test-matrix-linux-no-build)](https://ci.owncloud.org/job/client-test-matrix-linux-no-build/) |
| coverity_scan | [![Build Status](https://img.shields.io/coverity/scan/2482.svg)](https://scan.coverity.com/projects/owncloud-mirall)
## Introduction
+3 -3
Ver Arquivo
@@ -1,10 +1,10 @@
set( MIRALL_VERSION_MAJOR 2 )
set( MIRALL_VERSION_MINOR 0 )
set( MIRALL_VERSION_PATCH 2 )
set( MIRALL_VERSION_MINOR 1 )
set( MIRALL_VERSION_PATCH 0 )
set( MIRALL_SOVERSION 0 )
if ( NOT DEFINED MIRALL_VERSION_SUFFIX )
set( MIRALL_VERSION_SUFFIX "git") #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 -1
Ver Arquivo
@@ -23,7 +23,7 @@ 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="@APPLICATION_SHORTNAME@-@MIRALL_VERSION_FULL@@MIRALL_VERSION_SUFFIX@"
installer_file="$installer.pkg"
installer_file_tar="$installer.pkg.tar"
installer_file_tar_bz2="$installer.pkg.tar.bz2"
+6
Ver Arquivo
@@ -38,6 +38,8 @@ QT_PLUGINS = [
'imageformats/libqgif.dylib',
'imageformats/libqico.dylib',
'imageformats/libqjpeg.dylib',
'bearer/libqcorewlanbearer.dylib',
'bearer/libqgenericbearer.dylib',
'imageformats/libqsvg.dylib',
'imageformats/libqmng.dylib',
]
@@ -144,6 +146,10 @@ def FindFramework(path):
search_pathes = FRAMEWORK_SEARCH_PATH
search_pathes.insert(0, QueryQMake('QT_INSTALL_LIBS'))
for search_path in search_pathes:
# The following two lines are needed for a custom built Qt from version 5.5 on, possibly not for the one from the Qt SDK.
# Looks like the upstream macdeployqt also had an issue there https://bugreports.qt.io/browse/QTBUG-47868
if path.find( "\@rpath/"):
path = path.replace("@rpath/", "")
abs_path = os.path.join(search_path, path)
if os.path.exists(abs_path):
return abs_path
-4
Ver Arquivo
@@ -32,7 +32,3 @@ SET(QT_MOC_EXECUTABLE ${MINGW_PREFIX}-moc)
SET(QT_RCC_EXECUTABLE ${MINGW_PREFIX}-rcc)
SET(QT_UIC_EXECUTABLE ${MINGW_PREFIX}-uic)
SET(QT_LRELEASE_EXECUTABLE ${MINGW_PREFIX}-lrelease)
# neon config
SET(NEON_CONFIG_EXECUTABLE ${CMAKE_FIND_ROOT_PATH}/bin/neon-config)
# /usr/i686-w64-mingw32/sys-root/mingw/bin/neon-config
+1 -1
Ver Arquivo
@@ -9,6 +9,7 @@ StrCpy $PageReinstall_NEW_Field_3 "Neodinstalov
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Ji§ nainstalov no"
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Zvolte, jak chcete ${APPLICATION_NAME} nainstalovat."
StrCpy $PageReinstall_OLD_Field_1 "NovØjç¡ verze aplikace ${APPLICATION_NAME} je ji§ nainstalov na. Instalace starç¡ verze se nedoporuŸuje. Pokud opravdu chcete tuto starç¡ verzi nainstalovat, je lepç¡ nejprve odinstalovat souŸasnou verzi. Zvolte po§adovanou operaci a kliknØte na Dalç¡ pro pokraŸov n¡."
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} je ji§ nainstalov na.$\n$\nZvolte po§adovanou operaci a kliknØte na Dalç¡ pro pokraŸov n¡."
StrCpy $PageReinstall_SAME_Field_2 "Pýidat Ÿi znovu instalovat komponenty"
StrCpy $PageReinstall_SAME_Field_3 "Odinstalovat ${APPLICATION_NAME}"
StrCpy $UNINSTALLER_APPDATA_TITLE "Odinstalovat ${APPLICATION_NAME}"
@@ -40,4 +41,3 @@ StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Tento odinstal
StrCpy $UAC_ERROR_LOGON_SERVICE "Slu§ba pýihl çen¡ nebا¡, ukonŸuji!"
StrCpy $INIT_UNINSTALLER_RUNNING "Odinstal tor je ji§ spuçtØn."
StrCpy $SectionGroup_Shortcuts "Z stupci"
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} is already installed.$\r$\nSelect the operation you want to perform and click Next to continue."
+14 -14
Ver Arquivo
@@ -1,10 +1,22 @@
# Auto-generated - do not modify
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "نمایش پادداشت های انتشار نسخه"
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "${APPLICATION_EXECUTABLE} پردازش (ها) که باید متوقف شوند را پیدا کرد. $\nآیا میخواهیم برنامه نصاب این پردازشها را برای شما متوقف کند ؟"
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "حذف پردازش‌های ${APPLICATION_EXECUTABLE}."
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "پردازش برای از بین بردن یافت نشد!"
StrCpy $PageReinstall_NEW_Field_1 "نسخه‌ی قدیمی از برنامه ${APPLICATION_NAME} بر روی سیستم شما نصب شده است، پیشنهاد می‌شود نسخه‌ی فعلی را قبل از نصب حذف کنید. عملیات مورد نظر را انتخاب کنید و برای ادامه روی دکمه Next کلیک کنید."
StrCpy $PageReinstall_NEW_Field_2 "عمل حذف را قبل از نصب انجام دهید"
StrCpy $PageReinstall_NEW_Field_3 "حذف نکن"
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "از قبل نصب شده است"
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "نحوه‌ی نصب ${APPLICATION_NAME} را انتخاب کنید."
StrCpy $PageReinstall_OLD_Field_1 "نسخه جدیدتری از برنامه ${APPLICATION_NAME} بر روی سیستم شما نصب شده است، نصب نسخه‌ی قدیمی‌تر پیشنهاد نمی‌شود. درصورتیکه میخواهید نسخه‌ی قدیمی را نصب کنید، حذف نسخه‌ی کنونی قبل از اجرای نصب جدید پیشنهاد می‌شود. عملیات مورد نظر را انتخاب و بر روی دکمه‌ی Next کلیک کنید."
StrCpy $PageReinstall_SAME_Field_1 "نسخه ${VERSION} از ${APPLICATION_NAME} هم‌اکنون نصب شده است.$↩$\nعملیات مورد نظر را انتخاب و بر روی دکمه Next کلیک کنید."
StrCpy $PageReinstall_SAME_Field_2 "افزودن/نصب مجدد اجزا"
StrCpy $PageReinstall_SAME_Field_3 "حذف ${APPLICATION_NAME}"
StrCpy $UNINSTALLER_APPDATA_TITLE "حذف ${APPLICATION_NAME}"
StrCpy $PageReinstall_SAME_MUI_HEADER_TEXT_SUBTITLE "گزینه نگهداری را به منظور اجرا انتخاب کنید."
StrCpy $SEC_APPLICATION_DETAILS "نصب ضروریات ${APPLICATION_NAME}"
StrCpy $OPTION_SECTION_SC_SHELL_EXT_SECTION "یکپارچه‌سازی با Windows Explorer"
StrCpy $OPTION_SECTION_SC_SHELL_EXT_DetailPrint "نصب یکپارچه‌ساز با Windows Explorer"
StrCpy $OPTION_SECTION_SC_START_MENU_SECTION "بازکردن میانبر منو برنامه"
StrCpy $OPTION_SECTION_SC_START_MENU_DetailPrint "افزودن میانبر ${APPLICATION_NAME} به استارت منو ."
StrCpy $OPTION_SECTION_SC_DESKTOP_SECTION "میانبر دسکتاپ"
@@ -23,21 +35,9 @@ StrCpy $UNINSTALL_ABORT "عمل حذف توسط کاربر متوقف شد"
StrCpy $INIT_NO_QUICK_LAUNCH "میانبر بازکردن سریع ( N/A )"
StrCpy $INIT_NO_DESKTOP "میانبر دسکتاپ (رونویسی وجود دارد)"
StrCpy $UAC_ERROR_ELEVATE "مشکل در بالااوردن ، خطا : "
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "برای نصب، دسترسی مدیر سیستم نیاز است، مجددا تلاش کنید"
StrCpy $INIT_INSTALLER_RUNNING "نصاب از قبل در حال اجراست."
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "حذف برنامه نیاز به دسترسی مدیر دارد ، لطفا دوباره سعی کنید"
StrCpy $UAC_ERROR_LOGON_SERVICE "سرویس ورود اجرا نیست، درحال لغو نصب!"
StrCpy $INIT_UNINSTALLER_RUNNING "حذف کننده از قبل در حال اجراست."
StrCpy $SectionGroup_Shortcuts "میانبرها"
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Found ${APPLICATION_EXECUTABLE} process(s) which need to be stopped.$\nDo you want the installer to stop these for you?"
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Killing ${APPLICATION_EXECUTABLE} processes."
StrCpy $PageReinstall_NEW_Field_1 "An older version of ${APPLICATION_NAME} is installed on your system. It is recommended that you uninstall the current version before installing. Select the operation you want to perform and click Next to continue."
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Choose how you want to install ${APPLICATION_NAME}."
StrCpy $PageReinstall_OLD_Field_1 "A newer version of ${APPLICATION_NAME} is already installed! It is not recommended that you install an older version. If you really want to install this older version, it is better to uninstall the current version first. Select the operation you want to perform and click Next to continue."
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} is already installed.$\r$\nSelect the operation you want to perform and click Next to continue."
StrCpy $PageReinstall_SAME_Field_3 "Uninstall ${APPLICATION_NAME}"
StrCpy $UNINSTALLER_APPDATA_TITLE "Uninstall ${APPLICATION_NAME}"
StrCpy $PageReinstall_SAME_MUI_HEADER_TEXT_SUBTITLE "Choose the maintenance option to perform."
StrCpy $SEC_APPLICATION_DETAILS "Installing ${APPLICATION_NAME} essentials."
StrCpy $OPTION_SECTION_SC_SHELL_EXT_SECTION "Integration for Windows Explorer"
StrCpy $OPTION_SECTION_SC_SHELL_EXT_DetailPrint "Installing Integration for Windows Explorer"
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "This installer requires admin access, try again"
StrCpy $UAC_ERROR_LOGON_SERVICE "Logon service is not running, aborting!"
+1 -1
Ver Arquivo
@@ -9,6 +9,7 @@ StrCpy $PageReinstall_NEW_Field_3 "Ne pas désinstaller"
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Déjà installé"
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Choisissez comment installer ${APPLICATION_NAME}."
StrCpy $PageReinstall_OLD_Field_1 "Une version plus récente de ${APPLICATION_NAME} est déjà installée ! Il n'est pas recommandé d'installer une version plus ancienne. Si vous voulez vraiment installer cette version plus ancienne, il est préférable de d'abord désinstaller la version courante. Sélectionnez l'opération que vous voulez exécuter et cliquez sur Suivant pour continuer."
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} est déjà installé.$\n$\nSélectionnez l'opération que vous souhaitez effectuer et cliquez sur Suivant pour continuer."
StrCpy $PageReinstall_SAME_Field_2 "Ajouter/Réinstaller des composants"
StrCpy $PageReinstall_SAME_Field_3 "Désinstaller ${APPLICATION_NAME}"
StrCpy $UNINSTALLER_APPDATA_TITLE "Désinstaller ${APPLICATION_NAME}"
@@ -40,4 +41,3 @@ StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Ce désinstallateur requiert les droits a
StrCpy $UAC_ERROR_LOGON_SERVICE "Service de logon non lancé ! Abandon."
StrCpy $INIT_UNINSTALLER_RUNNING "Une désinstallation est déjà en cours."
StrCpy $SectionGroup_Shortcuts "Raccourcis"
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} is already installed.$\r$\nSelect the operation you want to perform and click Next to continue."
+1 -1
Ver Arquivo
@@ -9,6 +9,7 @@ StrCpy $PageReinstall_NEW_Field_3 "Ne távolítsa el"
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Már telepítve"
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Válaszd ki, hogy szeretnéd telepíteni a következő alkalmazást ${APPLICATION_NAME}."
StrCpy $PageReinstall_OLD_Field_1 "Az ${APPLICATION_NAME} alklamazás egy újabb verziója már megtalálható a rendszeren. Nem ajánlott egy régebbi verzió telepítése. Ha valóban szeretné a régebbi verziót telepíteni, akkor ajánlott a jelenleg telepített verzió eltávolítása. Válassza ki milyen műveletet szeretne végrehajtani, és nyomja meg a $\"Következő$\" gombot a folytatáshoz."
StrCpy $PageReinstall_SAME_Field_1 "Az ${APPLICATION_NAME} alkalmazás ${VERSION} verziója már telepítve van.$↩$\nKérjük válaszd ki milyen műveletet szeretnél végrehajtani, és nyomd meg a „Következő” gombot."
StrCpy $PageReinstall_SAME_Field_2 "Komponens hozzáadása/újratelepítése"
StrCpy $PageReinstall_SAME_Field_3 "${APPLICATION_NAME} eltávolítása"
StrCpy $UNINSTALLER_APPDATA_TITLE "${APPLICATION_NAME} eltávolítása"
@@ -40,4 +41,3 @@ StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Az eltávolító futtatásához adminisz
StrCpy $UAC_ERROR_LOGON_SERVICE "A bejelentkező szolgáltatás nem fut, megszakítás!"
StrCpy $INIT_UNINSTALLER_RUNNING "Az eltávolító már fut."
StrCpy $SectionGroup_Shortcuts "Parancsikonok"
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} is already installed.$\r$\nSelect the operation you want to perform and click Next to continue."
+1 -1
Ver Arquivo
@@ -9,6 +9,7 @@ StrCpy $PageReinstall_NEW_Field_3 "
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "インストール済"
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "${APPLICATION_NAME} のインストール方法を選択する"
StrCpy $PageReinstall_OLD_Field_1 "${APPLICATION_NAME} の最新バージョンがすでにインストールされています。\n旧バージョンのインストールはお勧めしません。旧バージョンのインストールが本当に必要な場合は、まず最新バージョンをアンインストールしてから、旧バージョンをインストールしてください。\nオペレーションを選択し、次へをクリックする。"
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} は、${VERSION} が既にインストールされています。$\n$\n実行したい操作を選択し、次へをクリックする。"
StrCpy $PageReinstall_SAME_Field_2 "追加/再インストールコンポーネント"
StrCpy $PageReinstall_SAME_Field_3 "${APPLICATION_NAME} をアンインストール"
StrCpy $UNINSTALLER_APPDATA_TITLE "${APPLICATION_NAME} をアンインストール"
@@ -40,4 +41,3 @@ StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "
StrCpy $UAC_ERROR_LOGON_SERVICE "ログオンサービスが動いていません。中止します。"
StrCpy $INIT_UNINSTALLER_RUNNING "アンインストーラーは、すでに起動しています。"
StrCpy $SectionGroup_Shortcuts "ショートカット"
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} is already installed.$\r$\nSelect the operation you want to perform and click Next to continue."
+1 -1
Ver Arquivo
@@ -9,6 +9,7 @@ StrCpy $PageReinstall_NEW_Field_3 "Не устанавливать"
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Уже установлено"
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Выберите, как вы хотите установить ${APPLICATION_NAME}."
StrCpy $PageReinstall_OLD_Field_1 "Новая версия ${APPLICATION_NAME} уже установлена​​! Не рекомендуется устанавливать старую версию. Если вы действительно хотите установить эту старую версию, то сначала лучше удалить текущую версию. Выберите желаемое действие и нажмите Далее для продолжения."
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} уже установлен.$\n$\nУкажите действие и нажмите Далее для продолжения."
StrCpy $PageReinstall_SAME_Field_2 "Добавить/Переустановить компоненты"
StrCpy $PageReinstall_SAME_Field_3 "Удалить ${APPLICATION_NAME}"
StrCpy $UNINSTALLER_APPDATA_TITLE "Удалить ${APPLICATION_NAME}"
@@ -40,4 +41,3 @@ StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Этому деинсталлятору
StrCpy $UAC_ERROR_LOGON_SERVICE "Служба входа в систему не запущена, прерывание!"
StrCpy $INIT_UNINSTALLER_RUNNING "Программа удаления уже выполняется."
StrCpy $SectionGroup_Shortcuts "Ярлыки"
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} is already installed.$\r$\nSelect the operation you want to perform and click Next to continue."
+1 -1
Ver Arquivo
@@ -9,6 +9,7 @@ StrCpy $PageReinstall_NEW_Field_3 "不要卸载"
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "已经安装"
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "选择如何安装${APPLICATION_NAME}。"
StrCpy $PageReinstall_OLD_Field_1 "较新版本的 ${APPLICATION_NAME} 已经安装!安装较旧版本的程序是不推荐的。如果您希望继续安装较旧版本,建议先卸载较新版本。选择您想要执行的操作并点击下一步以继续。"
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} 已经安装。$\n$\n请选择想要执行的操作并点击下一步。"
StrCpy $PageReinstall_SAME_Field_2 "增加/重装组件"
StrCpy $PageReinstall_SAME_Field_3 "卸载${APPLICATION_NAME}"
StrCpy $UNINSTALLER_APPDATA_TITLE "卸载${APPLICATION_NAME}"
@@ -39,5 +40,4 @@ StrCpy $INIT_INSTALLER_RUNNING "安装程序已经运行。"
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "卸载程序需要管理员权限,请重试"
StrCpy $INIT_UNINSTALLER_RUNNING "卸载程序已经运行。"
StrCpy $SectionGroup_Shortcuts "快捷方式"
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} is already installed.$\r$\nSelect the operation you want to perform and click Next to continue."
StrCpy $UAC_ERROR_LOGON_SERVICE "Logon service is not running, aborting!"
+2 -2
Ver Arquivo
@@ -9,6 +9,7 @@ StrCpy $PageReinstall_NEW_Field_3 "No desinstalar"
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Ya está instalado"
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Elija cómo quiere instalar ${APPLICATION_NAME}."
StrCpy $PageReinstall_OLD_Field_1 "Una nueva versión de ${APPLICATION_NAME} ya está instalada. No es recomendable instalar una versión anterior. Si realmente quiere instalar esta versión anterior, es mejor que desinstale la versión actual primero. Seleccione la operación que desea realizar y pulse Siguiente para continuar."
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} ya está instalado.$\n$\nSeleccione la operación que desea realizar y haga click en Siguiente para continuar."
StrCpy $PageReinstall_SAME_Field_2 "Añadir/Reinstalar componentes"
StrCpy $PageReinstall_SAME_Field_3 "Desinstalar ${APPLICATION_NAME}"
StrCpy $UNINSTALLER_APPDATA_TITLE "Desinstalar ${APPLICATION_NAME}"
@@ -29,7 +30,7 @@ StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "Lanzador R
StrCpy $UNINSTALLER_FILE_Detail "Escribiendo desinstalador"
StrCpy $UNINSTALLER_REGISTRY_Detail "Escribiendo claves en el registro del instalador"
StrCpy $UNINSTALLER_FINISHED_Detail "Terminado"
StrCpy $UNINSTALL_MESSAGEBOX "Parece que ${APPLICATION_NAME} no está instalado en el directorio '$INSTDIR'.$$ ¿Continuar de todos modos? (No Recomendado)"
StrCpy $UNINSTALL_MESSAGEBOX "Parece que ${APPLICATION_NAME} no está instalado en el directorio '$INSTDIR'.$$ ¿Continuar de todos modos? (No recomendado)"
StrCpy $UNINSTALL_ABORT "Desinstalación cancelada por el usuario"
StrCpy $INIT_NO_QUICK_LAUNCH "Atajo de inicio rápido (N/A)"
StrCpy $INIT_NO_DESKTOP "Atajo de escritorio (sobreescribe el existente)"
@@ -40,4 +41,3 @@ StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "El desinstalador requiere acceso administ
StrCpy $UAC_ERROR_LOGON_SERVICE "Servicio Inicio de sesión no se está ejecutando, abortando!"
StrCpy $INIT_UNINSTALLER_RUNNING "El desinstalador ya se encuentra en ejecución."
StrCpy $SectionGroup_Shortcuts "Accesos directos"
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} is already installed.$\r$\nSelect the operation you want to perform and click Next to continue."
+1 -1
Ver Arquivo
@@ -9,6 +9,7 @@ StrCpy $PageReinstall_NEW_Field_3 "Kald
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Zaten Yüklü"
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "${APPLICATION_NAME} uygulamasýný nasýl yüklemek istediðinizi seçin."
StrCpy $PageReinstall_OLD_Field_1 "${APPLICATION_NAME} uygulamasýnýn daha yeni sürümü zaten yüklü! Daha eski bir sürümünü yüklemeniz önerilmez. Gerçekten bu eski sürümü yüklemek isterseniz, ilk olarak geçerli sürümü kaldýrmanýz tavsiye edilir. Yapmak istediðiniz iþlemi seçin ve devam etmek üzere Ýleri týklayýn."
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} zaten yüklü.$\n$\nYapmak istediðiniz iþlemi seçin ve devam etmek için Ýleri týklayýn."
StrCpy $PageReinstall_SAME_Field_2 "Bileþenleri ekle/yeniden yükle"
StrCpy $PageReinstall_SAME_Field_3 "${APPLICATION_NAME} uygulamasýný kaldýr"
StrCpy $UNINSTALLER_APPDATA_TITLE "${APPLICATION_NAME} uygulamasýný kaldýr"
@@ -40,4 +41,3 @@ StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Bu kald
StrCpy $UAC_ERROR_LOGON_SERVICE "Oturum açýlacak sunucu çalýþmadýðýndan iptal ediliyor!"
StrCpy $INIT_UNINSTALLER_RUNNING "Kaldýrýcý zaten çalýþýyor."
StrCpy $SectionGroup_Shortcuts "Kýsayollar"
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} is already installed.$\r$\nSelect the operation you want to perform and click Next to continue."
+2
Ver Arquivo
@@ -20,5 +20,7 @@
<file>resources/lock-https.png</file>
<file>resources/lock-https@2x.png</file>
<file>resources/account.png</file>
<file>resources/more.png</file>
<file>resources/delete.png</file>
</qresource>
</RCC>
-73
Ver Arquivo
@@ -1,73 +0,0 @@
# - Try to find Neon
# Once done this will define
#
# NEON_FOUND - system has Neon
# NEON_INCLUDE_DIRS - the Neon include directory
# NEON_LIBRARIES - Link these to use Neon
# NEON_DEFINITIONS - Compiler switches required for using Neon
#
# Copyright (c) 2011-2013 Andreas Schneider <asn@cryptomilk.org>
#
# Redistribution and use is allowed according to the terms of the New
# BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
find_package(PkgConfig)
if (PKG_CONFIG_FOUND)
pkg_check_modules(_NEON neon)
endif (PKG_CONFIG_FOUND)
include(GNUInstallDirs)
find_path(NEON_INCLUDE_DIRS
NAMES
neon/ne_basic.h
HINTS
${_NEON_INCLUDEDIR}
${CMAKE_INSTALL_INCLUDEDIR}
)
find_library(NEON_LIBRARIES
NAMES
neon neon-27
HINTS
${_NEON_LIBDIR}
${CMAKE_INSTALL_LIBDIR}
${CMAKE_INSTALL_PREFIX}/lib
${CMAKE_INSTALL_PREFIX}/lib64
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Neon DEFAULT_MSG NEON_LIBRARIES NEON_INCLUDE_DIRS)
# show the NEON_INCLUDE_DIRS and NEON_LIBRARIES variables only in the advanced view
mark_as_advanced(NEON_INCLUDE_DIRS NEON_LIBRARIES)
# Check if neon was compiled with LFS support, if so, the NE_LFS variable has to
# be defined in the owncloud module.
# If neon was not compiled with LFS its also ok since the underlying system
# than probably supports large files anyway.
IF( CMAKE_FIND_ROOT_PATH )
FIND_PROGRAM( NEON_CONFIG_EXECUTABLE NAMES neon-config HINTS ${CMAKE_FIND_ROOT_PATH}/bin )
ELSE( CMAKE_FIND_ROOT_PATH )
FIND_PROGRAM( NEON_CONFIG_EXECUTABLE NAMES neon-config )
ENDIF( CMAKE_FIND_ROOT_PATH )
IF ( NEON_CONFIG_EXECUTABLE )
MESSAGE(STATUS "neon-config executable: ${NEON_CONFIG_EXECUTABLE}")
# neon-config --support lfs
EXECUTE_PROCESS( COMMAND ${NEON_CONFIG_EXECUTABLE} "--support" "lfs"
RESULT_VARIABLE LFS
OUTPUT_STRIP_TRAILING_WHITESPACE )
IF (LFS EQUAL 0)
MESSAGE(STATUS "libneon has been compiled with LFS support")
SET(NEON_WITH_LFS 1)
ELSE (LFS EQUAL 0)
MESSAGE(STATUS "libneon has not been compiled with LFS support, rely on OS")
ENDIF (LFS EQUAL 0)
ELSE ( NEON_CONFIG_EXECUTABLE )
MESSAGE(STATUS, "neon-config could not be found.")
ENDIF ( NEON_CONFIG_EXECUTABLE )
+1 -7
Ver Arquivo
@@ -134,13 +134,7 @@ if(NOT DEFINED CMAKE_INSTALL_LIBDIR OR (_libdir_set
AND NOT CMAKE_CROSSCOMPILING)
if (EXISTS "/etc/debian_version") # is this a debian system ?
if(CMAKE_LIBRARY_ARCHITECTURE)
if("${CMAKE_INSTALL_PREFIX}" MATCHES "^/usr/?$")
set(_LIBDIR_DEFAULT "lib/${CMAKE_LIBRARY_ARCHITECTURE}")
endif()
if(DEFINED _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX
AND "${_GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX}" MATCHES "^/usr/?$")
set(__LAST_LIBDIR_DEFAULT "lib/${CMAKE_LIBRARY_ARCHITECTURE}")
endif()
set(_LIBDIR_DEFAULT "lib/${CMAKE_LIBRARY_ARCHITECTURE}")
endif()
else() # not debian, rely on CMAKE_SIZEOF_VOID_P:
if(NOT DEFINED CMAKE_SIZEOF_VOID_P)
+5
Ver Arquivo
@@ -40,6 +40,7 @@
!define QT_DLL_PATH "${MING_BIN}"
!define ACCESSIBLE_DLL_PATH "${MING_LIB}/qt5/plugins/accessible"
!define SQLITE_DLL_PATH "${MING_LIB}/qt5/plugins/sqldrivers"
!define BEARER_DLL_PATH "${MING_LIB}/qt5/plugins/bearer"
!define IMAGEFORMATS_DLL_PATH "${MING_LIB}/qt5/plugins/imageformats"
!define PLATFORMS_DLL_PATH "${MING_LIB}/qt5/plugins/platforms"
@@ -406,6 +407,10 @@ Section "${APPLICATION_NAME}" SEC_APPLICATION
SetOutPath "$INSTDIR\sqldrivers"
File "${SQLITE_DLL_PATH}\qsqlite.dll"
SetOutPath "$INSTDIR\bearer"
File "${BEARER_DLL_PATH}\qgenericbearer.dll"
File "${BEARER_DLL_PATH}\qnativewifibearer.dll"
SetOutPath "$INSTDIR"
;License & release notes.
File "@CPACK_RESOURCE_FILE_LICENSE@"
+5 -1
Ver Arquivo
@@ -22,7 +22,9 @@ if( Qt5Core_FOUND )
find_package(Qt5WebKitWidgets REQUIRED)
find_package(Qt5WebKit REQUIRED)
find_package(Qt5PrintSupport REQUIRED)
find_package(Qt5Quick REQUIRED)
if(NOT APPLE)
find_package(Qt5Quick REQUIRED) # only needed on Windows because of OBS dependencies(?)
endif()
find_package(Qt5Widgets REQUIRED)
if(APPLE)
find_package(Qt5MacExtras REQUIRED)
@@ -31,7 +33,9 @@ if( Qt5Core_FOUND )
else( Qt5Core_FOUND )
if(WIN32 OR APPLE)
if (NOT BUILD_WITH_QT4)
message(FATAL_ERROR "Qt 5 not found, but application depends on Qt5 on Windows and Mac OS X")
endif ()
endif(WIN32 OR APPLE)
endif( Qt5Core_FOUND )
-4
Ver Arquivo
@@ -23,8 +23,4 @@
#cmakedefine SYSCONFDIR "@SYSCONFDIR@"
#cmakedefine SHAREDIR "@SHAREDIR@"
#ifndef NEON_WITH_LFS
#cmakedefine NEON_WITH_LFS "@NEON_WITH_LFS@"
#endif
#endif
-4
Ver Arquivo
@@ -24,10 +24,6 @@
#cmakedefine HAVE_ICONV 1
#cmakedefine HAVE_ICONV_CONST 1
#ifndef NEON_WITH_LFS
#cmakedefine NEON_WITH_LFS 1
#endif
#cmakedefine HAVE___MINGW_ASPRINTF 1
#cmakedefine HAVE_ASPRINTF 1
-16
Ver Arquivo
@@ -1,9 +1,6 @@
project(libcsync)
add_subdirectory(std)
if(USE_NEON)
add_subdirectory(httpbf)
endif()
# Statically include sqlite
@@ -71,19 +68,6 @@ else()
endif()
if(USE_NEON)
list(APPEND csync_SRCS
csync_owncloud.c
csync_owncloud_util.c
)
list(APPEND CSYNC_LINK_LIBRARIES
${NEON_LIBRARIES}
)
include_directories(${NEON_INCLUDE_DIRS})
add_definitions(-DUSE_NEON)
endif(USE_NEON)
configure_file(csync_version.h.in ${CMAKE_CURRENT_BINARY_DIR}/csync_version.h)
set(csync_HDRS
-47
Ver Arquivo
@@ -58,12 +58,6 @@
#include "csync_rename.h"
#include "c_jhash.h"
#ifdef USE_NEON
// Breaking the abstraction for fun and profit.
#include "csync_owncloud.h"
#endif
static int _key_cmp(const void *key, const void *data) {
uint64_t a;
csync_file_stat_t *b;
@@ -154,9 +148,6 @@ int csync_init(CSYNC *ctx) {
ctx->local.type = LOCAL_REPLICA;
#ifdef USE_NEON
owncloud_init(ctx);
#endif
ctx->remote.type = REMOTE_REPLICA;
if (c_rbtree_create(&ctx->local.tree, _key_cmp, _data_cmp) < 0) {
@@ -216,14 +207,6 @@ int csync_update(CSYNC *ctx) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "No exclude file loaded or defined!");
}
#ifdef USE_NEON
/* This is not actually connecting, just setting the info for neon. The legacy propagator can use it.. */
if (dav_connect( ctx, ctx->remote.uri ) < 0) {
ctx->status_code = CSYNC_STATUS_CONNECT_ERROR;
return -1;
}
#endif
/* update detection for local replica */
csync_gettime(&start);
ctx->current = LOCAL_REPLICA;
@@ -646,10 +629,6 @@ int csync_destroy(CSYNC *ctx) {
SAFE_FREE(ctx->remote.uri);
SAFE_FREE(ctx->error_string);
#ifdef USE_NEON
owncloud_destroy(ctx);
#endif
#ifdef WITH_ICONV
c_close_iconv();
#endif
@@ -672,21 +651,6 @@ void csync_clear_exclude_list(CSYNC *ctx)
csync_exclude_clear(ctx);
}
int csync_set_auth_callback(CSYNC *ctx, csync_auth_callback cb) {
if (ctx == NULL || cb == NULL) {
return -1;
}
if (ctx->status & CSYNC_STATUS_INIT) {
ctx->status_code = CSYNC_STATUS_CSYNC_STATUS_ERROR;
fprintf(stderr, "This function must be called before initialization.");
return -1;
}
ctx->callbacks.auth_function = cb;
return 0;
}
void *csync_get_userdata(CSYNC *ctx) {
if (ctx == NULL) {
return NULL;
@@ -781,14 +745,3 @@ void csync_file_stat_free(csync_file_stat_t *st)
SAFE_FREE(st);
}
}
int csync_set_module_property(CSYNC* ctx, const char* key, void* value)
{
#ifdef USE_NEON
return owncloud_set_property(ctx, key, value);
#else
(void)ctx, (void)key, (void)value;
return 0;
#endif
}
+2 -16
Ver Arquivo
@@ -144,7 +144,7 @@ enum csync_ftw_type_e {
};
#define FILE_ID_BUF_SIZE 21
#define FILE_ID_BUF_SIZE 36
// currently specified at https://github.com/owncloud/core/issues/8322 are 9 to 10
#define REMOTE_PERM_BUF_SIZE 15
@@ -173,7 +173,7 @@ enum csync_vio_file_stat_fields_e {
CSYNC_VIO_FILE_STAT_FIELDS_TYPE = 1 << 0,
CSYNC_VIO_FILE_STAT_FIELDS_MODE = 1 << 1, // local POSIX mode
CSYNC_VIO_FILE_STAT_FIELDS_FLAGS = 1 << 2,
CSYNC_VIO_FILE_STAT_FIELDS_DEVICE = 1 << 3,
// CSYNC_VIO_FILE_STAT_FIELDS_DEVICE = 1 << 3,
CSYNC_VIO_FILE_STAT_FIELDS_INODE = 1 << 4,
// CSYNC_VIO_FILE_STAT_FIELDS_LINK_COUNT = 1 << 5,
CSYNC_VIO_FILE_STAT_FIELDS_SIZE = 1 << 6,
@@ -212,7 +212,6 @@ struct csync_vio_file_stat_s {
mode_t mode;
dev_t device;
uint64_t inode;
int fields; // actually enum csync_vio_file_stat_fields_e fields;
@@ -519,19 +518,6 @@ const char *csync_get_status_string(CSYNC *ctx);
int csync_set_iconv_codec(const char *from);
#endif
/**
* @brief Set a property to module
*
* @param ctx The csync context.
*
* @param key The property key
*
* @param value An opaque pointer to the data.
*
* @return 0 on success, less than 0 if an error occured.
*/
int csync_set_module_property(CSYNC *ctx, const char *key, void *value);
/**
* @brief Aborts the current sync run as soon as possible. Can be called from another thread.
*
+59 -45
Ver Arquivo
@@ -171,7 +171,6 @@ bool csync_is_windows_reserved_word(const char* filename) {
static CSYNC_EXCLUDE_TYPE _csync_excluded_common(c_strlist_t *excludes, const char *path, int filetype, bool check_leading_dirs) {
size_t i = 0;
const char *p = NULL;
const char *bname = NULL;
size_t blen = 0;
char *conflict = NULL;
@@ -179,22 +178,6 @@ static CSYNC_EXCLUDE_TYPE _csync_excluded_common(c_strlist_t *excludes, const ch
CSYNC_EXCLUDE_TYPE match = CSYNC_NOT_EXCLUDED;
CSYNC_EXCLUDE_TYPE type = CSYNC_NOT_EXCLUDED;
for (p = path; *p; p++) {
switch (*p) {
case '\\':
case ':':
case '?':
case '*':
case '"':
case '>':
case '<':
case '|':
return CSYNC_FILE_EXCLUDE_INVALID_CHAR;
default:
break;
}
}
/* split up the path */
bname = strrchr(path, '/');
if (bname) {
@@ -217,7 +200,7 @@ static CSYNC_EXCLUDE_TYPE _csync_excluded_common(c_strlist_t *excludes, const ch
goto out;
}
#ifdef _WIN32
#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
@@ -231,7 +214,26 @@ static CSYNC_EXCLUDE_TYPE _csync_excluded_common(c_strlist_t *excludes, const ch
match = CSYNC_FILE_EXCLUDE_INVALID_CHAR;
goto out;
}
#endif
// Filter out characters not allowed in a filename on windows
const char *p = NULL;
for (p = path; *p; p++) {
switch (*p) {
case '\\':
case ':':
case '?':
case '*':
case '"':
case '>':
case '<':
case '|':
match = CSYNC_FILE_EXCLUDE_INVALID_CHAR;
goto out;
default:
break;
}
}
#endif
rc = csync_fnmatch(".owncloudsync.log*", bname, 0);
if (rc == 0) {
@@ -264,40 +266,41 @@ static CSYNC_EXCLUDE_TYPE _csync_excluded_common(c_strlist_t *excludes, const ch
goto out;
}
/* Build a list of path components to check. */
c_strlist_t *path_components = c_strlist_new(32);
char *path_split = strdup(path);
size_t len = strlen(path_split);
for (i = len; ; --i) {
// read backwards until a path separator is found
if (i != 0 && path_split[i-1] != '/') {
continue;
}
c_strlist_t *path_components = NULL;
if (check_leading_dirs) {
/* Build a list of path components to check. */
path_components = c_strlist_new(32);
char *path_split = strdup(path);
size_t len = strlen(path_split);
for (i = len; ; --i) {
// read backwards until a path separator is found
if (i != 0 && path_split[i-1] != '/') {
continue;
}
// check 'basename', i.e. for "/foo/bar/fi" we'd check 'fi', 'bar', 'foo'
if (path_split[i] != 0) {
c_strlist_add_grow(&path_components, path_split + i);
}
// check 'basename', i.e. for "/foo/bar/fi" we'd check 'fi', 'bar', 'foo'
if (path_split[i] != 0) {
c_strlist_add_grow(&path_components, path_split + i);
}
if (i == 0 || !check_leading_dirs) {
break;
}
if (i == 0) {
break;
}
// check 'dirname', i.e. for "/foo/bar/fi" we'd check '/foo/bar', '/foo'
path_split[i-1] = '\0';
c_strlist_add_grow(&path_components, path_split);
// check 'dirname', i.e. for "/foo/bar/fi" we'd check '/foo/bar', '/foo'
path_split[i-1] = '\0';
c_strlist_add_grow(&path_components, path_split);
}
SAFE_FREE(path_split);
}
SAFE_FREE(path_split);
/* Loop over all exclude patterns and evaluate the given path */
for (i = 0; match == CSYNC_NOT_EXCLUDED && i < excludes->count; i++) {
bool match_dirs_only = false;
char *pattern_stored = c_strdup(excludes->vector[i]);
char* pattern = pattern_stored;
char *pattern = excludes->vector[i];
type = CSYNC_FILE_EXCLUDE_LIST;
if (strlen(pattern) < 1) {
SAFE_FREE(pattern_stored);
if (!pattern[0]) { /* empty pattern */
continue;
}
/* Excludes starting with ']' means it can be cleanup */
@@ -309,6 +312,9 @@ static CSYNC_EXCLUDE_TYPE _csync_excluded_common(c_strlist_t *excludes, const ch
}
/* Check if the pattern applies to pathes only. */
if (pattern[strlen(pattern)-1] == '/') {
if (!check_leading_dirs && filetype == CSYNC_FTW_TYPE_FILE) {
continue;
}
match_dirs_only = true;
pattern[strlen(pattern)-1] = '\0'; /* Cut off the slash */
}
@@ -326,7 +332,7 @@ static CSYNC_EXCLUDE_TYPE _csync_excluded_common(c_strlist_t *excludes, const ch
}
/* if still not excluded, check each component and leading directory of the path */
if (match == CSYNC_NOT_EXCLUDED) {
if (match == CSYNC_NOT_EXCLUDED && check_leading_dirs) {
size_t j = 0;
if (match_dirs_only && filetype == CSYNC_FTW_TYPE_FILE) {
j = 1; // skip the first entry, which is bname
@@ -338,8 +344,16 @@ static CSYNC_EXCLUDE_TYPE _csync_excluded_common(c_strlist_t *excludes, const ch
break;
}
}
} else if (match == CSYNC_NOT_EXCLUDED && !check_leading_dirs) {
rc = csync_fnmatch(pattern, bname, 0);
if (rc == 0) {
match = type;
}
}
if (match_dirs_only) {
/* restore the '/' */
pattern[strlen(pattern)] = '/';
}
SAFE_FREE(pattern_stored);
}
c_strlist_destroy(path_components);
+3 -10
Ver Arquivo
@@ -57,20 +57,13 @@ int csync_fnmatch(__const char *__pattern, __const char *__name, int __flags) {
#else /* HAVE_FNMATCH */
#include <shlwapi.h>
int csync_fnmatch(__const char *__pattern, __const char *__name, int __flags) {
wchar_t *pat = NULL;
wchar_t *name = NULL;
int csync_fnmatch(const char *pattern, const char *name, int flags) {
BOOL match;
(void) __flags;
(void) flags;
name = c_utf8_string_to_locale(__name);
pat = c_utf8_string_to_locale(__pattern);
match = PathMatchSpecA(name, pattern);
match = PathMatchSpecW(name, pat);
c_free_locale_string(pat);
c_free_locale_string(name);
if(match)
return 0;
else
-617
Ver Arquivo
@@ -1,617 +0,0 @@
/*
* libcsync -- a library to sync a directory with another
*
* Copyright (c) 2011 by Andreas Schneider <asn@cryptomilk.org>
* Copyright (c) 2012 by Klaas Freitag <freitag@owncloud.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "csync_owncloud.h"
#include "csync_owncloud_private.h"
#include <inttypes.h>
#include "csync_private.h"
#include "csync_version.h"
/*
* helper method to build up a user text for SSL problems, called from the
* verify_sslcert callback.
*/
static void addSSLWarning( char *ptr, const char *warn, int len )
{
char *concatHere = ptr;
int remainingLen = 0;
if( ! (warn && ptr )) return;
remainingLen = len - strlen(ptr);
if( remainingLen <= 0 ) return;
concatHere = ptr + strlen(ptr); /* put the write pointer to the end. */
strncpy( concatHere, warn, remainingLen );
}
/*
* Callback to verify the SSL certificate, called from libneon.
* It analyzes the SSL problem, creates a user information text and passes
* it to the csync callback to ask the user.
*/
#define LEN 4096
static int ssl_callback_by_neon(void *userdata, int failures,
const ne_ssl_certificate *certificate)
{
char problem[LEN];
char buf[MAX(NE_SSL_DIGESTLEN, NE_ABUFSIZ)];
int ret = -1;
const ne_ssl_certificate *cert = certificate;
csync_auth_callback authcb = NULL;
csync_owncloud_ctx_t *ctx = (csync_owncloud_ctx_t*) userdata;
memset( problem, 0, LEN );
while( cert ) {
addSSLWarning( problem, "There are problems with the SSL certificate:\n", LEN );
if( failures & NE_SSL_NOTYETVALID ) {
addSSLWarning( problem, " * The certificate is not yet valid.\n", LEN );
}
if( failures & NE_SSL_EXPIRED ) {
addSSLWarning( problem, " * The certificate has expired.\n", LEN );
}
if( failures & NE_SSL_UNTRUSTED ) {
addSSLWarning( problem, " * The certificate is not trusted!\n", LEN );
}
if( failures & NE_SSL_IDMISMATCH ) {
addSSLWarning( problem, " * The hostname for which the certificate was "
"issued does not match the hostname of the server\n", LEN );
}
if( failures & NE_SSL_BADCHAIN ) {
addSSLWarning( problem, " * The certificate chain contained a certificate other than the server cert\n", LEN );
}
if( failures & NE_SSL_REVOKED ) {
addSSLWarning( problem, " * The server certificate has been revoked by the issuing authority.\n", LEN );
}
if (ne_ssl_cert_digest(cert, buf) == 0) {
addSSLWarning( problem, "Certificate fingerprint: ", LEN );
addSSLWarning( problem, buf, LEN );
addSSLWarning( problem, "\n", LEN );
}
cert = ne_ssl_cert_signedby( cert );
}
addSSLWarning( problem, "Do you want to accept the certificate chain anyway?\nAnswer yes to do so and take the risk: ", LEN );
if( ctx->csync_ctx ) {
authcb = csync_get_auth_callback( ctx->csync_ctx );
}
if( authcb ){
/* call the csync callback */
DEBUG_WEBDAV("Call the csync callback for SSL problems");
memset( buf, 0, NE_ABUFSIZ );
(*authcb) ( problem, buf, NE_ABUFSIZ-1, 1, 0, csync_get_userdata(ctx->csync_ctx) );
if( buf[0] == 'y' || buf[0] == 'Y') {
ret = 0;
} else {
DEBUG_WEBDAV("Authentication callback replied %s", buf );
}
}
DEBUG_WEBDAV("## VERIFY_SSL CERT: %d", ret );
return ret;
}
/*
* Authentication callback. Is set by ne_set_server_auth to be called
* from the neon lib to authenticate a request.
*/
static int authentication_callback_by_neon( void *userdata, const char *realm, int attempt,
char *username, char *password)
{
char buf[NE_ABUFSIZ];
csync_auth_callback authcb = NULL;
int re = attempt;
csync_owncloud_ctx_t *ctx = (csync_owncloud_ctx_t*) userdata;
(void) realm;
/* DEBUG_WEBDAV( "Authentication required %s", realm ); */
if( username && password ) {
DEBUG_WEBDAV( "Authentication required %s", username );
if( ctx->dav_session.user ) {
/* allow user without password */
if( strlen( ctx->dav_session.user ) < NE_ABUFSIZ ) {
strcpy( username, ctx->dav_session.user );
}
if( ctx->dav_session.pwd && strlen( ctx->dav_session.pwd ) < NE_ABUFSIZ ) {
strcpy( password, ctx->dav_session.pwd );
}
} else {
authcb = csync_get_auth_callback( ctx->csync_ctx );
if( authcb != NULL ){
/* call the csync callback */
DEBUG_WEBDAV("Call the csync callback for %s", realm );
memset( buf, 0, NE_ABUFSIZ );
(*authcb) ("Enter your username: ", buf, NE_ABUFSIZ-1, 1, 0, csync_get_userdata(ctx->csync_ctx) );
if( strlen(buf) < NE_ABUFSIZ ) {
strcpy( username, buf );
}
memset( buf, 0, NE_ABUFSIZ );
(*authcb) ("Enter your password: ", buf, NE_ABUFSIZ-1, 0, 0, csync_get_userdata(ctx->csync_ctx) );
if( strlen(buf) < NE_ABUFSIZ) {
strcpy( password, buf );
}
} else {
re = 1;
}
}
}
return re;
}
/*
* Authentication callback. Is set by ne_set_proxy_auth to be called
* from the neon lib to authenticate against a proxy. The data to authenticate
* against comes from mirall throught vio_module_init function.
*/
static int proxy_authentication_callback_by_neon( void *userdata, const char *realm, int attempt,
char *username, char *password)
{
csync_owncloud_ctx_t *ctx = (csync_owncloud_ctx_t*) userdata;
(void) realm;
if( ctx->dav_session.proxy_user && strlen( ctx->dav_session.proxy_user ) < NE_ABUFSIZ) {
strcpy( username, ctx->dav_session.proxy_user );
if( ctx->dav_session.proxy_pwd && strlen( ctx->dav_session.proxy_pwd ) < NE_ABUFSIZ) {
strcpy( password, ctx->dav_session.proxy_pwd );
}
}
/* NTLM needs several attempts */
return (attempt < 3) ? 0 : -1;
}
/* Configure the proxy depending on the variables */
static int configureProxy( csync_owncloud_ctx_t *ctx, ne_session *session )
{
int port = 8080;
int re = -1;
if( ! session ) return -1;
if( ! ctx->dav_session.proxy_type ) return 0; /* Go by NoProxy per default */
if( ctx->dav_session.proxy_port > 0 ) {
port = ctx->dav_session.proxy_port;
}
if( c_streq(ctx->dav_session.proxy_type, "NoProxy" )) {
DEBUG_WEBDAV("No proxy configured.");
re = 0;
} else if( c_streq(ctx->dav_session.proxy_type, "DefaultProxy") ||
c_streq(ctx->dav_session.proxy_type, "HttpProxy") ||
c_streq(ctx->dav_session.proxy_type, "HttpCachingProxy") ||
c_streq(ctx->dav_session.proxy_type, "Socks5Proxy")) {
if( ctx->dav_session.proxy_host ) {
DEBUG_WEBDAV("%s at %s:%d", ctx->dav_session.proxy_type, ctx->dav_session.proxy_host, port );
if (c_streq(ctx->dav_session.proxy_type, "Socks5Proxy")) {
ne_session_socks_proxy(session, NE_SOCK_SOCKSV5, ctx->dav_session.proxy_host, port,
ctx->dav_session.proxy_user, ctx->dav_session.proxy_pwd);
} else {
ne_session_proxy(session, ctx->dav_session.proxy_host, port );
}
re = 2;
} else {
DEBUG_WEBDAV("%s requested but no proxy host defined.", ctx->dav_session.proxy_type );
/* we used to try ne_system_session_proxy here, but we should rather err out
to behave exactly like the caller. */
}
} else {
DEBUG_WEBDAV( "Unsupported Proxy: %s", ctx->dav_session.proxy_type );
}
return re;
}
/*
* This hook is called for with the response of a request. Here its checked
* if a Set-Cookie header is there for the PHPSESSID. The key is stored into
* the webdav session to be added to subsequent requests.
*/
static void post_request_hook(ne_request *req, void *userdata, const ne_status *status)
{
const char *set_cookie_header = NULL;
const char *sc = NULL;
char *key = NULL;
csync_owncloud_ctx_t *ctx = (csync_owncloud_ctx_t*) userdata;
if (ctx->dav_session.session_key)
return; /* We already have a session cookie, and we should ignore other ones */
if(!(status && req)) return;
if( status->klass == 2 || status->code == 401 ) {
/* successful request */
set_cookie_header = ne_get_response_header( req, "Set-Cookie" );
if( set_cookie_header ) {
DEBUG_WEBDAV(" Set-Cookie found: %s", set_cookie_header);
/* try to find a ', ' sequence which is the separator of neon if multiple Set-Cookie
* headers are there.
* The following code parses a string like this:
* Set-Cookie: 50ace6bd8a669=p537brtt048jh8srlp2tuep7em95nh9u98mj992fbqc47d1aecp1;
*/
sc = set_cookie_header;
while(sc) {
const char *sc_val = sc;
const char *sc_end = sc_val;
int cnt = 0;
int len = strlen(sc_val); /* The length of the rest of the header string. */
while( cnt < len && *sc_end != ';' && *sc_end != ',') {
cnt++;
sc_end++;
}
if( cnt == len ) {
/* exit: We are at the end. */
sc = NULL;
} else if( *sc_end == ';' ) {
/* We are at the end of the session key. */
int keylen = sc_end-sc_val;
if( key ) {
int oldlen = strlen(key);
key = c_realloc(key, oldlen + 2 + keylen+1);
strcpy(key + oldlen, "; ");
strncpy(key + oldlen + 2, sc_val, keylen);
key[oldlen + 2 + keylen] = '\0';
} else {
key = c_malloc(keylen+1);
strncpy( key, sc_val, keylen );
key[keylen] = '\0';
}
/* now search for a ',' to find a potential other header entry */
while(cnt < len && *sc_end != ',') {
cnt++;
sc_end++;
}
if( cnt < len )
sc = sc_end+2; /* mind the space after the comma */
else
sc = NULL;
} else if( *sc_end == ',' ) {
/* A new entry is to check. */
if( *(sc_end + 1) == ' ') {
sc = sc_end+2;
} else {
/* error condition */
sc = NULL;
}
}
}
}
} else {
DEBUG_WEBDAV("Request failed, don't take session header.");
}
if( key ) {
DEBUG_WEBDAV("----> Session-key: %s", key);
SAFE_FREE(ctx->dav_session.session_key);
ctx->dav_session.session_key = key;
}
}
/*
* this hook is called just after a request has been created, before its sent.
* Here it is used to set the proxy connection header if available.
*/
static void request_created_hook(ne_request *req, void *userdata,
const char *method, const char *requri)
{
// FIXME Can possibly be merged with pre_send_hook
csync_owncloud_ctx_t *ctx = (csync_owncloud_ctx_t *) userdata;
(void) method;
(void) requri;
if( !req ) return;
if(ctx->dav_session.proxy_type) {
/* required for NTLM */
ne_add_request_header(req, "Proxy-Connection", "Keep-Alive");
}
}
/*
* this hook is called just before a request has been sent.
* Here it is used to set the session cookie if available.
*/
static void pre_send_hook(ne_request *req, void *userdata,
ne_buffer *header)
{
csync_owncloud_ctx_t *ctx = (csync_owncloud_ctx_t *) userdata;
if( !req ) return;
if(ctx->dav_session.session_key) {
ne_buffer_concat(header, "Cookie: ", ctx->dav_session.session_key, "\r\n", NULL);
} else {
DEBUG_WEBDAV("csync pre_send_hook We don't have a Auth Cookie (session_key), this is wrong!");
}
}
static int post_send_hook(ne_request *req, void *userdata,
const ne_status *status)
{
const char *location;
csync_owncloud_ctx_t *ctx = (csync_owncloud_ctx_t *) userdata;
(void) status;
location = ne_get_response_header(req, "Location");
if( !location ) return NE_OK;
if( ctx->dav_session.redir_callback ) {
if( ctx->dav_session.redir_callback( ctx->csync_ctx, location ) ) {
return NE_REDIRECT;
} else {
return NE_RETRY;
}
}
return NE_REDIRECT;
}
/*
* Connect to a DAV server
* This function sets the flag _connected if the connection is established
* and returns if the flag is set, so calling it frequently is save.
*/
int dav_connect(CSYNC *csyncCtx, const char *base_url) {
int useSSL = 0;
int rc;
char protocol[6] = {'\0'};
char uaBuf[256];
char *path = NULL;
char *scheme = NULL;
char *host = NULL;
unsigned int port = 0;
int proxystate = -1;
csync_owncloud_ctx_t *ctx = csyncCtx->owncloud_context;
struct csync_client_certs_s* clientCerts = csyncCtx->clientCerts;
if (ctx->_connected) {
return 0;
}
rc = c_parse_uri( base_url, &scheme,
&ctx->dav_session.user,
&ctx->dav_session.pwd,
&host, &port, &path );
if( rc < 0 ) {
DEBUG_WEBDAV("Failed to parse uri %s", base_url );
goto out;
}
DEBUG_WEBDAV("* scheme %s", scheme );
DEBUG_WEBDAV("* host %s", host );
DEBUG_WEBDAV("* port %u", port );
DEBUG_WEBDAV("* path %s", path );
if( strcmp( scheme, "owncloud" ) == 0 || strcmp( scheme, "http" ) == 0 ) {
strcpy( protocol, "http");
} else if( strcmp( scheme, "ownclouds" ) == 0 || strcmp( scheme, "https") == 0 ) {
strcpy( protocol, "https");
useSSL = 1;
} else {
DEBUG_WEBDAV("Invalid scheme %s, go out here!", scheme );
rc = -1;
goto out;
}
DEBUG_WEBDAV("* user %s", ctx->dav_session.user ? ctx->dav_session.user : "");
if (port == 0) {
port = ne_uri_defaultport(protocol);
}
ctx->dav_session.ctx = ne_session_create( protocol, host, port);
if (ctx->dav_session.ctx == NULL) {
DEBUG_WEBDAV("Session create with protocol %s failed", protocol );
rc = -1;
goto out;
}
if (ctx->dav_session.read_timeout != 0) {
ne_set_read_timeout(ctx->dav_session.ctx, ctx->dav_session.read_timeout);
DEBUG_WEBDAV("Timeout set to %u seconds", ctx->dav_session.read_timeout );
}
// Should never take more than some seconds, 30 is really a max.
ne_set_connect_timeout(ctx->dav_session.ctx, 30);
snprintf( uaBuf, sizeof(uaBuf), "Mozilla/5.0 (%s) mirall/%s (csyncoC)",
CSYNC_STRINGIFY( MIRALL_VERSION ), csync_owncloud_get_platform() );
ne_set_useragent( ctx->dav_session.ctx, uaBuf);
ne_set_server_auth(ctx->dav_session.ctx, authentication_callback_by_neon, ctx);
if( useSSL ) {
if (!ne_has_support(NE_FEATURE_SSL)) {
DEBUG_WEBDAV("Error: SSL is not enabled.");
rc = -1;
goto out;
}
if(clientCerts != NULL) {
ne_ssl_client_cert *clicert;
DEBUG_WEBDAV("dav_connect: certificatePath and certificatePasswd are set, so we use it" );
DEBUG_WEBDAV(" with certificatePath: %s", clientCerts->certificatePath );
DEBUG_WEBDAV(" with certificatePasswd: %s", clientCerts->certificatePasswd );
clicert = ne_ssl_clicert_read ( clientCerts->certificatePath );
if ( clicert == NULL ) {
DEBUG_WEBDAV ( "Error read certificate : %s", ne_get_error ( ctx->dav_session.ctx ) );
} else {
if ( ne_ssl_clicert_encrypted ( clicert ) ) {
int rtn = ne_ssl_clicert_decrypt ( clicert, clientCerts->certificatePasswd );
if ( !rtn ) {
DEBUG_WEBDAV ( "Certificate was deciphered successfully." );
ne_ssl_set_clicert ( ctx->dav_session.ctx, clicert );
} else {
DEBUG_WEBDAV ( "Errors while deciphering certificate: %s", ne_get_error ( ctx->dav_session.ctx ) );
}
}
}
} else {
DEBUG_WEBDAV("dav_connect: error with csync_client_certs_s* clientCerts");
}
ne_ssl_trust_default_ca( ctx->dav_session.ctx );
ne_ssl_set_verify( ctx->dav_session.ctx, ssl_callback_by_neon, ctx);
}
/* Hook called when a request is created. It sets the proxy connection header. */
ne_hook_create_request( ctx->dav_session.ctx, request_created_hook, ctx );
/* Hook called after response headers are read. It gets the Session ID. */
ne_hook_post_headers( ctx->dav_session.ctx, post_request_hook, ctx );
/* Hook called before a request is sent. It sets the cookies. */
ne_hook_pre_send( ctx->dav_session.ctx, pre_send_hook, ctx );
/* Hook called after request is dispatched. Used for handling possible redirections. */
ne_hook_post_send( ctx->dav_session.ctx, post_send_hook, ctx );
/* Proxy support */
proxystate = configureProxy( ctx, ctx->dav_session.ctx );
if( proxystate < 0 ) {
DEBUG_WEBDAV("Error: Proxy-Configuration failed.");
} else if( proxystate > 0 ) {
ne_set_proxy_auth( ctx->dav_session.ctx, proxy_authentication_callback_by_neon, ctx );
}
ctx->_connected = 1;
rc = 0;
out:
SAFE_FREE(path);
SAFE_FREE(host);
SAFE_FREE(scheme);
return rc;
}
char *owncloud_error_string(CSYNC* ctx)
{
return ctx->owncloud_context->dav_session.error_string;
}
int owncloud_commit(CSYNC* ctx) {
if (!ctx->owncloud_context) {
return 0;
}
if( ctx->owncloud_context->dav_session.ctx ) {
ne_forget_auth(ctx->owncloud_context->dav_session.ctx);
ne_session_destroy(ctx->owncloud_context->dav_session.ctx );
ctx->owncloud_context->dav_session.ctx = 0;
}
/* DEBUG_WEBDAV( "********** vio_module_shutdown" ); */
ctx->owncloud_context->dav_session.ctx = 0;
// ne_sock_exit();
ctx->owncloud_context->_connected = 0; /* triggers dav_connect to go through the whole neon setup */
SAFE_FREE( ctx->owncloud_context->dav_session.user );
SAFE_FREE( ctx->owncloud_context->dav_session.pwd );
SAFE_FREE( ctx->owncloud_context->dav_session.session_key);
SAFE_FREE( ctx->owncloud_context->dav_session.error_string );
return 0;
}
void owncloud_destroy(CSYNC* ctx)
{
owncloud_commit(ctx);
SAFE_FREE(ctx->owncloud_context);
if (ctx->clientCerts) {
SAFE_FREE(ctx->clientCerts->certificatePasswd);
SAFE_FREE(ctx->clientCerts->certificatePath);
SAFE_FREE(ctx->clientCerts);
}
ne_sock_exit();
}
int owncloud_set_property(CSYNC* ctx, const char *key, void *data) {
#define READ_STRING_PROPERTY(P) \
if (c_streq(key, #P)) { \
SAFE_FREE(ctx->owncloud_context->dav_session.P); \
ctx->owncloud_context->dav_session.P = c_strdup((const char*)data); \
return 0; \
}
READ_STRING_PROPERTY(session_key)
READ_STRING_PROPERTY(proxy_type)
READ_STRING_PROPERTY(proxy_host)
READ_STRING_PROPERTY(proxy_user)
READ_STRING_PROPERTY(proxy_pwd)
#undef READ_STRING_PROPERTY
if (c_streq(key, "proxy_port")) {
ctx->owncloud_context->dav_session.proxy_port = *(int*)(data);
return 0;
}
if (c_streq(key, "read_timeout") || c_streq(key, "timeout")) {
ctx->owncloud_context->dav_session.read_timeout = *(int*)(data);
return 0;
}
if( c_streq(key, "get_dav_session")) {
/* Give the ne_session to the caller */
*(ne_session**)data = ctx->owncloud_context->dav_session.ctx;
return 0;
}
if( c_streq(key, "redirect_callback")) {
if (data) {
csync_owncloud_redirect_callback_t* cb_wrapper = data;
ctx->owncloud_context->dav_session.redir_callback = *cb_wrapper;
} else {
ctx->owncloud_context->dav_session.redir_callback = NULL;
}
}
if( c_streq(key, "SSLClientCerts")) {
if(ctx->clientCerts != NULL) {
SAFE_FREE(ctx->clientCerts->certificatePasswd);
SAFE_FREE(ctx->clientCerts->certificatePath);
SAFE_FREE(ctx->clientCerts);
ctx->clientCerts = NULL;
}
if (data) {
struct csync_client_certs_s* clientCerts = (struct csync_client_certs_s*) data;
struct csync_client_certs_s* newCerts = c_malloc(sizeof(struct csync_client_certs_s));
newCerts->certificatePath = c_strdup(clientCerts->certificatePath);
newCerts->certificatePasswd = c_strdup(clientCerts->certificatePasswd);
ctx->clientCerts = newCerts;
} else {
DEBUG_WEBDAV("error: in owncloud_set_property for 'SSLClientCerts'" );
}
}
return -1;
}
void owncloud_init(CSYNC* ctx) {
ne_sock_init();
ctx->owncloud_context = c_malloc( sizeof( struct csync_owncloud_ctx_s ));
ctx->owncloud_context->csync_ctx = ctx; // back reference
}
/* vim: set ts=4 sw=4 et cindent: */
-36
Ver Arquivo
@@ -1,36 +0,0 @@
/*
* libcsync -- a library to sync a directory with another
*
* Copyright (c) 2011 by Andreas Schneider <asn@cryptomilk.org>
* Copyright (c) 2012 by Klaas Freitag <freitag@owncloud.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef CSYNC_OWNCLOUD_H
#define CSYNC_OWNCLOUD_H
#include "csync.h"
#include "vio/csync_vio.h"
// Public API used by csync
int owncloud_commit(CSYNC* ctx);
void owncloud_destroy(CSYNC* ctx);
char *owncloud_error_string(CSYNC* ctx);
int owncloud_set_property(CSYNC* ctx, const char *key, void *data);
void owncloud_init(CSYNC* ctx);
int dav_connect(CSYNC* ctx, const char *base_url);
#endif /* CSYNC_OWNCLOUD_H */
-115
Ver Arquivo
@@ -1,115 +0,0 @@
/*
* libcsync -- a library to sync a directory with another
*
* Copyright (c) 2011 by Andreas Schneider <asn@cryptomilk.org>
* Copyright (c) 2012 by Klaas Freitag <freitag@owncloud.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef CSYNC_OWNCLOUD_PRIVATE_H
#define CSYNC_OWNCLOUD_PRIVATE_H
#include <errno.h>
#include <stdio.h>
#include <time.h>
#include <limits.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "config_csync.h"
#ifdef NEON_WITH_LFS /* Switch on LFS in libneon. Never remove the NE_LFS! */
#define NE_LFS
#endif
#include <neon/ne_basic.h>
#include <neon/ne_socket.h>
#include <neon/ne_session.h>
#include <neon/ne_request.h>
#include <neon/ne_props.h>
#include <neon/ne_auth.h>
#include <neon/ne_dates.h>
#include <neon/ne_compress.h>
#include <neon/ne_redirect.h>
#include "c_rbtree.h"
#include "c_lib.h"
#include "csync.h"
#include "csync_misc.h"
#include "csync_macros.h"
#include "c_private.h"
#include "vio/csync_vio.h"
#include "csync_log.h"
#include "csync_owncloud.h"
#define DEBUG_WEBDAV(...) csync_log( 9, "oc_module", __VA_ARGS__);
typedef int (*csync_owncloud_redirect_callback_t)(CSYNC* ctx, const char* uri);
/* Struct with the WebDAV session */
struct dav_session_s {
ne_session *ctx;
char *user;
char *pwd;
char *proxy_type;
char *proxy_host;
int proxy_port;
char *proxy_user;
char *proxy_pwd;
char *session_key;
char *error_string;
int read_timeout;
csync_owncloud_redirect_callback_t redir_callback;
};
struct csync_owncloud_ctx_s {
CSYNC *csync_ctx;
// For the WebDAV connection
struct dav_session_s dav_session; /* The DAV Session, initialised in dav_connect */
int _connected; /* flag to indicate if a connection exists, ie.
the dav_session is valid */
};
typedef struct csync_owncloud_ctx_s csync_owncloud_ctx_t;
//typedef csync_owncloud_ctx_t* csync_owncloud_ctx_p;
void set_errno_from_http_errcode( int err );
void set_error_message( csync_owncloud_ctx_t *ctx, const char *msg );
void set_errno_from_neon_errcode(csync_owncloud_ctx_t *ctx, int neon_code );
int http_result_code_from_session(csync_owncloud_ctx_t *ctx);
void set_errno_from_session(csync_owncloud_ctx_t *ctx);
time_t oc_httpdate_parse( const char *date );
const char* csync_owncloud_get_platform(void);
char *_cleanPath( const char* uri );
#endif // CSYNC_OWNCLOUD_PRIVATE_H
-125
Ver Arquivo
@@ -1,125 +0,0 @@
/*
* libcsync -- a library to sync a directory with another
*
* Copyright (c) 2011 by Andreas Schneider <asn@cryptomilk.org>
* Copyright (c) 2012 by Klaas Freitag <freitag@owncloud.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "csync_owncloud.h"
#include "csync_owncloud_private.h"
#include "csync_misc.h"
void set_errno_from_http_errcode( int err ) {
int new_errno = 0;
switch(err) {
case 200: /* OK */
case 201: /* Created */
case 202: /* Accepted */
case 203: /* Non-Authoritative Information */
case 204: /* No Content */
case 205: /* Reset Content */
case 207: /* Multi-Status */
case 304: /* Not Modified */
new_errno = 0;
break;
case 401: /* Unauthorized */
case 402: /* Payment Required */
case 407: /* Proxy Authentication Required */
case 405:
new_errno = EPERM;
break;
case 301: /* Moved Permanently */
case 303: /* See Other */
case 404: /* Not Found */
case 410: /* Gone */
new_errno = ENOENT;
break;
case 408: /* Request Timeout */
case 504: /* Gateway Timeout */
new_errno = EAGAIN;
break;
case 423: /* Locked */
new_errno = EACCES;
break;
case 400: /* Bad Request */
case 403: /* Forbidden */
case 409: /* Conflict */
case 411: /* Length Required */
case 412: /* Precondition Failed */
case 414: /* Request-URI Too Long */
case 415: /* Unsupported Media Type */
case 424: /* Failed Dependency */
case 501: /* Not Implemented */
new_errno = EINVAL;
break;
case 507: /* Insufficient Storage */
new_errno = ENOSPC;
break;
case 206: /* Partial Content */
case 300: /* Multiple Choices */
case 302: /* Found */
case 305: /* Use Proxy */
case 306: /* (Unused) */
case 307: /* Temporary Redirect */
case 406: /* Not Acceptable */
case 416: /* Requested Range Not Satisfiable */
case 417: /* Expectation Failed */
case 422: /* Unprocessable Entity */
case 500: /* Internal Server Error */
case 502: /* Bad Gateway */
case 505: /* HTTP Version Not Supported */
new_errno = EIO;
break;
case 503: /* Service Unavailable */
new_errno = ERRNO_SERVICE_UNAVAILABLE;
break;
case 413: /* Request Entity too Large */
new_errno = EFBIG;
break;
default:
new_errno = EIO;
}
errno = new_errno;
}
// as per http://sourceforge.net/p/predef/wiki/OperatingSystems/
// extend as required
const char* csync_owncloud_get_platform() {
#if defined (_WIN32)
return "Windows";
#elif defined(__APPLE__)
return "Macintosh";
#elif defined(__gnu_linux__)
return "Linux";
#elif defined(__DragonFly__)
/* might also define __FreeBSD__ */
return "DragonFlyBSD";
#elif defined(__FreeBSD__)
return "FreeBSD";
#elif defined(__NetBSD__)
return "NetBSD";
#elif defined(__OpenBSD__)
return "OpenBSD";
#elif defined(sun) || defined(__sun)
return "Solaris";
#else
return "Unknown OS";
#endif
}
+4 -10
Ver Arquivo
@@ -77,9 +77,6 @@ enum csync_replica_e {
typedef struct csync_file_stat_s csync_file_stat_t;
struct csync_owncloud_ctx_s; // csync_owncloud.c
/**
* @brief csync public structure
*/
@@ -169,9 +166,6 @@ struct csync_s {
bool db_is_empty;
bool ignore_hidden_files;
struct csync_owncloud_ctx_s *owncloud_context;
};
@@ -185,11 +179,11 @@ struct csync_file_stat_s {
size_t pathlen; /* u64 */
uint64_t inode; /* u64 */
mode_t mode; /* u32 */
int type; /* u32 */
int child_modified;/*bool*/
int should_update_metadata; /*bool: specify that the etag, or the remote perm or fileid has
unsigned int type : 4;
unsigned int child_modified : 1;
unsigned int should_update_metadata : 1; /*specify that the etag, or the remote perm or fileid has
changed and need to be updated on the db even for INSTRUCTION_NONE */
int has_ignored_files; /*bool: specify that a directory, or child directory contains ignored files */
unsigned int has_ignored_files : 1; /* specify that a directory, or child directory contains ignored files */
char *destpath; /* for renames */
const char *etag;
+8 -38
Ver Arquivo
@@ -416,37 +416,10 @@ csync_file_stat_t *csync_statedb_get_stat_by_inode(CSYNC *ctx,
return st;
}
/* Get the etag. */
char *csync_statedb_get_etag( CSYNC *ctx, uint64_t jHash ) {
char *ret = NULL;
csync_file_stat_t *fs = NULL;
if( !ctx ) {
return NULL;
}
if( ! csync_get_statedb_exists(ctx)) return ret;
fs = csync_statedb_get_stat_by_hash(ctx, jHash );
if( fs ) {
if( fs->etag ) {
ret = c_strdup(fs->etag);
}
csync_file_stat_free(fs);
}
return ret;
}
#define BELOW_PATH_QUERY "SELECT phash, pathlen, path, inode, uid, gid, mode, modtime, type, md5, fileid, remotePerm, filesize, ignoredChildrenRemote FROM metadata WHERE pathlen>? AND path LIKE(?)"
int csync_statedb_get_below_path( CSYNC *ctx, const char *path ) {
int rc;
sqlite3_stmt *stmt = NULL;
int64_t cnt = 0;
char *likepath;
int asp;
int min_path_len;
if( !path ) {
return -1;
@@ -456,7 +429,12 @@ int csync_statedb_get_below_path( CSYNC *ctx, const char *path ) {
return -1;
}
SQLITE_BUSY_HANDLED(sqlite3_prepare_v2(ctx->statedb.db, BELOW_PATH_QUERY, -1, &stmt, NULL));
/* Select the entries for anything that starts with (path+'/')
* In other words, anything that is between path+'/' and path+'0',
* (because '0' follows '/' in ascii)
*/
const char *below_path_query = "SELECT phash, pathlen, path, inode, uid, gid, mode, modtime, type, md5, fileid, remotePerm, filesize, ignoredChildrenRemote FROM metadata WHERE path > (?||'/') AND path < (?||'0')";
SQLITE_BUSY_HANDLED(sqlite3_prepare_v2(ctx->statedb.db, below_path_query, -1, &stmt, NULL));
ctx->statedb.lastReturnValue = rc;
if( rc != SQLITE_OK ) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Unable to create stmt for below path query.");
@@ -467,15 +445,8 @@ int csync_statedb_get_below_path( CSYNC *ctx, const char *path ) {
return -1;
}
asp = asprintf( &likepath, "%s/%%%%", path);
if (asp < 0) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "asprintf failed!");
return -1;
}
min_path_len = strlen(path);
sqlite3_bind_int(stmt, 1, min_path_len);
sqlite3_bind_text(stmt, 2, likepath, -1, SQLITE_STATIC);
sqlite3_bind_text(stmt, 1, path, -1, SQLITE_STATIC);
sqlite3_bind_text(stmt, 2, path, -1, SQLITE_STATIC);
cnt = 0;
@@ -518,7 +489,6 @@ int csync_statedb_get_below_path( CSYNC *ctx, const char *path ) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "%" PRId64 " entries read below path %s from db.", cnt, path);
}
sqlite3_finalize(stmt);
SAFE_FREE(likepath);
return 0;
}
+13 -42
Ver Arquivo
@@ -270,10 +270,6 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
((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, fs->remotePerm, tmp->remotePerm, tmp->has_ignored_files );
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 && (!_csync_mtime_equal(fs->mtime, tmp->modtime)
// zero size in statedb can happen during migration
@@ -584,7 +580,6 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
char *d_name = NULL;
csync_vio_handle_t *dh = NULL;
csync_vio_file_stat_t *dirent = NULL;
csync_vio_file_stat_t *fs = NULL;
csync_file_stat_t *previous_fs = NULL;
int read_from_db = 0;
int rc = 0;
@@ -688,8 +683,8 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
}
/* skip "." and ".." */
if (d_name[0] == '.' && (d_name[1] == '\0'
|| (d_name[1] == '.' && d_name[2] == '\0'))) {
if ( (d_name[0] == '.' && d_name[1] == '\0')
|| (d_name[0] == '.' && d_name[1] == '.' && d_name[2] == '\0')) {
csync_vio_file_stat_destroy(dirent);
dirent = NULL;
continue;
@@ -741,15 +736,21 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
/* Only for the local replica we have to stat(), for the remote one we have all data already */
if (ctx->replica == LOCAL_REPLICA) {
fs = csync_vio_file_stat_new();
res = csync_vio_stat(ctx, filename, fs);
res = csync_vio_stat(ctx, filename, dirent);
} else {
fs = dirent;
res = 0;
}
/* if the filename starts with a . we consider it a hidden file
* For windows, the hidden state is also discovered within the vio
* local stat function.
*/
if( d_name[0] == '.' ) {
dirent->flags |= CSYNC_VIO_FILE_FLAGS_HIDDEN;
}
if( res == 0) {
switch (fs->type) {
switch (dirent->type) {
case CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK:
flag = CSYNC_FTW_FLAG_SLINK;
break;
@@ -772,42 +773,12 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
flag = CSYNC_FTW_FLAG_NSTAT;
}
if( ctx->current == LOCAL_REPLICA ) {
char *etag = NULL;
int len = strlen( path );
uint64_t h = c_jhash64((uint8_t *) path, len, 0);
etag = csync_statedb_get_etag( ctx, h );
if(_last_db_return_error(ctx)) {
ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
SAFE_FREE(etag);
goto error;
}
if( etag ) {
SAFE_FREE(fs->etag);
fs->etag = etag;
fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_ETAG;
if( c_streq(etag, "")) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Uniq ID from Database is EMPTY: %s", path);
} else {
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Uniq ID from Database: %s -> %s", path, fs->etag ? fs->etag : "<NULL>" );
}
}
}
previous_fs = ctx->current_fs;
/* Call walker function for each file */
rc = fn(ctx, filename, fs, flag);
rc = fn(ctx, filename, dirent, flag);
/* this function may update ctx->current and ctx->read_from_db */
/* Only for the local replica we have to destroy stat(), for the remote one it is a pointer to dirent */
if (ctx->replica == LOCAL_REPLICA) {
csync_vio_file_stat_destroy(fs);
}
if (rc < 0) {
if (CSYNC_STATUS_IS_OK(ctx->status_code)) {
ctx->status_code = CSYNC_STATUS_UPDATE_ERROR;
-57
Ver Arquivo
@@ -1,57 +0,0 @@
project(httpbflib C)
find_package(Neon)
set(HTTPBF_PUBLIC_INCLUDE_DIRS
${CMAKE_CURRENT_SOURCE_DIR}/src
${NEON_INCLUDE_DIRS}
CACHE INTERNAL "httpbflib public include directories"
)
set(HTTPBF_LIBRARY
httpbf
CACHE INTERNAL "httpbf library"
)
set(HTTPBF_LINK_LIBRARIES
${HTTPBF_LIBRARY}
)
set(httpbf_SRCS
src/httpbf.c
)
set(httpbf_HEADERS
src/httpbf.h
)
include_directories(
${HTTPBF_PUBLIC_INCLUDE_DIRS}
)
add_library(${HTTPBF_LIBRARY} STATIC ${httpbf_SRCS})
target_link_libraries(${HTTPBF_LIBRARY} ${NEON_LIBRARIES})
if(NOT WIN32)
add_definitions( -fPIC )
endif()
INSTALL(
TARGETS
${HTTPBF_LIBRARY}
LIBRARY DESTINATION
${LIB_INSTALL_DIR}
ARCHIVE DESTINATION
${LIB_INSTALL_DIR}
RUNTIME DESTINATION
${BIN_INSTALL_DIR}
)
if (NOT APPLE)
INSTALL(
FILES
${httpbf_HEADERS}
DESTINATION
${CMAKE_INSTALL_INCLUDEDIR}
)
endif (NOT APPLE)
-29
Ver Arquivo
@@ -1,29 +0,0 @@
This is a little code that does ownCloud file chunking.
Basically to put a local file to an url:
(Also see the client example code in client dir.)
/* Initialize the transfer, get a transfer struct. */
hbf_transfer_t *trans = hbf_init_transfer( url );
Hbf_State state;
if( trans ) {
int fd = open_local_file( file );
/* create a neon session to use for the transfer */
ne_session *session = create_neon_session(uri);
if( session && fd > -1 ) {
/* Prepare the list of chunks, ie. calculate chunks and write back to trans. */
state = hbf_splitlist(trans, fd);
if( state == HBF_SUCCESS ) {
/* Transfer all the chunks through the HTTP session using PUT. */
state = hbf_transfer( session, trans, "PUT" );
}
}
}
GET a large file:
Do GET Range requests.
-36
Ver Arquivo
@@ -1,36 +0,0 @@
project(client C)
set(CLIENT_EXECUTABLE httpbfclient CACHE INTERNAL "httpbf client")
set(CLIENT_LINK_LIBRARIES ${NEON_LIBRARIES} ${HBF_LIBRARY})
set(HTTPBF_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/src})
if(NOT LINUX)
list(APPEND CLIENT_LINK_LIBRARIES ${ARGP_LIBRARIES})
endif()
set(client_SRCS
httpbf_client.c
)
include_directories(
${HTTPBF_INCLUDE_DIR}
${HTTPBF_PUBLIC_INCLUDE_DIRS}
)
add_executable(${CLIENT_EXECUTABLE} ${client_SRCS})
target_link_libraries(${CLIENT_EXECUTABLE} ${CLIENT_LINK_LIBRARIES})
set_target_properties(
${CLIENT_EXECUTABLE}
PROPERTIES
OUTPUT_NAME
httpbf
)
# install( TARGETS ${CLIENT_EXECUTABLE} DESTINATION ${BIN_INSTALL_DIR} )
install(TARGETS ${CLIENT_EXECUTABLE} DESTINATION bin)
-225
Ver Arquivo
@@ -1,225 +0,0 @@
/*
* httpbf - send big files via http
*
* Copyright (c) 2012 Klaas Freitag <freitag@owncloud.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <getopt.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <neon/ne_auth.h>
#include "httpbf.h"
/* Program documentation. */
static char doc[] = "Usage: httpbf [OPTION...] LOCAL REMOTEDIR\n\
httpbf - command line client to upload big files via http.\n\
\n\
Transfer a big file to a remote directory on ownCloud.\n\
\n\
-?, --help Give this help list\n\
--usage Give a short usage message\n\
-V, --version Print program version\n\
";
static char _user[NE_ABUFSIZ];
static char _pwd[NE_ABUFSIZ];
/* The options we understand. */
static const struct option long_options[] =
{
{"version", no_argument, 0, 'V' },
{"usage", no_argument, 0, 'h' },
{0, 0, 0, 0}
};
static const char* httpbf_version = "0.1";
static void print_version()
{
printf( "%s\n", httpbf_version );
exit(0);
}
static void print_help()
{
printf( "%s\n", doc );
exit(0);
}
static int ne_auth( void *userdata, const char *realm, int attempt,
char *username, char *password)
{
(void) userdata;
(void) realm;
if( username && password ) {
if( _user ) {
/* allow user without password */
if( strlen( _user ) < NE_ABUFSIZ ) {
strcpy( username, _user );
}
if( _pwd && strlen( _pwd ) < NE_ABUFSIZ ) {
strcpy( password, _pwd );
}
}
}
return attempt;
}
static int parse_args(int argc, char **argv)
{
while(optind < argc) {
int c = -1;
struct option *opt = NULL;
int result = getopt_long( argc, argv, "Vh", long_options, &c );
if( result == -1 ) {
break;
}
switch(result) {
case 'V':
print_version();
break;
case 'h':
print_help();
break;
case 0:
opt = (struct option*)&(long_options[c]);
if(strcmp(opt->name, "no-name-yet")) {
} else {
fprintf(stderr, "Argument: No idea what!\n");
}
break;
default:
break;
}
}
return optind;
}
static ne_session* create_neon_session( const char *url )
{
ne_uri uri;
ne_session *sess = NULL;
memset( _user, 0, NE_ABUFSIZ );
memset( _pwd, 0, NE_ABUFSIZ );
if( ne_uri_parse( url, &uri ) == 0 ) {
unsigned int port = ne_uri_defaultport(uri.scheme);
if( uri.userinfo ) {
char *slash = NULL;
strcpy( _user, uri.userinfo );
slash = strchr( _user, ':');
if( slash ) {
strcpy( _pwd, slash+1);
*slash = 0;
}
}
sess = ne_session_create(uri.scheme, uri.host, port);
ne_set_server_auth(sess, ne_auth, 0 );
ne_uri_free(&uri);
}
return sess;
}
static int open_local_file( const char *file )
{
int fd = -1;
if( !file ) return -1;
fd = open(file, O_RDONLY);
return fd;
}
static void transfer( const char* local, const char* uri )
{
if( !(local && uri )) return;
char *whole_url;
int len;
char *filename = basename(local);
if( ! filename ) {
return;
}
len = strlen(filename)+strlen(uri)+2;
whole_url = malloc( len );
strcpy(whole_url, uri);
strcat(whole_url, "/");
strcat(whole_url, filename);
hbf_transfer_t *trans = hbf_init_transfer( whole_url );
Hbf_State state;
if( trans ) {
ne_session *session = create_neon_session(uri);
if( session ) {
int fd = open_local_file( local );
if( fd > -1 ) {
state = hbf_splitlist(trans, fd );
if( state == HBF_SUCCESS ) {
state = hbf_transfer( session, trans, "PUT" );
}
}
ne_session_destroy(session);
}
}
if( state != HBF_SUCCESS ) {
printf("Upload failed: %s\n", hbf_error_string(state));
printf(" HTTP result %d, Server Error: %s\n",
trans->status_code, trans->error_string ? trans->error_string : "<empty>" );
}
/* Print the result of the recent transfer */
hbf_free_transfer( trans );
free(whole_url);
}
int main(int argc, char **argv) {
int rc = 0;
char errbuf[256] = {0};
parse_args(argc, argv);
/* two options must remain as source and target */
/* printf("ARGC: %d -> optind: %d\n", argc, optind ); */
if( argc - optind < 2 ) {
print_help();
}
transfer( argv[optind], argv[optind+1]);
}
/* vim: set ts=8 sw=2 et cindent: */
-38
Ver Arquivo
@@ -1,38 +0,0 @@
project(httpbf C)
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
set(HTTPBF_PUBLIC_INCLUDE_DIRS
${CMAKE_CURRENT_SOURCE_DIR}
CACHE INTERNAL "httpbf public include directories"
)
set(HTTPBFLIB_PRIVATE_INCLUDE_DIRS
)
set(HBF_LIBRARY
httpbf
CACHE INTERNAL "httpbflib library"
)
set(HTTPBFLIB_LINK_LIBRARIES
${HBF_LIBRARY}
)
set(httpbflib_SRCS
httpbf.c
)
include_directories(
${NEON_INCLUDE_DIRS}
${GLIB2_INCLUDE_DIRS}
)
if(NOT WIN32)
add_definitions( -fPIC )
endif()
add_library(${HBF_LIBRARY} SHARED ${httpbflib_SRCS} )
target_link_libraries(${HBF_LIBRARY} ${NEON_LIBRARIES})
-688
Ver Arquivo
@@ -1,688 +0,0 @@
/*
* httpbf - send big files via http
*
* Copyright (c) 2012 Klaas Freitag <freitag@owncloud.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/timeb.h>
#include <sys/time.h>
#include <inttypes.h>
#include "httpbf.h"
#include <neon/ne_session.h>
#include <neon/ne_request.h>
#include <neon/ne_basic.h>
// #ifdef NDEBUG
// #define DEBUG_HBF(...)
// #else
#define DEBUG_HBF(...) { if(transfer->log_cb) { \
char buf[1024]; \
snprintf(buf, 1024, __VA_ARGS__); \
transfer->log_cb(__func__, buf, transfer->user_data); \
} }
// #endif
#define DEFAULT_BLOCK_SIZE (10*1024*1024)
/* Platform specific defines go here. */
#ifdef _WIN32
#define _hbf_fstat _fstat64
typedef struct stat64 hbf_stat_t;
#else
#define _hbf_fstat fstat
typedef struct stat hbf_stat_t;
#endif
static int transfer_id( hbf_stat_t *sb ) {
struct timeval tp;
int res;
int r;
if( gettimeofday(&tp, 0) < 0 ) {
return 0;
}
/* build a Unique ID:
* take the current epoch and shift 8 bits up to keep the least bits.
* than add the milliseconds, again shift by 8
* and finally add the least 8 bit of the inode of the file.
*/
res = tp.tv_sec; /* epoche value in seconds */
res = res << 8;
r = (sb->st_ino & 0xFF);
res += r; /* least six bit of inode */
res = res << sizeof(tp.tv_usec);
res += tp.tv_usec; /* milliseconds */
return res;
}
hbf_transfer_t *hbf_init_transfer( const char *dest_uri ) {
hbf_transfer_t * transfer = NULL;
transfer = malloc( sizeof(hbf_transfer_t) );
memset(transfer, 0, sizeof(hbf_transfer_t));
/* store the target uri */
transfer->url = strdup(dest_uri);
transfer->status_code = 200;
transfer->error_string = NULL;
transfer->start_id = 0;
transfer->block_size = DEFAULT_BLOCK_SIZE;
transfer->threshold = transfer->block_size;
transfer->modtime_accepted = 0;
transfer->oc_header_modtime = 0;
return transfer;
}
/* Create the splitlist of a given file descriptor */
Hbf_State hbf_splitlist(hbf_transfer_t *transfer, int fd ) {
hbf_stat_t sb;
int64_t num_blocks;
int64_t blk_size;
int64_t remainder = 0;
if( ! transfer ) {
return HBF_PARAM_FAIL;
}
if( fd <= 0 ) {
DEBUG_HBF("File descriptor is invalid.");
return HBF_PARAM_FAIL;
}
if( _hbf_fstat(fd, &sb) < 0 ) {
DEBUG_HBF("Failed to stat the file descriptor: errno = %d", errno);
return HBF_FILESTAT_FAIL;
}
/* Store the file characteristics. */
transfer->fd = fd;
transfer->stat_size = sb.st_size;
transfer->modtime = sb.st_mtime;
transfer->previous_etag = NULL;
#ifndef NDEBUG
transfer->calc_size = 0;
#endif
DEBUG_HBF("block_size: %" PRId64 " threshold: %" PRId64 " st_size: %" PRId64, transfer->block_size, transfer->threshold, sb.st_size );
/* calc the number of blocks to split in */
blk_size = transfer->block_size;
if (sb.st_size < transfer->threshold) {
blk_size = transfer->threshold;
}
num_blocks = sb.st_size / blk_size;
/* there migth be a remainder. */
remainder = sb.st_size - num_blocks * blk_size;
/* if there is a remainder, add one block */
if( remainder > 0 ) {
num_blocks++;
}
/* The file has size 0. There still needs to be at least one block. */
if( sb.st_size == 0 ) {
num_blocks = 1;
blk_size = 0;
}
DEBUG_HBF("num_blocks: %" PRId64 " rmainder: %" PRId64 " blk_size: %" PRId64, num_blocks, remainder, blk_size );
if( num_blocks ) {
int cnt;
int64_t overall = 0;
/* create a datastructure for the transfer data */
transfer->block_arr = calloc(num_blocks, sizeof(hbf_block_t*));
transfer->block_cnt = num_blocks;
transfer->transfer_id = transfer_id(&sb);
transfer->start_id = 0;
for( cnt=0; cnt < num_blocks; cnt++ ) {
/* allocate a block struct and fill */
hbf_block_t *block = malloc( sizeof(hbf_block_t) );
memset(block, 0, sizeof(hbf_block_t));
block->seq_number = cnt;
if( cnt > 0 ) {
block->start = cnt * blk_size;
}
block->size = blk_size;
block->state = HBF_NOT_TRANSFERED;
/* consider the remainder if we're already at the end */
if( cnt == num_blocks-1 && remainder > 0 ) {
block->size = remainder;
}
overall += block->size;
/* store the block data into the result array in the transfer */
*((transfer->block_arr)+cnt) = block;
DEBUG_HBF("created block %d (start: %" PRId64 " size: %" PRId64 ")", cnt, block->start, block->size );
}
#ifndef NDEBUG
transfer->calc_size = overall;
#endif
}
return HBF_SUCCESS;
}
void hbf_free_transfer( hbf_transfer_t *transfer ) {
int cnt;
if( !transfer ) return;
for( cnt = 0; cnt < transfer->block_cnt; cnt++ ) {
hbf_block_t *block = transfer->block_arr[cnt];
if( !block ) continue;
if( block->http_error_msg ) free( block->http_error_msg );
if( block->etag ) free( block->etag );
}
free( transfer->block_arr );
free( transfer->url );
free( transfer->file_id );
if( transfer->error_string) free( (void*) transfer->error_string );
free( transfer );
}
static char* get_transfer_url( hbf_transfer_t *transfer, int indx ) {
char *res = NULL;
hbf_block_t *block = NULL;
if( ! transfer ) return NULL;
if( indx >= transfer->block_cnt ) return NULL;
block = transfer->block_arr[indx];
if( ! block ) return NULL;
if( transfer->block_cnt == 1 ) {
/* Just one chunk. We send as an ordinary request without chunking. */
res = strdup( transfer->url );
} else {
char trans_id_str[32];
char trans_block_str[32];
char indx_str[32];
int len = 1; /* trailing zero. */
int tlen = 0;
tlen = sprintf( trans_id_str, "%u", transfer->transfer_id );
if( tlen < 0 ) {
return NULL;
}
len += tlen;
tlen = sprintf( trans_block_str, "%u", transfer->block_cnt );
if( tlen < 0 ) {
return NULL;
}
len += tlen;
tlen = sprintf( indx_str, "%u", indx );
if( tlen < 0 ) {
return NULL;
}
len += tlen;
len += strlen(transfer->url);
len += strlen("-chunking---");
res = malloc(len);
/* Note: must be %u for unsigned because one does not want '--' */
if( sprintf(res, "%s-chunking-%u-%u-%u", transfer->url, transfer->transfer_id,
transfer->block_cnt, indx ) < 0 ) {
return NULL;
}
}
return res;
}
/*
* perform one transfer of one block.
* returns HBF_TRANSFER_SUCCESS if the transfer of this block was a success
* returns HBF_SUCCESS if the server aknoweldge that he received all the blocks
*/
static int _hbf_dav_request(hbf_transfer_t *transfer, ne_request *req, int fd, hbf_block_t *blk ) {
Hbf_State state = HBF_TRANSFER_SUCCESS;
int res;
const ne_status *req_status = NULL;
const char *etag = NULL;
(void) transfer;
if( ! (blk && req) ) return HBF_PARAM_FAIL;
ne_set_request_body_fd(req, fd, blk->start, blk->size);
DEBUG_HBF("Block: %d , Start: %" PRId64 " and Size: %" PRId64 "", blk->seq_number, blk->start, blk->size );
res = ne_request_dispatch(req);
req_status = ne_get_status( req );
switch(res) {
case NE_OK:
blk->state = HBF_TRANSFER_FAILED;
state = HBF_FAIL;
etag = 0;
if( req_status->klass == 2 ) {
state = HBF_TRANSFER_SUCCESS;
blk->state = HBF_TRANSFER_SUCCESS;
etag = ne_get_response_header(req, "ETag");
if (etag && etag[0]) {
/* When there is an etag, it means the transfer was complete */
state = HBF_SUCCESS;
if( etag[0] == '"' && etag[ strlen(etag)-1] == '"') {
int len = strlen( etag )-2;
blk->etag = malloc( len+1 );
strncpy( blk->etag, etag+1, len );
blk->etag[len] = '\0';
} else {
blk->etag = strdup( etag );
}
} else {
/* DEBUG_HBF("OOOOOOOO No etag returned!"); */
}
/* check if the server was able to set the mtime already. */
etag = ne_get_response_header(req, "X-OC-MTime");
if( etag && strcmp(etag, "accepted") == 0 ) {
/* the server acknowledged that the mtime was set. */
transfer->modtime_accepted = 1;
}
etag = ne_get_response_header(req, "OC-FileID");
if( etag ) {
transfer->file_id = strdup( etag );
}
}
break;
case NE_AUTH:
state = HBF_AUTH_FAIL;
blk->state = HBF_TRANSFER_FAILED;
break;
case NE_PROXYAUTH:
state = HBF_PROXY_AUTH_FAIL;
blk->state = HBF_TRANSFER_FAILED;
break;
case NE_CONNECT:
state = HBF_CONNECT_FAIL;
blk->state = HBF_TRANSFER_FAILED;
break;
case NE_TIMEOUT:
state = HBF_TIMEOUT_FAIL;
blk->state = HBF_TRANSFER_FAILED;
break;
case NE_ERROR:
state = HBF_FAIL;
blk->state = HBF_TRANSFER_FAILED;
break;
}
blk->http_result_code = req_status->code;
if( req_status->reason_phrase ) {
blk->http_error_msg = strdup(req_status->reason_phrase);
}
return state;
}
Hbf_State hbf_validate_source_file( hbf_transfer_t *transfer ) {
Hbf_State state = HBF_SUCCESS;
hbf_stat_t sb;
if( transfer == NULL ) {
state = HBF_PARAM_FAIL;
}
if( state == HBF_SUCCESS ) {
if( transfer->fd <= 0 ) {
state = HBF_PARAM_FAIL;
}
}
if( state == HBF_SUCCESS ) {
int rc = _hbf_fstat( transfer->fd, &sb );
if( rc != 0 ) {
state = HBF_STAT_FAIL;
}
}
if( state == HBF_SUCCESS ) {
if( sb.st_mtime != transfer->modtime || sb.st_size != transfer->stat_size ) {
state = HBF_SOURCE_FILE_CHANGE;
}
}
return state;
}
/* Get the HTTP error code for the last request */
static int _hbf_http_error_code(ne_session *session) {
const char *msg = ne_get_error( session );
char *msg2;
int err;
err = strtol(msg, &msg2, 10);
if (msg == msg2) {
err = 0;
}
return err;
}
static Hbf_State _hbf_transfer_no_chunk(ne_session *session, hbf_transfer_t *transfer, const char *verb) {
int res;
const ne_status* req_status;
ne_request *req = ne_request_create(session, verb ? verb : "PUT", transfer->url);
if (!req)
return HBF_MEMORY_FAIL;
ne_add_request_header( req, "Content-Type", "application/octet-stream");
ne_set_request_body_fd(req, transfer->fd, 0, transfer->stat_size);
DEBUG_HBF("HBF: chunking not supported for %s", transfer->url);
res = ne_request_dispatch(req);
req_status = ne_get_status( req );
if (res == NE_OK && req_status->klass == 2) {
ne_request_destroy(req);
return HBF_SUCCESS;
}
if( transfer->error_string ) free( transfer->error_string );
transfer->error_string = strdup( ne_get_error(session) );
transfer->status_code = req_status->code;
ne_request_destroy(req);
return HBF_FAIL;
}
Hbf_State hbf_transfer( ne_session *session, hbf_transfer_t *transfer, const char *verb ) {
Hbf_State state = HBF_TRANSFER_SUCCESS;
int cnt;
if( ! session ) {
state = HBF_SESSION_FAIL;
}
if( ! transfer ) {
state = HBF_SPLITLIST_FAIL;
}
if( ! verb ) {
state = HBF_PARAM_FAIL;
}
if(state == HBF_TRANSFER_SUCCESS) {
DEBUG_HBF("%s request to %s", verb, transfer->url);
}
for( cnt=0; state == HBF_TRANSFER_SUCCESS && cnt < transfer->block_cnt; cnt++ ) {
/* cnt goes from O to block_cnt, but block_id starts at start_id and wrap around
* That way if we have not finished uploaded when we reach block_cnt, we re-upload
* the beginning of the file that the server did not have in cache anymore.
*/
int block_id = (cnt + transfer->start_id) % transfer->block_cnt;
hbf_block_t *block = transfer->block_arr[block_id];
char *transfer_url = NULL;
if( ! block ) state = HBF_PARAM_FAIL;
if( transfer->abort_cb ) {
int do_abort = (transfer->abort_cb)(transfer->user_data);
if( do_abort ) {
state = HBF_USER_ABORTED;
transfer->start_id = block_id % transfer->block_cnt;
}
}
if( state == HBF_TRANSFER_SUCCESS ) {
transfer_url = get_transfer_url( transfer, block_id );
if( ! transfer_url ) {
state = HBF_PARAM_FAIL;
}
}
if( state == HBF_TRANSFER_SUCCESS ) {
if( transfer->block_cnt > 1 && cnt > 0 ) {
/* The block count is > 1, check size and mtime before transmitting. */
state = hbf_validate_source_file(transfer);
if( state == HBF_SOURCE_FILE_CHANGE ) {
/* The source file has changed meanwhile */
}
}
}
if( state == HBF_TRANSFER_SUCCESS || state == HBF_SUCCESS ) {
ne_request *req = ne_request_create(session, verb, transfer_url);
if( req ) {
char buf[21];
snprintf(buf, sizeof(buf), "%"PRId64, transfer->stat_size);
ne_add_request_header(req, "OC-Total-Length", buf);
if( transfer->oc_header_modtime > 0 ) {
snprintf(buf, sizeof(buf), "%"PRId64, transfer->oc_header_modtime);
ne_add_request_header(req, "X-OC-Mtime", buf);
}
if( transfer->previous_etag ) {
ne_add_request_header(req, "If-Match", transfer->previous_etag);
}
if( transfer->block_cnt > 1 ) {
ne_add_request_header(req, "OC-Chunked", "1");
snprintf(buf, sizeof(buf), "%"PRId64, transfer->threshold);
ne_add_request_header(req, "OC-Chunk-Size", buf);
}
ne_add_request_header( req, "Content-Type", "application/octet-stream");
state = _hbf_dav_request(transfer, req, transfer->fd, block );
if( state != HBF_TRANSFER_SUCCESS && state != HBF_SUCCESS) {
if( transfer->error_string ) free( transfer->error_string );
transfer->error_string = strdup( ne_get_error(session) );
transfer->start_id = block_id % transfer->block_cnt;
/* Set the code of the last transmission. */
state = HBF_FAIL;
transfer->status_code = transfer->block_arr[block_id]->http_result_code;
}
ne_request_destroy(req);
if (transfer->block_cnt > 1 && state == HBF_SUCCESS && cnt == 0) {
/* Success on the first chunk is suspicious.
It could happen that the server did not support chunking */
int rc = ne_delete(session, transfer_url);
if (rc == NE_OK && _hbf_http_error_code(session) == 204) {
/* If delete suceeded, it means some proxy strips the OC_CHUNKING header
start again without chunking: */
free( transfer_url );
return _hbf_transfer_no_chunk(session, transfer, verb);
}
}
if (state == HBF_TRANSFER_SUCCESS && transfer->chunk_finished_cb) {
transfer->chunk_finished_cb(transfer, block_id, transfer->user_data);
}
} else {
state = HBF_MEMORY_FAIL;
}
}
free( transfer_url );
}
/* do the source file validation finally (again). */
if( state == HBF_TRANSFER_SUCCESS ) {
/* This means that no etag was returned on one of the chunks to indicate
* that the upload was finished. */
state = HBF_TRANSFER_NOT_ACKED;
}
return state;
}
int hbf_fail_http_code( hbf_transfer_t *transfer )
{
int cnt;
if( ! transfer ) return 0;
for( cnt = 0; cnt < transfer->block_cnt; cnt++ ) {
int block_id = (cnt + transfer->start_id) % transfer->block_cnt;
hbf_block_t *block = transfer->block_arr[block_id];
if( block->state != HBF_NOT_TRANSFERED && block->state != HBF_TRANSFER_SUCCESS ) {
return block->http_result_code;
}
}
return 200;
}
const char *hbf_transfer_etag( hbf_transfer_t *transfer )
{
int cnt;
const char *etag = NULL;
if( ! transfer ) return 0;
/* Loop over all parts and do a assertion that there is only one etag. */
for( cnt = 0; cnt < transfer->block_cnt; cnt++ ) {
int block_id = (cnt + transfer->start_id) % transfer->block_cnt;
hbf_block_t *block = transfer->block_arr[block_id];
if( block->etag ) {
if( etag && strcmp(etag, block->etag) != 0 ) {
/* multiple etags in the transfer, not equal. */
DEBUG_HBF( "WARN: etags are not equal in blocks of one single transfer." );
}
etag = block->etag;
}
}
return etag;
}
const char *hbf_transfer_file_id( hbf_transfer_t *transfer )
{
const char *re = NULL;
if(transfer) {
re = transfer->file_id;
}
return re;
}
const char *hbf_error_string(hbf_transfer_t *transfer, Hbf_State state)
{
const char *re;
int cnt;
switch( state ) {
case HBF_SUCCESS:
re = "Ok.";
break;
case HBF_NOT_TRANSFERED: /* never tried to transfer */
re = "Block was not yet tried to transfer.";
break;
case HBF_TRANSFER: /* transfer currently running */
re = "Block is currently transferred.";
break;
case HBF_TRANSFER_FAILED: /* transfer tried but failed */
re = "Block transfer failed.";
break;
case HBF_TRANSFER_SUCCESS: /* transfer succeeded. */
re = "Block transfer successful.";
break;
case HBF_SPLITLIST_FAIL: /* the file could not be split */
re = "Splitlist could not be computed.";
break;
case HBF_SESSION_FAIL:
re = "No valid session in transfer.";
break;
case HBF_FILESTAT_FAIL:
re = "Source file could not be stat'ed.";
break;
case HBF_PARAM_FAIL:
re = "Parameter fail.";
break;
case HBF_AUTH_FAIL:
re = "Authentication fail.";
break;
case HBF_PROXY_AUTH_FAIL:
re = "Proxy Authentication fail.";
break;
case HBF_CONNECT_FAIL:
re = "Connection could not be established.";
break;
case HBF_TIMEOUT_FAIL:
re = "Network timeout.";
break;
case HBF_MEMORY_FAIL:
re = "Out of memory.";
break;
case HBF_STAT_FAIL:
re = "Filesystem stat on file failed.";
break;
case HBF_SOURCE_FILE_CHANGE:
re = "Source file changed too often during upload.";
break;
case HBF_USER_ABORTED:
re = "Transmission aborted by user.";
break;
case HBF_TRANSFER_NOT_ACKED:
re = "The server did not provide an Etag.";
break;
case HBF_FAIL:
default:
for( cnt = 0; cnt < transfer->block_cnt; cnt++ ) {
int block_id = (cnt + transfer->start_id) % transfer->block_cnt;
hbf_block_t *block = transfer->block_arr[block_id];
if( block->state != HBF_NOT_TRANSFERED && block->state != HBF_TRANSFER_SUCCESS
&& block->http_error_msg != NULL) {
return block->http_error_msg;
}
}
re = "Unknown error.";
}
return re;
}
void hbf_set_abort_callback( hbf_transfer_t *transfer, hbf_abort_callback cb)
{
if( transfer ) {
transfer->abort_cb = cb;
}
}
void hbf_set_log_callback(hbf_transfer_t* transfer, hbf_log_callback cb)
{
if( transfer ) {
transfer->log_cb = cb;
}
}
-142
Ver Arquivo
@@ -1,142 +0,0 @@
/**
* http big file functions
*
* Copyright (c) 2012 by Klaas Freitag <freitag@owncloud.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _HBF_SEND_H
#define _HBF_SEND_H
#include "config_csync.h"
#ifdef NEON_WITH_LFS /* Switch on LFS in libneon. Never remove the NE_LFS! */
#define NE_LFS
#endif
#include <neon/ne_session.h>
#ifdef __cplusplus
extern "C" {
#endif
enum hbf_state_e {
HBF_SUCCESS,
HBF_NOT_TRANSFERED, /* never tried to transfer */
HBF_TRANSFER, /* transfer currently running */
HBF_TRANSFER_FAILED, /* transfer tried but failed */
HBF_TRANSFER_SUCCESS, /* block transfer succeeded. */
HBF_SPLITLIST_FAIL, /* the file could not be split */
HBF_SESSION_FAIL,
HBF_FILESTAT_FAIL,
HBF_PARAM_FAIL,
HBF_AUTH_FAIL,
HBF_PROXY_AUTH_FAIL,
HBF_CONNECT_FAIL,
HBF_TIMEOUT_FAIL,
HBF_MEMORY_FAIL,
HBF_STAT_FAIL,
HBF_SOURCE_FILE_CHANGE,
HBF_USER_ABORTED,
HBF_TRANSFER_NOT_ACKED,
HBF_FAIL
};
typedef enum hbf_state_e Hbf_State;
typedef struct hbf_block_s hbf_block_t;
struct hbf_block_s {
int seq_number;
int64_t start;
int64_t size;
Hbf_State state;
int http_result_code;
char *http_error_msg;
char *etag;
int tries;
};
typedef struct hbf_transfer_s hbf_transfer_t;
/* Callback for to check on abort */
typedef int (*hbf_abort_callback) (void *);
typedef void (*hbf_log_callback) (const char *, const char *, void*);
typedef void (*hbf_chunk_finished_callback) (hbf_transfer_t*,int, void*);
struct hbf_transfer_s {
hbf_block_t **block_arr;
int block_cnt;
int fd;
int transfer_id;
char *url;
int start_id;
int status_code;
char *error_string;
int64_t stat_size;
time_t modtime;
time_t oc_header_modtime;
int64_t block_size;
int64_t threshold;
void *user_data;
hbf_abort_callback abort_cb;
hbf_log_callback log_cb;
hbf_chunk_finished_callback chunk_finished_cb;
int modtime_accepted;
const char *previous_etag; /* etag send as the If-Match http header */
char *file_id;
#ifndef NDEBUG
int64_t calc_size;
#endif
};
hbf_transfer_t *hbf_init_transfer( const char *dest_uri );
Hbf_State hbf_transfer( ne_session *session, hbf_transfer_t *transfer, const char *verb );
Hbf_State hbf_splitlist( hbf_transfer_t *transfer, int fd );
void hbf_free_transfer( hbf_transfer_t *transfer );
const char *hbf_error_string(hbf_transfer_t* transfer, Hbf_State state);
const char *hbf_transfer_etag( hbf_transfer_t *transfer );
const char *hbf_transfer_file_id( hbf_transfer_t *transfer );
void hbf_set_abort_callback( hbf_transfer_t *transfer, hbf_abort_callback cb);
void hbf_set_log_callback( hbf_transfer_t *transfer, hbf_log_callback cb);
/* returns an http (error) code of the transmission. If the transmission
* succeeded, the code is 200. If it failed, its the error code of the
* first part transmission that failed.
*/
int hbf_fail_http_code( hbf_transfer_t *transfer );
Hbf_State hbf_validate_source_file( hbf_transfer_t *transfer );
#ifdef __cplusplus
}
#endif
#endif
-18
Ver Arquivo
@@ -1,18 +0,0 @@
project(hbf_test C )
add_definitions(-DUNIT_TESTING=1)
find_package(CMocka REQUIRED)
include_directories(
${CMAKE_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
${CMOCKA_INCLUDE_DIRS}
${NEON_INCLUDE_DIRS}
${HTTPBF_PUBLIC_INCLUDE_DIRS}
)
add_executable(send_test hbf_send_test.c)
target_link_libraries(send_test ${CMOCKA_LIBRARIES} ${NEON_LIBRARIES} ${HBF_LIBRARY} )
Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 1.2 MiB

-162
Ver Arquivo
@@ -1,162 +0,0 @@
/*
* httpbf - send big files via http
*
* Copyright (c) 2012 Klaas Freitag <freitag@owncloud.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <string.h>
#include <cmocka.h>
#include "config_csync.h"
#include <httpbf.h>
// A test case that does nothing and succeeds.
static void null_test_success(void **state) {
(void) state;
}
static char* test_file( const char* name ) {
if( ! name ) return 0;
char path[260];
strcpy( path, TESTFILEDIR);
if(path[strlen(TESTFILEDIR)-1] != '/')
strcat( path, "/");
strcat( path, name );
return strdup(path);
}
static void test_get_transfer_url( void **state ) {
const char *url = "http://example.org/owncloud";
const char *turl = NULL;
char res[256];
int i;
Hbf_State hbf_state;
hbf_transfer_t *list = NULL;
list = hbf_init_transfer( url );
assert_non_null( list );
/* open a file */
int fd = open( test_file("church.jpg"), O_RDONLY );
assert_true(fd >= 0);
hbf_state = hbf_splitlist(list, fd);
assert_true( hbf_state == HBF_SUCCESS);
for( i=0; i < list->block_cnt; i++ ) {
turl = get_transfer_url( list, i );
sprintf(res, "%s-chunking-%d-%d-%d", url, list->transfer_id,
list->block_cnt, i );
printf( "XX: %s\n", res );
assert_string_equal( turl, res );
}
}
static void test_hbf_init_transfer( void **state ) {
hbf_transfer_t *list = NULL;
const char *url = "http://example.org/owncloud";
list = hbf_init_transfer( url );
assert_non_null( list );
assert_string_equal( url, list->url );
}
/* test with a file size that is not a multiply of the slize size. */
static void test_hbf_splitlist_odd( void **state ){
hbf_transfer_t *list = NULL;
const char *dest_url = "http://localhost/ocm/remote.php/webdav/big/church.jpg";
/* open a file */
int fd = open(test_file("church.jpg"), O_RDONLY);
assert_true(fd >= 0);
int prev_id = 0;
int i;
Hbf_State hbf_state;
/* do a smoke test for uniqueness */
for( i=0; i < 10000; i++) {
list = hbf_init_transfer(dest_url);
assert_non_null(list);
usleep(1);
hbf_state = hbf_splitlist(list, fd);
assert_int_not_equal(list->transfer_id, prev_id);
prev_id = list->transfer_id;
hbf_free_transfer(list);
}
list = hbf_init_transfer(dest_url);
assert_non_null(list);
hbf_state = hbf_splitlist(list, fd);
assert_non_null(list);
assert_int_equal(list->calc_size, list->stat_size);
assert_int_not_equal(list->block_cnt, 0);
assert_true( hbf_state == HBF_SUCCESS);
/* checks on the block list */
int seen_zero_seq = 0;
int prev_seq = -1;
int64_t prev_block_end = -1;
for( i=0; i < list->block_cnt; i++) {
hbf_block_t *blk = list->block_arr[i];
assert_non_null(blk);
if( blk->seq_number == 0 ) seen_zero_seq++;
assert_int_equal(prev_seq, blk->seq_number -1 );
prev_seq = blk->seq_number;
assert_true((prev_block_end+1) == (blk->start));
prev_block_end = blk->start + blk->size;
}
/* Make sure we exactly saw blk->seq_number == 0 exactly one times */
assert_int_equal( seen_zero_seq, 1 );
hbf_free_transfer( list );
}
int main(void) {
const UnitTest tests[] = {
unit_test(null_test_success),
unit_test(test_hbf_splitlist_odd),
unit_test(test_hbf_init_transfer),
unit_test(test_get_transfer_url)
};
return run_tests(tests);
}
-6
Ver Arquivo
@@ -36,9 +36,6 @@
#define CSYNC_LOG_CATEGORY_NAME "csync.vio.main"
#include "csync_log.h"
#if USE_NEON
#include "csync_owncloud.h"
#endif
csync_vio_handle_t *csync_vio_opendir(CSYNC *ctx, const char *name) {
switch(ctx->replica) {
@@ -132,8 +129,5 @@ char *csync_vio_get_status_string(CSYNC *ctx) {
if(ctx->error_string) {
return ctx->error_string;
}
#ifdef USE_NEON
return owncloud_error_string(ctx);
#endif
return 0;
}
-10
Ver Arquivo
@@ -157,13 +157,6 @@ int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) {
return -1;
}
buf->name = c_basename(uri);
if (buf->name == NULL) {
csync_vio_file_stat_destroy(buf);
c_free_locale_string(wuri);
return -1;
}
buf->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE;
switch(sb.st_mode & S_IFMT) {
@@ -210,9 +203,6 @@ int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) {
#endif
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_FLAGS;
buf->device = sb.st_dev;
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_DEVICE;
buf->inode = sb.st_ino;
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_INODE;
+65 -89
Ver Arquivo
@@ -116,10 +116,31 @@ int csync_vio_local_closedir(csync_vio_handle_t *dhandle) {
return rc;
}
static time_t FileTimeToUnixTime(FILETIME *filetime, DWORD *remainder)
{
long long int t = filetime->dwHighDateTime;
t <<= 32;
t += (UINT32)filetime->dwLowDateTime;
t -= 116444736000000000LL;
if (t < 0)
{
if (remainder) *remainder = 9999999 - (-t - 1) % 10000000;
return -1 - ((-t - 1) / 10000000);
}
else
{
if (remainder) *remainder = t % 10000000;
return t / 10000000;
}
}
csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle) {
dhandle_t *handle = NULL;
csync_vio_file_stat_t *file_stat = NULL;
ULARGE_INTEGER FileIndex;
DWORD rem;
handle = (dhandle_t *) dhandle;
@@ -148,13 +169,43 @@ csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle) {
file_stat->name = c_utf8_from_locale(handle->ffd.cFileName);
file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
if (handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
file_stat->type = CSYNC_VIO_FILE_TYPE_DIRECTORY;
} else {
file_stat->type = CSYNC_VIO_FILE_TYPE_REGULAR;
}
if (handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT
&& handle->ffd.dwReserved0 & IO_REPARSE_TAG_SYMLINK) {
file_stat->flags = CSYNC_VIO_FILE_FLAGS_SYMLINK;
file_stat->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK;
} else if (handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_DEVICE
|| handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE
|| handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) {
file_stat->type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
} else if (handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
file_stat->type = CSYNC_VIO_FILE_TYPE_DIRECTORY;
} else {
file_stat->type = CSYNC_VIO_FILE_TYPE_REGULAR;
}
return file_stat;
file_stat->flags = CSYNC_VIO_FILE_FLAGS_NONE;
/* Check for the hidden flag */
if( handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN ) {
file_stat->flags |= CSYNC_VIO_FILE_FLAGS_HIDDEN;
}
file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_FLAGS;
file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
file_stat->size = (handle->ffd.nFileSizeHigh * ((int64_t)(MAXDWORD)+1)) + handle->ffd.nFileSizeLow;
file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE;
file_stat->atime = FileTimeToUnixTime(&handle->ffd.ftLastAccessTime, &rem);
file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_ATIME;
file_stat->mtime = FileTimeToUnixTime(&handle->ffd.ftLastWriteTime, &rem);
/* CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Local File MTime: %llu", (unsigned long long) buf->mtime ); */
file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MTIME;
file_stat->ctime = FileTimeToUnixTime(&handle->ffd.ftCreationTime, &rem);
file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_CTIME;
return file_stat;
err:
SAFE_FREE(file_stat);
@@ -162,34 +213,21 @@ err:
return NULL;
}
static time_t FileTimeToUnixTime(FILETIME *filetime, DWORD *remainder)
{
long long int t = filetime->dwHighDateTime;
t <<= 32;
t += (UINT32)filetime->dwLowDateTime;
t -= 116444736000000000LL;
if (t < 0)
{
if (remainder) *remainder = 9999999 - (-t - 1) % 10000000;
return -1 - ((-t - 1) / 10000000);
}
else
{
if (remainder) *remainder = t % 10000000;
return t / 10000000;
}
}
int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) {
HANDLE h, hFind;
FILETIME ftCreate, ftAccess, ftWrite;
/* Almost nothing to do since csync_vio_local_readdir already filled up most of the information
But we still need to fetch the file ID.
Possible optimisation: only fetch the file id when we need it (for new files)
*/
HANDLE h;
BY_HANDLE_FILE_INFORMATION fileInfo;
WIN32_FIND_DATAW FindFileData;
ULARGE_INTEGER FileIndex;
mbchar_t *wuri = c_utf8_path_to_locale( uri );
h = CreateFileW( wuri, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL+FILE_FLAG_BACKUP_SEMANTICS, NULL );
FILE_ATTRIBUTE_NORMAL+FILE_FLAG_BACKUP_SEMANTICS+FILE_FLAG_OPEN_REPARSE_POINT, NULL );
if( h == INVALID_HANDLE_VALUE ) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_CRIT, "CreateFileW failed on %s", uri );
errno = GetLastError();
@@ -205,47 +243,6 @@ int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) {
return -1;
}
buf->flags = CSYNC_VIO_FILE_FLAGS_NONE;
do {
// Check first if it is a symlink (code from c_islink)
if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
hFind = FindFirstFileW(wuri, &FindFileData );
if (hFind != INVALID_HANDLE_VALUE) {
if( (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
(FindFileData.dwReserved0 & IO_REPARSE_TAG_SYMLINK) ) {
buf->flags = CSYNC_VIO_FILE_FLAGS_SYMLINK;
buf->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK;
break;
}
}
FindClose(hFind);
}
if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DEVICE
|| fileInfo.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE
|| fileInfo.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) {
buf->type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
break;
}
if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
buf->type = CSYNC_VIO_FILE_TYPE_DIRECTORY;
break;
}
// fallthrough:
buf->type = CSYNC_VIO_FILE_TYPE_REGULAR;
break;
} while (0);
/* Check for the hidden flag */
if( fileInfo.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN ) {
buf->flags |= CSYNC_VIO_FILE_FLAGS_HIDDEN;
}
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_FLAGS;
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
buf->device = fileInfo.dwVolumeSerialNumber;
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_DEVICE;
/* Get the Windows file id as an inode replacement. */
FileIndex.HighPart = fileInfo.nFileIndexHigh;
FileIndex.LowPart = fileInfo.nFileIndexLow;
@@ -253,28 +250,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->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE;
/* Get the file time with a win32 call rather than through stat. See
* http://www.codeproject.com/Articles/1144/Beating-the-Daylight-Savings-Time-bug-and-getting
* for deeper explanation.
*/
if( GetFileTime(h, &ftCreate, &ftAccess, &ftWrite) ) {
DWORD rem;
buf->atime = FileTimeToUnixTime(&ftAccess, &rem);
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_ATIME;
buf->mtime = FileTimeToUnixTime(&ftWrite, &rem);
/* CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Local File MTime: %llu", (unsigned long long) buf->mtime ); */
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MTIME;
buf->ctime = FileTimeToUnixTime(&ftCreate, &rem);
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_CTIME;
}
c_free_locale_string(wuri);
CloseHandle(h);
return 0;
}
-5
Ver Arquivo
@@ -7,7 +7,6 @@ include_directories(
${CSTDLIB_PUBLIC_INCLUDE_DIRS}
${CMAKE_BINARY_DIR}
${CMOCKA_INCLUDE_DIR}
${HTTPBF_PUBLIC_INCLUDE_DIRS}
)
include_directories(${CHECK_INCLUDE_DIRS})
@@ -54,10 +53,6 @@ add_cmocka_test(check_csync_update csync_tests/check_csync_update.c ${TEST_TARGE
# encoding
add_cmocka_test(check_encoding_functions encoding_tests/check_encoding.c ${TEST_TARGET_LIBRARIES})
# httpbf
set(TEST_HTTPBF_LIBRARIES ${TEST_TARGET_LIBRARIES} ${NEON_LIBRARIES})
add_cmocka_test(check_httpbf httpbf_tests/hbf_send_test.c ${TEST_HTTPBF_LIBRARIES} )
if(UNIT_TESTING)
INSTALL( FILES "${CMOCKA_LIBRARIES}" DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif(UNIT_TESTING)
+17 -1
Ver Arquivo
@@ -48,6 +48,12 @@ static void setup_init(void **state) {
rc = csync_exclude_load(EXCLUDE_LIST_FILE, &(csync->excludes));
assert_int_equal(rc, 0);
/* and add some unicode stuff */
rc = _csync_exclude_add(&(csync->excludes), "*.💩");
assert_int_equal(rc, 0);
rc = _csync_exclude_add(&(csync->excludes), "пятницы.*");
assert_int_equal(rc, 0);
*state = csync;
}
@@ -81,7 +87,7 @@ static void check_csync_exclude_load(void **state)
rc = csync_exclude_load(EXCLUDE_LIST_FILE, &(csync->excludes) );
assert_int_equal(rc, 0);
assert_string_equal(csync->excludes->vector[0], "*.filepart");
assert_string_equal(csync->excludes->vector[0], "*~");
assert_int_not_equal(csync->excludes->count, 0);
}
@@ -145,6 +151,16 @@ static void check_csync_excluded(void **state)
rc = csync_excluded(csync, ".netscape/cache", CSYNC_FTW_TYPE_FILE);
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
/* Not excluded */
rc = csync_excluded(csync, "unicode/中文.hé", CSYNC_FTW_TYPE_FILE);
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
/* excluded */
rc = csync_excluded(csync, "unicode/пятницы.txt", CSYNC_FTW_TYPE_FILE);
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
rc = csync_excluded(csync, "unicode/中文.💩", CSYNC_FTW_TYPE_FILE);
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
}
static void check_csync_excluded_traversal(void **state)
@@ -201,7 +201,6 @@ static csync_vio_file_stat_t* create_fstat(const char *name,
}
fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_INODE;
fs->device = 0;
fs->size = 157459;
fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE;
-241
Ver Arquivo
@@ -1,241 +0,0 @@
/*
* libcsync -- a library to sync a directory with another
*
* Copyright (c) 2013 by Klaas Freitag <freitag@owncloud.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <string.h>
#include <unistd.h>
#include <cmocka.h>
#include "config_test.h"
#if USE_NEON
#include "httpbf.c"
#endif
// A test case that does nothing and succeeds.
static void null_test_success(void **state) {
(void) state;
}
#if USE_NEON
static char* test_file( const char* name ) {
char path[260];
if( ! name ) return 0;
strcpy( path, TESTFILES_DIR);
if(path[strlen(TESTFILES_DIR)-1] != '/')
strcat( path, "/");
strcat( path, name );
return strdup(path);
}
static void test_get_transfer_url( void **state ) {
const char *url = "http://example.org/owncloud";
const char *turl = NULL;
int fd;
Hbf_State hbf_state;
hbf_transfer_t *list = NULL;
(void) state;
list = hbf_init_transfer( url );
assert_non_null( list );
/* open a file */
fd = open( test_file("church.jpg"), O_RDONLY );
assert_true(fd >= 0);
hbf_state = hbf_splitlist(list, fd);
assert_true( hbf_state == HBF_SUCCESS);
assert_true( list->block_cnt == 1);
turl = get_transfer_url( list, 0 );
assert_non_null( turl );
assert_string_equal( url, turl );
hbf_free_transfer( list );
}
static void test_get_transfer_url_bigfile( void **state ) {
const char *url = "http://example.org/big_file";
const char *turl = NULL;
char res[256];
int i, fd;
Hbf_State hbf_state;
hbf_transfer_t *list = NULL;
(void) state;
list = hbf_init_transfer( url );
assert_non_null( list );
list->threshold = list->block_size = (1024*1024); /* block size 1 MB */
/* open a file */
fd = open( test_file("church.jpg"), O_RDONLY );
assert_true(fd >= 0);
hbf_state = hbf_splitlist(list, fd);
assert_true( hbf_state == HBF_SUCCESS);
assert_true( list->block_cnt == 2 );
for( i=0; i < list->block_cnt; i++ ) {
turl = get_transfer_url( list, i );
assert_non_null(turl);
sprintf(res, "%s-chunking-%u-%u-%u", url, list->transfer_id,
list->block_cnt, i );
/* printf( "XX: %s\n", res ); */
assert_string_equal( turl, res );
}
hbf_free_transfer(list);
}
static void test_hbf_init_transfer( void **state ) {
hbf_transfer_t *list = NULL;
const char *url = "http://example.org/owncloud";
(void) state;
list = hbf_init_transfer( url );
assert_non_null( list );
assert_string_equal( url, list->url );
}
/* test with a file size that is not a multiply of the slize size. */
static void test_hbf_splitlist_odd( void **state ){
hbf_transfer_t *list = NULL;
const char *dest_url = "http://localhost/ocm/remote.php/webdav/big/church.jpg";
int prev_id = 0;
int i, fd;
Hbf_State hbf_state;
(void) state;
/* open a file */
fd = open(test_file("church.jpg"), O_RDONLY);
assert_true(fd >= 0);
/* do a smoke test for uniqueness */
for( i=0; i < 10000; i++) {
list = hbf_init_transfer(dest_url);
assert_non_null(list);
usleep(1);
hbf_state = hbf_splitlist(list, fd);
assert_int_not_equal(list->transfer_id, prev_id);
prev_id = list->transfer_id;
hbf_free_transfer(list);
}
list = hbf_init_transfer(dest_url);
assert_non_null(list);
hbf_state = hbf_splitlist(list, fd);
assert_non_null(list);
#ifndef NDEBUG
assert_int_equal(list->calc_size, list->stat_size);
#endif
assert_int_not_equal(list->block_cnt, 0);
assert_true( hbf_state == HBF_SUCCESS);
/* checks on the block list */
if( 1 ) {
int seen_zero_seq = 0;
int prev_seq = -1;
int64_t prev_block_end = -1;
for( i=0; i < list->block_cnt; i++) {
hbf_block_t *blk = list->block_arr[i];
assert_non_null(blk);
if( blk->seq_number == 0 ) seen_zero_seq++;
assert_int_equal(prev_seq, blk->seq_number -1 );
prev_seq = blk->seq_number;
assert_true((prev_block_end+1) == (blk->start));
prev_block_end = blk->start + blk->size;
}
/* Make sure we exactly saw blk->seq_number == 0 exactly one times */
assert_int_equal( seen_zero_seq, 1 );
}
hbf_free_transfer( list );
}
/* test with a file size that is not a multiply of the slize size. */
static void test_hbf_splitlist_zero( void **state ){
hbf_transfer_t *list = NULL;
const char *dest_url = "http://localhost/ocm/remote.php/webdav/big/zerofile.txt";
int fd;
Hbf_State hbf_state;
(void) state;
/* open a file */
fd = open(test_file("zerofile.txt"), O_RDONLY);
assert_true(fd >= 0);
list = hbf_init_transfer(dest_url);
assert_non_null(list);
hbf_state = hbf_splitlist(list, fd);
assert_non_null(list);
assert_int_equal(list->stat_size, 0);
#ifndef NDEBUG
assert_int_equal(list->calc_size, list->stat_size);
#endif
assert_int_equal(list->block_cnt, 1);
assert_true( hbf_state == HBF_SUCCESS);
hbf_free_transfer( list );
}
#endif
int main(void) {
const UnitTest tests[] = {
unit_test(null_test_success),
#if USE_NEON
unit_test(test_hbf_splitlist_odd),
unit_test(test_hbf_splitlist_zero),
unit_test(test_hbf_init_transfer),
unit_test(test_get_transfer_url),
unit_test(test_get_transfer_url_bigfile)
#endif
};
return run_tests(tests);
}
-52
Ver Arquivo
@@ -73,15 +73,6 @@ static void setup_dir(void **state) {
assert_int_equal(rc, 0);
}
static void setup_file(void **state) {
int rc;
setup_dir(state);
rc = system("echo \"This is a test\" > /tmp/csync_test/file.txt");
assert_int_equal(rc, 0);
}
static void teardown(void **state) {
CSYNC *csync = *state;
int rc;
@@ -164,46 +155,6 @@ static void check_csync_vio_readdir(void **state)
}
/*
* Test for general functions (stat, chmod, chown, ...)
*/
static void check_csync_vio_stat_dir(void **state)
{
CSYNC *csync = *state;
csync_vio_file_stat_t *fs;
int rc;
fs = csync_vio_file_stat_new();
assert_non_null(fs);
rc = csync_vio_stat(csync, CSYNC_TEST_DIR, fs);
assert_int_equal(rc, 0);
assert_string_equal(fs->name, "csync_test");
assert_int_equal(fs->type, CSYNC_VIO_FILE_TYPE_DIRECTORY);
csync_vio_file_stat_destroy(fs);
}
static void check_csync_vio_stat_file(void **state)
{
CSYNC *csync = *state;
csync_vio_file_stat_t *fs;
int rc;
fs = csync_vio_file_stat_new();
assert_non_null(fs);
rc = csync_vio_stat(csync, CSYNC_TEST_FILE, fs);
assert_int_equal(rc, 0);
assert_string_equal(fs->name, "file.txt");
assert_int_equal(fs->type, CSYNC_VIO_FILE_TYPE_REGULAR);
csync_vio_file_stat_destroy(fs);
}
int torture_run_tests(void)
{
const UnitTest tests[] = {
@@ -211,9 +162,6 @@ int torture_run_tests(void)
unit_test_setup_teardown(check_csync_vio_opendir_perm, setup, teardown),
unit_test(check_csync_vio_closedir_null),
unit_test_setup_teardown(check_csync_vio_readdir, setup_dir, teardown),
unit_test_setup_teardown(check_csync_vio_stat_dir, setup_dir, teardown),
unit_test_setup_teardown(check_csync_vio_stat_file, setup_file, teardown),
};
return run_tests(tests);
+1 -1
Ver Arquivo
@@ -108,7 +108,7 @@ ownCloud Client 1.1 or later. Using an incompatible time stamp-based
synchronization mechanism can lead to data loss in rare cases, especially when
multiple clients are involved and one utilizes a non-synchronized NTP time.
.. _`NTP time synchronisation`: http://en.wikipedia.org/wiki/Network_Time_Protocol
.. _`NTP time synchronization`: http://en.wikipedia.org/wiki/Network_Time_Protocol
.. _Etag: http://en.wikipedia.org/wiki/HTTP_ETag
Comparison and Conflict Cases
+5 -5
Ver Arquivo
@@ -11,8 +11,8 @@ the Updater will check for updates and notify you when a new version is
available.
.. note:: Because of various technical issues, desktop sync clients older than
1.7 will not be allowed to connect and sync with the ownCloud 8.1 server. It is
highly recommended to keep your client updated.
1.7 will not be allowed to connect and sync with the ownCloud 8.1+ server. It
is highly recommended to keep your client updated.
Basic Workflow
--------------
@@ -73,8 +73,8 @@ To prevent automatic updates, but allow manual overrides:
1. Edit these Registry keys:
a. (32-bit) ``HKEY_LOCAL_MACHINE\Software\ownCloud\ownCloud``
b. (64-bit) ``HKEY_LOCAL_MACHINE\Software\Wow6432Node\ownCloud\ownCloud``
a. (32-bit-Windows) ``HKEY_LOCAL_MACHINE\Software\ownCloud\ownCloud``
b. (64-bit-Windows) ``HKEY_LOCAL_MACHINE\Software\Wow6432Node\ownCloud\ownCloud``
2. Add the key ``skipUpdateCheck`` (of type DWORD).
@@ -89,7 +89,7 @@ To prevent automatic updates and disallow manual overrides:
1. Edit this Registry key:
HKEY_LOCAL_MACHINE\Software\Policies\ownCloud\ownCloud
``HKEY_LOCAL_MACHINE\Software\Policies\ownCloud\ownCloud``
2. Add the key ``skipUpdateCheck`` (of type DWORD).
+3 -3
Ver Arquivo
@@ -48,9 +48,9 @@ copyright = u'2013, The ownCloud developers'
# built documents.
#
# The short X.Y version.
version = '@VERSION_MAJOR@.@VERSION_MINOR@'
version = '@MIRALL_VERSION_MAJOR@.@MIRALL_VERSION_MINOR@'
# The full version, including alpha/beta/rc tags.
release = '@VERSION@'
release = '@MIRALL_VERSION@'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@@ -189,7 +189,7 @@ latex_documents = [
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
latex_logo = '@LATEX_LOGO@'
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
+1 -1
Ver Arquivo
@@ -11,7 +11,7 @@ It is possible that another program is changing the modification date of the fil
If the file is uses the ``.eml`` extension, Windows automatically and
continually changes all files, unless you remove
``\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\PropertySystem\PropertyHandlers`
``\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\PropertySystem\PropertyHandlers``
from the windows registry.
See http://petersteier.wordpress.com/2011/10/22/windows-indexer-changes-modification-dates-of-eml-files/ for more information.
Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 34 KiB

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 41 KiB

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 67 KiB

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 63 KiB

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 5.5 KiB

Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 20 KiB

Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 39 KiB

Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 20 KiB

Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 34 KiB

Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 22 KiB

Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 18 KiB

Arquivo executável → Arquivo normal
BIN
Ver Arquivo
Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 53 KiB

Depois

Largura:  |  Altura:  |  Tamanho: 52 KiB

Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 41 KiB

Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 44 KiB

Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 59 KiB

Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 34 KiB

Depois

Largura:  |  Altura:  |  Tamanho: 30 KiB

Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 40 KiB

Depois

Largura:  |  Altura:  |  Tamanho: 4.9 KiB

Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 111 KiB

Depois

Largura:  |  Altura:  |  Tamanho: 42 KiB

+11 -65
Ver Arquivo
@@ -3,7 +3,8 @@ Installing the Desktop Synchronization Client
=============================================
You can download the latest version of the ownCloud Desktop Synchronization
Client from the `ownCloud Website <https://owncloud.org/install/#desktop>`_.
Client from the `ownCloud download page
<https://owncloud.org/install/#desktop>`_.
There are clients for Linux, Mac OS X, and Microsoft Windows.
Installation on Mac OS X and Windows is the same as for any software
@@ -21,43 +22,8 @@ will display a notification when an update is available.
Linux users must also have a password manager enabled, such as GNOME Keyring or
KWallet, so that the sync client can login automatically.
Improvements and New Features
-----------------------------
The 2.0 release of the ownCloud desktop sync client has many new features and
improvements.
* Multi-account support
* Many UI improvements
* Accessibility improvements (high contrast schemes)
* Automatic Bandwidth Throttling
* Don't show redundant directory entries in activity log
* Remove deleted accounts properly from toolbar
* File manager integration: Show hidden files as ignored
* Show wizard when last account was deleted
* Do not sync down new big folders from server without user's consent
* Integrate Selective Sync into the default UI
* More reliable reconnect after timeout
* Use SI units for the file sizes
* Improve progress reporting during sync
* Sharing: Do not allow sharing the root folder
* Sharing: Show thumbnail
* Client Updater: Check for updates periodically, not only once per run
* Quota: Only refresh from server when UI is shown
* SSL Button: Show more information
* System proxy: Ask user for credentials if needed
* Several fixes and performance improvements in the sync engine
* OS X: Show file name in UI if file has invalid UTF-8 in file name
* OS X: Support native finder integration for 10.10 Yosemite
* Network: Try to use SSL session tickets/identifiers
* Windows: Support paths >255 characters
* Windows, OS X: Allow to not sync hidden files
* Windows: Remove misleading option to remove sync data
* Windows: Do not provoke Active Directory account locking if password changes
* Windows: Fix installer when installing unprivileged
.. note:: When you upgrade from 1.8, restart Windows to ensure that all new
features are visible.
You will also find links to source code archives and older versions on the
download page.
Installation Wizard
-------------------
@@ -65,12 +31,12 @@ Installation Wizard
The installation wizard takes you step-by-step through configuration options and
account setup. First you need to enter the URL of your ownCloud server.
.. image:: images/client1.png
.. image:: images/client-1.png
:alt: form for entering ownCloud server URL
Enter your ownCloud login on the next screen.
.. image:: images/client2.png
.. image:: images/client-2.png
:alt: form for entering your ownCloud login
On the Local Folder Option screen you may sync
@@ -78,9 +44,9 @@ all of your files on the ownCloud server, or select individual folders. The
default local sync folder is ``ownCloud``, in your home directory. You may
change this as well.
.. image:: images/client3.png
.. image:: images/client-3.png
:alt: Select which remote folders to sync, and which local folder to store
them in.
them in.
When you have completed selecting your sync folders, click the Connect button
at the bottom right. The client will attempt to connect to your ownCloud
@@ -88,28 +54,8 @@ server, and when it is successful you'll see two buttons: one to connect to
your ownCloud Web GUI, and one to open your local folder. It will also start
synchronizing your files.
.. image:: images/client4.png
.. image:: images/client-4.png
:alt: A successful server connection, showing a button to connect to your
Web GUI, and one to open your local ownCloud folder
Web GUI, and one to open your local ownCloud folder
Click the Finish button, and you're all done.
When you are in your local ownCloud folder, you can right-click any file or
folder, and then left-click "Share with ownCloud" to create a share link. Note
that Windows may also have a Share With option. This is not the ownCloud Share
option. Linux users must install the ``owncloud-client-nautilus`` package to
enable file sharing from the Nautilus file manager. The ownCloud share dialog
looks like the following example on Ubuntu Linux:
.. image:: images/client5.png
:alt: the ownCloud file share option is integrated into the normal
right-click file menu in your file manager
You may change your sync options at any time by opening your ownCloud client
and selecting which folders to sync, or to remove from synchronization.
you saw in the installation wizard. **If you un-check any folders that
you have already synchronized, they will be deleted from your local system.**
.. image:: images/client6.png
:alt: Client dialogue to select different files to sync, or to remove from
syncing
Click the Finish button, and you're all done.
+40 -2
Ver Arquivo
@@ -13,5 +13,43 @@ Your files are always automatically synchronized between your ownCloud server
and local PC.
.. note:: Because of various technical issues, desktop sync clients older than
1.7 will not allowed to connect and sync with the ownCloud 8.1 server. It is
highly recommended to keep your client updated.
1.7 will not allowed to connect and sync with the ownCloud 8.1+ server. It
is highly recommended to keep your client updated.
Improvements and New Features
-----------------------------
The 2.0 release of the ownCloud desktop sync client has many new features and
improvements. (See the `complete changelog
<https://owncloud.org/changelog/desktop/>`_.)
* Multi-account support
* Many UI improvements
* Accessibility improvements (high contrast schemes)
* Automatic bandwidth throttling
* No redundant directory entries in activity log
* Remove deleted accounts properly from toolbar
* File manager integration: show hidden files as ignored
* Do not sync new big folders from server without user's consent
* Integrate selective sync into the default UI
* More reliable reconnect after timeout
* Improve progress reporting during sync
* Sharing: Do not allow sharing the root folder
* Sharing: Show thumbnail
* Client Updater: Check for updates periodically, not only once per run
* Quota: Only refresh from server when UI is shown
* SSL Button: Show more information
* System proxy: Ask user for credentials if needed
* Several fixes and performance improvements in the sync engine
* OS X: Show file name in UI if file has invalid UTF-8 in file name
* OS X: Support native finder integration for 10.10 Yosemite
* Network: Try to use SSL session tickets/identifiers
* Windows: Support paths >255 characters
* Windows, OS X: Allow to not sync hidden files
* Windows: Remove misleading option to remove sync data
* Windows: Do not provoke Active Directory account locking if password changes
* Windows: Fix installer when installing unprivileged
.. note:: When you upgrade from 1.8, restart Windows to ensure that all new
features are visible.
Arquivo binário não exibido.
+61 -13
Ver Arquivo
@@ -9,32 +9,39 @@ in the system tray (Windows, KDE), status bar (Mac OS X), or notification area
(Linux).
.. image:: images/icon.png
:alt: Status icon, little cloud with green circle and white checkmark
The status indicator uses overlay icons to indicate the current status of your
synchronization. The green circle with the white checkmark tells you that your
synchronization is current and you are connected to your ownCloud server.
.. image:: images/icon-syncing.png
:alt: Status icon, little cloud with blue circle and white semi-circles
The blue icon with the white semi-circles means synchronization is in progress.
.. image:: images/icon-paused.png
:alt: Status icon, little cloud with yellow circle and vertical parallel
lines
The yellow overlay icon with the parallel lines tells you your synchronization
has been paused. (Most likely by you, by opening the client and clicking
Account > Pause.)
has been paused. (Most likely by you.)
.. image:: images/icon-offline.png
:alt: Status icon, little gray cloud with gray circle and three horizontal
white dots
The gray icon with three white dots means your sync client has lost its
connection with your ownCloud server.
.. image:: images/icon-information.png
:alt: Status icon, little cloud with letter "i" in white circle
When you see a white circle with the letter "i" that is the informational icon,
so you should click it to see what it has to tell you.
.. image:: images/icon-error.png
:alt: Status icon, little cloud with red circle and white x
The red circle with the white "x" indicates a configuration error, such as an
incorrect login or server URL.
@@ -50,7 +57,6 @@ A right-click on the icon opens a menu for quick access to multiple operations.
The Desktop Client menu provides the following options:
* Open ownCloud in browser
* Managed folder
* Open folder [your local sync folder]
* Up to date
* Recent changes
@@ -65,18 +71,56 @@ Using the Account Settings Window
.. index:: account settings, user, password, Server URL
Click **Settings** in the right-click menu to see a summary of your ownCloud
account settings. This shows which ownCloud account you are connected to (or accounts, if you have more than one) your
account settings, or left-click your systray icon. This shows which ownCloud
account you are connected to (or accounts, if you have more than one) your
quota status, and a window for managing your synchronization settings.
.. image:: images/client6.png
:alt: Account settings window
At the top of the window are tabs for each configured sync account, and three others for Activity, General and Network settings.
At the top of the window are tabs for each configured sync account, and three
others for Activity, General and Network settings. On your account tabs you
have the following features:
* Connection status, showing which ownCloud server you are connected to, and
your ownCloud username.
* A **Remove Account** button, which deletes your account but does not delete
your data files.
* Used and available space on the server.
* Current synchronization status.
* **Add Folder Sync Connection** button, which is active only when you have
removed synchronization on an account (see **Remove Sync** below).
The little button with three dots that sits to the right of the sync status bar
offers four additional options:
* Open Folder
* Choose What to Sync
* Pause Sync / Resume Sync
* Remove Sync
**Open Folder** opens a file explorer window displaying the client-side folder
that is being synced.
**Choose What to Sync** opens the folder sync tree view. From there you can
choose to sync all or only some of the folders in the folder tree.
**Pause Sync** pauses sync operations for just this folder sync connection
without making any changes to your account.
**Resume Sync** resumes sync operations for this folder sync connection.
**Remove Sync** removes this folder sync connection without removing the
account. If you want to synchronize the folder tree again then click the
**Add Folder Sync Connection** button, and re-select the folder tree that
you want to sync.
.. image:: images/client-7.png
:alt: Extra options for sync operations
The Activity window contains the log of your recent activities, including files
downloaded and deleted.
downloaded and deleted, and which local folders your files went into.
The General window has configuration options such as Launch on **System
The General window has configuration options such as **Launch on System
Startup**, **Use Monochrome Icons**, and **Show Desktop Notifications**. This
is where you will find the **Edit Ignored Files** button, to launch the ignored
files editor, and two new features: **Ask confirmation before downloading
@@ -87,12 +131,15 @@ Multi-Account Support
You may now configure multiple ownCloud accounts in your desktop sync client.
Simply click the **Add an Account** button on the General tab, and follow the
account creation wizard. The new account will appear as a new tab in the settings dialog, where you can adjust its settings at any time.
account creation wizard. The new account will appear as a new tab in the
settings dialog, where you can adjust its settings at any time.
Editing Ignored Files
---------------------
The Ignored Files Editor can be opened by clicking on the button in the General tab of the settings dialog. The settings apply to all configured accounts. The :guilabel:`Ignored Files Editor` provides a list of files that are ignored
The Ignored Files Editor can be opened by clicking on the button in the General
tab of the settings dialog. The settings apply to all configured accounts. The
:guilabel:`Ignored Files Editor` provides a list of files that are ignored
(that is, not synchronized) by the client and server during synchronizations.
You may add additional files or directories that you want to exclude from the
synchronization process. In addition to using standard characters, the Ignored
@@ -149,7 +196,8 @@ components of the path being checked.
.. note:: Custom entries are currently not validated for syntactical
correctness by the editor, so you will not see any warnings for bad
syntax. If your synchronization does not work as you expected, check your syntax.
syntax. If your synchronization does not work as you expected, check your
syntax.
Each pattern string in the list is preceded by a checkbox. When the check box
contains a check mark, in addition to ignoring the file or directory component
@@ -162,8 +210,8 @@ this list:
- The ownCloud Client always excludes files containing characters that cannot
be synchronized to other file systems.
- Files are removed that cause individual errors three times during a synchronization.
However, the client provides the option of retrying a synchronization three additional
times on files that produce errors.
- Files are removed that cause individual errors three times during a
synchronization. However, the client provides the option of retrying a
synchronization three additional times on files that produce errors.
For more detailed information see :ref:`ignored-files-label`.
+6 -6
Ver Arquivo
@@ -51,8 +51,8 @@ Where:
* ``Connected to <ownCloud instance> as <user>``: Indicates the ownCloud server
which the client is syncing with and the user account on that server.
* ``Add Folder...``: Provides the ability to add another folder to the sync
(see ``Adding a folder``).
* ``Add Folder Sync Connection...``: Provides the ability to add another folder to the sync
(see ``Adding a folder sync connection``).
* ``Pause/Resume``: Will pause the current sync or prevent the client from
starting a new sync. Resume will resume the sync process.
* ``Remove``: Will remove the selected folder from being synced. This is used,
@@ -74,11 +74,11 @@ Where:
.. image:: images/settings_account.png
:scale: 50 %
Adding a Folder
^^^^^^^^^^^^^^^
Adding a Folder Sync Connection
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Adding a new sync is initiated by clicking ``Add Folder...`` in the ``Account``
settings.
Adding a new sync is initiated by clicking ``Add Folder Sync Connection`` in
the ``Account`` settings.
..note:: To add a folder, you must not already sync a folder that contains this
folder. By default, the wizard sets up the root folder of the ownCloud
Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 243 B

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 122 B

@@ -1,256 +0,0 @@
From 3a26dc77f8e988ea99b23c4d5a2c831ecc31c920 Mon Sep 17 00:00:00 2001
From: Olivier Goffart <ogoffart@woboq.com>
Date: Thu, 17 Jul 2014 13:26:56 +0200
Subject: [PATCH] WIP: add KOverlayIconPlugin
---
.../src/kitemviews/kfileitemmodelrolesupdater.cpp | 35 ++++++++++++-
.../src/kitemviews/kfileitemmodelrolesupdater.h | 9 ++++
lib/konq/CMakeLists.txt | 4 +-
lib/konq/koverlayiconplugin.cpp | 30 ++++++++++++
lib/konq/koverlayiconplugin.desktop | 4 ++
lib/konq/koverlayiconplugin.h | 57 ++++++++++++++++++++++
6 files changed, 137 insertions(+), 2 deletions(-)
create mode 100644 lib/konq/koverlayiconplugin.cpp
create mode 100644 lib/konq/koverlayiconplugin.desktop
create mode 100644 lib/konq/koverlayiconplugin.h
diff --git a/dolphin/src/kitemviews/kfileitemmodelrolesupdater.cpp b/dolphin/src/kitemviews/kfileitemmodelrolesupdater.cpp
index 0865d40..840a65d 100644
--- a/dolphin/src/kitemviews/kfileitemmodelrolesupdater.cpp
+++ b/dolphin/src/kitemviews/kfileitemmodelrolesupdater.cpp
@@ -28,9 +28,11 @@
#include <KGlobal>
#include <KIO/JobUiDelegate>
#include <KIO/PreviewJob>
+#include <KServiceTypeTrader>
#include "private/kpixmapmodifier.h"
#include "private/kdirectorycontentscounter.h"
+#include <koverlayiconplugin.h>
#include <QApplication>
#include <QPainter>
@@ -129,6 +131,17 @@ KFileItemModelRolesUpdater::KFileItemModelRolesUpdater(KFileItemModel* model, QO
m_directoryContentsCounter = new KDirectoryContentsCounter(m_model, this);
connect(m_directoryContentsCounter, SIGNAL(result(QString,int)),
this, SLOT(slotDirectoryContentsCountReceived(QString,int)));
+
+
+ const KService::List pluginServices = KServiceTypeTrader::self()->query("KOverlayIconPlugin");
+
+ for (KService::List::ConstIterator it = pluginServices.constBegin(); it != pluginServices.constEnd(); ++it) {
+ KOverlayIconPlugin* plugin = (*it)->createInstance<KOverlayIconPlugin>(this);
+ if (plugin) {
+ m_overlayIconsPlugin.append(plugin);
+ connect(plugin, SIGNAL(overlaysChanged(KUrl,QStringList)), this, SLOT(slotOverlaysChanged(KUrl,QStringList)));
+ }
+ }
}
KFileItemModelRolesUpdater::~KFileItemModelRolesUpdater()
@@ -1075,7 +1088,11 @@ QHash<QByteArray, QVariant> KFileItemModelRolesUpdater::rolesData(const KFileIte
data.insert("type", item.mimeComment());
}
- data.insert("iconOverlays", item.overlays());
+ QStringList overlays = item.overlays();
+ foreach(KOverlayIconPlugin *it, m_overlayIconsPlugin) {
+ overlays.append(it->getOverlays(item));
+ }
+ data.insert("iconOverlays", overlays);
#ifdef HAVE_BALOO
if (m_balooFileMonitor) {
@@ -1086,6 +1103,22 @@ QHash<QByteArray, QVariant> KFileItemModelRolesUpdater::rolesData(const KFileIte
return data;
}
+void KFileItemModelRolesUpdater::slotOverlaysChanged(const KUrl& url, const QStringList &)
+{
+ KFileItem item = m_model->fileItem(url);
+ if (item.isNull())
+ return;
+ int index = m_model->index(item);
+ QHash <QByteArray, QVariant> data = m_model->data(index);
+ QStringList overlays = item.overlays();
+ foreach(KOverlayIconPlugin *it, m_overlayIconsPlugin) {
+ overlays.append(it->getOverlays(item));
+ }
+ data.insert("iconOverlays", overlays);
+ m_model->setData(index, data);
+}
+
+
void KFileItemModelRolesUpdater::updateAllPreviews()
{
if (m_state == Paused) {
diff --git a/dolphin/src/kitemviews/kfileitemmodelrolesupdater.h b/dolphin/src/kitemviews/kfileitemmodelrolesupdater.h
index a9e979a..6d3add0 100644
--- a/dolphin/src/kitemviews/kfileitemmodelrolesupdater.h
+++ b/dolphin/src/kitemviews/kfileitemmodelrolesupdater.h
@@ -32,6 +32,7 @@
#include <QSize>
#include <QStringList>
+class KOverlayIconPlugin;
class KDirectoryContentsCounter;
class KFileItemModel;
class KJob;
@@ -180,6 +181,12 @@ private slots:
void slotPreviewJobFinished();
/**
+ * Is invoked when one of the KOverlayIconPlugin emit the signal that an overlay has changed
+ */
+ void slotOverlaysChanged(const KUrl&, const QStringList&);
+
+
+ /**
* Resolves the sort role of the next item in m_pendingSortRole, applies it
* to the model, and invokes itself if there are any pending items left. If
* that is not the case, \a startUpdating() is called.
@@ -331,6 +338,8 @@ private:
KDirectoryContentsCounter* m_directoryContentsCounter;
+ QList<KOverlayIconPlugin*> m_overlayIconsPlugin;
+
#ifdef HAVE_BALOO
Baloo::FileMonitor* m_balooFileMonitor;
#endif
diff --git a/lib/konq/CMakeLists.txt b/lib/konq/CMakeLists.txt
index 8ecbfa9..7381caf 100644
--- a/lib/konq/CMakeLists.txt
+++ b/lib/konq/CMakeLists.txt
@@ -22,6 +22,7 @@ set(konq_LIB_SRCS
konq_historyprovider.cpp
kversioncontrolplugin.cpp # used by dolphin and its version control plugins (deprecated)
kversioncontrolplugin2.cpp # used by dolphin and its version control plugins
+ koverlayiconplugin.cpp
konq_nameandurlinputdialog.cpp # deprecated (functionality has moved to kdelibs)
knewmenu.cpp # deprecated (functionality has moved to kdelibs)
@@ -67,8 +68,9 @@ install( FILES
konq_fileitemcapabilities.h
kversioncontrolplugin.h
kversioncontrolplugin2.h
+ koverlayiconplugin.h
konq_historyprovider.h
konq_historyentry.h
DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT Devel
)
-install( FILES konqpopupmenuplugin.desktop konqdndpopupmenuplugin.desktop DESTINATION ${SERVICETYPES_INSTALL_DIR} )
+install( FILES konqpopupmenuplugin.desktop konqdndpopupmenuplugin.desktop koverlayiconplugin.desktop DESTINATION ${SERVICETYPES_INSTALL_DIR} )
diff --git a/lib/konq/koverlayiconplugin.cpp b/lib/konq/koverlayiconplugin.cpp
new file mode 100644
index 0000000..6125040
--- /dev/null
+++ b/lib/konq/koverlayiconplugin.cpp
@@ -0,0 +1,30 @@
+/*****************************************************************************
+ * Copyright (C) 2014 by Olivier Goffart <ogoffart@woboq.com> *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Library General Public *
+ * License version 2 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Library General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Library General Public License *
+ * along with this library; see the file COPYING.LIB. If not, write to *
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301, USA. *
+ *****************************************************************************/
+
+#include "koverlayiconplugin.h"
+#include <KFileItem>
+
+KOverlayIconPlugin::KOverlayIconPlugin(QObject* parent) : QObject(parent)
+{
+}
+
+KOverlayIconPlugin::~KOverlayIconPlugin()
+{
+}
+
+#include "koverlayiconplugin.moc"
diff --git a/lib/konq/koverlayiconplugin.desktop b/lib/konq/koverlayiconplugin.desktop
new file mode 100644
index 0000000..65a1170
--- /dev/null
+++ b/lib/konq/koverlayiconplugin.desktop
@@ -0,0 +1,4 @@
+[Desktop Entry]
+Type=ServiceType
+X-KDE-ServiceType=KOverlayIconPlugin
+Comment=Plugin to add overlay icons in Dolphin
diff --git a/lib/konq/koverlayiconplugin.h b/lib/konq/koverlayiconplugin.h
new file mode 100644
index 0000000..bcdf31b
--- /dev/null
+++ b/lib/konq/koverlayiconplugin.h
@@ -0,0 +1,57 @@
+/*****************************************************************************
+ * Copyright (C) 2014 by Olivier Goffart <ogoffart@woboq.com> *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Library General Public *
+ * License version 2 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Library General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Library General Public License *
+ * along with this library; see the file COPYING.LIB. If not, write to *
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301, USA. *
+ *****************************************************************************/
+
+
+#ifndef OverlayIconPlugin_H
+#define OverlayIconPlugin_H
+
+#include <QtCore/QObject>
+#include <libkonq_export.h>
+
+class KUrl;
+class KFileItem;
+
+/**
+ * @brief Base class for overlay icon plugins.
+ *
+ * Enables the file manager to show custom overlay icons on files.
+ *
+ * To write a custom plugin you need to create a .desktop file for your plugin with
+ * KDE-ServiceTypes=KOverlayIconPlugin
+ */
+class LIBKONQ_EXPORT KOverlayIconPlugin : public QObject {
+ Q_OBJECT
+ void *d;
+public:
+ explicit KOverlayIconPlugin(QObject *parent = 0);
+ ~KOverlayIconPlugin();
+
+ /**
+ * Returns a list of overlay pixmap to add to a file
+ * This can be a path to an icon, or the icon name
+ */
+ virtual QStringList getOverlays(const KFileItem &item) = 0;
+signals:
+
+ /**
+ * Emit this signal when the list of overlay icon changed for a given URL
+ */
+ void overlaysChanged(const KUrl &url, const QStringList &overlays);
+};
+
+#endif
--
2.1.3
+41 -12
Ver Arquivo
@@ -1,17 +1,46 @@
cmake_minimum_required(VERSION 2.6)
project(dolphin-owncloud)
find_package(KDE4 REQUIRED)
include(KDE4Defaults)
include(MacroLibrary)
find_package(LibKonq REQUIRED)
add_definitions (${QT_DEFINITIONS} ${KDE4_DEFINITIONS})
cmake_minimum_required(VERSION 2.8.12)
include(FeatureSummary)
set(QT_MIN_VERSION "5.3.0")
set(KF5_MIN_VERSION "5.16.0")
find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS Core Network)
find_package(ECM 1.2.0 REQUIRED CONFIG)
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS CoreAddons KIO)
set_package_properties(DolphinVcs PROPERTIES
DESCRIPTION "the Dolphin plugin library"
URL "http://dolphin.kde.org/"
TYPE REQUIRED
PURPOSE "Provides plugin interfaces for Dolphin."
)
include(KDEInstallDirs)
include(KDECMakeSettings)
include(KDECompilerSettings)
include(ECMMarkNonGuiExecutable)
include(GenerateExportHeader)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
add_definitions(-DQT_USE_FAST_CONCATENATION -DQT_USE_FAST_OPERATOR_PLUS)
include_directories (${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ${KDE4_INCLUDES} )
include_directories( ${KDE4_INCLUDE_DIR} ${QT_INCLUDES} ${LIBKONQ_INCLUDE_DIR} )
kde4_add_plugin(ownclouddolphinplugin ownclouddolphinplugin.cpp)
#---HELPER---
add_library(ownclouddolphinpluginhelper SHARED ownclouddolphinpluginhelper.cpp)
target_link_libraries(ownclouddolphinpluginhelper Qt5::Network)
generate_export_header(ownclouddolphinpluginhelper)
install(TARGETS ownclouddolphinpluginhelper LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
target_link_libraries(ownclouddolphinplugin ${KDE4_KIO_LIBS} ${LIBKONQ_LIBRARY})
install(FILES ownclouddolphinplugin.desktop DESTINATION ${SERVICES_INSTALL_DIR})
install(TARGETS ownclouddolphinplugin DESTINATION ${PLUGIN_INSTALL_DIR})
#---OVERLAY PLUGIN---
kcoreaddons_add_plugin(ownclouddolphinoverlayplugin INSTALL_NAMESPACE "kf5/overlayicon"
JSON ownclouddolphinoverlayplugin.json SOURCES ownclouddolphinoverlayplugin.cpp)
target_link_libraries(ownclouddolphinoverlayplugin KF5::CoreAddons KF5::KIOCore KF5::KIOWidgets ownclouddolphinpluginhelper)
#---ACTION PLUGIN---
add_library(ownclouddolphinactionplugin MODULE ownclouddolphinactionplugin.cpp)
target_link_libraries(ownclouddolphinactionplugin KF5::CoreAddons KF5::KIOCore KF5::KIOWidgets ownclouddolphinpluginhelper)
install(FILES ownclouddolphinactionplugin.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
install(TARGETS ownclouddolphinactionplugin DESTINATION ${KDE_INSTALL_PLUGINDIR})
+4 -11
Ver Arquivo
@@ -1,18 +1,11 @@
- The patch 0001-KOverlayIconPlugin.patch should be applied to kde-baseapps git repository
(It should apply to both KDE/4.14 or Applications/14.12 branches)
- Recompile and install dolphin
- Recompile and install recent enough version of dolphin and kio (git from oct 2015)
- Build and install the plugin
- After installing, run
kdeinit4 --noincremental
- Make sure to set XDG_DATA_DIRS=$PREFIX/share, QT_PLUGIN_PATH=$PREFIX/lib64/plugins/
- To test that the plugin is well installed
ktraderclient --servicetype KOverlayIconPlugin
It should show the Owncloud plugin
- After installing, run
kdeinit5 --noincremental
- restart dolphin (make sure to kill all instances)
@@ -0,0 +1,67 @@
/******************************************************************************
* Copyright (C) 2014 by Olivier Goffart <ogoffart@woboq.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. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
******************************************************************************/
#include <KPluginFactory>
#include <KPluginLoader>
#include <KIOWidgets/kabstractfileitemactionplugin.h>
#include <QtNetwork/QLocalSocket>
#include <KIOCore/kfileitem.h>
#include <KIOCore/KFileItemListProperties>
#include <QtWidgets/QAction>
#include <QtCore/QTimer>
#include "ownclouddolphinpluginhelper.h"
class OwncloudDolphinPluginAction : public KAbstractFileItemActionPlugin
{
public:
explicit OwncloudDolphinPluginAction(QObject* parent, const QList<QVariant>&)
: KAbstractFileItemActionPlugin(parent) { }
QList<QAction*> actions(const KFileItemListProperties& fileItemInfos, QWidget* parentWidget) Q_DECL_OVERRIDE
{
auto helper = OwncloudDolphinPluginHelper::instance();
QList<QUrl> urls = fileItemInfos.urlList();
if (urls.count() != 1 || !helper->isConnected())
return {};
auto url = urls.first();
if (!url.isLocalFile())
return {};
auto localFile = url.toLocalFile();
const auto paths = helper->paths();
if (!std::any_of(paths.begin(), paths.end(), [&](const QString &s) {
return localFile.startsWith(s);
} ))
return {};
auto act = new QAction(parentWidget);
act->setText(helper->shareActionString());
connect(act, &QAction::triggered, this, [localFile, helper] {
helper->sendCommand("SHARE:"+localFile.toUtf8()+"\n");
} );
return { act };
}
};
K_PLUGIN_FACTORY(OwncloudDolphinPluginActionFactory, registerPlugin<OwncloudDolphinPluginAction>();)
K_EXPORT_PLUGIN(OwncloudDolphinPluginActionFactory("ownclouddolhpinpluginaction"))
#include "ownclouddolphinactionplugin.moc"
@@ -0,0 +1,6 @@
[Desktop Entry]
Type=Service
Name=OwncloudAction
ServiceTypes=KFileItemAction/Plugin
MimeType=application/octet-stream;inode/directory;
X-KDE-Library=ownclouddolphinactionplugin
@@ -0,0 +1,101 @@
/******************************************************************************
* Copyright (C) 2014 by Olivier Goffart <ogoffart@woboq.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. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
******************************************************************************/
#include <KOverlayIconPlugin>
#include <KPluginFactory>
#include <QtNetwork/QLocalSocket>
#include <KIOCore/kfileitem.h>
#include <QTimer>
#include "ownclouddolphinpluginhelper.h"
class OwncloudDolphinPlugin : public KOverlayIconPlugin
{
Q_PLUGIN_METADATA(IID "com.owncloud.ovarlayiconplugin" FILE "ownclouddolphinoverlayplugin.json");
Q_OBJECT
typedef QHash<QByteArray, QByteArray> StatusMap;
StatusMap m_status;
public:
OwncloudDolphinPlugin() {
auto helper = OwncloudDolphinPluginHelper::instance();
QObject::connect(helper, &OwncloudDolphinPluginHelper::commandRecieved,
this, &OwncloudDolphinPlugin::slotCommandRecieved);
}
QStringList getOverlays(const QUrl& url) override {
auto helper = OwncloudDolphinPluginHelper::instance();
if (!helper->isConnected())
return QStringList();
if (!url.isLocalFile())
return QStringList();
const QByteArray localFile = url.toLocalFile().toUtf8();
helper->sendCommand("RETRIEVE_FILE_STATUS:" + localFile + "\n");
StatusMap::iterator it = m_status.find(localFile);
if (it != m_status.constEnd()) {
return overlaysForString(*it);
}
return QStringList();
}
private:
QStringList overlaysForString(const QByteArray &status) {
QStringList r;
if (status.startsWith("NOP"))
return r;
if (status.startsWith("OK"))
r << "ownCloud_ok";
if (status.startsWith("SYNC") || status.startsWith("NEW"))
r << "ownCloud_sync";
if (status.startsWith("IGNORE") || status.startsWith("WARN"))
r << "ownCloud_warn";
if (status.startsWith("ERROR"))
r << "ownCloud_error";
if (status.contains("+SWM"))
r << "document-share";
return r;
}
void slotCommandRecieved(const QByteArray &line) {
QList<QByteArray> tokens = line.split(':');
if (tokens.count() != 3)
return;
if (tokens[0] != "STATUS" && tokens[0] != "BROADCAST")
return;
if (tokens[2].isEmpty())
return;
const QByteArray name = tokens[2];
QByteArray &status = m_status[name]; // reference to the item in the hash
if (status == tokens[1])
return;
status = tokens[1];
emit overlaysChanged(QUrl::fromLocalFile(QString::fromUtf8(name)), overlaysForString(status));
}
};
#include "ownclouddolphinoverlayplugin.moc"
@@ -0,0 +1,8 @@
{
"KPlugin": {
"Description": "Overlay icon for owncloud",
"ServiceTypes": [
"KOverlayIconPlugin"
]
}
}
@@ -1,131 +0,0 @@
/******************************************************************************
* Copyright (C) 2014 by Olivier Goffart <ogoffart@woboq.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. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
******************************************************************************/
#include <koverlayiconplugin.h>
#include <KPluginFactory>
#include <KPluginLoader>
#include <kdebug.h>
#include <kfileitem.h>
#include <QtNetwork/QLocalSocket>
class OwncloudDolphinPlugin : public KOverlayIconPlugin
{
Q_OBJECT
QLocalSocket m_socket;
typedef QHash<QByteArray, QByteArray> StatusMap;
StatusMap m_status;
QByteArray m_line;
public:
explicit OwncloudDolphinPlugin(QObject* parent, const QList<QVariant>&) : KOverlayIconPlugin(parent) {
connect(&m_socket, SIGNAL(readyRead()), this, SLOT(readyRead()));
tryConnect();
}
virtual QStringList getOverlays(const KFileItem& item) {
KUrl url = item.url();
if (!url.isLocalFile())
return QStringList();
const QByteArray localFile = url.toLocalFile().toUtf8();
kDebug() << localFile;
tryConnect();
if (m_socket.state() == QLocalSocket::ConnectingState) {
if (!m_socket.waitForConnected(100)) {
kWarning() << "not connected" << m_socket.errorString();
}
}
if (m_socket.state() == QLocalSocket::ConnectedState) {
m_socket.write("RETRIEVE_FILE_STATUS:");
m_socket.write(localFile);
m_socket.write("\n");
}
StatusMap::iterator it = m_status.find(localFile);
if (it != m_status.constEnd()) {
return overlaysForString(*it);
}
return QStringList();
}
private:
void tryConnect() {
if (m_socket.state() != QLocalSocket::UnconnectedState)
return;
QString runtimeDir = QFile::decodeName(qgetenv("XDG_RUNTIME_DIR"));
QString socketPath = runtimeDir + "/" + "ownCloud" + "/socket";
m_socket.connectToServer(socketPath);
}
QStringList overlaysForString(const QByteArray status) {
QStringList r;
if (status.startsWith("NOP"))
return r;
if (status.startsWith("OK"))
r << "dialog-ok";
if (status.startsWith("SYNC") || status.startsWith("NEW"))
r << "view-refresh";
if (status.contains("+SWM"))
r << "document-share";
kDebug() << status << r;
return r;
}
private slots:
void readyRead() {
while (m_socket.bytesAvailable()) {
m_line += m_socket.readLine();
if (!m_line.endsWith("\n"))
continue;
QByteArray line;
qSwap(line, m_line);
line.chop(1);
kDebug() << "got line " << line;
if (line.isEmpty())
continue;
QList<QByteArray> tokens = line.split(':');
if (tokens.count() != 3)
continue;
if (tokens[0] != "STATUS" && tokens[0] != "BROADCAST")
continue;
if (tokens[2].isEmpty())
continue;
const QByteArray name = tokens[2];
QByteArray &status = m_status[name]; // reference to the item in the hash
if (status == tokens[1])
continue;
status = tokens[1];
emit this->overlaysChanged(KUrl::fromLocalFile(QString::fromUtf8(name)), overlaysForString(status));
}
}
};
K_PLUGIN_FACTORY(OwncloudDolphinPluginFactory, registerPlugin<OwncloudDolphinPlugin>();)
K_EXPORT_PLUGIN(OwncloudDolphinPluginFactory("ownclouddolhpinplugin"))
#include "ownclouddolphinplugin.moc"
@@ -1,6 +0,0 @@
[Desktop Entry]
Type=Service
Name=Owncloud
X-KDE-ServiceTypes=KOverlayIconPlugin
MimeType=text/plain;
X-KDE-Library=ownclouddolphinplugin
@@ -0,0 +1,98 @@
/******************************************************************************
* Copyright (C) 2014 by Olivier Goffart <ogoffart@woboq.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. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
******************************************************************************/
#include <QtNetwork/QLocalSocket>
#include <qcoreevent.h>
#include <QFile>
#include "ownclouddolphinpluginhelper.h"
OwncloudDolphinPluginHelper* OwncloudDolphinPluginHelper::instance()
{
static OwncloudDolphinPluginHelper self;
return &self;
}
OwncloudDolphinPluginHelper::OwncloudDolphinPluginHelper()
{
connect(&_socket, &QLocalSocket::connected, this, &OwncloudDolphinPluginHelper::slotConnected);
connect(&_socket, &QLocalSocket::readyRead, this, &OwncloudDolphinPluginHelper::slotReadyRead);
_connectTimer.start(45 * 1000, Qt::VeryCoarseTimer, this);
tryConnect();
}
void OwncloudDolphinPluginHelper::timerEvent(QTimerEvent *e)
{
if (e->timerId() == _connectTimer.timerId()) {
tryConnect();
return;
}
QObject::timerEvent(e);
}
bool OwncloudDolphinPluginHelper::isConnected() const
{
return _socket.state() == QLocalSocket::ConnectedState;
}
void OwncloudDolphinPluginHelper::sendCommand(const char* data)
{
_socket.write(data);
_socket.flush();
}
void OwncloudDolphinPluginHelper::slotConnected()
{
sendCommand("SHARE_MENU_TITLE:\n");
}
void OwncloudDolphinPluginHelper::tryConnect()
{
if (_socket.state() != QLocalSocket::UnconnectedState) {
return;
}
QString runtimeDir = QFile::decodeName(qgetenv("XDG_RUNTIME_DIR"));
QString socketPath = runtimeDir + QLatin1String("/ownCloud/socket");
_socket.connectToServer(socketPath);
}
void OwncloudDolphinPluginHelper::slotReadyRead()
{
while (_socket.bytesAvailable()) {
_line += _socket.readLine();
if (!_line.endsWith("\n"))
continue;
QByteArray line;
qSwap(line, _line);
line.chop(1);
if (line.isEmpty())
continue;
if (line.startsWith("REGISTER_PATH:")) {
auto col = line.indexOf(':');
QString file = QString::fromUtf8(line.constData() + col + 1, line.size() - col - 1);
_paths.append(file);
continue;
} else if (line.startsWith("SHARE_MENU_TITLE:")) {
auto col = line.indexOf(':');
_shareActionString = QString::fromUtf8(line.constData() + col + 1, line.size() - col - 1);
continue;
}
emit commandRecieved(line);
}
}
@@ -0,0 +1,52 @@
/******************************************************************************
* Copyright (C) 2014 by Olivier Goffart <ogoffart@woboq.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. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
******************************************************************************/
#pragma once
#include <QObject>
#include <QBasicTimer>
#include <QLocalSocket>
#include "ownclouddolphinpluginhelper_export.h"
class OWNCLOUDDOLPHINPLUGINHELPER_EXPORT OwncloudDolphinPluginHelper : public QObject {
Q_OBJECT
public:
static OwncloudDolphinPluginHelper *instance();
QString shareActionString() const { return _shareActionString; }
bool isConnected() const;
void sendCommand(const char *data);
QVector<QString> paths() const { return _paths; }
signals:
void commandRecieved(const QByteArray &cmd);
protected:
void timerEvent(QTimerEvent*) override;
private:
OwncloudDolphinPluginHelper();
void slotConnected();
void slotReadyRead();
void tryConnect();
QLocalSocket _socket;
QByteArray _line;
QVector<QString> _paths;
QString _shareActionString;
QBasicTimer _connectTimer;
};
@@ -1,267 +0,0 @@
From d452ed613a9e02ed81eec2f3226f28babff240c8 Mon Sep 17 00:00:00 2001
From: Olivier Goffart <ogoffart@woboq.com>
Date: Thu, 17 Jul 2014 13:26:56 +0200
Subject: [PATCH] WIP: add KOverlayIconPlugin
Conflicts:
dolphin/src/kitemviews/kfileitemmodelrolesupdater.cpp
lib/konq/CMakeLists.txt
---
.../src/kitemviews/kfileitemmodelrolesupdater.cpp | 38 ++++++++++++++-
.../src/kitemviews/kfileitemmodelrolesupdater.h | 9 ++++
lib/konq/src/CMakeLists.txt | 4 +-
lib/konq/src/koverlayiconplugin.cpp | 30 ++++++++++++
lib/konq/src/koverlayiconplugin.desktop | 4 ++
lib/konq/src/koverlayiconplugin.h | 57 ++++++++++++++++++++++
6 files changed, 140 insertions(+), 2 deletions(-)
create mode 100644 lib/konq/src/koverlayiconplugin.cpp
create mode 100644 lib/konq/src/koverlayiconplugin.desktop
create mode 100644 lib/konq/src/koverlayiconplugin.h
diff --git a/dolphin/src/kitemviews/kfileitemmodelrolesupdater.cpp b/dolphin/src/kitemviews/kfileitemmodelrolesupdater.cpp
index df521e2..4d94836 100644
--- a/dolphin/src/kitemviews/kfileitemmodelrolesupdater.cpp
+++ b/dolphin/src/kitemviews/kfileitemmodelrolesupdater.cpp
@@ -29,9 +29,11 @@
#include <KJobWidgets>
#include <KIO/JobUiDelegate>
#include <KIO/PreviewJob>
+#include <KServiceTypeTrader>
#include "private/kpixmapmodifier.h"
#include "private/kdirectorycontentscounter.h"
+#include <koverlayiconplugin.h>
#include <QApplication>
#include <QPainter>
@@ -129,6 +131,20 @@ KFileItemModelRolesUpdater::KFileItemModelRolesUpdater(KFileItemModel* model, QO
m_directoryContentsCounter = new KDirectoryContentsCounter(m_model, this);
connect(m_directoryContentsCounter, &KDirectoryContentsCounter::result,
this, &KFileItemModelRolesUpdater::slotDirectoryContentsCountReceived);
+
+
+ const KService::List pluginServices = KServiceTypeTrader::self()->query("KOverlayIconPlugin");
+
+ for (KService::List::ConstIterator it = pluginServices.constBegin(); it != pluginServices.constEnd(); ++it) {
+ QString error;
+ KOverlayIconPlugin* plugin = (*it)->createInstance<KOverlayIconPlugin>(this, QVariantList(), &error);
+ if (plugin) {
+ m_overlayIconsPlugin.append(plugin);
+ connect(plugin, &KOverlayIconPlugin::overlaysChanged, this, &KFileItemModelRolesUpdater::slotOverlaysChanged);
+ } else {
+ qWarning() << "Could not load plugin " << (*it)->name() << ":" << error;
+ }
+ }
}
KFileItemModelRolesUpdater::~KFileItemModelRolesUpdater()
@@ -1065,7 +1081,11 @@ QHash<QByteArray, QVariant> KFileItemModelRolesUpdater::rolesData(const KFileIte
data.insert("type", item.mimeComment());
}
- data.insert("iconOverlays", item.overlays());
+ QStringList overlays = item.overlays();
+ foreach(KOverlayIconPlugin *it, m_overlayIconsPlugin) {
+ overlays.append(it->getOverlays(item));
+ }
+ data.insert("iconOverlays", overlays);
#ifdef HAVE_BALOO
if (m_balooFileMonitor) {
@@ -1076,6 +1096,22 @@ QHash<QByteArray, QVariant> KFileItemModelRolesUpdater::rolesData(const KFileIte
return data;
}
+void KFileItemModelRolesUpdater::slotOverlaysChanged(const QUrl& url, const QStringList &)
+{
+ KFileItem item = m_model->fileItem(url);
+ if (item.isNull())
+ return;
+ int index = m_model->index(item);
+ QHash <QByteArray, QVariant> data = m_model->data(index);
+ QStringList overlays = item.overlays();
+ foreach(KOverlayIconPlugin *it, m_overlayIconsPlugin) {
+ overlays.append(it->getOverlays(item));
+ }
+ data.insert("iconOverlays", overlays);
+ m_model->setData(index, data);
+}
+
+
void KFileItemModelRolesUpdater::updateAllPreviews()
{
if (m_state == Paused) {
diff --git a/dolphin/src/kitemviews/kfileitemmodelrolesupdater.h b/dolphin/src/kitemviews/kfileitemmodelrolesupdater.h
index 6c82dbe..1e5b98e 100644
--- a/dolphin/src/kitemviews/kfileitemmodelrolesupdater.h
+++ b/dolphin/src/kitemviews/kfileitemmodelrolesupdater.h
@@ -32,6 +32,7 @@
#include <QSize>
#include <QStringList>
+class KOverlayIconPlugin;
class KDirectoryContentsCounter;
class KFileItemModel;
class QPixmap;
@@ -183,6 +184,12 @@ private slots:
void slotPreviewJobFinished();
/**
+ * Is invoked when one of the KOverlayIconPlugin emit the signal that an overlay has changed
+ */
+ void slotOverlaysChanged(const QUrl& url, const QStringList&);
+
+
+ /**
* Resolves the sort role of the next item in m_pendingSortRole, applies it
* to the model, and invokes itself if there are any pending items left. If
* that is not the case, \a startUpdating() is called.
@@ -333,6 +340,8 @@ private:
KDirectoryContentsCounter* m_directoryContentsCounter;
+ QList<KOverlayIconPlugin*> m_overlayIconsPlugin;
+
#ifdef HAVE_BALOO
Baloo::FileMonitor* m_balooFileMonitor;
#endif
diff --git a/lib/konq/src/CMakeLists.txt b/lib/konq/src/CMakeLists.txt
index 9c05b9f..0ac0526 100644
--- a/lib/konq/src/CMakeLists.txt
+++ b/lib/konq/src/CMakeLists.txt
@@ -15,6 +15,7 @@ set(konq_LIB_SRCS
konq_historyprovider.cpp # konqueror and konqueror/sidebar
kversioncontrolplugin.cpp # used by dolphin and its version control plugins (deprecated)
kversioncontrolplugin2.cpp # used by dolphin and its version control plugins
+ koverlayiconplugin.cpp
)
add_library(KF5Konq ${konq_LIB_SRCS})
@@ -64,13 +65,14 @@ install(FILES
konq_popupmenuplugin.h
kversioncontrolplugin.h
kversioncontrolplugin2.h
+ koverlayiconplugin.h
${LibKonq_BINARY_DIR}/src/libkonq_export.h
DESTINATION ${KF5_INCLUDE_INSTALL_DIR}
COMPONENT Devel
)
-install(FILES konqpopupmenuplugin.desktop konqdndpopupmenuplugin.desktop
+install(FILES konqpopupmenuplugin.desktop konqdndpopupmenuplugin.desktop koverlayiconplugin.desktop
DESTINATION ${SERVICETYPES_INSTALL_DIR}
)
diff --git a/lib/konq/src/koverlayiconplugin.cpp b/lib/konq/src/koverlayiconplugin.cpp
new file mode 100644
index 0000000..6125040
--- /dev/null
+++ b/lib/konq/src/koverlayiconplugin.cpp
@@ -0,0 +1,30 @@
+/*****************************************************************************
+ * Copyright (C) 2014 by Olivier Goffart <ogoffart@woboq.com> *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Library General Public *
+ * License version 2 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Library General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Library General Public License *
+ * along with this library; see the file COPYING.LIB. If not, write to *
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301, USA. *
+ *****************************************************************************/
+
+#include "koverlayiconplugin.h"
+#include <KFileItem>
+
+KOverlayIconPlugin::KOverlayIconPlugin(QObject* parent) : QObject(parent)
+{
+}
+
+KOverlayIconPlugin::~KOverlayIconPlugin()
+{
+}
+
+#include "koverlayiconplugin.moc"
diff --git a/lib/konq/src/koverlayiconplugin.desktop b/lib/konq/src/koverlayiconplugin.desktop
new file mode 100644
index 0000000..65a1170
--- /dev/null
+++ b/lib/konq/src/koverlayiconplugin.desktop
@@ -0,0 +1,4 @@
+[Desktop Entry]
+Type=ServiceType
+X-KDE-ServiceType=KOverlayIconPlugin
+Comment=Plugin to add overlay icons in Dolphin
diff --git a/lib/konq/src/koverlayiconplugin.h b/lib/konq/src/koverlayiconplugin.h
new file mode 100644
index 0000000..bfdaa2f
--- /dev/null
+++ b/lib/konq/src/koverlayiconplugin.h
@@ -0,0 +1,57 @@
+/*****************************************************************************
+ * Copyright (C) 2014 by Olivier Goffart <ogoffart@woboq.com> *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Library General Public *
+ * License version 2 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Library General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Library General Public License *
+ * along with this library; see the file COPYING.LIB. If not, write to *
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301, USA. *
+ *****************************************************************************/
+
+
+#ifndef OverlayIconPlugin_H
+#define OverlayIconPlugin_H
+
+#include <QtCore/QObject>
+#include <libkonq_export.h>
+
+class KUrl;
+class KFileItem;
+
+/**
+ * @brief Base class for overlay icon plugins.
+ *
+ * Enables the file manager to show custom overlay icons on files.
+ *
+ * To write a custom plugin you need to create a .desktop file for your plugin with
+ * KDE-ServiceTypes=KOverlayIconPlugin
+ */
+class LIBKONQ_EXPORT KOverlayIconPlugin : public QObject {
+ Q_OBJECT
+ void *d;
+public:
+ explicit KOverlayIconPlugin(QObject *parent = 0);
+ ~KOverlayIconPlugin();
+
+ /**
+ * Returns a list of overlay pixmap to add to a file
+ * This can be a path to an icon, or the icon name
+ */
+ virtual QStringList getOverlays(const KFileItem &item) = 0;
+signals:
+
+ /**
+ * Emit this signal when the list of overlay icon changed for a given URL
+ */
+ void overlaysChanged(const QUrl &url, const QStringList &overlays);
+};
+
+#endif
--
2.2.1
-30
Ver Arquivo
@@ -1,30 +0,0 @@
project(dolphin-owncloud)
cmake_minimum_required(VERSION 2.8)
set(QT_MIN_VERSION "5.3.0")
find_package(ECM 1.2.0 REQUIRED CONFIG)
include(FeatureSummary)
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH})
include(KDEInstallDirs)
include(KDECMakeSettings)
include(KDECompilerSettings)
include(ECMInstallIcons)
include(ECMSetupVersion)
find_package(Qt5 CONFIG REQUIRED Core DBus Test Widgets)
find_package(KF5 REQUIRED Archive Bookmarks CoreAddons Config ConfigWidgets DBusAddons KIO KDELibs4Support Parts Activities)
find_package(KF5Konq REQUIRED)
add_definitions(-DQT_USE_FAST_CONCATENATION -DQT_USE_FAST_OPERATOR_PLUS)
add_library(ownclouddolphinplugin MODULE ownclouddolphinplugin.cpp)
target_link_libraries(ownclouddolphinplugin KF5::Konq)
install(FILES ownclouddolphinplugin.desktop DESTINATION ${SERVICES_INSTALL_DIR})
install(TARGETS ownclouddolphinplugin DESTINATION ${PLUGIN_INSTALL_DIR})
-16
Ver Arquivo
@@ -1,16 +0,0 @@
- The patch 0001-KOverlayIconPlugin.patch should be applied to kde-baseapps git repository
(It should apply to frameworks branch)
- Recompile and install dolphin (frameworks branch)
- Build and install the plugin
- Make sure to set XDG_DATA_DIRS=$PREFIX/share, QT_PLUGIN_PATH=$PREFIX/lib64/plugins/
- After installing, run
kdeinit5 --noincremental
- restart dolphin (make sure to kill all instances)
@@ -1,131 +0,0 @@
/******************************************************************************
* Copyright (C) 2014 by Olivier Goffart <ogoffart@woboq.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. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
******************************************************************************/
#include <koverlayiconplugin.h>
#include <KPluginFactory>
#include <KPluginLoader>
#include <kdebug.h>
#include <kfileitem.h>
#include <QtNetwork/QLocalSocket>
class OwncloudDolphinPlugin : public KOverlayIconPlugin
{
Q_OBJECT
QLocalSocket m_socket;
typedef QHash<QByteArray, QByteArray> StatusMap;
StatusMap m_status;
QByteArray m_line;
public:
explicit OwncloudDolphinPlugin(QObject* parent, const QList<QVariant>&) : KOverlayIconPlugin(parent) {
connect(&m_socket, SIGNAL(readyRead()), this, SLOT(readyRead()));
tryConnect();
}
virtual QStringList getOverlays(const KFileItem& item) {
auto url = item.url();
if (!url.isLocalFile())
return QStringList();
const QByteArray localFile = url.toLocalFile().toUtf8();
kDebug() << localFile;
tryConnect();
if (m_socket.state() == QLocalSocket::ConnectingState) {
if (!m_socket.waitForConnected(100)) {
kWarning() << "not connected" << m_socket.errorString();
}
}
if (m_socket.state() == QLocalSocket::ConnectedState) {
m_socket.write("RETRIEVE_FILE_STATUS:");
m_socket.write(localFile);
m_socket.write("\n");
}
StatusMap::iterator it = m_status.find(localFile);
if (it != m_status.constEnd()) {
return overlaysForString(*it);
}
return QStringList();
}
private:
void tryConnect() {
if (m_socket.state() != QLocalSocket::UnconnectedState)
return;
QString runtimeDir = QFile::decodeName(qgetenv("XDG_RUNTIME_DIR"));
QString socketPath = runtimeDir + "/" + "ownCloud" + "/socket";
m_socket.connectToServer(socketPath);
}
QStringList overlaysForString(const QByteArray status) {
QStringList r;
if (status.startsWith("NOP"))
return r;
if (status.startsWith("OK"))
r << "dialog-ok";
if (status.startsWith("SYNC") || status.startsWith("NEW"))
r << "view-refresh";
if (status.contains("+SWM"))
r << "document-share";
kDebug() << status << r;
return r;
}
private slots:
void readyRead() {
while (m_socket.bytesAvailable()) {
m_line += m_socket.readLine();
if (!m_line.endsWith("\n"))
continue;
QByteArray line;
qSwap(line, m_line);
line.chop(1);
kDebug() << "got line " << line;
if (line.isEmpty())
continue;
QList<QByteArray> tokens = line.split(':');
if (tokens.count() != 3)
continue;
if (tokens[0] != "STATUS" && tokens[0] != "BROADCAST")
continue;
if (tokens[2].isEmpty())
continue;
const QByteArray name = tokens[2];
QByteArray &status = m_status[name]; // reference to the item in the hash
if (status == tokens[1])
continue;
status = tokens[1];
emit this->overlaysChanged(QUrl::fromLocalFile(QString::fromUtf8(name)), overlaysForString(status));
}
}
};
K_PLUGIN_FACTORY(OwncloudDolphinPluginFactory, registerPlugin<OwncloudDolphinPlugin>();)
K_EXPORT_PLUGIN(OwncloudDolphinPluginFactory("ownclouddolhpinplugin"))
#include "ownclouddolphinplugin.moc"
@@ -1,6 +0,0 @@
[Desktop Entry]
Type=Service
Name=Owncloud
X-KDE-ServiceTypes=KOverlayIconPlugin
MimeType=text/plain;
X-KDE-Library=ownclouddolphinplugin
+48 -42
Ver Arquivo
@@ -2,6 +2,10 @@
#
# Copyright (C) by Klaas Freitag <freitag@owncloud.com>
#
# This program is the core of OwnCloud integration to Nautilus
# It will be installed on /usr/share/nautilus-python/extensions/ with the paquet owncloud-client-nautilus
# (https://github.com/owncloud/client/edit/master/shell_integration/nautilus/syncstate.py)
#
# 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
@@ -18,7 +22,9 @@ import socket
from gi.repository import GObject, Nautilus
# do not touch the following line.
print("Initializing owncloud-client-nautilus extension")
# Do not touch the following line.
appname = 'ownCloud'
def get_local_path(url):
@@ -38,7 +44,6 @@ def get_runtime_dir():
return fallback
class SocketConnect(GObject.GObject):
def __init__(self):
GObject.GObject.__init__(self)
@@ -48,8 +53,8 @@ class SocketConnect(GObject.GObject):
self._sock = None
self._listeners = [self._update_registered_paths]
self._remainder = ''
self.nautilusVFSFile_table = {} # not needed in this object actually but shared
# all over the other objects.
self.nautilusVFSFile_table = {} # not needed in this object actually but shared
# all over the other objects.
# returns true when one should try again!
if self._connectToSocketServer():
@@ -77,38 +82,38 @@ class SocketConnect(GObject.GObject):
def _connectToSocketServer(self):
try:
self._sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
postfix = "/"+appname+"/socket"
sock_file = get_runtime_dir()+postfix
postfix = "/" + appname + "/socket" # Should use os.path.join instead
sock_file = get_runtime_dir() + postfix
print ("Socket: " + sock_file + " <=> " + postfix)
if sock_file != postfix:
try:
print("Socket File: "+sock_file)
print("Socket File: " + sock_file)
self._sock.connect(sock_file)
self.connected = True
print("Setting connected to %r" % self.connected )
print("Setting connected to %r." % self.connected )
self._watch_id = GObject.io_add_watch(self._sock, GObject.IO_IN, self._handle_notify)
print("Socket watch id: "+str(self._watch_id))
return False # don't run again
print("Socket watch id: " + str(self._watch_id))
return False # Don't run again
except Exception as e:
print("Could not connect to unix socket." + str(e))
print("Could not connect to unix socket. " + str(e))
else:
print("Sock-File not valid: "+sock_file)
except Exception as e:
print("Connect could not be established, try again later ")
print("Sock-File not valid: " + sock_file)
except Exception as e: # Bad habbit
print("Connect could not be established, try again later.")
self._sock.close()
return True # run again, if enabled via timeout_add()
return True # Run again, if enabled via timeout_add()
# notify is the raw answer from the socket
# 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
# Prepend the remaining data from last call
if len(self._remainder) > 0:
data = self._remainder+data
data = self._remainder + data
self._remainder = ''
if len(data) > 0:
# remember the remainder for next round
# Remember the remainder for next round
lastNL = data.rfind('\n');
if lastNL > -1 and lastNL < len(data):
self._remainder = data[lastNL+1:]
@@ -119,10 +124,10 @@ class SocketConnect(GObject.GObject):
else:
return False
return True # run again
return True # Run again
def _handle_server_response(self, line):
print("Server response: "+line)
print("Server response: " + line)
parts = line.split(':')
action = parts[0]
args = parts[1:]
@@ -151,32 +156,33 @@ class MenuExtension(GObject.GObject, Nautilus.MenuProvider):
def get_file_items(self, window, files):
if len(files) != 1:
return
file=files[0]
items=[]
file = files[0]
items = []
# internal or external file?!
# Internal or external file?!
syncedFile = False
for reg_path in socketConnect.registered_paths:
topLevelFolder=False
topLevelFolder = False
filename = get_local_path(file.get_uri())
#check if its a folder (ends with an /), if yes add a "/" otherwise it will not find the entry in the table
if os.path.isdir(filename+"/"):
filename=filename+"/"
#check if toplevel folder, we need to ignore those as they cannot be shared
# Check if its a folder (ends with an /), if yes add a "/"
# otherwise it will not find the entry in the table
if os.path.isdir(filename + "/"):
filename += "/"
# Check if toplevel folder, we need to ignore those as they cannot be shared
if filename.count("/") < (reg_path.count("/")+2):
topLevelFolder=True
# only show the menu extension if the file is synced and the sync
# Only show the menu extension if the file is synced and the sync
# status is ok. Not for ignored files etc.
# ignore top level folders
if filename.startswith(reg_path) and topLevelFolder == False and socketConnect.nautilusVFSFile_table[filename]['state'] == 'OK':
syncedFile = True
# if it is neither in a synced folder or is a directory
if (not syncedFile):
# If it is neither in a synced folder or is a directory
if not syncedFile:
return items
# create an menu item
labelStr = "Share with "+appname+"..."
# Create an menu item
labelStr = "Share with " + appname + "..."
item = Nautilus.MenuItem(name='NautilusPython::ShareItem', label=labelStr,
tip='Share file %s through ownCloud' % file.get_name())
item.connect("activate", self.menu_share, file)
@@ -187,8 +193,8 @@ class MenuExtension(GObject.GObject, Nautilus.MenuProvider):
def menu_share(self, menu, file):
filename = get_local_path(file.get_uri())
print("Share file "+filename)
socketConnect.sendCommand("SHARE:"+filename+"\n")
print("Share file " + filename)
socketConnect.sendCommand("SHARE:" + filename + "\n")
class SyncStateExtension(GObject.GObject, Nautilus.ColumnProvider, Nautilus.InfoProvider):
@@ -205,7 +211,7 @@ class SyncStateExtension(GObject.GObject, Nautilus.ColumnProvider, Nautilus.Info
return None
def askForOverlay(self, file):
# print("Asking for overlay for "+file)
# print("Asking for overlay for "+file) # For debug only
if os.path.isdir(file):
folderStatus = socketConnect.sendCommand("RETRIEVE_FOLDER_STATUS:"+file+"\n");
@@ -240,8 +246,8 @@ class SyncStateExtension(GObject.GObject, Nautilus.ColumnProvider, Nautilus.Info
'NOP' : appname +'_error'
}
# file = args[0]
# print "Action for " + file + ": "+args[0]
# file = args[0] # For debug only
# print("Action for " + file + ": " + args[0]) # For debug only
if action == 'STATUS':
newState = args[0]
emblem = Emblems[newState]
@@ -253,7 +259,7 @@ class SyncStateExtension(GObject.GObject, Nautilus.ColumnProvider, Nautilus.Info
if( not itemStore['state'] or newState != itemStore['state'] ):
item = itemStore['item']
item.add_emblem(emblem)
# print "Setting emblem on " + args[1]+ "<>"+emblem+"<>"
# print("Setting emblem on " + args[1] + "<>" + emblem + "<>") # For debug only
socketConnect.nautilusVFSFile_table[args[1]] = {'item': item, 'state':newState}
elif action == 'UPDATE_VIEW':
@@ -278,9 +284,9 @@ class SyncStateExtension(GObject.GObject, Nautilus.ColumnProvider, Nautilus.Info
if filename.startswith(reg_path):
socketConnect.nautilusVFSFile_table[filename] = {'item': item, 'state':''}
# item.add_string_attribute('share_state', "share state")
# item.add_string_attribute('share_state', "share state") # ?
self.askForOverlay(filename)
break
else:
# print("Not in scope:"+filename)
# print("Not in scope:" + filename) # For debug only
pass

Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais