Example #1
0
class PlotItemViewModel:
    def __init__(self, strVariavel, strQuery, color, plotType):
        self.strVariavelBehavior = BehaviorSubject(strVariavel)
        self.strQueryBehavior = BehaviorSubject(strQuery)
        self.colorBehavior = BehaviorSubject(color)
        self.plotTypeBehavior = BehaviorSubject(plotType)

    def dispose(self):
        self.strVariavelBehavior.dispose()
        self.strQueryBehavior.dispose()
        self.colorBehavior.dispose()
        self.plotTypeBehavior.dispose()

    def _get_strVariavel_(self):
        return self.strVariavelBehavior.value

    def _set_strVariavel_(self, value):
        if value != self.strVariavelBehavior.value:
            self.strVariavelBehavior.on_next(value)

    strVariavel = property(_get_strVariavel_, _set_strVariavel_)

    def _get_strQuery_(self):
        return self.strQueryBehavior.value

    def _set_strQuery_(self, value):
        if value != self.strQueryBehavior.value:
            self.strQueryBehavior.on_next(value)

    strQuery = property(_get_strQuery_, _set_strQuery_)

    def _get_color_(self):
        return self.colorBehavior.value

    def _set_color_(self, value):
        if value[0] != self.colorBehavior.value[0] or value[
                1] != self.colorBehavior.value[1] or value[
                    2] != self.colorBehavior.value[2]:
            self.colorBehavior.on_next(value)

    color = property(_get_color_, _set_color_)

    def _get_plotType_(self):
        return self.plotTypeBehavior.value

    def _set_plotType_(self, value):
        if value != self.plotTypeBehavior.value:
            self.plotTypeBehavior.on_next(value)

    plotType = property(_get_plotType_, _set_plotType_)
class TabViewModel:
    """Informação global da tab"""
    def __init__(self, share_x, max_plots, name):
        self.sharexBehavior = BehaviorSubject(share_x)
        self.maxPlotsBehavior = BehaviorSubject(max_plots)
        self.nameBehavior = BehaviorSubject(name)

    def dispose(self):
        self.sharexBehavior.dispose()
        self.maxPlotsBehavior.dispose()
        self.nameBehavior.dispose()

    def _get_sharex_(self):
        return self.sharexBehavior.value

    def _set_sharex_(self, s):
        self.sharexBehavior.on_next(s)

    sharex = property(_get_sharex_, _set_sharex_)

    def _get_maxPlots_(self):
        return self.maxPlotsBehavior.value

    def _set_maxPlots_(self, m):
        self.maxPlotsBehavior.on_next(m)

    maxPlots = property(_get_maxPlots_, _set_maxPlots_)

    def _get_name_(self):
        return self.nameBehavior.value

    def _set_name_(self, value):
        self.nameBehavior.on_next(value)

    name = property(_get_name_, _set_name_)
Example #3
0
class PlotViewModel:
    def __init__(self, xVariavel, xQuery, grid):
        self.xVariavelBehavior = BehaviorSubject(xVariavel)
        self.xQueryBehavior = BehaviorSubject(xQuery)
        self.gridBehavior = BehaviorSubject(grid)
        # Fazer parte dos itens
        # self.plotItems = [ for pltItem in items]
        # Itens

    def dispose(self):
        self.xVariavelBehavior.dispose()
        self.xQueryBehavior.dispose()
        self.gridBehavior.dispose()

    def _get_xVariavel_(self):
        return self.xVariavelBehavior.value

    def _set_xVariavel_(self, value):
        if value != self.xVariavelBehavior.value:
            self.xVariavelBehavior.on_next(value)

    xVariavel = property(_get_xVariavel_, _set_xVariavel_)

    def _get_xQuery_(self):
        return self.xQueryBehavior.value

    def _set_xQuery_(self, value):
        if value != self.xQueryBehavior.value:
            self.xQueryBehavior.on_next(value)

    xQuery = property(_get_xQuery_, _set_xQuery_)

    def _get_grid_(self):
        return self.gridBehavior.value

    def _set_grid_(self, value):
        if value != self.gridBehavior.value:
            self.gridBehavior.on_next(value)

    grid = property(_get_grid_, _set_grid_)
