コード例 #1
0
ファイル: __init__.py プロジェクト: tsinclair/PyDeskAPI
def _send_request(api, url, request='get', params=None, save_xml=None):
    """Call api.xxxx_request and optionally save XML response to file.

    Parameter 'api' is an instance of class oDeskAPI
    """
    save_file = None
    pcopy = params[:] if params else None
    log.debug("send_{0:s} params: {1!r}".format(pcopy, request.upper()))
    request = request.lower()
    try:
        if request == 'get':
            response = api.get_request(url, pcopy)
        elif request == 'post':
            response = api.post_request(url, pcopy)
        elif request == 'put':
            response = api.put_request(url, pcopy)
        elif request == 'delete':
            response = api.delete_request(url, pcopy)
        else:
            e = "Unknown request type '{0:s}'".format(request)
            stderr("{0:s}\n".format(e))
            log.error(e)
            return None
    except RequestError, e:
        # api.last_error is the error code returned by server
        stderr(e)
        log.exception(e)
        # Do not change this return value.
        # Some callers may check 'if response is None: ...'
        return None
コード例 #2
0
ファイル: job.py プロジェクト: tsinclair/PyDeskAPI
def job_search(api, since=3, **kwargs):
    """Produce list of job posted after given date."""
    debug = log.debug
    url = 'https://www.odesk.com/api/profiles/v1/search/jobs.xml'
    dp = days_ago_to_dp(since)
    keys = kwargs.keys()
    params = [('dp', dp)]
    for keyword in keys:
        param = valid_job_search_parameter(keyword)
        if param:
            params.append((param, kwargs[keyword]))
    offset=0
    count = 200
    joblist = []
    while 1:
        params.append(('page', '{0:d};{1:d}'.format(offset, count)))
        xml = send_GET(api, url, params)
        if xml is None:
            e = "Error, request failed: send_GET(api, {0:s}, {1!s}".format(url, params)
            stderr("{0:s}\n".format(e))
            log.error(e)
            return joblist
        jl = list_from_xml(xml, 'job')
        if len(jl) == 0: break
        joblist.extend(jl)
        if len(jl) < count: break
        params.pop()
        offset += count
    return joblist
コード例 #3
0
ファイル: organization.py プロジェクト: tsinclair/PyDeskAPI
def teams(api, request=None, save_xml=None):
    """Retrieve a list of all teams this process (user) has access to.

    Parameters:
    request -  List which limits the amount of information returned. Must be a
               subset of:
                 ['parent_team__id', 'is_hidden', 'status', 'name',
                  'company_name', 'parent_team__name', 'company__reference',
                  'parent_team__reference', 'reference' , 'id']

    The teams may be from different companies.
    Results of this GET depend on the permissions granted to the authenticated
    user of this process- the oDesk user and password used to access the API.

    Returns:
    List of dict objects- one per team.
    """
    url = urls.get_API_URL('teams')
    if save_xml: save_xml = 'teams.xml'
    response = send_GET(api, url, save_xml=save_xml)
    if response is None:
        log.error("request failed: send_GET(api, {0:s}".format(url))
        return []
    teams = list_from_xml(response, 'team')
    all_info = ['parent_team__id', 'is_hidden', 'status', 'name',
                'company_name', 'parent_team__name', 'company__reference',
                'parent_team__reference', 'reference' , 'id']
    if not request:
        requested_info = all_info[:]
    else:
        requested_info = list_intersect(list(request), all_info)
    return dict_subset(teams, requested_info)
