Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[backend] Add Rocket.Chat backend #661

Merged
merged 1 commit into from
May 27, 2020
Merged

Conversation

animeshk08
Copy link
Contributor

Fixes: #543
This commit adds support to fetch
messages from a Rocket.Chat channel.

The tests have been added accordingly.
The usage docs have been updated.

Signed-off-by: Animesh Kumar animuz111@gmail.com

@coveralls
Copy link

coveralls commented May 2, 2020

Coverage Status

Coverage increased (+0.04%) to 97.833% when pulling a4155de on animeshk08:rocket-chat into 7f4cceb on chaoss:master.

if not self.from_archive:
self.sleep_for_rate_limit()

response = super().fetch(url, payload, headers=headers)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @valeriocos, Please have a look at this line.
In case a user provides a wrong Channel Name or User Id, an HTTP error is raised here. In that case, the log includes error.response.reason which is not that deductive. The actual cause for the error is returned in the body of the response. Hence I initially made the below change.

try:
      response = super().fetch(url, payload, headers=headers)
except requests.exceptions.HTTPError as error:
      logger.error(error.response.text)
      raise error

However, I think such a situation may happen in other APIs as well.(I found it in Pagure, Gitter, Groups.io when working with them) Hence, instead of addressing this in the backend a change in the core client should be addressed in separate PR.
WDYT?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea @animeshk08! I understand that the improvement should be made at https://github.com/chaoss/grimoirelab-perceval/blob/master/perceval/client.py#L182

Please open a new issue when you have time, and we can discuss there how to proceed, thanks!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I saw many error messages that were confusing in the backends.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @lukaszgryglicki for the feedback. The PR #672 tries to fix the problem, but the solution is still not good.

It would be great if you can add to the corresponding issue (#671), some examples of error messages that are confusing for you. Thanks

@animeshk08
Copy link
Contributor Author

Hi @valeriocos. Please have a look at this PR when you have time :)

Copy link
Member

@valeriocos valeriocos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @animeshk08 for taking over this PR. I left some comments, please add also the release note, thanks!



class RocketChat(Backend):
"""Rocket Chat backend.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The upstream server is mentioned in the code as Rocket Chat, Rocket.chat and RocketChat. For consistency with the README, we should use Rocket.Chat.

This comment applies to the rest of the code (please look for Rocket in the code)


This method parses a JSON stream, containing the history of
a channel, and returns a list with the parsed data. It also
returns if there are more messages that are not included on
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The second sentence isn't clear, I guess it refers to total. If this is the case, a possible rewriting could be:

This method parses a JSON stream, containing the history of
a channel. It returns a list of messages and the total messages count in that channel.

WDYT?


@staticmethod
def parse_channel_info(raw_channel_info):
"""Parse a user's info JSON stream.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docstring isn't aligned with the title and logic of the method

