Merge lp:~urbanape/ubuntuone-ios-files/auto-upload-pics into lp:ubuntuone-ios-files

Proposed by Zachery Bir
Status: Merged
Merge reported by: Zachery Bir
Merged at revision: not available
Proposed branch: lp:~urbanape/ubuntuone-ios-files/auto-upload-pics
Merge into: lp:ubuntuone-ios-files
Diff against target: 1698 lines (+1018/-63)
26 files modified
Files.xcodeproj/project.pbxproj (+33/-3)
Files/Files-Info.plist (+9/-1)
Files/FilesAppDelegate.m (+89/-29)
Files/Generated/_U1Asset.h (+76/-0)
Files/Generated/_U1Asset.m (+64/-0)
Files/Generated/_U1Volume.h (+16/-1)
Files/Generated/_U1Volume.m (+7/-0)
Files/U1Asset.h (+5/-0)
Files/U1Asset.m (+7/-0)
Files/U1AssetUploadOperation.h (+25/-0)
Files/U1AssetUploadOperation.m (+74/-0)
Files/U1DataRepository.h (+5/-1)
Files/U1DataRepository.m (+53/-0)
Files/U1FilePreviewViewController.m (+1/-0)
Files/U1Files.xcdatamodeld/.xccurrentversion (+1/-1)
Files/U1FilesClient.h (+6/-1)
Files/U1FilesClient.m (+124/-8)
Files/U1FilesService.h (+5/-3)
Files/U1FilesService.m (+77/-1)
Files/U1FolderViewController.m (+1/-1)
Files/U1LocalAssetsManager.h (+29/-0)
Files/U1LocalAssetsManager.m (+209/-0)
Files/U1Volume.h (+18/-1)
Files/U1Volume.m (+53/-1)
Files/U1VolumesViewController.h (+4/-3)
Files/U1VolumesViewController.m (+27/-8)
To merge this branch: bzr merge lp:~urbanape/ubuntuone-ios-files/auto-upload-pics
Reviewer Review Type Date Requested Status
Jason Foreman (community) Approve
Review via email: mp+77757@code.launchpad.net

Description of the change

This branch adds rough auto-upload of the user's photo library (only photos, no video).

It provides no feedback or controls to cancel the operation yet, and is very, very chatty.

To post a comment you must log in.
Revision history for this message
Zachery Bir (urbanape) wrote :

Also, this branch Singletonizes a bunch of the classes we use.

36. By Zachery Bir

Renamed to match the new bundle version

37. By Zachery Bir

Renamed data model

38. By Zachery Bir

Updated bundle version

39. By Zachery Bir

No longer a private property

40. By Zachery Bir

Using a FilesClient, rather than the bare FilesService

41. By Zachery Bir

Move the static variable outside the implementation, and close an errant code block

42. By Zachery Bir

Uncomment the icon block

43. By Zachery Bir

Updates to make build more better good.

Revision history for this message
Jason Foreman (threeve) wrote :