コード例 #4
0
ファイル: organization.py プロジェクト: tsinclair/PyDeskAPI
def team_users(api, team_name, request=None, eid=None,
                                                save_xml=None, debug=False):
    """Retrieve details of team members.

    Parameters:

    team_name - Name of team. Should be identical to a team returned by 
                company_teams(api, 'company name')

    request   - List which limits the amount of information returned. Must be
                a subset of:

                   ['last_name', 'first_name', 'status', 'id', 'reference',
                                'is_provider', 'timezone', 'timezone_offset']

                These are the keys in the dict object(s) returned.

    eid       - oDesk user id. This is the same as the 'id' above. If given
                a list of one dict object for a team member matching 'id' is
                returned.

    Return:
    A list of one dict object if 'eid' parameter is given, or a list of N dict
    objects where N equals the number of people on the named team.
    If 'request' is not given the dict object contains all information for each
    team member.  Otherwise each item in 'request' which exactly matchs one of
    the valid identifiers given above is returned in each dict object generated.
    """
    userlist = []
    (team_ref, parent_team_ref, company_ref) = \
                                    team_reference_IDs(api, team_name, save_xml)
    if not team_ref:
        log.warning("No results from team_users(api, '{0:s}')".format(team_name))
        return userlist
    log.info("fetching team {0:s} users".format(team_name))
    url = urls.get_API_URL('team_users', team_ref=team_ref)
    log.debug('URL: {0:s}'.format(url))
    if save_xml: save_xml = 'team_users.xml'
    response = send_GET(api, url, save_xml=save_xml)
    if response is None:
        log.error("request failed: send_GET(api, {0:s}".format(url))
        return userlist
    tmplist = list_from_xml(response, 'user', debug=debug)
    if eid:
        for user in tmplist:
            if user['id'] == eid:
                userlist.append(user)
                break
    else:
        userlist = tmplist[:]
    all_info = ['last_name', 'first_name', 'status', 'id', 'reference',
                            'is_provider', 'timezone', 'timezone_offset']
    if not request:
        requested_info = all_info[:]
    else:
        requested_info = list_intersect(list(request), all_info)
    return dict_subset(userlist, requested_info)
コード例 #5
0
ファイル: provider.py プロジェクト: tsinclair/PyDeskAPI
def provider_search(api, save_xml=False, **kwargs):
    """Use the provider search API to search all public providers on oDesk.    

    Parameter kwargs is expected to contain key-value pairs where the key
    is one of the keys, or the 'field_name', from the dict 'params' defined
    in  valid_provider_search_parameter().

    The utility function str2kwargs() from api.util.utility can be used to
    generate 'kwargs'.
    """
    node_name = 'providers'
    url = get_API_URL('providers')
    if save_xml: save_xml = 'providers.xml'
    params = []
    for keyword in kwargs.keys():
        parameter = valid_provider_search_parameter(keyword)
        if not parameter: continue
        if kwargs[keyword]:   # could be 'None'
            if parameter == 'sort':
                stderr('\nkwargs[keyword] = {0:s}\n'.format(kwargs[keyword]))
                value = _verify_sort(kwargs[keyword])
            else:
                value = kwargs[keyword]
            if value:
                params.append((parameter, value))
        else:
            params.append((parameter))
    # HERE
    #stderr('\nquery/provider.py:provider_search() params = {0!r}\n\n'.format(params))
    #
    offset=0
    count = 200
    providers = []
    while 1:
        # extrac parens needed, param to append is a tuple
        params.append(('page', '{0:d};{1:d}'.format(offset, count)))
        # HERE
        #stderr('send_GET params: {0:s}\n'.format(params))
        #
        xml = send_GET(api, url, params, save_xml)
        if xml is None:
            e = "Error, request failed: send_GET(api, {0:s}, {1!s}".format(url, params)
            stderr("{0:s}\n".format(e))
            log.error(e)
            return None
        pl = list_from_xml(xml, node_name)
        if len(pl) == 0: break
        providers.extend(pl)
        if len(pl) < count: break
        params.pop()
        offset += count
    return providers
コード例 #6
0
ファイル: organization.py プロジェクト: tsinclair/PyDeskAPI
def find_team(api, company_name, team_name):
    """Retrun reference Id and status of a team."""
    teamlist = company_teams(api, company_name)
    reference, status = None, None
    if not teamlist:
        e = 'Failed to find anything for company {0:s}'.format(company_name)
        log.error(e)
        return (reference, status)
    for team in teamlist:
        if team['name'] == team_name:
            reference = team['reference']
            status = team['status']
            break
    return (reference, status)
