Esempio n. 1
0
def test_client_read():
    """Test client read() method.

    Test cases:
      method default (get) - other we already tested

      format json|yaml ( should produce error)

      codes 200|400|401|403|404|500

    """
    public_key = 'public'
    secret_key = 'secret'

    client = Client(public_key, secret_key,
                oauth_access_token='some access token',
                oauth_access_token_secret='some access token secret')
    test_url = 'http://test.url'

    # Produce error on format other then json
    class NotJsonException(Exception):
        pass

    try:
        client.read(url=test_url, format='yaml')
        raise NotJsonException("Client.read() doesn't produce error on "
                               "yaml format")
    except NotJsonException, e:
        raise e
Esempio n. 2
0
def get_client(*access_token):
    """
    Get oDesk Client instance
    """
    try:
        key = current_app.config['ODESK_KEY']
        secret = current_app.config['ODESK_SECRET']
    except KeyError:
        raise Exception("ODESK_KEY and ODESK_SECRET were not found in app.config")
    c = Client(key, secret, auth='oauth')
    if access_token:
        c.oauth_access_token, c.oauth_access_token_secret = access_token
    elif ODESK_ACCESS_TOKEN in session:
        c.oauth_access_token, c.oauth_access_token_secret = session.get(ODESK_ACCESS_TOKEN, [None]*2)
    return c
Esempio n. 3
0
def test_client_urlopen():
    public_key = 'public'
    secret_key = 'secret'

    client = Client(public_key, secret_key,
                    oauth_access_token='some access token',
                    oauth_access_token_secret='some access token secret')

    #test urlopen
    data = [{'url': 'http://test.url',
             'data': {'foo': 'bar'},
             'method': 'GET',
             'result_data': None,
             'result_url': 'http://test.url?api_sig=ddbf4b10a47ca8300554441dc'
             '7c9042b&api_key=public&foo=bar',
             'result_method': 'GET'},
            {'url': 'http://test.url',
             'data': {},
             'method': 'POST',
             'result_data': 'api_sig=ba343f176db8166c4b7e88911e7e'
             '46ec&api_key=public',
             'result_url': 'http://test.url',
             'result_method': 'POST'},
            {'url': 'http://test.url',
             'data': {},
             'method': 'PUT',
             'result_data': 'api_sig=52cbaea073a5d47abdffc7fc8ccd839b&'
             'api_key=public&http_method=put',
             'result_url': 'http://test.url',
             'result_method': 'POST'},
            {'url': 'http://test.url',
             'data': {},
             'method': 'DELETE',
             'result_data': 'api_sig=8621f072b1492fbd164d808307ba72b9&'
             'api_key=public&http_method=delete',
             'result_url': 'http://test.url',
             'result_method': 'POST'},
            ]

    result_json = json.dumps(sample_json_dict)

    for params in data:
        result = client.urlopen(url=params['url'],
                                data=params['data'],
                                method=params['method'])
        assert result.data == result_json, (result.data, result_json)
Esempio n. 4
0
    def get_client(self):
        """Authenticate using keys stored in ``keys.json`` and return
        the ``Client`` instance ready for work.

        """
        if len(self.odesk_key) > 0 and len(self.odesk_secret) > 0 \
            and len(self.odesk_access_token_0) > 0 and len(self.odesk_access_token_1) > 0:

            self.client = Client(self.odesk_key, self.odesk_secret,
                        oauth_access_token=self.odesk_access_token_0,
                        oauth_access_token_secret=self.odesk_access_token_1 )
Esempio n. 5
0
def test_client_read():
    """Test client read() method.

    Test cases:
      method default (get) - other we already tested

      format json|yaml ( should produce error)

      codes 200|400|401|403|404|500

    """
    public_key = 'public'
    secret_key = 'secret'

    client = Client(public_key, secret_key,
                    oauth_access_token='some access token',
                    oauth_access_token_secret='some access token secret')
    test_url = 'http://test.url'

    # Produce error on format other then json
    class NotJsonException(Exception):
        pass

    try:
        client.read(url=test_url, format='yaml')
        raise NotJsonException("Client.read() doesn't produce error on "
                               "yaml format")
    except NotJsonException:
        raise
    except Exception:
        pass

    # Test get, all ok
    result = client.read(url=test_url)
    assert result == sample_json_dict, result

    # Test get and status is ok, but json is incorrect,
    # IncorrectJsonResponseError should be raised
    try:
        result = client_read_incorrect_json(client=client, url=test_url)
        ok_(0, "No exception raised for 200 code and "
               "incorrect json response: {0}".format(result))
    except IncorrectJsonResponseError:
        pass
    except Exception as e:
        assert 0, "Incorrect exception raised for 200 code " \
            "and incorrect json response: " + str(e)

    # Test get, 400 error
    try:
        result = client_read_400(client=client, url=test_url)
    except HTTP400BadRequestError:
        pass
    except Exception as e:
        raise
        assert 0, "Incorrect exception raised for 400 code: " + str(e)

    # Test get, 401 error
    try:
        result = client_read_401(client=client, url=test_url)
    except HTTP401UnauthorizedError:
        pass
    except Exception as e:
        assert 0, "Incorrect exception raised for 401 code: " + str(e)

    # Test get, 403 error
    try:
        result = client_read_403(client=client, url=test_url)
    except HTTP403ForbiddenError:
        pass
    except Exception as e:
        assert 0, "Incorrect exception raised for 403 code: " + str(e)

    # Test get, 404 error
    try:
        result = client_read_404(client=client, url=test_url)
    except HTTP404NotFoundError:
        pass
    except Exception as e:
        assert 0, "Incorrect exception raised for 404 code: " + str(e)

    # Test get, 500 error
    try:
        result = client_read_500(client=client, url=test_url)
    except urllib.error.HTTPError as e:
        if e.code == http_client.INTERNAL_SERVER_ERROR:
            pass
        else:
            assert 0, "Incorrect exception raised for 500 code: " + str(e)
    except Exception as e:
        assert 0, "Incorrect exception raised for 500 code: " + str(e)
