memotoo 1.0.6 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,19 +2,21 @@
2
2
 
3
3
  <b>This is not an official gem from the provider of memotoo !!!</b>
4
4
 
5
- The memotoo-gem is a soap(savon)-wrapper to (easy) access your {memotoo}[http://www.memotoo.com/index-saleshype.php] contacts.
5
+ The memotoo-gem is a soap(savon)-wrapper to (easy) access your {memotoo}[https://www.memotoo.com/index-saleshype.php] contacts.
6
6
 
7
- Add, get, search, modify and delete your memotoo contacts.
7
+ Add, get, search, modify and delete your memotoo contacts, contact-groups and bookmarks.
8
8
 
9
9
  == You need
10
10
  you need a memotoo-credential (username/passwd) to use this gem
11
11
 
12
- <b>get a free account here: {www.memotoo.com}[http://www.memotoo.com/index-saleshype.php]</b>
12
+ <b>get a free account here: {www.memotoo.com}[https://www.memotoo.com/index-saleshype.php]</b>
13
13
 
14
14
 
15
15
  ==Install
16
16
 
17
- if you use <b>bundler</b> add gem 'memotoo' to your Gemfile run
17
+ if you use <b>bundler</b> add
18
+ gem 'memotoo'
19
+ to your Gemfile run
18
20
  bundle install
19
21
  else put it in your <b>environment.rb</b> and run
20
22
  rake gems:install
@@ -23,6 +25,9 @@ else put it in your <b>environment.rb</b> and run
23
25
 
24
26
  give a first try in ./script/console
25
27
 
28
+ @connect=Memotoo.new("myusername","mypassword")
29
+
30
+ Changelog: (prev V 2.0 I wrapped it in a Module )
26
31
  @connect=Memotoo::Connect.new("myusername","mypassword")
27
32
 
28
33
  add a contact:
@@ -70,11 +75,44 @@ bookmarks:
70
75
  @connect.modifyBookmark({:id=>response[:id], :url=>"www.google.com", :description => "nice"})
71
76
 
72
77
  @connect.deleteBookmark(12345)
73
-
78
+
79
+
80
+ Requirements:
81
+
82
+ for the objects:
83
+
84
+ Contact:: :lastname
85
+ ContactGroup:: :name
86
+ Bookmark:: :url
87
+ BookmarkFolder:: :name
88
+ Note:: :description
89
+ CalendarCategory:: :name
90
+ Event:: :title, :dateBegin, :dateEnd
91
+ Holiday:: :description, :dateBegin, :dateEnd
92
+ Task:: :title
93
+
94
+ for the methods:
95
+
96
+ searchmethod:: {search=>" "}, a hash
97
+ id:: id of record, integer
98
+ get...Sync:: datetime, format YYYY-MM-DD HH:MM:SS - "2010-02-23 10:00:00"
99
+ modify:: id of record, integer
100
+ add and modify:: need always the object requirements
101
+
102
+ hint:
103
+
104
+ Holiday::
105
+ dateBegin:: "2011-01-01", Format: YYYY-MM-DD
106
+ dateEnd:: "2011-01-01", Format: YYYY-MM-DD
107
+
108
+ Task and Event::
109
+ dateBegin:: "2011-06-18T10:00:00", Format: YYYY-MM-DDTHH:II:SS - ISO8601 time format GMT
110
+ dateEnd:: "2011-06-18T10:00:00", Format: YYYY-MM-DDTHH:II:SS - ISO8601 time format GMT
111
+
74
112
  ==Testing
75
113
 
76
114
  I added tests for all implemented functions. (rcov 100%)
77
- You can add your own credential to /test/test_memotoo.rb
115
+ You can add your own credential to /test/helper.rb
78
116
 
79
117
  I also added support for {http://test.rubygems.org}[http://test.rubygems.org]
80
118
 
@@ -82,19 +120,35 @@ You can now use the gem rubygems-test for easy testing this gem.
82
120
 
83
121
  gem test memotoo
84
122
 
85
- See my testresult here: http://test.rubygems.org/gems/memotoo/v/1.0.6/test_results/1655
123
+ See my testresult here: http://test.rubygems.org/gems/memotoo/v/2.0.0/test_results/1663
124
+
125
+ (To make a fast functional test only contact will be tested - goto test_soapobjects.rb line 8 and uncomment for all soapobject-tests)
86
126
 
87
127
  ==Documentation
88
128
 
89
129
  see rdoc
90
130
 
91
- ==To-Dos
131
+ and memotoo api-documentation
132
+
133
+ https://www.memotoo.com/index.php?rub=api#SOAP-server.php
134
+
135
+ == Changelog V. 2.0.0
136
+
137
+ I create all methods now dynamically. This reduced the code dramatically.
138
+ I give up using a module to wrap the namespace. Now it's a class.
139
+
140
+ == Hint
141
+
142
+ Be careful with following methods due to a problem at memotoo's api:
143
+
144
+ searchBookmarkFolder:: (possible workaround: search for all -> " " and then go ahead)
92
145
 
93
- 1. Exception handling should be done - fetched problems are written to console
94
- 2. I only implemented contacts, contact's group and bookmark - these soap-objects are missing: bookmark's folder, event, holiday, task, note
146
+ getHoliday:: (possible workaround: search and use the result)
147
+ getHolidaySync (no workaround known)
95
148
 
96
- It would be nice if *someone* could help me with the missing parts .
149
+ All three methods seems not to be really important - just fyi
97
150
 
151
+ I will remove this hint when the soap-api is repaired.
98
152
 
99
153
  == Contributing to memotoo-gem
100
154
 
data/Rakefile CHANGED
@@ -15,7 +15,16 @@ Jeweler::Tasks.new do |gem|
15
15
  gem.homepage = "http://github.com/kredmer/memotoo"
16
16
  gem.license = "MIT"
17
17
  gem.summary = "Unofficial gem for connecting to memotoo.com with their given soap-api"
18
- gem.description = "Unofficial gem for connecting to memotoo.com with their soap-api and handle your contact needs. Memotoo lets your synchronize all your contacts, events and tasks with yahoo, gmail, facebook, xing, outlook, your mobile-phone and more. You can also get your e-mails in one place."
18
+ gem.description = "Unofficial gem for connecting to memotoo.com with their soap-api and handle your contact needs. Memotoo lets your synchronize all your contacts, events and tasks with yahoo, gmail, facebook, xing, outlook, your mobile-phone and more. You can also get your e-mails in one place.Features of memotoo:
19
+ New mobile? Transfer all your data to your new device!
20
+ Synchronise your data with your mobile phone (with SyncML)
21
+ Access all your e-mail in a single page from Google, Yahoo, Hotmail / MSN, ...!
22
+ View your data on your mobile phone (WAP / XHTML)
23
+ Access your contacts using a LDAP directory
24
+ Access your files via a Web Folder
25
+ Access your files via FTP
26
+ Add Memotoo widgets to iGoogle, Netvibes, Windows Vista, Apple Dashboard, ...
27
+ Memotoo plugins for your browser"
19
28
  gem.email = "k.redmer@yahoo.de"
20
29
  gem.authors = ["Karsten Redmer"]
21
30
  gem.add_dependency 'savon'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.6
1
+ 2.0.0
@@ -1,8 +1,75 @@
1
- require "memotoo/connect"
2
1
  require 'rubygems'
3
2
  require 'active_support/inflector'
3
+ require "savon"
4
+ require "memotoo/main"
5
+ require "memotoo/core-ext/hash"
6
+ require "memotoo/core-ext/kernel"
4
7
 
8
+ class Memotoo
5
9
 
6
- module Memotoo
10
+ # will hold username and password in a hash style (used for all requests)
11
+ attr_accessor :opts #:nodoc:
12
+
13
+ SEARCHDEFAULTS = { :limit_start => '0', :limit_nb => '100' }
14
+
15
+ # requirement for the objects - for validation
16
+ NEEDS = { :contact => [:lastname],
17
+ :contact_group => [:name],
18
+ :bookmark => [:url],
19
+ :bookmark_folder => [:name],
20
+ :note => [:description],
21
+ :calendar_category => [:name],
22
+ :event => [:title, :dateBegin, :dateEnd],
23
+ :holiday => [:description, :dateBegin, :dateEnd],
24
+ :task => [:title]}
25
+
26
+ #[https] default:true for the SOAP service. Use false to use http-connection
27
+ # example:(use https)
28
+ # @connect=Memotoo::Connect.new("myusername","mypassword")
29
+ # example:(use http)
30
+ # @connect=Memotoo::Connect.new("myusername","mypassword", false)
31
+ def initialize(username, password, https=true)
7
32
 
33
+ # we will need it for every request - will be merged in
34
+ self.opts= { :param => { :login => username, :password => password}}
35
+
36
+ # build dynamically all methods - some magic :-)
37
+ make_methods
38
+
39
+ # creates client with memotoo settings
40
+ client(https)
41
+ end
8
42
  end
43
+
44
+ # stop savon logging
45
+
46
+ module Savon # :nodoc: all
47
+ module Global
48
+ def log?
49
+ false
50
+ end
51
+ def raise_errors?
52
+ @raise_errors = true
53
+ end
54
+
55
+ end
56
+ end
57
+
58
+ #Finished in 12.361502 seconds.
59
+
60
+ #14 tests, 14 assertions, 0 failures, 0 errors
61
+ #+----------------------------------------------------+-------+-------+--------+
62
+ #| File | Lines | LOC | COV |
63
+ #+----------------------------------------------------+-------+-------+--------+
64
+ #|lib/memotoo.rb | 59 | 34 | 100.0% |
65
+ #|lib/memotoo/core-ext/hash.rb | 41 | 25 | 100.0% |
66
+ #|lib/memotoo/core-ext/kernel.rb | 10 | 6 | 100.0% |
67
+ #|lib/memotoo/main.rb | 280 | 77 | 100.0% |
68
+ #+----------------------------------------------------+-------+-------+--------+
69
+ #|Total | 390 | 142 | 100.0% |
70
+ #+----------------------------------------------------+-------+-------+--------+
71
+ #100.0% 4 file(s) 390 Lines 142 LOC
72
+
73
+ #Generated on Sun Jun 12 07:03:59 +0200 2011 with rcov 0.9.8
74
+
75
+
@@ -26,8 +26,8 @@ class Hash # :nodoc: all
26
26
 
27
27
  # Returns a new Hash with +self+ and +other_hash+ merged recursively.
28
28
  # Modifies the receiver in place.
29
- # => already in savon gem
30
- # => in case a time come and it will be away - just uncomment it
29
+ # => see this function also in savon gem
30
+ # got problems in my test and had to include it here...
31
31
  def deep_merge_me!(other_hash)
32
32
  other_hash.each_pair do |k,v|
33
33
  tv = self[k]
@@ -1,4 +1,4 @@
1
- module Kernel
1
+ module Kernel # :nodoc: all
2
2
  private
3
3
  # def this_method
4
4
  # caller[0] =~ /`([^']*)'/ and $1
@@ -0,0 +1,280 @@
1
+ class Memotoo
2
+
3
+ private
4
+
5
+ # Creates the <tt>Savon::Client</tt>.
6
+ def client(https=true)
7
+ #--
8
+ # in any case problems switch back to receiving the wsdl file from memotoo
9
+ # https: wsdl.document = "https://www.memotoo.com/SOAP-server.php?wsdl"
10
+ # http: wsdl.document = "http://www.memotoo.com/SOAP-server.php?wsdl"
11
+ #++
12
+
13
+ @client ||= Savon::Client.new do
14
+ wsdl.namespace="urn:memotooSoap"
15
+ if https
16
+ wsdl.endpoint="https://www.memotoo.com/SOAP-server.php"
17
+ http.auth.ssl.verify_mode = :none
18
+ else
19
+ wsdl.endpoint="http://www.memotoo.com/SOAP-server.php"
20
+ end
21
+ http.auth.basic self.opts[:param][:login], self.opts[:param][:password]
22
+ end
23
+ end
24
+
25
+ def selfclass
26
+ (class << self; self; end)
27
+ end
28
+
29
+ # builds for every soap-object six methods (add, search, get, get..Sync,modify, delete )
30
+ # on-the-fly :-)
31
+ def make_methods
32
+
33
+ # the accessible soap objects
34
+ soapobjects = %w{Contact ContactGroup Bookmark BookmarkFolder Note CalendarCategory Event Holiday Task}
35
+
36
+ soapobjects.each do |soapobject|
37
+ symbol=soapobject.underscore.to_sym
38
+
39
+ # add method
40
+ methodname="add"+soapobject
41
+ selfclass.send(:define_method, methodname) { |details| output(detailsApicall({symbol => details}), :id) if fields?(details, NEEDS[symbol]) }
42
+
43
+ # search
44
+ methodname="search"+soapobject
45
+ selfclass.send(:define_method, methodname) { |params| output(searchApiCall(params), :return, symbol) if fields?(params, [:search]) }
46
+
47
+ # get
48
+ methodname="get"+soapobject
49
+ selfclass.send(:define_method, methodname) { |id| output(idApicall(id), :return, symbol) }
50
+
51
+ # get...Sync
52
+ methodname="get"+soapobject+"Sync"
53
+ selfclass.send(:define_method, methodname) { |datetime| output(getSyncApiCall(datetime), :return, symbol) }
54
+
55
+ # modify
56
+ methodname="modify"+soapobject
57
+ selfclass.send(:define_method, methodname) { |details| output(detailsApicall({symbol => details}), :ok) if fields?(details, [NEEDS[symbol], :id].flatten!) }
58
+
59
+ # delete
60
+ methodname="delete"+soapobject
61
+ selfclass.send(:define_method, methodname) { |id| output(idApicall(id), :ok) }
62
+
63
+ end
64
+ end
65
+
66
+ def searchApiCall(searchparameter)
67
+ search = SEARCHDEFAULTS.merge!(searchparameter)
68
+ apicall(calling_method.to_sym, search)
69
+ end
70
+
71
+ def getSyncApiCall(datetime)
72
+ date2time=Time.mktime(*ParseDate.parsedate(datetime))
73
+ formated_date=date2time.strftime("%Y-%m-%d %H:%M:%S")
74
+ apicall(calling_method.to_sym, { :date => formated_date })
75
+ end
76
+
77
+ def idApicall(id)
78
+ apicall(calling_method.to_sym, { :id => id })
79
+ end
80
+
81
+ def detailsApicall(details)
82
+ apicall(calling_method.to_sym, details )
83
+ end
84
+
85
+ # used internally for a request
86
+ def apicall(action, parameter)
87
+ response=@client.request :wsdl, action do
88
+ soap.body = { :param => parameter }.deep_merge_me!(self.opts)
89
+ end
90
+ response
91
+ rescue Savon::Error => error
92
+ raise ArgumentError, "Memotoo::Connect #invalid username/password" if error.message.nil?
93
+ end
94
+
95
+ def output(response, *_keys_)
96
+ output_key = [(calling_method.underscore+"_response").to_sym] | _keys_
97
+ response.nil? ? nil : response.to_hash.seek(output_key)
98
+ end
99
+
100
+ def go_home(message)
101
+ raise ArgumentError, "Memotoo::Connect #missing fields: " + message.to_s
102
+ end
103
+
104
+ def fields?(thehash, args=[])
105
+ valid=true
106
+ retarr=[]
107
+ args.each do |arg_item|
108
+ unless thehash.has_key?(arg_item)
109
+ valid = false
110
+ retarr << arg_item
111
+ end
112
+ end
113
+ valid ? true : go_home(retarr.join(", "))
114
+ end
115
+
116
+ # ---------------------
117
+ # :section: memotoo soap actions
118
+ # === bookmark - ready implemented
119
+ # * searchBookmark(searchparams={})
120
+ # * addBookmark(params={})
121
+ # * getBookmark(id)
122
+ # * getBookmarkSync(datetime)
123
+ # * modifyBookmark(params={})
124
+ # * deleteBookmark(id)
125
+ #
126
+ # === bookmarkfolder - ready implemented - API problem with search
127
+ # * searchBookmarkFolder(searchparams={})
128
+ # * addBookmarkFolder(params={})
129
+ # * getBookmarkFolder(id)
130
+ # * getBookmarkFolderSync(datetime)
131
+ # * modifyBookmarkFolder(params={})
132
+ # * deleteBookmarkFolder(id)
133
+ #
134
+ # === calendar_category - ready implemented
135
+ # * searchCalendarCategory
136
+ # * addCalendarCategory
137
+ # * getCalendarCategory
138
+ # * getCalendarCategorySync
139
+ # * modifyCalendarCategory
140
+ # * deleteCalendarCategory
141
+ #
142
+ # === contact - ready implemented
143
+ # * searchContact
144
+ # * add_contact
145
+ # * getContact
146
+ # * getContactSync
147
+ # * modifyContact
148
+ # * deleteContact
149
+ #
150
+ # === contact-group - ready implemented
151
+ # * searchContactGroup
152
+ # * addContactGroup
153
+ # * getContactGroup
154
+ # * getContactGroupSync
155
+ # * modifyContactGroup
156
+ # * deleteContactGroup
157
+ #
158
+ # === event - ready implemented
159
+ # * searchEvent
160
+ # * addEvent
161
+ # * getEvent
162
+ # * getEventSync
163
+ # * modifyEvent
164
+ # * deleteEvent
165
+ #
166
+ # === holiday - ready implemented - API problem with get and getSync
167
+ # * searchHoliday
168
+ # * addHoliday
169
+ # * getHoliday
170
+ # * getHolidaySync
171
+ # * modifyHoliday
172
+ # * deleteHoliday
173
+ #
174
+ # === note - ready implemented
175
+ # * searchNote
176
+ # * addNote
177
+ # * getNote
178
+ # * getNoteSync
179
+ # * modifyNote
180
+ # * deleteNote
181
+ #
182
+ # === task - ready implemented
183
+ # * searchTask
184
+ # * addTask
185
+ # * getTask
186
+ # * getTaskSync
187
+ # * modifyTask
188
+ # * deleteTask
189
+ #
190
+ # ---------------------
191
+
192
+ # ---------------------
193
+ # :section: Bookmark fields
194
+ #
195
+ # id:: "2531368"
196
+ # url(*):: "http://www.google.com"
197
+ # description:: "google"
198
+ # rank:: "0"
199
+ # tags:: nil
200
+ # id_bookmark_folder:: "363174"
201
+ # ---------------------
202
+
203
+ # ---------------------
204
+ # :section: BookmarkFolder fields
205
+ #
206
+ # id:: "2531368"
207
+ # name(*):: "Download applications"
208
+ # id_bookmark_folder_parent:: "363174"
209
+ # ---------------------
210
+
211
+
212
+
213
+ # ---------------------
214
+ # :section: Contact fields
215
+ # all contacts fields
216
+ # :id
217
+ # :title => 'Mr.',
218
+ # :lastname => 'test',
219
+ # :firstname => 'user',
220
+ # :middlename => '',
221
+ # :nickname => 'bob',
222
+ # :suffix => '',
223
+ # :birthday => '1975-02-14', // Format YYYY-MM-DD
224
+ # :homeaddress => '',
225
+ # :homecity => 'new york',
226
+ # :homepostalcode => '',
227
+ # :homestate => '',
228
+ # :homecountry => 'usa',
229
+ # :homeemail => '',
230
+ # :homephone => '',
231
+ # :homemobile => '',
232
+ # :homefax => '',
233
+ # :homewebpage => '',
234
+ # :businessaddress => '',
235
+ # :businesscity => '',
236
+ # :businesspostalcode => '',
237
+ # :businessstate => '',
238
+ # :businesscountry => '',
239
+ # :businessemail => '',
240
+ # :businessphone => '',
241
+ # :businessmobile => '',
242
+ # :businessfax => '',
243
+ # :businesswebpage => '',
244
+ # :company => '',
245
+ # :department => '',
246
+ # :jobtitle => '',
247
+ # :notes => '',
248
+ # :otheraddress => '',
249
+ # :othercity => '',
250
+ # :otherpostalcode => '',
251
+ # :otherstate => '',
252
+ # :othercountry => '',
253
+ # :otheremail => '',
254
+ # :otherphone => '',
255
+ # :othermobile => '',
256
+ # :otherfax => '',
257
+ # :skypeid => '',
258
+ # :msnid => '',
259
+ # :aimid => '',
260
+ # :pager => '',
261
+ # :carphone => '',
262
+ # :managersname => '',
263
+ # :assistantsname => '',
264
+ # :assistantsphone => '',
265
+ # :parent => '',
266
+ # :spouse => '',
267
+ # :children => '',
268
+ # :custom1 => '',
269
+ # :custom2 => '',
270
+ # :custom3 => '',
271
+ # :custom4 => '',
272
+ # :group => '0',
273
+ # :photo => '', // Photo encoded with Base64
274
+ # ---------------------
275
+
276
+ end
277
+
278
+
279
+
280
+