├── .gitignore ├── App └── PutIOSync.app.zip ├── Assets.xcassets ├── AppIcon.appiconset │ ├── Contents.json │ ├── icon_128x128.png │ ├── icon_128x128@2x.png │ ├── icon_16x16.png │ ├── icon_16x16@2x.png │ ├── icon_256x256.png │ ├── icon_256x256@2x.png │ ├── icon_32x32.png │ └── icon_512x512.png ├── Contents.json ├── Status.imageset │ ├── Contents.json │ └── Status@3x.png ├── gearMenu.imageset │ ├── Contents.json │ └── gearMenu.png ├── iconPlaceholder.imageset │ ├── Contents.json │ └── iconPlaceholder.png ├── logo.imageset │ ├── Contents.json │ └── amblem.png ├── putioFolder.imageset │ ├── Contents.json │ └── folder@3x.png ├── resumeImage.imageset │ ├── Contents.json │ └── resumeImage.png ├── resumeImageInverted.imageset │ ├── Contents.json │ └── resumeImageInverted.png ├── stopImage.imageset │ ├── Contents.json │ └── stopImage.png ├── stopImageInverted.imageset │ ├── Contents.json │ └── stopImageInverted.png ├── syncIcon.imageset │ ├── Connection Sync Filled-100-dark.png │ ├── Connection Sync Filled-100.png │ └── Contents.json ├── syncRightArrow.imageset │ ├── Contents.json │ └── syncRightArrow.png ├── syncing.imageset │ ├── Contents.json │ └── syncing.png ├── systemFolder.imageset │ ├── Contents.json │ └── blank-1-(dragged).png ├── transfer.imageset │ ├── Contents.json │ └── transfer.png ├── transfer_failed.imageset │ ├── Contents.json │ └── transfer_failed.png └── transfer_finished.imageset │ ├── Contents.json │ └── transfer_finished.png ├── Classes ├── AccountPreferences.h ├── AccountPreferences.m ├── AccountSetupController.h ├── AccountSetupController.m ├── ApplicationDelegate.h ├── ApplicationDelegate.m ├── BackgroundView.h ├── BackgroundView.m ├── BytesFormatter.h ├── BytesFormatter.m ├── Download.h ├── Download.m ├── DownloadCellView.h ├── DownloadCellView.m ├── GeneralPreferences.h ├── GeneralPreferences.m ├── KnownItem.h ├── KnownItem.m ├── MASPreferencesViewController.h ├── MASPreferencesWindow.xib ├── MASPreferencesWindowController.h ├── MASPreferencesWindowController.m ├── MainPanel.h ├── MainPanel.m ├── MenubarController.h ├── MenubarController.m ├── NSDictionary+URLQueryString.h ├── NSDictionary+URLQueryString.m ├── Panel.h ├── Panel.m ├── PanelController.h ├── PanelController.m ├── PanelRowView.h ├── PanelRowView.m ├── Persistency.h ├── Persistency.m ├── PutIOAPI.h ├── PutIOAPI.m ├── PutIOAPIAccountInfo.h ├── PutIOAPIAccountInfo.m ├── PutIOAPIAccountInfoRequest.h ├── PutIOAPIAccountInfoRequest.m ├── PutIOAPIFile.h ├── PutIOAPIFile.m ├── PutIOAPIFileDeletionRequest.h ├── PutIOAPIFileDeletionRequest.m ├── PutIOAPIFileRequest.h ├── PutIOAPIFileRequest.m ├── PutIOAPIKeychainManager.h ├── PutIOAPIKeychainManager.m ├── PutIOAPIOAuthTokenRequest.h ├── PutIOAPIOAuthTokenRequest.m ├── PutIOAPIObject.h ├── PutIOAPIObject.m ├── PutIOAPIRequest.h ├── PutIOAPIRequest.m ├── PutIOAPITransfer.h ├── PutIOAPITransfer.m ├── PutIOAPITransfersRequest.h ├── PutIOAPITransfersRequest.m ├── PutIODownloadManager.h ├── PutIODownloadManager.m ├── PutIOFolderPicker.h ├── PutIOFolderPicker.m ├── PutIOSync-Prefix.pch ├── PutIOTransfersMonitor.h ├── PutIOTransfersMonitor.m ├── StatusItemView.h ├── StatusItemView.m ├── SyncInstruction.h ├── SyncInstruction.m ├── SyncInstructionEditor.h ├── SyncInstructionEditor.m ├── SyncPreferences.h ├── SyncPreferences.m ├── SyncRunner.h ├── SyncRunner.m ├── SyncScheduler.h ├── SyncScheduler.m ├── TimeIntervalFormatter.h ├── TimeIntervalFormatter.m ├── TransferCellView.h ├── TransferCellView.m ├── de.lproj │ └── SyncInstructionEditor.r4.xib ├── en.lproj │ ├── AccountPreferences.xib │ ├── AccountSetupController.xib │ ├── GeneralPreferences.xib │ ├── Localizable.strings │ ├── MainMenu.xib │ ├── MainPanel.xib │ ├── PutIOFolderPicker.xib │ ├── SyncInstructionEditor.r4.xib │ ├── SyncInstructionEditor.xib │ └── SyncPreferences.xib └── main.m ├── Frameworks └── Sparkle.framework │ ├── Headers │ ├── Modules │ ├── PrivateHeaders │ ├── Resources │ ├── Sparkle │ └── Versions │ ├── A │ ├── Headers │ │ ├── SUAppcast.h │ │ ├── SUAppcastItem.h │ │ ├── SUErrors.h │ │ ├── SUExport.h │ │ ├── SUStandardVersionComparator.h │ │ ├── SUUpdater.h │ │ ├── SUVersionComparisonProtocol.h │ │ ├── SUVersionDisplayProtocol.h │ │ └── Sparkle.h │ ├── Modules │ │ └── module.modulemap │ ├── PrivateHeaders │ │ └── SUUnarchiver.h │ ├── Resources │ │ ├── Autoupdate.app │ │ │ └── Contents │ │ │ │ ├── Info.plist │ │ │ │ ├── MacOS │ │ │ │ ├── Autoupdate │ │ │ │ └── fileop │ │ │ │ ├── PkgInfo │ │ │ │ └── Resources │ │ │ │ ├── AppIcon.icns │ │ │ │ ├── SUStatus.nib │ │ │ │ ├── ar.lproj │ │ │ │ └── Sparkle.strings │ │ │ │ ├── ca.lproj │ │ │ │ └── Sparkle.strings │ │ │ │ ├── cs.lproj │ │ │ │ └── Sparkle.strings │ │ │ │ ├── da.lproj │ │ │ │ └── Sparkle.strings │ │ │ │ ├── de.lproj │ │ │ │ └── Sparkle.strings │ │ │ │ ├── el.lproj │ │ │ │ └── Sparkle.strings │ │ │ │ ├── en.lproj │ │ │ │ └── Sparkle.strings │ │ │ │ ├── es.lproj │ │ │ │ └── Sparkle.strings │ │ │ │ ├── fi.lproj │ │ │ │ └── Sparkle.strings │ │ │ │ ├── fr.lproj │ │ │ │ └── Sparkle.strings │ │ │ │ ├── he.lproj │ │ │ │ └── Sparkle.strings │ │ │ │ ├── is.lproj │ │ │ │ └── Sparkle.strings │ │ │ │ ├── it.lproj │ │ │ │ └── Sparkle.strings │ │ │ │ ├── ja.lproj │ │ │ │ └── Sparkle.strings │ │ │ │ ├── ko.lproj │ │ │ │ └── Sparkle.strings │ │ │ │ ├── nb.lproj │ │ │ │ └── Sparkle.strings │ │ │ │ ├── nl.lproj │ │ │ │ └── Sparkle.strings │ │ │ │ ├── pl.lproj │ │ │ │ └── Sparkle.strings │ │ │ │ ├── pt_BR.lproj │ │ │ │ └── Sparkle.strings │ │ │ │ ├── pt_PT.lproj │ │ │ │ └── Sparkle.strings │ │ │ │ ├── ro.lproj │ │ │ │ └── Sparkle.strings │ │ │ │ ├── ru.lproj │ │ │ │ └── Sparkle.strings │ │ │ │ ├── sk.lproj │ │ │ │ └── Sparkle.strings │ │ │ │ ├── sl.lproj │ │ │ │ └── Sparkle.strings │ │ │ │ ├── sv.lproj │ │ │ │ └── Sparkle.strings │ │ │ │ ├── th.lproj │ │ │ │ └── Sparkle.strings │ │ │ │ ├── tr.lproj │ │ │ │ └── Sparkle.strings │ │ │ │ ├── uk.lproj │ │ │ │ └── Sparkle.strings │ │ │ │ ├── zh_CN.lproj │ │ │ │ └── Sparkle.strings │ │ │ │ └── zh_TW.lproj │ │ │ │ └── Sparkle.strings │ │ ├── Info.plist │ │ ├── SUModelTranslation.plist │ │ ├── SUStatus.nib │ │ ├── ar.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── ca.lproj │ │ │ └── Sparkle.strings │ │ ├── cs.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── da.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── de.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── el.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── en.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── es.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── fi.lproj │ │ │ └── Sparkle.strings │ │ ├── fr.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── fr_CA.lproj │ │ ├── he.lproj │ │ │ └── Sparkle.strings │ │ ├── is.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── it.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── ja.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── ko.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── nb.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── nl.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── pl.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── pt.lproj │ │ ├── pt_BR.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── pt_PT.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── ro.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── ru.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── sk.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── sl.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── sv.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── th.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── tr.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── uk.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── zh_CN.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ └── zh_TW.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ └── Sparkle │ └── Current ├── Icon.png ├── Model.xcdatamodeld ├── .xccurrentversion ├── Model 2.xcdatamodel │ └── contents ├── Model 3.xcdatamodel │ └── contents └── Model.xcdatamodel │ └── contents ├── PutIOSync-Info.plist ├── PutIOSync.xcodeproj ├── project.pbxproj ├── project.pbxproj.backup.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── PutIOSync.xccheckout │ └── xcuserdata │ │ └── matthias.xcuserdatad │ │ └── WorkspaceSettings.xcsettings ├── xcshareddata │ └── xcschemes │ │ └── PutIOSync.xcscheme └── xcuserdata │ └── matthias.xcuserdatad │ ├── xcdebugger │ └── Breakpoints.xcbkptlist │ └── xcschemes │ └── xcschememanagement.plist ├── README.md ├── Screenshots ├── account.png ├── menuitem.png ├── preferences.png ├── syncedfolder.png └── syncedfolders.png └── UserDefaults.plist /.gitignore: -------------------------------------------------------------------------------- 1 | /.DS_Store 2 | *.xcbkptlist 3 | *.xcuserstate 4 | PutIOSync.xcodeproj/project.xcworkspace/xcshareddata -------------------------------------------------------------------------------- /App/PutIOSync.app.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/App/PutIOSync.app.zip -------------------------------------------------------------------------------- /Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "icon_16x16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "icon_16x16@2x.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "icon_32x32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "idiom" : "mac", 23 | "size" : "32x32", 24 | "scale" : "2x" 25 | }, 26 | { 27 | "size" : "128x128", 28 | "idiom" : "mac", 29 | "filename" : "icon_128x128.png", 30 | "scale" : "1x" 31 | }, 32 | { 33 | "size" : "128x128", 34 | "idiom" : "mac", 35 | "filename" : "icon_128x128@2x.png", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "size" : "256x256", 40 | "idiom" : "mac", 41 | "filename" : "icon_256x256.png", 42 | "scale" : "1x" 43 | }, 44 | { 45 | "size" : "256x256", 46 | "idiom" : "mac", 47 | "filename" : "icon_256x256@2x.png", 48 | "scale" : "2x" 49 | }, 50 | { 51 | "size" : "512x512", 52 | "idiom" : "mac", 53 | "filename" : "icon_512x512.png", 54 | "scale" : "1x" 55 | }, 56 | { 57 | "idiom" : "mac", 58 | "size" : "512x512", 59 | "scale" : "2x" 60 | } 61 | ], 62 | "info" : { 63 | "version" : 1, 64 | "author" : "xcode" 65 | } 66 | } -------------------------------------------------------------------------------- /Assets.xcassets/AppIcon.appiconset/icon_128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Assets.xcassets/AppIcon.appiconset/icon_128x128.png -------------------------------------------------------------------------------- /Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png -------------------------------------------------------------------------------- /Assets.xcassets/AppIcon.appiconset/icon_16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Assets.xcassets/AppIcon.appiconset/icon_16x16.png -------------------------------------------------------------------------------- /Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.png -------------------------------------------------------------------------------- /Assets.xcassets/AppIcon.appiconset/icon_256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Assets.xcassets/AppIcon.appiconset/icon_256x256.png -------------------------------------------------------------------------------- /Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png -------------------------------------------------------------------------------- /Assets.xcassets/AppIcon.appiconset/icon_32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Assets.xcassets/AppIcon.appiconset/icon_32x32.png -------------------------------------------------------------------------------- /Assets.xcassets/AppIcon.appiconset/icon_512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Assets.xcassets/AppIcon.appiconset/icon_512x512.png -------------------------------------------------------------------------------- /Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Assets.xcassets/Status.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Status@3x.png" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } -------------------------------------------------------------------------------- /Assets.xcassets/Status.imageset/Status@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Assets.xcassets/Status.imageset/Status@3x.png -------------------------------------------------------------------------------- /Assets.xcassets/gearMenu.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "gearMenu.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "template" 23 | } 24 | } -------------------------------------------------------------------------------- /Assets.xcassets/gearMenu.imageset/gearMenu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Assets.xcassets/gearMenu.imageset/gearMenu.png -------------------------------------------------------------------------------- /Assets.xcassets/iconPlaceholder.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "iconPlaceholder.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Assets.xcassets/iconPlaceholder.imageset/iconPlaceholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Assets.xcassets/iconPlaceholder.imageset/iconPlaceholder.png -------------------------------------------------------------------------------- /Assets.xcassets/logo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "amblem.png" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Assets.xcassets/logo.imageset/amblem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Assets.xcassets/logo.imageset/amblem.png -------------------------------------------------------------------------------- /Assets.xcassets/putioFolder.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "folder@3x.png" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Assets.xcassets/putioFolder.imageset/folder@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Assets.xcassets/putioFolder.imageset/folder@3x.png -------------------------------------------------------------------------------- /Assets.xcassets/resumeImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "resumeImage.png" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Assets.xcassets/resumeImage.imageset/resumeImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Assets.xcassets/resumeImage.imageset/resumeImage.png -------------------------------------------------------------------------------- /Assets.xcassets/resumeImageInverted.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "resumeImageInverted.png" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Assets.xcassets/resumeImageInverted.imageset/resumeImageInverted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Assets.xcassets/resumeImageInverted.imageset/resumeImageInverted.png -------------------------------------------------------------------------------- /Assets.xcassets/stopImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "stopImage.png" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Assets.xcassets/stopImage.imageset/stopImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Assets.xcassets/stopImage.imageset/stopImage.png -------------------------------------------------------------------------------- /Assets.xcassets/stopImageInverted.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "stopImageInverted.png" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Assets.xcassets/stopImageInverted.imageset/stopImageInverted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Assets.xcassets/stopImageInverted.imageset/stopImageInverted.png -------------------------------------------------------------------------------- /Assets.xcassets/syncIcon.imageset/Connection Sync Filled-100-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Assets.xcassets/syncIcon.imageset/Connection Sync Filled-100-dark.png -------------------------------------------------------------------------------- /Assets.xcassets/syncIcon.imageset/Connection Sync Filled-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Assets.xcassets/syncIcon.imageset/Connection Sync Filled-100.png -------------------------------------------------------------------------------- /Assets.xcassets/syncIcon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Connection Sync Filled-100.png" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "Connection Sync Filled-100-dark.png", 10 | "appearances" : [ 11 | { 12 | "appearance" : "luminosity", 13 | "value" : "dark" 14 | } 15 | ] 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | }, 22 | "properties" : { 23 | "template-rendering-intent" : "template" 24 | } 25 | } -------------------------------------------------------------------------------- /Assets.xcassets/syncRightArrow.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "syncRightArrow.png" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Assets.xcassets/syncRightArrow.imageset/syncRightArrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Assets.xcassets/syncRightArrow.imageset/syncRightArrow.png -------------------------------------------------------------------------------- /Assets.xcassets/syncing.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "syncing.png" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } -------------------------------------------------------------------------------- /Assets.xcassets/syncing.imageset/syncing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Assets.xcassets/syncing.imageset/syncing.png -------------------------------------------------------------------------------- /Assets.xcassets/systemFolder.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "blank-1-(dragged).png" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Assets.xcassets/systemFolder.imageset/blank-1-(dragged).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Assets.xcassets/systemFolder.imageset/blank-1-(dragged).png -------------------------------------------------------------------------------- /Assets.xcassets/transfer.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "transfer.png" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } -------------------------------------------------------------------------------- /Assets.xcassets/transfer.imageset/transfer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Assets.xcassets/transfer.imageset/transfer.png -------------------------------------------------------------------------------- /Assets.xcassets/transfer_failed.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "transfer_failed.png" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Assets.xcassets/transfer_failed.imageset/transfer_failed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Assets.xcassets/transfer_failed.imageset/transfer_failed.png -------------------------------------------------------------------------------- /Assets.xcassets/transfer_finished.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "transfer_finished.png" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Assets.xcassets/transfer_finished.imageset/transfer_finished.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Assets.xcassets/transfer_finished.imageset/transfer_finished.png -------------------------------------------------------------------------------- /Classes/AccountPreferences.h: -------------------------------------------------------------------------------- 1 | 2 | #import "MASPreferencesViewController.h" 3 | 4 | #import "AccountSetupController.h" 5 | #import "PutIOAPI.h" 6 | 7 | @interface AccountPreferences : NSViewController 8 | 9 | { 10 | IBOutlet NSTextField *infoLabel; 11 | IBOutlet NSTextField *accountEMailAddressLabel; 12 | IBOutlet NSTextField *accountUsernameLabel; 13 | IBOutlet NSTextField *spaceLabel; 14 | IBOutlet NSButton *connectButton; 15 | 16 | IBOutlet NSProgressIndicator *activitySpinner; 17 | IBOutlet NSTextField *activityLabel; 18 | 19 | AccountSetupController *accountSetup; 20 | } 21 | 22 | @property (strong) PutIOAPI *putio; 23 | 24 | -(IBAction)connectAccountButtonClicked:(id)sender; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Classes/AccountSetupController.h: -------------------------------------------------------------------------------- 1 | 2 | @import Cocoa; 3 | @import WebKit; 4 | 5 | #import "PutIOAPI.h" 6 | 7 | @class AccountSetupController; 8 | @protocol AccountSetupControllerDelegate 9 | -(void)accountSetupController:(AccountSetupController*)c didFinishSetupWithOAuthAccessToken:(NSString*)token; 10 | -(void)accountSetupControllerDidCancelSetup:(AccountSetupController*)c; 11 | @end 12 | 13 | @interface AccountSetupController : NSWindowController 14 | { 15 | IBOutlet WebView *webView; 16 | IBOutlet NSProgressIndicator *spinner; 17 | BOOL loggingOut; 18 | PutIOAPI *putio; 19 | } 20 | 21 | @property (unsafe_unretained) id delegate; 22 | 23 | -(void)beginAccountSetup; 24 | -(IBAction)cancelButtonClicked:(id)sender; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Classes/AccountSetupController.m: -------------------------------------------------------------------------------- 1 | 2 | #import "AccountSetupController.h" 3 | #import "PutIOAPIOAuthTokenRequest.h" 4 | 5 | #define kAPISecret @"a4gz4pnrnxm2jxchok8v" 6 | 7 | @implementation AccountSetupController 8 | 9 | -(instancetype)init 10 | { 11 | self = [super initWithWindowNibName:NSStringFromClass([self class])]; 12 | if(self){ 13 | 14 | } 15 | return self; 16 | } 17 | 18 | -(void)cancelButtonClicked:(id)sender 19 | { 20 | [webView stopLoading:self]; 21 | [putio cancelAllRequests]; 22 | [_delegate accountSetupControllerDidCancelSetup:self]; 23 | } 24 | 25 | -(void)windowDidLoad 26 | { 27 | putio = [PutIOAPI api]; 28 | //[putio setDelegate:self]; 29 | webView.frameLoadDelegate = self; 30 | webView.policyDelegate = self; 31 | [webView setHidden:YES]; 32 | [spinner startAnimation:self]; 33 | } 34 | 35 | -(void)windowWillClose:(NSNotification *)notification 36 | { 37 | [webView setHidden:YES]; 38 | } 39 | 40 | -(void)beginAccountSetup 41 | { 42 | loggingOut = YES; 43 | webView.mainFrameURL = (putio.oAuthLogoutURL).absoluteString; 44 | 45 | } 46 | 47 | -(void)beginAuthentication 48 | { 49 | webView.mainFrameURL = (putio.oAuthAuthenticationURL).absoluteString; 50 | } 51 | 52 | - (void)webView:(WebView *)webView 53 | decidePolicyForNavigationAction:(NSDictionary *)actionInformation 54 | request:(NSURLRequest *)request 55 | frame:(WebFrame *)frame 56 | decisionListener:(id)listener 57 | { 58 | NSString *URL = request.URL.absoluteString; 59 | NSString *callbackURL = putio.oAuthRedirectURI; 60 | if([URL hasPrefix:callbackURL]){ 61 | callbackURL = [callbackURL stringByAppendingString:@"?code="]; 62 | NSString *code = [URL stringByReplacingOccurrencesOfString:callbackURL withString:@""]; 63 | __block PutIOAPIOAuthTokenRequest *request = [PutIOAPIOAuthTokenRequest requestOAuthTokenForCode:code api:putio secret:kAPISecret completion:^{ 64 | if(request.error == nil && !request.isCancelled){ 65 | NSDictionary *rawData = (NSDictionary*)request.responseObject; 66 | NSString *accessToken = rawData[@"access_token"]; 67 | [_delegate accountSetupController:self didFinishSetupWithOAuthAccessToken:accessToken]; 68 | }else if (request.error != nil){ 69 | [self.window presentError:request.error 70 | modalForWindow:self.window 71 | delegate:self 72 | didPresentSelector:@selector(errorDismissed) contextInfo:nil]; 73 | } 74 | }]; 75 | [putio performRequest:request]; 76 | [listener ignore]; 77 | }else{ 78 | [listener use]; 79 | } 80 | } 81 | 82 | -(void)webView:(WebView *)sender didStartProvisionalLoadForFrame:(WebFrame *)frame 83 | { 84 | [webView setHidden:YES]; 85 | [spinner startAnimation:self]; 86 | } 87 | 88 | -(void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame 89 | { 90 | [webView setHidden:NO]; 91 | [spinner stopAnimation:self]; 92 | if(loggingOut){ 93 | loggingOut = NO; 94 | [self beginAuthentication]; 95 | } 96 | } 97 | 98 | - (void)errorDismissed 99 | { 100 | [self cancelButtonClicked:self]; 101 | } 102 | 103 | @end 104 | -------------------------------------------------------------------------------- /Classes/ApplicationDelegate.h: -------------------------------------------------------------------------------- 1 | 2 | @import Sparkle; 3 | #import "MenubarController.h" 4 | #import "MainPanel.h" 5 | 6 | @interface ApplicationDelegate : NSObject 7 | 8 | { 9 | IBOutlet SUUpdater *updater; 10 | } 11 | 12 | @property (nonatomic, strong) MenubarController *menubarController; 13 | @property (nonatomic, strong) PanelController *panelController; 14 | @property (nonatomic, strong) NSWindowController *preferencesWindowController; 15 | @property (readonly) SUUpdater *updater; 16 | 17 | - (IBAction)showPreferences:(id)sender; 18 | - (IBAction)togglePanel:(id)sender; 19 | - (IBAction)checkForUpdates:(id)sender; 20 | 21 | - (void)deliverUserNotificationWithIdentifier:(NSString*)identifier message:(NSString*)message; 22 | 23 | + (void)setupUserDefaults; 24 | 25 | - (void)addApplicationAsLoginItem; 26 | - (void)removeApplicationLoginItem; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /Classes/BackgroundView.h: -------------------------------------------------------------------------------- 1 | #define ARROW_WIDTH 20 2 | #define ARROW_HEIGHT 8 3 | 4 | @interface BackgroundView : NSView 5 | { 6 | NSInteger _arrowX; 7 | } 8 | 9 | @property (nonatomic, assign) NSInteger arrowX; 10 | 11 | @end 12 | -------------------------------------------------------------------------------- /Classes/BackgroundView.m: -------------------------------------------------------------------------------- 1 | #import "BackgroundView.h" 2 | 3 | #define FILL_OPACITY 0.9f 4 | #define STROKE_OPACITY 1.0f 5 | 6 | #define LINE_THICKNESS 1.0f 7 | #define CORNER_RADIUS 6.0f 8 | 9 | #define SEARCH_INSET 10.0f 10 | 11 | #pragma mark - 12 | 13 | @implementation BackgroundView 14 | 15 | @synthesize arrowX = _arrowX; 16 | 17 | #pragma mark - 18 | 19 | - (void)drawRect:(NSRect)dirtyRect 20 | { 21 | NSRect contentRect = NSInsetRect(self.bounds, LINE_THICKNESS, LINE_THICKNESS); 22 | NSBezierPath *path = [NSBezierPath bezierPath]; 23 | 24 | [path moveToPoint:NSMakePoint(_arrowX, NSMaxY(contentRect))]; 25 | [path lineToPoint:NSMakePoint(_arrowX + ARROW_WIDTH / 2, NSMaxY(contentRect) - ARROW_HEIGHT)]; 26 | [path lineToPoint:NSMakePoint(NSMaxX(contentRect) - CORNER_RADIUS, NSMaxY(contentRect) - ARROW_HEIGHT)]; 27 | 28 | NSPoint topRightCorner = NSMakePoint(NSMaxX(contentRect), NSMaxY(contentRect) - ARROW_HEIGHT); 29 | [path curveToPoint:NSMakePoint(NSMaxX(contentRect), NSMaxY(contentRect) - ARROW_HEIGHT - CORNER_RADIUS) 30 | controlPoint1:topRightCorner controlPoint2:topRightCorner]; 31 | 32 | [path lineToPoint:NSMakePoint(NSMaxX(contentRect), NSMinY(contentRect) + CORNER_RADIUS)]; 33 | 34 | NSPoint bottomRightCorner = NSMakePoint(NSMaxX(contentRect), NSMinY(contentRect)); 35 | [path curveToPoint:NSMakePoint(NSMaxX(contentRect) - CORNER_RADIUS, NSMinY(contentRect)) 36 | controlPoint1:bottomRightCorner controlPoint2:bottomRightCorner]; 37 | 38 | [path lineToPoint:NSMakePoint(NSMinX(contentRect) + CORNER_RADIUS, NSMinY(contentRect))]; 39 | 40 | [path curveToPoint:NSMakePoint(NSMinX(contentRect), NSMinY(contentRect) + CORNER_RADIUS) 41 | controlPoint1:contentRect.origin controlPoint2:contentRect.origin]; 42 | 43 | [path lineToPoint:NSMakePoint(NSMinX(contentRect), NSMaxY(contentRect) - ARROW_HEIGHT - CORNER_RADIUS)]; 44 | 45 | NSPoint topLeftCorner = NSMakePoint(NSMinX(contentRect), NSMaxY(contentRect) - ARROW_HEIGHT); 46 | [path curveToPoint:NSMakePoint(NSMinX(contentRect) + CORNER_RADIUS, NSMaxY(contentRect) - ARROW_HEIGHT) 47 | controlPoint1:topLeftCorner controlPoint2:topLeftCorner]; 48 | 49 | [path lineToPoint:NSMakePoint(_arrowX - ARROW_WIDTH / 2, NSMaxY(contentRect) - ARROW_HEIGHT)]; 50 | [path closePath]; 51 | 52 | 53 | [[NSColor windowBackgroundColor] setFill]; 54 | [path fill]; 55 | 56 | [NSGraphicsContext saveGraphicsState]; 57 | 58 | NSBezierPath *clip = [NSBezierPath bezierPathWithRect:self.bounds]; 59 | [clip appendBezierPath:path]; 60 | [clip addClip]; 61 | 62 | [path setLineWidth:LINE_THICKNESS * 2]; 63 | [[NSColor windowBackgroundColor] setStroke]; 64 | [path stroke]; 65 | 66 | [NSGraphicsContext restoreGraphicsState]; 67 | } 68 | 69 | #pragma mark - 70 | #pragma mark Public accessors 71 | 72 | - (void)setArrowX:(NSInteger)value 73 | { 74 | _arrowX = value; 75 | [self setNeedsDisplay:YES]; 76 | } 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /Classes/BytesFormatter.h: -------------------------------------------------------------------------------- 1 | 2 | @interface BytesFormatter : NSObject 3 | 4 | - (NSString*)stringFromBytes:(double)bytes; 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /Classes/BytesFormatter.m: -------------------------------------------------------------------------------- 1 | 2 | #import "BytesFormatter.h" 3 | 4 | @implementation BytesFormatter 5 | 6 | static const char units[] = {'\0', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'}; 7 | static const int precisions[] = {0, 0, 1, 2, 2, 4, 4, 4, 4}; 8 | static NSNumberFormatter* formatter; 9 | 10 | -(NSString *)stringFromBytes:(double)bytes 11 | { 12 | int multiplier = 1024; 13 | int exponent = 0; 14 | 15 | while(bytes >= multiplier && exponent < (sizeof units - 1)){ 16 | bytes /= multiplier; 17 | exponent++; 18 | } 19 | 20 | if(formatter == nil){ 21 | formatter = [[NSNumberFormatter alloc] init]; 22 | formatter.numberStyle = NSNumberFormatterDecimalStyle; 23 | } 24 | formatter.maximumFractionDigits = precisions[exponent]; 25 | formatter.minimumFractionDigits = precisions[exponent]; 26 | 27 | // Beware of reusing this format string. -[NSString stringWithFormat] ignores \0, *printf does not. 28 | return [NSString stringWithFormat:@"%@ %cB", [formatter stringFromNumber:@(bytes)], units[exponent]]; 29 | } 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /Classes/Download.h: -------------------------------------------------------------------------------- 1 | 2 | @import Foundation; 3 | #import "PutIOAPI.h" 4 | #import "PutIOAPIFile.h" 5 | #import "SyncInstruction.h" 6 | 7 | #define PutIODownloadAddedNotification @"PutIODownloadAddedNotification" 8 | #define PutIODownloadFinishedNotification @"PutIODownloadFinishedNotification" 9 | #define PutIODownloadPausedNotification @"PutIODownloadPausedNotification" 10 | #define PutIODownloadStartedNotification @"PutIODownloadStartedNotification" 11 | #define PutIODownloadCancelledNotification @"PutIODownloadCancelledNotification" 12 | #define PutIODownloadFailedNotification @"PutIODownloadFailedNotification" 13 | 14 | typedef enum PutIODownloadStatusEnum : int16_t{ 15 | PutIODownloadStatusPending = 0, 16 | PutIODownloadStatusDownloading = 1, 17 | PutIODownloadStatusPaused = 2, 18 | PutIODownloadStatusFinished = 3, 19 | PutIODownloadStatusCancelled = 4, 20 | PutIODownloadStatusFailed = 5, 21 | PutIODownloadStatusFinishing = 6 22 | } PutIODownloadStatus; 23 | 24 | @interface Download : NSManagedObject 25 | 26 | @property (nonatomic, strong) NSData *putIOFileArchive; 27 | @property (nonatomic, strong) NSString *localFile; 28 | @property (nonatomic, strong) NSString *localPath; 29 | @property (nonatomic, strong) NSString *subdirectoryPath; 30 | @property (nonatomic) float progress; 31 | @property (nonatomic) BOOL progressIsKnown; 32 | @property (nonatomic) double estimatedRemainingTime; 33 | @property (nonatomic) BOOL estimatedRemainingTimeIsKnown; 34 | @property (nonatomic) int64_t totalSize; 35 | @property (nonatomic) int64_t receivedSize; 36 | @property (nonatomic, strong) NSString *localFileTemporary; 37 | @property (nonatomic) PutIODownloadStatus status; 38 | @property (nonatomic) BOOL shouldResumeOnAppLaunch; 39 | @property (nonatomic, retain) SyncInstruction *originatingSyncInstruction; 40 | 41 | @property (nonatomic, strong) PutIOAPIFile *putioFile; 42 | @property (nonatomic, strong) NSString *localizedStatus; 43 | @property (nonatomic) NSUInteger bytesPerSecond; 44 | @property (nonatomic, strong) NSError *downloadError; 45 | 46 | - (instancetype)initWithPutIOFile:(PutIOAPIFile*)file 47 | localPath:(NSString*)path 48 | subdirectoryPath:(NSString*)subdirectoryPath 49 | originatingSyncInstruction:(SyncInstruction*)syncInstruction; 50 | 51 | - (void)startDownload; 52 | - (void)pauseDownload; 53 | - (void)cancelDownload; 54 | - (void)unlinkFromOriginatingSyncInstruction; 55 | - (void)stopWaitingForOtherDownloads; 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /Classes/DownloadCellView.h: -------------------------------------------------------------------------------- 1 | 2 | @import Cocoa; 3 | #import "Download.h" 4 | 5 | @interface DownloadCellView : NSTableCellView 6 | 7 | { 8 | IBOutlet NSProgressIndicator *progressBar; 9 | IBOutlet NSTextField *statusLabel; 10 | IBOutlet NSLayoutConstraint *statusLabelConstraint; 11 | IBOutlet NSLayoutConstraint *textLabelConstraint; 12 | IBOutlet NSButton *pauseResumeButton; 13 | Download *_download; 14 | NSURLConnection *iconLoader; 15 | NSMutableData *iconImageData; 16 | } 17 | 18 | @property (strong) Download *download; 19 | 20 | - (IBAction)pauseOrResumeDownload:(id)sender; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Classes/GeneralPreferences.h: -------------------------------------------------------------------------------- 1 | 2 | #import "MASPreferencesViewController.h" 3 | 4 | @interface GeneralPreferences : NSViewController 5 | { 6 | IBOutlet NSButton *autocheckForUpdatesCheckbox; 7 | IBOutlet NSTextField *lastUpdateLabel; 8 | IBOutlet NSButton *launchOnLoginCheckbox; 9 | } 10 | 11 | -(IBAction)checkForUpdatesNow:(id)sender; 12 | -(IBAction)autocheckForUpdatesChanged:(id)sender; 13 | -(IBAction)launchOnLoginToggled:(id)sender; 14 | -(IBAction)maxParallelDownloadsChanged:(id)sender; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Classes/GeneralPreferences.m: -------------------------------------------------------------------------------- 1 | 2 | #import "GeneralPreferences.h" 3 | #import "ApplicationDelegate.h" 4 | #import "PutIODownloadManager.h" 5 | 6 | @implementation GeneralPreferences 7 | 8 | - (instancetype)init 9 | { 10 | return [super initWithNibName:@"GeneralPreferences" bundle:nil]; 11 | } 12 | 13 | #pragma mark - 14 | #pragma mark MASPreferencesViewController 15 | 16 | -(void)viewWillAppear 17 | { 18 | [self updateUpdaterState]; 19 | } 20 | 21 | - (void)updateUpdaterState 22 | { 23 | SUUpdater *updater = ((ApplicationDelegate*)NSApp.delegate).updater; 24 | autocheckForUpdatesCheckbox.state = (updater.automaticallyChecksForUpdates ? NSOnState : NSOffState); 25 | NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 26 | dateFormatter.dateStyle = NSDateFormatterLongStyle; 27 | dateFormatter.timeStyle = NSDateFormatterShortStyle; 28 | dateFormatter.locale = [NSLocale currentLocale]; 29 | NSString *dateString = (updater.lastUpdateCheckDate == nil 30 | ? NSLocalizedString(@"never", nil) 31 | : [dateFormatter stringFromDate:updater.lastUpdateCheckDate]); 32 | lastUpdateLabel.stringValue = [NSString stringWithFormat:NSLocalizedString(@"Last update: %@", nil), dateString]; 33 | } 34 | 35 | - (NSString *)identifier 36 | { 37 | return @"GeneralPreferences"; 38 | } 39 | 40 | - (NSImage *)toolbarItemImage 41 | { 42 | return [NSImage imageNamed:NSImageNamePreferencesGeneral]; 43 | } 44 | 45 | - (NSString *)toolbarItemLabel 46 | { 47 | return NSLocalizedString(@"General", @"General Preferences title"); 48 | } 49 | 50 | #pragma mark - Actions 51 | 52 | -(IBAction)checkForUpdatesNow:(id)sender 53 | { 54 | [(ApplicationDelegate*)NSApp.delegate checkForUpdates:sender]; 55 | [self updateUpdaterState]; 56 | } 57 | 58 | -(IBAction)autocheckForUpdatesChanged:(id)sender 59 | { 60 | SUUpdater *updater = ((ApplicationDelegate*)NSApp.delegate).updater; 61 | updater.automaticallyChecksForUpdates = ((autocheckForUpdatesCheckbox.state == NSOnState) ? YES : NO); 62 | } 63 | 64 | -(IBAction)launchOnLoginToggled:(id)sender 65 | { 66 | ApplicationDelegate *appDelegate = (ApplicationDelegate*)NSApp.delegate; 67 | if(launchOnLoginCheckbox.state == NSOnState) 68 | [appDelegate addApplicationAsLoginItem]; 69 | else 70 | [appDelegate removeApplicationLoginItem]; 71 | } 72 | 73 | -(IBAction)maxParallelDownloadsChanged:(id)sender 74 | { 75 | [[PutIODownloadManager manager] complyWithMaximumParallelDownloads]; 76 | } 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /Classes/KnownItem.h: -------------------------------------------------------------------------------- 1 | 2 | @import Foundation; 3 | @import CoreData; 4 | 5 | @class SyncInstruction; 6 | 7 | @interface KnownItem : NSManagedObject 8 | 9 | @property (nonatomic, retain) NSNumber *itemID; 10 | @property (nonatomic, retain) SyncInstruction *syncInstruction; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Classes/KnownItem.m: -------------------------------------------------------------------------------- 1 | 2 | #import "KnownItem.h" 3 | #import "SyncInstruction.h" 4 | 5 | @implementation KnownItem 6 | 7 | @dynamic itemID; 8 | @dynamic syncInstruction; 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /Classes/MASPreferencesViewController.h: -------------------------------------------------------------------------------- 1 | @protocol MASPreferencesViewController 2 | 3 | @optional 4 | 5 | - (void)viewWillAppear; 6 | - (void)viewDidDisappear; 7 | @property (nonatomic, readonly, strong) NSView *initialKeyView; 8 | 9 | @required 10 | 11 | @property (nonatomic, readonly) NSString *identifier; 12 | @property (nonatomic, readonly) NSImage *toolbarItemImage; 13 | @property (nonatomic, readonly) NSString *toolbarItemLabel; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Classes/MASPreferencesWindow.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Classes/MASPreferencesWindowController.h: -------------------------------------------------------------------------------- 1 | 2 | #import "MASPreferencesViewController.h" 3 | 4 | extern NSString *const kMASPreferencesWindowControllerDidChangeViewNotification; 5 | 6 | @interface MASPreferencesWindowController : NSWindowController 7 | 8 | @property (nonatomic, readonly) NSArray *viewControllers; 9 | @property (nonatomic, readonly) NSUInteger indexOfSelectedController; 10 | @property (nonatomic, readonly, retain) NSViewController *selectedViewController; 11 | @property (nonatomic, readonly) NSString *title; 12 | 13 | - (instancetype)initWithWindow:(NSWindow *)window NS_UNAVAILABLE; 14 | - (instancetype)initWithCoder:(NSCoder *)coder NS_UNAVAILABLE; 15 | 16 | - (instancetype)initWithViewControllers:(NSArray *)viewControllers; 17 | - (instancetype)initWithViewControllers:(NSArray *)viewControllers title:(NSString *)title; 18 | 19 | - (void)selectControllerAtIndex:(NSUInteger)controllerIndex; 20 | 21 | - (IBAction)goNextTab:(id)sender; 22 | - (IBAction)goPreviousTab:(id)sender; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Classes/MainPanel.h: -------------------------------------------------------------------------------- 1 | 2 | #import "PanelController.h" 3 | 4 | typedef NS_ENUM(NSInteger, MainPanelListMode) { 5 | MainPanelListModeDownloads = 1, 6 | MainPanelListModeTransfers = 0 7 | }; 8 | 9 | @interface MainPanel : PanelController 10 | 11 | { 12 | IBOutlet NSTableView *tableView; 13 | IBOutlet NSMenu *optionsMenu; 14 | IBOutlet NSSegmentedControl *listModeSelector; 15 | MainPanelListMode listMode; 16 | } 17 | 18 | - (IBAction)showOptionsMenu:(id)sender; 19 | - (IBAction)showPreferences:(id)sender; 20 | - (IBAction)syncNow:(id)sender; 21 | - (IBAction)pauseAllDownloads:(id)sender; 22 | - (IBAction)resumeAllDownloads:(id)sender; 23 | - (IBAction)clearDownloads:(id)sender; 24 | - (IBAction)quit:(id)sender; 25 | - (IBAction)changeListMode:(id)sender; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /Classes/MenubarController.h: -------------------------------------------------------------------------------- 1 | 2 | #define MenubarControllerStatusItemWidth 24.0 3 | 4 | @interface MenubarController : NSObject 5 | 6 | @property (nonatomic) BOOL hasActiveIcon; 7 | @property (nonatomic, strong, readonly) NSStatusItem *statusItem; 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /Classes/MenubarController.m: -------------------------------------------------------------------------------- 1 | #import "MenubarController.h" 2 | #import "StatusItemView.h" 3 | 4 | @interface MenubarController () 5 | 6 | @property (nonatomic, strong, readwrite) NSStatusItem *statusItem; 7 | 8 | @end 9 | 10 | 11 | @implementation MenubarController 12 | 13 | - (instancetype)init 14 | { 15 | self = [super init]; 16 | if (self != nil) 17 | { 18 | // Install status item into the menu bar 19 | self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:MenubarControllerStatusItemWidth]; 20 | NSImage *image = [NSImage imageNamed:@"Status"]; 21 | image.template = YES; 22 | self.statusItem.button.image = image; 23 | self.statusItem.button.target = [NSApplication sharedApplication].delegate; 24 | self.statusItem.button.action = @selector(togglePanel:); 25 | } 26 | return self; 27 | } 28 | 29 | - (void)dealloc 30 | { 31 | [[NSStatusBar systemStatusBar] removeStatusItem:self.statusItem]; 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /Classes/NSDictionary+URLQueryString.h: -------------------------------------------------------------------------------- 1 | 2 | @import Foundation; 3 | 4 | @interface NSDictionary(URLQueryString) 5 | 6 | @property (nonatomic, readonly, copy) NSString *URLQueryString; 7 | 8 | @end 9 | -------------------------------------------------------------------------------- /Classes/NSDictionary+URLQueryString.m: -------------------------------------------------------------------------------- 1 | 2 | #import "NSDictionary+URLQueryString.h" 3 | 4 | @implementation NSDictionary(URLQueryString) 5 | 6 | -(NSString *)URLQueryString 7 | { 8 | NSMutableArray *parts = [NSMutableArray array]; 9 | for(NSString *key in self){ 10 | NSString *value = self[key]; 11 | NSString *encodedKey = [key stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 12 | NSString *encodedValue = [value stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 13 | NSString *part = [NSString stringWithFormat: @"%@=%@", encodedKey, encodedValue]; 14 | [parts addObject: part]; 15 | } 16 | return [parts componentsJoinedByString: @"&"]; 17 | } 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Classes/Panel.h: -------------------------------------------------------------------------------- 1 | @interface Panel : NSPanel 2 | @end 3 | -------------------------------------------------------------------------------- /Classes/Panel.m: -------------------------------------------------------------------------------- 1 | #import "Panel.h" 2 | 3 | @implementation Panel 4 | 5 | - (BOOL)canBecomeKeyWindow; 6 | { 7 | return YES; // Allow Search field to become the first responder 8 | } 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /Classes/PanelController.h: -------------------------------------------------------------------------------- 1 | #import "BackgroundView.h" 2 | #import "StatusItemView.h" 3 | 4 | @class PanelController; 5 | 6 | @protocol PanelControllerDelegate 7 | 8 | @optional 9 | - (NSView *)statusItemViewForPanelController:(PanelController *)controller; 10 | @end 11 | 12 | #pragma mark - 13 | 14 | @interface PanelController : NSWindowController 15 | 16 | - (instancetype)initWithWindow:(NSWindow *)window NS_UNAVAILABLE; 17 | - (instancetype)initWithCoder:(NSCoder *)coder NS_UNAVAILABLE; 18 | - (instancetype)initWithDelegate:(id)delegate; 19 | - (NSRect)statusRectForWindow:(NSWindow *)window; 20 | 21 | @property (nonatomic) BOOL hasActivePanel; 22 | @property (nonatomic, unsafe_unretained) IBOutlet BackgroundView *backgroundView; 23 | @property (nonatomic, unsafe_unretained, readwrite) id delegate; 24 | 25 | - (void)openPanel; 26 | - (void)closePanel; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /Classes/PanelController.m: -------------------------------------------------------------------------------- 1 | 2 | #import "PanelController.h" 3 | #import "BackgroundView.h" 4 | #import "StatusItemView.h" 5 | #import "MenubarController.h" 6 | 7 | #define OPEN_DURATION .2 8 | #define CLOSE_DURATION .2 9 | #define ANIMATION_OFFSET 20 10 | 11 | #define POPUP_HEIGHT 122 12 | #define PANEL_WIDTH 280 13 | #define MENU_ANIMATION_DURATION .1 14 | 15 | @implementation PanelController 16 | 17 | #pragma mark - Initializers 18 | 19 | - (instancetype)initWithDelegate:(id)delegate 20 | { 21 | self = [super initWithWindowNibName:NSStringFromClass([self class])]; 22 | if (self != nil) 23 | { 24 | self.delegate = delegate; 25 | } 26 | return self; 27 | } 28 | 29 | - (void)awakeFromNib 30 | { 31 | [super awakeFromNib]; 32 | 33 | // Make a fully skinned panel 34 | NSPanel *panel = (id)self.window; 35 | [panel setAcceptsMouseMovedEvents:YES]; 36 | [panel setLevel:NSPopUpMenuWindowLevel]; 37 | [panel setOpaque:NO]; 38 | panel.backgroundColor = [NSColor clearColor]; 39 | } 40 | 41 | #pragma mark - Accessors 42 | 43 | - (void)setHasActivePanel:(BOOL)flag 44 | { 45 | if (_hasActivePanel != flag) 46 | { 47 | _hasActivePanel = flag; 48 | 49 | if (_hasActivePanel) 50 | { 51 | [self openPanel]; 52 | } 53 | else 54 | { 55 | [self closePanel]; 56 | } 57 | } 58 | } 59 | 60 | #pragma mark - NSWindowDelegate 61 | 62 | - (void)windowWillClose:(NSNotification *)notification 63 | { 64 | self.hasActivePanel = NO; 65 | } 66 | 67 | - (void)windowDidResignKey:(NSNotification *)notification; 68 | { 69 | if (self.window.visible) 70 | { 71 | self.hasActivePanel = NO; 72 | } 73 | } 74 | 75 | - (void)windowDidResize:(NSNotification *)notification 76 | { 77 | [self updateArrowX]; 78 | } 79 | 80 | - (void)updateArrowX 81 | { 82 | NSWindow *panel = self.window; 83 | NSRect statusRect = [self statusRectForWindow:panel]; 84 | NSRect panelRect = panel.frame; 85 | 86 | CGFloat statusX = roundf(NSMidX(statusRect)); 87 | CGFloat panelX = statusX - NSMinX(panelRect); 88 | 89 | self.backgroundView.arrowX = panelX; 90 | } 91 | 92 | #pragma mark - Keyboard 93 | 94 | - (void)cancelOperation:(id)sender 95 | { 96 | self.hasActivePanel = NO; 97 | } 98 | 99 | #pragma mark - Public methods 100 | 101 | - (NSRect)statusRectForWindow:(NSWindow *)window 102 | { 103 | NSRect screenRect = [NSScreen screens][0].frame; 104 | NSRect statusRect = NSZeroRect; 105 | 106 | NSView *statusItemView = nil; 107 | if ([self.delegate respondsToSelector:@selector(statusItemViewForPanelController:)]){ 108 | statusItemView = [self.delegate statusItemViewForPanelController:self]; 109 | } 110 | 111 | if(statusItemView){ 112 | statusRect = [statusItemView.window convertRectToScreen:statusItemView.frame]; 113 | statusRect.origin.y = NSMinY(statusRect) - NSHeight(statusRect); 114 | }else{ 115 | statusRect.size = NSMakeSize(MenubarControllerStatusItemWidth, [NSStatusBar systemStatusBar].thickness); 116 | statusRect.origin.x = roundf((NSWidth(screenRect) - NSWidth(statusRect)) / 2); 117 | statusRect.origin.y = NSHeight(screenRect) - NSHeight(statusRect) * 2; 118 | } 119 | return statusRect; 120 | } 121 | 122 | - (void)openPanel 123 | { 124 | NSWindow *panel = self.window; 125 | 126 | NSRect screenRect = [NSScreen screens][0].frame; 127 | NSRect statusRect = [self statusRectForWindow:panel]; 128 | 129 | NSRect panelRect = panel.frame; 130 | panelRect.origin.x = roundf(NSMidX(statusRect) - NSWidth(panelRect) / 2); 131 | panelRect.origin.y = NSMaxY(statusRect) - NSHeight(panelRect); 132 | 133 | if (NSMaxX(panelRect) > (NSMaxX(screenRect) - ARROW_HEIGHT)) 134 | panelRect.origin.x -= NSMaxX(panelRect) - (NSMaxX(screenRect) - ARROW_HEIGHT); 135 | 136 | [NSApp activateIgnoringOtherApps:NO]; 137 | panel.alphaValue = 0; 138 | 139 | NSRect fromRect = NSMakeRect(panelRect.origin.x, panelRect.origin.y - ANIMATION_OFFSET, panelRect.size.width, panelRect.size.height); 140 | [panel setFrame:fromRect display:YES]; 141 | [self updateArrowX]; 142 | [panel makeKeyAndOrderFront:nil]; 143 | 144 | NSTimeInterval openDuration = OPEN_DURATION; 145 | 146 | NSEvent *currentEvent = NSApp.currentEvent; 147 | if (currentEvent.type == NSLeftMouseDown){ 148 | NSUInteger clearFlags = (currentEvent.modifierFlags & NSDeviceIndependentModifierFlagsMask); 149 | BOOL shiftPressed = (clearFlags == NSShiftKeyMask); 150 | BOOL shiftOptionPressed = (clearFlags == (NSShiftKeyMask | NSAlternateKeyMask)); 151 | if (shiftPressed || shiftOptionPressed){ 152 | openDuration *= 10; 153 | } 154 | } 155 | 156 | [NSAnimationContext beginGrouping]; 157 | [NSAnimationContext currentContext].duration = openDuration; 158 | [[panel animator] setFrame:panelRect display:YES]; 159 | [panel animator].alphaValue = 1; 160 | [NSAnimationContext endGrouping]; 161 | } 162 | 163 | - (void)closePanel 164 | { 165 | [NSAnimationContext beginGrouping]; 166 | [[NSAnimationContext currentContext] setDuration:CLOSE_DURATION]; 167 | [self.window animator].alphaValue = 0; 168 | [NSAnimationContext endGrouping]; 169 | 170 | dispatch_after(dispatch_walltime(NULL, NSEC_PER_SEC * CLOSE_DURATION * 2), dispatch_get_main_queue(), ^{ 171 | [self.window orderOut:nil]; 172 | }); 173 | } 174 | 175 | @end 176 | -------------------------------------------------------------------------------- /Classes/PanelRowView.h: -------------------------------------------------------------------------------- 1 | 2 | @import Cocoa; 3 | 4 | @interface PanelRowView : NSTableRowView 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /Classes/PanelRowView.m: -------------------------------------------------------------------------------- 1 | 2 | #import "PanelRowView.h" 3 | 4 | @implementation PanelRowView 5 | 6 | -(void)drawSelectionInRect:(NSRect)dirtyRect 7 | { 8 | NSRect selectionRect = NSInsetRect(self.bounds, 4.0f, 0.0f); 9 | [[NSColor selectedControlColor] setFill]; 10 | NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:selectionRect xRadius:4.0f yRadius:5.0f]; 11 | [path fill]; 12 | } 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Classes/Persistency.h: -------------------------------------------------------------------------------- 1 | 2 | @import Foundation; 3 | 4 | @interface Persistency : NSObject 5 | 6 | +(instancetype)manager; 7 | 8 | @property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator; 9 | @property (readonly, strong, nonatomic) NSManagedObjectModel *model; 10 | @property (readonly, strong, nonatomic) NSManagedObjectContext *context; 11 | 12 | - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender; 13 | 14 | - (NSEntityDescription*)entityNamed:(NSString*)entityName; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Classes/PutIOAPI.h: -------------------------------------------------------------------------------- 1 | 2 | @import Foundation; 3 | #import "PutIOAPIRequest.h" 4 | 5 | @interface PutIOAPI : NSObject 6 | 7 | + (instancetype)api; 8 | 9 | @property (readonly) NSURL *baseURL; 10 | @property (readonly) NSURL *oAuthAuthenticationURL; 11 | @property (readonly) NSURL *oAuthLogoutURL; 12 | @property (readonly) NSString *oAuthClientID; 13 | @property (readonly) NSString *oAuthClientSecret; 14 | @property (readonly) NSString *oAuthRedirectURI; 15 | @property (strong, nonatomic) NSString *oAuthAccessToken; 16 | @property (readonly) BOOL isAuthenticated; 17 | 18 | - (instancetype)initWithBaseURL:(NSURL*)baseURL oAuthAccessToken:(NSString*)oAuthAccessToken oAuthClientID:(NSString*)clientID oAuthRedirectURI:(NSString*)redirectURI NS_DESIGNATED_INITIALIZER; 19 | - (NSURL*)downloadURLForFileWithID:(NSInteger)fileID; 20 | - (void)performRequest:(PutIOAPIRequest*)request; 21 | - (void)cancelAllRequests; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Classes/PutIOAPI.m: -------------------------------------------------------------------------------- 1 | 2 | #import "PutIOAPI.h" 3 | #import "PutIOAPIKeychainManager.h" 4 | #import "NSDictionary+URLQueryString.h" 5 | 6 | #define kDefaultBaseURL @"https://api.put.io/v2" 7 | #define kDefaultAPISecret @"a4gz4pnrnxm2jxchok8v" 8 | #define kDefaultClientID @"197" 9 | #define kDefaultRedirectURI @"https://matthiasschwab.de/putiosync/callback.html" 10 | 11 | static NSString *oAuthAccessToken; 12 | 13 | @interface PutIOAPI() 14 | { 15 | NSOperationQueue *queue; 16 | } 17 | @end 18 | 19 | @implementation PutIOAPI 20 | 21 | #pragma mark - Class Methods 22 | 23 | +(instancetype)api 24 | { 25 | static PutIOAPI *sharedInstance = nil; 26 | static dispatch_once_t onceToken; 27 | dispatch_once(&onceToken, ^{ 28 | sharedInstance = [[PutIOAPI alloc] init]; 29 | }); 30 | return sharedInstance; 31 | } 32 | 33 | #pragma mark - Initializers 34 | 35 | -(instancetype)init 36 | { 37 | return [self initWithBaseURL:[NSURL URLWithString:kDefaultBaseURL] 38 | oAuthAccessToken:[PutIOAPIKeychainManager keychainItemPassword] 39 | oAuthClientID:kDefaultClientID 40 | oAuthRedirectURI:kDefaultRedirectURI]; 41 | } 42 | 43 | -(instancetype)initWithBaseURL:(NSURL *)baseURL 44 | oAuthAccessToken:(NSString *)oAuthAccessToken 45 | oAuthClientID:(NSString *)clientID 46 | oAuthRedirectURI:(NSString *)redirectURI 47 | { 48 | self = [super init]; 49 | if (self) { 50 | _baseURL = baseURL; 51 | _oAuthAccessToken = oAuthAccessToken; 52 | _oAuthClientID = clientID; 53 | _oAuthRedirectURI = redirectURI; 54 | queue = [[NSOperationQueue alloc] init]; 55 | queue.maxConcurrentOperationCount = 1; 56 | } 57 | return self; 58 | } 59 | 60 | -(BOOL)isAuthenticated 61 | { 62 | return (_oAuthAccessToken != nil); 63 | } 64 | 65 | #pragma mark - OAuth 66 | 67 | -(void)setOAuthAccessToken:(NSString *)oAuthAccessToken 68 | { 69 | _oAuthAccessToken = oAuthAccessToken; 70 | } 71 | 72 | - (NSURL *)oAuthLogoutURL 73 | { 74 | return [NSURL URLWithString:@"https://put.io/logout"]; 75 | } 76 | 77 | - (NSURL *)oAuthAuthenticationURL 78 | { 79 | NSDictionary *parameters = @{ 80 | @"client_id" : self.oAuthClientID, 81 | @"response_type" : @"code", 82 | @"redirect_uri" : self.oAuthRedirectURI 83 | }; 84 | NSString *urlString = [self.baseURL URLByAppendingPathComponent:@"oauth2/authenticate"].absoluteString; 85 | urlString = [urlString stringByAppendingFormat:@"?%@", [parameters URLQueryString]]; 86 | return [NSURL URLWithString:urlString]; 87 | } 88 | 89 | #pragma mark - Performing Requests 90 | 91 | -(void)performRequest:(PutIOAPIRequest *)request 92 | { 93 | request.api = self; 94 | [queue addOperation:request]; 95 | } 96 | 97 | -(void)cancelAllRequests 98 | { 99 | [queue cancelAllOperations]; 100 | } 101 | 102 | -(NSURL *)downloadURLForFileWithID:(NSInteger)fileID 103 | { 104 | NSString *requestURLString = (self.baseURL).absoluteString; 105 | requestURLString = [requestURLString stringByAppendingFormat:@"/files/%ld/download?oauth_token=%@", fileID, self.oAuthAccessToken]; 106 | return [NSURL URLWithString:requestURLString]; 107 | } 108 | 109 | @end 110 | -------------------------------------------------------------------------------- /Classes/PutIOAPIAccountInfo.h: -------------------------------------------------------------------------------- 1 | 2 | #import "PutIOAPIObject.h" 3 | 4 | @interface PutIOAPIAccountInfo : PutIOAPIObject 5 | 6 | @property (readonly) NSString *username; 7 | @property (readonly) NSString *eMailAddress; 8 | @property (readonly) NSUInteger freeDiskSpace; 9 | @property (readonly) NSUInteger usedDiskSpace; 10 | @property (readonly) NSUInteger totalDiskSpace; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Classes/PutIOAPIAccountInfo.m: -------------------------------------------------------------------------------- 1 | 2 | #import "PutIOAPIAccountInfo.h" 3 | 4 | @implementation PutIOAPIAccountInfo 5 | 6 | -(instancetype)initWithRawData:(id)data 7 | { 8 | self = [super initWithRawData:data]; 9 | if(self){ 10 | NSDictionary *info = rawData[@"info"]; 11 | _username = info[@"username"]; 12 | _eMailAddress = info[@"mail"]; 13 | _freeDiskSpace = [info[@"disk"][@"avail"] integerValue]; 14 | _usedDiskSpace = [info[@"disk"][@"used"] integerValue]; 15 | _totalDiskSpace = [info[@"disk"][@"size"] integerValue]; 16 | } 17 | return self; 18 | } 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Classes/PutIOAPIAccountInfoRequest.h: -------------------------------------------------------------------------------- 1 | 2 | #import "PutIOAPIRequest.h" 3 | #import "PutIOAPIAccountInfo.h" 4 | 5 | @interface PutIOAPIAccountInfoRequest : PutIOAPIRequest 6 | 7 | @property (readonly) PutIOAPIAccountInfo *accountInfo; 8 | 9 | + (instancetype)requestWithCompletion:(PutIOAPIRequestCompletion)completion; 10 | 11 | @end 12 | -------------------------------------------------------------------------------- /Classes/PutIOAPIAccountInfoRequest.m: -------------------------------------------------------------------------------- 1 | 2 | #import "PutIOAPIAccountInfoRequest.h" 3 | 4 | @implementation PutIOAPIAccountInfoRequest 5 | 6 | +(instancetype)requestWithCompletion:(PutIOAPIRequestCompletion)completion 7 | { 8 | return [[self alloc] initWithMethod:PutIOAPIMethodGET 9 | endpoint:@"account/info" 10 | parameters:nil 11 | completionBlock:completion]; 12 | } 13 | 14 | -(void)parseResponseObject:(id)response 15 | { 16 | _accountInfo = [[PutIOAPIAccountInfo alloc] initWithRawData:response]; 17 | } 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Classes/PutIOAPIFile.h: -------------------------------------------------------------------------------- 1 | 2 | #import "PutIOAPIObject.h" 3 | 4 | @interface PutIOAPIFile : PutIOAPIObject 5 | { 6 | 7 | } 8 | 9 | @property (assign) NSInteger fileID; 10 | @property (assign) NSInteger parentFileID; 11 | @property (strong) NSString *name; 12 | @property (strong) NSDate *dateCreated; 13 | @property (strong) NSString *contentType; 14 | @property (strong) NSURL *iconURL; 15 | @property (strong) NSURL *screenshotURL; 16 | @property (assign) NSInteger size; 17 | @property (assign) BOOL isShared; 18 | @property (assign) BOOL mp4VersionAvailable; 19 | @property (readonly) BOOL isFolder; 20 | @property (readonly) BOOL isRootFolder; 21 | @property (strong) NSArray *subfolders; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Classes/PutIOAPIFile.m: -------------------------------------------------------------------------------- 1 | 2 | #import "PutIOAPIFile.h" 3 | 4 | @implementation PutIOAPIFile 5 | 6 | -(instancetype)initWithRawData:(id)data 7 | { 8 | self = [super initWithRawData:data]; 9 | if(self){ 10 | self.fileID = [data[@"id"] integerValue]; 11 | if(data[@"parent_id"] != [NSNull null]){ 12 | self.parentFileID = [data[@"parent_id"] integerValue]; 13 | }else{ 14 | self.parentFileID = -1; 15 | } 16 | self.name = data[@"name"]; 17 | self.dateCreated = [PutIOAPIObject dateFromRawDataString:data[@"created_at"]]; 18 | self.contentType = data[@"content_type"]; 19 | if(data[@"icon"] != [NSNull null]){ 20 | self.iconURL = [NSURL URLWithString:data[@"icon"]]; 21 | }else{ 22 | self.iconURL = nil; 23 | } 24 | self.size = [data[@"size"] integerValue]; 25 | if(data[@"screenshot"] != [NSNull null]) 26 | self.screenshotURL = [NSURL URLWithString:data[@"screenshot"]]; 27 | if(data[@"is_shared"] != [NSNull null]) 28 | self.isShared = [data[@"is_shared"] boolValue]; 29 | if(data[@"is_mp4_available"] != [NSNull null]) 30 | self.mp4VersionAvailable = [data[@"is_mp4_available"] boolValue]; 31 | } 32 | return self; 33 | } 34 | 35 | -(BOOL)isFolder 36 | { 37 | return [self.contentType isEqualToString:@"application/x-directory"]; 38 | } 39 | 40 | -(BOOL)isRootFolder 41 | { 42 | return (self.isFolder && self.parentFileID == -1); 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /Classes/PutIOAPIFileDeletionRequest.h: -------------------------------------------------------------------------------- 1 | 2 | #import "PutIOAPIRequest.h" 3 | 4 | @interface PutIOAPIFileDeletionRequest : PutIOAPIRequest 5 | 6 | + (instancetype)requestDeletionOfFileWithID:(NSInteger)fileID completion:(PutIOAPIRequestCompletion)completion; 7 | 8 | @end 9 | -------------------------------------------------------------------------------- /Classes/PutIOAPIFileDeletionRequest.m: -------------------------------------------------------------------------------- 1 | 2 | #import "PutIOAPIFileDeletionRequest.h" 3 | 4 | @implementation PutIOAPIFileDeletionRequest 5 | 6 | +(instancetype)requestDeletionOfFileWithID:(NSInteger)fileID completion:(PutIOAPIRequestCompletion)completion 7 | { 8 | return [[self alloc] initWithMethod:PutIOAPIMethodPOST 9 | endpoint:@"files/delete" 10 | parameters:@{@"file_ids" : (@(fileID)).stringValue} 11 | completionBlock:completion]; 12 | } 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Classes/PutIOAPIFileRequest.h: -------------------------------------------------------------------------------- 1 | 2 | #import "PutIOAPIRequest.h" 3 | #import "PutIOAPIFile.h" 4 | 5 | @interface PutIOAPIFileRequest : PutIOAPIRequest 6 | 7 | @property PutIOAPIFile *parentFolder; 8 | @property NSArray *files; 9 | 10 | + (instancetype)requestFilesInRootFolderWithCompletion:(PutIOAPIRequestCompletion)completion; 11 | + (instancetype)requestFilesInFolderWithID:(NSInteger)folderID completion:(PutIOAPIRequestCompletion)completion; 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Classes/PutIOAPIFileRequest.m: -------------------------------------------------------------------------------- 1 | 2 | #import "PutIOAPIFileRequest.h" 3 | 4 | @implementation PutIOAPIFileRequest 5 | 6 | +(instancetype)requestFilesInRootFolderWithCompletion:(PutIOAPIRequestCompletion)completion 7 | { 8 | return [self requestFilesInFolderWithID:0 completion:completion]; 9 | } 10 | 11 | +(instancetype)requestFilesInFolderWithID:(NSInteger)folderID 12 | completion:(PutIOAPIRequestCompletion)completion 13 | { 14 | return [[self alloc] initWithMethod:PutIOAPIMethodGET 15 | endpoint:@"files/list" 16 | parameters:@{@"parent_id" : (@(folderID)).stringValue} 17 | completionBlock:completion]; 18 | } 19 | 20 | -(void)parseResponseObject:(id)response 21 | { 22 | self.parentFolder = [[PutIOAPIFile alloc] initWithRawData:response[@"parent"]]; 23 | 24 | NSMutableArray *files = [NSMutableArray array]; 25 | for(NSDictionary *fileData in response[@"files"]){ 26 | PutIOAPIFile *file = [[PutIOAPIFile alloc] initWithRawData:fileData]; 27 | [files addObject:file]; 28 | } 29 | self.files = files; 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /Classes/PutIOAPIKeychainManager.h: -------------------------------------------------------------------------------- 1 | 2 | @import Foundation; 3 | 4 | @interface PutIOAPIKeychainManager : NSObject 5 | 6 | + (NSString*)keychainItemPassword; 7 | + (void)setKeychainItemPassword:(NSString*)password; 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /Classes/PutIOAPIKeychainManager.m: -------------------------------------------------------------------------------- 1 | 2 | #import "PutIOAPIKeychainManager.h" 3 | #include 4 | #include 5 | 6 | @implementation PutIOAPIKeychainManager 7 | 8 | static void *keychainServiceName = "PutIOSync"; 9 | static void *keychainAccountName = "APIOAuthToken"; 10 | 11 | + (NSString*)keychainItemPassword 12 | { 13 | OSStatus status; 14 | UInt32 passwordLength; 15 | void *passwordData = nil; 16 | SecKeychainItemRef itemRef = nil; 17 | NSString *password = nil; 18 | status = SecKeychainFindGenericPassword(NULL, 19 | (UInt32)strlen(keychainServiceName), keychainServiceName, 20 | (UInt32)strlen(keychainAccountName), keychainAccountName, 21 | &passwordLength, &passwordData, &itemRef); 22 | if(status == noErr){ 23 | password = [[NSString alloc] initWithBytes:passwordData length:passwordLength encoding:NSUTF8StringEncoding]; 24 | SecKeychainItemFreeContent(NULL, passwordData); 25 | //NSLog(@"Successfully read keychain item"); 26 | }else{ 27 | if(status != noErr) 28 | NSLog(@"Failed to get keychain item: %@", (NSString*)CFBridgingRelease(SecCopyErrorMessageString(status, NULL))); 29 | } 30 | return password; 31 | } 32 | 33 | + (void)setKeychainItemPassword:(NSString*)password 34 | { 35 | OSStatus status; 36 | SecKeychainItemRef itemRef = nil; 37 | void *passwordData = (void*)[password cStringUsingEncoding:NSUTF8StringEncoding]; 38 | // Check if the item is already in the keycain 39 | status = SecKeychainFindGenericPassword(NULL, 40 | (UInt32)strlen(keychainServiceName), keychainServiceName, 41 | (UInt32)strlen(keychainAccountName), keychainAccountName, 42 | NULL, NULL, 43 | &itemRef); 44 | if(status == noErr){ 45 | // Update the existing item 46 | status = SecKeychainItemModifyAttributesAndData(itemRef, NULL, (UInt32)strlen(passwordData), passwordData); 47 | if(status != noErr) 48 | NSLog(@"Failed to update keychain item: %@", (NSString*)CFBridgingRelease(SecCopyErrorMessageString(status, NULL))); 49 | }else if(status == errSecItemNotFound){ 50 | // Create a new item 51 | status = SecKeychainAddGenericPassword(NULL, 52 | (UInt32)strlen(keychainServiceName), keychainServiceName, 53 | (UInt32)strlen(keychainAccountName), keychainAccountName, 54 | (UInt32)strlen(passwordData), passwordData, 55 | NULL); 56 | if(status != noErr) 57 | NSLog(@"Failed to add new keychain item: %@", (NSString*)CFBridgingRelease(SecCopyErrorMessageString(status, NULL))); 58 | } 59 | } 60 | 61 | @end 62 | -------------------------------------------------------------------------------- /Classes/PutIOAPIOAuthTokenRequest.h: -------------------------------------------------------------------------------- 1 | 2 | #import "PutIOAPIRequest.h" 3 | 4 | @class PutIOAPI; 5 | 6 | @interface PutIOAPIOAuthTokenRequest : PutIOAPIRequest 7 | 8 | +(instancetype)requestOAuthTokenForCode:(NSString *)code api:(PutIOAPI*)api secret:(NSString*)clientSecret completion:(PutIOAPIRequestCompletion)completion; 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /Classes/PutIOAPIOAuthTokenRequest.m: -------------------------------------------------------------------------------- 1 | 2 | #import "PutIOAPIOAuthTokenRequest.h" 3 | #import "PutIOAPI.h" 4 | 5 | @implementation PutIOAPIOAuthTokenRequest 6 | 7 | +(instancetype)requestOAuthTokenForCode:(NSString *)code 8 | api:(PutIOAPI *)api 9 | secret:(NSString *)clientSecret 10 | completion:(PutIOAPIRequestCompletion)completion 11 | { 12 | NSDictionary *parameters = @{ 13 | @"client_id" : api.oAuthClientID, 14 | @"client_secret" : clientSecret, 15 | @"grant_type" : @"authorization_code", 16 | @"redirect_uri" : api.oAuthRedirectURI, 17 | @"code" : code 18 | }; 19 | PutIOAPIOAuthTokenRequest *request = [[self alloc] initWithMethod:PutIOAPIMethodGET 20 | endpoint:@"oauth2/access_token" 21 | parameters:parameters 22 | completionBlock:completion]; 23 | request.parseAPIResponse = NO; 24 | request.doesNotRequireAuthentication = YES; 25 | return request; 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /Classes/PutIOAPIObject.h: -------------------------------------------------------------------------------- 1 | 2 | @import Foundation; 3 | 4 | @interface PutIOAPIObject : NSObject 5 | 6 | { 7 | id rawData; 8 | } 9 | 10 | @property (readonly) id rawData; 11 | 12 | - (instancetype)init NS_UNAVAILABLE; 13 | - (instancetype)initWithRawData:(id)data NS_DESIGNATED_INITIALIZER; 14 | 15 | // Helper functions 16 | 17 | + (NSDate*)dateFromRawDataString:(NSString*)dateString; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Classes/PutIOAPIObject.m: -------------------------------------------------------------------------------- 1 | 2 | #import "PutIOAPIObject.h" 3 | 4 | @implementation PutIOAPIObject 5 | 6 | - (instancetype)initWithRawData:(id)data 7 | { 8 | self = [super init]; 9 | if (self) { 10 | rawData = data; 11 | } 12 | return self; 13 | } 14 | 15 | -(instancetype)initWithCoder:(NSCoder *)decoder 16 | { 17 | rawData = [decoder decodeObjectForKey:@"rawData"]; 18 | self = [self initWithRawData:rawData]; 19 | return self; 20 | } 21 | 22 | -(void)encodeWithCoder:(NSCoder *)coder 23 | { 24 | [coder encodeObject:rawData forKey:@"rawData"]; 25 | } 26 | 27 | -(id)rawData 28 | { 29 | return rawData; 30 | } 31 | 32 | + (NSDate*)dateFromRawDataString:(NSString*)dateString 33 | { 34 | NSString *format = @"yyyy-MM-dd'T'HH:mm:ss"; 35 | NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] initWithDateFormat:format allowNaturalLanguage:NO]; 36 | return [dateFormatter dateFromString:dateString]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /Classes/PutIOAPIRequest.h: -------------------------------------------------------------------------------- 1 | 2 | @import Foundation; 3 | 4 | @class PutIOAPI; 5 | 6 | typedef NS_ENUM(unsigned int, PutIOAPIMethod) { 7 | PutIOAPIMethodGET, 8 | PutIOAPIMethodPOST 9 | }; 10 | 11 | typedef NS_ENUM(unsigned int, PutIOAPIInternalError) { 12 | PutIOAPIInternalErrorBadHTTPStatus = 1, 13 | PutIOAPIInternalErrorNetworkError = 2, 14 | PutIOAPIInternalErrorMalformedJSON = 3, 15 | PutIOAPIInternalErrorUnexpectedData = 4, 16 | PutIOAPIInternalErrorNotAuthorized = 5 17 | }; 18 | 19 | typedef void (^PutIOAPIRequestCompletion)(void); 20 | 21 | @interface PutIOAPIRequest : NSOperation 22 | 23 | @property (weak) PutIOAPI *api; 24 | @property (readonly) PutIOAPIMethod method; 25 | @property (assign) BOOL doesNotRequireAuthentication; 26 | @property (readonly) NSString *endpoint; 27 | @property (readonly) NSDictionary *parameters; 28 | @property (readonly) NSString *queryString; 29 | @property (readonly) NSError *error; 30 | @property (readonly) NSURLResponse *urlResponse; 31 | @property (readonly) id responseObject; 32 | @property (assign) BOOL parseAPIResponse; 33 | @property (copy) PutIOAPIRequestCompletion completion; 34 | @property (assign) dispatch_queue_t completionQueue; 35 | 36 | - (instancetype)init NS_UNAVAILABLE; 37 | 38 | - (instancetype)initWithMethod:(PutIOAPIMethod)method 39 | endpoint:(NSString*)endpoint 40 | parameters:(NSDictionary *)parameters 41 | completionBlock:(PutIOAPIRequestCompletion)completionBlock NS_DESIGNATED_INITIALIZER; 42 | 43 | - (void)parseResponseObject:(id)response; 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /Classes/PutIOAPITransfer.h: -------------------------------------------------------------------------------- 1 | 2 | #import "PutIOAPIObject.h" 3 | 4 | typedef NS_ENUM(NSInteger, PutIOAPITransferStatus) { 5 | PutIOAPITransferStatusUnknown = 0, 6 | PutIOAPITransferStatusInQueue = 1, 7 | PutIOAPITransferStatusDownloading = 2, 8 | PutIOAPITransferStatusSeeding = 3, 9 | PutIOAPITransferStatusCompleted = 4, 10 | PutIOAPITransferStatusFailed = 5 11 | }; 12 | 13 | @interface PutIOAPITransfer : PutIOAPIObject 14 | { 15 | 16 | } 17 | 18 | @property (assign) NSInteger transferID; 19 | @property (assign) NSInteger fileID; 20 | @property (assign) NSInteger destinationFolderID; 21 | @property (assign) NSInteger originatingSubscriptionID; 22 | @property (assign) NSTimeInterval estimatedTimeRemaining; 23 | @property (strong) NSString *filename; 24 | @property (assign) float progress; 25 | @property (assign) PutIOAPITransferStatus status; 26 | @property (assign) NSInteger seedingToPeersCount; 27 | @property (assign) NSInteger leechingFromPeersCount; 28 | @property (assign) NSInteger connectedPeersCount; 29 | @property (assign) float torrentRatio; 30 | @property (assign) NSInteger size; 31 | @property (assign) NSInteger sizeUploaded; 32 | @property (assign) NSInteger uploadSpeed; 33 | @property (assign) NSInteger sizeDownloaded; 34 | @property (assign) NSInteger downloadSpeed; 35 | @property (assign) BOOL willExtractWhenFinished; 36 | @property (assign) BOOL isSeeding; 37 | @property (strong) NSString *trackerMessage; 38 | @property (strong) NSString *errorMessage; 39 | @property (strong) NSURL *sourceURL; 40 | @property (strong) NSDate *startTime; 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /Classes/PutIOAPITransfer.m: -------------------------------------------------------------------------------- 1 | 2 | #import "PutIOAPITransfer.h" 3 | 4 | @implementation PutIOAPITransfer 5 | 6 | -(instancetype)initWithRawData:(id)data 7 | { 8 | self = [super initWithRawData:data]; 9 | if (self) { 10 | self.transferID = [data[@"id"] integerValue]; 11 | if(data[@"file_id"] != [NSNull null]){ 12 | self.fileID = [data[@"file_id"] integerValue]; 13 | }else{ 14 | self.fileID = -1; 15 | } 16 | if(data[@"save_parent_id"] != [NSNull null]){ 17 | self.destinationFolderID = [data[@"save_parent_id"] integerValue]; 18 | }else{ 19 | self.destinationFolderID = -1; 20 | } 21 | if(data[@"subscription_id"] != [NSNull null]){ 22 | self.originatingSubscriptionID = [data[@"subscription_id"] integerValue]; 23 | }else{ 24 | self.originatingSubscriptionID = -1; 25 | } 26 | self.status = PutIOAPITransferStatusUnknown; 27 | if([data[@"status"] isEqualToString:@"IN_QUEUE"]) 28 | self.status = PutIOAPITransferStatusInQueue; 29 | else if([data[@"status"] isEqualToString:@"DOWNLOADING"]) 30 | self.status = PutIOAPITransferStatusDownloading; 31 | else if([data[@"status"] isEqualToString:@"SEEDING"]) 32 | self.status = PutIOAPITransferStatusSeeding; 33 | else if([data[@"status"] isEqualToString:@"COMPLETED"]) 34 | self.status = PutIOAPITransferStatusCompleted; 35 | else if([data[@"status"] isEqualToString:@"ERROR"]) 36 | self.status = PutIOAPITransferStatusFailed; 37 | 38 | self.filename = data[@"name"]; 39 | self.progress = (float)[data[@"percent_done"] integerValue]; 40 | self.seedingToPeersCount = [data[@"peers_getting_from_us"] integerValue]; 41 | self.leechingFromPeersCount = [data[@"peers_sending_to_us"] integerValue]; 42 | if(data[@"size"] != [NSNull null]){ 43 | self.size = [data[@"size"] integerValue]; 44 | }else{ 45 | self.size = 0; 46 | } 47 | self.sizeUploaded = [data[@"uploaded"] integerValue]; 48 | self.uploadSpeed = [data[@"up_speed"] integerValue]; 49 | self.sizeDownloaded = [data[@"downloaded"] integerValue]; 50 | self.downloadSpeed = [data[@"down_speed"] integerValue]; 51 | self.willExtractWhenFinished = [data[@"extract"] boolValue]; 52 | self.isSeeding = [data[@"is_seeding"] boolValue]; 53 | if(data[@"tracker_message"] != [NSNull null]){ 54 | self.trackerMessage = data[@"tracker_message"]; 55 | }else{ 56 | self.trackerMessage = nil; 57 | } 58 | if(data[@"error_message"] != [NSNull null]){ 59 | self.errorMessage = data[@"error_message"]; 60 | }else{ 61 | self.errorMessage = nil; 62 | } 63 | if(data[@"source"] != [NSNull null]){ 64 | self.sourceURL = [NSURL URLWithString:data[@"source"]]; 65 | }else{ 66 | self.sourceURL = nil; 67 | } 68 | self.startTime = [PutIOAPIObject dateFromRawDataString:data[@"created_at"]]; 69 | if(data[@"estimated_time"] != [NSNull null]){ 70 | self.estimatedTimeRemaining = [data[@"estimated_time"] doubleValue]; 71 | }else{ 72 | self.estimatedTimeRemaining = 0.0f; 73 | } 74 | self.torrentRatio = [data[@"current_ratio"] floatValue]; 75 | } 76 | return self; 77 | } 78 | 79 | @end 80 | -------------------------------------------------------------------------------- /Classes/PutIOAPITransfersRequest.h: -------------------------------------------------------------------------------- 1 | 2 | #import "PutIOAPIRequest.h" 3 | #import "PutIOAPITransfer.h" 4 | 5 | @interface PutIOAPITransfersRequest : PutIOAPIRequest 6 | 7 | @property (readonly) NSArray *transfers; 8 | 9 | + (instancetype)requestAllTransfersWithCompletion:(PutIOAPIRequestCompletion)completion; 10 | 11 | @end 12 | -------------------------------------------------------------------------------- /Classes/PutIOAPITransfersRequest.m: -------------------------------------------------------------------------------- 1 | 2 | #import "PutIOAPITransfersRequest.h" 3 | 4 | @implementation PutIOAPITransfersRequest 5 | 6 | +(instancetype)requestAllTransfersWithCompletion:(PutIOAPIRequestCompletion)completion 7 | { 8 | return [[self alloc] initWithMethod:PutIOAPIMethodGET 9 | endpoint:@"transfers/list" 10 | parameters:nil 11 | completionBlock:completion]; 12 | } 13 | 14 | -(void)parseResponseObject:(id)response 15 | { 16 | NSMutableArray *transfers = [NSMutableArray array]; 17 | for(NSDictionary *transferData in response[@"transfers"]){ 18 | PutIOAPITransfer *transfer = [[PutIOAPITransfer alloc] initWithRawData:transferData]; 19 | [transfers addObject:transfer]; 20 | } 21 | _transfers = transfers; 22 | } 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Classes/PutIODownloadManager.h: -------------------------------------------------------------------------------- 1 | 2 | #import "PutIOAPIFile.h" 3 | #import "Download.h" 4 | 5 | @interface PutIODownloadManager : NSObject 6 | 7 | @property (nonatomic, readonly) NSInteger numberOfRunningDownloads; 8 | @property (nonatomic, readonly, copy) NSArray *allDownloads; 9 | 10 | + (instancetype)manager; 11 | 12 | - (void)addDownload:(Download*)download; 13 | - (void)loadDownloads; 14 | - (void)clearDownloadList; 15 | - (BOOL)downloadExistsForFile:(PutIOAPIFile*)file; 16 | - (void)saveDownloads; 17 | - (void)complyWithMaximumParallelDownloads; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Classes/PutIODownloadManager.m: -------------------------------------------------------------------------------- 1 | 2 | #import "PutIODownloadManager.h" 3 | 4 | @interface PutIODownloadManager() 5 | { 6 | NSMutableArray* allDownloads; 7 | } 8 | @end 9 | 10 | @implementation PutIODownloadManager 11 | 12 | +(instancetype)manager 13 | { 14 | static PutIODownloadManager *sharedInstance = nil; 15 | static dispatch_once_t onceToken; 16 | dispatch_once(&onceToken, ^{ 17 | sharedInstance = [[PutIODownloadManager alloc] init]; 18 | }); 19 | return sharedInstance; 20 | } 21 | 22 | - (instancetype)init 23 | { 24 | self = [super init]; 25 | if (self) { 26 | allDownloads = [NSMutableArray array]; 27 | } 28 | return self; 29 | } 30 | 31 | -(void)loadDownloads 32 | { 33 | NSFetchRequest *request = [[Persistency manager].model fetchRequestTemplateForName:@"AllDownloads"]; 34 | allDownloads = [[[Persistency manager].context executeFetchRequest:request error:nil] mutableCopy]; 35 | for(Download *download in allDownloads){ 36 | if(download.shouldResumeOnAppLaunch){ 37 | download.shouldResumeOnAppLaunch = NO; 38 | [download startDownload]; 39 | } 40 | } 41 | } 42 | 43 | -(void)addDownload:(Download *)download 44 | { 45 | [allDownloads addObject:download]; 46 | } 47 | 48 | - (NSArray*)allDownloads 49 | { 50 | return allDownloads; 51 | } 52 | 53 | - (void)clearDownloadList 54 | { 55 | for(Download *download in [allDownloads copy]){ 56 | if(download.status != PutIODownloadStatusDownloading && download.status != PutIODownloadStatusPending && download.status != PutIODownloadStatusFinishing){ 57 | [download cancelDownload]; 58 | [allDownloads removeObject:download]; 59 | [download.managedObjectContext deleteObject:download]; 60 | } 61 | } 62 | } 63 | 64 | - (BOOL)downloadExistsForFile:(PutIOAPIFile *)file 65 | { 66 | for(Download *download in allDownloads) 67 | if((download.putioFile).fileID == file.fileID) 68 | return YES; 69 | return NO; 70 | } 71 | 72 | //- (void)pauseAndSaveAllDownloads 73 | //{ 74 | // // Call this before the application terminates 75 | // for(Download *download in allDownloads) 76 | // [download stopWaitingForOtherDownloads]; 77 | // for(Download *download in allDownloads){ 78 | // if(download.status == PutIODownloadStatusDownloading || download.status == PutIODownloadStatusPending){ 79 | // [download pauseDownload]; 80 | // download.shouldResumeOnAppLaunch = YES; 81 | // } 82 | // } 83 | // [[Persistency manager].context save:nil]; 84 | //} 85 | 86 | - (void)saveDownloads 87 | { 88 | //[PersistenceManager storePersistentObject:allDownloads forKey:@"downloads"]; 89 | } 90 | 91 | - (NSInteger)numberOfRunningDownloads 92 | { 93 | NSInteger count = 0; 94 | for(Download *download in allDownloads){ 95 | if(download.status == PutIODownloadStatusDownloading){ 96 | count++; 97 | } 98 | } 99 | return count; 100 | } 101 | 102 | - (void)complyWithMaximumParallelDownloads 103 | { 104 | NSInteger maxParallelDownloads = [[NSUserDefaults standardUserDefaults] integerForKey:@"general_paralleldownloads"]; 105 | while([self numberOfRunningDownloads] > maxParallelDownloads){ 106 | for(Download *download in allDownloads){ 107 | if(download.status == PutIODownloadStatusDownloading){ 108 | [download pauseDownload]; 109 | [download startDownload]; 110 | break; 111 | } 112 | } 113 | } 114 | for(Download *download in allDownloads){ 115 | if(download.status == PutIODownloadStatusPending) 116 | [download startDownload]; 117 | } 118 | } 119 | 120 | @end 121 | -------------------------------------------------------------------------------- /Classes/PutIOFolderPicker.h: -------------------------------------------------------------------------------- 1 | 2 | #import "PutIOAPI.h" 3 | #import "PutIOAPIFile.h" 4 | 5 | @class PutIOFolderPicker; 6 | @protocol PutIOFolderPickerDelegate 7 | -(void)folderPicker:(PutIOFolderPicker*)picker didPickFolder:(PutIOAPIFile*)folder; 8 | -(void)folderPickerDidCancel:(PutIOFolderPicker*)picker; 9 | @end 10 | 11 | @interface PutIOFolderPicker : NSWindowController 12 | 13 | { 14 | PutIOAPIFile *folderTree; 15 | 16 | IBOutlet NSOutlineView *outlineView; 17 | IBOutlet NSButton *chooseButton; 18 | IBOutlet NSButton *cancelButton; 19 | IBOutlet NSProgressIndicator *activitySpinner; 20 | } 21 | 22 | @property (unsafe_unretained) iddelegate; 23 | @property (assign, nonatomic) NSInteger pendingFetches; 24 | 25 | - (IBAction)chooseSelectedFolder:(id)sender; 26 | - (IBAction)cancel:(id)sender; 27 | 28 | - (void)updateFolders; 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /Classes/PutIOFolderPicker.m: -------------------------------------------------------------------------------- 1 | 2 | #import "PutIOFolderPicker.h" 3 | #import "PutIOAPIFileRequest.h" 4 | 5 | @interface PutIOFolderPicker () 6 | 7 | @end 8 | 9 | @implementation PutIOFolderPicker 10 | @synthesize pendingFetches = _pendingFetches; 11 | 12 | - (instancetype)init 13 | { 14 | self = [super initWithWindowNibName:@"PutIOFolderPicker"]; 15 | return self; 16 | } 17 | 18 | - (void)windowDidLoad 19 | { 20 | [super windowDidLoad]; 21 | } 22 | 23 | -(void)setPendingFetches:(NSInteger)pendingFetches 24 | { 25 | _pendingFetches = pendingFetches; 26 | if(pendingFetches > 0){ 27 | [activitySpinner startAnimation:self]; 28 | }else{ 29 | [activitySpinner stopAnimation:self]; 30 | } 31 | } 32 | 33 | #pragma mark - Actions 34 | 35 | -(void)chooseSelectedFolder:(id)sender 36 | { 37 | if(outlineView.selectedRow != -1){ 38 | NSTableCellView *selectedCellView = [outlineView viewAtColumn:0 row:outlineView.selectedRow makeIfNecessary:YES]; 39 | PutIOAPIFile *pickedFolder = selectedCellView.objectValue; 40 | [self.window close]; 41 | if([_delegate respondsToSelector:@selector(folderPicker:didPickFolder:)]) 42 | [_delegate folderPicker:self didPickFolder:pickedFolder]; 43 | } 44 | } 45 | 46 | -(void)cancel:(id)sender 47 | { 48 | [self.window close]; 49 | if([_delegate respondsToSelector:@selector(folderPickerDidCancel:)]) 50 | [_delegate folderPickerDidCancel:self]; 51 | } 52 | 53 | #pragma mark - Outline View Delegate 54 | 55 | -(PutIOAPIFile*)folderForOutlineItem:(id)item 56 | { 57 | if(item == nil){ 58 | return folderTree; 59 | }else{ 60 | return (PutIOAPIFile*)item; 61 | } 62 | } 63 | 64 | -(BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item 65 | { 66 | if(folderTree == nil) 67 | return NO; 68 | PutIOAPIFile *folder = [self folderForOutlineItem:item]; 69 | if(folder.subfolders == nil){ 70 | return YES; 71 | }else{ 72 | return folder.subfolders.count > 0; 73 | } 74 | } 75 | 76 | -(NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item 77 | { 78 | if(folderTree == nil) 79 | return NO; 80 | PutIOAPIFile *folder = [self folderForOutlineItem:item]; 81 | if(folder.subfolders == nil){ 82 | if(folder != folderTree){ 83 | [self fetchSubfoldersOfNode:item]; 84 | } 85 | return 0; 86 | }else{ 87 | return folder.subfolders.count; 88 | } 89 | } 90 | 91 | -(id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item 92 | { 93 | PutIOAPIFile *folder = [self folderForOutlineItem:item]; 94 | return folder.subfolders[index]; 95 | } 96 | 97 | -(id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item 98 | { 99 | return [self folderForOutlineItem:item]; 100 | } 101 | 102 | -(void)outlineViewSelectionDidChange:(NSNotification *)notification 103 | { 104 | chooseButton.enabled = (outlineView.selectedRow != -1); 105 | } 106 | 107 | #pragma mark - Fetch Folder Listing 108 | 109 | - (void)updateFolders 110 | { 111 | folderTree = nil; 112 | [outlineView reloadData]; 113 | [chooseButton setEnabled:NO]; 114 | [self fetchSubfoldersOfNode:nil]; 115 | } 116 | 117 | - (void)fetchSubfoldersOfNode:(PutIOAPIFile*)parent 118 | { 119 | NSInteger folderID = 0; 120 | if(parent != nil){ 121 | folderID = parent.fileID; 122 | } 123 | __block PutIOAPIFileRequest *request = [PutIOAPIFileRequest requestFilesInFolderWithID:folderID completion:^{ 124 | self.pendingFetches--; 125 | if(request.error == nil && !request.isCancelled){ 126 | PutIOAPIFile *node = parent; 127 | if(node == nil){ 128 | folderTree = request.parentFolder; 129 | node = folderTree; 130 | } 131 | NSMutableArray *subfolders = [NSMutableArray array]; 132 | for(PutIOAPIFile *file in request.files){ 133 | if(file.isFolder){ 134 | [subfolders addObject:file]; 135 | } 136 | } 137 | node.subfolders = subfolders; 138 | [outlineView reloadData]; 139 | }else if(request.error != nil){ 140 | [activitySpinner stopAnimation:self]; 141 | [outlineView reloadData]; 142 | } 143 | }]; 144 | 145 | PutIOAPI *api = [PutIOAPI api]; 146 | [api performRequest:request]; 147 | self.pendingFetches++; 148 | 149 | 150 | } 151 | 152 | @end 153 | -------------------------------------------------------------------------------- /Classes/PutIOSync-Prefix.pch: -------------------------------------------------------------------------------- 1 | 2 | #ifdef __OBJC__ 3 | 4 | @import Cocoa; 5 | @import CoreData; 6 | #import "Persistency.h" 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /Classes/PutIOTransfersMonitor.h: -------------------------------------------------------------------------------- 1 | 2 | @import Foundation; 3 | #import "PutIOAPI.h" 4 | 5 | #define PutIOTransfersMonitorUpdatedNotification @"PutIOTransfersMonitorUpdatedNotification" 6 | 7 | @interface PutIOTransfersMonitor : NSObject 8 | 9 | + (instancetype)monitor; 10 | 11 | - (void)startMonitoringTransfers; 12 | - (void)stopMonitoringTransfers; 13 | - (void)updateTransfers; 14 | @property (nonatomic, readonly, copy) NSArray *allActiveTransfers; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Classes/PutIOTransfersMonitor.m: -------------------------------------------------------------------------------- 1 | 2 | #import "PutIOTransfersMonitor.h" 3 | #import "PutIOAPITransfersRequest.h" 4 | 5 | @interface PutIOTransfersMonitor() 6 | { 7 | NSArray *activeTransfers; 8 | NSTimer *updateTransfersTimer; 9 | PutIOAPI *api; 10 | } 11 | @end 12 | 13 | @implementation PutIOTransfersMonitor 14 | 15 | static PutIOTransfersMonitor *sharedInstance; 16 | 17 | +(instancetype)monitor 18 | { 19 | if(!sharedInstance) 20 | sharedInstance = [[PutIOTransfersMonitor alloc] init]; 21 | return sharedInstance; 22 | } 23 | 24 | - (instancetype)init 25 | { 26 | self = [super init]; 27 | if (self) { 28 | activeTransfers = @[]; 29 | api = [PutIOAPI api]; 30 | } 31 | return self; 32 | } 33 | 34 | -(void)startMonitoringTransfers 35 | { 36 | [self stopMonitoringTransfers]; 37 | [self updateTransfers]; 38 | } 39 | 40 | -(void)stopMonitoringTransfers 41 | { 42 | if(updateTransfersTimer != nil){ 43 | [updateTransfersTimer invalidate]; 44 | updateTransfersTimer = nil; 45 | } 46 | } 47 | 48 | -(void)updateTransfers 49 | { 50 | __block PutIOAPITransfersRequest *request = [PutIOAPITransfersRequest requestAllTransfersWithCompletion:^{ 51 | if(request.error == nil && !request.isCancelled){ 52 | activeTransfers = request.transfers; 53 | [[NSNotificationCenter defaultCenter] postNotificationName:PutIOTransfersMonitorUpdatedNotification object:nil]; 54 | // Update again in a few seconds: 55 | updateTransfersTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateTransfers) userInfo:nil repeats:NO]; 56 | } 57 | }]; 58 | [api performRequest:request]; 59 | } 60 | 61 | -(NSArray *)allActiveTransfers 62 | { 63 | return activeTransfers; 64 | } 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /Classes/StatusItemView.h: -------------------------------------------------------------------------------- 1 | 2 | @interface StatusItemView : NSView 3 | 4 | - (instancetype)initWithFrame:(NSRect)frameRect NS_UNAVAILABLE; 5 | - (instancetype)initWithCoder:(NSCoder *)coder NS_UNAVAILABLE; 6 | - (instancetype)initWithStatusItem:(NSStatusItem *)statusItem NS_DESIGNATED_INITIALIZER; 7 | 8 | @property (nonatomic, strong, readonly) NSStatusItem *statusItem; 9 | @property (nonatomic, strong) NSImage *image; 10 | @property (nonatomic, strong) NSImage *alternateImage; 11 | @property (nonatomic) BOOL isHighlighted; 12 | @property (nonatomic, readonly) NSRect globalRect; 13 | @property (nonatomic) SEL action; 14 | @property (nonatomic, unsafe_unretained) id target; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Classes/StatusItemView.m: -------------------------------------------------------------------------------- 1 | #import "StatusItemView.h" 2 | 3 | @implementation StatusItemView 4 | 5 | #pragma mark - 6 | 7 | - (instancetype)initWithStatusItem:(NSStatusItem *)statusItem 8 | { 9 | CGFloat itemWidth = statusItem.length; 10 | CGFloat itemHeight = [NSStatusBar systemStatusBar].thickness; 11 | NSRect itemRect = NSMakeRect(0.0, 0.0, itemWidth, itemHeight); 12 | self = [super initWithFrame:itemRect]; 13 | 14 | if (self != nil) { 15 | _statusItem = statusItem; 16 | _statusItem.view = self; 17 | } 18 | return self; 19 | } 20 | 21 | 22 | #pragma mark - 23 | 24 | - (void)drawRect:(NSRect)dirtyRect 25 | { 26 | [self.statusItem drawStatusBarBackgroundInRect:dirtyRect withHighlight:self.isHighlighted]; 27 | 28 | NSImage *icon = self.isHighlighted ? self.alternateImage : self.image; 29 | NSSize iconSize = icon.size; 30 | NSRect bounds = self.bounds; 31 | CGFloat iconX = roundf((NSWidth(bounds) - iconSize.width) / 2); 32 | CGFloat iconY = roundf((NSHeight(bounds) - iconSize.height) / 2); 33 | NSPoint iconPoint = NSMakePoint(iconX, iconY); 34 | 35 | [icon drawAtPoint:iconPoint fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; 36 | } 37 | 38 | #pragma mark - 39 | #pragma mark Mouse tracking 40 | 41 | - (void)mouseDown:(NSEvent *)theEvent 42 | { 43 | [NSApp sendAction:self.action to:self.target from:self]; 44 | } 45 | 46 | #pragma mark - 47 | #pragma mark Accessors 48 | 49 | - (void)setHighlighted:(BOOL)newFlag 50 | { 51 | if (_isHighlighted == newFlag) return; 52 | _isHighlighted = newFlag; 53 | [self setNeedsDisplay:YES]; 54 | } 55 | 56 | #pragma mark - 57 | 58 | - (void)setImage:(NSImage *)newImage 59 | { 60 | if (_image != newImage) { 61 | _image = newImage; 62 | [self setNeedsDisplay:YES]; 63 | } 64 | } 65 | 66 | - (void)setAlternateImage:(NSImage *)newImage 67 | { 68 | if (_alternateImage != newImage) { 69 | _alternateImage = newImage; 70 | if (self.isHighlighted) { 71 | [self setNeedsDisplay:YES]; 72 | } 73 | } 74 | } 75 | 76 | #pragma mark - 77 | 78 | - (NSRect)globalRect 79 | { 80 | return [self.window convertRectToScreen:self.frame]; 81 | } 82 | 83 | @end 84 | -------------------------------------------------------------------------------- /Classes/SyncInstruction.h: -------------------------------------------------------------------------------- 1 | 2 | @import Foundation; 3 | @import CoreData; 4 | 5 | 6 | @interface SyncInstruction : NSManagedObject 7 | 8 | @property (nonatomic, retain) NSNumber *originFolderID; 9 | @property (nonatomic, retain) NSString *originFolderName; 10 | @property (nonatomic, retain) NSData *localDestinationBookmark; 11 | @property (nonatomic, retain) NSNumber *deleteRemoteFilesAfterSync; 12 | @property (nonatomic, retain) NSNumber *deleteRemoteEmptyFolders; 13 | @property (nonatomic, retain) NSNumber *recursive; 14 | @property (nonatomic, retain) NSNumber *flattenSubdirectories; 15 | @property (nonatomic, retain) NSDate *lastSynced; 16 | @property (nonatomic, retain) NSSet *knownItems; 17 | 18 | @property (strong) NSURL *localDestination; 19 | 20 | + (NSArray*)allSyncInstructions; 21 | 22 | - (void)addKnownItemWithID:(NSInteger)itemID; 23 | - (BOOL)itemWithIDIsKnown:(NSInteger)itemID; 24 | - (void)resetKnownItems; 25 | 26 | @end 27 | 28 | @interface SyncInstruction (CoreDataGeneratedAccessors) 29 | 30 | - (void)addKnownItemsObject:(NSManagedObject *)value; 31 | - (void)removeKnownItemsObject:(NSManagedObject *)value; 32 | - (void)addKnownItems:(NSSet *)values; 33 | - (void)removeKnownItems:(NSSet *)values; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /Classes/SyncInstruction.m: -------------------------------------------------------------------------------- 1 | 2 | #import "SyncInstruction.h" 3 | #import "KnownItem.h" 4 | #import "Persistency.h" 5 | 6 | @implementation SyncInstruction 7 | 8 | @dynamic originFolderID; 9 | @dynamic originFolderName; 10 | @dynamic localDestinationBookmark; 11 | @dynamic deleteRemoteFilesAfterSync; 12 | @dynamic deleteRemoteEmptyFolders; 13 | @dynamic recursive; 14 | @dynamic flattenSubdirectories; 15 | @dynamic lastSynced; 16 | @dynamic knownItems; 17 | 18 | @synthesize localDestination = _localDestination; 19 | 20 | -(void)awakeFromInsert 21 | { 22 | self.deleteRemoteFilesAfterSync = @(NO); 23 | self.deleteRemoteEmptyFolders = @(NO); 24 | self.flattenSubdirectories = @(YES); 25 | self.recursive = @(YES); 26 | } 27 | 28 | + (NSArray *)allSyncInstructions 29 | { 30 | NSFetchRequest *request = [[Persistency manager].model fetchRequestTemplateForName:@"AllSyncInstructions"]; 31 | NSArray *objects = [[Persistency manager].context executeFetchRequest:request error:nil]; 32 | return objects; 33 | } 34 | 35 | -(void)setLocalDestination:(NSURL *)localDestination 36 | { 37 | _localDestination = localDestination; 38 | self.localDestinationBookmark = [self.localDestination bookmarkDataWithOptions:NSURLBookmarkCreationSuitableForBookmarkFile 39 | includingResourceValuesForKeys:nil 40 | relativeToURL:nil 41 | error:nil]; 42 | } 43 | 44 | -(NSURL *)localDestination 45 | { 46 | if(_localDestination == nil && self.localDestinationBookmark != nil){ 47 | NSError *error; 48 | BOOL isStale = NO; 49 | _localDestination =[NSURL URLByResolvingBookmarkData:self.localDestinationBookmark 50 | options:NSURLBookmarkResolutionWithoutUI 51 | relativeToURL:nil 52 | bookmarkDataIsStale:&isStale 53 | error:&error]; 54 | if (error != nil) { 55 | NSLog(@"Failed to resolve localDestination of %@: %@", self, error); 56 | } 57 | } 58 | return _localDestination; 59 | } 60 | 61 | -(void)resetKnownItems 62 | { 63 | for(KnownItem *item in self.knownItems){ 64 | [item.managedObjectContext deleteObject:item]; 65 | } 66 | } 67 | 68 | -(void)addKnownItemWithID:(NSInteger)itemID 69 | { 70 | KnownItem *item = [[KnownItem alloc] initWithEntity:[[Persistency manager] entityNamed:@"KnownItem"] 71 | insertIntoManagedObjectContext:self.managedObjectContext]; 72 | item.itemID = @(itemID); 73 | [self addKnownItemsObject:item]; 74 | } 75 | 76 | -(BOOL)itemWithIDIsKnown:(NSInteger)itemID 77 | { 78 | for(KnownItem *item in self.knownItems){ 79 | if([item.itemID isEqual:@(itemID)]){ 80 | return YES; 81 | } 82 | } 83 | return NO; 84 | } 85 | 86 | @end 87 | -------------------------------------------------------------------------------- /Classes/SyncInstructionEditor.h: -------------------------------------------------------------------------------- 1 | 2 | @import Cocoa; 3 | #import "SyncInstruction.h" 4 | #import "PutIOFolderPicker.h" 5 | 6 | @interface SyncInstructionEditor : NSWindowController 7 | 8 | 9 | @property (strong) SyncInstruction *syncInstruction; 10 | //@property (unsafe_unretained) iddelegate; 11 | 12 | -(IBAction)pickOriginFolder:(id)sender; 13 | -(IBAction)pickDestinationFolder:(id)sender; 14 | -(IBAction)commit:(id)sender; 15 | -(IBAction)cancel:(id)sender; 16 | -(IBAction)optionsChanged:(id)sender; 17 | -(IBAction)resetKnownItems:(id)sender; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Classes/SyncPreferences.h: -------------------------------------------------------------------------------- 1 | 2 | #import "MASPreferencesViewController.h" 3 | #import "SyncInstructionEditor.h" 4 | @import Cocoa; 5 | 6 | @interface SyncPreferences : NSViewController 7 | 8 | { 9 | SyncInstructionEditor *syncInstructionEditor; 10 | NSInteger editedSyncInstructionIndex; 11 | 12 | IBOutlet NSButton *addButton; 13 | IBOutlet NSButton *removeButton; 14 | IBOutlet NSTableView *tableView; 15 | } 16 | 17 | @property (strong) NSMutableArray *syncInstrucions; 18 | @property (readonly) NSManagedObjectContext *context; 19 | 20 | -(IBAction)addSyncInstruction:(id)sender; 21 | -(IBAction)editSyncInstruction:(id)sender; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Classes/SyncPreferences.m: -------------------------------------------------------------------------------- 1 | 2 | #import "SyncPreferences.h" 3 | #import "SyncScheduler.h" 4 | 5 | @interface SyncPreferences () 6 | 7 | @end 8 | 9 | @implementation SyncPreferences 10 | 11 | - (instancetype)init 12 | { 13 | self = [super initWithNibName:@"SyncPreferences" bundle:nil]; 14 | return self; 15 | } 16 | 17 | #pragma mark - PreferencesViewController 18 | 19 | - (NSString *)identifier 20 | { 21 | return @"SyncPreferences"; 22 | } 23 | 24 | - (NSImage *)toolbarItemImage 25 | { 26 | return [NSImage imageNamed:@"syncIcon"]; 27 | } 28 | 29 | - (NSString *)toolbarItemLabel 30 | { 31 | return NSLocalizedString(@"Synced Folders", @"Sync Preferences title"); 32 | } 33 | 34 | -(void)viewWillAppear 35 | { 36 | //[super viewWillAppear]; 37 | addButton.enabled = [[PutIOAPI api] isAuthenticated]; 38 | } 39 | 40 | #pragma mark - Accessors 41 | 42 | -(NSManagedObjectContext *)context 43 | { 44 | return [Persistency manager].context; 45 | } 46 | 47 | #pragma mark - Actions 48 | 49 | -(void)addSyncInstruction:(id)sender 50 | { 51 | [self presentSyncInstrucionEditorFor:-1]; 52 | } 53 | 54 | -(void)editSyncInstruction:(id)sender 55 | { 56 | NSInteger row = [tableView rowForView:(NSView *)sender]; 57 | [self presentSyncInstrucionEditorFor:row]; 58 | } 59 | 60 | #pragma mark - Edit Sync Instruction 61 | 62 | - (void)presentSyncInstrucionEditorFor:(NSInteger)row 63 | { 64 | if(![[PutIOAPI api] isAuthenticated]) 65 | return; 66 | if(!syncInstructionEditor){ 67 | syncInstructionEditor = [[SyncInstructionEditor alloc] init]; 68 | } 69 | editedSyncInstructionIndex = row; 70 | if(row == -1) 71 | [syncInstructionEditor setSyncInstruction:nil]; 72 | else 73 | syncInstructionEditor.syncInstruction = [SyncInstruction allSyncInstructions][row]; 74 | [NSApp beginSheet:syncInstructionEditor.window 75 | modalForWindow:self.view.window 76 | modalDelegate:nil 77 | didEndSelector:nil 78 | contextInfo:nil]; 79 | } 80 | 81 | @end 82 | -------------------------------------------------------------------------------- /Classes/SyncRunner.h: -------------------------------------------------------------------------------- 1 | 2 | @import Foundation; 3 | #import "SyncInstruction.h" 4 | #import "PutIOAPI.h" 5 | 6 | @class SyncRunner; 7 | @protocol SyncRunnerDelegate 8 | - (void)syncRunnerDidFinish:(SyncRunner*)runner afterFindingFiles:(NSUInteger)fileCount; 9 | - (void)syncRunnerDidCancel:(SyncRunner*)runner; 10 | - (void)syncRunner:(SyncRunner*)runner didFailWithError:(NSError*)error; 11 | @end 12 | 13 | @interface SyncRunner : NSObject 14 | 15 | @property (unsafe_unretained) id delegate; 16 | @property (readonly) BOOL isBusy; 17 | @property (readonly) SyncInstruction *syncInstruction; 18 | @property (readonly, strong) NSString *localizedOperationName; 19 | 20 | - (instancetype)init NS_UNAVAILABLE; 21 | - (instancetype)initWithSyncInstruction:(SyncInstruction*)instruction NS_DESIGNATED_INITIALIZER; 22 | - (void)run; 23 | - (void)cancel; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /Classes/SyncScheduler.h: -------------------------------------------------------------------------------- 1 | 2 | @import Foundation; 3 | #import "SyncRunner.h" 4 | #import "SyncInstruction.h" 5 | 6 | #define SyncSchedulerSyncDidChangeNotification @"SyncSchedulerSyncDidChangeNotification" 7 | 8 | @interface SyncScheduler : NSObject 9 | 10 | { 11 | NSUInteger foundFiles; 12 | NSTimer *timer; 13 | } 14 | 15 | +(SyncScheduler*)sharedSyncScheduler; 16 | 17 | @property (strong) NSMutableArray *runningSyncs; 18 | 19 | -(void)scheduleSyncs; 20 | -(void)startSyncingAll; 21 | -(void)cancelAllSyncsInProgress; 22 | -(void)cancelSyncForInstruction:(SyncInstruction*)instruction; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Classes/SyncScheduler.m: -------------------------------------------------------------------------------- 1 | 2 | #import "SyncScheduler.h" 3 | #import "PutIODownloadManager.h" 4 | #import "ApplicationDelegate.h" 5 | 6 | @implementation SyncScheduler 7 | 8 | static SyncScheduler* sharedInstance; 9 | 10 | +(SyncScheduler*)sharedSyncScheduler 11 | { 12 | if(!sharedInstance) 13 | sharedInstance = [[SyncScheduler alloc] init]; 14 | return sharedInstance; 15 | } 16 | 17 | - (instancetype)init 18 | { 19 | self = [super init]; 20 | if (self) { 21 | self.runningSyncs = [NSMutableArray array]; 22 | 23 | NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 24 | [defaults addObserver:self 25 | forKeyPath:@"general_syncinterval" 26 | options:NSKeyValueObservingOptionNew 27 | context:NULL]; 28 | } 29 | return self; 30 | } 31 | 32 | -(void)observeValueForKeyPath:(NSString *)keyPath 33 | ofObject:(id)object 34 | change:(NSDictionary *)change 35 | context:(void *)context 36 | { 37 | [self scheduleSyncs]; 38 | } 39 | 40 | -(void)dealloc 41 | { 42 | NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 43 | [defaults removeObserver:self forKeyPath:@"general_syncinterval"]; 44 | [timer invalidate]; 45 | } 46 | 47 | -(void)scheduleSyncs 48 | { 49 | if(timer) 50 | [timer invalidate]; 51 | NSInteger intervalPreset = [[NSUserDefaults standardUserDefaults] integerForKey:@"general_syncinterval"]; 52 | NSTimeInterval interval = 0; 53 | if(intervalPreset == 0) 54 | interval = 60; // Every minute 55 | if(intervalPreset == 1) 56 | interval = 60 * 5; // Every 5 minutes 57 | if(intervalPreset == 2) 58 | interval = 60 * 10; 59 | if(intervalPreset == 3) 60 | interval = 60 * 30; 61 | if(intervalPreset == 4) 62 | interval = 60 * 60; 63 | if(interval == 0) 64 | return; 65 | timer = [NSTimer scheduledTimerWithTimeInterval:interval target:self selector:@selector(startSyncingAll) userInfo:nil repeats:YES]; 66 | 67 | NSLog(@"%@ scheduled sync every %f seconds", self, interval); 68 | } 69 | 70 | -(void)startSyncingAll 71 | { 72 | if(![[PutIOAPI api] isAuthenticated]) { 73 | return; 74 | } 75 | if((self.runningSyncs).count > 0) { 76 | return; 77 | } 78 | 79 | foundFiles = 0; 80 | 81 | for (SyncInstruction *instruction in [SyncInstruction allSyncInstructions]) { 82 | SyncRunner *runner = [[SyncRunner alloc] initWithSyncInstruction:instruction]; 83 | runner.delegate = self; 84 | [runner run]; 85 | [self.runningSyncs addObject:runner]; 86 | [[NSNotificationCenter defaultCenter] postNotificationName:SyncSchedulerSyncDidChangeNotification object:runner]; 87 | } 88 | } 89 | 90 | -(void)cancelAllSyncsInProgress 91 | { 92 | for(SyncRunner *runner in self.runningSyncs) { 93 | [runner cancel]; 94 | } 95 | } 96 | 97 | -(void)cancelSyncForInstruction:(SyncInstruction*)instruction 98 | { 99 | for (SyncRunner *runner in self.runningSyncs) { 100 | if ([runner.syncInstruction.objectID.URIRepresentation isEqual:instruction.objectID.URIRepresentation]) { 101 | [runner cancel]; 102 | } 103 | } 104 | } 105 | 106 | #pragma mark - Sync Runner Delegate 107 | 108 | -(void)syncRunner:(SyncRunner *)runner didFailWithError:(NSError *)error 109 | { 110 | [self.runningSyncs removeObject:runner]; 111 | [[NSNotificationCenter defaultCenter] postNotificationName:SyncSchedulerSyncDidChangeNotification object:runner]; 112 | [self deliverNotificationConditionally]; 113 | } 114 | 115 | -(void)syncRunnerDidFinish:(SyncRunner *)runner afterFindingFiles:(NSUInteger)fileCount 116 | { 117 | [self.runningSyncs removeObject:runner]; 118 | [[NSNotificationCenter defaultCenter] postNotificationName:SyncSchedulerSyncDidChangeNotification object:runner]; 119 | foundFiles += fileCount; 120 | [self deliverNotificationConditionally]; 121 | } 122 | 123 | -(void)syncRunnerDidCancel:(SyncRunner *)runner 124 | { 125 | [self.runningSyncs removeObject:runner]; 126 | [[NSNotificationCenter defaultCenter] postNotificationName:SyncSchedulerSyncDidChangeNotification object:runner]; 127 | [self deliverNotificationConditionally]; 128 | } 129 | 130 | -(void)deliverNotificationConditionally 131 | { 132 | if((self.runningSyncs).count == 0 && foundFiles > 0){ 133 | NSString *message = [NSString stringWithFormat:NSLocalizedString(@"%i files from put.io began downloading",nil), 134 | foundFiles]; 135 | [(ApplicationDelegate*)NSApp.delegate deliverUserNotificationWithIdentifier:@"newfiles" message:message]; 136 | } 137 | } 138 | 139 | @end 140 | -------------------------------------------------------------------------------- /Classes/TimeIntervalFormatter.h: -------------------------------------------------------------------------------- 1 | 2 | @interface TimeIntervalFormatter : NSObject 3 | 4 | - (NSString*)stringFromTimeInterval:(NSTimeInterval)interval; 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /Classes/TimeIntervalFormatter.m: -------------------------------------------------------------------------------- 1 | 2 | #import "TimeIntervalFormatter.h" 3 | 4 | @implementation TimeIntervalFormatter 5 | 6 | static const double multipliers[] = {1.0f, 60.0f, 60.0f * 60.0f, 60.0f * 60.0f * 24.0f}; 7 | static NSArray *unitsSingular; 8 | static NSArray *unitsPlural; 9 | 10 | - (instancetype)init 11 | { 12 | self = [super init]; 13 | if (self) { 14 | if(!unitsSingular){ 15 | unitsSingular = @[ 16 | NSLocalizedString(@"second", nil), 17 | NSLocalizedString(@"minute", nil), 18 | NSLocalizedString(@"hour", nil), 19 | NSLocalizedString(@"day", nil) 20 | ]; 21 | unitsPlural = @[ 22 | NSLocalizedString(@"seconds", nil), 23 | NSLocalizedString(@"minutes", nil), 24 | NSLocalizedString(@"hours", nil), 25 | NSLocalizedString(@"days", nil) 26 | ]; 27 | } 28 | } 29 | return self; 30 | } 31 | 32 | -(NSString *)stringFromTimeInterval:(NSTimeInterval)interval 33 | { 34 | long seconds = fabs(interval); 35 | NSString *result = @""; 36 | for(int i = 3; i >= 0; i--){ 37 | int value = (int)floor((double)seconds / multipliers[i]); 38 | if(value > 0){ 39 | seconds = seconds % (long)multipliers[i]; 40 | result = [result stringByAppendingFormat:@"%i %@ ", value, (value == 1 ? unitsSingular[i] : unitsPlural[i])]; 41 | if(i == 1){ 42 | // Hide seconds when we already have minutes 43 | break; 44 | } 45 | } 46 | } 47 | return result; 48 | } 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /Classes/TransferCellView.h: -------------------------------------------------------------------------------- 1 | 2 | @import Cocoa; 3 | #import "PutIOAPITransfer.h" 4 | 5 | @interface TransferCellView : NSTableCellView 6 | { 7 | IBOutlet NSProgressIndicator *progressBar; 8 | IBOutlet NSTextField *statusLabel; 9 | IBOutlet NSButton *cancelButton; 10 | IBOutlet NSImageView *icon; 11 | } 12 | 13 | - (IBAction)cancelTransfer:(id)sender; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Classes/TransferCellView.m: -------------------------------------------------------------------------------- 1 | 2 | #import "TransferCellView.h" 3 | #import "BytesFormatter.h" 4 | #import "TimeIntervalFormatter.h" 5 | 6 | static BytesFormatter *bytesFormatter; 7 | static TimeIntervalFormatter *timeIntervalFormatter; 8 | 9 | @implementation TransferCellView 10 | 11 | -(void)setObjectValue:(id)objectValue 12 | { 13 | if(bytesFormatter == nil){ 14 | bytesFormatter = [[BytesFormatter alloc] init]; 15 | } 16 | if(timeIntervalFormatter == nil){ 17 | timeIntervalFormatter = [[TimeIntervalFormatter alloc] init]; 18 | } 19 | 20 | super.objectValue = objectValue; 21 | PutIOAPITransfer *transfer = (PutIOAPITransfer*)objectValue; 22 | 23 | icon.image = [NSImage imageNamed:@"transfer"]; 24 | 25 | NSString *status = [NSMutableString string]; 26 | switch (transfer.status) { 27 | case PutIOAPITransferStatusInQueue:{ 28 | status = NSLocalizedString(@"In queue", nil); 29 | break; 30 | } 31 | case PutIOAPITransferStatusDownloading:{ 32 | status = [status stringByAppendingFormat:@"%@ of %@", [bytesFormatter stringFromBytes:transfer.sizeDownloaded], [bytesFormatter stringFromBytes:transfer.size]]; 33 | status = [status stringByAppendingFormat:@" (%@/s)", [bytesFormatter stringFromBytes:transfer.downloadSpeed]]; 34 | if(transfer.estimatedTimeRemaining > 0.0f) 35 | status = [status stringByAppendingFormat:@" - %@remaining", [timeIntervalFormatter stringFromTimeInterval:transfer.estimatedTimeRemaining]]; 36 | break; 37 | } 38 | case PutIOAPITransferStatusCompleted:{ 39 | status = NSLocalizedString(@"Finished", nil); 40 | status = [status stringByAppendingFormat:@" - %@", [bytesFormatter stringFromBytes:transfer.size]]; 41 | icon.image = [NSImage imageNamed:@"transfer_finished"]; 42 | break; 43 | } 44 | case PutIOAPITransferStatusSeeding:{ 45 | status = [NSString stringWithFormat:NSLocalizedString(@"Finished, seeding to %i peers - ", nil), transfer.seedingToPeersCount]; 46 | status = [status stringByAppendingFormat:@"%@", [bytesFormatter stringFromBytes:transfer.sizeUploaded]]; 47 | status = [status stringByAppendingFormat:@" (%@/s)", [bytesFormatter stringFromBytes:transfer.uploadSpeed]]; 48 | status = [status stringByAppendingFormat:@" - Ratio: %.2f", transfer.torrentRatio]; 49 | icon.image = [NSImage imageNamed:@"transfer_finished"]; 50 | break; 51 | } 52 | case PutIOAPITransferStatusFailed:{ 53 | status = [NSString stringWithFormat:NSLocalizedString(@"Error: %@", nil), transfer.errorMessage]; 54 | icon.image = [NSImage imageNamed:@"transfer_failed"]; 55 | break; 56 | } 57 | default: 58 | status = @""; 59 | break; 60 | } 61 | cancelButton.hidden = (transfer.status == PutIOAPITransferStatusCompleted || transfer.status == PutIOAPITransferStatusFailed); 62 | statusLabel.stringValue = status; 63 | } 64 | 65 | -(void)setBackgroundStyle:(NSBackgroundStyle)backgroundStyle 66 | { 67 | super.backgroundStyle = backgroundStyle; 68 | if(backgroundStyle == NSBackgroundStyleDark){ 69 | statusLabel.textColor = [NSColor selectedTextColor]; 70 | cancelButton.image = [NSImage imageNamed:@"stopImageInverted.png"]; 71 | }else if (backgroundStyle == NSBackgroundStyleLight){ 72 | statusLabel.textColor = [NSColor secondaryLabelColor]; 73 | cancelButton.image = [NSImage imageNamed:@"stopImage.png"]; 74 | } 75 | } 76 | 77 | -(void)cancelTransfer:(id)sender 78 | { 79 | 80 | } 81 | 82 | @end 83 | -------------------------------------------------------------------------------- /Classes/en.lproj/AccountSetupController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /Classes/en.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Classes/en.lproj/Localizable.strings -------------------------------------------------------------------------------- /Classes/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Popup 4 | // 5 | // Created by Vadim Shpakovski on 7/5/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | @import Cocoa; 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | return NSApplicationMain(argc, (const char **)argv); 14 | } 15 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Headers: -------------------------------------------------------------------------------- 1 | Versions/Current/Headers -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Modules: -------------------------------------------------------------------------------- 1 | Versions/Current/Modules -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/PrivateHeaders: -------------------------------------------------------------------------------- 1 | Versions/Current/PrivateHeaders -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Resources: -------------------------------------------------------------------------------- 1 | Versions/Current/Resources -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Sparkle: -------------------------------------------------------------------------------- 1 | Versions/Current/Sparkle -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Headers/SUAppcast.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUAppcast.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/12/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUAPPCAST_H 10 | #define SUAPPCAST_H 11 | 12 | #if __has_feature(modules) 13 | @import Foundation; 14 | #else 15 | #import 16 | #endif 17 | #import "SUExport.h" 18 | 19 | @class SUAppcastItem; 20 | SU_EXPORT @interface SUAppcast : NSObject 21 | 22 | @property (copy) NSString *userAgentString; 23 | @property (copy) NSDictionary *httpHeaders; 24 | 25 | - (void)fetchAppcastFromURL:(NSURL *)url completionBlock:(void (^)(NSError *))err; 26 | @property (nonatomic, readonly, strong) SUAppcast *copyWithoutDeltaUpdates; 27 | 28 | @property (readonly, copy) NSArray *items; 29 | @end 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Headers/SUAppcastItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUAppcastItem.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/12/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUAPPCASTITEM_H 10 | #define SUAPPCASTITEM_H 11 | 12 | #if __has_feature(modules) 13 | @import Foundation; 14 | #else 15 | #import 16 | #endif 17 | #import "SUExport.h" 18 | 19 | SU_EXPORT @interface SUAppcastItem : NSObject 20 | @property (copy, readonly) NSString *title; 21 | @property (copy, readonly) NSString *dateString; 22 | @property (copy, readonly) NSString *itemDescription; 23 | @property (strong, readonly) NSURL *releaseNotesURL; 24 | @property (copy, readonly) NSString *DSASignature; 25 | @property (copy, readonly) NSString *minimumSystemVersion; 26 | @property (copy, readonly) NSString *maximumSystemVersion; 27 | @property (strong, readonly) NSURL *fileURL; 28 | @property (copy, readonly) NSString *versionString; 29 | @property (copy, readonly) NSString *displayVersionString; 30 | @property (copy, readonly) NSDictionary *deltaUpdates; 31 | @property (strong, readonly) NSURL *infoURL; 32 | 33 | // Initializes with data from a dictionary provided by the RSS class. 34 | - (instancetype)initWithDictionary:(NSDictionary *)dict; 35 | - (instancetype)initWithDictionary:(NSDictionary *)dict failureReason:(NSString **)error; 36 | 37 | @property (getter=isDeltaUpdate, readonly) BOOL deltaUpdate; 38 | @property (getter=isCriticalUpdate, readonly) BOOL criticalUpdate; 39 | @property (getter=isInformationOnlyUpdate, readonly) BOOL informationOnlyUpdate; 40 | 41 | // Returns the dictionary provided in initWithDictionary; this might be useful later for extensions. 42 | @property (readonly, copy) NSDictionary *propertiesDictionary; 43 | 44 | - (NSURL *)infoURL; 45 | 46 | @end 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Headers/SUErrors.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUErrors.h 3 | // Sparkle 4 | // 5 | // Created by C.W. Betts on 10/13/14. 6 | // Copyright (c) 2014 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #ifndef SUERRORS_H 10 | #define SUERRORS_H 11 | 12 | #if __has_feature(modules) 13 | @import Foundation; 14 | #else 15 | #import 16 | #endif 17 | #import "SUExport.h" 18 | 19 | /** 20 | * Error domain used by Sparkle 21 | */ 22 | SU_EXPORT extern NSString *const SUSparkleErrorDomain; 23 | 24 | typedef NS_ENUM(OSStatus, SUError) { 25 | // Appcast phase errors. 26 | SUAppcastParseError = 1000, 27 | SUNoUpdateError = 1001, 28 | SUAppcastError = 1002, 29 | SURunningFromDiskImageError = 1003, 30 | 31 | // Download phase errors. 32 | SUTemporaryDirectoryError = 2000, 33 | SUDownloadError = 2001, 34 | 35 | // Extraction phase errors. 36 | SUUnarchivingError = 3000, 37 | SUSignatureError = 3001, 38 | 39 | // Installation phase errors. 40 | SUFileCopyFailure = 4000, 41 | SUAuthenticationFailure = 4001, 42 | SUMissingUpdateError = 4002, 43 | SUMissingInstallerToolError = 4003, 44 | SURelaunchError = 4004, 45 | SUInstallationError = 4005, 46 | SUDowngradeError = 4006, 47 | SUInstallationCancelledError = 4007, 48 | 49 | // System phase errors 50 | SUSystemPowerOffError = 5000 51 | }; 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Headers/SUExport.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUExport.h 3 | // Sparkle 4 | // 5 | // Created by Jake Petroules on 2014-08-23. 6 | // Copyright (c) 2014 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #ifndef SUEXPORT_H 10 | #define SUEXPORT_H 11 | 12 | #ifdef BUILDING_SPARKLE 13 | #define SU_EXPORT __attribute__((visibility("default"))) 14 | #else 15 | #define SU_EXPORT 16 | #endif 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Headers/SUStandardVersionComparator.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUStandardVersionComparator.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 12/21/07. 6 | // Copyright 2007 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUSTANDARDVERSIONCOMPARATOR_H 10 | #define SUSTANDARDVERSIONCOMPARATOR_H 11 | 12 | #if __has_feature(modules) 13 | @import Foundation; 14 | #else 15 | #import 16 | #endif 17 | #import "SUExport.h" 18 | #import "SUVersionComparisonProtocol.h" 19 | 20 | /*! 21 | Sparkle's default version comparator. 22 | 23 | This comparator is adapted from MacPAD, by Kevin Ballard. 24 | It's "dumb" in that it does essentially string comparison, 25 | in components split by character type. 26 | */ 27 | SU_EXPORT @interface SUStandardVersionComparator : NSObject 28 | 29 | /*! 30 | Returns a singleton instance of the comparator. 31 | */ 32 | + (SUStandardVersionComparator *)defaultComparator; 33 | 34 | /*! 35 | Compares version strings through textual analysis. 36 | 37 | See the implementation for more details. 38 | */ 39 | - (NSComparisonResult)compareVersion:(NSString *)versionA toVersion:(NSString *)versionB; 40 | @end 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Headers/SUVersionComparisonProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUVersionComparisonProtocol.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 12/21/07. 6 | // Copyright 2007 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUVERSIONCOMPARISONPROTOCOL_H 10 | #define SUVERSIONCOMPARISONPROTOCOL_H 11 | 12 | #if __has_feature(modules) 13 | @import Cocoa; 14 | #else 15 | #import 16 | #endif 17 | #import "SUExport.h" 18 | 19 | /*! 20 | Provides version comparison facilities for Sparkle. 21 | */ 22 | @protocol SUVersionComparison 23 | 24 | /*! 25 | An abstract method to compare two version strings. 26 | 27 | Should return NSOrderedAscending if b > a, NSOrderedDescending if b < a, 28 | and NSOrderedSame if they are equivalent. 29 | */ 30 | - (NSComparisonResult)compareVersion:(NSString *)versionA toVersion:(NSString *)versionB; // *** MAY BE CALLED ON NON-MAIN THREAD! 31 | 32 | @end 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Headers/SUVersionDisplayProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUVersionDisplayProtocol.h 3 | // EyeTV 4 | // 5 | // Created by Uli Kusterer on 08.12.09. 6 | // Copyright 2009 Elgato Systems GmbH. All rights reserved. 7 | // 8 | 9 | #if __has_feature(modules) 10 | @import Cocoa; 11 | #else 12 | #import 13 | #endif 14 | #import "SUExport.h" 15 | 16 | /*! 17 | Applies special display formatting to version numbers. 18 | */ 19 | @protocol SUVersionDisplay 20 | 21 | /*! 22 | Formats two version strings. 23 | 24 | Both versions are provided so that important distinguishing information 25 | can be displayed while also leaving out unnecessary/confusing parts. 26 | */ 27 | - (void)formatVersion:(NSString **)inOutVersionA andVersion:(NSString **)inOutVersionB; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Headers/Sparkle.h: -------------------------------------------------------------------------------- 1 | // 2 | // Sparkle.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/16/06. (Modified by CDHW on 23/12/07) 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SPARKLE_H 10 | #define SPARKLE_H 11 | 12 | #if __has_feature(modules) 13 | @import Cocoa; 14 | #else 15 | #import 16 | #endif 17 | 18 | // This list should include the shared headers. It doesn't matter if some of them aren't shared (unless 19 | // there are name-space collisions) so we can list all of them to start with: 20 | 21 | #import "SUAppcast.h" 22 | #import "SUAppcastItem.h" 23 | #import "SUStandardVersionComparator.h" 24 | #import "SUUpdater.h" 25 | #import "SUVersionComparisonProtocol.h" 26 | #import "SUVersionDisplayProtocol.h" 27 | #import "SUErrors.h" 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Modules/module.modulemap: -------------------------------------------------------------------------------- 1 | framework module Sparkle { 2 | umbrella header "Sparkle.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/PrivateHeaders/SUUnarchiver.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUUnarchiver.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/16/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUUNARCHIVER_H 10 | #define SUUNARCHIVER_H 11 | 12 | #import 13 | 14 | @class SUHost; 15 | @protocol SUUnarchiverDelegate; 16 | 17 | @interface SUUnarchiver : NSObject 18 | 19 | @property (copy, readonly) NSString *archivePath; 20 | @property (copy, readonly) NSString *updateHostBundlePath; 21 | @property (copy, readonly) NSString *decryptionPassword; 22 | @property (weak) id delegate; 23 | 24 | + (SUUnarchiver *)unarchiverForPath:(NSString *)path updatingHostBundlePath:(NSString *)host withPassword:(NSString *)decryptionPassword; 25 | 26 | - (void)start; 27 | @end 28 | 29 | @protocol SUUnarchiverDelegate 30 | - (void)unarchiverDidFinish:(SUUnarchiver *)unarchiver; 31 | - (void)unarchiverDidFail:(SUUnarchiver *)unarchiver; 32 | @optional 33 | - (void)unarchiver:(SUUnarchiver *)unarchiver extractedProgress:(double)progress; 34 | @end 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildMachineOSBuild 6 | 15G1208 7 | CFBundleDevelopmentRegion 8 | English 9 | CFBundleExecutable 10 | Autoupdate 11 | CFBundleIconFile 12 | AppIcon.icns 13 | CFBundleIdentifier 14 | org.sparkle-project.Sparkle.Autoupdate 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.15.1 4-gf47115d 21 | CFBundleSignature 22 | ???? 23 | CFBundleSupportedPlatforms 24 | 25 | MacOSX 26 | 27 | CFBundleVersion 28 | 1.15.1 29 | DTCompiler 30 | com.apple.compilers.llvm.clang.1_0 31 | DTPlatformBuild 32 | 8A218a 33 | DTPlatformVersion 34 | GM 35 | DTSDKBuild 36 | 16A300 37 | DTSDKName 38 | macosx10.12 39 | DTXcode 40 | 0800 41 | DTXcodeBuild 42 | 8A218a 43 | LSBackgroundOnly 44 | 1 45 | LSMinimumSystemVersion 46 | 10.7 47 | LSUIElement 48 | 1 49 | NSMainNibFile 50 | MainMenu 51 | NSPrincipalClass 52 | NSApplication 53 | 54 | 55 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/MacOS/Autoupdate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/MacOS/Autoupdate -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/MacOS/fileop: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/MacOS/fileop -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/PkgInfo: -------------------------------------------------------------------------------- 1 | APPL???? -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/AppIcon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/AppIcon.icns -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/SUStatus.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/SUStatus.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ar.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ar.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ca.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ca.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/cs.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/cs.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/da.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/da.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/de.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/de.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/el.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/el.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/en.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/en.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/es.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/es.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/fi.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/fi.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/fr.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/fr.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/he.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/he.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/is.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/is.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/it.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/it.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ja.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ja.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ko.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ko.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/nb.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/nb.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/nl.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/nl.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pl.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pl.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pt_BR.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pt_BR.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pt_PT.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pt_PT.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ro.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ro.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ru.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ru.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sk.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sk.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sl.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sl.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sv.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sv.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/th.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/th.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/tr.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/tr.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/uk.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/uk.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/zh_CN.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/zh_CN.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/zh_TW.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/zh_TW.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildMachineOSBuild 6 | 15G1208 7 | CFBundleDevelopmentRegion 8 | en 9 | CFBundleExecutable 10 | Sparkle 11 | CFBundleIdentifier 12 | org.sparkle-project.Sparkle 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | Sparkle 17 | CFBundlePackageType 18 | FMWK 19 | CFBundleShortVersionString 20 | 1.15.1 4-gf47115d 21 | CFBundleSignature 22 | ???? 23 | CFBundleSupportedPlatforms 24 | 25 | MacOSX 26 | 27 | CFBundleVersion 28 | 1.15.1 29 | DTCompiler 30 | com.apple.compilers.llvm.clang.1_0 31 | DTPlatformBuild 32 | 8A218a 33 | DTPlatformVersion 34 | GM 35 | DTSDKBuild 36 | 16A300 37 | DTSDKName 38 | macosx10.12 39 | DTXcode 40 | 0800 41 | DTXcodeBuild 42 | 8A218a 43 | 44 | 45 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/SUStatus.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/SUStatus.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/ar.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/ar.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/ar.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/ar.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/ca.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/ca.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/cs.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/cs.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/cs.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/cs.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/da.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/da.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/da.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/da.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/el.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/el.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/el.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/el.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/fi.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/fi.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/fr_CA.lproj: -------------------------------------------------------------------------------- 1 | fr.lproj -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/he.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/he.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/is.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/is.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/is.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/is.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/ja.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/ja.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/ja.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/ja.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/ko.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/ko.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/ko.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/ko.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/nb.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/nb.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/nb.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/nb.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/pl.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/pl.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/pl.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/pl.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/pt.lproj: -------------------------------------------------------------------------------- 1 | pt_BR.lproj -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/ro.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/ro.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/ro.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/ro.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/sk.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/sk.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/sk.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/sk.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/sl.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/sl.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/sl.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/sl.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/th.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/th.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/th.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/th.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/tr.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/tr.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/tr.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/tr.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/uk.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/uk.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/uk.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/uk.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Sparkle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Frameworks/Sparkle.framework/Versions/A/Sparkle -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/Current: -------------------------------------------------------------------------------- 1 | A -------------------------------------------------------------------------------- /Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Icon.png -------------------------------------------------------------------------------- /Model.xcdatamodeld/.xccurrentversion: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | _XCCurrentVersionName 6 | Model 3.xcdatamodel 7 | 8 | 9 | -------------------------------------------------------------------------------- /Model.xcdatamodeld/Model 2.xcdatamodel/contents: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Model.xcdatamodeld/Model 3.xcdatamodel/contents: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /Model.xcdatamodeld/Model.xcdatamodel/contents: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /PutIOSync-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | PutIO Sync 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleURLTypes 22 | 23 | 24 | CFBundleURLName 25 | BitTorrent Magnet Links 26 | CFBundleURLSchemes 27 | 28 | magnet 29 | 30 | 31 | 32 | CFBundleVersion 33 | 625 34 | LSApplicationCategoryType 35 | public.app-category.utilities 36 | LSMinimumSystemVersion 37 | ${MACOSX_DEPLOYMENT_TARGET} 38 | LSUIElement 39 | 40 | NSHumanReadableCopyright 41 | Copyright © Matthias Schwab 42 | NSMainNibFile 43 | MainMenu 44 | NSPrincipalClass 45 | NSApplication 46 | SUEnableSystemProfiling 47 | 48 | SUFeedURL 49 | https://matthiasschwab.de/updates/putiosync/appcast.xml.rss 50 | 51 | 52 | -------------------------------------------------------------------------------- /PutIOSync.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /PutIOSync.xcodeproj/project.xcworkspace/xcshareddata/PutIOSync.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 67B88819-BEAB-45CA-BE15-EB0693F40652 9 | IDESourceControlProjectName 10 | PutIOSync 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | CF454EF7418BC0DF98CA9BB41D9E118076E9B58E 14 | https://github.com/arrizer/PutIOSync-OSX.git 15 | 16 | IDESourceControlProjectPath 17 | PutIOSync.xcodeproj 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | CF454EF7418BC0DF98CA9BB41D9E118076E9B58E 21 | ../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/arrizer/PutIOSync-OSX.git 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | CF454EF7418BC0DF98CA9BB41D9E118076E9B58E 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | CF454EF7418BC0DF98CA9BB41D9E118076E9B58E 36 | IDESourceControlWCCName 37 | PutIOSync 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /PutIOSync.xcodeproj/project.xcworkspace/xcuserdata/matthias.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges 6 | 7 | SnapshotAutomaticallyBeforeSignificantChanges 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /PutIOSync.xcodeproj/xcshareddata/xcschemes/PutIOSync.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 68 | 69 | 70 | 71 | 72 | 73 | 79 | 81 | 87 | 88 | 89 | 90 | 92 | 93 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /PutIOSync.xcodeproj/xcuserdata/matthias.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /PutIOSync.xcodeproj/xcuserdata/matthias.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | PutIOSync.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 39010C3116BE053E00846535 16 | 17 | primary 18 | 19 | 20 | 398350C2194E736000C4CFC5 21 | 22 | primary 23 | 24 | 25 | 398350CC194E736100C4CFC5 26 | 27 | primary 28 | 29 | 30 | 399C94F3195BD952003E773D 31 | 32 | primary 33 | 34 | 35 | 399C94FA195BE41A003E773D 36 | 37 | primary 38 | 39 | 40 | 399C9500195BE4A2003E773D 41 | 42 | primary 43 | 44 | 45 | 399C9546195BE52B003E773D 46 | 47 | primary 48 | 49 | 50 | DD4F7C0313C30F9F00825C6E 51 | 52 | primary 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PutIOSync for OS X 2 | 3 | ![Screenshot](https://raw.github.com/arrizer/PutIOSync-OSX/master/Screenshots/menuitem.png) 4 | 5 | PutIOSync is a little menubar app for your Mac that allows you to automatically download new files from [put.io](http://put.io) as they arrive in your folders there. 6 | It can also delete successfully downloaded files from put.io and flatten folder hierarchies, if you want it to. 7 | 8 | [⬇︎ DOWNLOAD](https://github.com/arrizer/PutIOSync-OSX/raw/master/App/PutIOSync.app.zip) 9 | 10 | It is a 64-bit ARC Mac app and it runs on OS X 10.7 and later. 11 | 12 | ## Features 13 | - Account setup via OAuth 14 | - Automatically watch folders on put.io and download new files as they arrive 15 | - View current transfers happening to your put.io account 16 | - Notification Center alerts for new/successful downloads 17 | - Option to launch on login 18 | 19 | If you want to contribute, I am happy to accept pull requests for new features, bugfixes or improvements. Have fun! 20 | 21 | ## More Screenshots 22 | 23 | ![Screenshot](https://raw.github.com/arrizer/PutIOSync-OSX/master/Screenshots/account.png) 24 | ![Screenshot](https://raw.github.com/arrizer/PutIOSync-OSX/master/Screenshots/preferences.png) 25 | ![Screenshot](https://raw.github.com/arrizer/PutIOSync-OSX/master/Screenshots/syncedfolders.png) 26 | ![Screenshot](https://raw.github.com/arrizer/PutIOSync-OSX/master/Screenshots/syncedfolder.png) -------------------------------------------------------------------------------- /Screenshots/account.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Screenshots/account.png -------------------------------------------------------------------------------- /Screenshots/menuitem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Screenshots/menuitem.png -------------------------------------------------------------------------------- /Screenshots/preferences.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Screenshots/preferences.png -------------------------------------------------------------------------------- /Screenshots/syncedfolder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Screenshots/syncedfolder.png -------------------------------------------------------------------------------- /Screenshots/syncedfolders.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arrizer/PutIOSync-OSX/c11521b2dce5d52b0cc1070a913aa060215b8bfa/Screenshots/syncedfolders.png -------------------------------------------------------------------------------- /UserDefaults.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | general_launchonlogin 6 | 7 | general_syncinterval 8 | 2 9 | general_paralleldownloads 10 | 5 11 | general_notifications_newfiles 12 | 13 | general_notifications_downloadfinished 14 | 15 | general_notifications_downloadfailed 16 | 17 | general_sounds_newfiles 18 | 19 | general_sounds_downloadfinished 20 | 21 | 22 | 23 | --------------------------------------------------------------------------------