Esempio n. 6
0
class oDeskScreenlet(screenlets.Screenlet):
    """A simple example of how to create a Screenlet"""

    # default meta-info for Screenlets (should be removed and put into metainfo)
    __name__ = 'oDeskScreenlet'
    __version__ = '0.0.1+++'
    __author__ = 'Kirill Pekarov'
    __desc__ = __doc__    # set description to docstring of class
    __timeout = None
    text_colour = [1.0, 1.0, 1.0, 1.0]
    back_colour = [0, 0, 0, 1.0]
    show_image = True

    update_interval = 5
    odesk_key = ''
    odesk_secret = ''
    odesk_access_token_0 = ''
    odesk_access_token_1 = ''

    #keys = {'key': 'a4bf017a804d46a9695218f40a952e73', 'secret': '4493f04f50bbe387'}
    #keys['access_token_0'] = 'c664f9275a8871709ed6069dcc8aa07c'
    #keys['access_token_1'] = 'a7b6db2f1af73fe6'

    ODESK_WORKED_ON_FORMAT = '%Y%m%d'

    timereport_data = None

    def __init__(self, **keyword_args):
        # Create screenlet area
        screenlets.Screenlet.__init__(self, width=200, height=300, uses_theme=True, **keyword_args)

        self.theme_name = "default"

        self.add_options_group(_('Options'), _('Appearence Options'))
        self.add_option(ColorOption(_('Options'), 'text_colour', self.text_colour, _('Text Colour'), ''))
        self.add_option(ColorOption(_('Options'), 'back_colour', self.back_colour, _('Back Colour'), ''))

        self.add_options_group(_('oDesk'), _('oDesk Options'))
        self.add_option(IntOption('oDesk', 'update_interval',
                                  self.update_interval, 'Update interval:',
                                  'Update interval in minutes',
                                  min=5, max=360))
        self.add_option(StringOption('oDesk', 'odesk_key', '', 'API Key:', 'The oDesk API Key'))
        self.add_option(StringOption('oDesk', 'odesk_secret', '', 'API Secret:', 'The oDesk API Secret'), realtime=False)

        self.add_option(StringOption('oDesk', 'odesk_access_token_0', '', 'Access Token 1:', 'The oDesk API Token 0'))
        self.add_option(StringOption('oDesk', 'odesk_access_token_1', '', 'Access Token 2:', 'The oDesk API Token 1'))

        self.add_default_menuitems()
        self.update_interval = self.update_interval

    def get_client(self):
        """Authenticate using keys stored in ``keys.json`` and return
        the ``Client`` instance ready for work.

        """
        if len(self.odesk_key) > 0 and len(self.odesk_secret) > 0 \
            and len(self.odesk_access_token_0) > 0 and len(self.odesk_access_token_1) > 0:

            self.client = Client(self.odesk_key, self.odesk_secret,
                        oauth_access_token=self.odesk_access_token_0,
                        oauth_access_token_secret=self.odesk_access_token_1 )

    def get_auth_info(self):
        return self.client.get('https://www.odesk.com/api/auth/v1/info')

    def get_auth_user_uid(self):
        auth_info = self.get_auth_info()
        self.odesk_uid = auth_info['auth_user']['uid']

    def get_timereport(self, from_date=None, to_date=None):
        """Return parsed JSON data with timereport for given period.
        Fields are default.

        :from_date:    date object
        :to_date:      date object

        If empty - timereport from now to the begining of the current week.

        """

        if hasattr(self, 'client') is False:
            self.get_client()

        if hasattr(self, 'client'):
            now = datetime.now()
            if not to_date:
                to_date = now.date()
                if not from_date:
                    from_date = now.date() - timedelta(days=now.weekday())

            query = Query(
                select=Query.DEFAULT_TIMEREPORT_FIELDS,
                where=(Q('worked_on') >= from_date) & (Q('worked_on') <= to_date))

            self.get_auth_user_uid()

            return self.client.timereport.get_provider_report(self.odesk_uid, query)

    def get_today_and_this_week_times(self, data):
        """Return mapping of teams and hours worked for each team today
        and this week.

        :data:    parsed json data returned from ``get_timereport()`` function

        """
        now = datetime.now()

        date_idx = data['table']['cols'].index(
            {'type': 'date', 'label': 'worked_on'})
        team_idx = data['table']['cols'].index(
            {'type': 'string', 'label': 'team_name'})
        hours_idx = data['table']['cols'].index(
            {'type': 'number', 'label': 'hours'})

        teams = {}

        for row in data['table']['rows']:
            team_name = row['c'][team_idx]['v']
            hours = float(row['c'][hours_idx]['v'])
            date_worked_on = row['c'][date_idx]['v']
            if team_name not in teams:
                teams[team_name] = {'today_hours': 0.0, 'week_hours': 0.0}
            teams[team_name]['week_hours'] += hours
            if date_worked_on == now.strftime(self.ODESK_WORKED_ON_FORMAT):
                teams[team_name]['today_hours'] += hours
        return teams

    def get_timereport_layout(self, data):
        """Render text widged showing timereport data.

        :data:        parsed json data returned from ``get_timereport()`` function
        :odesk_uid:   oDesk user UID

        """
        row_template = '{0}:\n\t{1:.2f} hrs today\n\t{2:.2f} hrs this week\n'
        rows_rendered = '\n'.join(
            [row_template.format(team_name,
                                 team_data['today_hours'],
                                 team_data['week_hours'])
             for team_name, team_data
             in self.get_today_and_this_week_times(data).items()]
        )
        if not rows_rendered:
            rows_rendered = "\nNo worked hours yet"
        template = 'User: {odesk_uid}\n{rows}'
        return template.format(
            odesk_uid=self.odesk_uid,
            rows=rows_rendered
        )

    def on_draw(self, ctx):
        ctx.scale(self.scale, self.scale)

        if self.theme:
            data_start_position = 10
            data = self.get_timereport()
            if data is not None:
                data_text = self.get_timereport_layout(data)
            else:
                data_text = ''

            rectwidth = data_start_position + (len(data_text) * 13)
            # Background
            ctx.set_source_rgba(self.back_colour[0], self.back_colour[1], self.back_colour[2], 0.7)
            self.theme.draw_rounded_rectangle(ctx, 0, 0, 10, rectwidth, self.height, fill=True)

            # text
            if len(data_text) > 0:
                ctx.set_source_rgba(self.text_colour[0], self.text_colour[1], self.text_colour[2], 1.0)
                self.theme.draw_text(ctx, data_text, data_start_position, 23, 'Free Sans', 12, rectwidth - data_start_position,
                                     pango.ALIGN_LEFT)

    def on_draw_shape(self, ctx):
        self.on_draw(ctx)

    def show_edit_dialog(self):
        client = Client(self.odesk_key, self.odesk_secret)
        # create dialog
        dialog = gtk.Dialog(_("Verification Code"), self.window)
        dialog.resize(300, 200)

        link = gtk.LinkButton(format(client.auth.get_authorize_url()), "Press here and copy verification code here:")
        dialog.vbox.add(link)

        dialog.add_buttons(gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
        entrybox = gtk.Entry()
        dialog.vbox.add(entrybox)

        dialog.show_all()
        # run dialog
        response = dialog.run()
        if response == gtk.RESPONSE_OK:
            verification_code = entrybox.get_text()
            self.odesk_access_token_0, self.odesk_access_token_1 = client.auth.get_access_token(verification_code)
        dialog.hide()
        self.update()

    def update(self):
        gobject.idle_add(self.redraw_canvas)
        return True

    def __setattr__(self, name, value):
        # call Screenlet.__setattr__ in baseclass
        screenlets.Screenlet.__setattr__(self, name, value)

        # check for this Screenlet's attributes, we are interested in:
        if name == "update_interval":
            if value > 0:
                self.__dict__['update_interval'] = value
                if self.__timeout:
                    gobject.source_remove(self.__timeout)
                self.__timeout = gobject.timeout_add(value * 60 * 1000, self.update)
            else:
                pass
        elif name == "odesk_secret":
            if len(value) > 0 and len(self.odesk_key) > 0:
                self.__dict__['odesk_secret'] = value

                # if there is no tokens, show window with url and edit field
                # for enter verification code
                if len(self.odesk_access_token_0) == 0 or len(self.odesk_access_token_1) == 0:
                    self.show_edit_dialog()