pike.git / lib / modules / Web.pmod / Api.pmod / Api.pike

version» Context lines:

pike.git/lib/modules/Web.pmod/Api.pmod/Api.pike:2:      //! Base class for implementing a @tt{(RESTful) WebApi@} like Facebook's   //! Graph API, Instagram's API, Twitter's API and so on.   //!   //! @b{Note:@} This class is useless in it self, and is intended to be   //! inherited by classes implementing a given @tt{Web.Api@}.   //!   //! Look at the code in @[Web.Api.Github], @[Web.Api.Instagram],   //! @[Web.Api.Linkedin] etc to see some examples of implementations.    + // #define SOCIAL_REQUEST_DEBUG +    #if defined(SOCIAL_REQUEST_DEBUG) || defined(SOCIAL_REQUEST_DATA_DEBUG)   # define TRACE(X...) werror("%s:%d: %s",basename(__FILE__),__LINE__,sprintf(X))   #else   # define TRACE(X...) 0   #endif      //! The URI to the remote API   constant API_URI = 0;      //! In some API's (LinkedIn f ex) this is named something else so it needs
pike.git/lib/modules/Web.pmod/Api.pmod/Api.pike:42:      //! Authorization object.   //!   //! @seealso   //! @[Web.Auth.OAuth2]   protected Web.Auth.OAuth2.Client _auth;      //! Authentication class to use   protected constant AuthClass = Web.Auth.OAuth2.Client;    + //! The HTTP query objects when running async. + protected mapping(int:array(Protocols.HTTP.Query|Callback)) +  _query_objects = ([]); +    protected mapping(string:string) default_headers = ([    "user-agent" : .USER_AGENT   ]);    -  + protected int _call_id = 0; +    //! Creates a new Api instance   //!   //! @param client_id   //! The application ID   //!   //! @param client_secret   //! The application secret   //!   //! @param redirect_uri   //! Where the authorization page should redirect back to. This must be
pike.git/lib/modules/Web.pmod/Api.pmod/Api.pike:244:    }       if (http_method == "POST") {    if (!data) data = (string) p;    params = 0;    }    else {    params = (mapping) p;    }    -  //Request req; +     Protocols.HTTP.Query req = Protocols.HTTP.Query();       if (http_request_timeout) {    req->timeout = http_request_timeout;    }      #ifdef SOCIAL_REQUEST_DEBUG    TRACE("\n> Request: %s %s?%s\n", http_method, api_method, (string) p);    if (data) TRACE("> data: %s\n", data);   #endif       if (cb) { -  +  int myid = ++_call_id; +  _query_objects[myid] = ({ req, cb }); +     req->set_callbacks(    lambda (Protocols.HTTP.Query qq, mixed ... args) {    if (qq->status == 200) {    cb(handle_response(qq), qq);    }    else if ((< 301, 302 >)[qq->status]) {    cb(qq->headers, qq);    }    else {    cb(0, qq);    } -  +  +  m_delete(_query_objects, myid);    },    lambda (Protocols.HTTP.Query qq, mixed ... args) {    cb(0, qq); -  +  m_delete(_query_objects, myid);    }    );       Protocols.HTTP.do_async_method(http_method, api_method, params,    default_headers, req, data);       return 0;    }       req = Protocols.HTTP.do_method(http_method, api_method, params,    default_headers, req, data);    return req && handle_response(req);   }    -  + //! Forcefully close all HTTP connections. This only has effect in + //! async mode. + void close_connections() + { +  if (!sizeof(_query_objects)) { +  return; +  } +  +  foreach (values(_query_objects), array m) { +  catch { +  Protocols.HTTP.Query q = m[0]; +  if (q && q->con && q->con->is_open()) { + #ifdef SOCIAL_REQUEST_DEBUG +  werror("%s:%d: Forecefully closing open connection: %O\n", +  basename(__FILE__),__LINE__,q); + #endif +  q->close(); +  +  if (m[1]) { +  m[1](0, 0); +  } +  } +  destruct(q); +  }; +  } +  +  _query_objects = ([]); + } +    private mixed handle_response(Protocols.HTTP.Query req)   {    TRACE("Handle response: %O\n", req);       if ((< 301, 302 >)[req->status])    return req->headers;      #ifdef SOCIAL_REQUEST_DATA_DEBUG    TRACE("Data: [%s]\n\n", req->data()||"(empty)");   #endif
pike.git/lib/modules/Web.pmod/Api.pmod/Api.pike:389:    return ([]);   }      //! Internal class ment to be inherited by implementing Api's classes that   //! corresponds to a given API endpoint.   class Method   {    //! API method location within the API    //!    //! @code -  //! https://api.instagram.com/v1/media/search -  //! ............................^^^^^^^ +  //! https://api.instagram.com/v1/media/search +  //! ............................^^^^^^^    //! @endcode    protected constant METHOD_PATH = 0;       //! Hidden constructor. This class can not be instantiated directly    protected void create()    {    if (this_program == Web.Api.Api.Method)    error("This class can not be instantiated directly! ");    }