├── .gitignore ├── .swift-version ├── .travis.yml ├── LICENSE ├── Package.swift ├── PutioKit.podspec ├── README.md ├── Sources ├── Account.swift ├── DiskInfo.swift ├── Event.swift ├── File.swift ├── Friend.swift ├── MP4Status.swift ├── MockRequest.swift ├── Putio.swift ├── PutioError.swift ├── Router.swift ├── Settings.swift ├── Subtitle.swift └── Transfer.swift ├── Tests └── PutioKitTests │ ├── AccountTests.swift │ ├── EventTests.swift │ ├── FileTests.swift │ ├── FriendTests.swift │ ├── PutioTests.swift │ ├── SettingsTests.swift │ ├── SubtitleTests.swift │ └── TransferTests.swift └── docs ├── Classes.html ├── Classes ├── Account.html ├── Event.html ├── File.html ├── Friend.html ├── Putio.html ├── Settings.html ├── Subtitle.html └── Transfer.html ├── Enums.html ├── Enums ├── EventType.html ├── MP4Status.html ├── PutioError.html ├── SubtitleFormat.html ├── SubtitleSource.html └── TransferStatus.html ├── Structs.html ├── Structs └── DiskInfo.html ├── css ├── highlight.css └── jazzy.css ├── docsets ├── PutioKit.docset │ └── Contents │ │ ├── Info.plist │ │ └── Resources │ │ ├── Documents │ │ ├── Classes.html │ │ ├── Classes │ │ │ ├── Account.html │ │ │ ├── Event.html │ │ │ ├── File.html │ │ │ ├── Friend.html │ │ │ ├── Putio.html │ │ │ ├── Settings.html │ │ │ ├── Subtitle.html │ │ │ └── Transfer.html │ │ ├── Enums.html │ │ ├── Enums │ │ │ ├── EventType.html │ │ │ ├── MP4Status.html │ │ │ ├── PutioError.html │ │ │ ├── SubtitleFormat.html │ │ │ ├── SubtitleSource.html │ │ │ └── TransferStatus.html │ │ ├── Structs.html │ │ ├── Structs │ │ │ └── DiskInfo.html │ │ ├── css │ │ │ ├── highlight.css │ │ │ └── jazzy.css │ │ ├── img │ │ │ ├── carat.png │ │ │ ├── dash.png │ │ │ └── gh.png │ │ ├── index.html │ │ ├── js │ │ │ ├── jazzy.js │ │ │ └── jquery.min.js │ │ └── undocumented.json │ │ └── docSet.dsidx └── PutioKit.tgz ├── img ├── carat.png ├── dash.png └── gh.png ├── index.html ├── js ├── jazzy.js └── jquery.min.js └── undocumented.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xcuserstate 23 | 24 | ## Obj-C/Swift specific 25 | *.hmap 26 | *.ipa 27 | *.dSYM.zip 28 | *.dSYM 29 | 30 | ## Playgrounds 31 | timeline.xctimeline 32 | playground.xcworkspace 33 | 34 | # Swift Package Manager 35 | # 36 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 37 | Packages/ 38 | .build/ 39 | 40 | # CocoaPods 41 | # 42 | # We recommend against adding the Pods directory to your .gitignore. However 43 | # you should judge for yourself, the pros and cons are mentioned at: 44 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 45 | # 46 | # Pods/ 47 | 48 | # Carthage 49 | # 50 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 51 | # Carthage/Checkouts 52 | 53 | Carthage/Build 54 | 55 | # fastlane 56 | # 57 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 58 | # screenshots whenever they are needed. 59 | # For more information about the recommended setup visit: 60 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 61 | 62 | fastlane/report.xml 63 | fastlane/Preview.html 64 | fastlane/screenshots 65 | fastlane/test_output 66 | 67 | .DS_Store 68 | PutioKit.xcodeproj 69 | -------------------------------------------------------------------------------- /.swift-version: -------------------------------------------------------------------------------- 1 | 3.0.1 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | os: 2 | - osx 3 | language: generic 4 | sudo: required 5 | dist: trusty 6 | osx_image: xcode8 7 | install: 8 | - eval "$(curl -sL https://gist.githubusercontent.com/kylef/5c0475ff02b7c7671d2a/raw/9f442512a46d7a2af7b850d65a7e9bd31edfb09b/swiftenv-install.sh)" 9 | script: 10 | - swift test 11 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | import PackageDescription 2 | 3 | let package = Package( 4 | name: "PutioKit", 5 | dependencies: [ 6 | .Package(url: "https://github.com/Alamofire/Alamofire.git", majorVersion: 4) 7 | ] 8 | ) 9 | -------------------------------------------------------------------------------- /PutioKit.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | s.name = "PutioKit" 4 | s.version = "1.0.0" 5 | s.summary = "A Swift framework for Put.io's API" 6 | s.description = <<-DESC 7 | PutioKit is a modern Swift framework that interfaces with Put.io's API. It features near 100% coverage of Put.io's entire API and works with iOS, tvOS, and macOS (Linux support is currently reliant on Alamofire). 8 | 9 | The framework is derived from one of the same name used in the Fetch iOS app. 10 | DESC 11 | 12 | s.homepage = "https://github.com/TryFetch/PutioKit" 13 | s.license = "GPL 3.0" 14 | 15 | 16 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 17 | 18 | s.author = { "Cocoon Development Ltd" => "fetch@wearecocoon.co.uk" } 19 | s.social_media_url = "http://twitter.com/TryFetch" 20 | 21 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 22 | s.ios.deployment_target = "9.0" 23 | s.osx.deployment_target = "10.11" 24 | s.tvos.deployment_target = "9.0" 25 | 26 | 27 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 28 | s.source = { :git => "https://github.com/TryFetch/PutioKit.git", :tag => "1.0.0" } 29 | 30 | 31 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 32 | s.source_files = "Sources" 33 | 34 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 35 | s.dependency "Alamofire", "~> 4.3" 36 | 37 | end 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PutioKit 2 | [![Build Status](https://travis-ci.org/TryFetch/PutioKit.svg?branch=master)](https://travis-ci.org/TryFetch/PutioKit) [![CocoaPods](https://img.shields.io/cocoapods/p/AFNetworking.svg)](https://cocoapods.org/pods/PutioKit) 3 | 4 | ### A Swift framework for Put.io's API 5 | 6 | This project is currently a work in process but aims to be a feature complete wrapper for Put.io's API. It's derived from the framework of the same name used by [Fetch](https://github.com/TryFetch/Fetch). 7 | 8 | ## Installation 9 | 10 | ### CocoaPods 11 | 12 | CocoaPods is the easiest way to install PutioKit for inclusion in your project. Just add the following to your Podfile. 13 | 14 | ```ruby 15 | pod 'PutioKit', '~> 1.0' 16 | ``` 17 | 18 | ### Swift Package Manager 19 | 20 | PutioKit can easily be installed via Swift Pacakge Manager (SPM). 21 | 22 | ```swift 23 | dependencies: [ 24 | .Package(url: "https://github.com/TryFetch/PutioKit.git", majorVersion: 1) 25 | ] 26 | ``` 27 | 28 | ### Manual 29 | 30 | Manually install PutioKit by including the contents of the `Sources` directory in your project. 31 | 32 | ## Usage 33 | 34 | In order to access the Put.io API you'll need to create an OAuth app and use its client ID and secret. The following static properties can be set on the main `Putio` class. 35 | 36 | ```swift 37 | import PutioKit 38 | 39 | Putio.clientId = 1234 // The client ID given when registering an app with Put.io 40 | Putio.redirectUri = "http://example.com/auth" // The redirect URI registered with Put.io 41 | Putio.accessToken = "ABC123DE" // The user's access token obtained from OAuth 42 | ``` 43 | 44 | ### Authentication 45 | 46 | Authentication depends on whether you have a server or just want to authenticate on device. More information on these solutions can be found on [Put.io's API](https://put.io/v2/docs/gettingstarted.html#authentication-and-access). 47 | 48 | ### Examples 49 | 50 | > Full documentation can be found at https://tryfetch.github.io/PutioKit/ 51 | 52 | The main methods for interacting with the API are all included on the `Putio` class. Some model specific methods will be included elsewhere. For example there is a method for retrying a transfer on the `Transfer` object itself. 53 | 54 | Some examples of methods and their usage can be seen below. 55 | 56 | ```swift 57 | import PutioKit 58 | 59 | // FILES 60 | 61 | Putio.getFiles { files, error in 62 | print(files) 63 | print(error) 64 | } 65 | 66 | Putio.delete(files: [file1, file2]) { completed in 67 | print(completed) 68 | } 69 | 70 | file.getSubtitles { subtitles, error in 71 | print(subtitles) 72 | } 73 | 74 | // TRANSFERS 75 | 76 | Putio.getTransfers { transfers, error in 77 | print(transfers) 78 | print(error) 79 | } 80 | 81 | Putio.cleanTransfers { completed in 82 | print(completed) 83 | } 84 | 85 | transfer.cancel { completed in 86 | print(completed) 87 | } 88 | ``` 89 | -------------------------------------------------------------------------------- /Sources/Account.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Account.swift 3 | // PutioKit 4 | // 5 | // Created by Stephen Radford on 15/01/2017. 6 | // 7 | // 8 | 9 | import Foundation 10 | 11 | /// Represents the authenticated account on Put.io 12 | open class Account: NSObject { 13 | 14 | /// The username of the authenticated account 15 | open var username = "" 16 | 17 | /// The email address of the authenticated account 18 | open var email = "" 19 | 20 | /// The date the current plan expires 21 | open var planExpirationDate: Date? 22 | 23 | /// Subtitle languages selected by the user 24 | open var subtitleLanguages = [String]() 25 | 26 | /// The default subtitle language selected by the user 27 | open var defaultSubtitleLanguage: String? 28 | 29 | /// Information about the disk 30 | open var diskInfo: DiskInfo? 31 | 32 | /// How long until files on the account will be deleted 33 | open var daysUntilFilesDeletion = 0 34 | 35 | /// URL to the user's avatar if it exists 36 | open var avatar = "" 37 | 38 | internal convenience init(json: [String:Any]) { 39 | self.init() 40 | 41 | username = json["username"] as? String ?? "" 42 | email = json["mail"] as? String ?? "" 43 | subtitleLanguages = json["subtitle_languages"] as? [String] ?? [] 44 | defaultSubtitleLanguage = json["default_subtitle_language"] as? String 45 | daysUntilFilesDeletion = json["days_until_files_deletion"] as? Int ?? 0 46 | avatar = json["avatar_url"] as? String ?? "" 47 | 48 | if let disk = json["disk"] as? [String:Int] { 49 | diskInfo = DiskInfo(available: disk["avail"] ?? 0, used: disk["used"] ?? 0, size: disk["size"] ?? 0) 50 | } 51 | 52 | if let dateString = json["plan_expiration_date"] as? String { 53 | let formatter = DateFormatter() 54 | formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:s" 55 | planExpirationDate = formatter.date(from: dateString) 56 | } 57 | } 58 | 59 | } 60 | 61 | extension Putio { 62 | 63 | /// Get account information from Put.io 64 | /// 65 | /// - Parameter completionHandler: The response handler 66 | public class func getAccountInfo(completionHandler: @escaping (Account?, Error?) -> Void) { 67 | Putio.request(Router.getAccountInfo) { response, error in 68 | if let error = error { 69 | completionHandler(nil, error) 70 | return 71 | } 72 | 73 | guard let json = response as? [String: Any], let info = json["info"] as? [String:Any] else { 74 | completionHandler(nil, PutioError.couldNotParseJSON) 75 | return 76 | } 77 | 78 | completionHandler(Account(json: info), error) 79 | } 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /Sources/DiskInfo.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DiskInfo.swift 3 | // PutioKit 4 | // 5 | // Created by Stephen Radford on 15/01/2017. 6 | // 7 | // 8 | 9 | import Foundation 10 | 11 | /// Information about the disk usage on Put.io 12 | public struct DiskInfo { 13 | 14 | /// The available disk space 15 | public let available: Int 16 | 17 | /// The amount of space used on the disk 18 | public let used: Int 19 | 20 | /// The total size of the disk 21 | public let size: Int 22 | 23 | } 24 | -------------------------------------------------------------------------------- /Sources/Event.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Event.swift 3 | // PutioKit 4 | // 5 | // Created by Stephen Radford on 14/01/2017. 6 | // 7 | // 8 | 9 | import Foundation 10 | import Alamofire 11 | 12 | /// The type of event logged 13 | /// 14 | /// - transferCompleted: When a transfer has finished 15 | /// - fileShared: When a file was shared with you 16 | /// - transferFromRSSError: When a transfer failed to download from an RSS feed 17 | /// - zipCreated: When a ZIP file was generated 18 | /// - unknown: The event type was unable to be parsed 19 | public enum EventType { 20 | 21 | /// When a transfer has finished 22 | case transferCompleted 23 | 24 | /// When a file was shared with you 25 | case fileShared 26 | 27 | /// When a transfer failed to download from an RSS feed 28 | case transferFromRSSError 29 | 30 | /// When a ZIP file was generated 31 | case zipCreated 32 | 33 | /// The event type was unable to be parsed 34 | case unknown 35 | 36 | } 37 | 38 | /// Represents an event on Put.io 39 | open class Event: NSObject { 40 | 41 | /// The file or transfer name. This will be the main text that should be displayed. 42 | open var name: String? 43 | 44 | /// The type of event 45 | open var type: EventType = .unknown 46 | 47 | /// The ID of the file this event relates to 48 | open var fileId: Int? 49 | 50 | /// The size of the file this event relates to 51 | open var fileSize: Int? 52 | 53 | /// The size of the transfer this event relates to 54 | open var transferSize: Int? 55 | 56 | /// The username of the person sharing the file this event relates to 57 | open var sharingUsername: String? 58 | 59 | /// The date the event was created 60 | open var createdAt: Date? 61 | 62 | internal convenience init(json: [String:Any]) { 63 | self.init() 64 | 65 | if let typeString = json["type"] as? String { 66 | type = { 67 | switch typeString { 68 | case "zip_created": 69 | return .zipCreated 70 | case "transfer_from_rss_error": 71 | return .transferFromRSSError 72 | case "file_shared": 73 | return .fileShared 74 | case "transfer_completed": 75 | return .transferCompleted 76 | default: 77 | return .unknown 78 | } 79 | }() 80 | } 81 | 82 | fileId = json["file_id"] as? Int 83 | fileSize = json["file_size"] as? Int 84 | transferSize = json["transfer_size"] as? Int 85 | sharingUsername = json["sharing_user_name"] as? String 86 | 87 | if let fileName = json["file_name"] as? String { 88 | name = fileName 89 | } else if let transferName = json["transfer_name"] as? String { 90 | name = transferName 91 | } else if type == .zipCreated { 92 | name = "You requested we zip some files and they are ready" 93 | } else { 94 | name = "Unknown event" 95 | } 96 | 97 | if let dateString = json["created_at"] as? String { 98 | let formatter = DateFormatter() 99 | formatter.dateFormat = "yyyy-MM-dd HH:mm:s" 100 | createdAt = formatter.date(from: dateString) 101 | } 102 | 103 | } 104 | 105 | } 106 | 107 | extension Putio { 108 | 109 | /// Get a list of events from Put.io 110 | /// 111 | /// - Parameter completionHandler: The response handler 112 | public class func getEvents(completionHandler: @escaping ([Event], Error?) -> Void) { 113 | Putio.request(Router.getEvents) { response, error in 114 | if let error = error { 115 | completionHandler([], error) 116 | return 117 | } 118 | 119 | guard let json = response as? [String:Any], let events = json["events"] as? [[String:Any]] else { 120 | completionHandler([], PutioError.couldNotParseJSON) 121 | return 122 | } 123 | 124 | completionHandler(events.flatMap(Event.init), error) 125 | } 126 | } 127 | 128 | /// Clear all events from Put.io 129 | /// 130 | /// - Parameter completionHandler: The response handler 131 | public class func deleteEvents(completionHandler: @escaping (Bool) -> Void) { 132 | Putio.request(Router.deleteEvents) { response, error in 133 | if error != nil { 134 | completionHandler(false) 135 | return 136 | } 137 | 138 | completionHandler(true) 139 | } 140 | } 141 | 142 | } 143 | -------------------------------------------------------------------------------- /Sources/Friend.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Friend.swift 3 | // PutioKit 4 | // 5 | // Created by Stephen Radford on 10/01/2017. 6 | // 7 | // 8 | 9 | import Foundation 10 | 11 | /// Represents a friend of the logged in user. 12 | open class Friend: NSObject { 13 | 14 | /// The username of the friend 15 | open dynamic var username = "" 16 | 17 | /// URL of the user's avatar 18 | open dynamic var avatar = "" 19 | 20 | /// The ID that can be used for unsharing a file 21 | open dynamic var shareId = 0 22 | 23 | internal convenience init(json: [String:Any]) { 24 | self.init() 25 | username = json["user_name"] as? String ?? "" 26 | avatar = json ["user_avatar_url"] as? String ?? "" 27 | shareId = json["share_id"] as? Int ?? 0 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /Sources/MP4Status.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MP4Status.swift 3 | // PutioKit 4 | // 5 | // Created by Stephen Radford on 10/01/2017. 6 | // 7 | // 8 | 9 | import Foundation 10 | 11 | /// Represents the status of a file's MP4 conversion 12 | /// 13 | /// - unknown: We weren't able to get the status from the API 14 | /// - unavailable: There is currently no MP4 available for the file 15 | /// - queued: An MP4 has been requested and is currently awaiting conversion 16 | /// - preparing: Preparations are being made to enable the file to be converted 17 | /// - converting: The MP4 is currently being converting 18 | /// - finishing: The file has finished converting and Put.io are finalising and saving the file 19 | /// - completed: The MP4 has finished converting and is now available 20 | public enum MP4Status { 21 | 22 | /// We weren't able to get the status from the API 23 | case unknown 24 | 25 | /// There is currently no MP4 available for the file 26 | case unavailable 27 | 28 | /// An MP4 has been requested and is currently awaiting conversion 29 | case queued 30 | 31 | /// Preparations are being made to enable the file to be converted 32 | case preparing 33 | 34 | /// The MP4 is currently being converting 35 | case converting 36 | 37 | /// The file has finished converting and Put.io are finalising and saving the file 38 | case finishing 39 | 40 | /// The MP4 has finished converting and is now available 41 | case completed 42 | 43 | } 44 | -------------------------------------------------------------------------------- /Sources/MockRequest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MockRequest.swift 3 | // PutioKit 4 | // 5 | // Created by Stephen Radford on 09/01/2017. 6 | // 7 | // 8 | 9 | import Foundation 10 | import Alamofire 11 | 12 | /// This class is only used internally for testing. 13 | internal final class MockRequest { 14 | 15 | var value: Any = [] 16 | var statusCode = 200 17 | 18 | static let shared = MockRequest() 19 | 20 | fileprivate init() { } 21 | 22 | func request(_ urlRequest: URLRequestConvertible, completionHandler: (DataResponse) -> Void) { 23 | 24 | guard let url = urlRequest.urlRequest?.url else { 25 | return 26 | } 27 | 28 | let result = Result.success(value) 29 | let urlResponse = HTTPURLResponse(url: url, statusCode: statusCode, httpVersion: nil, headerFields: nil) 30 | let response = DataResponse(request: urlRequest.urlRequest, response: urlResponse, data: nil, result: result) 31 | 32 | completionHandler(response) 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /Sources/Putio.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Putio.swift 3 | // Fetch 4 | // 5 | // Created by Stephen Radford on 22/06/2016. 6 | // Copyright © 2016 Cocoon Development Ltd. All rights reserved. 7 | // 8 | 9 | import Alamofire 10 | import Foundation 11 | 12 | /// The main PutioKit class. Set your `clientId`, `redirectUri`, and `accessToken` here. 13 | public final class Putio { 14 | 15 | /// The client ID used for OAuth Authentication 16 | public static var clientId: Int? 17 | 18 | /// The access token used by the user to authorise requests 19 | public static var accessToken: String? 20 | 21 | /// The redirect URI registered with Put.io 22 | public static var redirectUri: String? 23 | 24 | /// Set by unit tests 25 | internal static var testing = false 26 | 27 | /// The URL used for authentication with Put.io 28 | public static var authenticationUrl: URL? { 29 | guard let id = clientId, let url = redirectUri else { return nil } 30 | let string = Router.base + "/oauth2/authenticate?client_id=\(id)&response_type=token&redirect_uri=\(url)" 31 | return URL(string: string) 32 | } 33 | 34 | /// Make an API request 35 | /// 36 | /// - Parameters: 37 | /// - request: The request to make. This will come from the Router. 38 | /// - completionHandler: The handler that will process the response 39 | /// - Returns: The raw request that was used 40 | internal class func request(_ request: URLRequestConvertible, completionHandler: @escaping (Any?, Error?) -> Void) { 41 | 42 | let handler: (DataResponse) -> Void = { response in 43 | if let error = response.result.error { 44 | completionHandler(nil, error) 45 | return 46 | } 47 | 48 | let status = response.response!.statusCode 49 | 50 | guard case 200 ..< 300 = status else { 51 | completionHandler(nil, PutioError.invalidStatusCode) 52 | return 53 | } 54 | 55 | completionHandler(response.result.value, nil) 56 | } 57 | 58 | if testing { 59 | MockRequest.shared.request(request, completionHandler: handler) 60 | return 61 | } 62 | 63 | Alamofire.request(request) 64 | .responseJSON(completionHandler: handler) 65 | } 66 | 67 | fileprivate init() {} 68 | 69 | } 70 | -------------------------------------------------------------------------------- /Sources/PutioError.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PutioError.swift 3 | // PutioKit 4 | // 5 | // Created by Stephen Radford on 09/01/2017. 6 | // 7 | // 8 | 9 | import Foundation 10 | 11 | /// Represents errors that can occur when accessing the Put.io API 12 | /// 13 | /// - couldNotParseJSON: There was an error parsing the JSON from the API 14 | /// - noAccessToken: An access token was not provided so this endpoint could not be called 15 | /// - invalidStatusCode: The expected status code was not returned 16 | public enum PutioError: Error { 17 | 18 | /// There was an error parsing the JSON from the API 19 | case couldNotParseJSON 20 | 21 | /// An access token was not provided so this endpoint could not be called 22 | case noAccessToken 23 | 24 | /// The expected status code was not returned 25 | case invalidStatusCode 26 | 27 | } 28 | -------------------------------------------------------------------------------- /Sources/Router.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Router.swift 3 | // Fetch 4 | // 5 | // Created by Stephen Radford on 22/06/2016. 6 | // Copyright © 2016 Cocoon Development Ltd. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Alamofire 11 | 12 | /// The router used for requests to the API. 13 | enum Router: URLRequestConvertible { 14 | 15 | static let base = "https://api.put.io/v2" 16 | 17 | /// MARK: - Cases 18 | 19 | case files(Int) 20 | case deleteFiles([Int]) 21 | case renameFile(Int, String) 22 | case file(Int) 23 | case moveFiles([Int], Int) 24 | case createFolder(String, Int) 25 | case convertToMp4(Int) 26 | case getMp4Status(Int) 27 | case shareFiles([Int], [String]) 28 | case getSharedWith(Int) 29 | case unshareFile(Int, [Int]) 30 | case getSubtitles(Int) 31 | case setVideoPosition(Int, Int) 32 | case deleteVideoPosition(Int) 33 | case getEvents 34 | case deleteEvents 35 | case transfers 36 | case cleanTransfers 37 | case addTransfer(String, Int, Bool) 38 | case retryTransfer(Int) 39 | case cancelTransfers([Int]) 40 | case getAccountInfo 41 | case getSettings 42 | 43 | var result: (method: HTTPMethod, path: String, parameters: Parameters) { 44 | 45 | switch self { 46 | case .files(let parent): 47 | return (.get, "/files/list", ["parent_id": parent, "start_from": 1]) 48 | case .file(let id): 49 | return (.get, "/files/\(id)", [:]) 50 | case .deleteFiles(let files): 51 | return (.post, "/files/delete", ["file_ids": files.map { String($0) }.joined(separator: ",")]) 52 | case .renameFile(let id, let name): 53 | return (.post, "/files/rename", ["file_id": id, "name": name]) 54 | case .moveFiles(let files, let parent): 55 | return (.post, "/files/move", ["file_ids": files.map { String($0) }.joined(separator: ","), "parent": parent]) 56 | case .createFolder(let name, let parent): 57 | return (.post, "/files/create-folder", ["name": name, "parent_id": parent]) 58 | case .convertToMp4(let id): 59 | return (.post, "/files/\(id)/mp4", [:]) 60 | case .getMp4Status(let id): 61 | return (.get, "/files/\(id)/mp4", [:]) 62 | case .shareFiles(let files, let friends): 63 | return (.post, "/files/share", ["file_ids": files.map { String($0) }.joined(separator: ","), "friends": friends.joined(separator: ",")]) 64 | case .getSharedWith(let id): 65 | return (.get, "/files/\(id)/shared-with", [:]) 66 | case .unshareFile(let id, let friends): 67 | return (.post, "/files/\(id)/unshare", ["shares": friends.map { String($0) }.joined(separator: ",")]) 68 | case .getSubtitles(let id): 69 | return (.get, "/files/\(id)/subtitles", [:]) 70 | case .setVideoPosition(let id, let position): 71 | return (.post, "/files/\(id)/start-from", ["time": position]) 72 | case .deleteVideoPosition(let id): 73 | return (.post, "/files/\(id)/start-from/delete", [:]) 74 | case .getEvents: 75 | return (.get, "/events/list", [:]) 76 | case .deleteEvents: 77 | return (.post, "/events/delete", [:]) 78 | case .transfers: 79 | return (.get, "/transfers/list", [:]) 80 | case .cleanTransfers: 81 | return (.post, "/transfers/clean", [:]) 82 | case .addTransfer(let url, let parent, let extract): 83 | return (.post, "/transfers/add", ["url": url, "parent": parent, "extract": extract]) 84 | case .retryTransfer(let id): 85 | return (.post, "/transfers/retry", ["id": id]) 86 | case .cancelTransfers(let transfers): 87 | return (.post, "/transfers/cancel", ["transfer_ids": transfers.map { String($0) }.joined(separator: ",")]) 88 | case .getAccountInfo: 89 | return (.get, "/account/info", [:]) 90 | case .getSettings: 91 | return (.get, "/account/settings", [:]) 92 | } 93 | } 94 | 95 | 96 | /// Returns a URL request or throws if an `Error` was encountered. 97 | /// 98 | /// - throws: An `Error` if the underlying `URLRequest` is `nil`. 99 | /// 100 | /// - returns: A URL request. 101 | public func asURLRequest() throws -> URLRequest { 102 | 103 | let url = try Router.base.asURL() 104 | var urlRequest = URLRequest(url: url.appendingPathComponent(result.path)) 105 | urlRequest.httpMethod = result.method.rawValue 106 | 107 | var parameters = result.parameters 108 | if let token = Putio.accessToken { 109 | parameters["oauth_token"] = token 110 | } 111 | 112 | return try URLEncoding.default.encode(urlRequest, with: parameters) 113 | 114 | } 115 | 116 | 117 | } 118 | -------------------------------------------------------------------------------- /Sources/Settings.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Settings.swift 3 | // PutioKit 4 | // 5 | // Created by Stephen Radford on 30/01/2017. 6 | // 7 | // 8 | 9 | import Foundation 10 | 11 | /// Represents settings on Put.io 12 | open class Settings { 13 | 14 | /// Whether the user is in the beta program or not 15 | public let betaUser: Bool 16 | 17 | /// A callback URL to ping once a transfer has completed 18 | public let callbackURL: String 19 | 20 | /// The default folder that files are downloaded to when adding a transfer 21 | public let defaultDownloadFolder: Int 22 | 23 | /// Whether the user is invisible in searches or not 24 | public let isInvisible: Bool 25 | 26 | /// Whether the next episode in a folder should automatically be played 27 | public let nextEpisode: Bool 28 | 29 | /// The number of files that can be downloaded at any given time 30 | public let simultaneousDownloadLimit: Int 31 | 32 | internal init(json: [String:Any]) { 33 | betaUser = json["beta_user"] as? Bool ?? false 34 | callbackURL = json["callback_url"] as? String ?? "" 35 | defaultDownloadFolder = json["default_download_folder"] as? Int ?? 0 36 | isInvisible = json["is_invisible"] as? Bool ?? false 37 | nextEpisode = json["next_episode"] as? Bool ?? false 38 | simultaneousDownloadLimit = json["simultaneous_download_limit"] as? Int ?? 0 39 | } 40 | 41 | } 42 | 43 | extension Putio { 44 | 45 | /// Fetch settings from the API 46 | /// 47 | /// - Parameter completionHandler: The response handler 48 | public class func getSettings(completionHandler: @escaping (Settings?, Error?) -> Void) { 49 | Putio.request(Router.getSettings) { response, error in 50 | if let error = error { 51 | completionHandler(nil, error) 52 | return 53 | } 54 | 55 | guard let json = response as? [String:Any], let settings = json["settings"] as? [String:Any] else { 56 | completionHandler(nil, PutioError.couldNotParseJSON) 57 | return 58 | } 59 | 60 | completionHandler(Settings(json: settings), error) 61 | } 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /Sources/Subtitle.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Subtitle.swift 3 | // PutioKit 4 | // 5 | // Created by Stephen Radford on 12/01/2017. 6 | // 7 | // 8 | 9 | import Foundation 10 | 11 | /// The file format of subtitle. 12 | /// 13 | /// - srt: Default. SRT file format. 14 | /// - webvtt: webVTT file format used by things like Chromecast. 15 | public enum SubtitleFormat: String { 16 | 17 | /// The default subtitle format used by Put.io. 18 | case srt = "srt" 19 | 20 | /// An alternative format available if required. Things like Chromecast require WebVTT. 21 | case webvtt = "webvtt" 22 | 23 | } 24 | 25 | /// Where the subtitle was obtained from 26 | /// 27 | /// - folder: An SRT file with an identical name as the video 28 | /// - mkv: Subtitles are extracted from an MKV file 29 | /// - opensubtitles: The sutitles were fetched from OpenSubtitles 30 | public enum SubtitleSource { 31 | 32 | /// An SRT file with an identical name as the video 33 | case folder 34 | 35 | /// Subtitles are extracted from an MKV file 36 | case mkv 37 | 38 | /// The sutitles were fetched from OpenSubtitles 39 | case opensubtitles 40 | 41 | } 42 | 43 | /// Represents a subtitle relating to a specific file. 44 | open class Subtitle: NSObject { 45 | 46 | /// The unique key for the subtitle 47 | open dynamic var key = "" 48 | 49 | /// The detected language of the subtitle 50 | open dynamic var language: String? 51 | 52 | /// The name of the file e.g MySubtitle.srt 53 | open dynamic var name = "" 54 | 55 | /// The ID of the file this subtitle is associated with 56 | open dynamic var fileId = 0 57 | 58 | /// Where the subtitle was obtained from 59 | open var source: SubtitleSource = .folder 60 | 61 | internal convenience init(json: [String:Any], id: Int) { 62 | self.init() 63 | 64 | key = json["key"] as? String ?? "" 65 | language = json["language"] as? String 66 | name = json["name"] as? String ?? "Unknown" 67 | fileId = id 68 | 69 | if let text = json["source"] as? String { 70 | source = { 71 | switch text { 72 | case "folder": 73 | return .folder 74 | case "mkv": 75 | return .mkv 76 | case "opensubtitles": 77 | return .opensubtitles 78 | default: 79 | return .folder 80 | } 81 | }() 82 | } 83 | 84 | } 85 | 86 | /// Generate the URL for the requested format 87 | /// 88 | /// - Parameter format: The format to request. Defaults to `.srt` 89 | /// - Returns: The generated URL 90 | open func url(forFormat format: SubtitleFormat = .srt) -> URL? { 91 | let urlString = Router.base + "/files/\(fileId)/subtitles/\(key)?format=" + format.rawValue 92 | return URL(string: urlString) 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /Sources/Transfer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Transfer.swift 3 | // Fetch 4 | // 5 | // Created by Stephen Radford on 23/06/2016. 6 | // Copyright © 2016 Cocoon Development Ltd. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Alamofire 11 | 12 | /// The current status of a transfer 13 | /// 14 | /// - downloading: The transfer is currently in progress 15 | /// - inQueue: The transfer is queued and will be started shortly 16 | /// - completed: The transfer has completed 17 | /// - cancelled: The transfer was manually cancelled 18 | public enum TransferStatus { 19 | 20 | /// The transfer is currently in progress 21 | case downloading 22 | 23 | /// The transfer is queued and will be started shortly 24 | case inQueue 25 | 26 | /// The transfer has completed 27 | case completed 28 | 29 | /// The transfer was manually cancelled 30 | case cancelled 31 | 32 | } 33 | 34 | /// Represents a transfer on Put.io 35 | open class Transfer { 36 | 37 | /// The number of bytes uploaded 38 | open var uploaded = 0 39 | 40 | /// The number of seconds remaining 41 | open var estimatedTime = 0 42 | 43 | /// Number of peers downloading from Put.io 44 | open var peersGettingFromUs = 0 45 | 46 | /// Should this file be extracted automatically or not? 47 | open var extract = false 48 | 49 | /// The current ration of downloaded to uploaded 50 | open var currentRatio: Double = 0.0 51 | 52 | /// The size of the file in bytes 53 | open var size = 0 54 | 55 | /// The upload of the transfer in bytes 56 | open var upSpeed = 0 57 | 58 | /// The ID of the transfer 59 | open var id = 0 60 | 61 | /// URL source of the file 62 | open var source: String? 63 | 64 | /// The ID of the subscription used to instigate the download 65 | open var subscriptionID: Int? 66 | 67 | /// The status message that's shown on Put.io 68 | open var statusMessage: String? 69 | 70 | /// The status of the transfer 71 | open var status: TransferStatus = .downloading 72 | 73 | /// The downspeed of the transfer in bytes 74 | open var downSpeed = 0 75 | 76 | /// The number of peers connected 77 | open var peersConnected = 0 78 | 79 | /// The number of bytes downloaded 80 | open var downloaded = 0 81 | 82 | /// The ID of the file that's being downloaded 83 | open var fileID: Int? 84 | 85 | /// The number of peers we're downloading from 86 | open var peersSendingToUs = 0 87 | 88 | /// The percentage donwloaded 89 | open var percentComplete = 0 90 | 91 | /// Custom message from the track (if there is one) 92 | open var trackerMessage: String? 93 | 94 | /// The name of the file that's being downloaded 95 | open var name: String? 96 | 97 | /// The date that the transfer was created 98 | open var createdAt: String? 99 | 100 | /// The error message, if there is one 101 | open var errorMessage: String? 102 | 103 | /// The folder that the file is being saved in 104 | open var parentID = 0 105 | 106 | /** 107 | Create an empty transfer 108 | 109 | - returns: A newly constructed transfer object 110 | */ 111 | init() { } 112 | 113 | /** 114 | Create a new transfer object from JSON 115 | 116 | - parameter json: The JSON received from the server 117 | 118 | - returns: A newly constructed transfer object 119 | */ 120 | internal convenience init(json: [String:Any]) { 121 | self.init() 122 | 123 | uploaded = (json["uploaded"] as? Int) ?? 0 124 | estimatedTime = (json["estimated_time"] as? Int) ?? 0 125 | peersGettingFromUs = (json["peers_getting_from_us"] as? Int) ?? 0 126 | extract = (json["extract"] as? Bool) ?? false 127 | currentRatio = (json["currentRatio"] as? Double) ?? 0.0 128 | size = (json["size"] as? Int) ?? 0 129 | upSpeed = (json["up_speed"] as? Int) ?? 0 130 | id = (json["id"] as? Int) ?? 0 131 | source = json["source"] as? String 132 | subscriptionID = json["subscription_id"] as? Int 133 | statusMessage = json["status_message"] as? String 134 | 135 | status = { 136 | switch json["status"] as! String { 137 | case "COMPLETED": 138 | return .completed 139 | default: 140 | return .downloading 141 | } 142 | }() 143 | 144 | downSpeed = (json["down_speed"] as? Int) ?? 0 145 | peersConnected = (json["peers_connected"] as? Int) ?? 0 146 | downloaded = (json["downloaded"] as? Int) ?? 0 147 | fileID = json["file_id"] as? Int 148 | peersSendingToUs = (json["peers_sending_to_us"] as? Int) ?? 0 149 | percentComplete = (json["percent_complete"] as? Int) ?? 0 150 | trackerMessage = json["tracker_message"] as? String 151 | name = json["name"] as? String 152 | createdAt = json["created_at"] as? String 153 | errorMessage = json["error_message"] as? String 154 | parentID = (json["parent_id"] as? Int) ?? 0 155 | } 156 | 157 | } 158 | 159 | // MARK: - Transfer class functions 160 | 161 | extension Transfer { 162 | 163 | /// Retry a failed transfer 164 | /// 165 | /// - Parameter completionHandler: The response handler 166 | public func retry(completionHandler: @escaping (Bool) -> Void) { 167 | Putio.request(Router.retryTransfer(id)) { json, error in 168 | guard error == nil else { 169 | completionHandler(false) 170 | return 171 | } 172 | 173 | completionHandler(true) 174 | } 175 | } 176 | 177 | /// Cancel the current transfer 178 | /// 179 | /// - Parameter completionHandler: The response handler 180 | public func cancel(completionHandler: @escaping (Bool) -> Void) { 181 | Putio.cancel(transfers: [self], completionHandler: completionHandler) 182 | } 183 | 184 | } 185 | 186 | 187 | // MARK : - Main class functions 188 | 189 | extension Putio { 190 | 191 | /// Fetch transfers from the API 192 | /// 193 | /// - Parameter completionHandler: The response handler 194 | public class func getTransfers(completionHandler: @escaping ([Transfer], Error?) -> Void) { 195 | Putio.request(Router.transfers) { response, error in 196 | if let error = error { 197 | completionHandler([], error) 198 | return 199 | } 200 | 201 | guard let json = response as? [String:Any], let transfers = json["transfers"] as? [[String:Any]] else { 202 | completionHandler([], PutioError.couldNotParseJSON) 203 | return 204 | } 205 | 206 | completionHandler(transfers.flatMap(Transfer.init), error) 207 | } 208 | } 209 | 210 | /// Add a new transfer from a URL string 211 | /// 212 | /// - Parameters: 213 | /// - url: The URL the transfer should be added from. 214 | /// - parent: The parent directory the file should be added to. Defaults to the root directory. 215 | /// - extract: Whether zip files should be extracted. Defaults to false. 216 | /// - completionHandler: The response handler 217 | public class func addTransfer(fromUrl url: String, parent: Int = 0, extract: Bool = false, completionHandler: @escaping (Transfer?, Error?) -> Void) { 218 | Putio.request(Router.addTransfer(url, parent, extract)) { json, error in 219 | if let error = error { 220 | completionHandler(nil, error) 221 | return 222 | } 223 | 224 | guard let json = json as? [String:Any] else { 225 | completionHandler(nil, PutioError.couldNotParseJSON) 226 | return 227 | } 228 | 229 | completionHandler(Transfer(json: json), error) 230 | } 231 | } 232 | 233 | 234 | /// Clean up all completed transfers 235 | /// 236 | /// - Parameter completionHandler: The response handler 237 | public class func cleanTransfers(completionHandler: @escaping (Bool) -> Void) { 238 | Putio.request(Router.cleanTransfers) { json, error in 239 | guard error == nil else { 240 | completionHandler(false) 241 | return 242 | } 243 | 244 | completionHandler(true) 245 | } 246 | } 247 | 248 | /// Cancel the selected transfers 249 | /// 250 | /// - Parameters: 251 | /// - transfers: The transfers to cancel 252 | /// - completionHandler: The response handler 253 | public class func cancel(transfers: [Transfer], completionHandler: @escaping (Bool) -> Void) { 254 | let ids = transfers.map { $0.id } 255 | Putio.request(Router.cancelTransfers(ids)) { json, error in 256 | guard error == nil else { 257 | completionHandler(false) 258 | return 259 | } 260 | 261 | completionHandler(true) 262 | } 263 | } 264 | 265 | } 266 | -------------------------------------------------------------------------------- /Tests/PutioKitTests/AccountTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AccountTests.swift 3 | // PutioKit 4 | // 5 | // Created by Stephen Radford on 15/01/2017. 6 | // 7 | // 8 | 9 | import XCTest 10 | @testable import PutioKit 11 | 12 | class AccountTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | 17 | Putio.testing = true 18 | } 19 | 20 | let data: [String:Any] = [ 21 | "username": "cenk", 22 | "mail": "cenk@gmail.com", 23 | "plan_expiration_date": "2014-03-04T06:33:30", 24 | "subtitle_languages": ["tr", "eng"], 25 | "default_subtitle_language": "tr", 26 | "disk": [ 27 | "avail": 20849243836, 28 | "used": 32837847364, 29 | "size": 53687091200 30 | ], 31 | "days_until_files_deletion": 2, 32 | "avatar_url": "https://secure.gravatar.com/avatar/6f51d9da35df428484c9d6f0288c2b22.jpg?s=50" 33 | ] 34 | 35 | func testJSONInitialiser() { 36 | let account = Account(json: data) 37 | 38 | XCTAssertEqual(account.username, "cenk") 39 | XCTAssertEqual(account.email, "cenk@gmail.com") 40 | XCTAssertEqual(account.subtitleLanguages, ["tr", "eng"]) 41 | XCTAssertEqual(account.defaultSubtitleLanguage, "tr") 42 | XCTAssertEqual(account.diskInfo?.available, 20849243836) 43 | XCTAssertEqual(account.diskInfo?.used, 32837847364) 44 | XCTAssertEqual(account.diskInfo?.size, 53687091200) 45 | XCTAssertNotNil(account.planExpirationDate) 46 | XCTAssertEqual(account.daysUntilFilesDeletion, 2) 47 | XCTAssertEqual(account.avatar, "https://secure.gravatar.com/avatar/6f51d9da35df428484c9d6f0288c2b22.jpg?s=50") 48 | } 49 | 50 | func testGetAccountInfo() { 51 | 52 | MockRequest.shared.statusCode = 200 53 | MockRequest.shared.value = [ 54 | "info": [ 55 | "username": "cenk", 56 | "mail": "cenk@gmail.com", 57 | "plan_expiration_date": "2014-03-04T06:33:30", 58 | "subtitle_languages": ["tr", "eng"], 59 | "default_subtitle_language": "tr", 60 | "disk": [ 61 | "avail": 20849243836, 62 | "used": 32837847364, 63 | "size": 53687091200 64 | ] 65 | ], 66 | "status": "OK" 67 | ] 68 | 69 | let expect = expectation(description: "A successful response") 70 | 71 | Putio.getAccountInfo { account, error in 72 | XCTAssertNil(error) 73 | XCTAssertNotNil(account) 74 | expect.fulfill() 75 | } 76 | 77 | waitForExpectations(timeout: 1) { error in 78 | if let error = error { 79 | XCTFail("wait for expectations \(error)") 80 | } 81 | } 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /Tests/PutioKitTests/EventTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EventTests.swift 3 | // PutioKit 4 | // 5 | // Created by Stephen Radford on 15/01/2017. 6 | // 7 | // 8 | 9 | import XCTest 10 | @testable import PutioKit 11 | 12 | class EventTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | 17 | Putio.testing = true 18 | } 19 | 20 | let data: [String:Any] = [ 21 | "transfer_name": "4th Rock from The Sun", 22 | "created_at": "2014-12-09 22:31:42", 23 | "transfer_size": 14872103214, 24 | "file_id": 257901855, 25 | "type": "transfer_completed" 26 | ] 27 | 28 | func testJSONInitialiser() { 29 | let event = Event(json: data) 30 | 31 | XCTAssertEqual(event.name, "4th Rock from The Sun") 32 | XCTAssertNotNil(event.createdAt) 33 | XCTAssertEqual(event.transferSize, 14872103214) 34 | XCTAssertEqual(event.fileId, 257901855) 35 | XCTAssertEqual(event.type, .transferCompleted) 36 | } 37 | 38 | func testGetEvents() { 39 | MockRequest.shared.statusCode = 200 40 | MockRequest.shared.value = [ 41 | "events": [ 42 | [ 43 | "transfer_name": "4th Rock from The Sun", 44 | "created_at": "2014-12-09 22:31:42", 45 | "transfer_size": 14872103214, 46 | "file_id": 257901855, 47 | "type": "transfer_completed" 48 | ] 49 | ] 50 | ] 51 | 52 | let expect = expectation(description: "Successful response") 53 | 54 | Putio.getEvents { events, error in 55 | XCTAssertNil(error) 56 | XCTAssertEqual(events.first?.name, "4th Rock from The Sun") 57 | expect.fulfill() 58 | } 59 | 60 | waitForExpectations(timeout: 1) { error in 61 | if let error = error { 62 | XCTFail("wait for expectations \(error)") 63 | } 64 | } 65 | } 66 | 67 | func testDeleteEvents() { 68 | MockRequest.shared.statusCode = 200 69 | MockRequest.shared.value = [ 70 | "status": "OK" 71 | ] 72 | 73 | let expect = expectation(description: "Successful response") 74 | 75 | Putio.deleteEvents { success in 76 | XCTAssertTrue(success) 77 | expect.fulfill() 78 | } 79 | 80 | waitForExpectations(timeout: 1) { error in 81 | if let error = error { 82 | XCTFail("wait for expectations \(error)") 83 | } 84 | } 85 | 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /Tests/PutioKitTests/FriendTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FriendTests.swift 3 | // PutioKit 4 | // 5 | // Created by Stephen Radford on 10/01/2017. 6 | // 7 | // 8 | 9 | import XCTest 10 | @testable import PutioKit 11 | 12 | class FriendTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | 17 | Putio.testing = true 18 | } 19 | 20 | let data: [String:Any] = [ 21 | "user_name": "John Doe", 22 | "user_avatar_url": "https://gravatar.com/avatars/johndoe.png", 23 | "share_id": 3913572317 24 | ] 25 | 26 | func testJSONInitialiser() { 27 | let friend = Friend(json: data) 28 | 29 | XCTAssertEqual(friend.username, "John Doe") 30 | XCTAssertEqual(friend.avatar, "https://gravatar.com/avatars/johndoe.png") 31 | XCTAssertEqual(friend.shareId, 3913572317) 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /Tests/PutioKitTests/PutioTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PutioTests.swift 3 | // PutioKit 4 | // 5 | // Created by Stephen Radford on 14/01/2017. 6 | // 7 | // 8 | 9 | import XCTest 10 | @testable import PutioKit 11 | 12 | class PutioTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | Putio.testing = true 17 | } 18 | 19 | func testAuthenticationUri() { 20 | 21 | Putio.redirectUri = "http://getfetchapp.com/auth" 22 | Putio.clientId = 1234 23 | let url = Putio.authenticationUrl 24 | 25 | XCTAssertEqual(url?.absoluteString, "https://api.put.io/v2/oauth2/authenticate?client_id=1234&response_type=token&redirect_uri=http://getfetchapp.com/auth") 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /Tests/PutioKitTests/SettingsTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SettingsTests.swift 3 | // PutioKit 4 | // 5 | // Created by Stephen Radford on 30/01/2017. 6 | // 7 | // 8 | 9 | import XCTest 10 | @testable import PutioKit 11 | 12 | class SettingsTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | 17 | Putio.testing = true 18 | } 19 | 20 | let data: [String:Any] = [ 21 | "beta_user": true, 22 | "callback_url": "", 23 | "default_download_folder": 123, 24 | "is_invisible": true, 25 | "next_episode": true, 26 | "sort_by": "DATE_DESC", 27 | "start_from": true, 28 | "subtitle_languages": [ 29 | "eng" 30 | ], 31 | "theater_mode": true, 32 | "transfer_sort_by": "DATEADDED_ASC", 33 | "tunnel_route_name": "London", 34 | "use_private_download_ip": false, 35 | "simultaneous_download_limit": 20 36 | ] 37 | 38 | func testJSONInitialiser() { 39 | let settings = Settings(json: data) 40 | 41 | XCTAssertTrue(settings.betaUser) 42 | XCTAssertTrue(settings.isInvisible) 43 | XCTAssertTrue(settings.nextEpisode) 44 | XCTAssertEqual(settings.defaultDownloadFolder, 123) 45 | XCTAssertEqual(settings.simultaneousDownloadLimit, 20) 46 | } 47 | 48 | func testGetAccountInfo() { 49 | 50 | MockRequest.shared.statusCode = 200 51 | MockRequest.shared.value = [ 52 | "settings": data, 53 | "status": "OK" 54 | ] 55 | 56 | let expect = expectation(description: "A successful response") 57 | 58 | Putio.getSettings { settings, error in 59 | XCTAssertNil(error) 60 | XCTAssertNotNil(settings) 61 | expect.fulfill() 62 | } 63 | 64 | waitForExpectations(timeout: 1) { error in 65 | if let error = error { 66 | XCTFail("wait for expectations \(error)") 67 | } 68 | } 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /Tests/PutioKitTests/SubtitleTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SubtitleTests.swift 3 | // PutioKit 4 | // 5 | // Created by Stephen Radford on 12/01/2017. 6 | // 7 | // 8 | 9 | import XCTest 10 | @testable import PutioKit 11 | 12 | class SubtitleTests: XCTestCase { 13 | 14 | let data: [String:Any] = [ 15 | "key": "V7mVadfvq34erarjy9tqj0435hgare", 16 | "language": "Japanese", 17 | "name": "Subtitles.srt", 18 | "source": "mkv" 19 | ] 20 | 21 | func testJSONInitialiser() { 22 | let subtitle = Subtitle(json: data, id: 123) 23 | 24 | XCTAssertEqual(subtitle.fileId, 123) 25 | XCTAssertEqual(subtitle.key, "V7mVadfvq34erarjy9tqj0435hgare") 26 | XCTAssertEqual(subtitle.language, "Japanese") 27 | XCTAssertEqual(subtitle.name, "Subtitles.srt") 28 | XCTAssertEqual(subtitle.source, SubtitleSource.mkv) 29 | } 30 | 31 | func testURL() { 32 | 33 | let subtitle = Subtitle(json: data, id: 123) 34 | let defaultURL = subtitle.url() 35 | 36 | XCTAssertEqual(defaultURL?.absoluteString, "https://api.put.io/v2/files/123/subtitles/V7mVadfvq34erarjy9tqj0435hgare?format=srt") 37 | 38 | let webVTT = subtitle.url(forFormat: .webvtt) 39 | 40 | XCTAssertEqual(webVTT?.absoluteString, "https://api.put.io/v2/files/123/subtitles/V7mVadfvq34erarjy9tqj0435hgare?format=webvtt") 41 | 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /Tests/PutioKitTests/TransferTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TransferTests.swift 3 | // PutioKit 4 | // 5 | // Created by Stephen Radford on 09/01/2017. 6 | // 7 | // 8 | 9 | import XCTest 10 | @testable import PutioKit 11 | 12 | class TransferTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | 17 | Putio.testing = true 18 | } 19 | 20 | let data: [String:Any] = [ 21 | "uploaded": 1234, 22 | "estimated_time": 2345, 23 | "peers_getting_from_us": 5, 24 | "extract": true, 25 | "currentRatio": 1.2, 26 | "size": 2345876, 27 | "up_speed": 352, 28 | "id": 9284, 29 | "source": "http://google.com", 30 | "subscription_id": 12, 31 | "status_message": "Can anyone hear me?", 32 | "status": "COMPLETED", 33 | "down_speed": 8288, 34 | "peers_connected": 29, 35 | "downloaded": 234, 36 | "file_id": 11234, 37 | "peers_sending_to_us": 1, 38 | "percent_complete": 12, 39 | "tracker_message": "A lovely message", 40 | "name": "1337hax.exe", 41 | "created_at": "2017-01-04 10:10:23", 42 | "error_message": "Unlikely to happen", 43 | "parent_id": 13 44 | ] 45 | 46 | func testJSONInitializer() { 47 | let transfer = Transfer(json: data) 48 | 49 | XCTAssertEqual(transfer.uploaded, 1234) 50 | XCTAssertEqual(transfer.estimatedTime, 2345) 51 | XCTAssertEqual(transfer.peersGettingFromUs, 5) 52 | XCTAssertEqual(transfer.extract, true) 53 | XCTAssertEqual(transfer.currentRatio, 1.2) 54 | XCTAssertEqual(transfer.size, 2345876) 55 | XCTAssertEqual(transfer.upSpeed, 352) 56 | XCTAssertEqual(transfer.id, 9284) 57 | XCTAssertEqual(transfer.source, "http://google.com") 58 | XCTAssertEqual(transfer.subscriptionID, 12) 59 | XCTAssertEqual(transfer.statusMessage, "Can anyone hear me?") 60 | XCTAssertEqual(transfer.status, .completed) 61 | XCTAssertEqual(transfer.downSpeed, 8288) 62 | XCTAssertEqual(transfer.peersConnected, 29) 63 | XCTAssertEqual(transfer.downloaded, 234) 64 | XCTAssertEqual(transfer.fileID, 11234) 65 | XCTAssertEqual(transfer.peersSendingToUs, 1) 66 | XCTAssertEqual(transfer.percentComplete, 12) 67 | XCTAssertEqual(transfer.trackerMessage, "A lovely message") 68 | XCTAssertEqual(transfer.name, "1337hax.exe") 69 | XCTAssertEqual(transfer.createdAt, "2017-01-04 10:10:23") 70 | XCTAssertEqual(transfer.errorMessage, "Unlikely to happen") 71 | XCTAssertEqual(transfer.parentID, 13) 72 | } 73 | 74 | 75 | // MARK: - Global Methods 76 | 77 | 78 | func testGetTransfers() { 79 | 80 | MockRequest.shared.statusCode = 200 81 | MockRequest.shared.value = [ 82 | "transfers": [data] 83 | ] 84 | 85 | let expect = expectation(description: "Array of transfers is returned") 86 | 87 | Putio.getTransfers { transfers, error in 88 | 89 | XCTAssertNotNil(transfers) 90 | XCTAssertNil(error) 91 | 92 | expect.fulfill() 93 | } 94 | 95 | MockRequest.shared.statusCode = 401 96 | MockRequest.shared.value = [ 97 | "transfers": [data] 98 | ] 99 | 100 | let expect2 = expectation(description: "Error will be bad status") 101 | 102 | Putio.getTransfers { transfers, error in 103 | XCTAssertNotNil(error) 104 | XCTAssertTrue(error as! PutioError == PutioError.invalidStatusCode, "Invalid status code") 105 | expect2.fulfill() 106 | } 107 | 108 | MockRequest.shared.statusCode = 200 109 | MockRequest.shared.value = "" 110 | 111 | let expect3 = expectation(description: "JSON parse error will be returned") 112 | 113 | Putio.getTransfers { transfers, error in 114 | XCTAssertNotNil(error) 115 | XCTAssertTrue(error as! PutioError == PutioError.couldNotParseJSON, "Could not parse JSON") 116 | 117 | expect3.fulfill() 118 | } 119 | 120 | waitForExpectations(timeout: 1) { error in 121 | if let error = error { 122 | XCTFail("wait for expectations \(error)") 123 | } 124 | } 125 | 126 | } 127 | 128 | func testAddTransfer() { 129 | 130 | MockRequest.shared.statusCode = 200 131 | MockRequest.shared.value = data 132 | 133 | let expect = expectation(description: "A transfer to be returned") 134 | 135 | Putio.addTransfer(fromUrl: "http://google.com") { transfer, error in 136 | XCTAssertNotNil(transfer) 137 | XCTAssertNil(error) 138 | expect.fulfill() 139 | } 140 | 141 | MockRequest.shared.statusCode = 401 142 | MockRequest.shared.value = data 143 | 144 | let expect2 = expectation(description: "Bad status error") 145 | 146 | Putio.addTransfer(fromUrl: "http://google.com") { transfer, error in 147 | XCTAssertNotNil(error) 148 | XCTAssertTrue(error as! PutioError == PutioError.invalidStatusCode, "Invalid status code") 149 | 150 | expect2.fulfill() 151 | } 152 | 153 | MockRequest.shared.statusCode = 200 154 | MockRequest.shared.value = "" 155 | 156 | let expect3 = expectation(description: "JSON parse error") 157 | 158 | Putio.addTransfer(fromUrl: "http://google.com") { transfer, error in 159 | XCTAssertNotNil(error) 160 | XCTAssertTrue(error as! PutioError == PutioError.couldNotParseJSON, "Invalid status code") 161 | 162 | expect3.fulfill() 163 | } 164 | 165 | 166 | waitForExpectations(timeout: 1) { error in 167 | if let error = error { 168 | XCTFail("wait for expectations \(error)") 169 | } 170 | } 171 | 172 | } 173 | 174 | func testCleanTransfers() { 175 | 176 | MockRequest.shared.statusCode = 200 177 | MockRequest.shared.value = "Success" 178 | 179 | let expect = expectation(description: "Successful response") 180 | 181 | Putio.cleanTransfers { completed in 182 | XCTAssertTrue(completed) 183 | expect.fulfill() 184 | } 185 | 186 | let expect2 = expectation(description: "Fail response") 187 | 188 | MockRequest.shared.statusCode = 500 189 | MockRequest.shared.value = "" 190 | 191 | Putio.cleanTransfers { completed in 192 | XCTAssertFalse(completed) 193 | expect2.fulfill() 194 | } 195 | 196 | waitForExpectations(timeout: 1) { error in 197 | if let error = error { 198 | XCTFail("wait for expectations \(error)") 199 | } 200 | } 201 | 202 | } 203 | 204 | func testCancelTransfers() { 205 | 206 | let transfer = Transfer(json: data) 207 | 208 | MockRequest.shared.statusCode = 200 209 | MockRequest.shared.value = "Success" 210 | 211 | let expect = expectation(description: "Successful response") 212 | 213 | Putio.cancel(transfers: [transfer]) { completed in 214 | XCTAssertTrue(completed) 215 | expect.fulfill() 216 | } 217 | 218 | MockRequest.shared.statusCode = 500 219 | MockRequest.shared.value = "Fail" 220 | 221 | let expect2 = expectation(description: "Fail response") 222 | 223 | Putio.cancel(transfers: [transfer]) { completed in 224 | XCTAssertFalse(completed) 225 | expect2.fulfill() 226 | } 227 | 228 | waitForExpectations(timeout: 1) { error in 229 | if let error = error { 230 | XCTFail("wait for expectations \(error)") 231 | } 232 | } 233 | 234 | } 235 | 236 | 237 | // MARK: - Model Methods 238 | 239 | func testRetryTransfer() { 240 | 241 | let transfer = Transfer(json: data) 242 | 243 | MockRequest.shared.statusCode = 200 244 | MockRequest.shared.value = "Success" 245 | 246 | let expect = expectation(description: "Successful response") 247 | 248 | transfer.retry { completed in 249 | XCTAssertTrue(completed) 250 | expect.fulfill() 251 | } 252 | 253 | MockRequest.shared.statusCode = 500 254 | MockRequest.shared.value = "Fail" 255 | 256 | let expect2 = expectation(description: "Fail response") 257 | 258 | transfer.retry { completed in 259 | XCTAssertFalse(completed) 260 | expect2.fulfill() 261 | } 262 | 263 | waitForExpectations(timeout: 1) { error in 264 | if let error = error { 265 | XCTFail("wait for expectations \(error)") 266 | } 267 | } 268 | 269 | } 270 | 271 | } 272 | -------------------------------------------------------------------------------- /docs/Classes/Friend.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Friend Class Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |

