Compare commits

...
210 Commits
Author SHA1 Message Date
Ludovic Marcotte 329552030b Merge to 2.2.8 2014-09-10 14:17:14 -04:00
Ludovic Marcotte 38cb86bdb1 Update ChangeLog 2014-09-10 14:15:34 -04:00
Alexandre Cloutier 69c8aa0743 quickfix for IE for searchInbox 2014-09-10 13:22:36 -04:00
Alexandre Cloutier 60e3c1c822 Merge branch 'master' of https://github.com/inverse-inc/sogo 2014-09-10 13:02:45 -04:00
Alexandre Cloutier 36b833ccb5 bugFix InboxSearch IMAP query keywords 2014-09-10 13:02:13 -04:00
Francis Lachapelle 9d6bcb00bc Fix compilation warning 2014-09-10 11:58:47 -04:00
Francis Lachapelle 1dd3dbacb5 Various fixes and improvements to the Mail module 2014-09-10 11:37:52 -04:00
Francis Lachapelle c441fa5b80 Various fix and improvements to Scheduler module 2014-09-10 10:58:58 -04:00
Francis Lachapelle 7e297ad56c Remove spaces 2014-09-10 10:58:46 -04:00
Francis Lachapelle 8eb4212f5d Various fix and improvements to Mail module 2014-09-10 10:49:54 -04:00
Luc Charland 3ad9327d17 putting test-prevent-invitations back in 2014-09-10 10:25:42 -04:00
Ludovic Marcotte 0483794f45 Updated the documentation for the release 2014-09-10 09:20:47 -04:00
Alexandre Cloutier 3c1d6d7d89 bugfix; UserSettings was not refresh properly after toggling threads 2014-09-09 16:05:12 -04:00
Francis Lachapelle 1dcf631ad6 Update translations 2014-09-09 15:50:39 -04:00
Ludovic Marcotte cbc53b3a52 Updated NEWS file 2014-09-09 15:38:15 -04:00
Alexandre Cloutier 574c245758 bugfix PreventInvitation; fix object parsing on a blank user 2014-09-09 15:36:14 -04:00
Alexandre Cloutier f3ca4ea7fc bugfix foldingThread; Renaming a foldername with a space was not correctly handled 2014-09-09 15:36:14 -04:00
Ludovic Marcotte e542ff5646 Fix for bug #1240 2014-09-09 15:15:56 -04:00
Francis Lachapelle bbe1e09ab9 Merge pull request #52 from alexcloutier/feature/RefreshViewCheck
All modules can now be automatically refreshed
2014-09-09 15:12:21 -04:00
Alexandre Cloutier 9daab5a9a1 update NEWS file 2014-09-09 14:28:05 -04:00
Alexandre Cloutier 1fb3198dbc applied comments 2014-09-09 14:27:05 -04:00
Alexandre Cloutier d62c504763 Changed the configurable variable SOGoMailMessageCheck to a general refresh associated to the current view 2014-09-09 14:27:05 -04:00
extrafu 126a05d391 Merge pull request #54 from alexcloutier/feature/FoldingThreads
Feature/folding threads
2014-09-09 14:06:30 -04:00
extrafu 42ffe14052 Merge pull request #55 from alexcloutier/bugfix/LabelsTagging
Bugfix/labels tagging
2014-09-09 14:06:19 -04:00
Alexandre Cloutier 7db526a5d9 bugfix for new user without userSettings.mail 2014-09-09 13:51:02 -04:00
Alexandre Cloutier 06f81a032c applied comments 2014-09-09 13:51:02 -04:00
Alexandre Cloutier df42c31618 Update NEWS file 2014-09-09 13:51:02 -04:00
Alexandre Cloutier e6002c9b2a applied comments 2014-09-09 13:51:02 -04:00
Alexandre Cloutier 0c88edc61b bugfix where an exception was raised if threadsCollapsed is undefined 2014-09-09 13:51:02 -04:00
Alexandre Cloutier 267a689683 Applied comments 2014-09-09 13:51:02 -04:00
Alexandre Cloutier c9d1294a8a Manage the collapse UIDs save in the user settings 2014-09-09 13:51:02 -04:00
Alexandre Cloutier 59023da7f0 applied comments and fix bug where the folded threads were saved only after refreshing the entire page 2014-09-09 13:51:02 -04:00
Alexandre Cloutier c5f9dd086b Possibility to collapsed threads with persistance 2014-09-09 13:51:02 -04:00
Alexandre Cloutier 0bfaceb398 applied comments 2014-09-09 12:51:59 -04:00
Alexandre Cloutier 9a380f711c bugfix PreventInvitation 2014-09-09 11:30:00 -04:00
Ludovic Marcotte 8c8e7d24a7 Modified Apache's config file to handle Apache > 2.3 2014-09-08 15:25:21 -04:00
Alexandre Cloutier 77c50e5232 applied comments; fix errors from merge and update NEWS file 2014-09-08 14:11:42 -04:00
Francis Lachapelle 56ef00661c Merge pull request #50 from alexcloutier/feature/SearchInbox
New feature to search multiple mailboxes
2014-09-05 16:09:59 -04:00
Francis Lachapelle b639c2d251 Fixes for IE 2014-09-05 16:04:29 -04:00
Alexandre Cloutier 984e208dd9 IE bugfixes 2014-09-05 11:01:57 -04:00
Luc Charland 606ee9780e dont test prevent invitations 2014-09-04 22:36:02 -04:00
Luc Charland c6f82dac01 catch specific exception 2014-09-04 22:24:32 -04:00
Luc Charland e37a603632 should help some builds that might timeout 2014-09-04 21:59:36 -04:00
Alexandre Cloutier ca8351d1f9 fix IE7, IE8, IE9, IE10, IE11 GUI 2014-09-04 10:50:03 -04:00
Luc Charland 031e4c9409 more of the same 2014-09-03 22:43:49 -04:00
Luc Charland c621bbcd56 Those need the same adjustments 2014-09-03 22:32:46 -04:00
Luc Charland 4b94a183be urllib.quote needs a string 2014-09-03 13:50:13 -04:00
Alexandre Cloutier 32476b16cc applied comments and fix bug when tagging msgs already tagged 2014-09-02 14:31:46 -04:00
Alexandre Cloutier 3b65eaea0b Tagging labels with 1 AJAX request 2014-09-02 13:42:04 -04:00
Alexandre Cloutier 7e26d80c77 merge conflicts 2014-09-02 10:11:27 -04:00
Francis Lachapelle 1af52e6d6b Fix message labels handling
Selecting "none" from the label submenu on a multiple selection of
messages is now working. When changing the label of multiple messages,
the display is now properly updated.