コード例 #7
0
ファイル: job_hr.py プロジェクト: tsinclair/PyDeskAPI
def jobs_managed(api, company, team, request=None, **kwargs):
    """Compile a list of open jobs managed under 'company'."""
    # Need team reference for 'buyer_team_reference' parameter to Jobs HR API
    bad_result = (0, None)
    (ref, status) = find_team(api, company, team)
    if not ref:
        log.error("Failed to find team {0:s} (company {1:s})".format(team, company))
        return bad_result
    node_name = 'job'
    params = [('buyer_team__reference', ref)]
    if kwargs:
        keys = kwargs.keys()
        for key in keys:
            param = valid_jobs_managed_parameter(key)
            if param:
                params.append((param, kwargs[key]))
            elif key == 'save_xml':
                save_xml = 'jobs_managed' if kwargs[key] else None
    url = get_API_URL('jobs_hr')
    xml = send_GET(api, url, params, save_xml=save_xml)
    if xml is None:
        e = "Error, request failed: send_GET(api, {0:s}, {1!s}".format(url, params)
        stderr("{0:s}\n".format(e))
        log.error(e)
        return bad_result
    total_items = int(xml_get_tag(xml, 'total_items'))
    all_info = ['buyer_company__name','buyer_company__reference','buyer_team__id',
        'buyer_team__name','buyer_team__reference','category','company__reference',
        'company_name','created_by','created_by_name','created_time','description',
        'duration','end_date','filled_date','id','job_type','name',
        'num_active_candidates','num_candidates','num_new_candidates',
        'owner_user_id','parent_team__id','parent_team__name',
        'parent_team__reference','public_url','reference','start_date','status',
        'subcategory','title','visibility']
    if not request:
        requested_info = all_info[:]
    else:
        requested_info = list_intersect(request, all_info)
    if total_items > 0:
        result = dict_subset(list_from_xml(xml, node_name), requested_info)
    else:
        result = []
    return (total_items, result)
コード例 #8
0
ファイル: __init__.py プロジェクト: tsinclair/PyDeskAPI
 def get_api_frob(self, api_sig):
     """Retrieve the 'frob' token from the odesk server.
     This token lives 600s.
     """
     iam = func()
     assert self.user_authorized
     assert api_sig
     if self.frob: return frob
     url = get_auth_URL('frobs') + self.get_api_keys_uri(api_sig, iam)
     log.debug('{0:s}: frob URI: {1:s}'.format(iam,url))
     data = self.send_request(url, 'post', caller=iam)
     if not self.request_ok(data):
         return None
     frob = xml_get_tag(data['ret'], 'frob', unicode=False)
     log.debug("frob: {0:s}".format(frob))
     if not frob:
         log.error("Failed to parse 'frob' from server response")
     else:
         self.frob = frob
     return frob
コード例 #9
0
ファイル: provider.py プロジェクト: tsinclair/PyDeskAPI
def provider_profile(api, provider_keys, request=None,
                        brief_listing=True, save_xml=False):
    """Fetch provider profile(s) associated with provider key(s).

    Parameter 'provider_keys' is interpreted as a string of one or more
    keys, or a tuple or list of two or more keys.

    'ciphertext' returned from provider_search() above is the 'provider_key'.
    """
    url = get_API_URL('profiles')
    url_suffix = '/brief.xml' if brief_listing else '.xml'
    node_name = 'profile'
    # 'Parameters: Accepts a provider key or list of keys'
    # E.g. "~~d4080e9142d610ea;~~d4080e9142d610ea;~~9eaf4d98034b5bd8"
    # Note: as of 2011-04-08 the list of keys format does not work? Perms?
    if isinstance(provider_keys, basestring):
        provider_keys = provider_keys.replace(' ', ';')
        provider_keys = provider_keys.split(';')
    elif isinstance(provider_keys, list) or isinstance(provider_keys, tuple):
        provider_keys = list(provider_keys)
    else:
        e = "provider_profile(api, provider_keys): provider_keys parmeter must\n"
        e += "be a string, tuple, or list."
        raise ParamFmtError(e)
    assert isinstance(provider_keys,list)
    params = ''
    for pk in provider_keys:
        params += pk + ';'
    params = params.rstrip(';')
    
    # quoting multiple strings does not work either
    # url += "'" + params + "'"+ url_suffix
    url += params + url_suffix
    xml = send_GET(api, url, params=None, save_xml=save_xml)
    if xml is None:
        e = "Error, request failed: send_GET(api, {0:s})".format(url)
        stderr("{0:s}\n".format(e))
        log.error(e)
        return None
    result = list_from_xml(xml, node_name)
    return result