20 | 21 | PutioKit Docs 22 | 23 | (100% documented) 24 |

25 | 26 | 27 |
28 | 29 | 34 | 35 |
36 | 100 |
101 | 102 |
103 |
104 |

Friend

105 |
106 |
107 |
open class Friend: NSObject
108 | 109 |
110 |
111 |

Represents a friend of the logged in user.

112 | 113 |
114 |
115 | 116 |
117 |
118 |
119 |
    120 |
  • 121 |
    122 | 123 | 124 | 125 | username 126 | 127 |
    128 |
    129 |
    130 |
    131 |
    132 |
    133 |

    The username of the friend

    134 | 135 |
    136 |
    137 |

    Declaration

    138 |
    139 |

    Swift

    140 |
    open dynamic var username = ""
    141 | 142 |
    143 |
    144 |
    145 |
    146 |
  • 147 |
  • 148 |
    149 | 150 | 151 | 152 | avatar 153 | 154 |
    155 |
    156 |
    157 |
    158 |
    159 |
    160 |

    URL of the user’s avatar

    161 | 162 |
    163 |
    164 |

    Declaration

    165 |
    166 |

    Swift

    167 |
    open dynamic var avatar = ""
    168 | 169 |
    170 |
    171 |
    172 |
    173 |
  • 174 |
  • 175 |
    176 | 177 | 178 | 179 | shareId 180 | 181 |
    182 |
    183 |
    184 |
    185 |
    186 |
    187 |

    The ID that can be used for unsharing a file

    188 | 189 |
    190 |
    191 |

    Declaration

    192 |
    193 |

    Swift

    194 |
    open dynamic var shareId = 0
    195 | 196 |
    197 |
    198 |
    199 |
    200 |
  • 201 |