Fixes #2902
2014-08-29 15:39:06 -04:00
Alexandre Cloutier eaf815eae6 update NEWS file 2014-08-29 14:55:21 -04:00
Alexandre Cloutier 9bd09cc55d add the location column 2014-08-28 13:20:43 -04:00
Luc Charland ced0962894 Added white_listed_attendee to the config file 2014-08-28 10:43:32 -04:00
Francis Lachapelle dadad3df2a Fix some compilation warnings 2014-08-28 09:38:09 -04:00
Alexandre Cloutier da184f8459 bugfix#2864 2014-08-27 16:50:45 -04:00
Alexandre Cloutier 03152ea3d4 bugfix with DND from calendar view to calendar list 2014-08-27 16:01:35 -04:00
Alexandre Cloutier 8fbd2384a4 Merge branch 'master' of https://github.com/inverse-inc/sogo 2014-08-27 13:55:02 -04:00
Alexandre Cloutier 84a08659ec bugfix where it is not possible to delete msg when mailbox is full 2014-08-27 13:50:56 -04:00
Luc Charland d749d5c2fb Added tests for prevent invitation and whitelist 2014-08-27 13:31:49 -04:00
Alexandre Cloutier 07a138e0d6 applied comments and add the possibility to resize the search inbox window 2014-08-27 12:30:33 -04:00
Alexandre Cloutier 76c9b45fd0 update Localizable.strings
Update the print window options strings
2014-08-26 14:25:27 -04:00
Alexandre Cloutier 1ab3a588f3 Merge branch 'master' of https://github.com/inverse-inc/sogo 2014-08-26 13:41:58 -04:00
Alexandre Cloutier 38a3b7bb4f print calendars events&Tasks with colors - either borders or backgrounds 2014-08-26 13:36:42 -04:00
Francis Lachapelle b2b77c65d3 Fix folders paths of "sogo-tool restore -l" 2014-08-26 09:00:13 -04:00
Alexandre Cloutier 6aecccf6ca indentations 2014-08-25 13:46:35 -04:00
Francis Lachapelle e4a84d4920 Fix usage of SOGoSubscriptionFolderFormat default 2014-08-25 12:15:05 -04:00
Francis Lachapelle 28f26ec08e Fix display of users with no possible subscription 2014-08-25 10:16:10 -04:00
Francis Lachapelle 74bd96e5a6 Fix encoding of new calendars + new subscriptions 2014-08-25 10:12:09 -04:00
Alexandre Cloutier e044476772 bugFix #2827 2014-08-15 13:41:30 -04:00
Alexandre Cloutier c76cb36461 Disable the search button on toolbar once it is opened 2014-08-15 13:06:46 -04:00
Alexandre Cloutier 73fcdc2306 adjust css for other browser, fix display bug 2014-08-15 11:41:37 -04:00
Ludovic Marcotte b9dd1ddc5a Fix for bug #2892 2014-08-15 09:57:19 -04:00
Alexandre Cloutier 8783f09a4a fix leak 2014-08-14 15:01:40 -04:00
Alexandre Cloutier 52476251b8 applied comments, fix bug and add sortable results 2014-08-14 14:49:44 -04:00
Alexandre Cloutier f6c7ca3379 applied comments 2014-08-13 17:41:58 -04:00
Alexandre Cloutier c3e46e4baf code refactoring and GUI improvement 2014-08-11 09:25:09 -04:00
Alexandre Cloutier 7794d716b9 version 1 of the inbox search 2014-08-06 14:49:36 -04:00
Francis Lachapelle 5b886e5c4d Fix issue with DnD of tasks with FireFox 2014-08-01 12:26:53 -04:00
Ludovic Marcotte cde1db9324 Refactored GCSFolder: -writeContent and fixed sogo-tool restore 2014-08-01 09:40:45 -04:00
Ludovic Marcotte f43341c100 Fixed JSON'ification of the admin module 2014-07-31 16:19:49 -04:00
Ludovic Marcotte b05fcc7d82 Fat commit to refactor the quick record generation 2014-07-30 14:51:00 -04:00
Francis Lachapelle 07324e56a0 Update ChangeLog 2014-07-30 11:16:35 -04:00
Francis Lachapelle 397a36cc89 Preparation for release 2.2.7 2014-07-30 11:16:10 -04:00
Francis Lachapelle c240931c54 Update CKEditor to version 4.4.3 2014-07-30 11:15:05 -04:00
Francis Lachapelle ef2432e10f Update NEWS file 2014-07-30 10:36:31 -04:00
Francis Lachapelle 571322958a Update fi, fr, de, and es_ES translations 2014-07-30 10:33:15 -04:00
Francis Lachapelle bd5c05cca2 Indentation in JavaScript files 2014-07-30 10:31:25 -04:00
Francis Lachapelle ea44308aa3 Fix all-day events display in IE
It also fixes the display of the event categories for all-day events in
IE.
2014-07-29 16:05:46 -04:00
Ludovic Marcotte 94f3246658 Improved error message when you cannot invite users 2014-07-29 10:36:20 -04:00
Ludovic Marcotte 1df7e989e0 Removed worthless declaration 2014-07-25 14:48:25 -04:00
Francis Lachapelle d9ca1051b3 Improve headers of multicolumns view 2014-07-25 11:34:33 -04:00
Ludovic Marcotte 4eefa4c269 Fixed test since we now return a 200 instead of a 204 2014-07-25 08:12:12 -04:00
Ludovic Marcotte 4c21a050d9 JSON interface to folder subscriptions 2014-07-24 14:00:57 -04:00
Alexandre Cloutier b52289904f task.png for DnD taskList 2014-07-24 13:48:41 -04:00
Alexandre Cloutier d5b71526ed Merge branch 'master' of https://github.com/inverse-inc/sogo 2014-07-24 13:44:02 -04:00
Alexandre Cloutier c389630d76 DnD tasksList 2014-07-24 13:35:14 -04:00
Ludovic Marcotte f6ef94a631 improved handling of SOGoSubscriptionFolderFormat 2014-07-24 12:48:03 -04:00
Francis Lachapelle 5de51e8aa1 Fix missing argument with new DnD controller 2014-07-24 09:30:19 -04:00
Ludovic Marcotte 006727a74b Properly destroy cache objects of vanished folders 2014-07-24 08:39:41 -04:00
extrafu 037dd67635 Merge pull request #47 from dekkers/mailpartviewers-requires
Add Mailer and Appointments to product.list requires of MailPartViewers
2014-07-22 14:00:35 -04:00
Jeroen Dekkers 6619840f80 Add Mailer and Appointments to product.list requires of MailPartViewers 2014-07-22 19:54:18 +02:00
Francis Lachapelle 08fd2fcfaa Fix JavaScript after bad merge 2014-07-22 13:26:28 -04:00
Alexandre Cloutier a43dd97fc9 Fix bug with DnD; leftPanelController.stopEvent() 2014-07-22 11:37:45 -04:00
Francis Lachapelle 192659fdd9 Add missing localizable string 2014-07-21 16:12:27 -04:00
Francis Lachapelle 06fe36fd75 Add missing localizable strings 2014-07-21 16:07:13 -04:00
Francis Lachapelle 24f9d83ff7 Fix JavaScript from merge leftover 2014-07-21 16:06:24 -04:00
Ludovic Marcotte 8dd967d0a8 Updated NEWS file for two merged pull requests 2014-07-21 15:38:23 -04:00
Ludovic Marcotte 08cd080d47 Fixed charset substitution in meta tags 2014-07-21 15:34:56 -04:00
Francis Lachapelle 11920f592c Merge pull request #46 from alexcloutier/feature/DragNDropCalendars
Improve drag'n'drop of events in multi-column view
2014-07-21 11:00:27 -04:00
Alexandre Cloutier 28e6bb8b9d Applied comments 2014-07-21 09:52:09 -04:00
Alexandre Cloutier b892b3f794 Add RegEx 2014-07-21 09:52:09 -04:00
Alexandre Cloutier cdf4cc1acb fix DnD from eventList to calendarList for repeated event 2014-07-21 09:52:08 -04:00
Alexandre Cloutier 3cac794de5 move line 2014-07-21 09:52:08 -04:00
Alexandre Cloutier 8f9b24a23f visual helper while dragging from calendar view to calendarList 2014-07-21 09:52:08 -04:00
Alexandre Cloutier a2a7014140 fix dnd repeated event bug + applied comments 2014-07-21 09:52:08 -04:00
Alexandre Cloutier a5ecb2063f added event7.png and adjust javascript indentation 2014-07-21 09:52:08 -04:00
Alexandre Cloutier 9bd7aeebfb DnD from calendarView to CalendarList 2014-07-21 09:40:04 -04:00
Alexandre Cloutier 01af72cfe9 DnD from eventList to the calendarList 2014-07-21 09:40:04 -04:00
Alexandre Cloutier 6dddb5c98c dragNdrop from the events table to the calendars list 2014-07-21 09:40:04 -04:00
Alexandre Cloutier ccf181bcf9 applied comments and fix repeated events dragNdrop between calendars 2014-07-21 09:40:04 -04:00
Alexandre Cloutier e478b29c2e creating and dragNDrop between calendars in multicolumndayview 2014-07-21 09:40:04 -04:00
Francis Lachapelle f3ded6ce2a Merge pull request #45 from alexcloutier/feature/PreventInvitations
New user preference to prevent invitations
2014-07-21 09:38:42 -04:00
Alexandre Cloutier c2027f072d indentation 2014-07-21 09:29:00 -04:00
Alexandre Cloutier ce6a31dd38 Adjust line of code to make it easier to read 2014-07-21 09:27:02 -04:00
Alexandre Cloutier a71013eebf javascript indentation 2014-07-21 09:27:02 -04:00
Alexandre Cloutier eaec5a614d Change exception 403 to 409 and fix indentation in the javascript 2014-07-21 09:27:02 -04:00
Alexandre Cloutier 5217bed5ae Organized the categories and appointments invitations inside a tabContainer 2014-07-21 09:27:02 -04:00
Alexandre Cloutier 17319cc8dd reverted UIxListEditor.wox 2014-07-21 09:27:02 -04:00
Alexandre Cloutier 89d116363c replace ampersands with commas 2014-07-21 09:27:02 -04:00
Alexandre Cloutier 7c3e85f517 applied comments 2014-07-21 09:27:02 -04:00
Alexandre Cloutier 05fb7ae0c8 applied comments 2014-07-21 09:27:02 -04:00
Alexandre Cloutier ef20108e32 fix bug where the user could enter any names in the whitelist 2014-07-21 09:27:02 -04:00
Alexandre Cloutier b5c0363400 applied comment and refactor code 2014-07-21 09:27:02 -04:00
Alexandre Cloutier f0b8eb8dfb server side code to integrate the whitelist 2014-07-21 09:27:02 -04:00
Alexandre Cloutier 16d02455bd Serialization of the whiteList 2014-07-21 09:27:02 -04:00
Alexandre Cloutier 8ded5a8aaf Prevent Invitations and whitelist GUI 2014-07-21 09:27:02 -04:00
Ludovic Marcotte 1cc93c700a Updated NEWS file for changes occurred right after v2.2.6 was released 2014-07-09 14:08:31 -04:00
Francis Lachapelle 44d0cb5c0d Fix refresh of list when forwarding a message
Fixes #2818
2014-07-09 11:19:35 -04:00
Ludovic Marcotte dbdb7d9051 Fix sending of METHOD:REPLY for DAV clients 2014-07-09 10:04:44 -04:00
Francis Lachapelle e343ed240b Fix regression of word breaking
Fixes #2845
2014-07-08 22:01:41 -04:00
Francis Lachapelle 45553be122 Fix rename of calendars, improve tasks count badge 2014-07-08 17:19:55 -04:00
Alexandre Cloutier 1cf4841477 fix display glitch 2014-07-04 11:23:59 -04:00
Alexandre Cloutier 017a85b7f2 fix month events categories display 2014-07-04 10:46:49 -04:00
Alexandre Cloutier 103bb6803a Merge branch 'master' of https://github.com/inverse-inc/sogo 2014-07-04 10:38:24 -04:00
Alexandre Cloutier 8c8e47daf6 fix spacing between events and categorie display 2014-07-04 10:37:35 -04:00
Ludovic Marcotte 8a17246725 Cleaned up code and fixed the translation of the weekdays in the datepicker 2014-07-04 10:18:56 -04:00
Ludovic Marcotte 4843c6b6d7 Renamed Multi-Column to Multicolumn and refactored some code 2014-07-04 08:55:35 -04:00
Ludovic Marcotte 04904d8c61 Merge to 2.2.6 2014-07-02 11:41:46 -04:00
Ludovic Marcotte 6e13f15477 Update ChangeLog 2014-07-02 11:32:18 -04:00
Ludovic Marcotte 5dd2088d42 Updated for the release 2014-07-02 11:32:06 -04:00
Ludovic Marcotte 9c3c2cb926 Updated the doc for the release 2014-07-02 11:23:57 -04:00
Ludovic Marcotte 55422b5f03 Fixed typo 2014-07-02 10:11:13 -04:00
Ludovic Marcotte 899a1eb026 Updated NEWS file 2014-07-02 08:39:01 -04:00
Alexandre Cloutier 660f39a980 delete notice and put grey background for multi-columns view 2014-06-30 14:13:52 -04:00
Alexandre Cloutier 8335c38830 fix infinite loop bug 2014-06-30 13:57:10 -04:00
Alexandre Cloutier 0fb7135335 bugfixes 2014-06-30 13:36:12 -04:00
extrafu 70b0cb78cd Merge pull request #44 from alexcloutier/fix/DailyViewByCalendars
Fix/daily view by calendars
2014-06-30 11:01:06 -04:00
Alexandre Cloutier d197ab71b7 merging conflicts 2014-06-30 10:55:55 -04:00
Alexandre Cloutier 6b58e034f3 printView display the parentView by default 2014-06-30 10:42:07 -04:00
Ludovic Marcotte ff015afde8 Fixed indent 2014-06-30 10:35:55 -04:00
Ludovic Marcotte 6da03bc75c Cleaned up code for older gcc 2014-06-28 08:31:07 -04:00
Alexandre Cloutier 2b119c63e0 Applied comments 2014-06-27 17:21:18 -04:00
Alexandre Cloutier 5b61df8ca4 activeTasks updates dynamically 2014-06-27 17:00:32 -04:00
Alexandre Cloutier 659e2f3aa8 Merge branch 'master' of https://github.com/inverse-inc/sogo 2014-06-27 10:30:10 -04:00
extrafu 8191576361 Merge pull request #41 from alexcloutier/fix/displayTaskNumber
Display the number of active tasks in calendar view
2014-06-27 09:07:07 -04:00
Alexandre Cloutier 5b9c7e07d1 text wraping and text alignment in list view 2014-06-26 21:22:12 -04:00
Alexandre Cloutier cafb896e8c Merge branch 'fix/displayTaskNumber' of https://github.com/alexcloutier/SOGo into fix/displayTaskNumber 2014-06-26 16:43:10 -04:00
Alexandre Cloutier 7a69bc46eb applied comments 2014-06-26 16:42:05 -04:00
Alexandre Cloutier 302e40a1c3 bugFix#2823 2014-06-26 16:08:47 -04:00
Ludovic Marcotte b6be4e6e2f Applied patch from bug #2810 2014-06-26 11:01:16 -04:00
Alexandre Cloutier dabd8d3282 Fix list view printing with multiColumns view 2014-06-26 10:05:48 -04:00
Alexandre Cloutier d7d458a934 multiColumns print view + bugFixes 2014-06-25 17:39:48 -04:00
Ludovic Marcotte 5419f411e5 Fix for bug #2734 2014-06-25 15:05:25 -04:00
Ludovic Marcotte 22f5ed62fe Fixed tests regarding default permissions on CalDAV collections 2014-06-25 10:14:28 -04:00
Ludovic Marcotte 3523dc489f Fix for bug #2825 2014-06-23 12:19:02 -04:00
Alexandre Cloutier 5b3de04fc1 Fix error from the last commit 2014-06-20 13:27:04 -04:00
Alexandre Cloutier eb3cc8916d The multiColumns view 2014-06-20 13:16:55 -04:00
Ludovic Marcotte 9fa0b42e19 Ignore SCHEDULE-AGENT for Thunderbird/Lightning 2014-06-20 11:25:02 -04:00
Ludovic Marcotte e048346cb7 Include, in our private NS, all ACLs defined on a calendar collectiob 2014-06-19 16:08:15 -04:00
Ludovic Marcotte 333b561a59 Applied patch from bug #2736 2014-06-16 15:30:26 -04:00
Ludovic Marcotte 50c0b49a6f Fix for bug #2813 2014-06-16 11:00:39 -04:00
Francis Lachapelle 8202d0588f Add documentation for SOGoSubscriptionFolderFormat
Fixes #2799
2014-06-16 10:20:34 -04:00
Francis Lachapelle d9b578b869 Wait 20 seconds before deleting temporary forms
Those temporary forms are created to download attachments.
Fixes #2811
2014-06-16 09:52:29 -04:00
Francis Lachapelle 5bb64916c6 Fix regression when attaching files to a reply 2014-06-12 09:09:08 -04:00
Ludovic Marcotte e7ddfb0546 Fix for bug #2805 2014-06-11 12:55:51 -04:00
Alexandre Cloutier 0e182f8436 Update SOGoAppointmentFolder.m
Fix the status filtering from 2 to 1
2014-06-11 11:25:17 -04:00
Alexandre Cloutier de2ee2322a Change the NSString with NSNumber and add some JavaScript 2014-06-11 10:24:04 -04:00
Ludovic Marcotte ce07695a55 Make sure to keep the / path prefix 2014-06-10 16:35:36 -04:00
Alexandre Cloutier 43ac57b671 display the number of active tasks in calendar view 2014-06-10 16:18:12 -04:00
Francis Lachapelle 7f7e3cb06a Fix folder name of new subscriptions
Fixes #2801
2014-06-10 14:48:25 -04:00
Francis Lachapelle 6b3a3f858b Update prototype.js to version 1.7.2 2014-06-10 14:32:35 -04:00
Ludovic Marcotte 0133bb3b6b Correctly update the cache on folder update/delete ops. 2014-06-10 13:07:14 -04:00
Ludovic Marcotte 91e3e19e40 Added the Ping ActiveSync command 2014-06-10 11:04:27 -04:00
Ludovic Marcotte 19a95a1818 Applied fix from #2809 2014-06-10 08:58:44 -04:00
Ludovic Marcotte 1292c191ec Make sure we don't have '-' in table names. 2014-06-10 08:46:35 -04:00
Ludovic Marcotte 77dad178d1 Make sure we don't have '-' in table names. 2014-06-10 08:45:35 -04:00
Ludovic Marcotte f48839bf55 Added (slightly modified) patch from #2806 2014-06-09 09:34:00 -04:00
Ludovic Marcotte 0f04be2bcb Added patch from #2808 2014-06-09 09:25:06 -04:00
Ludovic Marcotte 3f8bbe8c60 Applied patch from #2807 2014-06-09 09:14:30 -04:00
Francis Lachapelle f0b4a05c70 Merge to 2.2.5 2014-06-05 13:35:45 -04:00
Francis Lachapelle 6b6ec8a2ae Update ChangeLog 2014-06-05 13:35:17 -04:00
Francis Lachapelle ad30df26af Preparation for release 2.2.5 2014-06-05 13:34:40 -04:00
Francis Lachapelle 6e56f46f86 Update Dutch, Finnish, German, Polish translations 2014-06-05 13:29:10 -04:00
Francis Lachapelle fe38518a36 Minor syntax and comments improvements 2014-06-05 12:14:34 -04:00
Francis Lachapelle e118a72eab Add meta tag to tell IE to use the highest mode 2014-06-05 10:32:13 -04:00
Ludovic Marcotte 72bec939d6 Fixed text/plain reencoding issues for Outlook 2014-06-04 15:56:22 -04:00
Ludovic Marcotte ba258ca806 Fixed repetitive events issues 2014-06-04 15:23:41 -04:00
Ludovic Marcotte 0c2e2f28f7 Don't try to add attachments during reply operations 2014-05-30 13:53:20 -04:00
Ludovic Marcotte f0dfe37a55 Avoid crashing when forwarding mails with no Subject header 2014-05-30 08:41:42 -04:00
311 changed files with 12901 additions and 7125 deletions

No files matched your search