コード例 #10
0
ファイル: organization.py プロジェクト: tsinclair/PyDeskAPI
def company_users(api, company_name, request=None, save_xml=None, debug=False):
    """Retrieve list of contractors working for 'company_name'

    Parameters:
    company_name - Target company of query. Should be identical to a name returned
                   by odesk.api.query.organization:companies(api, request)

    request - List which limits the amount of information returned for each user.
              Must be a subset of:
                [timezone, reference, status, timezone_offset, id,
                 is_provider, last_name, first_name]

    This ultimately depends on the success of api.query.company_details().
    That GET depends on the permissions granted to the authenticated user of
    this process- the oDesk user and password used to access the API.

    Return:
    List of dictionary objects- one per employee.
    """
    userlist = []
    details = company_details(api, company_name, save_xml=False)
    if not details:
        warn = "No results from company_details(api, '{0:s}')"
        log.warning(warn.format(company_name))
        return userlist
    log.info("fetching company {0:s} users".format(company_name))
    url = urls.get_API_URL('company_users', company_ref=details['reference'])
    log.debug('URL: {0:s}'.format(url))
    if save_xml: save_xml = 'company_users.xml'
    response = send_GET(api, url, save_xml=save_xml)
    if response is None:
        log.error("request failed: send_GET(api, {0:s}".format(url))
        return userlist
    userlist = list_from_xml(response, 'user', debug=debug)
    all_info = ['timezone', 'reference', 'status', 'timezone_offset',
                'id', 'is_provider', 'last_name', 'first_name']
    if not request:
        requested_info = all_info[:]
    else:
        requested_info = list_intersect(request, all_info)
    return dict_subset(userlist, requested_info)
コード例 #11
0
ファイル: organization.py プロジェクト: tsinclair/PyDeskAPI
def company_teams(api, company_name, request=None, save_xml=None):
    """Retrieve a list of teams within a company.

    Parameters:
    api - Instance of class oDeskAPI
    company_name - Target company of query. Should be identical to a name returned
                   by api.query.organization:companies(api, request)

    request - List which limits the amount of information returned for each team.
              Must be a subset of:

              ['parent_team__id', 'is_hidden', 'status', 'name', 'company_name',
               'parent_team__name', 'company__reference, 'parent_team__reference',
               'reference', 'id']

    Return:   
    A list of dictionary objects describing each team in the company. Default
    is to return all information. 

    Results depend on the access permission of the currently authorized user.
    """
    node_tag_name = 'team'
    details = company_details(api, company_name, request=['reference'],
                                                            save_xml=save_xml)
    if not details: return None
    refId = details['reference']
    url = urls.get_API_URL('company_teams', company_ref=refId)
    if save_xml: save_xml = 'company_teams.xml'
    xml = send_GET(api, url, save_xml=save_xml)
    if xml is None:
        log.error("request failed: send_GET(api, {0:s}".format(url))
        return None
    team_list = list_from_xml(xml, node_tag_name)
    all_info = ['parent_team__id', 'is_hidden', 'status', 'name', 'company_name',
               'parent_team__name', 'company__reference', 'parent_team__reference',
               'reference', 'id']
    if not request:               
        requested_info = all_info[:]
    else:
        requested_info = list_intersect(request, all_info)
    return dict_subset(team_list, requested_info)