Example #4
0
class GenericRantList(urwid.WidgetWrap):
    def __init__(self, rants_subscriptable):

        self.widget = None
        self.rants_subscriptable = rants_subscriptable
        self.rants = []
        self.update = BehaviorSubject(self)
        self._subscriptions = []

        self.create()
        super().__init__(self.widget)

    def __del__(self):
        self.update.dispose()
        for subscription in self._subscritpions:
            subscription.unsubscribe()

    def create_list_box(self):

        elements = []
        for i, rant in enumerate(self.rants):
            if i > 0:
                elements.append(urwid.Divider(u'\u2500'))

            element = RantListElementWidget(rant)
            elements.append(element)

        list_box = urwid.ListBox(urwid.SimpleListWalker(elements))

        return list_box

    def create(self):
        self.widget = urwid.Frame(self.create_list_box())
        self._subscribe_rant_list()

    def _subscribe_rant_list(self):
        def action(new_value):
            self.rants = new_value

            simple_list_walker = self.widget.contents['body'][0].body
            i = 0
            j = 0

            # update existent
            while i < len(simple_list_walker) and j < len(new_value):
                element = simple_list_walker[i]
                rant = new_value[j]
                if type(element) is not RantListElementWidget:
                    i += 1
                else:
                    element.update_rant(rant)
                    i += 1
                    j += 1

            # append new ones
            while j < len(new_value):
                rant = new_value[j]
                if i > 0:
                    simple_list_walker.append(urwid.Divider(u'\u2500'))
                    i += 1
                simple_list_walker.contents.append(RantListElementWidget(rant))
                i += 1
                j += 1

            # delete excedent
            simple_list_walker.contents[:i]

            self.update.on_next(self)

        self._subscriptions.append(self.rants_subscriptable.subscribe(action))
