diff options
Diffstat (limited to 'docs/api')
| -rw-r--r-- | docs/api/components.rst | 20 | ||||
| -rw-r--r-- | docs/api/datatypes.rst | 560 | ||||
| -rw-r--r-- | docs/api/json_api.rst | 95 | ||||
| -rw-r--r-- | docs/api/overview.rst | 36 | ||||
| -rw-r--r-- | docs/api/websocket_api.rst | 25 | 
5 files changed, 736 insertions, 0 deletions
| diff --git a/docs/api/components.rst b/docs/api/components.rst new file mode 100644 index 000000000..08560b535 --- /dev/null +++ b/docs/api/components.rst @@ -0,0 +1,20 @@ +.. _components: + +Components +========== + +The API consists of different parts, all combined and accessible over one interface. A summary and documetation +of the available components listed by topic can be found below. + +.. autosummary:: +    :toctree: module + +    pyload.api.CoreApi.CoreApi +    pyload.api.ConfigApi.ConfigApi +    pyload.api.DownloadPreparingApi.DownloadPreparingApi +    pyload.api.DownloadApi.DownloadApi +    pyload.api.FileApi.FileApi +    pyload.api.CollectorApi.CollectorApi +    pyload.api.AccountApi.AccountApi +    pyload.api.UserInteractionApi.UserInteractionApi +    pyload.api.AddonApi.AddonApi
\ No newline at end of file diff --git a/docs/api/datatypes.rst b/docs/api/datatypes.rst new file mode 100644 index 000000000..df9fb6e41 --- /dev/null +++ b/docs/api/datatypes.rst @@ -0,0 +1,560 @@ +.. _datatypes: + +******************* +Datatype Definition +******************* + +Below you find a copy of :file:`pyload/remote/thriftbackend/pyload.thrift`, which is used to generate the data structs +for various languages. It is also a good overview of avaible methods and return data. + +.. code-block:: c + +     .. [[[cog cog.out(open('pyload/remote/pyload.thrift', 'rb').read()) ]]] +     namespace java org.pyload.thrift + +     typedef i32 FileID +     typedef i32 PackageID +     typedef i32 ResultID +     typedef i32 InteractionID +     typedef i32 UserID +     typedef i64 UTCDate +     typedef i64 ByteCount +     typedef list<string> LinkList +     typedef string PluginName +     typedef string JSONString + +     // NA - Not Available +     enum DownloadStatus { +       NA, +       Offline, +       Online, +       Queued, +       Paused, +       Finished, +       Skipped, +       Failed, +       Starting, +       Waiting, +       Downloading, +       TempOffline, +       Aborted, +       Decrypting, +       Processing, +       Custom, +       Unknown +     } + +     // Download states, combination of several downloadstatuses +     // defined in Api +     enum DownloadState { +         All, +         Finished, +         Unfinished, +         Failed, +         Unmanaged // internal state +     } + +     enum MediaType { +       All = 0 +       Other = 1, +       Audio = 2, +       Image = 4, +       Video = 8, +       Document = 16, +       Archive = 32, +       Executable = 64 +     } + +     enum FileStatus { +       Ok, +       Missing, +       Remote,   // file is available at remote location +     } + +     enum PackageStatus { +       Ok, +       Paused, +       Folder, +       Remote, +     } + +     // types for user interaction +     // some may only be place holder currently not supported +     // also all input - output combination are not reasonable, see InteractionManager for further info +     // Todo: how about: time, ip, s.o. +     enum InputType { +       NA, +       Text, +       Int, +       File, +       Folder, +       Textbox, +       Password, +       Time, +       Bool,   // confirm like, yes or no dialog +       Click,  // for positional captchas +       Select,  // select from list +       Multiple,  // multiple choice from list of elements +       List, // arbitary list of elements +       PluginList, // a list plugins from pyload +       Table  // table like data structure +     } +     // more can be implemented by need + +     // this describes the type of the outgoing interaction +     // ensure they can be logcial or'ed +     enum Interaction { +       All = 0, +       Notification = 1, +       Captcha = 2, +       Query = 4, +     } + +     enum Permission { +         All = 0,  // requires no permission, but login +         Add = 1,  // can add packages +         Delete = 2, // can delete packages +         Modify = 4, // modify some attribute of downloads +         Download = 8,  // can download from webinterface +         Accounts = 16, // can access accounts +         Interaction = 32, // can interact with plugins +         Plugins = 64 // user can configure plugins and activate addons +     } + +     enum Role { +         Admin = 0,  //admin has all permissions implicit +         User = 1 +     } + +     struct Input { +         1: InputType type, +         2: optional JSONString default_value, +         3: optional JSONString data, +     } + +     struct DownloadProgress { +         1: FileID fid, +         2: PackageID pid, +         3: ByteCount speed, // per second +         4: DownloadStatus status, +     } + +     struct ProgressInfo { +       1: PluginName plugin, +       2: string name, +       3: string statusmsg, +       4: i32 eta, // in seconds +       5: ByteCount done, +       6: ByteCount total, // arbitary number, size in case of files +       7: optional DownloadProgress download +     } + +     // download info for specific file +     struct DownloadInfo { +       1: string url, +       2: PluginName plugin, +       3: string hash, +       4: DownloadStatus status, +       5: string statusmsg, +       6: string error, +     } + +     struct FileInfo { +       1: FileID fid, +       2: string name, +       3: PackageID package, +       4: UserID owner, +       5: ByteCount size, +       6: FileStatus status, +       7: MediaType media, +       8: UTCDate added, +       9: i16 fileorder, +       10: optional DownloadInfo download, +     } + +     struct PackageStats { +       1: i16 linkstotal, +       2: i16 linksdone, +       3: ByteCount sizetotal, +       4: ByteCount sizedone, +     } + +     struct PackageInfo { +       1: PackageID pid, +       2: string name, +       3: string folder, +       4: PackageID root, +       5: UserID owner, +       6: string site, +       7: string comment, +       8: string password, +       9: UTCDate added, +       10: list<string> tags, +       11: PackageStatus status, +       12: bool shared, +       13: i16 packageorder, +       14: PackageStats stats, +       15: list<FileID> fids, +       16: list<PackageID> pids, +     } + +     // thrift does not allow recursive datatypes, so all data is accumulated and mapped with id +     struct TreeCollection { +       1: PackageInfo root, +       2: map<FileID, FileInfo> files, +       3: map<PackageID, PackageInfo> packages +     } + +     // general info about link, used for collector and online results +     struct LinkStatus { +         1: string url, +         2: string name, +         3: PluginName plugin, +         4: ByteCount size,   // size <= 0 : unknown +         5: DownloadStatus status, +         6: string packagename, +     } + +     struct ServerStatus { +       1: ByteCount speed, +       2: i16 linkstotal, +       3: i16 linksqueue, +       4: ByteCount sizetotal, +       5: ByteCount sizequeue, +       6: bool notifications, +       7: bool paused, +       8: bool download, +       9: bool reconnect, +     } + +     struct InteractionTask { +       1: InteractionID iid, +       2: Interaction type, +       3: Input input, +       4: string title, +       5: string description, +       6: PluginName plugin, +     } + +     struct AddonService { +       1: string func_name, +       2: string description, +       3: list<string> arguments, +       4: optional i16 media, +     } + +     struct AddonInfo { +       1: string func_name, +       2: string description, +       3: JSONString value, +     } + +     struct ConfigItem { +       1: string name, +       2: string label, +       3: string description, +       4: Input input, +       5: JSONString value, +     } + +     struct ConfigHolder { +       1: string name, // for plugin this is the PluginName +       2: string label, +       3: string description, +       4: string explanation, +       5: list<ConfigItem> items, +       6: optional list<AddonInfo> info, +     } + +     struct ConfigInfo { +       1: string name +       2: string label, +       3: string description, +       4: string category, +       5: bool user_context, +       6: optional bool activated, +     } + +     struct EventInfo { +       1: string eventname, +       2: list<JSONString> event_args, //will contain json objects +     } + +     struct UserData { +       1: UserID uid, +       2: string name, +       3: string email, +       4: i16 role, +       5: i16 permission, +       6: string folder, +       7: ByteCount traffic +       8: i16 dllimit +       9: string dlquota, +       10: ByteCount hddquota, +       11: UserID user, +       12: string templateName +     } + +     struct AccountInfo { +       1: PluginName plugin, +       2: string loginname, +       3: UserID owner, +       4: bool valid, +       5: UTCDate validuntil, +       6: ByteCount trafficleft, +       7: ByteCount maxtraffic, +       8: bool premium, +       9: bool activated, +       10: bool shared, +       11: list <ConfigItem> config, +     } + +     struct OnlineCheck { +       1: ResultID rid, // -1 -> nothing more to get +       2: map<string, LinkStatus> data, // url to result +     } + +     // exceptions + +     exception PackageDoesNotExists { +       1: PackageID pid +     } + +     exception FileDoesNotExists { +       1: FileID fid +     } + +     exception UserDoesNotExists { +       1: string user +     } + +     exception ServiceDoesNotExists { +       1: string plugin +       2: string func +     } + +     exception ServiceException { +       1: string msg +     } + +     exception InvalidConfigSection { +       1: string section +     } + +     exception Unauthorized { +     } + +     exception Forbidden { +     } + +     exception Conflict { +     } + + +     service Pyload { + +       /////////////////////// +       // Core Status +       /////////////////////// + +       string getServerVersion(), +       string getWSAddress(), +       ServerStatus getServerStatus(), +       list<ProgressInfo> getProgressInfo(), + +       list<string> getLog(1: i32 offset), +       ByteCount freeSpace(), + +       void pauseServer(), +       void unpauseServer(), +       bool togglePause(), +       bool toggleReconnect(), + +       void quit(), +       void restart(), + +       /////////////////////// +       // Configuration +       /////////////////////// + +       map<string, ConfigHolder> getConfig(), +       string getConfigValue(1: string section, 2: string option), + +       // two methods with ambigous classification, could be configuration or addon/plugin related +       list<ConfigInfo> getCoreConfig(), +       list<ConfigInfo> getPluginConfig(), +       list<ConfigInfo> getAvailablePlugins(), + +       ConfigHolder loadConfig(1: string name), + +       void setConfigValue(1: string section, 2: string option, 3: string value), +       void saveConfig(1: ConfigHolder config), +       void deleteConfig(1: PluginName plugin), + +       /////////////////////// +       // Download Preparing +       /////////////////////// + +       map<PluginName, LinkList> checkURLs(1: LinkList urls), +       map<PluginName, LinkList> parseURLs(1: string html, 2: string url), + +       // parses results and generates packages +       OnlineCheck checkOnlineStatus(1: LinkList urls), +       OnlineCheck checkOnlineStatusContainer(1: LinkList urls, 2: string filename, 3: binary data) + +       // poll results from previously started online check +       OnlineCheck pollResults(1: ResultID rid), + +       // packagename -> urls +       map<string, LinkList> generatePackages(1: LinkList links), + +       /////////////////////// +       // Download +       /////////////////////// + +       list<PackageID> generateAndAddPackages(1: LinkList links, 2: bool paused), + +       PackageID createPackage(1: string name, 2: string folder, 3: PackageID root, 4: string password, +                                 5: string site, 6: string comment, 7: bool paused), + +       PackageID addPackage(1: string name, 2: LinkList links, 3: string password), +       // same as above with paused attribute +       PackageID addPackageP(1: string name, 2: LinkList links, 3: string password, 4: bool paused), + +       // pid -1 is toplevel +       PackageID addPackageChild(1: string name, 2: LinkList links, 3: string password, 4: PackageID root, 5: bool paused), + +       PackageID uploadContainer(1: string filename, 2: binary data), + +       void addLinks(1: PackageID pid, 2: LinkList links) throws (1: PackageDoesNotExists e), +       void addLocalFile(1: PackageID pid, 2: string name, 3: string path) throws (1: PackageDoesNotExists e) + +       // these are real file operations and WILL delete files on disk +       void deleteFiles(1: list<FileID> fids), +       void deletePackages(1: list<PackageID> pids), // delete the whole folder recursive + +       // Modify Downloads + +       void restartPackage(1: PackageID pid), +       void restartFile(1: FileID fid), +       void recheckPackage(1: PackageID pid), +       void restartFailed(), +       void stopDownloads(1: list<FileID> fids), +       void stopAllDownloads(), + +       /////////////////////// +       // Collector +       /////////////////////// + +       list<LinkStatus> getCollector(), + +       void addToCollector(1: LinkList links), +       PackageID addFromCollector(1: string name, 2: bool paused), +       void renameCollPack(1: string name, 2: string new_name), +       void deleteCollPack(1: string name), +       void deleteCollLink(1: string url), + +       //////////////////////////// +       // File Information retrieval +       //////////////////////////// + +       TreeCollection getAllFiles(), +       TreeCollection getFilteredFiles(1: DownloadState state), + +       // pid -1 for root, full=False only delivers first level in tree +       TreeCollection getFileTree(1: PackageID pid, 2: bool full), +       TreeCollection getFilteredFileTree(1: PackageID pid, 2: bool full, 3: DownloadState state), + +       // same as above with full=False +       TreeCollection getPackageContent(1: PackageID pid), + +       PackageInfo getPackageInfo(1: PackageID pid) throws (1: PackageDoesNotExists e), +       FileInfo getFileInfo(1: FileID fid) throws (1: FileDoesNotExists e), + +       TreeCollection findFiles(1: string pattern), +       TreeCollection findPackages(1: list<string> tags), +       list<string> searchSuggestions(1: string pattern), + +       // Modify Files/Packages + +       // moving package while downloading is not possible, so they will return bool to indicate success +       void updatePackage(1: PackageInfo pack) throws (1: PackageDoesNotExists e), +       bool setPackageFolder(1: PackageID pid, 2: string path) throws (1: PackageDoesNotExists e), + +       // as above, this will move files on disk +       bool movePackage(1: PackageID pid, 2: PackageID root) throws (1: PackageDoesNotExists e), +       bool moveFiles(1: list<FileID> fids, 2: PackageID pid) throws (1: PackageDoesNotExists e), + +       void orderPackage(1: list<PackageID> pids, 2: i16 position), +       void orderFiles(1: list<FileID> fids, 2: PackageID pid, 3: i16 position), + +       /////////////////////// +       // User Interaction +       /////////////////////// + +       // mode = interaction types binary ORed +       bool isInteractionWaiting(1: i16 mode), +       list<InteractionTask> getInteractionTasks(1: i16 mode), +       void setInteractionResult(1: InteractionID iid, 2: JSONString result), + +       // generate a download link, everybody can download the file until timeout reached +       string generateDownloadLink(1: FileID fid, 2: i16 timeout), + +       /////////////////////// +       // Account Methods +       /////////////////////// + +       list<string> getAccountTypes(), + +       list<AccountInfo> getAccounts(), +       AccountInfo getAccountInfo(1: PluginName plugin, 2: string loginname, 3: bool refresh), + +       AccountInfo updateAccount(1: PluginName plugin, 2: string loginname, 3: string password), +       void updateAccountInfo(1: AccountInfo account), +       void removeAccount(1: AccountInfo account), +        +       ///////////////////////// +       // Auth+User Information +       ///////////////////////// + +       bool login(1: string username, 2: string password), +       // returns own user data +       UserData getUserData(), + +       // all user, for admins only +       map<UserID, UserData> getAllUserData(), + +       UserData addUser(1: string username, 2:string password), + +       // normal user can only update their own userdata and not all attributes +       void updateUserData(1: UserData data), +       void removeUser(1: UserID uid), + +       // works contextual, admin can change every password +       bool setPassword(1: string username, 2: string old_password, 3: string new_password), + +       /////////////////////// +       // Addon Methods +       /////////////////////// + +       //map<PluginName, list<AddonInfo>> getAllInfo(), +       //list<AddonInfo> getInfoByPlugin(1: PluginName plugin), + +       map<PluginName, list<AddonService>> getAddonHandler(), +       bool hasAddonHandler(1: PluginName plugin, 2: string func), + +       void callAddon(1: PluginName plugin, 2: string func, 3: list<JSONString> arguments) +             throws (1: ServiceDoesNotExists e, 2: ServiceException ex), + +       // special variant of callAddon that works on the media types, acccepting integer +       void callAddonHandler(1: PluginName plugin, 2: string func, 3: PackageID pid_or_fid) +             throws (1: ServiceDoesNotExists e, 2: ServiceException ex), + + +       //scheduler + +       // TODO + +     } +     .. [[[end]]] + diff --git a/docs/api/json_api.rst b/docs/api/json_api.rst new file mode 100644 index 000000000..504de20bf --- /dev/null +++ b/docs/api/json_api.rst @@ -0,0 +1,95 @@ +.. _json_api: + +======== +JSON API +======== + +JSON [1]_ is a lightweight object notation and wrappers exists for nearly every programming language. Every +modern browser is able to load JSON objects with JavaScript. Unlike other RPC methods you don't need to generate or precompile +any stub methods. The JSON :class:`Api <pyload.Api.Api>` is ready to be used in most languages and most JSON libraries are lightweight +enough to build very small and performant scripts. Because of the builtin support, JSON is the first choice for all browser +applications. + +Login +----- + +First you need to authenticate, if you are using this within the web interface and the user is logged in, the API is also accessible, +since they share the same cookie/session. + +However, if you are building an external client and want to authenticate manually +you have to send your credentials ``username`` and ``password`` as +POST parameter to ``http://pyload-core/api/login``. + +The result will be your session id. If you are using cookies, it will be set and you can use the API now. +In case you don't have cookies enabled you can pass the session id as ``session`` POST parameter +so pyLoad can authenticate you. + + +Calling Methods +--------------- + +In general you can use any method listed at the :class:`Api <pyload.Api.Api>` documentation, which is also available to +the thrift backend. + +Access works simply via ``http://pyload-core/api/methodName``, where ``pyload-core`` is the ip address +or hostname including the web interface port. By default on local access this would be `localhost:8000`. + +The return value will be formatted in JSON, complex data types as dictionaries. Definition for data types can be found +:doc:`here <datatypes>` + +Passing parameters +------------------ + +To pass arguments you have two choices: +Either use positional arguments, e.g.: ``http://pyload-core/api/getFileData/1``, where 1 is the FileID, or use keyword +arguments supplied via GET or POST ``http://pyload-core/api/getFileData?fid=1``. You can find the argument names +in the :class:`Api <pyload.Api.Api>` documentation. + +It is important that *all* arguments are in JSON format. So ``http://pyload-core/api/getFileData/1`` is valid because +1 represents an integer in json format. On the other hand if the method is expecting strings, this would be correct: +``http://pyload-core/api/getUserData/"username"/"password"``. + +Strings are wrapped in double qoutes, because `"username"` represents a string in JSON format. It's not limited to +strings and integers, every container type like lists and dicts are possible. You usually don't have to convert them. +Just use a JSON encoder before using them in the HTTP request. + +Please note that the data has to be urlencoded at last. (Most libraries will do that automatically) + +Example +------- + +Here is a little python script that is able to send commands to the pyload api:: + +    #!/usr/bin/env python +    # -*- coding: utf-8 -*- + +    from urllib import urlopen, urlencode +    from json import dumps + +    URL = "http://localhost:8001/api/%s" + +    def login(user, pw): +        params = {"username": user, "password": pw} +        ret = urlopen(URL % "login", urlencode(params)) +        return ret.read().strip("\"") + +    # send arbitrary command to pyload api, parameter as keyword argument +    def send(session, command, **kwargs): +        # convert arguments to json format +        params = dict([(k, dumps(v)) for k,v in kwargs.iteritems()]) +        params["session"] = session +        ret = urlopen(URL % command, urlencode(params)) +        return ret.read() + +    if __name__ == "__main__": +        session = login("User", "pwhere") +        print "Session id:", session + +        result = send(session, "setCaptchaResult", tid=0, result="some string") +        print result + + + +.. rubric:: Footnotes + +.. [1] http://de.wikipedia.org/wiki/JavaScript_Object_Notation diff --git a/docs/api/overview.rst b/docs/api/overview.rst new file mode 100644 index 000000000..3b65a45b0 --- /dev/null +++ b/docs/api/overview.rst @@ -0,0 +1,36 @@ +.. _overview: + +======================================= +API - Application Programming Interface +======================================= + +From Wikipedia, the free encyclopedia [1]_: + +    An application programming interface (API) is a source code based specification intended to be used as an interface +    by software components to communicate with each other. An API may include specifications for routines, +    data structures, object classes, and variables. + +.. rubric:: Motivation + +The idea of the centralized pyLoad :class:`Api <pyload.Api.Api>` is to give uniform access to all integral parts +and plugins in pyLoad as well as other clients written in arbitrary programming languages. +Most of the :class:`Api <pyload.Api.Api>` functionality is exposed via HTTP or WebSocktes [2]_ as +simple JSON objects [3]_. In conclusion the :class:`Api <pyload.Api.Api>` is accessible via many programming languages, +over network from remote machines and over browser with javascript. + + +.. rubric:: Contents + +.. toctree:: + +    json_api.rst +    websocket_api.rst +    components.rst +    datatypes.rst + + +.. rubric:: Footnotes + +.. [1] http://en.wikipedia.org/wiki/Application_programming_interface +.. [2] http://en.wikipedia.org/wiki/WebSocket +.. [3] http://en.wikipedia.org/wiki/Json
\ No newline at end of file diff --git a/docs/api/websocket_api.rst b/docs/api/websocket_api.rst new file mode 100644 index 000000000..bc5d67fa3 --- /dev/null +++ b/docs/api/websocket_api.rst @@ -0,0 +1,25 @@ +.. _websocket_api: + +============= +WebSocket API +============= + +TODO + + +Login +----- + +Calling Methods +--------------- + +Passing parameters +------------------ + +Example +------- + + +.. rubric:: Footnotes + +.. [1] http://en.wikipedia.org/wiki/WebSocket
\ No newline at end of file | 