コード例 #12
0
ファイル: engagement.py プロジェクト: tsinclair/PyDeskAPI
def engagement_details(api, reference_no, request=None, save_xml=None):
    """Fetch details on one engagements.
    
    Parameter 'reference_no' is the engagement reference number- same as
    'reference' returned from the query api.query.engagements(api, team)

    Parameter 'request' if given limits the information returned to a subset of: 

      [buyer_team__id, buyer_team__reference, created_time, engagement_job_type,
       engagement_start_date, engagement_title, estimated_duration,
       estimated_duration_id, hourly_charge_rate, hourly_pay_rate,
       job__reference, job__title, modified_time, offer__reference, provider__id,
       provider__reference, reference, role, status, weekly_hours_limit,
       weekly_salary_charge_amount, weekly_salary_pay_amount]

    Return value is a list of dicionary objects, one for each 'engagement'
    the query returns.
    """
    all_info = ['buyer_team__id', 'buyer_team__reference', 'created_time',
        'engagement_job_type', 'engagement_start_date', 'engagement_title',
        'estimated_duration', 'estimated_duration_id', 'hourly_charge_rate',
        'hourly_pay_rate', 'job__reference', 'job__title', 'modified_time',
        'offer__reference', 'provider__id', 'provider__reference', 'reference',
        'role', 'status', 'weekly_hours_limit', 'weekly_salary_charge_amount',
        'weekly_salary_pay_amount']
    if not request:
        requested_info = all_info[:]
    else:
        requested_info = list_intersect(request, all_info)
    node_name = 'engagement'
    url = get_API_URL('engagement', engagement_ref=reference_no)
    xml = send_GET(api, url)
    if xml is None:
        e = "Error, request failed: send_GET(api, {0:s})".format(url)
        stderr("{0:s}\n".format(e))
        log.error(e)
        return None
    result = list_from_xml(xml, node_name)
    details = dict_subset(result, requested_info)
    return details[0]
コード例 #13
0
ファイル: organization.py プロジェクト: tsinclair/PyDeskAPI
def company_details(api, company_name, request=None, save_xml=None):
    """Retrieve details of a specific company.

    Return a dictionary object containing the details for 'company_name'. If
    currently authenticated user (this process) does not have access to this
    company return None.

    Parameters:
    company_name - 'My Company', not company id or reference

    request - List which limits the amount of information returned.
              Must be a subset of:
                ['reference', 'status', 'name', 'owner_user_id']

    Return:
    A dictionary object describing the company. 
    Default is to return all information.
    """
    refId = company_reference_ID(api, company_name, save_xml=save_xml)
    if refId == -1: return None
    node_name = 'company'
    url = urls.get_API_URL('company_details', company_ref=refId)
    if save_xml: save_xml = 'company_details.xml'
    xml = send_GET(api, url, save_xml=save_xml)
    if xml is None:
        log.error("request failed: send_GET(api, {0:s}".format(url))
        return None
    details = list_from_xml(xml, node_name)
    if len(details) != 1:
        return None
    all_info = ('reference', 'status', 'name', 'owner_user_id')
    if not request:
        requested_info = all_info
        log.debug('requested_info: {0!r}')
    else:
        requested_info = list_intersect(request, all_info)
    details = dict_subset(details, requested_info)
    return details[0]
コード例 #14
0
ファイル: userroles.py プロジェクト: tsinclair/PyDeskAPI
def user_roles(api, request=None, save_xml=None):
    """Retrieve permission information of user.

    For the currently authenticated user return a list of permission information
    for each company/team the user has access to.

    Parameter 'request' is a list which limits the information returned. Must
    be a subset of:

        ['affiliation_status', 'company__name', 'company__reference',
         'engagement__reference', 'has_team_room_access', 'parent_team__id',
         'parent_team__name', 'parent_team__reference', 'permission',
         'reference', 'role', 'team__id', 'team__name', 'team__reference',
         'user__first_name', 'user__id', 'user__is_provider', 'user__last_name',
         'user__reference']

    """
    url = urls.get_API_URL('user_roles')
    xmlnode = 'userrole'
    if save_xml: save_xml = 'user_roles'
    xml = send_GET(api, url, save_xml=save_xml)
    if xml is None:
        e = "Error, request failed: send_GET(api, {0:s}".format(url)
        stderr("{0:s}\n".format(e))
        log.error(e)
        return None
    roles = list_from_xml(xml, xmlnode)
    all_info = ['affiliation_status', 'company__name', 'company__reference',
         'engagement__reference', 'has_team_room_access', 'parent_team__id',
         'parent_team__name', 'parent_team__reference', 'permission',
         'reference', 'role', 'team__id', 'team__name', 'team__reference',
         'user__first_name', 'user__id', 'user__is_provider', 'user__last_name',
         'user__reference']
    if not request:
        requested_info = all_info[:]
    else:
        requested_info = list_intersect(list(request), all_info)
    return dict_subset(roles, requested_info)