def has_resuming(cls):
"""Returns whether it supports to resume the fetch process.

:returns: this backend does supports items resuming
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo does supports

return response

def messages(self, channel, from_date, offset):
"""Fetch messages from a channel."""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add to this docstring the details how the messages are fetched (for instance, in ascending order based on the time they were last updated)? Thanks

I'm asking this because the value 1 in the sort params isn't clear. Info about that value is here https://rocket.chat/docs/developer-guides/rest-api/offset-and-count-and-sort-info/

if not self.from_archive:
self.sleep_for_rate_limit()

response = super().fetch(url, payload, headers=headers)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea @animeshk08! I understand that the improvement should be made at https://github.com/chaoss/grimoirelab-perceval/blob/master/perceval/client.py#L182

Please open a new issue when you have time, and we can discuss there how to proceed, thanks!

An API token and a User Id is required to access the server.

:param url: server url from where messages are to be fetched
:param user_id: generated user-id using your RocketChat account
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we switch user_id with channel? The current sequence url, user_id, channel doesn't seem logical to me.

action.required = True

# Required argument
parser.parser.add_argument('-u', '--user_id',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why --user_id is separated from the other positional arguments? What's the difference?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When running perceval rocketchat --help, the user_id appears as an optional argument (see below), however it doesn't seem possible to fetch messages without providing an user_id.

[2020-05-03 11:06:14,424] - Sir Perceval is on his quest.
usage: perceval [-h] [--category CATEGORY] [--tag TAG] [--filter-classified]
                [--from-date FROM_DATE] -t API_TOKEN
                [--archive-path ARCHIVE_PATH] [--no-archive] [--fetch-archive]
                [--archived-since ARCHIVED_SINCE] [--no-ssl-verify]
                [-o OUTFILE] [--json-line] [-u USER_ID]
                [--max-items MAX_ITEMS] [--sleep-for-rate]
                [--min-rate-to-sleep MIN_RATE_TO_SLEEP]
                url channel

positional arguments:
  url                   URL of the RocketChat server
  channel               RocketChat channel(room) name

optional arguments:
  -h, --help            show this help message and exit
  -u USER_ID, --user_id USER_ID
                        User Id to fetch messages

...

If line 377 is changed to the code below, the user_id appears as a positional argument

parser.parser.add_argument('user_id',
                                   help="User Id to fetch messages")

self.assertEqual(backend.max_items, MAX_ITEMS)

# When tag is empty or None it will be set to
# the value in uri
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

URI should be URL

self.assertEqual(client.min_rate_to_sleep, 1)

@httpretty.activate
def test_message(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing s at the end.

@animeshk08
Copy link
Contributor Author

Hi @valeriocos I have made the updates requested, please have a look :)

Copy link
Member

@valeriocos valeriocos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @animeshk08 for addressing the previous comments! Please have a look at the last ones!

Feel free to start the development of the ELK connectors, so we can have an early evaluation of this new backend (and provide corrections if needed before merging this PR).

Thanks!

action.required = True

# Required positional arguments
parser.parser.add_argument('user_id',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be after channel to be consistent with the position of the params at https://github.com/chaoss/grimoirelab-perceval/pull/661/files#diff-5933efe10c89e406b289947bcf03c4e5R73

README.md Outdated

Rocket.Chat backend needs an API token and a User Id to authenticate to the server.
```
$ perceval rocketchat -t 'abchdefghij' --from-date '2020-05-02' 1234abcd https://open.rocket.chat general
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1234abcd should be at the end

@animeshk08
Copy link
Contributor Author

Thank you for your reviews @valeriocos. I have made the changes!

Feel free to start the development of the ELK connectors, so we can have an early evaluation of this new backend (and provide corrections if needed before merging this PR).

Sure I am on it!

Copy link
Member

@valeriocos valeriocos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @animeshk08 , I hope you are fine!

I understand that you are working on chaoss/grimoirelab-elk#876, and I have some feeback regarding it.

I made a quick test to see how the current Perceval implementation will shape how to pass the params via the projects.json. If we keep it as it is, we should include the user id in the projects.json as follows:

       "rocketchat": [
            "https://open.rocket.chat general AvCH4MNPFbXQ6nSQA"
        ]

However, since the same user_id can be used to fetch more channels, the projects.json will contain redundant information (the user_id will appear for every channel we are fetching). I would suggest to apply the change below to the user_id argument (as similarly done for groupsio).

diff --git a/perceval/backends/core/rocketchat.py b/perceval/backends/core/rocketchat.py
index 5b9a933..b41f302 100644
--- a/perceval/backends/core/rocketchat.py
+++ b/perceval/backends/core/rocketchat.py
@@ -385,7 +385,7 @@ class RocketChatCommand(BackendCommand):
         parser.parser.add_argument('channel',
                                    help="Rocket.Chat channel(room) name")
 
-        parser.parser.add_argument('user_id',
+        parser.parser.add_argument('-u', '--user-id', dest='user_id',
                                    help="User Id to fetch messages")

With this modification, the projects.json will look like the one below, and we will be able to put the user_id in the setup.cfg, WDYT?

       "rocketchat": [
            "https://open.rocket.chat general"
        ]
[rocketchat]
api-token = ...
raw_index = rocketchat_today_raw
user-id = AvCH4MNPFbXQ6nSQA
enriched_index = rocketchat_today_enriched
sleep-for-rate = true

Thanks for working on the support for RocketChat!

'channel_id': ['channel_info', '_id']
}

def __init__(self, url=None, channel=None, user_id=None, api_token=None,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The following params are mandatory, the default value can be removed
def __init__(self, url, channel, user_id, api_token, ..)

WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, I have updated it :)

PCOUNT = "count"
POLDEST = "oldest"

def __init__(self, url=None, user_id=None, api_token=None, max_items=MAX_ITEMS,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar comment as above, if url, user_id and api_token are mandatory, the default values are not needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, I have updated it :)

@animeshk08 animeshk08 force-pushed the rocket-chat branch 2 times, most recently from a6e883a to 4b2496e Compare May 26, 2020 21:48
This commit adds support to fetch
messages from a Rocket.Chat channel.

The tests have been added accordingly.
The usage docs have been updated.
Release notes have also been added.

Signed-off-by: Animesh Kumar <animuz111@gmail.com>
@animeshk08
Copy link
Contributor Author

Reply #661 (review)

I had the same thought process, while initially working on this backend(#661 (comment)).
I missed to justify the reason at that time, Thank you for pointing this out :)

Copy link
Member

@valeriocos valeriocos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks @animeshk08 ! Nice work!

@valeriocos valeriocos merged commit 48eff53 into chaoss:master May 27, 2020
@valeriocos
Copy link
Member

valeriocos commented May 27, 2020

Coveralls reports that the test coverage went down after merging, however the build reports a different info https://coveralls.io/builds/31056088

I have run the coverage locally and rocketchat is fully covered:

Name                                                                                                                                             Stmts   Miss  Cover   Missing
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
/home/slimbook/Escritorio/sources/perceval/perceval/backends/core/rocketchat.py                                                                    133      0   100%

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Feature request] Add support for Rocket.Chat
4 participants