public
Description: A small, yet powerful, gem to interface with Flickr photostreams
Homepage: http://sneaq.net/tag/fleakr
Clone URL: git://github.com/reagent/fleakr.git
fleakr / README.rdoc
72d796e9 » reagent 2008-12-05 Added RDoc to source files ... 1 = Fleakr
866e035c » reagent 2008-11-02 Initial commit 2
72d796e9 » reagent 2008-12-05 Added RDoc to source files ... 3 == Description
866e035c » reagent 2008-11-02 Initial commit 4
40d146cc » reagent 2009-01-01 Updated main README file wi... 5 A small, yet powerful, gem to interface with Flickr photostreams
866e035c » reagent 2008-11-02 Initial commit 6
72d796e9 » reagent 2008-12-05 Added RDoc to source files ... 7 == Installation
866e035c » reagent 2008-11-02 Initial commit 8
949a07b8 » reagent 2008-12-11 Update documentation 9 === Stable
10
11 sudo gem install fleakr
12
13 === Bleeding Edge
14
caa37c17 » reagent 2008-11-29 Updated README file to incl... 15 $ git clone git://github.com/reagent/fleakr.git
16 $ cd fleakr
17 $ rake gem && sudo gem install pkg/fleakr-<version>.gem
866e035c » reagent 2008-11-02 Initial commit 18
72d796e9 » reagent 2008-12-05 Added RDoc to source files ... 19 == Usage
866e035c » reagent 2008-11-02 Initial commit 20
40d146cc » reagent 2009-01-01 Updated main README file wi... 21 To get started, you'll need to grab an API key from Flickr to at least perform any of
22 the non-authenticated, read-only calls. Head on over to the Flickr site to grab one, I'll
23 be here when you get back: http://www.flickr.com/services/api/misc.api_keys.html
caa37c17 » reagent 2008-11-29 Updated README file to incl... 24
40d146cc » reagent 2009-01-01 Updated main README file wi... 25 Now that you have your key, you can get things rolling with irb and the fleakr gem:
caa37c17 » reagent 2008-11-29 Updated README file to incl... 26
40d146cc » reagent 2009-01-01 Updated main README file wi... 27 $ irb -r rubygems
28 >> require 'fleakr'
29
caa37c17 » reagent 2008-11-29 Updated README file to incl... 30 Then, set your API key (only need to do this once per session):
31
0121127a » reagent 2008-12-05 Update README to reflect AP... 32 >> Fleakr.api_key = '<your api key here>'
40d146cc » reagent 2009-01-01 Updated main README file wi... 33
34 === A Brief Tour
35
36 With just an API key, you have the ability to retrieve a substantial amount of data
37 about users, their photosets, photos, contacts, and groups. Let's start by finding a
38 user by his username:
caa37c17 » reagent 2008-11-29 Updated README file to incl... 39
0121127a » reagent 2008-12-05 Update README to reflect AP... 40 >> user = Fleakr.user('the decapitator')
41 => #<Fleakr::Objects::User:0x692648 @username="the decapitator", @id="21775151@N06">
caa37c17 » reagent 2008-11-29 Updated README file to incl... 42
873a83ec » reagent 2009-10-18 Added collection support, U... 43 By email:
1c69d9ad » reagent 2008-12-02 Updated documentation to re... 44
0121127a » reagent 2008-12-05 Update README to reflect AP... 45 >> user = Fleakr.user('user@host.com')
46 => #<Fleakr::Objects::User:0x11f484c @username="bckspcr", @id="84481630@N00">
873a83ec » reagent 2009-10-18 Added collection support, U... 47
48 Or even by URL:
49
50 >> user = Fleakr.user('http://www.flickr.com/photos/the_decapitator/')
51 => #<Fleakr::Objects::User:0x113440c @username="the decapitator", @id="21775151@N06">
1c69d9ad » reagent 2008-12-02 Updated documentation to re... 52
53 Once you have a user, you can find his associated sets:
caa37c17 » reagent 2008-11-29 Updated README file to incl... 54
55 >> user.sets
0121127a » reagent 2008-12-05 Update README to reflect AP... 56 => [#<Fleakr::Objects::Set:0x671358 @title="The Decapitator", @description="">,
57 #<Fleakr::Objects::Set:0x66d898 @title="londonpaper hijack", ...
eaeea626 » reagent 2008-11-29 Updated example; removed TO... 58
40d146cc » reagent 2009-01-01 Updated main README file wi... 59 His individual photos:
60
61 >> user.photos.first
62 => #<Fleakr::Objects::Photo:0x161b024 @title="\"Be Fabulous\"" ... >
63
949a07b8 » reagent 2008-12-11 Update documentation 64 Or contacts:
65
66 >> user.contacts.first
67 => #<Fleakr::Objects::User:0x19039bc @username=".schill",
68 @id="12289718@N00", @icon_farm="1", @icon_server="4">
69
40d146cc » reagent 2009-01-01 Updated main README file wi... 70 Or his groups if you would like:
1614c050 » reagent 2008-11-30 Updated README to reflect g... 71
72 >> user.groups
0121127a » reagent 2008-12-05 Update README to reflect AP... 73 => [#<Fleakr::Objects::Group:0x11f2330 ...,
74 #<Fleakr::Objects::Group:0x11f2308 ...
1614c050 » reagent 2008-11-30 Updated README to reflect g... 75 >> user.groups.first.name
76 => "Rural Decay"
77 >> user.groups.first.id
78 => "14581414@N00"
79
949a07b8 » reagent 2008-12-11 Update documentation 80 Groups also contain photos:
81
431269e9 » reagent 2008-12-11 Correct typo in README docu... 82 >> user.groups.last.photos.first.title
949a07b8 » reagent 2008-12-11 Update documentation 83 => "Welcome To The Machine"
84
1c69d9ad » reagent 2008-12-02 Updated documentation to re... 85 When accessing a set, you can also grab all the photos that are in that set:
11978883 » reagent 2008-11-29 Update examples in document... 86
87 >> user.sets.first
0121127a » reagent 2008-12-05 Update README to reflect AP... 88 => #<Fleakr::Objects::Set:0x1195bbc @title="The Decapitator", @id="72157603480986566", @description="">
11978883 » reagent 2008-11-29 Update examples in document... 89 >> user.sets.first.photos.first
0121127a » reagent 2008-12-05 Update README to reflect AP... 90 => #<Fleakr::Objects::Photo:0x1140108 ... >
11978883 » reagent 2008-11-29 Update examples in document... 91 >> user.sets.first.photos.first.title
92 => "Untitled1"
7223202d » reagent 2009-07-20 Update documentation 93
94 === Contacts
95
96 Besides pulling back a given user's public contacts list, you can also retrieve the list of
97 contacts for the currently authenticated user (see below about authentication). For example,
98 you can retrieve all contacts:
99
100 >> Fleakr.contacts
101 => [#<Fleakr::Objects::Contact:0x111ff84 @username="bryan.ray" ...>]
102
103 Or just the contacts marked as 'family':
104
105 >> Fleakr.contacts(:family)
106 => [#<Fleakr::Objects::Contact:0x12db42c @username="Grandbob" ...>]
107
108 Or a specific page of contacts marked as 'friends':
1c69d9ad » reagent 2008-12-02 Updated documentation to re... 109
7223202d » reagent 2009-07-20 Update documentation 110 >> Fleakr.contacts(:friends, :page => 3, :per_page => 5)
111 => [#<Fleakr::Objects::Contact:0x12a6c54 @username="Louise and BCG" ...>]
112
113 See the documentation for Fleakr.contacts for what options are available.
114
40d146cc » reagent 2009-01-01 Updated main README file wi... 115 === Photos
116
117 Each photo object contains metadata about a collection of images, each representing different
118 sizes. Once we have a single photo:
119
120 >> photo = user.photos.first
121 => #<Fleakr::Objects::Photo:0x161b024 @title="\"Be Fabulous\"" ... >
122
123 We can get information about one of the sizes:
124
125 >> photo.small
126 => #<Fleakr::Objects::Image:0x1768f1c @height="172", @size="Small", @width="240",
127 @url="http://farm4.static.flickr.com/3250/2924549350_cbc1804258_m.jpg",
128 @page="http://www.flickr.com/photos/the_decapitator/2924549350/sizes/s/">
129
130 Grab the URL for the image itself:
131
132 >> photo.small.url
133 => "http://farm4.static.flickr.com/3250/2924549350_cbc1804258_m.jpg"
134
135 Or grab the URL for its page on the Flickr site:
136
137 >> photo.small.page
138 => "http://www.flickr.com/photos/the_decapitator/2924549350/sizes/s/"
139
140 Other sizes are available (:square, :thumbnail, :small, :medium, :large, :original) and
141 are accessed in the same way:
142
143 >> photo.original.url
3c110520 » reagent 2009-04-11 Update documentation for re... 144 => "http://farm4.static.flickr.com/3250/2924549350_1cf67c2d47_o.jpg"
145
146 === Tags
147
148 Tags are available for users and photos. Retrieving them is easy:
149
150 >> user = Fleakr.user('the decapitator')
151 >> user.tags
152 => [#<Fleakr::Objects::Tag:0x190d5fc @value="ad">,
153 #<Fleakr::Objects::Tag:0x1908a20 @value="ads">, ...
154 >> user.photos.first.tags
155 => [#<Fleakr::Objects::Tag:0x17b1b18 @machine_flag="0", @author_id="21775151@N06", ...
156
157 All tags have values, but for tags associated with photos there is some additional information:
158
159 >> tag = user.photos.first.tags.first
160 >> tag.id
161 => "21729829-3263659141-427098"
162 >> tag.raw
163 => "decapitator"
164 >> tag.value
165 => "decapitator"
166 >> tag.to_s
167 => "decapitator"
168 >> tag.machine?
169 => false
170 >> tag.author
171 => #<Fleakr::Objects::User:0x1a149f0 @username="the decapitator", ... >
172
c089296c » reagent 2009-04-11 Add information about relat... 173 Each tag can also have related tags:
174
175 >> user.photos.first.tags[1].related.first.related.first.to_s
176 => "face"
177
178 You get the idea - see Fleakr::Objects::Tag for more information.
3c110520 » reagent 2009-04-11 Update documentation for re... 179
180 === Comments
181
182 Similar to tags, photosets and photos can each have comments:
183
184 >> user.sets.first.comments
185 => [#<Fleakr::Objects::Comment:0x19795cc ...
186 >> user.photos.first.comments
187 => [#<Fleakr::Objects::Comment:0x17bf0b0 @body="Dayum, that's some wishful thinking!" ...
188
189 All comments have additional information:
190
191 >> comment = user.photos.first.comments.first
192 >> comment.id
193 => "21729829-3263659141-72157613553885978"
194 >> comment.body
195 => "Dayum, that's some wishful thinking!"
196 >> comment.to_s
197 => "Dayum, that's some wishful thinking!"
198 >> comment.url
199 => "http://www.flickr.com/photos/the_decapitator/3263659141/#comment72157613553885978"
200 >> comment.author
201 => #<Fleakr::Objects::User:0x178e3d4 @username="jaspertandy", ... >
202
203 See Fleakr::Objects::Comment for more information.
40d146cc » reagent 2009-01-01 Updated main README file wi... 204
873a83ec » reagent 2009-10-18 Added collection support, U... 205 === Collections
206
207 An individual can have zero or more collections associated with his account. These collections,
208 in turn, can have either collections or sets associated with them. For example:
209
210 >> user = Fleakr.user('username')
211 >> user.collections.length
212 => 1
213 >> user.collections.first.title
214 => "The Year in Pictures"
215 >> user.collections.first.collections.length
216 => 2
217 >> user.collections.first.collections.first.sets.length
218 => 3
219 >> user.collections.first.collections.first.sets.first.title
220 => "A Trip to Yosemite"
221
222 Note that collections are limited to Flickr pro members. See Fleakr::Objects::Collection for more
223 information.
224
40d146cc » reagent 2009-01-01 Updated main README file wi... 225 === Saving Images
226
1c69d9ad » reagent 2008-12-02 Updated documentation to re... 227 If a photo interests you, save it down to a directory of your choosing:
228
40d146cc » reagent 2009-01-01 Updated main README file wi... 229 >> photo.original.save_to('/tmp')
230 => #<File:/tmp/2924549350_1cf67c2d47_o.jpg (closed)>
1c69d9ad » reagent 2008-12-02 Updated documentation to re... 231
40d146cc » reagent 2009-01-01 Updated main README file wi... 232 Similarly, you can save down entire sets. Just specify the target directory and the size
233 of the images you're interested in:
1c69d9ad » reagent 2008-12-02 Updated documentation to re... 234
235 >> user.sets.first.save_to('/tmp', :square)
0121127a » reagent 2008-12-05 Update README to reflect AP... 236 => [#<Fleakr::Objects::Photo:0x1187a1c @secret="715587b2cb" ...
40d146cc » reagent 2009-01-01 Updated main README file wi... 237
238 This creates a subdirectory within the target directory based on the set's name and preserves
239 the original order of the photos:
240
1c69d9ad » reagent 2008-12-02 Updated documentation to re... 241 >> Dir["/tmp/#{user.sets.first.title}/*.jpg"].map
40d146cc » reagent 2009-01-01 Updated main README file wi... 242 => ["/tmp/The Decapitator/01_2117922283_715587b2cb_s.jpg",
243 "/tmp/The Decapitator/02_2125604584_9c09348fd6_s.jpg",
244 "/tmp/The Decapitator/03_2118696542_8af5763bde_s.jpg", ... ]
245
246 === Searching
11978883 » reagent 2008-11-29 Update examples in document... 247
ac1e3263 » reagent 2008-12-02 Updated docs to reflect sea... 248 If you would prefer to just search photos, you can do that with search text:
237efab4 » reagent 2008-12-01 Added documentation for sea... 249
949a07b8 » reagent 2008-12-11 Update documentation 250 >> photos = Fleakr.search('ponies!!')
0121127a » reagent 2008-12-05 Update README to reflect AP... 251 => [#<Fleakr::Objects::Photo:0x11f4e64 @title="hiroshima atomic garden", @id="3078234390">,
252 #<Fleakr::Objects::Photo:0x11f4928 @title="PONYLOV", @id="3077360853">, ...
949a07b8 » reagent 2008-12-11 Update documentation 253 >> photos.first.title
ac1e3263 » reagent 2008-12-02 Updated docs to reflect sea... 254 => "hiroshima atomic garden"
255
256 You can also search based on tags:
257
949a07b8 » reagent 2008-12-11 Update documentation 258 >> photos = Fleakr.search(:tags => 'macro')
259 >> photos.first.title
9c782f33 » reagent 2008-12-01 Fixed README formatting 260 => "Demure"
949a07b8 » reagent 2008-12-11 Update documentation 261 >> photos.first.id
9c782f33 » reagent 2008-12-01 Fixed README formatting 262 => "3076049945"
237efab4 » reagent 2008-12-01 Added documentation for sea... 263
949a07b8 » reagent 2008-12-11 Update documentation 264 Searches can also be scoped to other entities in the system (namely Users and Groups):
265
266 >> user.groups.first.search('awesome')
267 => [#<Fleakr::Objects::Photo:0x18cb4cc @server_id="2012", @id="2181921273",
268 @farm_id="3", @title="", @secret="634eda7521">, ...
269 >> user.search('serpent')
270 => [#<Fleakr::Objects::Photo:0x18a6960 @server_id="41", @id="81370156",
271 @farm_id="1", @title="Clear and Serpent Danger", @secret="013091582a">]
866e035c » reagent 2008-11-02 Initial commit 272
0e8b2f03 » reagent 2009-03-03 Update documentation to ref... 273 === Uploading Files
274
275 Before you can upload files, you need to be able to make authenticated calls to the Flickr
276 API. Skip to the next section (Authenticated Calls) for details on how to make this work.
277
278 Uploading single files is simple:
279
280 >> Fleakr.upload('/path/to/image.jpg')
281 => [#<Fleakr::Objects::Photo:0x217fb54 @updated="1236133594", @server_id="3266", ...>]
282
283 Notice that the newly-uploaded image is returned. You can further inspect / modify this as
284 necessary. The real magic is in uploading multiple files - the upload method takes a file
285 glob:
286
287 >> Fleakr.upload('/path/to/images/*.jpg')
288 => [#<Fleakr::Objects::Photo:0x217faa0 ...>,
289 #<Fleakr::Objects::Photo:0x212fb18 ...>,
290 #<Fleakr::Objects::Photo:0x20e09c8 ...>]
291
292 You can also set options on the file(s) that you're uploading:
293
294 >> Fleakr.upload('/path/to/party/images/*.jpg', :viewable_by => :everyone,
295 :title => 'Party Pics')
296
297 The full list of options can be found in the Fleakr::Objects::Photo documentation.
298
299 === Authenticated Calls
40d146cc » reagent 2009-01-01 Updated main README file wi... 300
301 While read-only access to the API gets you quite a bit of data, you'll need to generate an
302 authentication token if you want access to the more powerful features (like uploading your
303 own photos).
304
af9b5b9c » reagent 2009-10-25 Update documentation to ref... 305 Depending on how you intend to use the Flickr API, there are 2 methods for performing
306 authenticated calls.
307
308 === Single User
309
310 You'll need to configure your API key to to use Mobile authentication. If you're viewing your
311 list of keys on the Flickr site, click on the 'Edit key details' link and ensure that:
40d146cc » reagent 2009-01-01 Updated main README file wi... 312
313 1. Your application description and notes are up-to-date
314 1. The value for 'Authentication Type' is set to 'Mobile Application'
315 1. The value for 'Mobile Permissions' is set to either 'write' or 'delete'
316
317 Once this is set, you'll see your Authentication URL on the key details page (it will look
318 something like http://www.flickr.com/auth-534525246245). Paste this URL into your browser and
af9b5b9c » reagent 2009-10-25 Update documentation to ref... 319 confirm access to get your mini-token. Now you're ready to configure your authentication token:
40d146cc » reagent 2009-01-01 Updated main README file wi... 320
348b14c4 » reagent 2009-01-21 Document process for loggin... 321 Fleakr.api_key = 'ABC123'
322 Fleakr.shared_secret = 'sekrit' # Available with your key details on the Flickr site
af9b5b9c » reagent 2009-10-25 Update documentation to ref... 323
324 token = Fleakr.token_from_mini_token('294-585-410')
325 Fleakr.auth_token = token.value
326
348b14c4 » reagent 2009-01-21 Document process for loggin... 327 Fleakr.upload('/path/to/my/photo.jpg')
40d146cc » reagent 2009-01-01 Updated main README file wi... 328
af9b5b9c » reagent 2009-10-25 Update documentation to ref... 329 Once you use the mini-token once it is no longer available. To use the generated auth_token
330 for future requests, you'll need to make sure that you set the value permanently:
331
332 Fleakr.auth_token = '72157622657341094-41241e527f325abb'
333
334 === Multiple Users
335
336 If you need to have your application access other users photos on their behalf, you'll want to
337 use the Web authentication method. Edit your key details and make sure that:
338
339 1. Your application description and notes are up-to-date
340 1. The value for 'Authentication Type' is set to 'Web Application'
341 1. You configure your callback URL to point to something valid and accessible
342
343 Make sure that your key and secret are set as above. You can then begin the process by requesting
344 that the user authorize access to his Flickr account by redirecting to an authorization URL. I'm
345 assuming Rails conventions here, but this should work with any Ruby web framework:
346
347 redirect_to Fleakr.authorization_url
348
349 By default, we request read permission for access. This doesn't really do much more than what the
350 public API allows, so you can request different permissions when asking for authorization:
351
352 # The values :read, :write, and :delete are supported
353 redirect_to Fleakr.authorization_url(:delete)
354
355 One the user authorizes your application, he will be redirected back to your callback URL with a
356 <tt>frob</tt> parameter as part of the query string. You'll need to exchange this for a token:
357
358 token = Fleakr.token_from_frob(params[:frob])
359
360 The actual authentication token is available by calling <tt>token.value</tt> in the above
361 example. You'll want to store this value somewhere to make future API calls on behalf of this
362 user. To make that process easier, there is a method that you can use that will allow you to
363 automatically scope your requests to the authenticated user:
364
365 user = Fleakr.user_for_token('72157622657341094-41241e527f325abb')
366
367 From there, you can make any of the usual calls available with the API. See
368 Fleakr::Objects::User for more information.
40d146cc » reagent 2009-01-01 Updated main README file wi... 369
348b14c4 » reagent 2009-01-21 Document process for loggin... 370 === What Went Wrong?
371
372 Because so much of the underlying API is hidden under the covers, it's often tough to know
373 what's really going on when you run into unexpected behavior. To make things easier, you can
374 have Fleakr log all of the API traffic. Here's how:
375
376 Fleakr.logger = Logger.new('/tmp/fleakr.log')
377
378 Now any calls to the API will log both their request and response data to that file. But be
379 warned, this can be pretty verbose by default (especially if you're doing file uploads). To see
380 just the requests you need to tune the log level:
381
382 logger = Logger.new('/tmp/fleakr.log')
383 logger.level = Logger::INFO
384
385 Fleakr.logger = logger
386
387 Even if something doesn't go wrong, this is a good way to get a sense for when you're making
388 API requests.
389
387c5d02 » reagent 2009-09-12 Update README with contribu... 390 == Contributing
391
392 If there is a feature that you would like to contribute, I gladly accept pull requests. There
393 are a few things that make my life easier when integrating your changes:
394
395 * Verify that all tests are passing (run `rake` from the project root)
396 * Keep your commits small, focused, and tested - this allows me to apply changes cleanly
397 * Leave the Rakefile and version information intact - if you really want to make changes,
398 please do so in a separate commit.
399
400 Once your changes are applied, I will add you to the list of contributors.
401
7223202d » reagent 2009-07-20 Update documentation 402 == Contributors
403
404 While Fleakr started as a labor of love for me, I'm glad that others have been interested
405 in this project enough to contribute their ideas and code:
406
873a83ec » reagent 2009-10-18 Added collection support, U... 407 * {Mark Dickson}[http://github.com/ideaoforder]
7223202d » reagent 2009-07-20 Update documentation 408 * {John Guenin}[http://github.com/johng]
409 * {Thomas Olausson}[http://github.com/latompa]
873a83ec » reagent 2009-10-18 Added collection support, U... 410 * {Robert Sköld}[http://github.com/slaskis]
e1a20e2e » reagent 2009-12-06 Added Björn to contributors 411 * {Björn Wolf}[http://github.com/we5]
7223202d » reagent 2009-07-20 Update documentation 412
413 Thanks!
414
40d146cc » reagent 2009-01-01 Updated main README file wi... 415 == Roadmap / TODO
416
417 === 0.5.x
418
387c5d02 » reagent 2009-09-12 Update README with contribu... 419 * Implement remaining bits of person and photo-related API calls (read-only)
eff1109d » reagent 2009-03-03 Update TODO 420 * Provide a better searching interface with ruby-like option syntax
40d146cc » reagent 2009-01-01 Updated main README file wi... 421
422 === Future
423
387c5d02 » reagent 2009-09-12 Update README with contribu... 424 * Implement asynchronous file upload / replacement w/ ticket checking
7db81a15 » reagent 2008-12-31 Update TODOs 425 * Implement save-able search results (e.g. Fleakr.search('ponies').save_to('/path', :medium))
40d146cc » reagent 2009-01-01 Updated main README file wi... 426 * Implement deeper associations for core elements (e.g. tags / etc..)
427 * Implement write methods for photos & photosets
eff1109d » reagent 2009-03-03 Update TODO 428 * Implement flickr.places.* portion of API
40d146cc » reagent 2009-01-01 Updated main README file wi... 429
72d796e9 » reagent 2008-12-05 Added RDoc to source files ... 430 == License
866e035c » reagent 2008-11-02 Initial commit 431
432 Copyright (c) 2008 Patrick Reagan (reaganpr@gmail.com)
433
434 Permission is hereby granted, free of charge, to any person
435 obtaining a copy of this software and associated documentation
436 files (the "Software"), to deal in the Software without
437 restriction, including without limitation the rights to use,
438 copy, modify, merge, publish, distribute, sublicense, and/or sell
439 copies of the Software, and to permit persons to whom the
440 Software is furnished to do so, subject to the following
441 conditions:
442
443 The above copyright notice and this permission notice shall be
444 included in all copies or substantial portions of the Software.
445
446 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
447 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
448 OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
449 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
450 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
451 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
452 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
453 OTHER DEALINGS IN THE SOFTWARE.