+12 -3
View File
@@ -40,6 +40,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#import <Contacts/NGVCard+SOGo.h>
#import <SOGo/NSString+Utilities.h>
#include "NSDate+ActiveSync.h"
#include "NSString+ActiveSync.h"
@@ -199,6 +201,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[s appendFormat: @"<Data>%@</Data>", o];
[s appendString: @"</Body>"];
}
if ((o = [self photo]))
[s appendFormat: @"<Picture xmlns=\"Contacts:\">%@</Picture>", o];
return s;
}
@@ -285,13 +290,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if ((o = [theValues objectForKey: @"Email1Address"]))
{
element = [self elementWithTag: @"email" ofType: @"work"];
[element setSingleValue: o forKey: @""];
[element setSingleValue: [o pureEMailAddress] forKey: @""];
}
if ((o = [theValues objectForKey: @"Email2Address"]))
{
element = [self elementWithTag: @"email" ofType: @"home"];
[element setSingleValue: o forKey: @""];
[element setSingleValue: [o pureEMailAddress] forKey: @""];
}
// SOGo currently only supports 2 email addresses ... but AS clients might send 3
@@ -299,7 +304,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if ((o = [theValues objectForKey: @"Email3Address"]))
{
element = [self elementWithTag: @"email" ofType: @"three"];
[element setSingleValue: o forKey: @""];
[element setSingleValue: [o pureEMailAddress] forKey: @""];
}
// Formatted name
@@ -346,6 +351,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if ((o = [theValues objectForKey: @"NickName"]))
[self setNickname: o];
if ((o = [theValues objectForKey: @"Picture"]))
[self setPhoto: o];
}
@end
+1
View File
@@ -47,6 +47,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- (NSCalendarDate *) calendarDate;
- (NSString *) deviceId;
- (NSString *) deviceType;
- (NSString *) attachmentName;
- (NSString *) command;
- (NSData *) convertHexStringToBytes;
+17
View File
@@ -186,6 +186,23 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
return s;
}
// This method extracts the "AttachmentName" from a URI:
//
// /SOGo/Microsoft-Server-ActiveSync?Cmd=GetAttachment&User=sogo&DeviceId=HTCa04b4932597acd3f2dc1a918b9728&DeviceType=htcvision&AttachmentName=mail/TestFldr/8/2
//
- (NSString *) attachmentName
{
NSString *s;
s = [self _valueForParameter: @"ATTACHMENTNAME="];
if (!s)
s = @"Unknown";
return s;
}
//
//
//
+71 -8
View File
@@ -123,8 +123,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[o setTableUrl: [self folderTableURL]];
[o reloadIfNeeded];
[[o properties] removeObjectForKey: @"SyncKey"];
[[o properties] removeObjectForKey: @"SyncCache"];
[[o properties] removeObjectForKey: @"DateCache"];
[[o properties] removeObjectForKey: @"MoreAvailable"];
[[o properties] addEntriesFromDictionary: theFolderMetadata];
[o save];
@@ -476,20 +478,70 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
lastServerKey: (NSString **) theLastServerKey
{
NSMutableDictionary *folderMetadata, *dateCache, *syncCache;
NSMutableString *s;
BOOL more_available;
int i, max;
s = [NSMutableString string];
more_available = NO;
if (theFolderType == ActiveSyncMailFolder && !([theSyncKey isEqualToString: @"-1"]) && theFilterType)
{
NSArray *allKeys;
NSString *key;
int softdelete_count;
softdelete_count = 0;
folderMetadata = [self _folderMetadataForKey: [theCollection nameInContainer]];
dateCache = [folderMetadata objectForKey: @"DateCache"];
syncCache = [folderMetadata objectForKey: @"SyncCache"];
allKeys = [dateCache allKeys];
for (i = 0; i < [allKeys count]; i++)
{
key = [allKeys objectAtIndex: i];
if ([[dateCache objectForKey:key] compare: theFilterType] == NSOrderedAscending)
{
[s appendString: @"<SoftDelete xmlns=\"AirSync:\">"];
[s appendFormat: @"<ServerId xmlns=\"AirSync:\">%@</ServerId>", key];
[s appendString: @"</SoftDelete>"];
[syncCache removeObjectForKey: key];
[dateCache removeObjectForKey: key];
softdelete_count++;
}
if (softdelete_count >= theWindowSize)
{
[folderMetadata setObject: [NSNumber numberWithBool: YES] forKey: @"MoreAvailable"];
[self _setFolderMetadata: folderMetadata forKey: [theCollection nameInContainer]];
more_available = YES;
*theLastServerKey = theSyncKey;
// Since WindowSize is reached don't even try to add more to the response, let's just
// jump to the end and return the response immediately
goto return_response;
}
}
[folderMetadata removeObjectForKey: @"MoreAvailable"];
[self _setFolderMetadata: folderMetadata forKey: [theCollection nameInContainer]];
}
//
// No changes in the collection - 2.2.2.19.1.1 Empty Sync Request.
// We check this and we don't generate any commands if we don't have to.
//
if ([theSyncKey isEqualToString: [theCollection davCollectionTag]])
if ([theSyncKey isEqualToString: [theCollection davCollectionTag]] && !([s length]))
return;
s = [NSMutableString string];
more_available = NO;
switch (theFolderType)
@@ -602,12 +654,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[s appendString: @"</Add>"];
}
} // for ...
folderMetadata = [NSDictionary dictionaryWithObject: [theCollection davCollectionTag]
forKey: @"SyncKey"];
[self _setFolderMetadata: folderMetadata
forKey: [NSString stringWithFormat: @"%@/%@", component_name, [theCollection nameInContainer]]];
}
break;
case ActiveSyncMailFolder:
default:
{
NSMutableDictionary *syncCache, *dateCache, *folderMetadata;
SOGoSyncCacheObject *lastCacheObject, *aCacheObject;
NSMutableArray *allCacheObjects, *sortedBySequence;
@@ -637,6 +693,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[folderMetadata setObject: [NSMutableDictionary dictionary] forKey: @"SyncCache"];
[folderMetadata setObject: [NSMutableDictionary dictionary] forKey: @"DateCache"];
}
// Check whether GUID in cache is equal to the GUID from imap - this is to avoid cache corruptions if a folder has been renamed and a new folder
// with the same name has been created but folderSync has not yet updated the cache
if (!([[theCollection nameInContainer] isEqualToString:
@@ -782,17 +839,24 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
}
if (more_available)
[folderMetadata setObject: [NSNumber numberWithBool: YES] forKey: @"MoreAvailable"];
{
[folderMetadata setObject: [NSNumber numberWithBool: YES] forKey: @"MoreAvailable"];
[folderMetadata setObject: *theLastServerKey forKey: @"SyncKey"];
}
else
[folderMetadata removeObjectForKey: @"MoreAvailable"];
{
[folderMetadata removeObjectForKey: @"MoreAvailable"];
[folderMetadata setObject: [theCollection davCollectionTag] forKey: @"SyncKey"];
}
[self _setFolderMetadata: folderMetadata
forKey: [theCollection nameInContainer]];
} // default:
break;
} // switch (folderType) ...
return_response:
if ([s length])
{
[theBuffer appendString: @"<Commands>"];
@@ -996,7 +1060,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
davCollectionTag = [collection davCollectionTag];
}
// Generate the response buffer
[theBuffer appendString: @"<Collection>"];
+314 -31
View File
@@ -64,6 +64,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#import <NGMime/NGMimeBodyPart.h>
#import <NGMime/NGMimeFileData.h>
#import <NGMime/NGMimeMultipartBody.h>
#import <NGMime/NGMimeType.h>
#import <NGMail/NGMimeMessageParser.h>
#import <NGMail/NGMimeMessage.h>
#import <NGMail/NGMimeMessageGenerator.h>
@@ -122,6 +123,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <unistd.h>
@interface SOGoActiveSyncDispatcher (Sync)
- (NSMutableDictionary *) _folderMetadataForKey: (NSString *) theFolderKey;
@end
@implementation SOGoActiveSyncDispatcher
- (id) init
@@ -164,6 +171,41 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
return [o properties];
}
- (unsigned int) _softDeleteCountWithFilter: (NSCalendarDate *) theFilter
collectionId: (NSString *) theCollectionId
{
NSMutableDictionary *dateCache;
NSMutableArray *sdUids;
SOGoCacheGCSObject *o;
NSArray *allKeys;
NSString *key;
int i;
sdUids = [NSMutableArray array];
if (theFilter)
{
o = [SOGoCacheGCSObject objectWithName: [NSString stringWithFormat: @"%@+folder%@", [context objectForKey: @"DeviceId"], theCollectionId] inContainer: nil];
[o setObjectType: ActiveSyncGlobalCacheObject];
[o setTableUrl: [self folderTableURL]];
[o reloadIfNeeded];
dateCache = [[o properties] objectForKey: @"DateCache"];
allKeys = [dateCache allKeys];
for (i = 0; i < [allKeys count]; i++)
{
key = [allKeys objectAtIndex: i];
if ([[dateCache objectForKey:key] compare: theFilter ] == NSOrderedAscending)
[sdUids addObject: [dateCache objectForKey:key]];
}
}
return [sdUids count];
}
- (id) globallyUniqueIDToIMAPFolderName: (NSString *) theIdToTranslate
type: (SOGoMicrosoftActiveSyncFolderType) theFolderType
{
@@ -409,10 +451,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if (!error)
{
NSString *syncKey, *key;
SOGoCacheGCSObject *o;
NSMutableString *s;
NSString *syncKey;
NSData *d;
//
// We destroy the cache object
//
key = [NSString stringWithFormat: @"%@+%@", [context objectForKey: @"DeviceId"], [folderToDelete nameInContainer]];
o = [SOGoCacheGCSObject objectWithName: key inContainer: nil];
[o setTableUrl: [self folderTableURL]];
[o destroy];
//
// We update the FolderSync's synckey
//
@@ -484,10 +535,22 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Handle new name exist
if (!error)
{
NSString *syncKey, *key;
SOGoCacheGCSObject *o;
NSMutableString *s;
NSString *syncKey;
NSData *d;
//
// We update our cache
//
key = [NSString stringWithFormat: @"%@+folder%@", [context objectForKey: @"DeviceId"], serverId];
o = [SOGoCacheGCSObject objectWithName: key inContainer: nil];
[o setTableUrl: [self folderTableURL]];
[o reloadIfNeeded];
key = [NSString stringWithFormat: @"/%@+%@", [context objectForKey: @"DeviceId"], [folderToUpdate nameInContainer]];
[o changePathTo: key];
//
// We update the FolderSync's synckey
//
@@ -499,8 +562,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[self _setFolderSyncKey: syncKey];
// FIXME - TODO: We *MUST* update the path in our cache! See -changePathTo in SOGoCacheGCSObject
s = [NSMutableString string];
[s appendString: @"<?xml version=\"1.0\" encoding=\"utf-8\"?>"];
[s appendString: @"<!DOCTYPE ActiveSync PUBLIC \"-//MICROSOFT//DTD ActiveSync//EN\" \"http://www.microsoft.com/\">"];
@@ -635,7 +696,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if (![imapGUIDs allKeysForObject: cKey])
{
// Delete folders cache content to avoid stale data if a new folder gets created with the same name
// Destroy folders cache content to avoid stale data if a new folder gets created with the same name
key = [NSString stringWithFormat: @"%@+folder%@", [context objectForKey: @"DeviceId"], [cachedGUIDs objectForKey: cKey]];
o = [SOGoCacheGCSObject objectWithName: key inContainer: nil];
[o setObjectType: ActiveSyncFolderCacheObject];
@@ -649,8 +710,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
command_count++;
}
[[o properties] removeAllObjects];
[o save];
[o destroy];
}
}
@@ -781,7 +841,51 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- (void) processGetAttachment: (id <DOMElement>) theDocumentElement
inResponse: (WOResponse *) theResponse
{
NSString *fileReference, *realCollectionId;
SOGoMicrosoftActiveSyncFolderType folderType;
fileReference = [context objectForKey: @"AttachmentName"];
realCollectionId = [fileReference realCollectionIdWithFolderType: &folderType];
if (folderType == ActiveSyncMailFolder)
{
id currentFolder, currentCollection, currentBodyPart;
NSString *folderName, *messageName, *pathToPart;
SOGoMailAccounts *accountsFolder;
SOGoUserFolder *userFolder;
SOGoMailObject *mailObject;
NSRange r1, r2;
r1 = [realCollectionId rangeOfString: @"/"];
r2 = [realCollectionId rangeOfString: @"/" options: 0 range: NSMakeRange(NSMaxRange(r1)+1, [realCollectionId length]-NSMaxRange(r1)-1)];
folderName = [realCollectionId substringToIndex: r1.location];
messageName = [realCollectionId substringWithRange: NSMakeRange(NSMaxRange(r1), r2.location-r1.location-1)];
pathToPart = [realCollectionId substringFromIndex: r2.location+1];
userFolder = [[context activeUser] homeFolderInContext: context];
accountsFolder = [userFolder lookupName: @"Mail" inContext: context acquire: NO];
currentFolder = [accountsFolder lookupName: @"0" inContext: context acquire: NO];
currentCollection = [currentFolder lookupName: [NSString stringWithFormat: @"folder%@", folderName]
inContext: context
acquire: NO];
mailObject = [currentCollection lookupName: messageName inContext: context acquire: NO];
currentBodyPart = [mailObject lookupImap4BodyPartKey: pathToPart inContext: context];
[theResponse setHeader: [NSString stringWithFormat: @"%@/%@", [[currentBodyPart partInfo] objectForKey: @"type"], [[currentBodyPart partInfo] objectForKey: @"subtype"]]
forKey: @"Content-Type"];
[theResponse setContent: [currentBodyPart fetchBLOB] ];
}
else
{
[theResponse setStatus: 500];
}
}
//
@@ -849,6 +953,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
sortOrdering: @"REVERSE ARRIVAL"
threaded: NO];
count = [uids count];
// Add the number of UIDs expected to "soft delete"
count += [self _softDeleteCountWithFilter: filter collectionId: realCollectionId];
}
else
{
@@ -891,7 +999,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
fileReference = [[[(id)[theDocumentElement getElementsByTagName: @"FileReference"] lastObject] textValue] stringByUnescapingURL];
realCollectionId = [fileReference realCollectionIdWithFolderType: &folderType];
realCollectionId = [self globallyUniqueIDToIMAPFolderName: realCollectionId type: folderType];
if (folderType == ActiveSyncMailFolder)
{
@@ -1218,30 +1325,73 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
}
//
// Ping requests make a little sense because the request
// doesn't contain the SyncKey on the client. So we can't
// really know if something has changed on the server. What we
// do for now is simply return Status=5 with the HeartbeatInterval
// set at 60 seconds or we wait 60 seconds before responding with
// Status=1
// <?xml version="1.0"?>
// <!DOCTYPE ActiveSync PUBLIC "-//MICROSOFT//DTD ActiveSync//EN" "http://www.microsoft.com/">
// <Ping xmlns="Ping:">
// <HeartbeatInterval>3540</HeartbeatInterval>
// <Folders>
// <Folder>
// <Id>mail%2Fsogo_680f_193506d5_0</Id>
// <Class>Email</Class>
// </Folder>
// <Folder>
// <Id>vevent/personal</Id>
// <Class>Calendar</Class>
// </Folder>
// <Folder>
// <Id>vcard/personal</Id>
// <Class>Contacts</Class>
// </Folder>
// <Folder>
// <Id>mail%2Fsogo_680f_193506d5_1</Id>
// <Class>Email</Class>
// </Folder>
// <Folder>
// <Id>mail%2Fsogo_680f_193506d5_2</Id>
// <Class>Email</Class>
// </Folder>
// <Folder>
// <Id>vtodo/personal</Id>
// <Class>Tasks</Class>
// </Folder>
// <Folder>
// <Id>mail%2Fsogo_753e_193511a1_0</Id>
// <Class>Email</Class>
// </Folder>
// <Folder>
// <Id>mail%2Fsogo_753e_193511a1_1</Id>
// <Class>Email</Class>
// </Folder>
// </Folders>
// </Ping>
//
- (void) processPing: (id <DOMElement>) theDocumentElement
inResponse: (WOResponse *) theResponse
{
NSString *collectionId, *realCollectionId, *syncKey;
NSMutableArray *foldersWithChanges, *allFoldersID;
SOGoMicrosoftActiveSyncFolderType folderType;
NSMutableDictionary *folderMetadata;
SOGoSystemDefaults *defaults;
id <DOMElement> aCollection;
NSArray *allCollections;
NSMutableString *s;
id collection;
NSData *d;
int heartbeatInterval, defaultInterval, status;
int i, j, heartbeatInterval, defaultInterval, internalInterval, status;
defaults = [SOGoSystemDefaults sharedSystemDefaults];
defaultInterval = [defaults maximumPingInterval];
internalInterval = [defaults internalSyncInterval];
if (theDocumentElement)
heartbeatInterval = [[[(id)[theDocumentElement getElementsByTagName: @"HeartbeatInterval"] lastObject] textValue] intValue];
else
heartbeatInterval = defaultInterval;
if (heartbeatInterval > defaultInterval || heartbeatInterval == 0)
{
heartbeatInterval = defaultInterval;
@@ -1252,15 +1402,116 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
status = 1;
}
NSLog(@"Got Ping request with valid interval - sleeping for %d seconds.", heartbeatInterval);
sleep(heartbeatInterval);
// We build the list of folders to "ping". When the payload is empty, we use the list
// of "cached" folders.
allCollections = (id)[theDocumentElement getElementsByTagName: @"Folders"];
allFoldersID = [NSMutableArray array];
if (![allCollections count])
{
SOGoMailAccounts *accountsFolder;
SOGoMailAccount *accountFolder;
SOGoUserFolder *userFolder;
NSArray *allValues;
userFolder = [[context activeUser] homeFolderInContext: context];
accountsFolder = [userFolder lookupName: @"Mail" inContext: context acquire: NO];
accountFolder = [accountsFolder lookupName: @"0" inContext: context acquire: NO];
allValues = [[accountFolder imapFolderGUIDs] allValues];
for (i = 0; i < [allValues count]; i++)
[allFoldersID addObject: [NSString stringWithFormat: @"mail/%@", [allValues objectAtIndex: i]]];
// FIXME: handle multiple GCS collecitons
[allFoldersID addObject: @"vcard/personal"];
[allFoldersID addObject: @"vevent/personal"];
[allFoldersID addObject: @"vtodo/personal"];
}
else
{
for (i = 0; i < [allCollections count]; i++)
{
aCollection = [allCollections objectAtIndex: i];
collectionId = [[(id) [aCollection getElementsByTagName: @"Id"] lastObject] textValue];
[allFoldersID addObject: collectionId];
}
}
foldersWithChanges = [NSMutableArray array];
// We enter our loop detection change
for (i = 0; i < (heartbeatInterval/internalInterval); i++)
{
for (j = 0; j < [allFoldersID count]; j++)
{
collectionId = [allFoldersID objectAtIndex: j];
realCollectionId = [collectionId realCollectionIdWithFolderType: &folderType];
realCollectionId = [self globallyUniqueIDToIMAPFolderName: realCollectionId type: folderType];
collection = [self collectionFromId: realCollectionId type: folderType];
switch (folderType)
{
case ActiveSyncContactFolder:
folderMetadata = [self _folderMetadataForKey: [NSString stringWithFormat: @"vcard/%@", [collection nameInContainer]]];
break;
case ActiveSyncEventFolder:
folderMetadata = [self _folderMetadataForKey: [NSString stringWithFormat: @"vevent/%@", [collection nameInContainer]]];
break;
case ActiveSyncTaskFolder:
folderMetadata = [self _folderMetadataForKey: [NSString stringWithFormat: @"vtodo/%@", [collection nameInContainer]]];
break;
default:
folderMetadata = [self _folderMetadataForKey: [collection nameInContainer]];
}
syncKey = [folderMetadata objectForKey: @"SyncKey"];
if (![syncKey isEqualToString: [collection davCollectionTag]])
{
[foldersWithChanges addObject: collectionId];
}
}
if ([foldersWithChanges count])
{
NSLog(@"Change detected, we push the content.");
status = 2;
break;
}
else
{
NSLog(@"Sleeping %d seconds while detecting changes...", internalInterval);
sleep(internalInterval);
}
}
// We generate our response
s = [NSMutableString string];
[s appendString: @"<?xml version=\"1.0\" encoding=\"utf-8\"?>"];
[s appendString: @"<!DOCTYPE ActiveSync PUBLIC \"-//MICROSOFT//DTD ActiveSync//EN\" \"http://www.microsoft.com/\">"];
[s appendString: @"<Ping xmlns=\"Ping:\">"];
[s appendFormat: @"<Status>%d</Status>", status];
if ([foldersWithChanges count])
{
[s appendString: @"<Folders>"];
for (i = 0; i < [foldersWithChanges count]; i++)
{
// A bit tricky here because we must call stringByEscapingURL on mail folders, but not on GCS ones.
// We do the same thing in -processFolderSync
collectionId = [foldersWithChanges objectAtIndex: i];
if ([collectionId hasPrefix: @"mail/"])
collectionId = [collectionId stringByEscapingURL];
[s appendFormat: @"<Folder>%@</Folder>", collectionId];
}
[s appendString: @"</Folders>"];
}
if (status == 5)
{
@@ -1686,9 +1937,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
value = [theDocumentElement getElementsByTagName: @"ReplaceMime"];
// ReplaceMime isn't specified so we must NOT use the server copy
// ReplaceMime IS specified so we must NOT use the server copy
// but rather take the data as-is from the client.
if (![value count])
if ([value count])
{
[self processSendMail: theDocumentElement
inResponse: theResponse];
@@ -1708,11 +1959,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
NSData *data;
NGMimeMessageGenerator *generator;
NGMimeBodyPart *bodyPart;
NGMimeBodyPart *bodyPart;
NGMutableHashMap *map;
NGMimeFileData *fdata;
NSException *error;
id body;
id body, bodyFromSmartForward;
userFolder = [[context activeUser] homeFolderInContext: context];
accountsFolder = [userFolder lookupName: @"Mail" inContext: context acquire: NO];
@@ -1728,10 +1980,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
parser = [[NGMimeMessageParser alloc] init];
data = [[[[(id)[theDocumentElement getElementsByTagName: @"MIME"] lastObject] textValue] stringByDecodingBase64] dataUsingEncoding: NSUTF8StringEncoding];
messageFromSmartForward = [parser parsePartFromData: data];
RELEASE(parser);
// We create a new MIME multipart/mixed message. The first part will be the text part
// of our "smart forward" and the second part will be the message/rfc822 part of the
// "smart forwarded" message.
@@ -1741,11 +1991,39 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
messageToSend = [[[NGMimeMessage alloc] initWithHeader: map] autorelease];
body = [[[NGMimeMultipartBody alloc] initWithPart: messageToSend] autorelease];
// First part
// First part - either a text/* or a multipart/*. If it's a multipart,
// we take the first part text/* part we see.
map = [[[NGMutableHashMap alloc] initWithCapacity: 1] autorelease];
[map setObject: @"text/plain" forKey: @"content-type"];
bodyFromSmartForward = nil;
if ([[messageFromSmartForward body] isKindOfClass: [NGMimeMultipartBody class]])
{
NGMimeBodyPart *part;
NSArray *parts;
int i;
parts = [[messageFromSmartForward body] parts];
for (i = 0; i < [parts count]; i++)
{
part = [parts objectAtIndex: i];
if ([[[part contentType] type] isEqualToString: @"text"])
{
[map setObject: [[part contentType] stringValue] forKey: @"content-type"];
bodyFromSmartForward = [part body];
break;
}
}
}
else
{
[map setObject: [[messageFromSmartForward contentType] stringValue] forKey: @"content-type"];
bodyFromSmartForward = [messageFromSmartForward body];
}
bodyPart = [[[NGMimeBodyPart alloc] initWithHeader:map] autorelease];
[bodyPart setBody: [messageFromSmartForward body]];
[bodyPart setBody: bodyFromSmartForward];
[body addBodyPart: bodyPart];
// Second part
@@ -1826,6 +2104,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
deviceId = [[theRequest uri] deviceId];
[context setObject: deviceId forKey: @"DeviceId"];
[context setObject: [[theRequest uri] deviceType] forKey: @"DeviceType"];
[context setObject: [[theRequest uri] attachmentName] forKey: @"AttachmentName"];
cmdName = [[theRequest uri] command];
@@ -1869,7 +2149,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{
// We check if it's a Ping command with no body.
// See http://msdn.microsoft.com/en-us/library/ee200913(v=exchg.80).aspx for details
if ([cmdName caseInsensitiveCompare: @"Ping"] != NSOrderedSame)
if ([cmdName caseInsensitiveCompare: @"Ping"] != NSOrderedSame && [cmdName caseInsensitiveCompare: @"GetAttachment"] != NSOrderedSame)
return [NSException exceptionWithHTTPStatus: 500];
}
@@ -1923,9 +2203,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if ([parts count] == 5)
{
/* If "OCSFolderInfoURL" is properly configured, we must have 5
parts in this url. */
parts in this url. We strip the '-' character in case we have
this in the domain part - like foo@bar-zot.com */
ocFSTableName = [NSString stringWithFormat: @"sogo_cache_folder_%@",
[[user loginInDomain] asCSSIdentifier]];
[[[user loginInDomain] asCSSIdentifier]
stringByReplacingOccurrencesOfString: @"-"
withString: @"_"]];
[parts replaceObjectAtIndex: 4 withObject: ocFSTableName];
folderTableURL
= [NSURL URLWithString: [parts componentsJoinedByString: @"/"]];
+55 -18
View File
@@ -238,6 +238,8 @@ struct GlobalObjectId {
if (key)
{
NSString *s, *charset;
d = [[self fetchPlainTextParts] objectForKey: key];
encoding = [[self lookupInfoForBodyPart: key] objectForKey: @"encoding"];
@@ -246,6 +248,14 @@ struct GlobalObjectId {
d = [d dataByDecodingBase64];
else if ([encoding caseInsensitiveCompare: @"quoted-printable"] == NSOrderedSame)
d = [d dataByDecodingQuotedPrintableTransferEncoding];
charset = [[[self lookupInfoForBodyPart: key] objectForKey: @"parameterList"] objectForKey: @"charset"];
if (![charset length])
charset = @"us-ascii";
s = [NSString stringWithData: d usingEncodingNamed: charset];
d = [s dataUsingEncoding: NSUTF8StringEncoding];
}
return d;
@@ -285,20 +295,31 @@ struct GlobalObjectId {
[self _sanitizedMIMEPart: body
performed: b];
}
else if ([body isKindOfClass: [NSData class]] &&
else if (([body isKindOfClass: [NSData class]] || [body isKindOfClass: [NSString class]]) &&
[[[thePart contentType] type] isEqualToString: @"text"] &&
([[[thePart contentType] subType] isEqualToString: @"plain"] || [[[thePart contentType] subType] isEqualToString: @"html"]))
{
// We make sure everything is encoded in UTF-8
NSString *charset, *s;
NGMimeType *mimeType;
int encoding;
NSString *s;
charset = [[thePart contentType] valueOfParameter: @"charset"];
encoding = [NGMimeType stringEncodingForCharset: charset];
if ([body isKindOfClass: [NSData class]])
{
NSString *charset;
charset = [[thePart contentType] valueOfParameter: @"charset"];
s = [[NSString alloc] initWithData: body encoding: encoding];
AUTORELEASE(s);
if (![charset length])
charset = @"us-ascii";
s = [NSString stringWithData: body usingEncodingNamed: charset];
}
else
{
// Handle situations when SOPE stupidly returns us a NSString
// This can happen for Content-Type: text/plain, Content-Transfer-Encoding: 8bit
s = body;
}
if (s)
{
@@ -385,6 +406,13 @@ struct GlobalObjectId {
{
if ([type isEqualToString: @"text"])
{
NSString *s, *charset;
charset = [[[self lookupInfoForBodyPart: @""] objectForKey: @"parameterList"] objectForKey: @"charset"];
if (![charset length])
charset = @"us-ascii";
d = [[self fetchPlainTextParts] objectForKey: @""];
// We check if we have base64 encoded parts. If so, we just
@@ -396,17 +424,15 @@ struct GlobalObjectId {
else if ([encoding caseInsensitiveCompare: @"quoted-printable"] == NSOrderedSame)
d = [d dataByDecodingQuotedPrintableTransferEncoding];
s = [NSString stringWithData: d usingEncodingNamed: charset];
// Check if we must convert html->plain
if (theType == 1 && [subtype isEqualToString: @"html"])
{
NSString *s;
s = [[NSString alloc] initWithData: d encoding: NSUTF8StringEncoding];
AUTORELEASE(s);
s = [s htmlToText];
d = [s dataUsingEncoding: NSUTF8StringEncoding];
}
d = [s dataUsingEncoding: NSUTF8StringEncoding];
}
else if ([type isEqualToString: @"multipart"])
{
@@ -750,7 +776,7 @@ struct GlobalObjectId {
// Flags
[s appendString: @"<Flag xmlns=\"Email:\">"];
[s appendFormat: @"<FlagStatus>%d</FlagStatus>", 0];
[s appendFormat: @"<FlagStatus>%d</FlagStatus>", ([self flagged] ? 2 : 0)];
[s appendString: @"</Flag>"];
// FIXME - support these in the future
@@ -788,10 +814,21 @@ struct GlobalObjectId {
if ((o = [theValues objectForKey: @"Flag"]))
{
o = [o objectForKey: @"FlagStatus"];
if ([o intValue])
[self addFlags: @"\\Flagged"];
// We must handle empty flags -> {Flag = ""; } - some ActiveSync clients, like the HTC Desire
// will send an empty Flag message when "unflagging" a mail.
if (([o isKindOfClass: [NSMutableDictionary class]]))
{
if ((o = [o objectForKey: @"FlagStatus"]))
{
// 0 = The flag is cleared.
// 1 = The status is set to complete.
// 2 = The status is set to active.
if (([o isEqualToString: @"2"]))
[self addFlags: @"\\Flagged"];
else
[self removeFlags: @"\\Flagged"];
}
}
else
[self removeFlags: @"\\Flagged"];
}
-1
View File
@@ -18,7 +18,6 @@ ADDITIONAL_INCLUDE_DIRS += \
ADDITIONAL_LIB_DIRS += \
-L../SoObjects/SOGo/SOGo.framework/ \
-L../SoObjects/SOGo/$(GNUSTEP_OBJ_DIR)/ \
-L../OGoContentStore/$(GNUSTEP_OBJ_DIR)/ \
-L../SOPE/NGCards/$(GNUSTEP_OBJ_DIR)/ \
-L/usr/local/lib
+20 -3
View File
@@ -34,6 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#import <Foundation/NSDictionary.h>
#import <Foundation/NSString.h>
#import <NGCards/iCalEvent.h>
#import <NGCards/iCalByDayMask.h>
#import "NSCalendarDate+ActiveSync.h"
@@ -77,10 +78,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
occurrences = [[self byDayMask] weekDayOccurrences];
v = 0;
for (i = 0; i < 7; i++)
if (occurrences)
{
if (occurrences[0][i])
v += (1 << i);
for (i = 0; i < 7; i++)
{
if (occurrences[0][i])
v += (1 << i);
}
}
else
{
// No byDayMask, we take the event's start date to compute the DayOfWeek
// 0 == Sunday, 6 == Saturday
v = (1 << [[[self parent] startDate] dayOfWeek]);
}
[s appendFormat: @"<Recurrence_DayOfWeek xmlns=\"Calendar:\">%d</Recurrence_DayOfWeek>", v];
@@ -125,6 +135,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// FIXME
}
}
else
{
// Simple reccurrence rule of type "Monthly"
type = 2;
[s appendFormat: @"<Recurrence_DayOfMonth xmlns=\"Calendar:\">%d</Recurrence_DayOfMonth>",
[[[self parent] startDate] dayOfMonth]];
}
}
else if ([self frequency] == iCalRecurrenceFrequenceYearly)
{
+7 -2
View File
@@ -28,8 +28,13 @@
ProxyPass /SOGo http://127.0.0.1:20000/SOGo interpolate
ProxyPass / http://127.0.0.1:20000/SOGo/dav/ interpolate
<Location />
Order allow,deny
Allow from all
<IfVersion < 2.4>
Order deny,allow
Allow from all
</IfVersion>
<IfVersion >= 2.4>
Require all granted
</IfVersion>
</Location>
<Proxy http://127.0.0.1:20000>
+8 -2
View File
@@ -5,8 +5,14 @@ Alias /SOGo/WebServerResources/ \
<Directory /usr/lib/GNUstep/SOGo/>
AllowOverride None
Order deny,allow
Allow from all
<IfVersion < 2.4>
Order deny,allow
Allow from all
</IfVersion>
<IfVersion >= 2.4>
Require all granted
</IfVersion>
# Explicitly allow caching of static content to avoid browser specific behavior.
# A resource's URL MUST change in order to have the client load the new version.
+2052
View File
File diff suppressed because it is too large. Load diff
Binary file not shown.
-1
View File
@@ -6,7 +6,6 @@ include $(GNUSTEP_MAKEFILES)/common.make
SUBPROJECTS = \
SOPE/NGCards \
SOPE/GDLContentStore \
OGoContentStore \
SoObjects \
Main \
UI \
-2
View File
@@ -10,14 +10,12 @@ ADDITIONAL_INCLUDE_DIRS += \
ADDITIONAL_LIB_DIRS += \
-L../SoObjects/SOGo/SOGo.framework \
-L../OGoContentStore/$(GNUSTEP_OBJ_DIR)/ \
-L../SOPE/NGCards/$(GNUSTEP_OBJ_DIR)/
SYSTEM_LIB_DIR += -L/usr/local/lib -L/usr/lib
$(SOGOD)_TOOL_LIBS += \
-lSOGo \
-lOGoContentStore \
-lGDLContentStore \
-lGDLAccess \
-lWEExtensions \
+94
View File
@@ -1,3 +1,97 @@
2.2.8 (2014-09-10)
------------------
New features
- new user settings for threads collapsing
- IMAP global search support (#2670)
Enchancements
- major refactoring of the GCS component saving code (dropped OGoContentStore)
- printing calendars in colors is now possible in all views; list, daily, weekly and multicolumns
- new option to print calendars events and tasks with a background color or with a border color
- labels tagging only make one AJAX call for all the selected messages instead of one AJAX call per message
- new option to print calendars events and tasks with a background color or with a border color
- all modules can now be automatically refreshed
- new configurable user defaults variables; SOGoRefreshViewCheck & SOGoRefreshViewIntervals. SOGoMailMessageCheck has
been replaced by SOGoRefreshViewCheck and SOGoMailPollingIntervals has been replaced by SOGoRefreshViewIntervals
- updated Catalan, Czech, Dutch, Finnish, French, Hungarian, Norwegian, and Polish translations
Bug fixes
- fixed crasher when subscribing users to resources (#2892)
- fixed encoding of new calendars and new subscriptions (JavaScript only)
- fixed display of users with no possible subscription
- fixed usage of SOGoSubscriptionFolderFormat domain default when the folder's name hasn't been changed
- fixed "sogo-tool restore -l" that was returning incorrect folder IDs
- fixed Can not delete mail when over quota (#2812)
- fixed Events and tasks cannot be moved to other calendars using drag&drop (#2759)
- fixed In "Multicolumn Day View" mouse position is not honored when creating an event (#2864)
- fixed handling of messages labels (#2902)
- fixed Apache > 2.3 configuration
- fixed freebusy retrieval during timezone changes (#1240)
2.2.7 (2014-07-30)
------------------
New features
- new user preference to prevent event invitations
Enhancements
- improved badges of active tasks count
- refresh draft folder after sending a message
- now possible to DnD events in the calendar list
- improved handling of SOGoSubscriptionFolderFormat
- JSON'ified folder subscription interface
- updated Finnish, French, German, and Spanish (Spain) translations
- updated CKEditor to version 4.4.3
Bug fixes
- fixed weekdays translation in the datepicker
- fixed event categories display
- fixed all-day events display in IE
- fixed rename of calendars
- we now correctly add the "METHOD:REPLY" when sending out ITIP messages from DAV clients
- fixed refresh of message headers when forwarding a message (#2818)
- we now correctly escape all charset= in <meta> tags, not only in the <head>
- we now destroy cache objects of vanished folders
2.2.6 (2014-07-02)
------------------
New features
- add new 'multi-columns' calendar view (#1948)
Enhancements
- contacts photos are now synchronized using ActiveSync (#2807)
- implemented the GetAttachment ActiveSync command (#2808)
- implemented the Ping ActiveSync command
- added "soft deletes" support for ActiveSync (#2734)
- now display the active tasks count next to calendar names (#2760)
Bug fixes
- better handling of empty "Flag" messages over ActiveSync (#2806)
- fixed Chinese charset handling (#2809)
- fixed folder name (calendars and contacts) of new subscriptions (#2801)
- fixed the reply/forward operation over ActiveSync (#2805)
- fixed regression when attaching files to a reply
- wait 20 seconds (instead of 2) before deleting temporary download forms (#2811)
- avoid raising exceptions when the db is down and we try to access the preferences module (#2813)
- we now ignore the SCHEDULE-AGENT property when Thunderbird/Lightning sends it to avoid
not-generating invitation responses for externally received IMIP messages
- improved charset handling over ActiveSync (#2810)
2.2.5 (2014-06-05)
------------------
Enhancements
- new meta tag to tell IE to use the highest mode available
- updated Dutch, Finnish, German, and Polish translations
Bug fixes
- avoid crashing when we forward an email with no Subject header
- we no longer try to include attachments when replying to a mail
- fixed ActiveSync repetitive events issues with "Weekly" and "Monthly" ones
- fixed ActiveSync text/plain parts re-encoding issues for Outlook
2.2.4 (2014-05-29)
------------------
-482
View File
@@ -1,482 +0,0 @@
GNU LIBRARY GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1991 Free Software Foundation, Inc.
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the library GPL. It is
numbered 2 because it goes with version 2 of the ordinary GPL.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Library General Public License, applies to some
specially designated Free Software Foundation software, and to any
other libraries whose authors decide to use it. You can use it for
your libraries, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if
you distribute copies of the library, or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link a program with the library, you must provide
complete object files to the recipients so that they can relink them
with the library, after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
Our method of protecting your rights has two steps: (1) copyright
the library, and (2) offer you this license which gives you legal
permission to copy, distribute and/or modify the library.
Also, for each distributor's protection, we want to make certain
that everyone understands that there is no warranty for this free
library. If the library is modified by someone else and passed on, we
want its recipients to know that what they have is not the original
version, so that any problems introduced by others will not reflect on
the original authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that companies distributing free
software will individually obtain patent licenses, thus in effect
transforming the program into proprietary software. To prevent this,
we have made it clear that any patent must be licensed for everyone's
free use or not licensed at all.
Most GNU software, including some libraries, is covered by the ordinary
GNU General Public License, which was designed for utility programs. This
license, the GNU Library General Public License, applies to certain
designated libraries. This license is quite different from the ordinary
one; be sure to read it in full, and don't assume that anything in it is
the same as in the ordinary license.
The reason we have a separate public license for some libraries is that
they blur the distinction we usually make between modifying or adding to a
program and simply using it. Linking a program with a library, without
changing the library, is in some sense simply using the library, and is
analogous to running a utility program or application program. However, in
a textual and legal sense, the linked executable is a combined work, a
derivative of the original library, and the ordinary General Public License
treats it as such.
Because of this blurred distinction, using the ordinary General
Public License for libraries did not effectively promote software
sharing, because most developers did not use the libraries. We
concluded that weaker conditions might promote sharing better.
However, unrestricted linking of non-free programs would deprive the
users of those programs of all benefit from the free status of the
libraries themselves. This Library General Public License is intended to
permit developers of non-free programs to use free libraries, while
preserving your freedom as a user of such programs to change the free
libraries that are incorporated in them. (We have not seen how to achieve
this as regards changes in header files, but we have achieved it as regards
changes in the actual functions of the Library.) The hope is that this
will lead to faster development of free libraries.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, while the latter only
works together with the library.
Note that it is possible for a library to be covered by the ordinary
General Public License rather than by this special one.
GNU LIBRARY GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library which
contains a notice placed by the copyright holder or other authorized
party saying it may be distributed under the terms of this Library
General Public License (also called "this License"). Each licensee is
addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also compile or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
c) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
d) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the source code distributed need not include anything that is normally
distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Library General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
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; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!
-34
View File
@@ -1,34 +0,0 @@
# GNUstep makefile
include ../config.make
include $(GNUSTEP_MAKEFILES)/common.make
include ./Version
LIBRARY_NAME = libOGoContentStore
TYPEMODELS_DIR = $(SOGO_TYPEMODELS)
libOGoContentStore_HEADER_FILES_DIR = .
libOGoContentStore_HEADER_FILES_INSTALL_DIR = /OGoContentStore
libOGoContentStore_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION)
ADDITIONAL_INCLUDE_DIRS += -I../SOPE
ADDITIONAL_LIB_DIRS += -L../SOPE/GDLContentStore/obj
libOGoContentStore_OBJC_FILES += \
OCSiCalFieldExtractor.m \
OCSContactFieldExtractor.m \
libOGoContentStore_TYPEMODELS += \
appointment.ocs \
contact.ocs \
appointment-oracle.ocs \
contact-oracle.ocs
-include GNUmakefile.preamble
ifneq ($(FHS_INSTALL_ROOT),)
GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include
endif
include $(GNUSTEP_MAKEFILES)/library.make
include $(GNUSTEP_MAKEFILES)/tool.make
-include GNUmakefile.postamble
-32
View File
@@ -1,32 +0,0 @@
# compilation settings
libOGoContentStore_LIBRARIES_DEPEND_UPON += \
-lGDLContentStore \
-lGDLAccess \
-lNGCards \
-lNGExtensions \
-lEOControl \
-lSaxObjC \
$(BASE_LIBS)
ADDITIONAL_INCLUDE_DIRS += -I. -I.. -I../SOPE -I../SoObjects
ADDITIONAL_LIB_DIRS += -L./$(GNUSTEP_OBJ_DIR) -L../SOPE/NGCards/$(GNUSTEP_OBJ_DIR)/ -L../SoObjects/SOGo/SOGo.framework/
SYSTEM_LIB_DIR += -L/usr/local/lib -L/usr/lib
ifeq ($(FOUNDATION_LIB),apple)
libOGoContentStore_PREBIND_ADDR="0xC7700000"
libOGoContentStore_LDFLAGS += -seg1addr $(libOGoContentStore_PREBIND_ADDR)
endif
test_quick_extract_TOOL_LIBS += \
-lEOControl \
-lSaxObjC \
-lDOM \
-lNGExtensions \
-lNGCards \
-lGDLContentStore \
-lGDLAccess \
-lOGoContentStore \
$(BASE_LIBS)
-136
View File
@@ -1,136 +0,0 @@
/*
Copyright (C) 2004-2005 SKYRIX Software AG
This file is part of OpenGroupware.org.
OGo 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, or (at your option) any
later version.
OGo 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 OGo; see the file COPYING. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <NGExtensions/NSNull+misc.h>
#import <NGExtensions/NSObject+Logs.h>
#import <GDLContentStore/GCSFieldExtractor.h>
#import <NGCards/NGVCard.h>
#import <NGCards/NGVList.h>
#import <SOGo/NSArray+Utilities.h>
@interface OCSContactFieldExtractor : GCSFieldExtractor
@end
@implementation OCSContactFieldExtractor
- (NSMutableDictionary *) extractQuickFieldsFromVCard: (NGVCard *) vCard
{
NSMutableDictionary *fields;
NSArray *values;
CardElement *element;
NSString *value;
fields = [NSMutableDictionary dictionaryWithCapacity: 16];
value = [vCard fn];
if (value)
[fields setObject: value forKey: @"c_cn"];
element = [vCard n];
[fields setObject: [element flattenedValueAtIndex: 0 forKey: @""]
forKey: @"c_sn"];
[fields setObject: [element flattenedValueAtIndex: 1 forKey: @""]
forKey: @"c_givenName"];
value = [vCard preferredTel];
if (value)
[fields setObject: value forKey: @"c_telephonenumber"];
value = [vCard preferredEMail];
if (![value isNotNull])
value = @"";
[fields setObject: value forKey: @"c_mail"];
element = [vCard org];
[fields setObject: [element flattenedValueAtIndex: 0 forKey: @""]
forKey: @"c_o"];
[fields setObject: [element flattenedValueAtIndex: 1 forKey: @""]
forKey: @"c_ou"];
element = [vCard preferredAdr];
if (element && ![element isVoid])
[fields setObject: [element flattenedValueAtIndex: 3
forKey: @""]
forKey: @"c_l"];
value = [[vCard uniqueChildWithTag: @"X-AIM"] flattenedValuesForKey: @""];
[fields setObject: value forKey: @"c_screenname"];
values = [[vCard categories] trimmedComponents];
if ([values count] > 0)
[fields setObject: [values componentsJoinedByString: @","]
forKey: @"c_categories"];
else
[fields setObject: [NSNull null] forKey: @"c_categories"];
[fields setObject: @"vcard" forKey: @"c_component"];
return fields;
}
- (NSMutableDictionary *) extractQuickFieldsFromVList: (NGVList *) vList
{
NSMutableDictionary *fields;
NSString *value;
fields = [NSMutableDictionary dictionaryWithCapacity: 1];
value = [vList fn];
if (value)
[fields setObject: value forKey: @"c_cn"];
[fields setObject: @"vlist" forKey: @"c_component"];
return fields;
}
- (NSMutableDictionary *) extractQuickFieldsFromContent: (NSString *) content
{
NSMutableDictionary *fields;
NGVCard *vCard;
NGVList *vList;
NSString *upperContent;
fields = nil;
if ([content length] > 0)
{
upperContent = [content uppercaseString];
if ([upperContent hasPrefix: @"BEGIN:VCARD"])
{
vCard = [NGVCard parseSingleFromSource: content];
if (vCard)
fields = [self extractQuickFieldsFromVCard: vCard];
else
[self errorWithFormat: @"Could not parse VCARD content."];
}
else if ([upperContent hasPrefix: @"BEGIN:VLIST"])
{
vList = [NGVList parseSingleFromSource: content];
if (vList)
fields = [self extractQuickFieldsFromVList: vList];
else
[self errorWithFormat: @"Could not parse VLIST content."];
}
else
[self errorWithFormat: @"Content is unknown."];
}
else
[self errorWithFormat: @"Content is empty."];
return fields;
}
@end /* OCSContactFieldExtractor */
-35
View File
@@ -1,35 +0,0 @@
/*
Copyright (C) 2004-2005 SKYRIX Software AG
This file is part of OpenGroupware.org.
OGo 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, or (at your option) any
later version.
OGo 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 OGo; see the file COPYING. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
#ifndef __OGoContentStore_OCSiCalFieldExtractor_H__
#define __OGoContentStore_OCSiCalFieldExtractor_H__
#include <GDLContentStore/GCSFieldExtractor.h>
@interface OCSiCalFieldExtractor : GCSFieldExtractor
{
}
+ (id)sharedICalFieldExtractor;
@end
#endif /* __OGoContentStore_OCSiCalFieldExtractor_H__ */
-96
View File
@@ -1,96 +0,0 @@
/*
Copyright (C) 2004 SKYRIX Software AG
This file is part of OpenGroupware.org.
OGo 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, or (at your option) any
later version.
OGo 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 SOGo; see the file COPYING. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
#import <Foundation/NSArray.h>
#import <Foundation/NSCalendarDate.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSString.h>
#import <NGExtensions/NSNull+misc.h>
#import <NGExtensions/NSObject+Logs.h>
#import <NGCards/iCalCalendar.h>
#import <SoObjects/Appointments/iCalRepeatableEntityObject+SOGo.h>
#import "OCSiCalFieldExtractor.h"
@implementation OCSiCalFieldExtractor
+ (id) sharedICalFieldExtractor
{
static OCSiCalFieldExtractor *extractor = nil;
if (!extractor)
extractor = [self new];
return extractor;
}
/* operations */
- (CardGroup *) firstElementFromCalendar: (iCalCalendar *) ical
{
NSArray *elements;
CardGroup *element;
unsigned int count;
elements = [ical allObjects];
count = [elements count];
if (count)
element = [elements objectAtIndex: 0];
else
{
[self logWithFormat: @"ERROR: given calendar contains no elements: %@", ical];
element = nil;
}
return element;
}
- (NSMutableDictionary *) extractQuickFieldsFromContent: (NSString *) _content
{
NSMutableDictionary *fields;
id cal;
fields = nil;
if ([_content length])
{
cal = [iCalCalendar parseSingleFromSource: _content];
if (cal)
{
if ([cal isKindOfClass: [iCalCalendar class]])
cal = [self firstElementFromCalendar: cal];
if ([cal isKindOfClass: [iCalRepeatableEntityObject class]])
fields = [cal quickRecord];
else if ([cal isNotNull])
[self logWithFormat: @"ERROR: unexpected iCalendar parse result: %@",
cal];
}
else
[self logWithFormat: @"ERROR: parsing source didn't return anything"];
}
return fields;
}
@end /* OCSiCalFieldExtractor */
-144
View File
@@ -1,144 +0,0 @@
Storage Backend
===============
The storage backend implements the "low level" folder abstraction, which is
basically an arbitary "BLOB" containing some document. The feature is that
we extract "quick access" / "searchable" attributes from the document content.
Further it contains the "folder management" API, as named folders can be stored
in different databases.
Note: we need a way to tell where "new" folders should be created
Note: to sync with LDAP we need to periodically delete or archive old folders
Folders have associated a type (like 'calendar') which defines the query
attributes and serialization format.
TODO
====
- hierarchies deeper than 4 (properly filter on path in OCS)
Open Questions
==============
System-meta-data in the blob-table or in the quick-table?
- master data belongs into the blob table
- could be regular 'NSxxx' keys to differentiate meta data from
Class Hierarchy
===============
[NSObject]
OCSContext - tracking context
OCSFolder - represents a single folder
OCSFolderManager - manages folders
OCSFolderType - the mapping info for a specific folder-type
OCSFieldInfo - mapping info for one 'quick field'
OCSChannelManager - maintains EOAdaptorChannel objects
TBD:
- field 'extractor'
- field 'value' (eg array values for participants?)
- BLOB archiver/unarchiver
Defaults
========
OCSFolderInfoURL - the DB URL where the folder-info table is located
eg: http://OGo:OGo@localhost/test/folder_info
OCSFolderManagerDebugEnabled - enable folder-manager debug logs
OCSFolderManagerSQLDebugEnabled - enable folder-manager SQL gen debug logs
OCSChannelManagerDebugEnabled - enable channel debug pooling logs
OCSChannelManagerPoolDebugEnabled - debug pool handle allocation
OCSChannelExpireAge - if that age in seconds is exceeded, a channel
will be removed from the pool
OCSChannelCollectionTimer - time in seconds. each n-seconds the pool will be
checked for channels too old
[PGDebugEnabled] - enable PostgreSQL adaptor debugging
URLs
====
"Database URLs"
We use the schema:
postgresql://[user]:[password]@[host]:[port]/[dbname]/[tablename]
BLOB Formats
============
- TBD
- iCal, XML
- problem with iCal is that a complete and valid iCal file is different from
just the vevent. so we basically need to parse those files in any case.
- XML: the iCal SaxDriver reports XML events, so we can easily store that as
XML
- we need to parse the BLOB for different clients anyway (iCal != iCal ...)
- XML: we could use some XML query extension to PG in the future?
Update: we now have OCSiCalFieldExtractor
- it parses the BLOB as an iCalendar file and extracts a set of fixed
keys:
- title - plain copy of "summary"
- uid - plain copy
- startdate - date as utime
- enddate - date as utime
- participants - CNs of attendees separated by comma ", "
- location
- partmails
- sequence
- TBD: iscyclic
- TBD: isallday
- TBD: cycles - I guess the client should fetch the BLOB to resolve
- the field extractor is accessed by OCSFolder using the folderinfo:
extractor = [self->folderInfo quickExtractor];
quickRow = [extractor extractQuickFieldsFromContent:_content];
Support Tools
=============
- tools we need:
- one to recreate a quick table based on the blob table
Notes
=====
- need to use http:// URLs for connect info, until generic URLs in
libFoundation are fixed (the parses breaks on the login/password parts)
QA
==
Q: Why do we use two tables, we could store the quick columns in the blob?
==
They could be in the same table. I considered using separate tables since the
quick table is likely to be recreated now and then if BLOB indexing
requirements change.
Actually one could even use different _quick tables which share a common BLOB
table.
(a quick table is nothing more than a database index and like with DB indexes
multiple ones for different requirements can make sense).
Further it might improve caching behaviour for row based caches (the quick
table is going to be queried much more often) - not sure whether this is
relevant with PostgreSQL, probably not?
Q: Can we use a VARCHAR primary key?
==
I asked in the postgres IRC channel and apparently the performance penalty of
string primary keys isn't big.
We could also use an 'internal' int sequence in addition (might be useful for
supporting ZideLook)
Motivation: the 'iCalendar' ID is a string and usually looks like a GUID.
Q: Why using VARCHAR instead of TEXT in the BLOB?
==
To quote PostgreSQL documentation:
"There are no performance differences between these three types, apart from
the increased storage size when using the blank-padded type."
So varchar(xx) is just a large TEXT. Since we intend to store mostly small
snippets of data (tiny XML fragments), I considered VARCHAR the more
appropriate type.
-14
View File
@@ -1,14 +0,0 @@
# Version file
MAJOR_VERSION=0
MINOR_VERSION=9
SUBMINOR_VERSION:=33
# v0.9.30 requires libNGiCal v4.5.48
# v0.9.26 requires libGDLContentStore v4.5.26
# v0.9.19 requires libNGiCal v4.5.40
# v0.9.18 requires libNGiCal v4.5.38
# v0.9.17 requires libNGiCal v4.5.37
# v0.9.11 requires libFoundation v1.0.63
# v0.9.11 requires libNGExtensions v4.3.125
# v0.9.7 requires libGDLAccess v1.1.35
@@ -1,35 +0,0 @@
/*
Copyright (C) 2004-2005 SKYRIX Software AG
This file is part of OpenGroupware.org.
OGo 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, or (at your option) any
later version.
OGo 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 OGo; see the file COPYING. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
// $Id: iCalRepeatableEntityObject+OCS.h 617 2005-03-01 17:08:11Z znek $
#ifndef __OGoContentStore_iCalRepeatableEntityObject_OCS_H_
#define __OGoContentStore_iCalRepeatableEntityObject_OCS_H_
#include <NGCards/NGCards.h>
@interface iCalRepeatableEntityObject (OCS)
- (NSString *)cycleInfo;
@end
#endif /* __OGoContentStore_iCalRepeatableEntityObject_OCS_H_ */
@@ -1,29 +0,0 @@
/*
Copyright (C) 2004-2005 SKYRIX Software AG
This file is part of OpenGroupware.org.
OGo 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, or (at your option) any
later version.
OGo 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 OGo; see the file COPYING. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import "iCalRepeatableEntityObject+OCS.h"
@implementation iCalRepeatableEntityObject (OCS)
@end
-108
View File
@@ -1,108 +0,0 @@
http://www.faqs.org/rfcs/rfc2798.html
Class
NAME 'inetOrgPerson'
SUP organizationalPerson
STRUCTURAL
MAY (
audio $ businessCategory $ carLicense $ departmentNumber $
displayName $ employeeNumber $ employeeType $ givenName $
homePhone $ homePostalAddress $ initials $ jpegPhoto $
labeledURI $ mail $ manager $ mobile $ o $ pager $
photo $ roomNumber $ secretary $ uid $ userCertificate $
x500uniqueIdentifier $ preferredLanguage $
userSMIMECertificate $ userPKCS12
)
MUST (
cn $ objectClass $ sn
)
MAY (
description $ destinationIndicator $ facsimileTelephoneNumber $
internationaliSDNNumber $ l $ ou $ physicalDeliveryOfficeName $
postalAddress $ postalCode $ postOfficeBox $
preferredDeliveryMethod $ registeredAddress $ seeAlso $
st $ street $ telephoneNumber $ teletexTerminalIdentifier $
telexNumber $ title $ userPassword $ x121Address
)
Properties (inetOrgPerson + organizationalPerson)
businessCategory
carLicense
departmentNumber
destinationIndicator
employeeNumber
employeeType
facsimileTelephoneNumber
givenName
homePostalAddress
initials
jpegPhoto
l
mail
manager
mobile
o
objectClass
ou
pager
physicalDeliveryOfficeName
postOfficeBox
postalCode
preferredLanguage
registeredAddress
roomNumber
secretary
seeAlso
sn
street
telephoneNumber
teletexTerminalIdentifier
title
uid
userCertificate
userPKCS12
userPassword
x121Address
audio
cn
description
displayName
homePhone
internationaliSDNNumber
labeledURI
photo
postalAddress
preferredDeliveryMethod
st
telexNumber
userSMIMECertificate
x500uniqueIdentifier
Sample:
version: 1
dn: cn=Barbara Jensen,ou=Product Development,dc=siroe,dc=com
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
cn: Barbara Jensen
cn: Babs Jensen
displayName: Babs Jensen
sn: Jensen
givenName: Barbara
initials: BJJ
title: manager, product development
uid: bjensen
mail: bjensen@siroe.com
telephoneNumber: +1 408 555 1862
facsimileTelephoneNumber: +1 408 555 1992
mobile: +1 408 555 1941
roomNumber: 0209
carLicense: 6ABC246
o: Siroe
ou: Product Development
departmentNumber: 2604
employeeNumber: 42
employeeType: full time
preferredLanguage: fr, en-gb;q=0.8, en;q=0.7
labeledURI: http://www.siroe.com/users/bjensen My Home Page
-30
View File
@@ -1,30 +0,0 @@
BEGIN:VEVENT
DURATION:PT1H
ATTENDEE;CN="Elke Bethke";DIR="addressbook://B156F3F0-9CFD-11D8-8561-000
D93C1A604:ABPerson":mailto:E.Bethke@Sachsen-Anhalt-Lotto.de
ATTENDEE;CN="Erik Doernenburg";DIR="addressbook://B15FCB0F-9CFD-11D8-8561
-000D93C1A604:ABPerson":mailto:erik@x101.net
ATTENDEE;CN="Christian Schnelle";DIR="addressbook://B1418D4E-9CFD-11D8-8
561-000D93C1A604:ABPerson":mailto:cs@enervation.de
ATTENDEE;CN="Chris Herrenberger";DIR="addressbook://B14A390C-9CFD-11D8-8
561-000D93C1A604:ABPerson":invalid:nomail
ATTENDEE;CN="Horst Parplies";DIR="addressbook://B19B47E5-9CFD-11D8-8561-
000D93C1A604:ABPerson":mailto:horst.parplies@freenet.de
ATTENDEE;CN="Imdat Solak";DIR="addressbook://B19EDB62-9CFD-11D8-8561-000
D93C1A604:ABPerson":mailto:imdat@solak.de
ATTENDEE;CN="Jens Enders";DIR="addressbook://B1B6819F-9CFD-11D8-8561-000
D93C1A604:ABPerson":mailto:jens.enders@skyrix.com
ATTENDEE;CN="Jens Muenster";DIR="addressbook://B1BBA42E-9CFD-11D8-8561-00
0D93C1A604:ABPerson":mailto:jens.muenster@skyrix.com
ATTENDEE;CN="Laurent Pierre";DIR="addressbook://9337C270-A825-11D8-B930-
000D93C1A604:ABPerson":mailto:laurent.pierre@linagora.com
ATTENDEE;CN="Marcel Weiher";DIR="addressbook://B1F9BB12-9CFD-11D8-8561-0
00D93C1A604:ABPerson":mailto:marcel@metaobject.co
DTSTAMP:20040520T140002Z
UID:BD91C454-AA65-11D8-84CA-000D93C1A604
SEQUENCE:3
STATUS:CONFIRMED
DTSTART;TZID=Europe/Berlin:20040618T160000
SUMMARY:SIZE EVENT
X-WR-ITIPSTATUSML:UNCLEAN
END:VEVENT
-15
View File
@@ -1,15 +0,0 @@
# $Id$
include $(GNUSTEP_MAKEFILES)/common.make
TOOL_NAME = test
test_OBJC_FILES += test1.m
ADDITIONAL_TOOL_LIBS += -lOGoContentStore
ADDITIONAL_LIB_DIRS += -L../../$(GNUSTEP_OBJ_DIR)
-include GNUmakefile.preamble
include $(GNUSTEP_MAKEFILES)/tool.make
-include GNUmakefile.postamble
-3
View File
@@ -1,3 +0,0 @@
// $Id$
#import <Foundation/Foundation.h>
-31
View File
@@ -1,31 +0,0 @@
// $Id$
#include "common.h"
static void testurl(NSString *s) {
NSURL *url;
url = [NSURL URLWithString:s];
NSLog(@"url: %@", url);
NSLog(@" login: %@", [url user]);
NSLog(@" pwd: %@", [url password]);
}
static void test(void) {
testurl(@"http://OGoUser:OGoPwd@localhost/OGo");
testurl(@"postgresql://OGoUser:OGoPwd@localhost/OGo");
}
int main(int argc, char **argv, char **env) {
NSAutoreleasePool *pool;
pool = [[NSAutoreleasePool alloc] init];
#if LIB_FOUNDATION_LIBRARY
[NSProcessInfo initializeWithArguments:argv count:argc environment:env];
#endif
test();
[pool release];
return 0;
}
-2
View File
@@ -137,7 +137,6 @@ $(DBMSGREADER_TOOL)_OBJC_FILES += \
$(DBMSGREADER_TOOL)_LIB_DIRS += \
-L../SoObjects/SOGo/SOGo.framework/ -lSOGo \
-L../OGoContentStore/obj/ -lOGoContentStore \
-L../SOPE/GDLContentStore/obj/ -lGDLContentStore \
-L../SOPE/NGCards/obj/ -lNGCards \
-lNGObjWeb
@@ -166,7 +165,6 @@ $(MAPISTORESOGO)_LIB_DIRS += \
$(LIBMAPISTORE_LIBS)
$(SOGOBACKEND)_LIB_DIRS += \
-L../OGoContentStore/$(GNUSTEP_OBJ_DIR)/ -lOGoContentStore \
-L../SoObjects/SOGo/SOGo.framework/ -lSOGo \
$(LIBMAPI_LIBS) \
$(LIBMAPISTORE_LIBS)
+1 -1
View File
@@ -1200,7 +1200,7 @@ fromProperties: (NSDictionary *) attachmentProps
//
// we save the new/modified card
//
[sogoObject saveContentString: [newCard versitString]];
[sogoObject saveComponent: newCard];
[self updateVersions];
}
+1 -1
View File
@@ -513,7 +513,7 @@
}
[vToDo setTimeStampAsDate: now];
[sogoObject saveContentString: [vCalendar versitString]];
[sogoObject saveComponent: vCalendar];
[self updateVersions];
}
+5 -2
View File
@@ -294,9 +294,12 @@ static NSMapTable *contextsTable = nil;
if ([parts count] == 5)
{
/* If "OCSFolderInfoURL" is properly configured, we must have 5
parts in this url. */
parts in this url. We strip the '-' character in case we have
this in the domain part - like foo@bar-zot.com */
ocFSTableName = [NSString stringWithFormat: @"sogo_cache_folder_%@",
[username asCSSIdentifier]];
[[[user loginInDomain] asCSSIdentifier]
stringByReplacingOccurrencesOfString: @"-"
withString: @"_"]];
[parts replaceObjectAtIndex: 4 withObject: ocFSTableName];
folderTableURL
= [NSURL URLWithString: [parts componentsJoinedByString: @"/"]];
-37
View File
@@ -1,37 +0,0 @@
/*
Copyright (C) 2004-2005 SKYRIX Software AG
This file is part of OpenGroupware.org.
OGo 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, or (at your option) any
later version.
OGo 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 OGo; see the file COPYING. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
#ifndef __GDLContentStore_GCSFieldExtractor_H__
#define __GDLContentStore_GCSFieldExtractor_H__
#import <Foundation/NSObject.h>
@class NSString, NSMutableDictionary;
@interface GCSFieldExtractor : NSObject
{
}
- (NSMutableDictionary *)extractQuickFieldsFromContent:(NSString *)_content;
@end
#endif /* __GDLContentStore_GCSFieldExtractor_H__ */
-30
View File
@@ -1,30 +0,0 @@
/*
Copyright (C) 2004-2005 SKYRIX Software AG
This file is part of OpenGroupware.org.
OGo 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, or (at your option) any
later version.
OGo 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 OGo; see the file COPYING. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
#import "GCSFieldExtractor.h"
@implementation GCSFieldExtractor
- (NSMutableDictionary *)extractQuickFieldsFromContent:(NSString *)_content {
return nil;
}
@end /* GCSFieldExtractor */
+3 -2
View File
@@ -117,10 +117,11 @@
- (NSDictionary *) recordOfEntryWithName: (NSString *) name;
- (NSException *) writeContent: (NSString *) _content
fromComponent: (id) theComponent
container: (id) theContainer
toName: (NSString *) _name
baseVersion: (unsigned int *) _baseVersion;
- (NSException *) writeContent: (NSString *) _content
toName: (NSString *) _name;
- (NSException *) deleteContentWithName: (NSString *) _name;
- (NSException *) deleteAllContent;
+11 -19
View File
@@ -1,22 +1,22 @@
/*
Copyright (C) 2004-2007 SKYRIX Software AG
Copyright (C) 2007 Helge Hess
Copyright (c) 2008-2011 Inverse inc.
Copyright (c) 2008-2014 Inverse inc.
This file is part of OpenGroupware.org.
This file is part of SOGo.
OGo is free software; you can redistribute it and/or modify it under
SOGo 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, or (at your option) any
later version.
OGo is distributed in the hope that it will be useful, but WITHOUT ANY
SOGo 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 OGo; see the file COPYING. If not, write to the
License along with SOGo; see the file COPYING. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
@@ -38,7 +38,6 @@
#import "GCSFolderManager.h"
#import "GCSFolderType.h"
#import "GCSChannelManager.h"
#import "GCSFieldExtractor.h"
#import "NSURL+GCS.h"
#import "EOAdaptorChannel+GCS.h"
#import "EOQualifier+GCS.h"
@@ -882,13 +881,14 @@ andAttribute: (EOAttribute *)_attribute
}
- (NSException *) writeContent: (NSString *) _content
toName: (NSString *) _name
fromComponent: (id) theComponent
container: (id) theContainer
toName: (NSString *) _name
baseVersion: (unsigned int *) _baseVersion
{
EOAdaptorChannel *storeChannel, *quickChannel;
NSMutableDictionary *quickRow, *contentRow;
NSDictionary *currentRow;
GCSFieldExtractor *extractor;
NSNumber *storedVersion;
BOOL isNewRecord, hasInsertDelegate, hasUpdateDelegate;
NSCalendarDate *nowDate;
@@ -944,8 +944,7 @@ andAttribute: (EOAttribute *)_attribute
|| *_baseVersion == [storedVersion unsignedIntValue])
{
/* extract quick info */
extractor = [folderInfo quickExtractor];
quickRow = [extractor extractQuickFieldsFromContent:_content];
quickRow = [theComponent performSelector: @selector(quickRecordForContainer:) withObject: theContainer];
if (quickRow)
{
[quickRow setObject:_name forKey:@"c_name"];
@@ -1080,8 +1079,8 @@ andAttribute: (EOAttribute *)_attribute
__PRETTY_FUNCTION__];
}
else
error = [self errorExtractorReturnedNoQuickRow:extractor
forContent:_content];
[self errorWithFormat:@"%s: could not extract quick row information",
__PRETTY_FUNCTION__];
}
else /* version mismatch (concurrent update) */
error = [self errorVersionMismatchBetweenStoredVersion:
@@ -1101,13 +1100,6 @@ andAttribute: (EOAttribute *)_attribute
return error;
}
- (NSException *)writeContent:(NSString *)_content toName:(NSString *)_name {
/* this method does not check for concurrent writes */
unsigned int v = 0;
return [self writeContent:_content toName:_name baseVersion:&v];
}
- (NSException *)deleteContentWithName:(NSString *)_name {
EOAdaptorChannel *storeChannel, *quickChannel;
EOAdaptorContext *adaptorCtx;
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 2006-2011 Inverse inc.
Copyright (C) 2006-2014 Inverse inc.
Copyright (C) 2004-2007 SKYRIX Software AG
This file is part of SOGo.
+1 -6
View File
@@ -41,7 +41,7 @@
@class NSString, NSArray, NSDictionary;
@class EOQualifier;
@class NGResourceLocator;
@class GCSFolder, GCSFieldExtractor;
@class GCSFolder;
@interface GCSFolderType : NSObject
{
@@ -50,7 +50,6 @@
NSArray *fields, *quickFields; // GCSFieldInfo objects
EOQualifier *folderQualifier; // to further limit the table set
NSString *extractorClassName;
GCSFieldExtractor *extractor;
}
+ (id)folderTypeWithName:(NSString *)_type;
@@ -67,10 +66,6 @@
- (NSString *)sqlQuickCreateWithTableName:(NSString *)_tabName;
/* quick support */
- (GCSFieldExtractor *)quickExtractor;
/* locator used to find .ocs files */
+ (NGResourceLocator *)resourceLocator;
+4 -36
View File
@@ -1,20 +1,20 @@
/*
Copyright (C) 2004-2005 SKYRIX Software AG
This file is part of OpenGroupware.org.
This file is part of SOGo.
OGo is free software; you can redistribute it and/or modify it under
SOGo 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, or (at your option) any
later version.
OGo is distributed in the hope that it will be useful, but WITHOUT ANY
SOGo 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 OGo; see the file COPYING. If not, write to the
License along with SOGo; see the file COPYING. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
@@ -35,7 +35,6 @@
#import "GCSFolderType.h"
#import "GCSFolder.h"
#import "GCSFieldInfo.h"
#import "GCSFieldExtractor.h"
@implementation GCSFolderType
@@ -116,7 +115,6 @@
- (void) dealloc
{
[extractor release];
[extractorClassName release];
[blobTablePattern release];
[quickTablePattern release];
@@ -173,36 +171,6 @@
return sql;
}
/* quick support */
- (GCSFieldExtractor *) quickExtractor
{
Class clazz;
GCSFieldExtractor *quickExtractor;
if (!extractor)
{
clazz = (extractorClassName
? NSClassFromString (extractorClassName)
: [GCSFieldExtractor class]);
if (clazz)
{
extractor = [clazz new];
if (!extractor)
[self logWithFormat:@"ERROR: could not create field extractor of class %@",
clazz];
}
else
[self logWithFormat:@"ERROR: did not find field extractor class (%@)", extractorClassName];
}
if ([extractor isNotNull])
quickExtractor = extractor;
else
quickExtractor = nil;
return quickExtractor;
}
- (NSArray *) quickFields
{
return quickFields;
+8 -2
View File
@@ -31,7 +31,6 @@ libGDLContentStore_HEADER_FILES += \
GCSFolderManager.h \
GCSFolderType.h \
GCSChannelManager.h \
GCSFieldExtractor.h \
GCSSessionsFolder.h \
GCSSpecialQueries.h \
GCSStringFormatter.h \
@@ -48,7 +47,6 @@ libGDLContentStore_OBJC_FILES += \
GCSFolderManager.m \
GCSFolderType.m \
GCSChannelManager.m \
GCSFieldExtractor.m \
GCSSessionsFolder.m \
GCSSpecialQueries.m \
GCSStringFormatter.m \
@@ -60,6 +58,14 @@ GDLContentStore_HEADER_FILES = $(libGDLContentStore_HEADER_FILES)
GDLContentStore_OBJC_FILES = $(libGDLContentStore_OBJC_FILES)
GDLContentStore_SUBPROJECTS = $(libGDLContentStore_SUBPROJECTS)
# Type models
TYPEMODELS_DIR = $(SOGO_TYPEMODELS)
libGDLContentStore_TYPEMODELS += \
appointment.ocs \
contact.ocs \
appointment-oracle.ocs \
contact-oracle.ocs
# building
@@ -3,10 +3,10 @@
$(TYPEMODELS_DIR) :
$(MKDIRS) $(TYPEMODELS_DIR)
ocs-typemodels : $(TYPEMODELS_DIR) $(libOGoContentStore_TYPEMODELS)
@(if [ "$(libOGoContentStore_TYPEMODELS)" != "" ]; then \
ocs-typemodels : $(TYPEMODELS_DIR) $(libGDLContentStore_TYPEMODELS)
@(if [ "$(libGDLContentStore_TYPEMODELS)" != "" ]; then \
echo "Copying type models into install path ..."; \
for ff in $(libOGoContentStore_TYPEMODELS); do \
for ff in $(libGDLContentStore_TYPEMODELS); do \
cp $$ff $(TYPEMODELS_DIR)/$$ff; \
done; \
fi)
File renamed without changes.
File renamed without changes.
File renamed without changes.
+1 -1
View File
@@ -232,7 +232,7 @@ static NSArray *privilegedTagNames = nil;
}
- (void) characters: (unichar *) _chars
length: (int) _len
length: (NSUInteger) _len
{
if (_len && _chars)
{
+3
View File
@@ -126,6 +126,9 @@ typedef enum
- (void) setCategories: (NSArray *) newCategories;
- (NSArray *) categories;
- (NSString *) photo;
- (void) setPhoto: (NSString *) _value;
// - (void) setN: (NGVCardName *) _v;
// - (NGVCardName *) n;
+19
View File
@@ -288,6 +288,25 @@
return [self uniqueChildWithTag: @"n"];
}
- (NSString *) photo
{
NGVCardPhoto *photo;
photo = (NGVCardPhoto *)[self uniqueChildWithTag: @"photo"];
return [[photo valuesAtIndex: 0 forKey: @""] objectAtIndex: 0];
}
- (void) setPhoto: (NSString *) _value
{
CardElement *photo;
photo = [self uniqueChildWithTag: @"photo"];
[photo setValue: 0 ofAttribute: @"encoding" to: @"BASE64"];
[photo setSingleValue: _value forKey: @""];
}
- (void) setOrg: (NSString *) anOrg
units: (NSArray *) someUnits
{
+4 -4
View File
@@ -217,10 +217,10 @@
printf("</%s>\n", [_localName cString]);
}
- (void)characters:(unichar *)_chars length:(int)_len {
- (void)characters:(unichar *)_chars length:(NSUInteger)_len {
NSString *str;
id tmp;
unsigned i, len;
NSUInteger i, len;
if (_len == 0) {
[self indent];
@@ -228,7 +228,7 @@
return;
}
for (i = 0; i < (unsigned)_len; i++) {
for (i = 0; i < _len; i++) {
if (_chars[i] > 255) {
NSLog(@"detected large char: o%04o d%03i h%04X",
_chars[i], _chars[i], _chars[i]);
@@ -246,7 +246,7 @@
[self indent];
printf("\"%s\"\n", [str cString]);
}
- (void)ignorableWhitespace:(unichar *)_chars length:(int)_len {
- (void)ignorableWhitespace:(unichar *)_chars length:(NSUInteger)_len {
NSString *data;
id tmp;
@@ -1,3 +1,4 @@
"Inviting the following persons is prohibited:" = "Està prohibit Convidar a les següents persones:";
"Personal Calendar" = "Calendari personal";
vevent_class0 = "(Esdeveniment públic)";
vevent_class1 = "(Esdeveniment privat)";
@@ -1,3 +1,4 @@
"Inviting the following persons is prohibited:" = "Pozvání následujících osob je zakázáno:";
"Personal Calendar" = "Osobní kalendář";
vevent_class0 = "(Veřejná událost)";
vevent_class1 = "(Soukromá událost)";
@@ -1,3 +1,4 @@
"Inviting the following persons is prohibited:" = "De volgende personen uitnodigen is niet toegestaan:";
"Personal Calendar" = "Persoonlijke agenda";
vevent_class0 = "(Publieke afspraak)";
vevent_class1 = "(Privé-afspraak)";
@@ -1,3 +1,4 @@
"Inviting the following persons is prohibited:" = "Inviting the following persons is prohibited:";
"Personal Calendar" = "Personal Calendar";
vevent_class0 = "(Public event)";
vevent_class1 = "(Private event)";
@@ -1,3 +1,4 @@
"Inviting the following persons is prohibited:" = "Seuraavien henkilöiden kutsuminen on estetty:";
"Personal Calendar" = "Henkilökohtainen kalenteri";
vevent_class0 = "(Julkinen tapahtuma)";
vevent_class1 = "(Yksityinen tapahtuma)";
@@ -1,3 +1,4 @@
"Inviting the following persons is prohibited:" = "L'invitation des personnes suivantes est interdite :";
"Personal Calendar" = "Agenda personnel";
vevent_class0 = "(Événement public)";
vevent_class1 = "(Événement privé)";
@@ -1,3 +1,4 @@
"Inviting the following persons is prohibited:" = "Das Einladen von folgenden Personen ist verboten:";
"Personal Calendar" = "Persönlicher Kalender";
vevent_class0 = "(Öffentlicher Termin)";
vevent_class1 = "(Privater Termin)";
@@ -1,3 +1,4 @@
"Inviting the following persons is prohibited:" = "A következő személyek meghívása tilos:";
"Personal Calendar" = "Személyes naptár";
vevent_class0 = "(Nyilvános esemény)";
vevent_class1 = "(Magán esemény)";
@@ -1,3 +1,4 @@
"Inviting the following persons is prohibited:" = "Invitering av følgende personer er forbudt.";
"Personal Calendar" = "Personlig kalender";
vevent_class0 = "(Offentlig hendelse)";
vevent_class1 = "(Privat hendelse)";
@@ -1,3 +1,4 @@
"Inviting the following persons is prohibited:" = "Zapraszanie następujących osób jest zakazane:";
"Personal Calendar" = "Kalendarz osobisty";
vevent_class0 = "(Wydarzenie publiczne)";
vevent_class1 = "(Wydarzenie prywatne)";
@@ -80,6 +80,8 @@ typedef enum {
- (NSArray *) calendarUIDs;
- (NSNumber *) activeTasks;
/* vevent UID handling */
- (NSString *) resourceNameForEventUID: (NSString *) _uid;
+94 -7
View File
@@ -230,6 +230,8 @@ static iCalEvent *iCalEventK = nil;
abstract: NO
withEquivalent: SoPerm_AddDocumentsImagesAndFiles
asChildOf: davElement (@"write", XMLNS_WEBDAV)];
/* read-acl and write-acl are defined in RFC3744 */
[aclManager registerDAVPermission: davElement (@"admin", nsI)
abstract: YES
withEquivalent: nil
@@ -242,6 +244,72 @@ static iCalEvent *iCalEventK = nil;
abstract: YES
withEquivalent: SoPerm_ChangePermissions
asChildOf: davElement (@"admin", nsI)];
/* Default permissions for calendars. These are very important so that DAV client can
detect permission changes on calendars and reload all items, if necessary */
/* Public ones */
[aclManager registerDAVPermission: davElement (@"viewwhole-public-records", nsI)
abstract: YES
withEquivalent: SOGoCalendarPerm_ViewWholePublicRecords
asChildOf: davElement (@"admin", nsI)];
[aclManager registerDAVPermission: davElement (@"viewdant-public-records", nsI)
abstract: YES
withEquivalent: SOGoCalendarPerm_ViewDAndTOfPublicRecords
asChildOf: davElement (@"admin", nsI)];
[aclManager registerDAVPermission: davElement (@"modify-public-records", nsI)
abstract: YES
withEquivalent: SOGoCalendarPerm_ModifyPublicRecords
asChildOf: davElement (@"admin", nsI)];
[aclManager registerDAVPermission: davElement (@"respondto-public-records", nsI)
abstract: YES
withEquivalent: SOGoCalendarPerm_RespondToPublicRecords
asChildOf: davElement (@"admin", nsI)];
/* Private ones */
[aclManager registerDAVPermission: davElement (@"viewwhole-private-records", nsI)
abstract: YES
withEquivalent: SOGoCalendarPerm_ViewWholePrivateRecords
asChildOf: davElement (@"admin", nsI)];
[aclManager registerDAVPermission: davElement (@"viewdant-private-records", nsI)
abstract: YES
withEquivalent: SOGoCalendarPerm_ViewDAndTOfPrivateRecords
asChildOf: davElement (@"admin", nsI)];
[aclManager registerDAVPermission: davElement (@"modify-private-records", nsI)
abstract: YES
withEquivalent: SOGoCalendarPerm_ModifyPrivateRecords
asChildOf: davElement (@"admin", nsI)];
[aclManager registerDAVPermission: davElement (@"respondto-private-records", nsI)
abstract: YES
withEquivalent: SOGoCalendarPerm_RespondToPrivateRecords
asChildOf: davElement (@"admin", nsI)];
/* Condifential ones */
[aclManager registerDAVPermission: davElement (@"viewwhole-confidential-records", nsI)
abstract: YES
withEquivalent: SOGoCalendarPerm_ViewWholeConfidentialRecords
asChildOf: davElement (@"admin", nsI)];
[aclManager registerDAVPermission: davElement (@"viewdant-confidential-records", nsI)
abstract: YES
withEquivalent: SOGoCalendarPerm_ViewDAndTOfConfidentialRecords
asChildOf: davElement (@"admin", nsI)];
[aclManager registerDAVPermission: davElement (@"modify-confidential-records", nsI)
abstract: YES
withEquivalent: SOGoCalendarPerm_ModifyConfidentialRecords
asChildOf: davElement (@"admin", nsI)];
[aclManager registerDAVPermission: davElement (@"respondto-confidential-records", nsI)
abstract: YES
withEquivalent: SOGoCalendarPerm_RespondToConfidentialRecords
asChildOf: davElement (@"admin", nsI)];
}
return aclManager;
@@ -522,7 +590,6 @@ static iCalEvent *iCalEventK = nil;
{
/* this is used for group calendars (this folder just returns itself) */
NSString *s;
s = [[self container] nameInContainer];
// [self logWithFormat:@"CAL UID: %@", s];
return [s isNotNull] ? [NSArray arrayWithObjects:&s count:1] : nil;
@@ -916,7 +983,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
{
if ([dateRange containsDate: [component startDate]])
{
newRecord = [self fixupRecord: [component quickRecord]];
newRecord = [self fixupRecord: [component quickRecordForContainer: self]];
[ma replaceObjectAtIndex: recordIndex withObject: newRecord];
}
else
@@ -932,7 +999,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
{
// The recurrence id of the exception is outside the date range;
// simply add the exception to the records array
newRecord = [self fixupRecord: [component quickRecord]];
newRecord = [self fixupRecord: [component quickRecordForContainer: self]];
newRecordRange = [NGCalendarDateRange
calendarDateRangeWithStartDate: [newRecord objectForKey: @"startDate"]
endDate: [newRecord objectForKey: @"endDate"]];
@@ -2967,7 +3034,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
[content appendFormat: @"%@\n", [timezone versitString]];
[content appendFormat: @"%@\nEND:VCALENDAR", [event versitString]];
return ([object saveContentString: content] == nil) ? uid : nil;
return ([object saveCalendar: [iCalCalendar parseSingleFromSource: content]] == nil) ? uid : nil;
}
/**
@@ -2980,7 +3047,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
NSArray *vtimezones;
NSMutableArray *components;
NSMutableDictionary *timezones, *uids;
NSString *tzId, *uid, *originalUid, *content;
NSString *tzId, *uid, *originalUid;
iCalEntityObject *element;
iCalDateTime *startDate;
iCalTimeZone *timezone;
@@ -3108,8 +3175,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
[masterCalendar addToEvents: event];
if (timezone)
[masterCalendar addTimeZone: timezone];
content = [masterCalendar versitString];
[master saveContentString: content];
[master saveCalendar: masterCalendar];
continue;
}
}
@@ -3270,4 +3336,25 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
return users;
}
- (NSNumber *) activeTasks
{
NSArray *tasksList;
NSMutableArray *fields;
NSNumber *activeTasks;
fields = [NSMutableArray arrayWithObjects: @"c_component", @"c_status", nil];
tasksList = [self bareFetchFields: fields
from: nil
to: nil
title: nil
component: @"vtodo"
additionalFilters: @"c_status != 1 AND c_status != 3"];
activeTasks = [NSNumber numberWithInt:[tasksList count]];
return activeTasks;
}
@end /* SOGoAppointmentFolder */
@@ -750,7 +750,8 @@ static SoSecurityManager *sm = nil;
for (userCount = 0; userCount < userMax; userCount++)
[currentFolder
subscribeUserOrGroup: [proxySubscribers objectAtIndex: userCount]
reallyDo: YES];
reallyDo: YES
response: nil];
}
}
}
@@ -775,7 +776,8 @@ static SoSecurityManager *sm = nil;
for (userCount = 0; userCount < userMax; userCount++)
[currentFolder
subscribeUserOrGroup: [proxySubscribers objectAtIndex: userCount]
reallyDo: NO];
reallyDo: NO
response: nil];
}
}
}
@@ -1,5 +1,5 @@
/*
Copyright (C) 2007-2011 Inverse inc.
Copyright (C) 2007-2014 Inverse inc.
This file is part of SOGo
File diff suppressed because it is too large. Load diff
@@ -1,6 +1,6 @@
/* SOGoCalendarComponent.h - this file is part of SOGo
*
* Copyright (C) 2006-2013 Inverse inc.
* Copyright (C) 2006-2014 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
+19 -2
View File
@@ -169,6 +169,11 @@
DESTROY(originalCalendar);
}
- (Class *) parsingClass
{
return [iCalCalendar class];
}
- (NSString *) davContentType
{
return @"text/calendar";
@@ -662,7 +667,7 @@
- (NSException *) saveCalendar: (iCalCalendar *) newCalendar
{
[self saveContentString: [newCalendar versitString]];
[super saveComponent: newCalendar];
return nil;
}
@@ -1193,7 +1198,19 @@
[NSString stringWithFormat: @"%@.ics", newUID]
inContainer: newFolder];
return [newComponent saveContentString: [calendar versitString]];
return [newComponent saveCalendar: calendar];
}
- (NSException *) moveToFolder: (SOGoGCSFolder *) newFolder
{
NSException *ex;
ex = [self copyToFolder: newFolder];
if (!ex)
ex = [self delete];
return ex;
}
#warning Should we not remove the concept of Organizer and Participant roles?
@@ -1,9 +1,6 @@
/* SOGoComponentOccurence.m - this file is part of SOGo
*
* Copyright (C) 2008-2011 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Francis Lachapelle <flachapelle@inverse.ca>
* Copyright (C) 2008-2014 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -152,7 +149,6 @@
NSArray *occurences;
NSCalendarDate *recurrenceId, *currentId;
NSException *error;
NSString *newContent;
NSTimeZone *timeZone;
iCalCalendar *calendar;
iCalEntityObject *currentOccurence;
@@ -197,10 +193,8 @@
[master addToExceptionDates: recurrenceId];
[master increaseSequence];
// We generate the updated iCalendar file and we save it
// in the database.
newContent = [calendar versitString];
error = [container saveContentString: newContent];
// We save the updated iCalendar in the database.
error = [container saveComponent: calendar];
}
return error;
+1 -1
View File
@@ -1,6 +1,6 @@
/*
Copyright (C) 2006-2013 Inverse inc.
Copyright (C) 2006-2014 Inverse inc.
Copyright (C) 2004-2005 SKYRIX Software AG
This file is part of SOGo.
+4 -4
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 2006-2012 Inverse inc.
Copyright (C) 2006-2014 Inverse inc.
Copyright (C) 2004-2005 SKYRIX Software AG
This file is part of SOGo.
@@ -65,12 +65,12 @@
#warning this code should be put in SOGoCalendarComponent once the UID hack\
in SOGoAppointmentObject is resolved
- (NSException *) saveContentString: (NSString *) newContent
baseVersion: (unsigned int) newVersion
- (NSException *) saveComponent: (id) theComponent
baseVersion: (unsigned int) newVersion
{
NSException *ex;
ex = [super saveContentString: newContent baseVersion: newVersion];
ex = [super saveComponent: theComponent baseVersion: newVersion];
[fullCalendar release];
fullCalendar = nil;
[safeCalendar release];
@@ -1,9 +1,6 @@
/* SOGoWebAppointmentFolder.h - this file is part of SOGo
*
* Copyright (C) 2009-2012 Inverse inc.
*
* Author: Cyril Robert <crobert@inverse.ca>
* Ludovic Marcotte <lmarcotte@inverse.ca>
* Copyright (C) 2009-2014 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1,9 +1,6 @@
/* SOGoWebAppointmentFolder.m - this file is part of SOGo
*
* Copyright (C) 2009-2013 Inverse inc.
*
* Author: Cyril Robert <crobert@inverse.ca>
* Ludovic Marcotte <lmarcotte@inverse.ca>
* Copyright (C) 2009-2014 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1,3 +1,4 @@
"Inviting the following persons is prohibited:" = "Esta prohibido invitar las siguientes personas:";
"Personal Calendar" = "Calendario personal";
vevent_class0 = "(Evento público)";
vevent_class1 = "(Evento privado)";
+21 -3
View File
@@ -1,8 +1,6 @@
/* iCalCalendar+SOGo.m - this file is part of SOGo
*
* Copyright (C) 2012 Inverse inc
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2012-2014 Inverse inc
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -80,4 +78,24 @@
return [self _occurrence: recID inArray: [self todos]];
}
- (NSMutableDictionary *) quickRecordForContainer: (id) theContainer
{
CardGroup *element;
NSArray *elements;
unsigned int count;
elements = [self allObjects];
count = [elements count];
if (count)
element = [elements objectAtIndex: 0];
else
{
[self logWithFormat: @"ERROR: given calendar contains no elements: %@", self];
element = nil;
}
return [element quickRecordForContainer: theContainer];
}
@end
@@ -43,7 +43,7 @@ extern NSNumber *iCalDistantFutureNumber;
- (id) itipEntryWithMethod: (NSString *) method;
- (NSArray *) attendeesWithoutUser: (SOGoUser *) user;
- (NSMutableDictionary *) quickRecord;
- (NSMutableDictionary *) quickRecordForContainer: (id) theContainer;
- (int) priorityNumber;
- (NSString *) createdBy;
@@ -213,7 +213,7 @@ NSNumber *iCalDistantFutureNumber = nil;
return dateNumber;
}
- (NSMutableDictionary *) quickRecord
- (NSMutableDictionary *) quickRecordForContainer: (id) theContainer
{
[self subclassResponsibility: _cmd];
+2 -5
View File
@@ -1,9 +1,6 @@
/* iCalEvent+SOGo.h - this file is part of SOGo
*
* Copyright (C) 2007-2011 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Francis Lachapelle <flachapelle@inverse.ca>
* Copyright (C) 2007-2014 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -32,7 +29,7 @@
- (BOOL) isStillRelevant;
- (unsigned int) occurenceInterval;
- (NSMutableDictionary *) quickRecord;
- (NSMutableDictionary *) quickRecordForContainer: (id) theContainer;
- (void) updateRecurrenceRulesUntilDate: (NSCalendarDate *) previousEndDate;
@end
+2 -5
View File
@@ -1,9 +1,6 @@
/* iCalEvent+SOGo.m - this file is part of SOGo
*
* Copyright (C) 2007-2013 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Francis Lachapelle <flachapelle@inverse.ca>
* Copyright (C) 2007-2014 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -67,7 +64,7 @@
//
//
//
- (NSMutableDictionary *) quickRecord
- (NSMutableDictionary *) quickRecordForContainer: (id) theContainer
{
NSMutableDictionary *row;
NSCalendarDate *startDate, *endDate, *nextAlarmDate;
@@ -1,24 +1,22 @@
/* iCalRepeatableEntityObject+SOGo.h - this file is part of SOGo
Copyright (C) 2004-2005 SKYRIX Software AG
Copyright (C) 2008-2013 Inverse inc.
This file is part of OpenGroupware.org.
OGo 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, or (at your option) any
later version.
OGo 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 OGo; see the file COPYING. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
*
* Copyright (C) 2007-2014 Inverse inc.
*
* This file 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, or (at your option)
* any later version.
*
* This file 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#import <NGCards/iCalRepeatableEntityObject.h>
@@ -1,24 +1,22 @@
/*
Copyright (C) 2008-2013 Inverse inc.
Copyright (C) 2004-2005 SKYRIX Software AG
This file is part of OpenGroupware.org.
OGo 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, or (at your option) any
later version.
OGo 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 OGo; see the file COPYING. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
/* iCalRepeatableEntityObject+SOGo.m - this file is part of SOGo
*
* Copyright (C) 2007-2014 Inverse inc.
*
* This file 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, or (at your option)
* any later version.
*
* This file 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#import <Foundation/NSArray.h>
#import <Foundation/NSCalendarDate.h>
+2 -4
View File
@@ -1,8 +1,6 @@
/* iCalToDo+SOGo.h - this file is part of SOGo
*
* Copyright (C) 2007 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2007-2014 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,7 +27,7 @@
@interface iCalToDo (SOGoExtensions)
- (NSMutableDictionary *) quickRecord;
- (NSMutableDictionary *) quickRecordForContainer: (id) theContainer;
@end
+3 -6
View File
@@ -1,9 +1,6 @@
/* iCalEvent+SOGo.m - this file is part of SOGo
/* iCalToDot+SOGo.m - this file is part of SOGo
*
* Copyright (C) 2008 Inverse inc.
* Copyright (C) 2004-2005 SKYRIX Software AG
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2008-2014 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -41,7 +38,7 @@
@implementation iCalToDo (SOGoExtensions)
- (NSMutableDictionary *) quickRecord
- (NSMutableDictionary *) quickRecordForContainer: (id) theContainer
{
NSMutableDictionary *row;
NSCalendarDate *startDate, *dueDate, *nextAlarmDate;
@@ -1 +1,2 @@
"Personal Address Book" = "Llibreta personal d'adreces";
"Collected Address Book" = "Llibreta d'adreces recopilades";
@@ -1 +1,2 @@
"Personal Address Book" = "Persoonlijk adresboek";
"Collected Address Book" = "Verzamelde adressen";
@@ -1 +1,2 @@
"Personal Address Book" = "Henkilökohtainen osoitekirja";
"Collected Address Book" = "Kerätty osoitekirja";
@@ -1 +1,2 @@
"Personal Address Book" = "Persönliches Adressbuch";
"Collected Address Book" = "Gesammelte Adressen";
+50
View File
@@ -24,9 +24,12 @@
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSString.h>
#import <NGExtensions/NSNull+misc.h>
#import <NGCards/NSArray+NGCards.h>
#import <NGCards/NSString+NGCards.h>
#import <SOGo/NSArray+Utilities.h>
#import <SOGo/NSCalendarDate+SOGo.h>
#import "NSDictionary+LDIF.h"
@@ -788,4 +791,51 @@ convention:
return date;
}
- (NSMutableDictionary *) quickRecordForContainer: (id) theContainer
{
NSMutableDictionary *fields;
CardElement *element;
NSString *value;
NSArray *v;
fields = [NSMutableDictionary dictionaryWithCapacity: 16];
value = [self fn];
if (value)
[fields setObject: value forKey: @"c_cn"];
element = [self n];
[fields setObject: [element flattenedValueAtIndex: 0 forKey: @""]
forKey: @"c_sn"];
[fields setObject: [element flattenedValueAtIndex: 1 forKey: @""]
forKey: @"c_givenName"];
value = [self preferredTel];
if (value)
[fields setObject: value forKey: @"c_telephonenumber"];
value = [self preferredEMail];
if (![value isNotNull])
value = @"";
[fields setObject: value forKey: @"c_mail"];
element = [self org];
[fields setObject: [element flattenedValueAtIndex: 0 forKey: @""]
forKey: @"c_o"];
[fields setObject: [element flattenedValueAtIndex: 1 forKey: @""]
forKey: @"c_ou"];
element = [self preferredAdr];
if (element && ![element isVoid])
[fields setObject: [element flattenedValueAtIndex: 3
forKey: @""]
forKey: @"c_l"];
value = [[self uniqueChildWithTag: @"X-AIM"] flattenedValuesForKey: @""];
[fields setObject: value forKey: @"c_screenname"];
v = [[self categories] trimmedComponents];
if ([v count] > 0)
[fields setObject: [v componentsJoinedByString: @","]
forKey: @"c_categories"];
else
[fields setObject: [NSNull null] forKey: @"c_categories"];
[fields setObject: @"vcard" forKey: @"c_component"];
return fields;
}
@end /* NGVCard */
+1 -3
View File
@@ -1,8 +1,6 @@
/* NGVCard+SOGo.h - this file is part of SOGo
*
* Copyright (C) 2009 Inverse inc.
*
* Author: Cyril Robert <crobert@inverse.ca>
* Copyright (C) 2009-2014 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
+16 -3
View File
@@ -1,8 +1,6 @@
/* NGVCard+SOGo.m - this file is part of SOGo
*
* Copyright (C) 2009 Inverse inc.
*
* Author: Cyril Robert <crobert@inverse.ca>
* Copyright (C) 2009-2014 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -71,4 +69,19 @@
return rc;
}
- (NSMutableDictionary *) quickRecordForContainer: (id) theContainer
{
NSMutableDictionary *fields;
NSString *value;
fields = [NSMutableDictionary dictionaryWithCapacity: 1];
value = [self fn];
if (value)
[fields setObject: value forKey: @"c_cn"];
[fields setObject: @"vlist" forKey: @"c_component"];
return fields;
}
@end /* NGVList */
@@ -1 +1,2 @@
"Personal Address Book" = "Personlig adressebok";
"Collected Address Book" = "Samlet addressebok";
@@ -1,2 +1,2 @@
"Personal Address Book" = "Osobista książka adresowa";
"Collected Address Book" = "Zbierana Książka Adresowa";
"Collected Address Book" = "Książka zebranych adresów";
+26 -7
View File
@@ -48,6 +48,11 @@
[super dealloc];
}
- (Class *) parsingClass
{
return [NGVCard class];
}
/* content */
- (NGVCard *) vCard
@@ -121,11 +126,25 @@
newContact = [[self class] objectWithName:
[NSString stringWithFormat: @"%@.vcf", newUID]
inContainer: newFolder];
inContainer: newFolder];
return [newContact saveContentString: [newCard versitString]];
return [newContact saveComponent: newCard];
}
- (NSException *) moveToFolder: (SOGoGCSFolder *) newFolder
{
NSException *ex;
ex = [self copyToFolder: newFolder];
if (!ex)
ex = [self delete];
return ex;
}
- (NSString *) displayName
{
return [[self vCard] fn];
@@ -150,7 +169,7 @@
NSException *result;
if (card)
result = [self saveContentString: [card versitString]];
result = [super saveComponent: card];
else
result = nil; /* TODO: we should probably return an exception instead */
@@ -160,15 +179,15 @@
- (NSException *) saveComponent: (NGVCard *) newCard
{
ASSIGN(card, newCard);
return [self save];
return [super saveComponent: newCard];
}
- (NSException *) saveContentString: (NSString *) newContent
baseVersion: (unsigned int) newVersion
- (NSException *) saveComponent: (NGVCard *) newCard
baseVersion: (unsigned int) newVersion
{
NSException *ex;
ex = [super saveContentString: newContent baseVersion: newVersion];
ex = [super saveComponent: newCard baseVersion: newVersion];
[card release];
card = nil;
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (C) 2006-2011 Inverse inc.
Copyright (C) 2006-2014 Inverse inc.
Copyright (C) 2004-2005 SKYRIX Software AG
This file is part of SOGo.
+21 -5
View File
@@ -1,8 +1,6 @@
/* SOGoContactGCSList.m - this file is part of SOGo
*
* Copyright (C) 2008-2009 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2008-2014 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -45,6 +43,12 @@
[super dealloc];
}
- (Class *) parsingClass
{
return [NGVList class];
}
/* content */
- (NGVList *) vList
@@ -77,7 +81,19 @@
[NSString stringWithFormat: @"%@.vlf", newUID]
inContainer: newFolder];
return [newGList saveContentString: [newList versitString]];
return [newGList saveComponent: newList];
}
- (NSException *) moveToFolder: (SOGoGCSFolder *) newFolder
{
NSException *ex;
ex = [self copyToFolder: newFolder];
if (!ex)
ex = [self delete];
return ex;
}
/* DAV */
@@ -100,7 +116,7 @@
vlist = [self vList];
[self saveContentString: [vlist versitString]];
[self saveComponent: vlist];
}
@end
+2 -5
View File
@@ -1,9 +1,6 @@
/* SOGoContactLDIFEntry.m - this file is part of SOGo
*
* Copyright (C) 2006-2012 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Ludovic Marcotte <lmarcotte@inverse.ca>
* Copyright (C) 2006-2014 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -231,7 +228,7 @@
[NSString stringWithFormat: @"%@.vcf", newUID]
inContainer: newFolder];
return [newContact saveContentString: [newCard versitString]];
return [newContact saveComponent: newCard];
}
@end
@@ -1,2 +1,2 @@
"SieveFolderName" = "Filtres";
"OtherUsersFolderName" = "Altres usuaris";
"SharedFoldersName" = "Carpetes compartides";
+1 -1
View File
@@ -430,7 +430,7 @@
}
- (void) ignorableWhitespace: (unichar *) whitespaces
length: (int) length
length: (NSUInteger) length
{
showWhoWeAre();
}
Loaded 100 of 311 files, more files were not shown because too many files have changed in this diff. Show more