Skip to content
This repository has been archived by the owner on Jan 23, 2021. It is now read-only.

Commit

Permalink
Support reply to channel directly (#5)
Browse files Browse the repository at this point in the history
* Support reply to channel directly

* Support pylint
  • Loading branch information
ahelal authored Aug 29, 2017
1 parent cea6988 commit f5931a7
Show file tree
Hide file tree
Showing 11 changed files with 53 additions and 29 deletions.
5 changes: 2 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ python:
- "2.7"
# - "3.6"

# command to install dependencies
install:
- "pip install -r requirements.txt"
- "pip install nose coverage"
# command to run tests
- "pip install nose coverage pylint"

script: make tests-detail
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ tests-detail:
$(info $(M) Running tests for $(VERSION))
@PYTHONPATH="src/lib" nosetests --detailed-errors -w "src/tests" -vv --nocapture \
--with-coverage --cover-package=base,check_op,in_op,out_op,payload
@pylint src/lib/*.py

push:
$(info $(M) Pushing $(NAME):$(VERSION) )
Expand Down
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,15 @@ In accepts no params.

### `out`: Reply to original message

Replies to the original message in a thread format.
Replies with a message to the selected `channel`.

#### `out Parameters`

* `path`: *Required.* The path of the resource name.
* `reply`: *Required*. The message to be used as reply. Supports [template format](#template).

* `reply`: *Required.* The message to be used as reply. Supports [template format](#template).
* `reply_thread`: *optional*, *default `False`*. If enabled will post reply to original message as a thread.

* `path`: *required*. The path of the resource name. This is used to get context from original message.

### Template

Expand Down Expand Up @@ -96,6 +98,8 @@ The template uses python [Jinja2](http://jinja.pocoo.org/docs/2.9/) engine.

## TODO

* Support reading from a file for `template` and `reply`
* Refactor and simplify logic of check_logic_unread
* Increase code coverage

## Contribution
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.0.3
0.0.4
2 changes: 1 addition & 1 deletion src/lib/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def fail_unless(condition, msg):
exit(1)


class Base(object):
class Base(object): # pylint: disable=too-few-public-methods,too-many-instance-attributes
"""Slack Concourse resource implementation"""

def __init__(self, **kwargs):
Expand Down
2 changes: 1 addition & 1 deletion src/lib/check_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ def _parse_msgs(self, messages, index):

def check_logic_unread(self, max_api_count=100):
"""Concourse resource `check` logic using unread mark by slack"""
# TODO: (A) Simplify the check logic :(
latest_ts = 0
msgs_2_return = max_api_count
unread_counter = 1
Expand Down Expand Up @@ -93,6 +92,7 @@ def check_output(self):
print(json.dumps(self.checked_msg, indent=4, sort_keys=True))

def main():
"""Concourse resource `check` main """
payload = PayLoad()
slack_client = Check(**payload.args)

Expand Down
3 changes: 1 addition & 2 deletions src/lib/in_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from __future__ import print_function

import json
import sys
import os

from payload import PayLoad
Expand Down Expand Up @@ -45,7 +44,7 @@ def in_logic(self):
{"name": "Message", "value": text}]

def in_output(self):
"""Concourse resource `in` output """
"""Concourse resource `in` main """

output = {"version": self.version, "metadata": self.metadata, "original_msg": self.original_msg}
# Write response as bender.json for further use
Expand Down
27 changes: 18 additions & 9 deletions src/lib/out_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import json
import os
import sys

from payload import PayLoad
from base import Base, fail_unless, template_with_regex
Expand All @@ -18,26 +17,35 @@ def __init__(self, **kwargs):
self.metadata = []
self.path = kwargs.get("path", False)
self.reply = kwargs.get("reply", False)
self.reply_thread = kwargs.get("reply_thread", True)
self.bender_json_path = '{}/{}/bender.json'.format(self.working_dir, self.path)

def _reply(self, thread_timestamp, text):
args = {}
if thread_timestamp:
args = {"thread_ts": thread_timestamp}

def _reply(self, timestamp, text):
self._call_api("chat.postMessage",
channel=self.channel_id,
thread_ts=timestamp,
text=text)
text=text,
**args)

def out_logic(self):
"""Concourse resource `out` logic """
output_file = '{}/{}/bender.json'.format(self.working_dir, self.path)
fail_unless(os.path.isfile(output_file), "Failed to get version info from file {}".format(output_file))

with open(output_file) as bender_file:
fail_unless(os.path.isfile(self.bender_json_path), "Failed to get version info from file {}".format(self.bender_json_path))
with open(self.bender_json_path) as bender_file:
output_data = json.load(bender_file)
self.version = output_data["version"]
self.metadata = output_data["metadata"]
regex = self._msg_grammar(output_data["original_msg"])
templated_reply = template_with_regex(self.reply, regex)
# template reply
self._reply(self.version["id_ts"], templated_reply)

if self.reply_thread:
reply_to_thread = self.version["id_ts"]
else:
reply_to_thread = False
self._reply(reply_to_thread, templated_reply)

def out_output(self):
"""Concourse resource `out` output """
Expand All @@ -46,6 +54,7 @@ def out_output(self):


def main():
''' Main `out` entry point'''
payload = PayLoad()
fail_unless(payload.args.get("path", False), "path is required")
fail_unless(payload.args.get("reply", False), "reply is required")
Expand Down
10 changes: 5 additions & 5 deletions src/lib/payload.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@

from base import fail_unless


class PayLoad(object):
class PayLoad(object): # pylint: disable=too-few-public-methods
''' Payload class '''

def __init__(self):
Expand All @@ -20,7 +19,7 @@ def __init__(self):
fail_unless(False, "Source not configured.")
else:
self.params = self.payload.get("params", {})
self._parse_payload()
self.parse_payload()
self.args["working_dir"] = self._get_dir_from_argv()

@staticmethod
Expand All @@ -40,8 +39,8 @@ def _get_dir_from_argv():
fail_unless(os.path.isdir(sys.argv[1]), "Invalid dir argument passed '{}'".format(sys.argv[1]))
return sys.argv[1]

def _parse_payload(self):
# Version send by concourses in check and get
def parse_payload(self):
''' Parse payload passed by concourse'''
self.args["version"] = self.payload.get("version")
try:
# Mandatory source configs
Expand All @@ -58,3 +57,4 @@ def _parse_payload(self):
# Optional params config
self.args["path"] = self.params.get("path")
self.args["reply"] = self.params.get("reply")
self.args["reply_thread"] = self.params.get("reply_thread", True)
16 changes: 13 additions & 3 deletions src/tests/test_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,19 @@ def setUp(self, mock_call_api, mock_get_channel_group_info, mock_filter):
mock_filter.return_value = "U01B12FDS"

self.grammar = "^(superApp)\s+(deploy)\s+(live|staging)\s+(\S+)($|\s+)"
self.resource = out_op.Out(token="token", channel="testChannel", bot="theBender",
template="VERSION={{ regex[4] }}", template_file="template_file.txt",
grammar=self.grammar, path="bender_path", reply="testing 1.2.3")
self.resource = out_op.Out(token="token", channel="testChannel", bot="theBender", working_dir="/tmp",
grammar=self.grammar, path="bender_path", reply="testing 1.2.3",
reply_thread="reply_thread")

def test__init__(self):
# Channel info
self.assertEqual(self.resource.bender_json_path, "/tmp/bender_path/bender.json")
self.assertEqual(self.resource.path, "bender_path")
self.assertEqual(self.resource.reply, "testing 1.2.3")
self.assertEqual(self.resource.reply_thread, "reply_thread")
self.assertEqual(self.resource.working_dir, "/tmp")

#self.bender_json_path = '{}/{}/bender.json'.format(self.working_dir, self.path)

@mock.patch('out_op.json.dumps')
@mock.patch('out_op.print', create=True)
Expand Down
4 changes: 3 additions & 1 deletion src/tests/test_payload.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,14 @@ def test_parse_payload_defaults(self, mock_get_payload, mock_fail_unless, mock_g
self.assertIsNone(py.args["grammar"])
self.assertIsNone(py.args["path"])
self.assertIsNone(py.args["reply"])
self.assertTrue(py.args["reply_thread"])

@mock.patch('payload.PayLoad._get_dir_from_argv')
@mock.patch('payload.fail_unless')
@mock.patch('payload.PayLoad._get_payload')
def test_parse_payload_values(self, mock_get_payload, mock_fail_unless, mock_get_dir_from_argv):
mock_get_dir_from_argv.return_value = "/tmp"
mock_get_payload.side_effect = [{'params': {'path': 'path', 'reply': 'reply'},
mock_get_payload.side_effect = [{'params': {'path': 'path', 'reply': 'reply', "reply_thread": "reply_thread"},
'source': {'bot_name': 'bot_name',
'channel': 'channel',
'grammar': 'grammar',
Expand All @@ -94,3 +95,4 @@ def test_parse_payload_values(self, mock_get_payload, mock_fail_unless, mock_get
self.assertEqual(py.args["grammar"], "grammar")
self.assertEqual(py.args["path"], "path")
self.assertEqual(py.args["reply"], "reply")
self.assertEqual(py.args["reply_thread"], "reply_thread")

0 comments on commit f5931a7

Please sign in to comment.