コード例 #15
0
ファイル: job_hr.py プロジェクト: tsinclair/PyDeskAPI
def job_details(api, job_reference, request=None, **kwargs):
    """Find all available information for a particular job."""
    # Need team reference for 'buyer_team_reference' parameter to Jobs HR API
    (ref, status) = find_team(api, company, team)
    if not ref:
        log.error("Failed to find team {0:s} (company {1:s})".format(team, company))
        return None
    node_name = 'job'
    save_xml = None
    params = [('buyer_team__reference', ref)]
    if kwargs:
        keys = kwargs.keys()
        for key in keys:
            param = valid_jobs_managed_parameter(key)
            if param:
                params.append((param, kwargs[key]))
            elif key == 'save_xml':
                save_xml = kwargs[key]
    url = get_API_URL('jobs_hr')
    xml = send_GET(api, url, params, save_xml=save_xml)
    if xml is None:
        e = "Error, request failed: send_GET(api, {0:s}, {1!s}".format(url, params)
        stderr("{0:s}\n".format(e))
        log.error(e)
        return None
    result = list_from_xml(xml, node_name)
    all_info= ['reference','title','job_type','description','public_url',
        'created_time','created_by','start_date','end_date','filled_date',
        'cancelled_date','buyer_team__reference','buyer_team__id',
        'buyer_team__name','buyer_company__reference','buyer_company__name',
        'visibility','budget','duration','category','subcategory','num_candidates',
        'num_active_candidates','num_new_candidates','last_candidacy_access_time',
        'status'] 
    if not rquest:
        requested_info = all_info[:]
    else:
        requested_info = list_intersect(request, all_info)
    return dict_subset(result, all_info)
コード例 #16
0
ファイル: organization.py プロジェクト: tsinclair/PyDeskAPI
def companies(api, request=None, save_xml=None):
    """Retrieve a list of all companies this process (user) has access to.

    Parameters:
    request - List which limits the amount of information returned for each
              company the user has access to.  Must be a subset of:
                [reference, status, name, owner_user_id]

    """
    node_name = 'company'
    url = urls.get_API_URL('companies')
    if save_xml: save_xml = 'companies.xml'
    xml = send_GET(api, url, save_xml=save_xml)
    if xml is None:
        log.error("request failed: send_GET(api, {0:s}".format(url))
        return None
    company_list = list_from_xml(xml, node_name)
    all_info = ['reference', 'status', 'name', 'owner_user_id']
    if not request:
        requested_info = all_info[:]
    else:
        requested_info = list_intersect(request, all_info)
    return dict_subset(company_list, requested_info)
コード例 #17
0
ファイル: __init__.py プロジェクト: tsinclair/PyDeskAPI
    def get_api_token(self, frob):
        """Retrieve the API token needed for odesk.com server communication.

        This is the token appended to all server requests. The 'frob' token
        must be available to aquire this token from the server.
        """
        iam = func()
        self.api_token = self.get_token()
        if self.api_token: return self.api_token
        assert frob is not None
        params = [('frob', self.frob)]
        api_sig = self.get_signature(params, caller=iam)
        url = get_auth_URL('tokens') + \
            self.merge_params_to_uri(self.get_api_keys_uri(api_sig, iam), params)
        log.debug("get_api_token(): url: {0:s}".format(url))
        data = self.send_request(url, 'get', caller=iam)
        if self.request_ok(data):
            self.api_token = xml_get_tag(data['ret'], 'token')
        else:
            log.error("Unable to get API token.")
        if not self.api_token:
            raise AppAPITokenError("Unable to get API token.")
        return self.api_token
コード例 #18
0
ファイル: urls.py プロジェクト: tsinclair/PyDeskAPI
def get_auth_URL(auth, fmt='xml'):
    e = "Expected a string identifier, i.e. 'login' or 'auth'.".format(auth)
    if not isinstance(auth, basestring):
        log.error(e)
        raise AppParameterError(e)

    authorization = {
     'login':'******',
     'auth':'https://www.odesk.com/services/api/auth',
    # origional authorization 
     'tokens':'https://www.odesk.com/api/auth/v1/keys/tokens.xml',
     'frobs':'https://www.odesk.com/api/auth/v1/keys/frobs.xml',
    # OAuth
    'access':'https://www.odesk.com/api/auth/v1/oauth/token/access',
    'request':'https://www.odesk.com/api/auth/v1/oauth/token/request',

    }
    try:
        url = authorization[auth]
    except KeyError:
        log.error("unknow URL request '{0:s}'".format(auth))
        raise AppParameterError(e)
    if fmt == 'json': url = url.replace('.xml', '.json')
    return url