202 |
203 |
204 |
205 | 206 |
207 |
208 | 212 | 213 | 214 | 215 | -------------------------------------------------------------------------------- /docs/Enums/PutioError.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | PutioError Enum Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |

20 | 21 | PutioKit Docs 22 | 23 | (100% documented) 24 |

25 | 26 | 27 |
28 | 29 | 34 | 35 |
36 | 100 |
101 | 102 |
103 |
104 |

PutioError

105 |
106 |
107 |
public enum PutioError: Error
108 | 109 |
110 |
111 |

Represents errors that can occur when accessing the Put.io API

112 | 113 |
    114 |
  • couldNotParseJSON: There was an error parsing the JSON from the API
  • 115 |
  • noAccessToken: An access token was not provided so this endpoint could not be called
  • 116 |
  • invalidStatusCode: The expected status code was not returned
  • 117 |
118 | 119 |
120 |
121 | 122 |
123 |
124 |
125 |
    126 |
  • 127 |
    128 | 129 | 130 | 131 | couldNotParseJSON 132 | 133 |
    134 |
    135 |
    136 |
    137 |
    138 |
    139 |

    There was an error parsing the JSON from the API

    140 | 141 |
    142 |
    143 |

    Declaration

    144 |
    145 |

    Swift

    146 |
    case couldNotParseJSON
    147 | 148 |
    149 |
    150 |
    151 |
    152 |
  • 153 |
