Skip to content

Commit

Permalink
Restructure msg protocol to extend querying server
Browse files Browse the repository at this point in the history
- Modify actions to create BOARD and SEND
- SEND is equivalent to previous BOARD behaviour (send data to clipster).
- BOARD is now only for queries.
- CONTENT with BOARD is a regex pattern to filter results from server.
  • Loading branch information
mrichar1 committed Jul 20, 2017
1 parent 0361be7 commit 08e7f6f
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 23 deletions.
15 changes: 10 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,17 @@ optional arguments:
-c, --clipboard Query, or write STDIN to, the CLIPBOARD clipboard.
-d, --daemon Launch the daemon.
-s, --select Launch the clipboard history selection window.
-o, --output Output last selection from history. (See -n).
-o, --output Output last selection from history. (See -n and -S).
-i, --ignore Instruct daemon to ignore next update to clipboard.
-r [DELETE], --delete [DELETE]
Delete from clipboard. Deletes matching text, or if no
argument given, deletes last item.
-n NUMBER, --number NUMBER
Number of lines to output: defaults to 1 (See -o).
0 returns entire history.
-S SEARCH, --search SEARCH
Pattern to match for output.
-0, --nul Use NUL character as output delimiter.
-m DELIM, --delim DELIM
String to use as output delimiter (defaults to '\n')
```
Expand Down Expand Up @@ -290,13 +291,17 @@ Note: The final `:` separator is only included when content is present.
### Action: BOARD

This is the default action.
If content is none, return clipboard history (using count to determine the number of items to return).
If content is defined, add its value to the clipboard.
Return clipboard history (using count to determine the number of items to return).
If CONTENT is defined, use this as a regex pattern to filter history.

### Action: SEND

Add the value of CONTENT to the clipboard.

### Action: DELETE

Deletes an item from the clipboard.
If content is defined, delete by pattern match. Else delete the last item on the board.
If CONTENT is defined, delete by pattern match. Else delete the last item on the board.

### Action: SELECT

Expand Down
44 changes: 28 additions & 16 deletions clipster
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ class Client(object):
def __init__(self, config, args):
self.config = config
self.args = args
self.client_action = args.select and "SELECT" or (args.ignore and "IGNORE" or args.delete is not None and "DELETE" or "BOARD")
self.client_action = args.select and "SELECT" or (args.ignore and "IGNORE" or args.delete is not None and "DELETE" or args.search is not None and "BOARD" or args.output is not None and "BOARD" or "SEND")
logging.debug("client_action: %s", self.client_action)

def update(self):
Expand All @@ -116,7 +116,7 @@ class Client(object):
# Send delete args
sock.sendall(":{0}".format(self.args.delete).encode('utf-8'))

if self.client_action == "BOARD":
if self.client_action == "SEND":
# Send data read from stdin
buf_size = 8192
# Send another colon to show that content is coming
Expand Down Expand Up @@ -146,10 +146,13 @@ class Client(object):
raise ClipsterError("Error connecting to socket. Is daemon running?")
logging.debug("Sending request to server.")
# Send message 'header'
sock.sendall("{0}:{1}:{2}".format(self.client_action,
self.config.get('clipster',
'default_selection'),
self.args.number).encode('utf-8'))
message = "{0}:{1}:{2}".format(self.client_action,
self.config.get('clipster',
'default_selection'),
self.args.number)
if self.args.search:
message = "{0}:{1}".format(message, self.args.search)
sock.sendall(message.encode('utf-8'))

sock.shutdown(socket.SHUT_WR)
data = []
Expand Down Expand Up @@ -535,19 +538,24 @@ class Daemon(object):
logging.debug("Received: sig:%s, board:%s, count:%s", sig, board, count)
if sig == "SELECT":
self.selection_widget(board)
elif sig == "BOARD":
elif sig == "SEND":
if content is not None:
logging.debug("Received content: %s", content)
self.update_board(board, content)
else:
logging.debug("Sending requested selection(s): %s",
self.boards[board][-count:])
# Send list (reversed) as json to preserve structure
try:
conn.sendall(json.dumps(self.boards[board][-count:][::-1]).encode('utf-8'))
except (socket.error, OSError) as exc:
logging.error("Socket error %s", exc)
logging.debug("Exception:", exc_info=True)
raise ClipsterError("No content received!")
elif sig == "BOARD":
result = self.boards[board]
if content:
logging.debug("Searching for pattern: %s", content)
result = [x for x in self.boards[board] if re.search(content, x)]
logging.debug("Sending requested selection(s): %s", result[-count:][::-1])
# Send list (reversed) as json to preserve structure
try:
conn.sendall(json.dumps(result[-count:][::-1]).encode('utf-8'))
except (socket.error, OSError) as exc:
logging.error("Socket error %s", exc)
logging.debug("Exception:", exc_info=True)
elif sig == "IGNORE":
self.ignore_next[board] = True
elif sig == "DELETE":
Expand Down Expand Up @@ -695,14 +703,18 @@ def parse_args(default_conf_file):
actiongrp.add_argument('-s', '--select', action="store_true",
help="Launch the clipboard history selection window.")
actiongrp.add_argument('-o', '--output', action="store_true",
help="Output last selection from history. (See -n).")
help="Output selection from history. (See -n and -S).")
actiongrp.add_argument('-i', '--ignore', action="store_true",
help="Instruct daemon to ignore next update to clipboard.")
actiongrp.add_argument('-r', '--delete', action="store", nargs='?', const='',
help="Delete from clipboard. Deletes matching text, or if no argument given, deletes last item.")

parser.add_argument('-n', '--number', action="store", type=int, default=1,
help="Number of lines to output: defaults to 1 (See -o). 0 returns entire history.")

parser.add_argument('-S', '--search', action="store",
help="Pattern to match for output.")

# --delim must come before -0 to ensure delim is set correctly
# otherwise if neither arg is passed, delim=None
parser.add_argument('-m', '--delim', action="store", default='\n',
Expand Down
4 changes: 2 additions & 2 deletions tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ def test_max_input(self, mock_socket):
"""Test that the max_input limit works."""

max_input = self.config.getint('clipster', 'max_input')
header = "BOARD:PRIMARY:0:"
header = "SEND:PRIMARY:0:"
# Set the text to be the same length as max_input
# so that total length (plus header) exceeds it.
text = "x" * max_input
Expand Down Expand Up @@ -324,7 +324,7 @@ def test_process_msg_update(self, mock_update_board):
conn = mock.MagicMock()
conn.fileno.return_value = 1

action = 'BOARD'
action = 'SEND'
board = 'PRIMARY'
count = '0'
msg = 'Hello world\n'
Expand Down

0 comments on commit 08e7f6f

Please sign in to comment.