コード例 #19
0
ファイル: main.py プロジェクト: tsinclair/PyDeskAPI
    kwargs = {'app_auth_file': auth}
    if alias: kwargs['app_alias'] = alias
    try:
        api = oDeskAPI(config=config, **kwargs)
    except AppInitError, e:
        stderr(e)
        stderr("Failed to initialize oDeskAPI instance...\n")
        exit(1)

    if popts['debug']: api.debug = True

    init_logging(api, popts)
    # Authorize this process with odesk.com developer API
    if not api.authorize():
        assert api.api_token == None
        log.error('failed to authorize client-- no api token')
        api.clean_exit(1)
    log.debug("app_main() returning {0!s}".format(argv2))
    return (api, argv2)

# This is intended only for testing.
if __name__ == '__main__':
    from odapi.logger import initLogger
    usage = """
  usage: $ {0:s} [OPTIONS]

  [OPTIONS]"""

    initLogger(logLevel='debug',logDisk=False, logConsole=True)

    (api, argv) = app_main(sys.argv[0], sys.argv, usage)
コード例 #20
0
ファイル: team_users.py プロジェクト: tsinclair/PyDeskAPI
(pgm, ext) = path.splitext(path.basename(sys.argv[0]))
(api, argv) = app_main(pgm, sys.argv[1:], usage)
(popts, args) = parse_request(pgm, argv, usage)
if popts is None: api.clean_exit(1)
if len(args) != 1:
    stderr ("\n  ** Need team name **, quoted if necessary.\n")
    api.clean_exit(usage_tail(pgm, usage, 1))
team = args[0]
if popts['request']:
    req = strip_csv(popts['request'])
    request =  req.split(',')
else:
    request = None
userlist = team_users(api, team, request=request, eid=None, save_xml=api.debug)
if len(userlist) == 0:
    log.error('failed to get user list for team {0:s}'.format(team))
    api.clean_exit(1)

hdr = '---- contractor {0:2d} of {1:2d} ----\n'
total = len(userlist)
stdout('------ Team {0:s} ---------\n'.format(team))
for n in range(total):
    header = hdr.format(n+1, total)
    stdout(header)
    print_dict_ordered(stdout, userlist[n],
        ['last_name', 'first_name', 'status', 'id', 'reference',
             'is_provider', 'timezone', 'timezone_offset'])
    stdout('\n')
api.clean_exit(0)