class DevRantService():
    def __init__(self, *args, **kwargs):

        self.base_url = "https://devrant.com/api"

        self.base_params = {
            'app': 3,
        }

        self.rants = BehaviorSubject([])
        self.error = Subject()
        self.me = BehaviorSubject(None)
        self.auth_token = BehaviorSubject(None)
        self.is_logged = BehaviorSubject(False)

        self._subscribe_to_auth_token()
        self._load_cache()

    def __del__(self):
        self.rants.dispose()
        self.error.dispose()
        self.me.dispose()
        self.auth_token.dispose()
        self.is_logged.dispose()

    def _get_params(self, **kwargs):
        params = dict(self.base_params, **kwargs)
        return urllib.parse.urlencode(params)

    def _load_cache(self, filename='.cache.json'):
        try:
            fh = open(filename, 'r')
        except FileNotFoundError:
            self._write_cache(filename)
            self._load_cache(filename)
        else:
            try:
                cache_data = json.load(fh)
            except json.decoder.JSONDecodeError:
                pass
            else:
                cached_auth_token = cache_data.get('auth_token')

                if cached_auth_token is not None:
                    cached_auth_token = AuthToken(**cached_auth_token)
                    self.auth_token.on_next(cached_auth_token)
            fh.close()

    def _write_cache(self, filename='.cache.json'):

        cache_data = {}

        try:
            fh = open(filename, 'r')
            cache_data = json.load(fh)
        except FileNotFoundError:
            pass
        except json.JSONDecodeError:
            pass
        else:
            fh.close()

        fh = open(filename, 'w')
        if self.auth_token.value is not None:
            cache_data['auth_token'] = self.auth_token.value.__dict__()

        json.dump(cache_data, fh)
        fh.close()

    def _delete_cache(self, filename='.cache.json'):
        fh = open(filename, 'w')
        json.dump({}, fh)
        fh.close()

    def _subscribe_to_auth_token(self):
        def action(value):
            # change is_logged value
            if self.is_logged.value and value.user_id is None:
                self.is_logged.on_next(False)
            elif not self.is_logged.value and value and value.user_id:
                self.is_logged.on_next(True)

            # save new auth_token
            self._write_cache()

        self._auth_token_subscription = self.auth_token.subscribe(action)
        return self

    async def get_rants(self, limit=10):
        param_url = self._get_params(sort='recent',
                                     limit=limit,
                                     skip=len(self.rants.value))

        response = requests.get(self.base_url + '/devrant/rants' + '?' +
                                param_url)

        if response.status_code == 200:
            new_rants = json.loads(response.text)['rants']
            new_rants = [Rant(rant) for rant in new_rants]
            all_rants = list(
                merge(self.rants.value,
                      new_rants,
                      key=lambda x: x.id,
                      reverse=True))
            self.rants.on_next(all_rants)
        else:
            self.error.on_next({
                'code': 1,
                'message': 'Unexpected status code',
                'response': response
            })

        return self

    async def get_new_rants(self, skip=0, limit=10):

        if len(self.rants.value) == 0:
            return await self.get_rants()

        newest_actual_rant = self.rants.value[0]

        param_url = self._get_params(sort='recent', limit=limit, skip=skip)
        response = requests.get(self.base_url + '/devrant/rants' + '?' +
                                param_url)

        if response.status_code == 200:
            new_rants = json.loads(response.text)['rants']
            new_rants = [Rant(rant) for rant in new_rants]
            new_rants.sort(key=lambda x: x.id, reverse=True)
            if new_rants[-1].id > newest_actual_rant.id:
                await self.get_new_rants(skip + limit, limit)
                newest_actual_rant = self.rants.value[0]

            new_rants = [
                rant for rant in new_rants if rant.id > newest_actual_rant.id
            ]

            all_rants = list(
                merge(new_rants,
                      self.rants.value,
                      key=lambda x: x.id,
                      reverse=True))

            self.rants.on_next(all_rants)
        else:
            self.error.on_next({
                'code': 1,
                'message': 'Unexpected status code',
                'response': response
            })

        return self

    async def post_rant(self, draft_rant):

        headers = {
            "Host": "devrant.com",
            "Connection": "keep-alive",
            "Accept": "application/json",
            "Origin": "https://devrant.com",
            "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
            "Referer": "https://devrant.com/feed",
        }

        form_data = {
            **self.base_params, 'rant': draft_rant.text,
            'token_id': self.auth_token.value.id,
            'token_key': self.auth_token.value.key,
            'user_id': self.auth_token.value.user_id,
            'tags': ', '.join(draft_rant.tags),
            'type': 1
        }

        draft_rant.response = requests.post(self.base_url + '/devrant/rants',
                                            headers=headers,
                                            data=form_data)

        draft_rant.state.on_next(DraftState.Sent)

        if draft_rant.response.status_code == 200:
            success = json.loads(draft_rant.response.text).get('success')
            if success:
                await self.get_new_rants()
                draft_rant.state.on_next(DraftState.Published)
            else:
                draft_rant.state.on_next(DraftState.Rejected)
                self.error.on_next({
                    'code': 2,
                    'message': 'Posted rant error',
                    'response': draft_rant.response
                })
        elif draft_rant.response.status_code == 400:
            draft_rant.state.on_next(DraftState.Rejected)
            self.error.on_next({
                'code': 2,
                'message': 'Posted rant error',
                'response': draft_rant.response
            })
        else:
            draft_rant.state.on_next(DraftState.Rejected)
            self.error.on_next({
                'code': 1,
                'message': 'Unexpected status code',
                'response': draft_rant.response
            })

    async def login(self, username, password):

        headers = {
            "Host": "devrant.com",
            "Connection": "keep-alive",
            "Accept": "application/json",
            "Origin": "https://devrant.com",
            "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
            "Referer": "https://devrant.com/",
        }
        response = requests.post(self.base_url + '/users/auth-token',
                                 headers=headers,
                                 data={
                                     **self.base_params,
                                     "username": username,
                                     "password": password,
                                 })

        if response.status_code == 200:
            data = response.json()
            if data.get('success'):
                auth_token = AuthToken(**data.get('auth_token'))
                self.auth_token.on_next(auth_token)
                # await self.get_about_me()
            else:
                self.error.on_next({'message': data.get('error')})

    def logout(self):
        self._delete_cache()
        self.auth_token.on_next(AuthToken())

    async def get_about_me(self):

        param_url = self._get_params(token_id=self.auth_token.value.id,
                                     token_key=self.auth_token.value.key)
        response = requests.get(
            self.base_url + '/users/{}'.format(self.auth_token.value.user_id) +
            '?' + param_url)
        return response