I've ended up un-singletonizing (just the bits about overriding retain/release) in a later changeset, but otherwise looks good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'Files.xcodeproj/project.pbxproj'
--- Files.xcodeproj/project.pbxproj 2011-09-27 14:36:00 +0000
+++ Files.xcodeproj/project.pbxproj 2011-10-04 14:38:28 +0000
@@ -7,6 +7,11 @@
7 objects = {7 objects = {
88
9/* Begin PBXBuildFile section */9/* Begin PBXBuildFile section */
10 91A5E2DC142A70DF00EAAC2B /* U1LocalAssetsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 91A5E2DB142A70DF00EAAC2B /* U1LocalAssetsManager.m */; };
11 91A5E2DF142B727600EAAC2B /* U1AssetUploadOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 91A5E2DE142B727500EAAC2B /* U1AssetUploadOperation.m */; };
12 91B3F2D5141E87F900939B3C /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 91B3F2D4141E87F900939B3C /* AssetsLibrary.framework */; };
13 91B3F2DC141FDFAB00939B3C /* _U1Asset.m in Sources */ = {isa = PBXBuildFile; fileRef = 91B3F2DB141FDFAB00939B3C /* _U1Asset.m */; };
14 91B3F2DF141FDFBE00939B3C /* U1Asset.m in Sources */ = {isa = PBXBuildFile; fileRef = 91B3F2DE141FDFBE00939B3C /* U1Asset.m */; };
10 960D46131409E0E100B73177 /* PullRefreshTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 960D46001409E09F00B73177 /* PullRefreshTableViewController.m */; };15 960D46131409E0E100B73177 /* PullRefreshTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 960D46001409E09F00B73177 /* PullRefreshTableViewController.m */; };
11 960D46141409E0F000B73177 /* arrow.png in Resources */ = {isa = PBXBuildFile; fileRef = 960D45FB1409E09F00B73177 /* arrow.png */; };16 960D46141409E0F000B73177 /* arrow.png in Resources */ = {isa = PBXBuildFile; fileRef = 960D45FB1409E09F00B73177 /* arrow.png */; };
12 960D46161409E10200B73177 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 960D46151409E10200B73177 /* QuartzCore.framework */; };17 960D46161409E10200B73177 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 960D46151409E10200B73177 /* QuartzCore.framework */; };
@@ -116,6 +121,15 @@
116/* End PBXContainerItemProxy section */121/* End PBXContainerItemProxy section */
117122
118/* Begin PBXFileReference section */123/* Begin PBXFileReference section */
124 91A5E2DB142A70DF00EAAC2B /* U1LocalAssetsManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = U1LocalAssetsManager.m; sourceTree = "<group>"; };
125 91A5E2DD142B727500EAAC2B /* U1AssetUploadOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = U1AssetUploadOperation.h; sourceTree = "<group>"; };
126 91A5E2DE142B727500EAAC2B /* U1AssetUploadOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = U1AssetUploadOperation.m; sourceTree = "<group>"; };
127 91B3F2D4141E87F900939B3C /* AssetsLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AssetsLibrary.framework; path = System/Library/Frameworks/AssetsLibrary.framework; sourceTree = SDKROOT; };
128 91B3F2D7141FC9BE00939B3C /* U1LocalAssetsManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = U1LocalAssetsManager.h; sourceTree = "<group>"; };
129 91B3F2DA141FDFAB00939B3C /* _U1Asset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _U1Asset.h; sourceTree = "<group>"; };
130 91B3F2DB141FDFAB00939B3C /* _U1Asset.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = _U1Asset.m; sourceTree = "<group>"; };
131 91B3F2DD141FDFBE00939B3C /* U1Asset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = U1Asset.h; sourceTree = "<group>"; };
132 91B3F2DE141FDFBE00939B3C /* U1Asset.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = U1Asset.m; sourceTree = "<group>"; };
119 960D45FA1409E09F00B73177 /* .gitignore */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitignore; sourceTree = "<group>"; };133 960D45FA1409E09F00B73177 /* .gitignore */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitignore; sourceTree = "<group>"; };
120 960D45FB1409E09F00B73177 /* arrow.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = arrow.png; sourceTree = "<group>"; };134 960D45FB1409E09F00B73177 /* arrow.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = arrow.png; sourceTree = "<group>"; };
121 960D45FD1409E09F00B73177 /* DemoTableViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DemoTableViewController.h; sourceTree = "<group>"; };135 960D45FD1409E09F00B73177 /* DemoTableViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DemoTableViewController.h; sourceTree = "<group>"; };
@@ -194,6 +208,7 @@
194 96A1699F1430C9C900E4C990 /* 265-download@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "265-download@2x.png"; path = "Assets/265-download@2x.png"; sourceTree = "<group>"; };208 96A1699F1430C9C900E4C990 /* 265-download@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "265-download@2x.png"; path = "Assets/265-download@2x.png"; sourceTree = "<group>"; };
195 96A169A21430D53600E4C990 /* U1LocalFileInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = U1LocalFileInfo.h; sourceTree = "<group>"; };209 96A169A21430D53600E4C990 /* U1LocalFileInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = U1LocalFileInfo.h; sourceTree = "<group>"; };
196 96A169A31430D53600E4C990 /* U1LocalFileInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = U1LocalFileInfo.m; sourceTree = "<group>"; };210 96A169A31430D53600E4C990 /* U1LocalFileInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = U1LocalFileInfo.m; sourceTree = "<group>"; };
211 96A56430143265B4007A1A93 /* U1Files 1.0-3.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "U1Files 1.0-3.xcdatamodel"; sourceTree = "<group>"; };
197 96CC17C71417E5E400EFC1BA /* U1Files.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = U1Files.xcdatamodel; sourceTree = "<group>"; };212 96CC17C71417E5E400EFC1BA /* U1Files.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = U1Files.xcdatamodel; sourceTree = "<group>"; };
198 96CC17CB1417EA0700EFC1BA /* _U1FileNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _U1FileNode.h; sourceTree = "<group>"; };213 96CC17CB1417EA0700EFC1BA /* _U1FileNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _U1FileNode.h; sourceTree = "<group>"; };
199 96CC17CC1417EA0700EFC1BA /* _U1FileNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = _U1FileNode.m; sourceTree = "<group>"; };214 96CC17CC1417EA0700EFC1BA /* _U1FileNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = _U1FileNode.m; sourceTree = "<group>"; };
@@ -292,6 +307,7 @@
292 isa = PBXFrameworksBuildPhase;307 isa = PBXFrameworksBuildPhase;
293 buildActionMask = 2147483647;308 buildActionMask = 2147483647;
294 files = (309 files = (
310 91B3F2D5141E87F900939B3C /* AssetsLibrary.framework in Frameworks */,
295 96CC17D81417EA2B00EFC1BA /* CoreData.framework in Frameworks */,311 96CC17D81417EA2B00EFC1BA /* CoreData.framework in Frameworks */,
296 96733B12140DFD6D0074D545 /* Security.framework in Frameworks */,312 96733B12140DFD6D0074D545 /* Security.framework in Frameworks */,
297 960D46161409E10200B73177 /* QuartzCore.framework in Frameworks */,313 960D46161409E10200B73177 /* QuartzCore.framework in Frameworks */,
@@ -350,6 +366,8 @@
350 96CC17CA1417E9E500EFC1BA /* Generated */,366 96CC17CA1417E9E500EFC1BA /* Generated */,
351 96CC17DF1418091100EFC1BA /* Parsers */,367 96CC17DF1418091100EFC1BA /* Parsers */,
352 96CC17C61417E5E400EFC1BA /* U1Files.xcdatamodeld */,368 96CC17C61417E5E400EFC1BA /* U1Files.xcdatamodeld */,
369 91B3F2DD141FDFBE00939B3C /* U1Asset.h */,
370 91B3F2DE141FDFBE00939B3C /* U1Asset.m */,
353 96CC17D91417EBF500EFC1BA /* U1Volume.h */,371 96CC17D91417EBF500EFC1BA /* U1Volume.h */,
354 96CC17DA1417EBF500EFC1BA /* U1Volume.m */,372 96CC17DA1417EBF500EFC1BA /* U1Volume.m */,
355 960D4629140D99DB00B73177 /* U1Node.h */,373 960D4629140D99DB00B73177 /* U1Node.h */,
@@ -407,6 +425,8 @@
407 96CC17CA1417E9E500EFC1BA /* Generated */ = {425 96CC17CA1417E9E500EFC1BA /* Generated */ = {
408 isa = PBXGroup;426 isa = PBXGroup;
409 children = (427 children = (
428 91B3F2DA141FDFAB00939B3C /* _U1Asset.h */,
429 91B3F2DB141FDFAB00939B3C /* _U1Asset.m */,
410 96CC17CB1417EA0700EFC1BA /* _U1FileNode.h */,430 96CC17CB1417EA0700EFC1BA /* _U1FileNode.h */,
411 96CC17CC1417EA0700EFC1BA /* _U1FileNode.m */,431 96CC17CC1417EA0700EFC1BA /* _U1FileNode.m */,
412 96CC17CD1417EA0700EFC1BA /* _U1FolderNode.h */,432 96CC17CD1417EA0700EFC1BA /* _U1FolderNode.h */,
@@ -451,6 +471,7 @@
451 96E860B413F7251D0026783D /* Frameworks */ = {471 96E860B413F7251D0026783D /* Frameworks */ = {
452 isa = PBXGroup;472 isa = PBXGroup;
453 children = (473 children = (
474 91B3F2D4141E87F900939B3C /* AssetsLibrary.framework */,
454 96CC17D71417EA2B00EFC1BA /* CoreData.framework */,475 96CC17D71417EA2B00EFC1BA /* CoreData.framework */,
455 96733B11140DFD6D0074D545 /* Security.framework */,476 96733B11140DFD6D0074D545 /* Security.framework */,
456 960D46151409E10200B73177 /* QuartzCore.framework */,477 960D46151409E10200B73177 /* QuartzCore.framework */,
@@ -486,6 +507,8 @@
486 96E8614213F728380026783D /* U1FilesService.m */,507 96E8614213F728380026783D /* U1FilesService.m */,
487 96CC17E314180C5F00EFC1BA /* U1FilesClient.h */,508 96CC17E314180C5F00EFC1BA /* U1FilesClient.h */,
488 96CC17E414180C5F00EFC1BA /* U1FilesClient.m */,509 96CC17E414180C5F00EFC1BA /* U1FilesClient.m */,
510 91B3F2D7141FC9BE00939B3C /* U1LocalAssetsManager.h */,
511 91A5E2DB142A70DF00EAAC2B /* U1LocalAssetsManager.m */,
489 969EF22613F8C10C00CEF6CB /* U1VolumesViewController.h */,512 969EF22613F8C10C00CEF6CB /* U1VolumesViewController.h */,
490 969EF22713F8C10C00CEF6CB /* U1VolumesViewController.m */,513 969EF22713F8C10C00CEF6CB /* U1VolumesViewController.m */,
491 969EF22813F8C10C00CEF6CB /* U1VolumesViewController.xib */,514 969EF22813F8C10C00CEF6CB /* U1VolumesViewController.xib */,
@@ -498,6 +521,8 @@
498 960D4624140D8AF200B73177 /* U1ByteSizeValueTransformer.m */,521 960D4624140D8AF200B73177 /* U1ByteSizeValueTransformer.m */,
499 960D4626140D8B4400B73177 /* U1FriendlyDateValueTransformer.h */,522 960D4626140D8B4400B73177 /* U1FriendlyDateValueTransformer.h */,
500 960D4627140D8B4400B73177 /* U1FriendlyDateValueTransformer.m */,523 960D4627140D8B4400B73177 /* U1FriendlyDateValueTransformer.m */,
524 91A5E2DD142B727500EAAC2B /* U1AssetUploadOperation.h */,
525 91A5E2DE142B727500EAAC2B /* U1AssetUploadOperation.m */,
501 965D7EB71429690C00E4754F /* U1NavigationBar.h */,526 965D7EB71429690C00E4754F /* U1NavigationBar.h */,
502 965D7EB81429690C00E4754F /* U1NavigationBar.m */,527 965D7EB81429690C00E4754F /* U1NavigationBar.m */,
503 96A169A21430D53600E4C990 /* U1LocalFileInfo.h */,528 96A169A21430D53600E4C990 /* U1LocalFileInfo.h */,
@@ -818,6 +843,10 @@
818 96CC17DE1417EF7200EFC1BA /* U1DataRepository.m in Sources */,843 96CC17DE1417EF7200EFC1BA /* U1DataRepository.m in Sources */,
819 96CC17E21418094800EFC1BA /* U1NodeJSONParser.m in Sources */,844 96CC17E21418094800EFC1BA /* U1NodeJSONParser.m in Sources */,
820 96CC17E514180C6000EFC1BA /* U1FilesClient.m in Sources */,845 96CC17E514180C6000EFC1BA /* U1FilesClient.m in Sources */,
846 91B3F2DC141FDFAB00939B3C /* _U1Asset.m in Sources */,
847 91B3F2DF141FDFBE00939B3C /* U1Asset.m in Sources */,
848 91A5E2DC142A70DF00EAAC2B /* U1LocalAssetsManager.m in Sources */,
849 91A5E2DF142B727600EAAC2B /* U1AssetUploadOperation.m in Sources */,
821 965D7EB91429690C00E4754F /* U1NavigationBar.m in Sources */,850 965D7EB91429690C00E4754F /* U1NavigationBar.m in Sources */,
822 96A169A41430D53700E4C990 /* U1LocalFileInfo.m in Sources */,851 96A169A41430D53700E4C990 /* U1LocalFileInfo.m in Sources */,
823 );852 );
@@ -939,14 +968,14 @@
939 96E860F013F7251D0026783D /* Release */ = {968 96E860F013F7251D0026783D /* Release */ = {
940 isa = XCBuildConfiguration;969 isa = XCBuildConfiguration;
941 buildSettings = {970 buildSettings = {
942 "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";971 "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: Zachery Bir (P7WDPDEFHU)";
943 GCC_PRECOMPILE_PREFIX_HEADER = YES;972 GCC_PRECOMPILE_PREFIX_HEADER = YES;
944 GCC_PREFIX_HEADER = "Files/Files-Prefix.pch";973 GCC_PREFIX_HEADER = "Files/Files-Prefix.pch";
945 GCC_VERSION = com.apple.compilers.llvm.clang.1_0;974 GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
946 INFOPLIST_FILE = "Files/Files-Info.plist";975 INFOPLIST_FILE = "Files/Files-Info.plist";
947 IPHONEOS_DEPLOYMENT_TARGET = 4.0;976 IPHONEOS_DEPLOYMENT_TARGET = 4.0;
948 PRODUCT_NAME = "$(TARGET_NAME)";977 PRODUCT_NAME = "$(TARGET_NAME)";
949 "PROVISIONING_PROFILE[sdk=iphoneos*]" = "";978 "PROVISIONING_PROFILE[sdk=iphoneos*]" = "84E0B7E6-02A2-46EF-9C76-AA80C48130A7";
950 TARGETED_DEVICE_FAMILY = 1;979 TARGETED_DEVICE_FAMILY = 1;
951 WRAPPER_EXTENSION = app;980 WRAPPER_EXTENSION = app;
952 };981 };
@@ -1022,9 +1051,10 @@
1022 96CC17C61417E5E400EFC1BA /* U1Files.xcdatamodeld */ = {1051 96CC17C61417E5E400EFC1BA /* U1Files.xcdatamodeld */ = {
1023 isa = XCVersionGroup;1052 isa = XCVersionGroup;
1024 children = (1053 children = (
1054 96A56430143265B4007A1A93 /* U1Files 1.0-3.xcdatamodel */,
1025 96CC17C71417E5E400EFC1BA /* U1Files.xcdatamodel */,1055 96CC17C71417E5E400EFC1BA /* U1Files.xcdatamodel */,
1026 );1056 );
1027 currentVersion = 96CC17C71417E5E400EFC1BA /* U1Files.xcdatamodel */;1057 currentVersion = 96A56430143265B4007A1A93 /* U1Files 1.0-3.xcdatamodel */;
1028 path = U1Files.xcdatamodeld;1058 path = U1Files.xcdatamodeld;
1029 sourceTree = "<group>";1059 sourceTree = "<group>";
1030 versionGroupType = wrapper.xcdatamodel;1060 versionGroupType = wrapper.xcdatamodel;
10311061
=== modified file 'Files/Files-Info.plist'
--- Files/Files-Info.plist 2011-09-27 14:42:09 +0000
+++ Files/Files-Info.plist 2011-10-04 14:38:28 +0000
@@ -6,6 +6,8 @@
6 <string>en</string>6 <string>en</string>
7 <key>CFBundleDisplayName</key>7 <key>CFBundleDisplayName</key>
8 <string>${PRODUCT_NAME}</string>8 <string>${PRODUCT_NAME}</string>
9 <key>CFBundleDocumentTypes</key>
10 <array/>
9 <key>CFBundleExecutable</key>11 <key>CFBundleExecutable</key>
10 <string>${EXECUTABLE_NAME}</string>12 <string>${EXECUTABLE_NAME}</string>
11 <key>CFBundleIconFile</key>13 <key>CFBundleIconFile</key>
@@ -22,8 +24,10 @@
22 <string>1.0</string>24 <string>1.0</string>
23 <key>CFBundleSignature</key>25 <key>CFBundleSignature</key>
24 <string>????</string>26 <string>????</string>
27 <key>CFBundleURLTypes</key>
28 <array/>
25 <key>CFBundleVersion</key>29 <key>CFBundleVersion</key>
26 <string>2</string>30 <string>3</string>
27 <key>LSRequiresIPhoneOS</key>31 <key>LSRequiresIPhoneOS</key>
28 <true/>32 <true/>
29 <key>NSMainNibFile</key>33 <key>NSMainNibFile</key>
@@ -43,5 +47,9 @@
43 <string>UIInterfaceOrientationLandscapeLeft</string>47 <string>UIInterfaceOrientationLandscapeLeft</string>
44 <string>UIInterfaceOrientationLandscapeRight</string>48 <string>UIInterfaceOrientationLandscapeRight</string>
45 </array>49 </array>
50 <key>UTExportedTypeDeclarations</key>
51 <array/>
52 <key>UTImportedTypeDeclarations</key>
53 <array/>
46</dict>54</dict>
47</plist>55</plist>
4856
=== modified file 'Files/FilesAppDelegate.m'
--- Files/FilesAppDelegate.m 2011-09-27 14:36:00 +0000
+++ Files/FilesAppDelegate.m 2011-10-04 14:38:28 +0000
@@ -13,6 +13,10 @@
13// You should have received a copy of the GNU Affero General Public License13// You should have received a copy of the GNU Affero General Public License
14// along with this program. If not, see <http://www.gnu.org/licenses/>.14// along with this program. If not, see <http://www.gnu.org/licenses/>.
1515
16#import <AssetsLibrary/ALAssetsLibrary.h>
17#import <AssetsLibrary/ALAssetsGroup.h>
18#import <AssetsLibrary/ALAsset.h>
19
16#import "FilesAppDelegate.h"20#import "FilesAppDelegate.h"
1721
18#import "U1AccountManager.h"22#import "U1AccountManager.h"
@@ -20,35 +24,41 @@
20#import "U1FileNode.h"24#import "U1FileNode.h"
21#import "U1FilePreviewViewController.h"25#import "U1FilePreviewViewController.h"
22#import "U1FilesClient.h"26#import "U1FilesClient.h"
27#import "U1LocalAssetsManager.h"
23#import "U1FilesService.h"28#import "U1FilesService.h"
24#import "U1FolderNode.h"29#import "U1FolderNode.h"
25#import "U1FolderViewController.h"30#import "U1FolderViewController.h"
26#import "U1LoginController.h"31#import "U1LoginController.h"
27#import "U1Node.h"32#import "U1Node.h"
28#import "U1VolumesViewController.h"33#import "U1VolumesViewController.h"
34#import "U1Volume.h"
2935
3036
31@interface FilesAppDelegate () <U1FolderViewControllerDelegate, U1VolumesViewControllerDelegate, U1LoginControllerDelegate>37@interface FilesAppDelegate () <U1FolderViewControllerDelegate, U1VolumesViewControllerDelegate, U1LoginControllerDelegate>
32@property (retain) U1FilesService *filesService;38@property (retain) U1FilesService *filesService;
33@property (retain) U1FilesClient *filesClient;39@property (retain) U1FilesClient *filesClient;
40@property (retain) U1LocalAssetsManager *localAssetsManager;
34@property (retain) U1LoginController *loginController;41@property (retain) U1LoginController *loginController;
35@property (retain) U1DataRepository *dataRepository;42@property (retain) U1DataRepository *dataRepository;
36- (NSURL*)dataStoreURL;
37- (void)showVolumes;43- (void)showVolumes;
38- (void)showLoginController;44- (void)showLoginController;
45- (void)ensureUploadFolder;
46- (NSString*)remoteUploadFolderPath;
47- (NSString*)localUploadQueuePath;
39@end48@end
4049
4150
42@implementation FilesAppDelegate51@implementation FilesAppDelegate
4352
44@synthesize window;53@synthesize window;
45@synthesize filesService, filesClient, navController, loginController, dataRepository;54@synthesize filesService, filesClient, localAssetsManager, navController, loginController, dataRepository;
4655
47- (void)dealloc56- (void)dealloc
48{57{
49 [window release];58 [window release];
50 [filesService release];59 [filesService release];
51 [filesClient release];60 [filesClient release];
61 [localAssetsManager release];
52 [navController release];62 [navController release];
53 [loginController release];63 [loginController release];
54 [dataRepository release];64 [dataRepository release];
@@ -59,51 +69,104 @@
59{69{
60 [self.window makeKeyAndVisible];70 [self.window makeKeyAndVisible];
6171
72 return YES;
73}
74
75- (void)applicationDidBecomeActive:(UIApplication *)application;
76{
62 if (![[U1AccountManager sharedAccountManager] hasCredentials])77 if (![[U1AccountManager sharedAccountManager] hasCredentials])
63 {78 {
64 [self showLoginController];79 [self showLoginController];
65 }80 }
66 else81 else
67 {82 {
68 [self showVolumes];83 self.filesService = [U1FilesService sharedFilesService];
84 self.filesClient = [U1FilesClient sharedFilesClient];
85
86 self.localAssetsManager = [U1LocalAssetsManager sharedFilesManager];
87 NSLog(@"Showing Volumes: Reading localAssetsToUpload from filesystem.");
88 NSMutableArray *uploadQueue = [NSMutableArray arrayWithContentsOfFile:[self localUploadQueuePath]];
89 if (uploadQueue != nil) {
90 NSLog(@"Retrieved the upload queue from the filesystem.");
91 NSLog(@"Length of the array on filesystem: %d", [uploadQueue count]);
92 self.localAssetsManager.localAssetsToUpload = uploadQueue;
93 NSLog(@"Read in the file, now we delete it.");
94 NSError *error = nil;
95 [[NSFileManager defaultManager] removeItemAtPath:[self localUploadQueuePath] error:&error];
96 }
97
98 [self ensureUploadFolder];
69 }99 }
70100}
71 return YES;101
102- (void)ensureUploadFolder;
103{
104 [self.filesClient volumesWithCompletionBlock:^(NSArray *volumeInfos, NSError *error) {
105 dispatch_async(dispatch_get_main_queue(), ^(void) {
106 // iterate over volumeInfos. If there isn't one there called "Pictures - <device name>", create it.
107 BOOL found = NO;
108 NSLog(@"Walking the volumes, to see if it has been created already.");
109 for (U1Volume *volume in volumeInfos) {
110 if ([volume.path isEqualToString:[self remoteUploadFolderPath]])
111 {
112 NSLog(@"Found the volume. No need to try to create it.");
113 found = YES;
114 self.localAssetsManager.remoteUploadVolume = volume;
115 break;
116 }
117 }
118 if (!found)
119 {
120 NSLog(@"Didn't find the volume. Creating it.");
121 [self.filesClient createVolumeAtPath:[self remoteUploadFolderPath]
122 completionBlock:^(U1Volume *volume, NSError *error) {
123 self.localAssetsManager.remoteUploadVolume = volume;
124 [self.localAssetsManager uploadPendingAssets];
125 [self.localAssetsManager checkForNewAssets];
126 NSLog(@"Error: %@", error);
127 }];
128 } else
129 {
130 [self.localAssetsManager uploadPendingAssets];
131 [self.localAssetsManager checkForNewAssets];
132 }
133 [self showVolumes];
134 });
135 }];
136}
137
138- (NSString *)remoteUploadFolderPath;
139{
140 return [NSString stringWithFormat:@"/~/Pictures - %@", [[UIDevice currentDevice] name]];
141}
142
143- (NSString*)localUploadQueuePath;
144{
145 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
146 return [[paths objectAtIndex:0] stringByAppendingPathComponent:@"localAssetsToUpload.array"];
72}147}
73148
74- (void)applicationWillResignActive:(UIApplication *)application;149- (void)applicationWillResignActive:(UIApplication *)application;
75{150{
76 [self.dataRepository save:NULL];151 [self.dataRepository save:NULL];
152 NSLog(@"Application Resigning: Writing localAssetsToUpload (%d items) to the filesystem.", [self.localAssetsManager.localAssetsToUpload count]);
153 [self.localAssetsManager.localAssetsToUpload writeToFile:[self localUploadQueuePath] atomically:YES];
154 // serialize self.filesManager's localAssetsToUpload to the filesystem
77}155}
78156
79- (void)applicationWillTerminate:(UIApplication *)application;157- (void)applicationWillTerminate:(UIApplication *)application;
80{158{
81 // TODO: check error159 // TODO: check error
82 [self.dataRepository save:NULL];160 [self.dataRepository save:NULL];
83}161 NSLog(@"Application Terminating: Writing localAssetsToUpload (%d items) to the filesystem.", [self.localAssetsManager.localAssetsToUpload count]);
84162 [self.localAssetsManager.localAssetsToUpload writeToFile:[self localUploadQueuePath] atomically:YES];
85- (NSURL*)dataStoreURL;163 // serialize self.filesManager's localAssetsToUpload to the filesystem
86{
87 NSURL *cachesDirectory = [[[NSFileManager defaultManager] URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask] lastObject];
88 NSURL *storeURL = [NSURL URLWithString:@"U1Files.sqlite" relativeToURL:cachesDirectory];
89 return storeURL;
90}164}
91165
92- (void)showVolumes;166- (void)showVolumes;
93{167{
94 filesService = [U1FilesService new];
95
96 NSURL *storeURL = [self dataStoreURL];
97 self.dataRepository = [[U1DataRepository alloc] initWithStoreURL:storeURL];
98 [dataRepository release];
99
100 filesClient = [[U1FilesClient alloc] init];
101 [self.filesClient setFilesService:filesService];
102 [self.filesClient setDataRepository:self.dataRepository];
103
104 U1VolumesViewController *rootController = [U1VolumesViewController new];168 U1VolumesViewController *rootController = [U1VolumesViewController new];
105 rootController.delegate = self;169 rootController.delegate = self;
106 rootController.filesService = self.filesService;
107 170
108 [self.navController setViewControllers:[NSArray arrayWithObject:rootController] animated:NO];171 [self.navController setViewControllers:[NSArray arrayWithObject:rootController] animated:NO];
109}172}
@@ -119,7 +182,7 @@
119{182{
120 [self.navController dismissModalViewControllerAnimated:YES];183 [self.navController dismissModalViewControllerAnimated:YES];
121 self.loginController = nil;184 self.loginController = nil;
122 [self showVolumes];185 [self applicationDidBecomeActive:nil];
123}186}
124187
125188
@@ -130,14 +193,12 @@
130 if ([node isFolder])193 if ([node isFolder])
131 {194 {
132 U1FolderViewController *nextFolderController = [[U1FolderViewController alloc] initWithNodeResourcePath:node.resourcePath];195 U1FolderViewController *nextFolderController = [[U1FolderViewController alloc] initWithNodeResourcePath:node.resourcePath];
133 nextFolderController.filesClient = self.filesClient;
134 nextFolderController.delegate = self;196 nextFolderController.delegate = self;
135 [self.navController pushViewController:nextFolderController animated:YES];197 [self.navController pushViewController:nextFolderController animated:YES];
136 }198 }
137 else if ([node isFile])199 else if ([node isFile])
138 {200 {
139 U1FilePreviewViewController *fileController = [[U1FilePreviewViewController alloc] initWithNode:(id)node];201 U1FilePreviewViewController *fileController = [[U1FilePreviewViewController alloc] initWithNode:(id)node];
140 fileController.filesClient = self.filesClient;
141 [self.navController pushViewController:fileController animated:YES];202 [self.navController pushViewController:fileController animated:YES];
142 }203 }
143}204}
@@ -145,11 +206,10 @@
145206
146#pragma mark U1VolumesControllerDelegate Methods207#pragma mark U1VolumesControllerDelegate Methods
147208
148- (void)volumesController:(U1VolumesViewController *)volumesController didSelectVolume:(NSDictionary *)volume;209- (void)volumesController:(U1VolumesViewController *)volumesController didSelectVolume:(U1Volume *)volume;
149{210{
150 NSString *nodePath = [volume objectForKey:@"node_path"];211 NSString *nodePath = volume.nodePath;
151 U1FolderViewController *folderController = [[U1FolderViewController alloc] initWithNodeResourcePath:nodePath];212 U1FolderViewController *folderController = [[U1FolderViewController alloc] initWithNodeResourcePath:nodePath];
152 folderController.filesClient = self.filesClient;
153 folderController.delegate = self;213 folderController.delegate = self;
154 [self.navController pushViewController:folderController animated:YES];214 [self.navController pushViewController:folderController animated:YES];
155}215}
156216
=== added file 'Files/Generated/_U1Asset.h'
--- Files/Generated/_U1Asset.h 1970-01-01 00:00:00 +0000
+++ Files/Generated/_U1Asset.h 2011-10-04 14:38:28 +0000
@@ -0,0 +1,76 @@
1// DO NOT EDIT. This file is machine-generated and constantly overwritten.
2// Make changes to U1Asset.h instead.
3
4#import <CoreData/CoreData.h>
5
6
7
8
9
10
11
12@interface U1AssetID : NSManagedObjectID {}
13@end
14
15@interface _U1Asset : NSManagedObject {}
16+ (id)insertInManagedObjectContext:(NSManagedObjectContext*)moc_;
17+ (NSString*)entityName;
18+ (NSEntityDescription*)entityInManagedObjectContext:(NSManagedObjectContext*)moc_;
19- (U1AssetID*)objectID;
20
21
22
23
24@property (nonatomic, retain) NSString *filename;
25
26
27//- (BOOL)validateFilename:(id*)value_ error:(NSError**)error_;
28
29
30
31
32@property (nonatomic, retain) NSString *groupId;
33
34
35//- (BOOL)validateGroupId:(id*)value_ error:(NSError**)error_;
36
37
38
39
40@property (nonatomic, retain) NSString *url;
41
42
43//- (BOOL)validateUrl:(id*)value_ error:(NSError**)error_;
44
45
46
47
48
49@end
50
51@interface _U1Asset (CoreDataGeneratedAccessors)
52
53@end
54
55@interface _U1Asset (CoreDataGeneratedPrimitiveAccessors)
56
57
58- (NSString*)primitiveFilename;
59- (void)setPrimitiveFilename:(NSString*)value;
60
61
62
63
64- (NSString*)primitiveGroupId;
65- (void)setPrimitiveGroupId:(NSString*)value;
66
67
68
69
70- (NSString*)primitiveUrl;
71- (void)setPrimitiveUrl:(NSString*)value;
72
73
74
75
76@end
077
=== added file 'Files/Generated/_U1Asset.m'
--- Files/Generated/_U1Asset.m 1970-01-01 00:00:00 +0000
+++ Files/Generated/_U1Asset.m 2011-10-04 14:38:28 +0000
@@ -0,0 +1,64 @@
1// DO NOT EDIT. This file is machine-generated and constantly overwritten.
2// Make changes to U1Asset.m instead.
3
4#import "_U1Asset.h"
5
6@implementation U1AssetID
7@end
8
9@implementation _U1Asset
10
11+ (id)insertInManagedObjectContext:(NSManagedObjectContext*)moc_ {
12 NSParameterAssert(moc_);
13 return [NSEntityDescription insertNewObjectForEntityForName:@"Asset" inManagedObjectContext:moc_];
14}
15
16+ (NSString*)entityName {
17 return @"Asset";
18}
19
20+ (NSEntityDescription*)entityInManagedObjectContext:(NSManagedObjectContext*)moc_ {
21 NSParameterAssert(moc_);
22 return [NSEntityDescription entityForName:@"Asset" inManagedObjectContext:moc_];
23}
24
25- (U1AssetID*)objectID {
26 return (U1AssetID*)[super objectID];
27}
28
29+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key {
30 NSSet *keyPaths = [super keyPathsForValuesAffectingValueForKey:key];
31
32
33 return keyPaths;
34}
35
36
37
38
39@dynamic filename;
40
41
42
43
44
45
46@dynamic groupId;
47
48
49
50
51
52
53@dynamic url;
54
55
56
57
58
59
60
61
62
63
64@end
065
=== modified file 'Files/Generated/_U1Volume.h'
--- Files/Generated/_U1Volume.h 2011-09-08 16:59:34 +0000
+++ Files/Generated/_U1Volume.h 2011-10-04 14:38:28 +0000
@@ -2,6 +2,7 @@
2// Make changes to U1Volume.h instead.2// Make changes to U1Volume.h instead.
33
4#import <CoreData/CoreData.h>4#import <CoreData/CoreData.h>
5#import "U1Node.h"
56
67
78
@@ -9,7 +10,7 @@
9@interface U1VolumeID : NSManagedObjectID {}10@interface U1VolumeID : NSManagedObjectID {}
10@end11@end
1112
12@interface _U1Volume : NSManagedObject {}13@interface _U1Volume : U1Node {}
13+ (id)insertInManagedObjectContext:(NSManagedObjectContext*)moc_;14+ (id)insertInManagedObjectContext:(NSManagedObjectContext*)moc_;
14+ (NSString*)entityName;15+ (NSString*)entityName;
15+ (NSEntityDescription*)entityInManagedObjectContext:(NSManagedObjectContext*)moc_;16+ (NSEntityDescription*)entityInManagedObjectContext:(NSManagedObjectContext*)moc_;
@@ -18,6 +19,14 @@
1819
1920
2021
22@property (nonatomic, retain) NSString *nodePath;
23
24
25//- (BOOL)validateNodePath:(id*)value_ error:(NSError**)error_;
26
27
28
29
2130
22@end31@end
2332
@@ -28,4 +37,10 @@
28@interface _U1Volume (CoreDataGeneratedPrimitiveAccessors)37@interface _U1Volume (CoreDataGeneratedPrimitiveAccessors)
2938
3039
40- (NSString*)primitiveNodePath;
41- (void)setPrimitiveNodePath:(NSString*)value;
42
43
44
45
31@end46@end
3247
=== modified file 'Files/Generated/_U1Volume.m'
--- Files/Generated/_U1Volume.m 2011-09-08 16:59:34 +0000
+++ Files/Generated/_U1Volume.m 2011-10-04 14:38:28 +0000
@@ -36,6 +36,13 @@
3636
3737
3838
39@dynamic nodePath;
40
41
42
43
44
45
3946
4047
4148
4249
=== added file 'Files/U1Asset.h'
--- Files/U1Asset.h 1970-01-01 00:00:00 +0000
+++ Files/U1Asset.h 2011-10-04 14:38:28 +0000
@@ -0,0 +1,5 @@
1#import "_U1Asset.h"
2
3@interface U1Asset : _U1Asset {}
4// Custom logic goes here.
5@end
06
=== added file 'Files/U1Asset.m'
--- Files/U1Asset.m 1970-01-01 00:00:00 +0000
+++ Files/U1Asset.m 2011-10-04 14:38:28 +0000
@@ -0,0 +1,7 @@
1#import "U1Asset.h"
2
3@implementation U1Asset
4
5// Custom logic goes here.
6
7@end
08
=== added file 'Files/U1AssetUploadOperation.h'
--- Files/U1AssetUploadOperation.h 1970-01-01 00:00:00 +0000
+++ Files/U1AssetUploadOperation.h 2011-10-04 14:38:28 +0000
@@ -0,0 +1,25 @@
1//
2// U1AssetUploadOperation.h
3// Files
4//
5// Created by Zachery Bir on 9/22/11.
6// Copyright 2011 __MyCompanyName__. All rights reserved.
7//
8
9#import <Foundation/Foundation.h>
10#import <AssetsLibrary/AssetsLibrary.h>
11
12@class U1Asset;
13@class U1FolderNode;
14
15@interface U1AssetUploadOperation : NSOperation {
16@private
17
18}
19@property (retain) ALAssetRepresentation *representation;
20@property (retain) NSData *assetData;
21@property (retain) U1Asset *asset;
22@property (retain) U1FolderNode *folder;
23@property (retain) NSString *filename;
24@property (retain) NSError *error;
25@end
026
=== added file 'Files/U1AssetUploadOperation.m'
--- Files/U1AssetUploadOperation.m 1970-01-01 00:00:00 +0000
+++ Files/U1AssetUploadOperation.m 2011-10-04 14:38:28 +0000
@@ -0,0 +1,74 @@
1//
2// U1AssetUploadOperation.m
3// Files
4//
5// Created by Zachery Bir on 9/22/11.
6// Copyright 2011 __MyCompanyName__. All rights reserved.
7//
8
9#import "U1AssetUploadOperation.h"
10#import "U1Asset.h"
11#import "U1FilesClient.h"
12
13@interface U1AssetUploadOperation ()
14@property (getter=isExecuting) BOOL executing;
15@property (getter=isFinished) BOOL finished;
16- (void)finishExecuting;
17@end
18
19@implementation U1AssetUploadOperation
20
21@synthesize executing, finished, asset, assetData, representation, folder, filename, error;
22
23- (id)init
24{
25 self = [super init];
26 if (self) {
27 // Initialization code here.
28 }
29
30 return self;
31}
32
33- (BOOL)isConcurrent;
34{
35 return YES;
36}
37
38- (void)finishExecuting;
39{
40 [self willChangeValueForKey:@"isExecuting"];
41 [self willChangeValueForKey:@"isFinished"];
42 self.finished = YES;
43 self.executing = NO;
44 [self didChangeValueForKey:@"isFinished"];
45 [self didChangeValueForKey:@"isExecuting"];
46// [UONetworkStatusCoordinator removeNetworkActivity];
47}
48
49- (void)start;
50{
51 // Trigger the filesClient to upload our asset, setting the completion block to marking ourself completed.
52 [self willChangeValueForKey:@"isExecuting"];
53 self.executing = YES;
54 [self didChangeValueForKey:@"isExecuting"];
55 dispatch_async(dispatch_get_main_queue(), ^(void) {
56 U1FilesClient *filesClient = [U1FilesClient sharedFilesClient];
57 [filesClient uploadContentData:self.assetData
58 toFolder:self.folder withResourceName:self.filename progressBlock:^(long long bytesUploaded, long long totalBytes) {
59 dispatch_async(dispatch_get_main_queue(), ^(void){
60 NSLog(@"Uploaded %lld of %lld for %@", bytesUploaded, totalBytes, self.filename);
61 });
62 } completionBlock:^(U1FileNode *updatedNode, NSError *uploadError) {
63 self.error = uploadError;
64 [self finishExecuting];
65 }];
66 });
67}
68
69- (void)dealloc
70{
71 [super dealloc];
72}
73
74@end
075
=== modified file 'Files/U1DataRepository.h'
--- Files/U1DataRepository.h 2011-09-08 16:59:34 +0000
+++ Files/U1DataRepository.h 2011-10-04 14:38:28 +0000
@@ -20,12 +20,16 @@
2020
2121
22@interface U1DataRepository : NSObject22@interface U1DataRepository : NSObject
2323+ (U1DataRepository*)sharedDataRepository;
24- (id)initWithStoreURL:(NSURL*)storeURL;24- (id)initWithStoreURL:(NSURL*)storeURL;
25- (BOOL)save:(NSError**)error;25- (BOOL)save:(NSError**)error;
2626
27- (U1Node*)nodeWithResourcePath:(NSString*)resourcePath;27- (U1Node*)nodeWithResourcePath:(NSString*)resourcePath;
2828
29//- (void)fetchResultsForEntityClass:(Class)entityClass matchingPredicate:(NSPredicate*)predicate withSortDescriptors:(NSArray*)sortDescriptors completionBlock:(void(^)(NSArray *results, NSError *error))completionBlock;
30
31- (NSArray*)resultsForEntityClass:(Class)entityClass matchingPredicate:(NSPredicate*)predicate withSortDescriptors:(NSArray*)sortDescriptors error:(NSError**)error;
32
29- (void)dispatchBlockWithManagedObjectContext:(void(^)(NSManagedObjectContext *context))block;33- (void)dispatchBlockWithManagedObjectContext:(void(^)(NSManagedObjectContext *context))block;
3034
31- (void)dispatchAsyncBlockWithManagedObjectContext:(void(^)(NSManagedObjectContext *context))block;35- (void)dispatchAsyncBlockWithManagedObjectContext:(void(^)(NSManagedObjectContext *context))block;
3236
=== modified file 'Files/U1DataRepository.m'
--- Files/U1DataRepository.m 2011-09-08 16:59:34 +0000
+++ Files/U1DataRepository.m 2011-10-04 14:38:28 +0000
@@ -19,6 +19,7 @@
1919
20#import "U1Node.h"20#import "U1Node.h"
2121
22static U1DataRepository *sharedDataRepository = nil;
2223
23@interface U1DataRepository ()24@interface U1DataRepository ()
2425
@@ -35,6 +36,48 @@
3536
36@synthesize model, mainContext, storeCoordinator;37@synthesize model, mainContext, storeCoordinator;
3738
39+ (U1DataRepository*)sharedDataRepository;
40{
41 if (sharedDataRepository == nil)
42 {
43 NSURL *cachesDirectory = [[[NSFileManager defaultManager] URLsForDirectory:NSCachesDirectory
44 inDomains:NSUserDomainMask] lastObject];
45 NSURL *storeURL = [NSURL URLWithString:@"U1Files.sqlite" relativeToURL:cachesDirectory];
46 sharedDataRepository = [[super allocWithZone:NULL] initWithStoreURL:storeURL];
47 }
48 return sharedDataRepository;
49}
50
51+ (id)allocWithZone:(NSZone *)zone;
52{
53 return [[self sharedDataRepository] retain];
54}
55
56- (id)copyWithZone:(NSZone *)zone;
57{
58 return self;
59}
60
61- (id)retain;
62{
63 return self;
64}
65
66- (NSUInteger)retainCount;
67{
68 return NSUIntegerMax;
69}
70
71- (void)release;
72{
73
74}
75
76- (id)autorelease;
77{
78 return self;
79}
80
38- (id)initWithStoreURL:(NSURL*)storeURL;81- (id)initWithStoreURL:(NSURL*)storeURL;
39{82{
40 if (!(self = [super init]))83 if (!(self = [super init]))
@@ -93,6 +136,16 @@
93 return node;136 return node;
94}137}
95138
139//- (void)fetchResultsForEntityClass:(Class)entityClass matchingPredicate:(NSPredicate*)predicate withSortDescriptors:(NSArray*)sortDescriptors completionBlock:(void(^)(NSArray *results, NSError *error))completionBlock;
140//{
141//
142//}
143
144- (NSArray*)resultsForEntityClass:(Class)entityClass matchingPredicate:(NSPredicate*)predicate withSortDescriptors:(NSArray*)sortDescriptors error:(NSError**)error;
145{
146 return [self fetchEntitiesForClass:entityClass inContext:self.mainContext withPredicate:predicate sortDescriptors:sortDescriptors error:error];
147}
148
96- (NSArray*)fetchEntitiesForClass:(Class)class inContext:(NSManagedObjectContext*)context withPredicate:(NSPredicate*)predicate sortDescriptors:(NSArray*)sortDescriptors error:(NSError**)error;149- (NSArray*)fetchEntitiesForClass:(Class)class inContext:(NSManagedObjectContext*)context withPredicate:(NSPredicate*)predicate sortDescriptors:(NSArray*)sortDescriptors error:(NSError**)error;
97{150{
98 NSParameterAssert(class != nil);151 NSParameterAssert(class != nil);
99152
=== modified file 'Files/U1FilePreviewViewController.m'
--- Files/U1FilePreviewViewController.m 2011-09-27 14:36:00 +0000
+++ Files/U1FilePreviewViewController.m 2011-10-04 14:38:28 +0000
@@ -78,6 +78,7 @@
78 self = [super initWithNibName:@"U1FilePreviewViewController" bundle:nil];78 self = [super initWithNibName:@"U1FilePreviewViewController" bundle:nil];
79 if (self == nil)79 if (self == nil)
80 return nil;80 return nil;
81 filesClient = [U1FilesClient sharedFilesClient];
81 self.node = theNode;82 self.node = theNode;
82 self.title = [node.path lastPathComponent];83 self.title = [node.path lastPathComponent];
83 84
8485
=== modified file 'Files/U1Files.xcdatamodeld/.xccurrentversion'
--- Files/U1Files.xcdatamodeld/.xccurrentversion 2011-09-08 16:59:34 +0000
+++ Files/U1Files.xcdatamodeld/.xccurrentversion 2011-10-04 14:38:28 +0000
@@ -3,6 +3,6 @@
3<plist version="1.0">3<plist version="1.0">
4<dict>4<dict>
5 <key>_XCCurrentVersionName</key>5 <key>_XCCurrentVersionName</key>
6 <string>U1Files.xcdatamodel</string>6 <string>U1Files 1.0-3.xcdatamodel</string>
7</dict>7</dict>
8</plist>8</plist>
99
=== added directory 'Files/U1Files.xcdatamodeld/U1Files 1.0-3.xcdatamodel'
=== added file 'Files/U1Files.xcdatamodeld/U1Files 1.0-3.xcdatamodel/elements'
10Binary files Files/U1Files.xcdatamodeld/U1Files 1.0-3.xcdatamodel/elements 1970-01-01 00:00:00 +0000 and Files/U1Files.xcdatamodeld/U1Files 1.0-3.xcdatamodel/elements 2011-10-04 14:38:28 +0000 differ10Binary files Files/U1Files.xcdatamodeld/U1Files 1.0-3.xcdatamodel/elements 1970-01-01 00:00:00 +0000 and Files/U1Files.xcdatamodeld/U1Files 1.0-3.xcdatamodel/elements 2011-10-04 14:38:28 +0000 differ
=== added file 'Files/U1Files.xcdatamodeld/U1Files 1.0-3.xcdatamodel/layout'
11Binary files Files/U1Files.xcdatamodeld/U1Files 1.0-3.xcdatamodel/layout 1970-01-01 00:00:00 +0000 and Files/U1Files.xcdatamodeld/U1Files 1.0-3.xcdatamodel/layout 2011-10-04 14:38:28 +0000 differ11Binary files Files/U1Files.xcdatamodeld/U1Files 1.0-3.xcdatamodel/layout 1970-01-01 00:00:00 +0000 and Files/U1Files.xcdatamodeld/U1Files 1.0-3.xcdatamodel/layout 2011-10-04 14:38:28 +0000 differ
=== modified file 'Files/U1Files.xcdatamodeld/U1Files.xcdatamodel/elements'
12Binary files Files/U1Files.xcdatamodeld/U1Files.xcdatamodel/elements 2011-09-08 16:59:34 +0000 and Files/U1Files.xcdatamodeld/U1Files.xcdatamodel/elements 2011-10-04 14:38:28 +0000 differ12Binary files Files/U1Files.xcdatamodeld/U1Files.xcdatamodel/elements 2011-09-08 16:59:34 +0000 and Files/U1Files.xcdatamodeld/U1Files.xcdatamodel/elements 2011-10-04 14:38:28 +0000 differ
=== modified file 'Files/U1Files.xcdatamodeld/U1Files.xcdatamodel/layout'
13Binary files Files/U1Files.xcdatamodeld/U1Files.xcdatamodel/layout 2011-09-08 16:59:34 +0000 and Files/U1Files.xcdatamodeld/U1Files.xcdatamodel/layout 2011-10-04 14:38:28 +0000 differ13Binary files Files/U1Files.xcdatamodeld/U1Files.xcdatamodel/layout 2011-09-08 16:59:34 +0000 and Files/U1Files.xcdatamodeld/U1Files.xcdatamodel/layout 2011-10-04 14:38:28 +0000 differ
=== modified file 'Files/U1FilesClient.h'
--- Files/U1FilesClient.h 2011-09-27 14:36:00 +0000
+++ Files/U1FilesClient.h 2011-10-04 14:38:28 +0000
@@ -16,7 +16,7 @@
16#import <Foundation/Foundation.h>16#import <Foundation/Foundation.h>
1717
18@class NSFetchedResultsController;18@class NSFetchedResultsController;
19@class U1Node, U1FileNode, U1FolderNode, U1NodeChildrenResultSet, U1LocalFileInfo;19@class U1Node, U1FileNode, U1FolderNode, U1NodeChildrenResultSet, U1Volume, U1LocalFileInfo;
20@class U1DataRepository, U1FilesService;20@class U1DataRepository, U1FilesService;
2121
2222
@@ -25,11 +25,16 @@
25@property (retain) U1DataRepository *dataRepository;25@property (retain) U1DataRepository *dataRepository;
26@property (retain) U1FilesService *filesService;26@property (retain) U1FilesService *filesService;
2727
28+ (U1FilesClient *)sharedFilesClient;
29
30- (id)volumesWithCompletionBlock:(void(^)(NSArray *volumes, NSError *error))completionBlock;
28- (id)fetchNodeWithResourcePath:(NSString*)nodePath completionBlock:(void(^)(U1Node *node, NSFetchedResultsController *childrenResultsController, NSError *error))completionBlock;31- (id)fetchNodeWithResourcePath:(NSString*)nodePath completionBlock:(void(^)(U1Node *node, NSFetchedResultsController *childrenResultsController, NSError *error))completionBlock;
29- (id)deleteNode:(U1Node*)node completionBlock:(void(^)(NSError *error))completionBlock;32- (id)deleteNode:(U1Node*)node completionBlock:(void(^)(NSError *error))completionBlock;
30- (id)uploadContentData:(NSData*)contentData toFolder:(U1FolderNode*)folderNode withResourceName:(NSString*)resourceName progressBlock:(void(^)(long long bytesUploaded, long long totalBytes))progressBlock completionBlock:(void(^)(U1FileNode *updatedNode, NSError *error))completionBlock;33- (id)uploadContentData:(NSData*)contentData toFolder:(U1FolderNode*)folderNode withResourceName:(NSString*)resourceName progressBlock:(void(^)(long long bytesUploaded, long long totalBytes))progressBlock completionBlock:(void(^)(U1FileNode *updatedNode, NSError *error))completionBlock;
31- (id)publishNode:(U1FileNode*)node completionBlock:(void(^)(U1FileNode *node, NSError *error))completionBlock;34- (id)publishNode:(U1FileNode*)node completionBlock:(void(^)(U1FileNode *node, NSError *error))completionBlock;
32- (id)unpublishNode:(U1FileNode*)node completionBlock:(void(^)(U1FileNode *node, NSError *error))completionBlock;35- (id)unpublishNode:(U1FileNode*)node completionBlock:(void(^)(U1FileNode *node, NSError *error))completionBlock;
36- (id)createFolderNamed:(NSString*)name inFolder:(U1FolderNode*)folderNode completionBlock:(void(^)(U1FolderNode *newFolderNode, NSError *error))completionBlock;
37- (id)createVolumeAtPath:(NSString*)folderPath completionBlock:(void(^)(U1Volume *volume, NSError *error))completionBlock;
33- (BOOL)isNodeSavedLocally:(U1FileNode*)node;38- (BOOL)isNodeSavedLocally:(U1FileNode*)node;
34- (U1LocalFileInfo*)localInfoForNode:(U1FileNode*)node;39- (U1LocalFileInfo*)localInfoForNode:(U1FileNode*)node;
3540
3641
=== modified file 'Files/U1FilesClient.m'
--- Files/U1FilesClient.m 2011-09-27 14:36:00 +0000
+++ Files/U1FilesClient.m 2011-10-04 14:38:28 +0000
@@ -23,22 +23,93 @@
23#import "U1FolderNode.h"23#import "U1FolderNode.h"
24#import "U1LocalFileInfo.h"24#import "U1LocalFileInfo.h"
25#import "U1Node.h"25#import "U1Node.h"
26#import "U1Volume.h"
2627
2728
28@interface U1FilesClient ()29@interface U1FilesClient ()
29- (NSURL*)fileURLForNode:(U1FileNode*)node;30- (NSURL*)fileURLForNode:(U1FileNode*)node;
30@end31@end
3132
33static U1FilesClient *sharedFilesClient = nil;
3234
33@implementation U1FilesClient35@implementation U1FilesClient
3436
35@synthesize dataRepository, filesService;37@synthesize dataRepository, filesService;
3638
37- (void)dealloc;39+ (U1FilesClient*)sharedFilesClient;
38{40{
39 [dataRepository release];41 if (sharedFilesClient == nil)
40 [filesService release];42 {
41 [super dealloc];43 sharedFilesClient = [[super allocWithZone:NULL] init];
44 }
45 return sharedFilesClient;
46}
47
48+ (id)allocWithZone:(NSZone *)zone;
49{
50 return [[self sharedFilesClient] retain];
51}
52
53- (id)copyWithZone:(NSZone *)zone;
54{
55 return self;
56}
57
58- (id)retain;
59{
60 return self;
61}
62
63- (NSUInteger)retainCount;
64{
65 return NSUIntegerMax;
66}
67
68- (void)release;
69{
70
71}
72
73- (id)autorelease;
74{
75 return self;
76}
77
78- (id)init;
79{
80 self = [super init];
81 if (self == nil)
82 return nil;
83 dataRepository = [U1DataRepository sharedDataRepository];
84 filesService = [U1FilesService sharedFilesService];
85 return self;
86}
87
88- (id)volumesWithCompletionBlock:(void(^)(NSArray *volumes, NSError *error))completionBlock;
89{
90 NSParameterAssert(completionBlock != NULL);
91
92 [self.filesService volumeInfoWithCompletionBlock:^(NSArray *volumeInfos, NSError *error) {
93
94 NSMutableArray *volumes = [NSMutableArray array];
95 [self.dataRepository dispatchBlockWithManagedObjectContext:^(NSManagedObjectContext *context) {
96 for (NSDictionary *volumeInfo in volumeInfos)
97 {
98 NSString *path = [volumeInfo objectForKey:@"path"];
99 NSPredicate *p = [NSPredicate predicateWithFormat:@"path = %@", path];
100 U1Volume *volume = [[self.dataRepository resultsForEntityClass:[U1Volume class] matchingPredicate:p withSortDescriptors:nil error:NULL] lastObject];
101 if (!volume)
102 {
103 volume = [U1Volume insertInManagedObjectContext:context];
104 }
105 [volume updatePropertiesFromJSONDictionary:volumeInfo];
106 [volumes addObject:volume];
107 }
108 [context save:NULL];
109 }];
110 completionBlock(volumes, error);
111 }];
112 return nil;
42}113}
43114
44- (id)fetchNodeWithResourcePath:(NSString*)nodePath completionBlock:(void(^)(U1Node *node, NSFetchedResultsController *childrenResultsController, NSError *error))completionBlock;115- (id)fetchNodeWithResourcePath:(NSString*)nodePath completionBlock:(void(^)(U1Node *node, NSFetchedResultsController *childrenResultsController, NSError *error))completionBlock;
@@ -144,9 +215,18 @@
144 }215 }
145 216
146 return [self.filesService uploadContentData:contentData forNode:node progressBlock:progressBlock completionBlock:^(NSDictionary *updatedNodeInfo, NSError *error) {217 return [self.filesService uploadContentData:contentData forNode:node progressBlock:progressBlock completionBlock:^(NSDictionary *updatedNodeInfo, NSError *error) {
147 218 if (error != nil)
148 [node updatePropertiesFromJSONDictionary:updatedNodeInfo];219 {
149 completionBlock(node, error);220 [self.dataRepository dispatchBlockWithManagedObjectContext:^(NSManagedObjectContext *context) {
221 [context deleteObject:node];
222 }];
223 completionBlock(nil, error);
224 }
225 else
226 {
227 [node updatePropertiesFromJSONDictionary:updatedNodeInfo];
228 completionBlock(node, error);
229 }
150 }];230 }];
151}231}
152232
@@ -160,6 +240,42 @@
160 return [self.filesService unpublishNode:node completionBlock:completionBlock];240 return [self.filesService unpublishNode:node completionBlock:completionBlock];
161}241}
162242
243- (id)createFolderNamed:(NSString*)name inFolder:(U1FolderNode*)folderNode completionBlock:(void(^)(U1FolderNode *newFolderNode, NSError *error))completionBlock;
244{
245 NSString *resourcePath = folderNode.resourcePath;
246 resourcePath = [resourcePath stringByAppendingPathComponent:name];
247
248 U1FolderNode *node = (id)[self.dataRepository nodeWithResourcePath:resourcePath];
249 if (!node)
250 {
251 [self.dataRepository dispatchBlockWithManagedObjectContext:^(NSManagedObjectContext *context) {
252 U1FolderNode *newNode = [U1FolderNode insertInManagedObjectContext:context];
253 newNode.resourcePath = resourcePath;
254 newNode.kind = @"directory";
255 newNode.contentPath = [folderNode.contentPath stringByAppendingPathComponent:name];
256 newNode.parent = folderNode;
257 [context save:NULL];
258 }];
259 node = (id)[self.dataRepository nodeWithResourcePath:resourcePath];
260 }
261
262 return [self.filesService createFolderAtPath:resourcePath completionBlock:^(NSDictionary *nodeInfo, NSError *error) {
263 [node updatePropertiesFromJSONDictionary:nodeInfo];
264 completionBlock(node, error);
265 }];
266}
267
268- (id)createVolumeAtPath:(NSString*)folderPath completionBlock:(void(^)(U1Volume *volume, NSError *error))completionBlock;
269{
270 return [self.filesService createVolumeAtPath:folderPath completionBlock:^(NSDictionary *volumeInfo, NSError *error) {
271 [self.dataRepository dispatchBlockWithManagedObjectContext:^(NSManagedObjectContext *context) {
272 U1Volume *volume = [U1Volume insertInManagedObjectContext:context];
273 [volume updatePropertiesFromJSONDictionary:volumeInfo];
274 completionBlock(volume, error);
275 }];
276 }];
277}
278
163- (BOOL)isNodeSavedLocally:(U1FileNode*)node;279- (BOOL)isNodeSavedLocally:(U1FileNode*)node;
164{280{
165 NSString *contentPath = node.contentPath;281 NSString *contentPath = node.contentPath;
166282
=== modified file 'Files/U1FilesService.h'
--- Files/U1FilesService.h 2011-09-08 16:59:34 +0000
+++ Files/U1FilesService.h 2011-10-04 14:38:28 +0000
@@ -15,12 +15,12 @@
1515
16#import <Foundation/Foundation.h>16#import <Foundation/Foundation.h>
1717
18@class U1Node, U1FileNode;18@class U1Node, U1FileNode, U1FolderNode;
1919
2020
21@interface U1FilesService : NSObject21@interface U1FilesService : NSObject
2222+ (U1FilesService *)sharedFilesService;
23- (id)volumeInfoWithCompletionBlock:(void(^)(NSArray *volumeInfo, NSError *error))completionBlock;23- (id)volumeInfoWithCompletionBlock:(void(^)(NSArray *volumeInfos, NSError *error))completionBlock;
2424
25- (id)infoForNodeAtResourcePath:(NSString*)resourcePath includeChildren:(BOOL)includeChildren completionBlock:(void(^)(NSDictionary *node, NSError *error))completionBlock;25- (id)infoForNodeAtResourcePath:(NSString*)resourcePath includeChildren:(BOOL)includeChildren completionBlock:(void(^)(NSDictionary *node, NSError *error))completionBlock;
26- (id)infoForNode:(U1Node*)node includeChildren:(BOOL)includeChildren completionBlock:(void(^)(NSDictionary *node, NSError *error))completionBlock;26- (id)infoForNode:(U1Node*)node includeChildren:(BOOL)includeChildren completionBlock:(void(^)(NSDictionary *node, NSError *error))completionBlock;
@@ -30,5 +30,7 @@
30- (id)deleteNodeAtResourcePath:(NSString*)resourcePath completionBlock:(void(^)(NSError *error))completionBlock;30- (id)deleteNodeAtResourcePath:(NSString*)resourcePath completionBlock:(void(^)(NSError *error))completionBlock;
31- (id)publishNode:(U1FileNode*)node completionBlock:(void(^)(U1FileNode *node, NSError *error))completionBlock;31- (id)publishNode:(U1FileNode*)node completionBlock:(void(^)(U1FileNode *node, NSError *error))completionBlock;
32- (id)unpublishNode:(U1FileNode*)node completionBlock:(void(^)(U1FileNode *node, NSError *error))completionBlock;32- (id)unpublishNode:(U1FileNode*)node completionBlock:(void(^)(U1FileNode *node, NSError *error))completionBlock;
33- (id)createFolderAtPath:(NSString*)folderPath completionBlock:(void(^)(NSDictionary *nodeInfo, NSError *error))completionBlock;
34- (id)createVolumeAtPath:(NSString*)folderPath completionBlock:(void(^)(NSDictionary *volumeInfo, NSError *error))completionBlock;
3335
34@end36@end
3537
=== modified file 'Files/U1FilesService.m'
--- Files/U1FilesService.m 2011-09-27 14:36:00 +0000
+++ Files/U1FilesService.m 2011-10-04 14:38:28 +0000
@@ -23,11 +23,13 @@
23#import "U1Node.h"23#import "U1Node.h"
24#import "U1FileNode.h"24#import "U1FileNode.h"
2525
26static U1FilesService *sharedFilesService = nil;
2627
27@interface U1FilesService ()28@interface U1FilesService ()
2829
29@property (retain) NSOperationQueue *networkQueue;30@property (retain) NSOperationQueue *networkQueue;
3031
32- (NSURL*)URLForVolumeWithPath:(NSString*)volumePath;
31- (NSURL*)URLForNode:(NSString*)nodePath includeChildren:(BOOL)includeChildren;33- (NSURL*)URLForNode:(NSString*)nodePath includeChildren:(BOOL)includeChildren;
32- (id)execute:(NSString*)method toURL:(NSURL*)url withParameters:(NSDictionary*)parameters requestBody:(NSString*)body parseResponseBody:(BOOL)parseResponseBody completionBlock:(void(^)(id results, NSError *error))completionBlock;34- (id)execute:(NSString*)method toURL:(NSURL*)url withParameters:(NSDictionary*)parameters requestBody:(NSString*)body parseResponseBody:(BOOL)parseResponseBody completionBlock:(void(^)(id results, NSError *error))completionBlock;
33- (id)execute:(NSString*)method toURL:(NSURL*)url withParameters:(NSDictionary*)parameters requestData:(NSData*)bodyData contentType:(NSString*)contentType parseResponseBody:(BOOL)parseResponseBody completionBlock:(void(^)(id results, NSError *error))completionBlock;35- (id)execute:(NSString*)method toURL:(NSURL*)url withParameters:(NSDictionary*)parameters requestData:(NSData*)bodyData contentType:(NSString*)contentType parseResponseBody:(BOOL)parseResponseBody completionBlock:(void(^)(id results, NSError *error))completionBlock;
@@ -44,6 +46,45 @@
4446
45@synthesize networkQueue;47@synthesize networkQueue;
4648
49+ (U1FilesService*)sharedFilesService;
50{
51 if (sharedFilesService == nil)
52 {
53 sharedFilesService = [[super allocWithZone:NULL] init];
54 }
55 return sharedFilesService;
56}
57
58+ (id)allocWithZone:(NSZone *)zone;
59{
60 return [[self sharedFilesService] retain];
61}
62
63- (id)copyWithZone:(NSZone *)zone;
64{
65 return self;
66}
67
68- (id)retain;
69{
70 return self;
71}
72
73- (NSUInteger)retainCount;
74{
75 return NSUIntegerMax;
76}
77
78- (void)release;
79{
80
81}
82
83- (id)autorelease;
84{
85 return self;
86}
87
47- (id)init;88- (id)init;
48{89{
49 self = [super init];90 self = [super init];
@@ -59,7 +100,7 @@
59 [super dealloc];100 [super dealloc];
60}101}
61102
62- (id)volumeInfoWithCompletionBlock:(void(^)(NSArray *volumeInfo, NSError *error))completionBlock;103- (id)volumeInfoWithCompletionBlock:(void(^)(NSArray *volumeInfos, NSError *error))completionBlock;
63{104{
64 NSURL *volumesURL = [self URLForNode:@"/volumes" includeChildren:NO];105 NSURL *volumesURL = [self URLForNode:@"/volumes" includeChildren:NO];
65 return [self execute:@"GET" toURL:volumesURL withParameters:nil requestBody:nil parseResponseBody:YES completionBlock:^(id results, NSError *error) {106 return [self execute:@"GET" toURL:volumesURL withParameters:nil requestBody:nil parseResponseBody:YES completionBlock:^(id results, NSError *error) {
@@ -205,9 +246,44 @@
205 }];246 }];
206}247}
207248
249- (id)createFolderAtPath:(NSString*)folderPath completionBlock:(void(^)(NSDictionary *nodeInfo, NSError *error))completionBlock;
250{
251 NSParameterAssert(folderPath != nil);
252 NSParameterAssert(completionBlock != NULL);
253
254 NSURL *nodeURL = [self URLForNode:folderPath includeChildren:NO];
255 return [self execute:@"PUT" toURL:nodeURL withParameters:nil requestBody:@"{\"kind\": \"directory\"}" parseResponseBody:YES completionBlock:^(id results, NSError *error) {
256 completionBlock(results, error);
257 }];
258}
259
260- (id)createVolumeAtPath:(NSString*)volumePath completionBlock:(void(^)(NSDictionary *volumeInfo, NSError *error))completionBlock;
261{
262 NSParameterAssert(volumePath != nil);
263 NSParameterAssert(completionBlock != NULL);
264
265 NSURL *volumeURL = [self URLForVolumeWithPath:volumePath];
266 return [self execute:@"PUT" toURL:volumeURL withParameters:nil requestBody:@"" parseResponseBody:YES completionBlock:^(id results, NSError *error) {
267 completionBlock(results, error);
268 }];
269}
270
208271
209#pragma mark Private Methods272#pragma mark Private Methods
210273
274- (NSURL*)URLForVolumeWithPath:(NSString*)volumePath;
275{
276 NSParameterAssert(volumePath != nil);
277 NSParameterAssert([volumePath hasPrefix:@"/"]);
278
279 NSMutableString *urlString = [NSMutableString stringWithString:U1FilesServiceAPIBase];
280 [urlString appendString:U1FilesServiceAPIPath];
281 [urlString appendString:U1FilesServiceAPIVersion1];
282 [urlString appendString:@"/volumes"];
283 [urlString appendString:volumePath];
284 return [NSURL URLWithString:[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
285}
286
211- (NSURL*)URLForNode:(NSString*)nodePath includeChildren:(BOOL)includeChildren;287- (NSURL*)URLForNode:(NSString*)nodePath includeChildren:(BOOL)includeChildren;
212{288{
213 NSMutableString *urlString = [NSMutableString stringWithString:U1FilesServiceAPIBase];289 NSMutableString *urlString = [NSMutableString stringWithString:U1FilesServiceAPIBase];
214290
=== modified file 'Files/U1FolderViewController.m'
--- Files/U1FolderViewController.m 2011-09-27 14:36:00 +0000
+++ Files/U1FolderViewController.m 2011-10-04 14:38:28 +0000
@@ -50,6 +50,7 @@
50 self.title = [theResourcePath lastPathComponent];50 self.title = [theResourcePath lastPathComponent];
51 self.resourcePath = [theResourcePath copy];51 self.resourcePath = [theResourcePath copy];
52 self.byteSizeTransformer = [[U1ByteSizeValueTransformer new] autorelease];52 self.byteSizeTransformer = [[U1ByteSizeValueTransformer new] autorelease];
53 filesClient = [U1FilesClient sharedFilesClient];
53 54
54 UIBarButtonItem *uploadItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(uploadImage:)];55 UIBarButtonItem *uploadItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(uploadImage:)];
55 [self.navigationItem setRightBarButtonItem:uploadItem];56 [self.navigationItem setRightBarButtonItem:uploadItem];
@@ -74,7 +75,6 @@
74- (void)dealloc;75- (void)dealloc;
75{76{
76 [loadingCell release];77 [loadingCell release];
77 [filesClient release];
78 [resourcePath release];78 [resourcePath release];
79 [node release];79 [node release];
80 [byteSizeTransformer release];80 [byteSizeTransformer release];
8181
=== added file 'Files/U1LocalAssetsManager.h'
--- Files/U1LocalAssetsManager.h 1970-01-01 00:00:00 +0000
+++ Files/U1LocalAssetsManager.h 2011-10-04 14:38:28 +0000
@@ -0,0 +1,29 @@
1//
2// Copyright 2011 Canonical Ltd.
3//
4// This program is free software: you can redistribute it and/or modify it
5// under the terms of the GNU Affero General Public License version 3,
6// as published by the Free Software Foundation.
7//
8// This program is distributed in the hope that it will be useful, but
9// WITHOUT ANY WARRANTY; without even the implied warranties of
10// MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11// PURPOSE. See the GNU Affero General Public License for more details.
12//
13// You should have received a copy of the GNU Affero General Public License
14// along with this program. If not, see <http://www.gnu.org/licenses/>.
15
16#import <Foundation/Foundation.h>
17
18@class U1DataRepository;
19@class U1Volume;
20
21
22@interface U1LocalAssetsManager : NSObject
23@property (retain) U1DataRepository *dataRepository;
24@property (retain) NSMutableArray *localAssetsToUpload;
25@property (retain) U1Volume *remoteUploadVolume;
26+ (U1LocalAssetsManager *)sharedFilesManager;
27- (void)checkForNewAssets;
28- (void)uploadPendingAssets;
29@end
030
=== added file 'Files/U1LocalAssetsManager.m'
--- Files/U1LocalAssetsManager.m 1970-01-01 00:00:00 +0000
+++ Files/U1LocalAssetsManager.m 2011-10-04 14:38:28 +0000
@@ -0,0 +1,209 @@
1//
2// Copyright 2011 Canonical Ltd.
3//
4// This program is free software: you can redistribute it and/or modify it
5// under the terms of the GNU Affero General Public License version 3,
6// as published by the Free Software Foundation.
7//
8// This program is distributed in the hope that it will be useful, but
9// WITHOUT ANY WARRANTY; without even the implied warranties of
10// MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11// PURPOSE. See the GNU Affero General Public License for more details.
12//
13// You should have received a copy of the GNU Affero General Public License
14// along with this program. If not, see <http://www.gnu.org/licenses/>.
15
16#import <AssetsLibrary/AssetsLibrary.h>
17
18#import "U1Asset.h"
19#import "U1DataRepository.h"
20#import "U1LocalAssetsManager.h"
21#import "U1AssetUploadOperation.h"
22#import "U1FilesClient.h"
23#import "U1Volume.h"
24
25@interface U1LocalAssetsManager ()
26@property (retain) ALAssetsLibrary *assetsLibrary;
27@property (retain) NSOperationQueue *uploadQueue;
28- (void)walkAssetsInLibrary;
29- (void)uploadRepresentation:(ALAssetRepresentation*)rep forAsset:(U1Asset*)asset;
30- (NSString *)generateFilenameForAsset:(ALAsset *)asset;
31@end
32
33static U1LocalAssetsManager *sharedFilesManager = nil;
34
35@implementation U1LocalAssetsManager
36
37@synthesize dataRepository, uploadQueue, localAssetsToUpload, remoteUploadVolume;
38@synthesize assetsLibrary;
39
40+ (U1LocalAssetsManager *)sharedFilesManager;
41{
42 if (sharedFilesManager == nil)
43 {
44 sharedFilesManager = [[super allocWithZone:NULL] init];
45 }
46 return sharedFilesManager;
47}
48
49+ (id)allocWithZone:(NSZone *)zone;
50{
51 return [[self sharedFilesManager] retain];
52}
53
54- (id)copyWithZone:(NSZone *)zone;
55{
56 return self;
57}
58
59- (id)retain;
60{
61 return self;
62}
63
64- (NSUInteger)retainCount;
65{
66 return NSUIntegerMax;
67}
68
69- (void)release;
70{
71
72}
73
74- (id)autorelease;
75{
76 return self;
77}
78
79- (id)init
80{
81 if (!(self = [super init]))
82 return nil;
83
84 assetsLibrary = [[ALAssetsLibrary alloc] init];
85 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(libraryChanged:) name:ALAssetsLibraryChangedNotification object:assetsLibrary];
86 dataRepository = [U1DataRepository sharedDataRepository];
87 uploadQueue = [[NSOperationQueue alloc] init];
88 self.localAssetsToUpload = [NSMutableArray array];
89 return self;
90}
91
92- (void)dealloc
93{
94 [[NSNotificationCenter defaultCenter] removeObserver:self];
95 [assetsLibrary release];
96 [super dealloc];
97}
98
99- (void)checkForNewAssets;
100{
101 NSLog(@"Checking for new assets.");
102 [self walkAssetsInLibrary];
103}
104
105- (void)libraryChanged:(NSNotification*)notification;
106{
107 NSLog(@"The library changed, so we'll walk the assets again.");
108 [self walkAssetsInLibrary];
109}
110
111- (void)walkAssetsInLibrary;
112{
113 [self.assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos
114 usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
115 [group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stop) {
116
117 ALAsset *someAsset = asset;
118 if (someAsset == nil)
119 return;
120 dispatch_async(dispatch_get_main_queue(), ^(void) {
121 ALAssetRepresentation *defaultRep = [someAsset defaultRepresentation];
122 NSString *assetURL = [[defaultRep url] absoluteString];
123 NSString *groupId = [group valueForProperty:ALAssetsGroupPropertyPersistentID];
124
125 NSPredicate *p = [NSPredicate predicateWithFormat:@"groupId = %@ and url = %@",
126 groupId, assetURL];
127 NSError *error = nil;
128 NSArray *results = [self.dataRepository resultsForEntityClass:[U1Asset class] matchingPredicate:p withSortDescriptors:nil error:&error];
129 U1Asset *trackedAsset = [results lastObject];
130 NSLog(@"Did we find an asset? (%@)", [trackedAsset description]);
131 if (trackedAsset == nil)
132 {
133 if ([[someAsset valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypePhoto]) {
134 [self.dataRepository dispatchBlockWithManagedObjectContext:^(NSManagedObjectContext *context) {
135
136 U1Asset *newAsset = [U1Asset insertInManagedObjectContext:context];
137 newAsset.groupId = groupId;
138 newAsset.url = assetURL;
139 newAsset.filename = [self generateFilenameForAsset:someAsset];
140 NSLog(@"Adding and uploading an asset for %@ (filename: %@)", newAsset.url, newAsset.filename);
141 [self.localAssetsToUpload addObject:newAsset];
142 [self uploadRepresentation:defaultRep forAsset:newAsset];
143 [self.dataRepository save:NULL];
144 }];
145 }
146 }
147 });
148 }];
149 }
150 failureBlock:^(NSError *error) {
151 NSLog(@"Some error happened.");
152 }];
153}
154
155- (NSString *)generateFilenameForAsset:(ALAsset *)asset;
156{
157 // get the type of the asset
158 NSString *ext = @"JPG";
159
160 if ([asset valueForProperty:ALAssetPropertyType] == ALAssetTypeVideo) {
161 ext = @"M4V";
162 }
163
164 NSError *error = nil;
165 int idx = [[self.dataRepository resultsForEntityClass:[U1Asset class]
166 matchingPredicate:nil
167 withSortDescriptors:nil
168 error:&error] count];
169
170 return [NSString stringWithFormat:@"IMG_%d.%@", idx, ext];
171}
172
173- (void)uploadPendingAssets;
174{
175 NSLog(@"Uploading %d assets", [self.localAssetsToUpload count]);
176 [self.localAssetsToUpload enumerateObjectsUsingBlock:^(U1Asset *obj, NSUInteger idx, BOOL *stop) {
177 [self.assetsLibrary assetForURL:[NSURL URLWithString:obj.url]
178 resultBlock:^(ALAsset *asset) {
179 [self uploadRepresentation:[asset defaultRepresentation] forAsset:obj];
180 } failureBlock:^(NSError *error) {
181 NSLog(@"Error: %@", error);
182 }];
183 }];
184}
185
186- (void)uploadRepresentation:(ALAssetRepresentation *)rep forAsset:(U1Asset *)asset
187{
188 // iterate self.localAssetsToUpload, creating NSOperations for each, giving each a completionBlock to remove the asset from localAssetsToUpload if it completed properly
189 Byte *buffer = (Byte*)malloc(rep.size);
190 NSUInteger length = [rep getBytes:buffer fromOffset:0 length:rep.size error:nil];
191 NSData *assetData = [NSData dataWithBytesNoCopy:buffer length:length freeWhenDone:YES];
192
193 U1AssetUploadOperation *operation = [[U1AssetUploadOperation alloc] init];
194 operation.asset = asset;
195 operation.folder = [self.remoteUploadVolume rootFolder];
196 operation.filename = asset.filename;
197 operation.assetData = assetData;
198 [operation setCompletionBlock:^{
199 dispatch_async(dispatch_get_main_queue(), ^(void) {
200 if (operation.error == nil) // or the error is somehow unrecoverable (e.g., over quota)
201 {
202 [self.localAssetsToUpload removeObject:asset];
203 }
204 });
205 }];
206 [self.uploadQueue addOperation:operation];
207}
208
209@end
0210
=== modified file 'Files/U1Volume.h'
--- Files/U1Volume.h 2011-09-08 16:59:34 +0000
+++ Files/U1Volume.h 2011-10-04 14:38:28 +0000
@@ -1,5 +1,22 @@
1//
2// Copyright 2011 Canonical Ltd.
3//
4// This program is free software: you can redistribute it and/or modify it
5// under the terms of the GNU Affero General Public License version 3,
6// as published by the Free Software Foundation.
7//
8// This program is distributed in the hope that it will be useful, but
9// WITHOUT ANY WARRANTY; without even the implied warranties of
10// MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11// PURPOSE. See the GNU Affero General Public License for more details.
12//
13// You should have received a copy of the GNU Affero General Public License
14// along with this program. If not, see <http://www.gnu.org/licenses/>.
15
1#import "_U1Volume.h"16#import "_U1Volume.h"
17#import "U1FolderNode.h"
18
219
3@interface U1Volume : _U1Volume {}20@interface U1Volume : _U1Volume {}
4// Custom logic goes here.21- (U1FolderNode *)rootFolder;
5@end22@end
623
=== modified file 'Files/U1Volume.m'
--- Files/U1Volume.m 2011-09-08 16:59:34 +0000
+++ Files/U1Volume.m 2011-10-04 14:38:28 +0000
@@ -1,7 +1,59 @@
1//
2// Copyright 2011 Canonical Ltd.
3//
4// This program is free software: you can redistribute it and/or modify it
5// under the terms of the GNU Affero General Public License version 3,
6// as published by the Free Software Foundation.
7//
8// This program is distributed in the hope that it will be useful, but
9// WITHOUT ANY WARRANTY; without even the implied warranties of
10// MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11// PURPOSE. See the GNU Affero General Public License for more details.
12//
13// You should have received a copy of the GNU Affero General Public License
14// along with this program. If not, see <http://www.gnu.org/licenses/>.
15
1#import "U1Volume.h"16#import "U1Volume.h"
17#import "U1FolderNode.h"
18#import "U1DataRepository.h"
19
220
3@implementation U1Volume21@implementation U1Volume
422
5// Custom logic goes here.23- (void)updatePropertiesFromJSONDictionary:(NSDictionary *)jsonDictionary;
24{
25 [super updatePropertiesFromJSONDictionary:jsonDictionary];
26 self.nodePath = [jsonDictionary objectForKey:@"node_path"];
27}
28
29- (U1FolderNode *)rootFolder;
30{
31 // Look up a U1FolderNode with us as the volume path and some part of us as its name?
32 // If it doesn't exist, create it, and return it.
33 U1DataRepository *dataRepository = [U1DataRepository sharedDataRepository];
34 NSPredicate *p = [NSPredicate predicateWithFormat:@"resourcePath = %@", self.nodePath];
35 NSError *error = nil;
36 NSArray *results = [dataRepository resultsForEntityClass:[U1FolderNode class] matchingPredicate:p withSortDescriptors:nil error:&error];
37 U1FolderNode *rootFolder = [results lastObject];
38 NSLog(@"Did we find a root folder? (%@)", [rootFolder description]);
39
40 if (rootFolder == nil)
41 {
42 // Upload
43 [dataRepository dispatchBlockWithManagedObjectContext:^(NSManagedObjectContext *context) {
44
45 U1FolderNode *rootFolder = [U1FolderNode insertInManagedObjectContext:context];
46 rootFolder.resourcePath = self.nodePath;
47 rootFolder.contentPath = self.contentPath;
48 NSLog(@"Adding a rootFolder node for %@", self.nodePath);
49 [dataRepository save:NULL];
50 }];
51
52 results = [dataRepository resultsForEntityClass:[U1FolderNode class] matchingPredicate:p withSortDescriptors:nil error:&error];
53 rootFolder = [results lastObject];
54 }
55
56 return rootFolder;
57}
658
7@end59@end
860
=== modified file 'Files/U1VolumesViewController.h'
--- Files/U1VolumesViewController.h 2011-08-31 14:56:30 +0000
+++ Files/U1VolumesViewController.h 2011-10-04 14:38:28 +0000
@@ -17,7 +17,8 @@
1717
18#import "PullRefreshTableViewController.h"18#import "PullRefreshTableViewController.h"
1919
20@class U1FilesService;20@class U1FilesClient;
21@class U1Volume;
2122
22@protocol U1VolumesViewControllerDelegate;23@protocol U1VolumesViewControllerDelegate;
2324
@@ -27,12 +28,12 @@
27@property (nonatomic, retain, readonly) IBOutlet UITableViewCell *loadingCell;28@property (nonatomic, retain, readonly) IBOutlet UITableViewCell *loadingCell;
2829
29@property (assign) id<U1VolumesViewControllerDelegate> delegate;30@property (assign) id<U1VolumesViewControllerDelegate> delegate;
30@property (nonatomic, retain) U1FilesService *filesService;31@property (retain) U1FilesClient *filesClient;
3132
32@end33@end
3334
3435
35@protocol U1VolumesViewControllerDelegate <NSObject>36@protocol U1VolumesViewControllerDelegate <NSObject>
36@required37@required
37- (void)volumesController:(U1VolumesViewController*)volumesController didSelectVolume:(NSDictionary*)volume;38- (void)volumesController:(U1VolumesViewController*)volumesController didSelectVolume:(U1Volume*)volume;
38@end39@end
3940
=== modified file 'Files/U1VolumesViewController.m'
--- Files/U1VolumesViewController.m 2011-09-27 14:36:00 +0000
+++ Files/U1VolumesViewController.m 2011-10-04 14:38:28 +0000
@@ -15,18 +15,20 @@
1515
16#import "U1VolumesViewController.h"16#import "U1VolumesViewController.h"
1717
18#import "U1FilesService.h"18#import "U1FilesClient.h"
19#import "U1Volume.h"
1920
2021
21@interface U1VolumesViewController ()22@interface U1VolumesViewController ()
22@property (retain) NSArray *volumes;23@property (retain) NSArray *volumes;
24- (void)loadVolumes;
23@end25@end
2426
2527
26@implementation U1VolumesViewController28@implementation U1VolumesViewController
2729
28@synthesize loadingCell;30@synthesize loadingCell;
29@synthesize delegate, filesService;31@synthesize delegate, filesClient;
30@synthesize volumes;32@synthesize volumes;
3133
32- (id)init;34- (id)init;
@@ -35,6 +37,7 @@
35 if (!self)37 if (!self)
36 return nil;38 return nil;
37 self.title = NSLocalizedString(@"Home", @"");39 self.title = NSLocalizedString(@"Home", @"");
40 filesClient = [U1FilesClient sharedFilesClient];
38 UIImage *logoImage = [UIImage imageNamed:@"logo_4_white"];41 UIImage *logoImage = [UIImage imageNamed:@"logo_4_white"];
39 UIImageView *logoView = [[UIImageView alloc] initWithImage:logoImage];42 UIImageView *logoView = [[UIImageView alloc] initWithImage:logoImage];
40 [self.navigationItem setTitleView:logoView];43 [self.navigationItem setTitleView:logoView];
@@ -45,7 +48,6 @@
45- (void)dealloc;48- (void)dealloc;
46{49{
47 [loadingCell release];50 [loadingCell release];
48 [filesService release];
49 [volumes release];51 [volumes release];
50 [super dealloc];52 [super dealloc];
51}53}
@@ -53,12 +55,18 @@
53- (void)viewDidLoad;55- (void)viewDidLoad;
54{56{
55 [super viewDidLoad];57 [super viewDidLoad];
56 [self.filesService volumeInfoWithCompletionBlock:^(NSArray *volumeInfo, NSError *error) {58 [self.filesClient volumesWithCompletionBlock:^(NSArray *volumeInfos, NSError *error) {
57 dispatch_async(dispatch_get_main_queue(), ^(void) {59 dispatch_async(dispatch_get_main_queue(), ^(void) {
58 self.volumes = volumeInfo;60 self.volumes = volumeInfos;
59 [self.tableView reloadData];61 [self.tableView reloadData];
60 });62 });
61 }];63 }];
64 [self loadVolumes];
65}
66
67- (void)refresh;
68{
69 [self loadVolumes];
62}70}
6371
64- (void)viewDidUnload;72- (void)viewDidUnload;
@@ -93,8 +101,8 @@
93 [cell setSelectionStyle:UITableViewCellSelectionStyleGray];101 [cell setSelectionStyle:UITableViewCellSelectionStyleGray];
94 [cell.imageView setImage:[UIImage imageNamed:@"ic_folder"]];102 [cell.imageView setImage:[UIImage imageNamed:@"ic_folder"]];
95 }103 }
96 NSDictionary *volume = [self.volumes objectAtIndex:indexPath.row];104 U1Volume *volume = [self.volumes objectAtIndex:indexPath.row];
97 NSString *volumePath = [volume objectForKey:@"path"];105 NSString *volumePath = volume.path;
98 if ([@"~/.ubuntuone/Purchased from Ubuntu One" isEqualToString:volumePath])106 if ([@"~/.ubuntuone/Purchased from Ubuntu One" isEqualToString:volumePath])
99 volumePath = @"Purchased Music";107 volumePath = @"Purchased Music";
100 if ([volumePath hasPrefix:@"~/"])108 if ([volumePath hasPrefix:@"~/"])
@@ -106,8 +114,19 @@
106114
107- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;115- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
108{116{
109 NSDictionary *volume = [self.volumes objectAtIndex:indexPath.row];117 U1Volume *volume = [self.volumes objectAtIndex:indexPath.row];
110 [self.delegate volumesController:self didSelectVolume:volume];118 [self.delegate volumesController:self didSelectVolume:volume];
111}119}
112120
121- (void)loadVolumes;
122{
123 [self.filesClient volumesWithCompletionBlock:^(NSArray *volumeInfos, NSError *error) {
124 dispatch_async(dispatch_get_main_queue(), ^(void) {
125 self.volumes = volumeInfos;
126 [self stopLoading];
127 [self.tableView reloadData];
128 });
129 }];
130}
131
113@end132@end

Subscribers

People subscribed via source and target branches