Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,41 @@ Tips
----

* Rooms in ErrBot are streams in Zulip.

Directly send message to room
----
when a time you need errbot work like api

* Example Code

`#{{stream}}*{{topic}}`
```python
self.send(
self.build_identifier("#{{code_runtime_alert}}*{{hello}}"),
"your message here"
)
```

* A demo errbot api for log your code exception in a specific zulip room

``` python
@webhook
def cra(self, request):
self.log.debug(repr(request))
if type(request) is dict:
# self.log.info(request)
if request['type'] == 'exception':
response = tenv().get_template('exception.md').render(request)
# self.log.info(response)
self.send(
self.build_identifier("#{{{{{stream}}}}}*{{{{{topic}}}}}".format(
stream=request['stream'],
topic=request['topic']
)),
response
)
return "{'status': '100'}"
else:
return "{'status': '999'}"

```
109 changes: 105 additions & 4 deletions zulip.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from errbot.rendering.ansiext import enable_format, TEXT_CHRS

from urllib.parse import quote
import re

# Can't use __name__ because of Yapsy.
log = logging.getLogger('errbot.backends.zulip')
Expand Down Expand Up @@ -293,11 +294,111 @@ def change_presence(self, status: str = ONLINE, message: str = '') -> None:
# At this time, Zulip doesn't support active presence change.
pass

@staticmethod
def check_email(email):
regex_email = re.compile(r'^.+@([?)[a-zA-Z0-9-.]+.([a-zA-Z]{2,3}|[0-9]{1,3})(]?))$')
if regex_email.match(email) != None:
return True
else:
return False

def extract_identifiers_from_string(self, text):
"""
extract username streamname topicname from text
:param text:
:return username streamname topicname:
"""

exception_message = (
'Unparseable zulip identifier, should be of the format `#{{stream}}*{{topic}}`,'
'`@U12345`. (Got `%s`)'
)
text = text.strip()

if text == '':
raise ValueError(exception_message % '')

username = None
streamname = None
topicname = None

regex_str_stream = r'#{{(.*)}}$'
regex_str_topic = r'\*{{(.*)}}$'
regex_str_user = r'@{{(.*)}}$'

regex_stream = re.compile(regex_str_stream)
regex_topic = re.compile(regex_str_topic)
regex_user = re.compile(regex_str_user)

if self.check_email(text):
username = text

if text[0] == "#":
Copy link
Collaborator

Choose a reason for hiding this comment

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

The logic in this if-statement is rather complicated. Perhaps there is a simpler way to parse this? Maybe something that involves extracting every occurrence of {{}} and making the if-statements switch based on the number of these statements.

Copy link
Author

Choose a reason for hiding this comment

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

sry for my poor regex skill, if you have some cool idea, just instead of using my poor code

if '*{{' in text:
tmp_text = text.split('*{{')
try:
tmp_text[1] = '*{{' + tmp_text[1]
except Exception as e:
pass
re_res = regex_stream.search(tmp_text[0])
if re_res:
if len(re_res.groups()) > 0:
streamname = re_res[1]
re_res = regex_topic.search(tmp_text[1])
if re_res:
if len(re_res.groups()) > 0:
topicname = re_res[1]
else:
re_res = regex_stream.search(text)
if re_res:
if len(re_res.groups()) > 0:
streamname = re_res[1]
elif text[0] == '@':
if text[1] != '{':
username= text
else:
re_res = regex_user.search(text)
if re_res:
if len(re_res.groups()) > 0:
username = re_res[1]
else:
raise ValueError(exception_message % text)

return username, streamname, topicname

def build_identifier(self, txtrep):
return ZulipPerson(id=txtrep,
full_name=txtrep,
emails=[txtrep],
client=self.client)

log.debug('building an identifier from %s.', txtrep)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Another debugging artifact.

Copy link
Collaborator

Choose a reason for hiding this comment

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

(Or do other backends actually log something here?)

if self.check_email(txtrep):
return ZulipPerson(
id=txtrep,
full_name=txtrep,
emails=[txtrep],
client=self.client
)
username, streamname, topicname = self.extract_identifiers_from_string(txtrep)

if username:
return ZulipPerson(
id=txtrep,
full_name=txtrep,
emails=[txtrep],
client=self.client
)
if streamname and not topicname:
return ZulipRoom(
id=streamname,
title=streamname,
subject='',
client=self.client,
)
elif streamname and topicname:
return ZulipRoom(
id=streamname,
title=streamname,
subject=topicname,
client=self.client,
)

def build_reply(self, msg, text=None, private=False, threaded=False):
response = self.build_message(text)
Expand Down