154 |
155 |
156 |
    157 |
  • 158 |
    159 | 160 | 161 | 162 | noAccessToken 163 | 164 |
    165 |
    166 |
    167 |
    168 |
    169 |
    170 |

    An access token was not provided so this endpoint could not be called

    171 | 172 |
    173 |
    174 |

    Declaration

    175 |
    176 |

    Swift

    177 |
    case noAccessToken
    178 | 179 |
    180 |
    181 |
    182 |
    183 |
  • 184 |
185 |
186 |
187 |
    188 |
  • 189 |
    190 | 191 | 192 | 193 | invalidStatusCode 194 | 195 |
    196 |
    197 |
    198 |
    199 |
    200 |
    201 |

    The expected status code was not returned

    202 | 203 |
    204 |
    205 |

    Declaration

    206 |
    207 |

    Swift

    208 |
    case invalidStatusCode
    209 | 210 |
    211 |
    212 |
    213 |
    214 |
  • 215 |
216 |
217 |
218 |
219 | 220 |
221 |
222 | 226 | 227 | 228 | 229 | -------------------------------------------------------------------------------- /docs/Enums/SubtitleFormat.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SubtitleFormat Enum Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |

20 | 21 | PutioKit Docs 22 | 23 | (100% documented) 24 |

25 | 26 | 27 |
28 | 29 | 34 | 35 |
36 | 100 |
101 | 102 |
103 |
104 |