コード例 #21
0
ファイル: engagement.py プロジェクト: tsinclair/PyDeskAPI
def team_engagements(api, team, request=None, **kwargs):
    """Fetch details on one or more engagements for given team.
    
    Parameter  'team' is the team name, not integer reference or team Id.

    Parameter 'request', if given, limits the information returned to a
    subset of: 

    [buyer_team__id, buyer_team__reference, created_time, 
     engagement_job_type, engagement_start_date,
     engagement_title, estimated_duration, estimated_duration_id,
     hourly_charge_rate, hourly_pay_rate, job__reference, job__title,
     offer__reference, provider__id, provider__reference, 
     provider_team__reference, reference, role,
     status, weekly_hours_limit, weekly_salary_charge_amount,
     weekly_salary_pay_amount, weekly_stipend_hours]

    Parameter kwargs contains one or more of the following API parameters:
        'job__reference'
        'include_sub_teams'         # 0|1
        'provider__reference'
        'agency_team__reference'
        'status'                    # 'active' or 'closed'
        'created_time_from'         # yyyy-mm-dd HH:MM:SS
        'created-time_to'           # yyyy-mm-dd HH:MM:SS
        'page'                      # page=offset;count
        'order_by'                  # order_by=
     
    Return value is a list of dicionary objects, one for each 'engagement'
    the query returns.
    """
    iam = func()
    from odapi.query.organization import team_reference_ID
    ref = team_reference_ID(api, team)
    if not ref:
        log.error("Failed to find team {0:s}".format(team))
        return None
    node_name = 'engagement'
    save_xml = None

    # These are all the fields returned by this query
    # Note: 'reference' is the number needed to make a bonus payment to
    #       a provider.
    all_info = ['buyer_team__id', 'buyer_team__reference', 'created_time',
       'description', 'engagement_end_date', 'engagement_job_type',
       'engagement_start_date', 'engagement_title', 'estimated_duration',
       'estimated_duration_id', 'hourly_charge_rate', 'hourly_pay_rate',
       'job__reference', 'job__title', 'offer__reference', 'provider__id',
       'provider__reference', 'provider_team__id', 'provider_team__reference',
       'reference', 'role', 'status', 'weekly_hours_limit',
       'weekly_salary_charge_amount', 'weekly_salary_pay_amount',
       'weekly_stipend_hours']

    if not request:
        requested_info = all_info[:]
    else:
        requested_info = list_intersect(request, all_info)
    params = [('buyer_team__reference', ref)]
    if kwargs:
        keys = kwargs.keys()
        for key in keys:
            param = valid_engagement_parameter(key)
            if param:
                params.append((param, kwargs[key]))
            elif key == 'save_xml':
                if kwargs[key]:
                    save_xml = '{0:s}.xml'.format(iam)
    url = get_API_URL('engagements')
    offset=0
    count=10
    engagements = []
    while 1:
        # page parameter is page=offset;count
        params.append(('page', '{0:d};{1:d}'.format(offset, count)))
        xml = send_GET(api, url, params, save_xml=save_xml)
        if xml is None:
            e = "Error, request failed: send_GET(api, {0:s}, {1!s})"
            estr = e.format(url, params)
            stderr("{0:s}\n".format(estr))
            log.error(estr)
            return None
        if save_xml:
            with open(save_xml, 'w') as f:
                f.write(xml)   
        result = list_from_xml(xml, node_name)
        if len(result) == 0: break
        engagements.extend(result)
        if len(result) < count: break
        params.pop()
        offset += count
    return dict_subset(engagements, requested_info)
コード例 #22
0
ファイル: pay_bonus.py プロジェクト: tsinclair/PyDeskAPI
    (popts, args) = parseargs(pgm, sys.argv[1:])
except AppInitError, e:
    stderr(e)
    exit(1)

if not len(args) == 2:
    stderr ("\n  ** Need 'company' and 'team', in that order **, quoted if needed.\n")
    exit(usage(pgm, 1))

if not popts['user']:
    stderr ("\n  ** Need -u username **.\n")
    exit(usage(pgm, 1))

company = args[0]
team = args[1]
user = popts['user']
bonus = popts['bonus']
comment = popts['comment']
notes = popts['notes']

if not (bonus and comment):
    stderr('\n  Bonus and comment are required. See --help if needed.\n')
    exit(1)
result = grant_bonus(api, company, team, user, amount=bonus,
                               comment=comment, notes=notes)
if result != amount:
    err = 'Error occurred while processing bonus of {0:d}'.format(bonus)
    stderr('{0:s}\n'.format(err))
    log.error(err)
api.clean_exit(0)
コード例 #23
0
ファイル: pay_by_ref.py プロジェクト: tsinclair/PyDeskAPI
if not len(args) == 2:
    stderr ("\n  ** Need reference_no and amount, in that order **.\n")
    exit(usage(pgm, 1))

auth = '/home/tsinclair/archive/auth/auth.txt'
kwargs = {'app_auth_file': auth}

try:
    api = oDeskAPI(config=None, **kwargs)
except AppInitError, e:
    stderr("Failed to obtain oDeskAPI instance...\n")
    exit(1)

if not api.authorize():
    assert api.api_token == None
    log.error('failed to authorize client-- no api token')
    api.clean_exit(1)

ref = args[0]
bonus = args[1]
notes = '{0:s}: ${1:s}'.format(ref, bonus)
comment = 'Thank You!'
print ref, bonus, notes
#api.clean_exit(0)
result = custom_pay_by_ref(api, ref, bonus,
                               comment=comment, notes=notes)
if not result:
    err = 'Error occurred while processing bonus of {0:d}'.format(bonus)
    stderr('{0:s}\n'.format(err))
    log.error(err)
api.clean_exit(0)