SubtitleFormat

105 |
106 |
107 |
public enum SubtitleFormat: String
108 | 109 |
110 |
111 |

The file format of subtitle.

112 | 113 |
    114 |
  • srt: Default. SRT file format.
  • 115 |
  • webvtt: webVTT file format used by things like Chromecast.
  • 116 |
117 | 118 |
119 |
120 | 121 |
122 |
123 |
124 |
    125 |
  • 126 |
    127 | 128 | 129 | 130 | srt 131 | 132 |
    133 |
    134 |
    135 |
    136 |
    137 |
    138 |

    The default subtitle format used by Put.io.

    139 | 140 |
    141 |
    142 |

    Declaration

    143 |
    144 |

    Swift

    145 |
    case srt = "srt"
    146 | 147 |
    148 |
    149 |
    150 |
    151 |
  • 152 |
153 |
154 |
155 |
    156 |
  • 157 |
    158 | 159 | 160 | 161 | webvtt 162 | 163 |
    164 |
    165 |
    166 |
    167 |
    168 |
    169 |

    An alternative format available if required. Things like Chromecast require WebVTT.

    170 | 171 |
    172 |
    173 |

    Declaration

    174 |
    175 |

    Swift

    176 |
    case webvtt = "webvtt"
    177 | 178 |
    179 |
    180 |
    181 |
    182 |
  • 183 |
184 |
185 |
186 |
187 | 188 |
189 |
190 | 194 | 195 | 196 | 197 | -------------------------------------------------------------------------------- /docs/Enums/SubtitleSource.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SubtitleSource Enum Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |

20 | 21 | PutioKit Docs 22 | 23 | (100% documented) 24 |

25 | 26 | 27 |
28 | 29 | 34 | 35 |
36 | 100 |
101 | 102 |
103 |
104 |

SubtitleSource

105 |
106 |
107 |
public enum SubtitleSource
108 | 109 |
110 |
111 |

Where the subtitle was obtained from

112 | 113 |
    114 |
  • folder: An SRT file with an identical name as the video
  • 115 |
  • mkv: Subtitles are extracted from an MKV file
  • 116 |
  • opensubtitles: The sutitles were fetched from OpenSubtitles
  • 117 |
118 | 119 |
120 |
121 | 122 |
123 |
124 |
125 |
    126 |
  • 127 |
    128 | 129 | 130 | 131 | folder 132 | 133 |
    134 |
    135 |
    136 |
    137 |
    138 |
    139 |

    An SRT file with an identical name as the video

    140 | 141 |
    142 |
    143 |

    Declaration

    144 |
    145 |

    Swift

    146 |
    case folder
    147 | 148 |
    149 |
    150 |
    151 |
    152 |
  • 153 |
154 |
155 |
156 |
    157 |
  • 158 |
    159 | 160 | 161 | 162 | mkv 163 | 164 |
    165 |
    166 |
    167 |
    168 |
    169 |
    170 |

    Subtitles are extracted from an MKV file

    171 | 172 |
    173 |
    174 |

    Declaration

    175 |
    176 |

    Swift

    177 |
    case mkv
    178 | 179 |
    180 |
    181 |
    182 |
    183 |
  • 184 |
185 |
186 |
187 |
    188 |
  • 189 |
    190 | 191 | 192 | 193 | opensubtitles 194 | 195 |
    196 |
    197 |
    198 |
    199 |
    200 |
    201 |

    The sutitles were fetched from OpenSubtitles

    202 | 203 |
    204 |
    205 |

    Declaration

    206 |
    207 |

    Swift

    208 |
    case opensubtitles
    209 | 210 |
    211 |
    212 |
    213 |
    214 |
  • 215 |
216 |
217 |
218 |
219 | 220 |
221 |
222 | 226 | 227 | 228 | 229 | -------------------------------------------------------------------------------- /docs/Enums/TransferStatus.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | TransferStatus Enum Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |

20 | 21 | PutioKit Docs 22 | 23 | (100% documented) 24 |

25 | 26 | 27 |
28 | 29 | 34 | 35 |
36 | 100 |
101 | 102 |
103 |
104 |

TransferStatus

105 |
106 |
107 |
public enum TransferStatus
108 | 109 |
110 |
111 |

The current status of a transfer

112 | 113 |
    114 |
  • downloading: The transfer is currently in progress
  • 115 |
  • inQueue: The transfer is queued and will be started shortly
  • 116 |
  • completed: The transfer has completed
  • 117 |
  • cancelled: The transfer was manually cancelled
  • 118 |
119 | 120 |
121 |
122 | 123 |
124 |
125 |
126 |
    127 |
  • 128 |
    129 | 130 | 131 | 132 | downloading 133 | 134 |
    135 |
    136 |
    137 |
    138 |
    139 |
    140 |

    The transfer is currently in progress

    141 | 142 |
    143 |
    144 |

    Declaration

    145 |
    146 |

    Swift

    147 |
    case downloading
    148 | 149 |
    150 |
    151 |
    152 |
    153 |
  • 154 |
155 |
156 |
157 |
    158 |
  • 159 |
    160 | 161 | 162 | 163 | inQueue 164 | 165 |
    166 |
    167 |
    168 |
    169 |
    170 |
    171 |

    The transfer is queued and will be started shortly

    172 | 173 |
    174 |
    175 |

    Declaration

    176 |
    177 |

    Swift

    178 |
    case inQueue
    179 | 180 |
    181 |
    182 |
    183 |
    184 |
  • 185 |
186 |
187 |
188 |
    189 |
  • 190 |
    191 | 192 | 193 | 194 | completed 195 | 196 |
    197 |
    198 |
    199 |
    200 |
    201 |
    202 |

    The transfer has completed

    203 | 204 |
    205 |
    206 |

    Declaration

    207 |
    208 |

    Swift

    209 |
    case completed
    210 | 211 |
    212 |
    213 |
    214 |
    215 |
  • 216 |
217 |
218 |
219 |
    220 |
  • 221 |
    222 | 223 | 224 | 225 | cancelled 226 | 227 |
    228 |
    229 |
    230 |
    231 |
    232 |
    233 |

    The transfer was manually cancelled

    234 | 235 |
    236 |
    237 |

    Declaration

    238 |
    239 |

    Swift

    240 |
    case cancelled
    241 | 242 |
    243 |
    244 |
    245 |
    246 |
  • 247 |
248 |
249 |
250 |
251 | 252 |
253 |
254 | 258 | 259 | 260 | 261 | -------------------------------------------------------------------------------- /docs/Structs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Structs Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 |

19 | 20 | PutioKit Docs 21 | 22 | (100% documented) 23 |

24 | 25 | 26 |
27 | 28 | 33 | 34 |
35 | 99 |
100 | 101 |
102 |
103 |

Structs

104 |

The following structs are available globally.

105 | 106 |
107 |
108 | 109 |
110 |
111 |
112 |
    113 |
  • 114 |
    115 | 116 | 117 | 118 | DiskInfo 119 | 120 |
    121 |
    122 |
    123 |
    124 |
    125 |
    126 |

    Information about the disk usage on Put.io

    127 | 128 | See more 129 |
    130 |
    131 |

    Declaration

    132 |
    133 |

    Swift

    134 |
    public struct DiskInfo
    135 | 136 |
    137 |
    138 |
    139 |
    140 |
  • 141 |
142 |
143 |
144 |
145 | 146 |
147 |
148 | 152 | 153 | 154 | 155 | -------------------------------------------------------------------------------- /docs/Structs/DiskInfo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | DiskInfo Struct Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |

20 | 21 | PutioKit Docs 22 | 23 | (100% documented) 24 |

25 | 26 | 27 |
28 | 29 | 34 | 35 |
36 | 100 |
101 | 102 |
103 |
104 |

DiskInfo

105 |
106 |
107 |
public struct DiskInfo
108 | 109 |
110 |
111 |

Information about the disk usage on Put.io

112 | 113 |
114 |
115 | 116 |
117 |
118 |
119 |
    120 |
  • 121 |
    122 | 123 | 124 | 125 | available 126 | 127 |
    128 |
    129 |
    130 |
    131 |
    132 |
    133 |

    The available disk space

    134 | 135 |
    136 |
    137 |

    Declaration

    138 |
    139 |

    Swift

    140 |
    public let available: Int
    141 | 142 |
    143 |
    144 |
    145 |
    146 |
  • 147 |
  • 148 |
    149 | 150 | 151 | 152 | used 153 | 154 |
    155 |
    156 |
    157 |
    158 |
    159 |
    160 |

    The amount of space used on the disk

    161 | 162 |
    163 |
    164 |

    Declaration

    165 |
    166 |

    Swift

    167 |
    public let used: Int
    168 | 169 |
    170 |
    171 |
    172 |
    173 |
  • 174 |
  • 175 |
    176 | 177 | 178 | 179 | size 180 | 181 |
    182 |
    183 |
    184 |
    185 |
    186 |
    187 |

    The total size of the disk

    188 | 189 |
    190 |
    191 |

    Declaration

    192 |
    193 |

    Swift

    194 |
    public let size: Int
    195 | 196 |
    197 |
    198 |
    199 |
    200 |
  • 201 |
202 |
203 |
204 |
205 | 206 |
207 |
208 | 212 | 213 | 214 | 215 | -------------------------------------------------------------------------------- /docs/css/highlight.css: -------------------------------------------------------------------------------- 1 | /* Credit to https://gist.github.com/wataru420/2048287 */ 2 | .highlight { 3 | /* Comment */ 4 | /* Error */ 5 | /* Keyword */ 6 | /* Operator */ 7 | /* Comment.Multiline */ 8 | /* Comment.Preproc */ 9 | /* Comment.Single */ 10 | /* Comment.Special */ 11 | /* Generic.Deleted */ 12 | /* Generic.Deleted.Specific */ 13 | /* Generic.Emph */ 14 | /* Generic.Error */ 15 | /* Generic.Heading */ 16 | /* Generic.Inserted */ 17 | /* Generic.Inserted.Specific */ 18 | /* Generic.Output */ 19 | /* Generic.Prompt */ 20 | /* Generic.Strong */ 21 | /* Generic.Subheading */ 22 | /* Generic.Traceback */ 23 | /* Keyword.Constant */ 24 | /* Keyword.Declaration */ 25 | /* Keyword.Pseudo */ 26 | /* Keyword.Reserved */ 27 | /* Keyword.Type */ 28 | /* Literal.Number */ 29 | /* Literal.String */ 30 | /* Name.Attribute */ 31 | /* Name.Builtin */ 32 | /* Name.Class */ 33 | /* Name.Constant */ 34 | /* Name.Entity */ 35 | /* Name.Exception */ 36 | /* Name.Function */ 37 | /* Name.Namespace */ 38 | /* Name.Tag */ 39 | /* Name.Variable */ 40 | /* Operator.Word */ 41 | /* Text.Whitespace */ 42 | /* Literal.Number.Float */ 43 | /* Literal.Number.Hex */ 44 | /* Literal.Number.Integer */ 45 | /* Literal.Number.Oct */ 46 | /* Literal.String.Backtick */ 47 | /* Literal.String.Char */ 48 | /* Literal.String.Doc */ 49 | /* Literal.String.Double */ 50 | /* Literal.String.Escape */ 51 | /* Literal.String.Heredoc */ 52 | /* Literal.String.Interpol */ 53 | /* Literal.String.Other */ 54 | /* Literal.String.Regex */ 55 | /* Literal.String.Single */ 56 | /* Literal.String.Symbol */ 57 | /* Name.Builtin.Pseudo */ 58 | /* Name.Variable.Class */ 59 | /* Name.Variable.Global */ 60 | /* Name.Variable.Instance */ 61 | /* Literal.Number.Integer.Long */ } 62 | .highlight .c { 63 | color: #999988; 64 | font-style: italic; } 65 | .highlight .err { 66 | color: #a61717; 67 | background-color: #e3d2d2; } 68 | .highlight .k { 69 | color: #000000; 70 | font-weight: bold; } 71 | .highlight .o { 72 | color: #000000; 73 | font-weight: bold; } 74 | .highlight .cm { 75 | color: #999988; 76 | font-style: italic; } 77 | .highlight .cp { 78 | color: #999999; 79 | font-weight: bold; } 80 | .highlight .c1 { 81 | color: #999988; 82 | font-style: italic; } 83 | .highlight .cs { 84 | color: #999999; 85 | font-weight: bold; 86 | font-style: italic; } 87 | .highlight .gd { 88 | color: #000000; 89 | background-color: #ffdddd; } 90 | .highlight .gd .x { 91 | color: #000000; 92 | background-color: #ffaaaa; } 93 | .highlight .ge { 94 | color: #000000; 95 | font-style: italic; } 96 | .highlight .gr { 97 | color: #aa0000; } 98 | .highlight .gh { 99 | color: #999999; } 100 | .highlight .gi { 101 | color: #000000; 102 | background-color: #ddffdd; } 103 | .highlight .gi .x { 104 | color: #000000; 105 | background-color: #aaffaa; } 106 | .highlight .go { 107 | color: #888888; } 108 | .highlight .gp { 109 | color: #555555; } 110 | .highlight .gs { 111 | font-weight: bold; } 112 | .highlight .gu { 113 | color: #aaaaaa; } 114 | .highlight .gt { 115 | color: #aa0000; } 116 | .highlight .kc { 117 | color: #000000; 118 | font-weight: bold; } 119 | .highlight .kd { 120 | color: #000000; 121 | font-weight: bold; } 122 | .highlight .kp { 123 | color: #000000; 124 | font-weight: bold; } 125 | .highlight .kr { 126 | color: #000000; 127 | font-weight: bold; } 128 | .highlight .kt { 129 | color: #445588; } 130 | .highlight .m { 131 | color: #009999; } 132 | .highlight .s { 133 | color: #d14; } 134 | .highlight .na { 135 | color: #008080; } 136 | .highlight .nb { 137 | color: #0086B3; } 138 | .highlight .nc { 139 | color: #445588; 140 | font-weight: bold; } 141 | .highlight .no { 142 | color: #008080; } 143 | .highlight .ni { 144 | color: #800080; } 145 | .highlight .ne { 146 | color: #990000; 147 | font-weight: bold; } 148 | .highlight .nf { 149 | color: #990000; } 150 | .highlight .nn { 151 | color: #555555; } 152 | .highlight .nt { 153 | color: #000080; } 154 | .highlight .nv { 155 | color: #008080; } 156 | .highlight .ow { 157 | color: #000000; 158 | font-weight: bold; } 159 | .highlight .w { 160 | color: #bbbbbb; } 161 | .highlight .mf { 162 | color: #009999; } 163 | .highlight .mh { 164 | color: #009999; } 165 | .highlight .mi { 166 | color: #009999; } 167 | .highlight .mo { 168 | color: #009999; } 169 | .highlight .sb { 170 | color: #d14; } 171 | .highlight .sc { 172 | color: #d14; } 173 | .highlight .sd { 174 | color: #d14; } 175 | .highlight .s2 { 176 | color: #d14; } 177 | .highlight .se { 178 | color: #d14; } 179 | .highlight .sh { 180 | color: #d14; } 181 | .highlight .si { 182 | color: #d14; } 183 | .highlight .sx { 184 | color: #d14; } 185 | .highlight .sr { 186 | color: #009926; } 187 | .highlight .s1 { 188 | color: #d14; } 189 | .highlight .ss { 190 | color: #990073; } 191 | .highlight .bp { 192 | color: #999999; } 193 | .highlight .vc { 194 | color: #008080; } 195 | .highlight .vg { 196 | color: #008080; } 197 | .highlight .vi { 198 | color: #008080; } 199 | .highlight .il { 200 | color: #009999; } 201 | -------------------------------------------------------------------------------- /docs/css/jazzy.css: -------------------------------------------------------------------------------- 1 | *, *:before, *:after { 2 | box-sizing: inherit; } 3 | 4 | body { 5 | margin: 0; 6 | background: #fff; 7 | color: #333; 8 | font: 16px/1.7 "Helvetica Neue", Helvetica, Arial, sans-serif; 9 | letter-spacing: .2px; 10 | -webkit-font-smoothing: antialiased; 11 | box-sizing: border-box; } 12 | 13 | h1 { 14 | font-size: 2rem; 15 | font-weight: 700; 16 | margin: 1.275em 0 0.6em; } 17 | 18 | h2 { 19 | font-size: 1.75rem; 20 | font-weight: 700; 21 | margin: 1.275em 0 0.3em; } 22 | 23 | h3 { 24 | font-size: 1.5rem; 25 | font-weight: 700; 26 | margin: 1em 0 0.3em; } 27 | 28 | h4 { 29 | font-size: 1.25rem; 30 | font-weight: 700; 31 | margin: 1.275em 0 0.85em; } 32 | 33 | h5 { 34 | font-size: 1rem; 35 | font-weight: 700; 36 | margin: 1.275em 0 0.85em; } 37 | 38 | h6 { 39 | font-size: 1rem; 40 | font-weight: 700; 41 | margin: 1.275em 0 0.85em; 42 | color: #777; } 43 | 44 | p { 45 | margin: 0 0 1em; } 46 | 47 | ul, ol { 48 | padding: 0 0 0 2em; 49 | margin: 0 0 0.85em; } 50 | 51 | blockquote { 52 | margin: 0 0 0.85em; 53 | padding: 0 15px; 54 | color: #858585; 55 | border-left: 4px solid #e5e5e5; } 56 | 57 | img { 58 | max-width: 100%; } 59 | 60 | a { 61 | color: #4183c4; 62 | text-decoration: none; } 63 | a:hover, a:focus { 64 | outline: 0; 65 | text-decoration: underline; } 66 | 67 | table { 68 | background: #fff; 69 | width: 100%; 70 | border-collapse: collapse; 71 | border-spacing: 0; 72 | overflow: auto; 73 | margin: 0 0 0.85em; } 74 | 75 | tr:nth-child(2n) { 76 | background-color: #fbfbfb; } 77 | 78 | th, td { 79 | padding: 6px 13px; 80 | border: 1px solid #ddd; } 81 | 82 | pre { 83 | margin: 0 0 1.275em; 84 | padding: .85em 1em; 85 | overflow: auto; 86 | background: #f7f7f7; 87 | font-size: .85em; 88 | font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; } 89 | 90 | code { 91 | font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; } 92 | 93 | p > code, li > code { 94 | background: #f7f7f7; 95 | padding: .2em; } 96 | p > code:before, p > code:after, li > code:before, li > code:after { 97 | letter-spacing: -.2em; 98 | content: "\00a0"; } 99 | 100 | pre code { 101 | padding: 0; 102 | white-space: pre; } 103 | 104 | .content-wrapper { 105 | display: flex; 106 | flex-direction: column; } 107 | @media (min-width: 768px) { 108 | .content-wrapper { 109 | flex-direction: row; } } 110 | 111 | .header { 112 | display: flex; 113 | padding: 8px; 114 | font-size: 0.875em; 115 | background: #444; 116 | color: #999; } 117 | 118 | .header-col { 119 | margin: 0; 120 | padding: 0 8px; } 121 | 122 | .header-col--primary { 123 | flex: 1; } 124 | 125 | .header-link { 126 | color: #fff; } 127 | 128 | .header-icon { 129 | padding-right: 6px; 130 | vertical-align: -4px; 131 | height: 16px; } 132 | 133 | .breadcrumbs { 134 | font-size: 0.875em; 135 | padding: 8px 16px; 136 | margin: 0; 137 | background: #fbfbfb; 138 | border-bottom: 1px solid #ddd; } 139 | 140 | .carat { 141 | height: 10px; 142 | margin: 0 5px; } 143 | 144 | .navigation { 145 | order: 2; } 146 | @media (min-width: 768px) { 147 | .navigation { 148 | order: 1; 149 | width: 25%; 150 | max-width: 300px; 151 | padding-bottom: 64px; 152 | overflow: hidden; 153 | word-wrap: normal; 154 | background: #fbfbfb; 155 | border-right: 1px solid #ddd; } } 156 | 157 | .nav-groups { 158 | list-style-type: none; 159 | padding-left: 0; } 160 | 161 | .nav-group-name { 162 | border-bottom: 1px solid #ddd; 163 | padding: 8px 0 8px 16px; } 164 | 165 | .nav-group-name-link { 166 | color: #333; } 167 | 168 | .nav-group-tasks { 169 | margin: 8px 0; 170 | padding: 0 0 0 8px; } 171 | 172 | .nav-group-task { 173 | font-size: 1em; 174 | list-style-type: none; 175 | white-space: nowrap; } 176 | 177 | .nav-group-task-link { 178 | color: #808080; } 179 | 180 | .main-content { 181 | order: 1; } 182 | @media (min-width: 768px) { 183 | .main-content { 184 | order: 2; 185 | flex: 1; 186 | padding-bottom: 60px; } } 187 | 188 | .section { 189 | padding: 0 32px; 190 | border-bottom: 1px solid #ddd; } 191 | 192 | .section-content { 193 | max-width: 834px; 194 | margin: 0 auto; 195 | padding: 16px 0; } 196 | 197 | .section-name { 198 | color: #666; 199 | display: block; } 200 | 201 | .declaration .highlight { 202 | overflow-x: initial; 203 | padding: 8px 0; 204 | margin: 0; 205 | background-color: transparent; 206 | border: none; } 207 | 208 | .task-group-section { 209 | border-top: 1px solid #ddd; } 210 | 211 | .task-group { 212 | padding-top: 0px; } 213 | 214 | .task-name-container a[name]:before { 215 | content: ""; 216 | display: block; } 217 | 218 | .item-container { 219 | padding: 0; } 220 | 221 | .item { 222 | padding-top: 8px; 223 | width: 100%; 224 | list-style-type: none; } 225 | .item a[name]:before { 226 | content: ""; 227 | display: block; } 228 | .item .token { 229 | padding-left: 3px; 230 | margin-left: 0px; 231 | font-size: 1rem; } 232 | .item .declaration-note { 233 | font-size: .85em; 234 | color: #808080; 235 | font-style: italic; } 236 | 237 | .pointer-container { 238 | border-bottom: 1px solid #ddd; 239 | left: -23px; 240 | padding-bottom: 13px; 241 | position: relative; 242 | width: 110%; } 243 | 244 | .pointer { 245 | left: 21px; 246 | top: 7px; 247 | display: block; 248 | position: absolute; 249 | width: 12px; 250 | height: 12px; 251 | border-left: 1px solid #ddd; 252 | border-top: 1px solid #ddd; 253 | background: #fff; 254 | transform: rotate(45deg); } 255 | 256 | .height-container { 257 | display: none; 258 | position: relative; 259 | width: 100%; 260 | overflow: hidden; } 261 | .height-container .section { 262 | background: #fff; 263 | border: 1px solid #ddd; 264 | border-top-width: 0; 265 | padding-top: 10px; 266 | padding-bottom: 5px; 267 | padding: 8px 16px; } 268 | 269 | .aside, .language { 270 | padding: 6px 12px; 271 | margin: 12px 0; 272 | border-left: 5px solid #dddddd; 273 | overflow-y: hidden; } 274 | .aside .aside-title, .language .aside-title { 275 | font-size: 9px; 276 | letter-spacing: 2px; 277 | text-transform: uppercase; 278 | padding-bottom: 0; 279 | margin: 0; 280 | color: #aaa; 281 | -webkit-user-select: none; } 282 | .aside p:last-child, .language p:last-child { 283 | margin-bottom: 0; } 284 | 285 | .language { 286 | border-left: 5px solid #cde9f4; } 287 | .language .aside-title { 288 | color: #4183c4; } 289 | 290 | .aside-warning { 291 | border-left: 5px solid #ff6666; } 292 | .aside-warning .aside-title { 293 | color: #ff0000; } 294 | 295 | .graybox { 296 | border-collapse: collapse; 297 | width: 100%; } 298 | .graybox p { 299 | margin: 0; 300 | word-break: break-word; 301 | min-width: 50px; } 302 | .graybox td { 303 | border: 1px solid #ddd; 304 | padding: 5px 25px 5px 10px; 305 | vertical-align: middle; } 306 | .graybox tr td:first-of-type { 307 | text-align: right; 308 | padding: 7px; 309 | vertical-align: top; 310 | word-break: normal; 311 | width: 40px; } 312 | 313 | .slightly-smaller { 314 | font-size: 0.9em; } 315 | 316 | .footer { 317 | padding: 8px 16px; 318 | background: #444; 319 | color: #ddd; 320 | font-size: 0.8em; } 321 | .footer p { 322 | margin: 8px 0; } 323 | .footer a { 324 | color: #fff; } 325 | 326 | html.dash .header, html.dash .breadcrumbs, html.dash .navigation { 327 | display: none; } 328 | html.dash .height-container { 329 | display: block; } 330 | -------------------------------------------------------------------------------- /docs/docsets/PutioKit.docset/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleIdentifier 6 | com.jazzy.putiokit 7 | CFBundleName 8 | PutioKit 9 | DocSetPlatformFamily 10 | putiokit 11 | isDashDocset 12 | 13 | dashIndexFilePath 14 | index.html 15 | isJavaScriptEnabled 16 | 17 | DashDocSetFamily 18 | dashtoc 19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/docsets/PutioKit.docset/Contents/Resources/Documents/Classes/Friend.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Friend Class Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |

20 | 21 | PutioKit Docs 22 | 23 | (100% documented) 24 |

25 | 26 | 27 |
28 | 29 | 34 | 35 |
36 | 100 |
101 | 102 |
103 |
104 |

Friend

105 |
106 |
107 |
open class Friend: NSObject
108 | 109 |
110 |
111 |

Represents a friend of the logged in user.

112 | 113 |
114 |
115 | 116 |
117 |
118 |
119 |
    120 |
  • 121 |
    122 | 123 | 124 | 125 | username 126 | 127 |
    128 |
    129 |
    130 |
    131 |
    132 |
    133 |

    The username of the friend

    134 | 135 |
    136 |
    137 |

    Declaration

    138 |
    139 |

    Swift

    140 |
    open dynamic var username = ""
    141 | 142 |
    143 |
    144 |
    145 |
    146 |
  • 147 |
  • 148 |
    149 | 150 | 151 | 152 | avatar 153 | 154 |
    155 |
    156 |
    157 |
    158 |
    159 |
    160 |

    URL of the user’s avatar

    161 | 162 |
    163 |
    164 |

    Declaration

    165 |
    166 |

    Swift

    167 |
    open dynamic var avatar = ""
    168 | 169 |
    170 |
    171 |
    172 |
    173 |
  • 174 |
  • 175 |
    176 | 177 | 178 | 179 | shareId 180 | 181 |
    182 |
    183 |
    184 |
    185 |
    186 |
    187 |

    The ID that can be used for unsharing a file

    188 | 189 |
    190 |
    191 |

    Declaration

    192 |
    193 |

    Swift

    194 |
    open dynamic var shareId = 0
    195 | 196 |
    197 |
    198 |
    199 |
    200 |
  • 201 |
202 |
203 |
204 |
205 | 206 |
207 |
208 | 212 | 213 | 214 | 215 | -------------------------------------------------------------------------------- /docs/docsets/PutioKit.docset/Contents/Resources/Documents/Enums/PutioError.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | PutioError Enum Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |

20 | 21 | PutioKit Docs 22 | 23 | (100% documented) 24 |

25 | 26 | 27 |
28 | 29 | 34 | 35 |
36 | 100 |
101 | 102 |
103 |
104 |

PutioError

105 |
106 |
107 |
public enum PutioError: Error
108 | 109 |
110 |
111 |

Represents errors that can occur when accessing the Put.io API

112 | 113 |
    114 |
  • couldNotParseJSON: There was an error parsing the JSON from the API
  • 115 |
  • noAccessToken: An access token was not provided so this endpoint could not be called
  • 116 |
  • invalidStatusCode: The expected status code was not returned
  • 117 |
118 | 119 |
120 |
121 | 122 |
123 |
124 |
125 |
    126 |
  • 127 |
    128 | 129 | 130 | 131 | couldNotParseJSON 132 | 133 |
    134 |
    135 |
    136 |
    137 |
    138 |
    139 |

    There was an error parsing the JSON from the API

    140 | 141 |
    142 |
    143 |

    Declaration

    144 |
    145 |

    Swift

    146 |
    case couldNotParseJSON
    147 | 148 |
    149 |
    150 |
    151 |
    152 |
  • 153 |
154 |
155 |
156 |
    157 |
  • 158 |
    159 | 160 | 161 | 162 | noAccessToken 163 | 164 |
    165 |
    166 |
    167 |
    168 |
    169 |
    170 |

    An access token was not provided so this endpoint could not be called

    171 | 172 |
    173 |
    174 |

    Declaration

    175 |
    176 |

    Swift

    177 |
    case noAccessToken
    178 | 179 |
    180 |
    181 |
    182 |
    183 |
  • 184 |
185 |
186 |
187 |
    188 |
  • 189 |
    190 | 191 | 192 | 193 | invalidStatusCode 194 | 195 |
    196 |
    197 |
    198 |
    199 |
    200 |
    201 |

    The expected status code was not returned

    202 | 203 |
    204 |
    205 |

    Declaration

    206 |
    207 |

    Swift

    208 |
    case invalidStatusCode
    209 | 210 |
    211 |
    212 |
    213 |
    214 |
  • 215 |
216 |
217 |
218 |
219 | 220 |
221 |
222 | 226 | 227 | 228 | 229 | -------------------------------------------------------------------------------- /docs/docsets/PutioKit.docset/Contents/Resources/Documents/Enums/SubtitleFormat.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SubtitleFormat Enum Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |

20 | 21 | PutioKit Docs 22 | 23 | (100% documented) 24 |

25 | 26 | 27 |
28 | 29 | 34 | 35 |
36 | 100 |
101 | 102 |
103 |
104 |

SubtitleFormat

105 |
106 |
107 |
public enum SubtitleFormat: String
108 | 109 |
110 |
111 |

The file format of subtitle.

112 | 113 |
    114 |
  • srt: Default. SRT file format.
  • 115 |
  • webvtt: webVTT file format used by things like Chromecast.
  • 116 |
117 | 118 |
119 |
120 | 121 |
122 |
123 |
124 |
    125 |
  • 126 |
    127 | 128 | 129 | 130 | srt 131 | 132 |
    133 |
    134 |
    135 |
    136 |
    137 |
    138 |

    The default subtitle format used by Put.io.

    139 | 140 |
    141 |
    142 |

    Declaration

    143 |
    144 |

    Swift

    145 |
    case srt = "srt"
    146 | 147 |
    148 |
    149 |
    150 |
    151 |
  • 152 |
153 |
154 |
155 |
    156 |
  • 157 |
    158 | 159 | 160 | 161 | webvtt 162 | 163 |
    164 |
    165 |
    166 |
    167 |
    168 |
    169 |

    An alternative format available if required. Things like Chromecast require WebVTT.

    170 | 171 |
    172 |
    173 |

    Declaration

    174 |
    175 |

    Swift

    176 |
    case webvtt = "webvtt"
    177 | 178 |
    179 |
    180 |
    181 |
    182 |
  • 183 |
184 |
185 |
186 |
187 | 188 |
189 |
190 | 194 | 195 | 196 | 197 | -------------------------------------------------------------------------------- /docs/docsets/PutioKit.docset/Contents/Resources/Documents/Enums/SubtitleSource.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SubtitleSource Enum Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |

20 | 21 | PutioKit Docs 22 | 23 | (100% documented) 24 |

25 | 26 | 27 |
28 | 29 | 34 | 35 |
36 | 100 |
101 | 102 |
103 |
104 |

SubtitleSource

105 |
106 |
107 |
public enum SubtitleSource
108 | 109 |
110 |
111 |

Where the subtitle was obtained from

112 | 113 |
    114 |
  • folder: An SRT file with an identical name as the video
  • 115 |
  • mkv: Subtitles are extracted from an MKV file
  • 116 |
  • opensubtitles: The sutitles were fetched from OpenSubtitles
  • 117 |
118 | 119 |
120 |
121 | 122 |
123 |
124 |
125 |
    126 |
  • 127 |
    128 | 129 | 130 | 131 | folder 132 | 133 |
    134 |
    135 |
    136 |
    137 |
    138 |
    139 |

    An SRT file with an identical name as the video

    140 | 141 |
    142 |
    143 |

    Declaration

    144 |
    145 |

    Swift

    146 |
    case folder
    147 | 148 |
    149 |
    150 |
    151 |
    152 |
  • 153 |
154 |
155 |
156 |
    157 |
  • 158 |
    159 | 160 | 161 | 162 | mkv 163 | 164 |
    165 |
    166 |
    167 |
    168 |
    169 |
    170 |

    Subtitles are extracted from an MKV file

    171 | 172 |
    173 |
    174 |

    Declaration

    175 |
    176 |

    Swift

    177 |
    case mkv
    178 | 179 |
    180 |
    181 |
    182 |
    183 |
  • 184 |
185 |
186 |
187 |
    188 |
  • 189 |
    190 | 191 | 192 | 193 | opensubtitles 194 | 195 |
    196 |
    197 |
    198 |
    199 |
    200 |
    201 |

    The sutitles were fetched from OpenSubtitles

    202 | 203 |
    204 |
    205 |

    Declaration

    206 |
    207 |

    Swift

    208 |
    case opensubtitles
    209 | 210 |
    211 |
    212 |
    213 |
    214 |
  • 215 |
216 |
217 |
218 |
219 | 220 |
221 |
222 | 226 | 227 | 228 | 229 | -------------------------------------------------------------------------------- /docs/docsets/PutioKit.docset/Contents/Resources/Documents/Enums/TransferStatus.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | TransferStatus Enum Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |

20 | 21 | PutioKit Docs 22 | 23 | (100% documented) 24 |

25 | 26 | 27 |
28 | 29 | 34 | 35 |
36 | 100 |
101 | 102 |
103 |
104 |

TransferStatus

105 |
106 |
107 |
public enum TransferStatus
108 | 109 |
110 |
111 |

The current status of a transfer

112 | 113 |
    114 |
  • downloading: The transfer is currently in progress
  • 115 |
  • inQueue: The transfer is queued and will be started shortly
  • 116 |
  • completed: The transfer has completed
  • 117 |
  • cancelled: The transfer was manually cancelled
  • 118 |
119 | 120 |
121 |
122 | 123 |
124 |
125 |
126 |
    127 |
  • 128 |
    129 | 130 | 131 | 132 | downloading 133 | 134 |
    135 |
    136 |
    137 |
    138 |
    139 |
    140 |

    The transfer is currently in progress

    141 | 142 |
    143 |
    144 |

    Declaration

    145 |
    146 |

    Swift

    147 |
    case downloading
    148 | 149 |
    150 |
    151 |
    152 |
    153 |
  • 154 |
155 |
156 |
157 |
    158 |
  • 159 |
    160 | 161 | 162 | 163 | inQueue 164 | 165 |
    166 |
    167 |
    168 |
    169 |
    170 |
    171 |

    The transfer is queued and will be started shortly

    172 | 173 |
    174 |
    175 |

    Declaration

    176 |
    177 |

    Swift

    178 |
    case inQueue
    179 | 180 |
    181 |
    182 |
    183 |
    184 |
  • 185 |
186 |
187 |
188 |
    189 |
  • 190 |
    191 | 192 | 193 | 194 | completed 195 | 196 |
    197 |
    198 |
    199 |
    200 |
    201 |
    202 |

    The transfer has completed

    203 | 204 |
    205 |
    206 |

    Declaration

    207 |
    208 |

    Swift

    209 |
    case completed
    210 | 211 |
    212 |
    213 |
    214 |
    215 |
  • 216 |
217 |
218 |
219 |
    220 |
  • 221 |
    222 | 223 | 224 | 225 | cancelled 226 | 227 |
    228 |
    229 |
    230 |
    231 |
    232 |
    233 |

    The transfer was manually cancelled

    234 | 235 |
    236 |
    237 |

    Declaration

    238 |
    239 |

    Swift

    240 |
    case cancelled
    241 | 242 |
    243 |
    244 |
    245 |
    246 |
  • 247 |
248 |
249 |
250 |
251 | 252 |
253 |
254 | 258 | 259 | 260 | 261 | -------------------------------------------------------------------------------- /docs/docsets/PutioKit.docset/Contents/Resources/Documents/Structs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Structs Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 |

19 | 20 | PutioKit Docs 21 | 22 | (100% documented) 23 |

24 | 25 | 26 |
27 | 28 | 33 | 34 |
35 | 99 |
100 | 101 |
102 |
103 |

Structs

104 |

The following structs are available globally.

105 | 106 |
107 |
108 | 109 |
110 |
111 |
112 |
    113 |
  • 114 |
    115 | 116 | 117 | 118 | DiskInfo 119 | 120 |
    121 |
    122 |
    123 |
    124 |
    125 |
    126 |

    Information about the disk usage on Put.io

    127 | 128 | See more 129 |
    130 |
    131 |

    Declaration

    132 |
    133 |

    Swift

    134 |
    public struct DiskInfo
    135 | 136 |
    137 |
    138 |
    139 |
    140 |
  • 141 |
142 |
143 |
144 |
145 | 146 |
147 |
148 | 152 | 153 | 154 | 155 | -------------------------------------------------------------------------------- /docs/docsets/PutioKit.docset/Contents/Resources/Documents/Structs/DiskInfo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | DiskInfo Struct Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |

20 | 21 | PutioKit Docs 22 | 23 | (100% documented) 24 |

25 | 26 | 27 |
28 | 29 | 34 | 35 |
36 | 100 |
101 | 102 |
103 |
104 |

DiskInfo

105 |
106 |
107 |
public struct DiskInfo
108 | 109 |
110 |
111 |

Information about the disk usage on Put.io

112 | 113 |
114 |
115 | 116 |
117 |
118 |
119 |
    120 |
  • 121 |
    122 | 123 | 124 | 125 | available 126 | 127 |
    128 |
    129 |
    130 |
    131 |
    132 |
    133 |

    The available disk space

    134 | 135 |
    136 |
    137 |

    Declaration

    138 |
    139 |

    Swift

    140 |
    public let available: Int
    141 | 142 |
    143 |
    144 |
    145 |
    146 |
  • 147 |
  • 148 |
    149 | 150 | 151 | 152 | used 153 | 154 |
    155 |
    156 |
    157 |
    158 |
    159 |
    160 |

    The amount of space used on the disk

    161 | 162 |
    163 |
    164 |

    Declaration

    165 |
    166 |

    Swift

    167 |
    public let used: Int
    168 | 169 |
    170 |
    171 |
    172 |
    173 |
  • 174 |
  • 175 |
    176 | 177 | 178 | 179 | size 180 | 181 |
    182 |
    183 |
    184 |
    185 |
    186 |
    187 |

    The total size of the disk

    188 | 189 |
    190 |
    191 |

    Declaration

    192 |
    193 |

    Swift

    194 |
    public let size: Int
    195 | 196 |
    197 |
    198 |
    199 |
    200 |
  • 201 |
202 |
203 |
204 |
205 | 206 |
207 |
208 | 212 | 213 | 214 | 215 | -------------------------------------------------------------------------------- /docs/docsets/PutioKit.docset/Contents/Resources/Documents/css/highlight.css: -------------------------------------------------------------------------------- 1 | /* Credit to https://gist.github.com/wataru420/2048287 */ 2 | .highlight { 3 | /* Comment */ 4 | /* Error */ 5 | /* Keyword */ 6 | /* Operator */ 7 | /* Comment.Multiline */ 8 | /* Comment.Preproc */ 9 | /* Comment.Single */ 10 | /* Comment.Special */ 11 | /* Generic.Deleted */ 12 | /* Generic.Deleted.Specific */ 13 | /* Generic.Emph */ 14 | /* Generic.Error */ 15 | /* Generic.Heading */ 16 | /* Generic.Inserted */ 17 | /* Generic.Inserted.Specific */ 18 | /* Generic.Output */ 19 | /* Generic.Prompt */ 20 | /* Generic.Strong */ 21 | /* Generic.Subheading */ 22 | /* Generic.Traceback */ 23 | /* Keyword.Constant */ 24 | /* Keyword.Declaration */ 25 | /* Keyword.Pseudo */ 26 | /* Keyword.Reserved */ 27 | /* Keyword.Type */ 28 | /* Literal.Number */ 29 | /* Literal.String */ 30 | /* Name.Attribute */ 31 | /* Name.Builtin */ 32 | /* Name.Class */ 33 | /* Name.Constant */ 34 | /* Name.Entity */ 35 | /* Name.Exception */ 36 | /* Name.Function */ 37 | /* Name.Namespace */ 38 | /* Name.Tag */ 39 | /* Name.Variable */ 40 | /* Operator.Word */ 41 | /* Text.Whitespace */ 42 | /* Literal.Number.Float */ 43 | /* Literal.Number.Hex */ 44 | /* Literal.Number.Integer */ 45 | /* Literal.Number.Oct */ 46 | /* Literal.String.Backtick */ 47 | /* Literal.String.Char */ 48 | /* Literal.String.Doc */ 49 | /* Literal.String.Double */ 50 | /* Literal.String.Escape */ 51 | /* Literal.String.Heredoc */ 52 | /* Literal.String.Interpol */ 53 | /* Literal.String.Other */ 54 | /* Literal.String.Regex */ 55 | /* Literal.String.Single */ 56 | /* Literal.String.Symbol */ 57 | /* Name.Builtin.Pseudo */ 58 | /* Name.Variable.Class */ 59 | /* Name.Variable.Global */ 60 | /* Name.Variable.Instance */ 61 | /* Literal.Number.Integer.Long */ } 62 | .highlight .c { 63 | color: #999988; 64 | font-style: italic; } 65 | .highlight .err { 66 | color: #a61717; 67 | background-color: #e3d2d2; } 68 | .highlight .k { 69 | color: #000000; 70 | font-weight: bold; } 71 | .highlight .o { 72 | color: #000000; 73 | font-weight: bold; } 74 | .highlight .cm { 75 | color: #999988; 76 | font-style: italic; } 77 | .highlight .cp { 78 | color: #999999; 79 | font-weight: bold; } 80 | .highlight .c1 { 81 | color: #999988; 82 | font-style: italic; } 83 | .highlight .cs { 84 | color: #999999; 85 | font-weight: bold; 86 | font-style: italic; } 87 | .highlight .gd { 88 | color: #000000; 89 | background-color: #ffdddd; } 90 | .highlight .gd .x { 91 | color: #000000; 92 | background-color: #ffaaaa; } 93 | .highlight .ge { 94 | color: #000000; 95 | font-style: italic; } 96 | .highlight .gr { 97 | color: #aa0000; } 98 | .highlight .gh { 99 | color: #999999; } 100 | .highlight .gi { 101 | color: #000000; 102 | background-color: #ddffdd; } 103 | .highlight .gi .x { 104 | color: #000000; 105 | background-color: #aaffaa; } 106 | .highlight .go { 107 | color: #888888; } 108 | .highlight .gp { 109 | color: #555555; } 110 | .highlight .gs { 111 | font-weight: bold; } 112 | .highlight .gu { 113 | color: #aaaaaa; } 114 | .highlight .gt { 115 | color: #aa0000; } 116 | .highlight .kc { 117 | color: #000000; 118 | font-weight: bold; } 119 | .highlight .kd { 120 | color: #000000; 121 | font-weight: bold; } 122 | .highlight .kp { 123 | color: #000000; 124 | font-weight: bold; } 125 | .highlight .kr { 126 | color: #000000; 127 | font-weight: bold; } 128 | .highlight .kt { 129 | color: #445588; } 130 | .highlight .m { 131 | color: #009999; } 132 | .highlight .s { 133 | color: #d14; } 134 | .highlight .na { 135 | color: #008080; } 136 | .highlight .nb { 137 | color: #0086B3; } 138 | .highlight .nc { 139 | color: #445588; 140 | font-weight: bold; } 141 | .highlight .no { 142 | color: #008080; } 143 | .highlight .ni { 144 | color: #800080; } 145 | .highlight .ne { 146 | color: #990000; 147 | font-weight: bold; } 148 | .highlight .nf { 149 | color: #990000; } 150 | .highlight .nn { 151 | color: #555555; } 152 | .highlight .nt { 153 | color: #000080; } 154 | .highlight .nv { 155 | color: #008080; } 156 | .highlight .ow { 157 | color: #000000; 158 | font-weight: bold; } 159 | .highlight .w { 160 | color: #bbbbbb; } 161 | .highlight .mf { 162 | color: #009999; } 163 | .highlight .mh { 164 | color: #009999; } 165 | .highlight .mi { 166 | color: #009999; } 167 | .highlight .mo { 168 | color: #009999; } 169 | .highlight .sb { 170 | color: #d14; } 171 | .highlight .sc { 172 | color: #d14; } 173 | .highlight .sd { 174 | color: #d14; } 175 | .highlight .s2 { 176 | color: #d14; } 177 | .highlight .se { 178 | color: #d14; } 179 | .highlight .sh { 180 | color: #d14; } 181 | .highlight .si { 182 | color: #d14; } 183 | .highlight .sx { 184 | color: #d14; } 185 | .highlight .sr { 186 | color: #009926; } 187 | .highlight .s1 { 188 | color: #d14; } 189 | .highlight .ss { 190 | color: #990073; } 191 | .highlight .bp { 192 | color: #999999; } 193 | .highlight .vc { 194 | color: #008080; } 195 | .highlight .vg { 196 | color: #008080; } 197 | .highlight .vi { 198 | color: #008080; } 199 | .highlight .il { 200 | color: #009999; } 201 | -------------------------------------------------------------------------------- /docs/docsets/PutioKit.docset/Contents/Resources/Documents/css/jazzy.css: -------------------------------------------------------------------------------- 1 | *, *:before, *:after { 2 | box-sizing: inherit; } 3 | 4 | body { 5 | margin: 0; 6 | background: #fff; 7 | color: #333; 8 | font: 16px/1.7 "Helvetica Neue", Helvetica, Arial, sans-serif; 9 | letter-spacing: .2px; 10 | -webkit-font-smoothing: antialiased; 11 | box-sizing: border-box; } 12 | 13 | h1 { 14 | font-size: 2rem; 15 | font-weight: 700; 16 | margin: 1.275em 0 0.6em; } 17 | 18 | h2 { 19 | font-size: 1.75rem; 20 | font-weight: 700; 21 | margin: 1.275em 0 0.3em; } 22 | 23 | h3 { 24 | font-size: 1.5rem; 25 | font-weight: 700; 26 | margin: 1em 0 0.3em; } 27 | 28 | h4 { 29 | font-size: 1.25rem; 30 | font-weight: 700; 31 | margin: 1.275em 0 0.85em; } 32 | 33 | h5 { 34 | font-size: 1rem; 35 | font-weight: 700; 36 | margin: 1.275em 0 0.85em; } 37 | 38 | h6 { 39 | font-size: 1rem; 40 | font-weight: 700; 41 | margin: 1.275em 0 0.85em; 42 | color: #777; } 43 | 44 | p { 45 | margin: 0 0 1em; } 46 | 47 | ul, ol { 48 | padding: 0 0 0 2em; 49 | margin: 0 0 0.85em; } 50 | 51 | blockquote { 52 | margin: 0 0 0.85em; 53 | padding: 0 15px; 54 | color: #858585; 55 | border-left: 4px solid #e5e5e5; } 56 | 57 | img { 58 | max-width: 100%; } 59 | 60 | a { 61 | color: #4183c4; 62 | text-decoration: none; } 63 | a:hover, a:focus { 64 | outline: 0; 65 | text-decoration: underline; } 66 | 67 | table { 68 | background: #fff; 69 | width: 100%; 70 | border-collapse: collapse; 71 | border-spacing: 0; 72 | overflow: auto; 73 | margin: 0 0 0.85em; } 74 | 75 | tr:nth-child(2n) { 76 | background-color: #fbfbfb; } 77 | 78 | th, td { 79 | padding: 6px 13px; 80 | border: 1px solid #ddd; } 81 | 82 | pre { 83 | margin: 0 0 1.275em; 84 | padding: .85em 1em; 85 | overflow: auto; 86 | background: #f7f7f7; 87 | font-size: .85em; 88 | font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; } 89 | 90 | code { 91 | font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; } 92 | 93 | p > code, li > code { 94 | background: #f7f7f7; 95 | padding: .2em; } 96 | p > code:before, p > code:after, li > code:before, li > code:after { 97 | letter-spacing: -.2em; 98 | content: "\00a0"; } 99 | 100 | pre code { 101 | padding: 0; 102 | white-space: pre; } 103 | 104 | .content-wrapper { 105 | display: flex; 106 | flex-direction: column; } 107 | @media (min-width: 768px) { 108 | .content-wrapper { 109 | flex-direction: row; } } 110 | 111 | .header { 112 | display: flex; 113 | padding: 8px; 114 | font-size: 0.875em; 115 | background: #444; 116 | color: #999; } 117 | 118 | .header-col { 119 | margin: 0; 120 | padding: 0 8px; } 121 | 122 | .header-col--primary { 123 | flex: 1; } 124 | 125 | .header-link { 126 | color: #fff; } 127 | 128 | .header-icon { 129 | padding-right: 6px; 130 | vertical-align: -4px; 131 | height: 16px; } 132 | 133 | .breadcrumbs { 134 | font-size: 0.875em; 135 | padding: 8px 16px; 136 | margin: 0; 137 | background: #fbfbfb; 138 | border-bottom: 1px solid #ddd; } 139 | 140 | .carat { 141 | height: 10px; 142 | margin: 0 5px; } 143 | 144 | .navigation { 145 | order: 2; } 146 | @media (min-width: 768px) { 147 | .navigation { 148 | order: 1; 149 | width: 25%; 150 | max-width: 300px; 151 | padding-bottom: 64px; 152 | overflow: hidden; 153 | word-wrap: normal; 154 | background: #fbfbfb; 155 | border-right: 1px solid #ddd; } } 156 | 157 | .nav-groups { 158 | list-style-type: none; 159 | padding-left: 0; } 160 | 161 | .nav-group-name { 162 | border-bottom: 1px solid #ddd; 163 | padding: 8px 0 8px 16px; } 164 | 165 | .nav-group-name-link { 166 | color: #333; } 167 | 168 | .nav-group-tasks { 169 | margin: 8px 0; 170 | padding: 0 0 0 8px; } 171 | 172 | .nav-group-task { 173 | font-size: 1em; 174 | list-style-type: none; 175 | white-space: nowrap; } 176 | 177 | .nav-group-task-link { 178 | color: #808080; } 179 | 180 | .main-content { 181 | order: 1; } 182 | @media (min-width: 768px) { 183 | .main-content { 184 | order: 2; 185 | flex: 1; 186 | padding-bottom: 60px; } } 187 | 188 | .section { 189 | padding: 0 32px; 190 | border-bottom: 1px solid #ddd; } 191 | 192 | .section-content { 193 | max-width: 834px; 194 | margin: 0 auto; 195 | padding: 16px 0; } 196 | 197 | .section-name { 198 | color: #666; 199 | display: block; } 200 | 201 | .declaration .highlight { 202 | overflow-x: initial; 203 | padding: 8px 0; 204 | margin: 0; 205 | background-color: transparent; 206 | border: none; } 207 | 208 | .task-group-section { 209 | border-top: 1px solid #ddd; } 210 | 211 | .task-group { 212 | padding-top: 0px; } 213 | 214 | .task-name-container a[name]:before { 215 | content: ""; 216 | display: block; } 217 | 218 | .item-container { 219 | padding: 0; } 220 | 221 | .item { 222 | padding-top: 8px; 223 | width: 100%; 224 | list-style-type: none; } 225 | .item a[name]:before { 226 | content: ""; 227 | display: block; } 228 | .item .token { 229 | padding-left: 3px; 230 | margin-left: 0px; 231 | font-size: 1rem; } 232 | .item .declaration-note { 233 | font-size: .85em; 234 | color: #808080; 235 | font-style: italic; } 236 | 237 | .pointer-container { 238 | border-bottom: 1px solid #ddd; 239 | left: -23px; 240 | padding-bottom: 13px; 241 | position: relative; 242 | width: 110%; } 243 | 244 | .pointer { 245 | left: 21px; 246 | top: 7px; 247 | display: block; 248 | position: absolute; 249 | width: 12px; 250 | height: 12px; 251 | border-left: 1px solid #ddd; 252 | border-top: 1px solid #ddd; 253 | background: #fff; 254 | transform: rotate(45deg); } 255 | 256 | .height-container { 257 | display: none; 258 | position: relative; 259 | width: 100%; 260 | overflow: hidden; } 261 | .height-container .section { 262 | background: #fff; 263 | border: 1px solid #ddd; 264 | border-top-width: 0; 265 | padding-top: 10px; 266 | padding-bottom: 5px; 267 | padding: 8px 16px; } 268 | 269 | .aside, .language { 270 | padding: 6px 12px; 271 | margin: 12px 0; 272 | border-left: 5px solid #dddddd; 273 | overflow-y: hidden; } 274 | .aside .aside-title, .language .aside-title { 275 | font-size: 9px; 276 | letter-spacing: 2px; 277 | text-transform: uppercase; 278 | padding-bottom: 0; 279 | margin: 0; 280 | color: #aaa; 281 | -webkit-user-select: none; } 282 | .aside p:last-child, .language p:last-child { 283 | margin-bottom: 0; } 284 | 285 | .language { 286 | border-left: 5px solid #cde9f4; } 287 | .language .aside-title { 288 | color: #4183c4; } 289 | 290 | .aside-warning { 291 | border-left: 5px solid #ff6666; } 292 | .aside-warning .aside-title { 293 | color: #ff0000; } 294 | 295 | .graybox { 296 | border-collapse: collapse; 297 | width: 100%; } 298 | .graybox p { 299 | margin: 0; 300 | word-break: break-word; 301 | min-width: 50px; } 302 | .graybox td { 303 | border: 1px solid #ddd; 304 | padding: 5px 25px 5px 10px; 305 | vertical-align: middle; } 306 | .graybox tr td:first-of-type { 307 | text-align: right; 308 | padding: 7px; 309 | vertical-align: top; 310 | word-break: normal; 311 | width: 40px; } 312 | 313 | .slightly-smaller { 314 | font-size: 0.9em; } 315 | 316 | .footer { 317 | padding: 8px 16px; 318 | background: #444; 319 | color: #ddd; 320 | font-size: 0.8em; } 321 | .footer p { 322 | margin: 8px 0; } 323 | .footer a { 324 | color: #fff; } 325 | 326 | html.dash .header, html.dash .breadcrumbs, html.dash .navigation { 327 | display: none; } 328 | html.dash .height-container { 329 | display: block; } 330 | -------------------------------------------------------------------------------- /docs/docsets/PutioKit.docset/Contents/Resources/Documents/img/carat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TryFetch/PutioKit/2a46201238e3e5bb2505bd55ed84ffe793f0bbdd/docs/docsets/PutioKit.docset/Contents/Resources/Documents/img/carat.png -------------------------------------------------------------------------------- /docs/docsets/PutioKit.docset/Contents/Resources/Documents/img/dash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TryFetch/PutioKit/2a46201238e3e5bb2505bd55ed84ffe793f0bbdd/docs/docsets/PutioKit.docset/Contents/Resources/Documents/img/dash.png -------------------------------------------------------------------------------- /docs/docsets/PutioKit.docset/Contents/Resources/Documents/img/gh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TryFetch/PutioKit/2a46201238e3e5bb2505bd55ed84ffe793f0bbdd/docs/docsets/PutioKit.docset/Contents/Resources/Documents/img/gh.png -------------------------------------------------------------------------------- /docs/docsets/PutioKit.docset/Contents/Resources/Documents/js/jazzy.js: -------------------------------------------------------------------------------- 1 | window.jazzy = {'docset': false} 2 | if (typeof window.dash != 'undefined') { 3 | document.documentElement.className += ' dash' 4 | window.jazzy.docset = true 5 | } 6 | if (navigator.userAgent.match(/xcode/i)) { 7 | document.documentElement.className += ' xcode' 8 | window.jazzy.docset = true 9 | } 10 | 11 | // On doc load, toggle the URL hash discussion if present 12 | $(document).ready(function() { 13 | if (!window.jazzy.docset) { 14 | var linkToHash = $('a[href="' + window.location.hash +'"]'); 15 | linkToHash.trigger("click"); 16 | } 17 | }); 18 | 19 | // On token click, toggle its discussion and animate token.marginLeft 20 | $(".token").click(function(event) { 21 | if (window.jazzy.docset) { 22 | return; 23 | } 24 | var link = $(this); 25 | var animationDuration = 300; 26 | $content = link.parent().parent().next(); 27 | $content.slideToggle(animationDuration); 28 | 29 | // Keeps the document from jumping to the hash. 30 | var href = $(this).attr('href'); 31 | if (history.pushState) { 32 | history.pushState({}, '', href); 33 | } else { 34 | location.hash = href; 35 | } 36 | event.preventDefault(); 37 | }); 38 | -------------------------------------------------------------------------------- /docs/docsets/PutioKit.docset/Contents/Resources/Documents/undocumented.json: -------------------------------------------------------------------------------- 1 | { 2 | "warnings": [ 3 | 4 | ], 5 | "source_directory": "/Users/steve228uk/Apps/PutioKit" 6 | } -------------------------------------------------------------------------------- /docs/docsets/PutioKit.docset/Contents/Resources/docSet.dsidx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TryFetch/PutioKit/2a46201238e3e5bb2505bd55ed84ffe793f0bbdd/docs/docsets/PutioKit.docset/Contents/Resources/docSet.dsidx -------------------------------------------------------------------------------- /docs/docsets/PutioKit.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TryFetch/PutioKit/2a46201238e3e5bb2505bd55ed84ffe793f0bbdd/docs/docsets/PutioKit.tgz -------------------------------------------------------------------------------- /docs/img/carat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TryFetch/PutioKit/2a46201238e3e5bb2505bd55ed84ffe793f0bbdd/docs/img/carat.png -------------------------------------------------------------------------------- /docs/img/dash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TryFetch/PutioKit/2a46201238e3e5bb2505bd55ed84ffe793f0bbdd/docs/img/dash.png -------------------------------------------------------------------------------- /docs/img/gh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TryFetch/PutioKit/2a46201238e3e5bb2505bd55ed84ffe793f0bbdd/docs/img/gh.png -------------------------------------------------------------------------------- /docs/js/jazzy.js: -------------------------------------------------------------------------------- 1 | window.jazzy = {'docset': false} 2 | if (typeof window.dash != 'undefined') { 3 | document.documentElement.className += ' dash' 4 | window.jazzy.docset = true 5 | } 6 | if (navigator.userAgent.match(/xcode/i)) { 7 | document.documentElement.className += ' xcode' 8 | window.jazzy.docset = true 9 | } 10 | 11 | // On doc load, toggle the URL hash discussion if present 12 | $(document).ready(function() { 13 | if (!window.jazzy.docset) { 14 | var linkToHash = $('a[href="' + window.location.hash +'"]'); 15 | linkToHash.trigger("click"); 16 | } 17 | }); 18 | 19 | // On token click, toggle its discussion and animate token.marginLeft 20 | $(".token").click(function(event) { 21 | if (window.jazzy.docset) { 22 | return; 23 | } 24 | var link = $(this); 25 | var animationDuration = 300; 26 | $content = link.parent().parent().next(); 27 | $content.slideToggle(animationDuration); 28 | 29 | // Keeps the document from jumping to the hash. 30 | var href = $(this).attr('href'); 31 | if (history.pushState) { 32 | history.pushState({}, '', href); 33 | } else { 34 | location.hash = href; 35 | } 36 | event.preventDefault(); 37 | }); 38 | -------------------------------------------------------------------------------- /docs/undocumented.json: -------------------------------------------------------------------------------- 1 | { 2 | "warnings": [ 3 | 4 | ], 5 | "source_directory": "/Users/steve228uk/Apps/PutioKit" 6 | } --------------------------------------------------------------------------------