1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
# coding=utf-8
# pystray
# Copyright (C) 2016-2022 Moses Palmér
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from __future__ import print_function
import itertools
from PIL import Image, ImageDraw
from six.moves import input
import pystray
from pystray import MenuItem as item
COLORS = itertools.cycle((
'black',
'white',
'red',
'yellow',
'blue',
'red',
'green',
'white'))
def say(*args, **kwargs):
"""Prints a message, ensuring space between messages.
"""
print('\n')
print(*args, **kwargs)
def action(on_activate):
"""A convenience function to create a hidden default menu item.
:param callable on_activate: The activation callback.
"""
return item('Default', on_activate, default=True, visible=False)
def separator():
"""A wrapper around :attr:`pystray.Menu.SEPARATOR`.
"""
return pystray.Menu.SEPARATOR
def icon(no_image=False, **kwargs):
"""Generates a systray icon with the specified colours.
A systray icon created by this method will be automatically hidden
when the current test finishes.
:return: the tuple ``(icon, colors)``, where ``icon`` is a
hidden systray icon, and ``colors`` is the ``colors`` return value
of :meth:`image`.
"""
img, colors = image()
ico = pystray.Icon(
'test',
icon=img if not no_image else None,
**kwargs)
return ico, colors
def image(width=64, height=64):
"""Generates an icon image.
:return: the tuple ``(image, colors)``, where ``image`` is a
*PIL* image and ``colors`` is a tuple containing the colours as
*PIL* colour names, suitable for printing; the stringification of
the tuple is also suitable for printing
"""
class Colors(tuple):
def __str__(self):
return ' and '.join(self)
colors = Colors((next_color(), next_color()))
img = Image.new('RGB', (width, height), colors[0])
dc = ImageDraw.Draw(img)
dc.rectangle((width // 2, 0, width, height // 2), fill=colors[1])
dc.rectangle((0, height // 2, width // 2, height), fill=colors[1])
return img, colors
def next_color():
"""Returns the next colour to use.
"""
return next(COLORS)
def confirm(self, statement, *fmt):
"""Asks the user to confirm a statement.
:param self: An instance of a test suite.
:param str statement: The statement to confirm.
:raises AssertionError: if the user does not confirm
"""
valid_responses = ('yes', 'y', 'no', 'n')
accept_responses = valid_responses[:2]
message = ('\n' + statement % fmt) + ' '
while True:
response = input(message)
if response.lower() in valid_responses:
self.assertIn(
response.lower(), accept_responses,
'User declined statement "%s"' % message)
return
else:
print(
'Please respond %s' % ', '.join(
'"%s"' % r for r in valid_responses))
def true(*args):
"""Returns ``True``.
"""
return True
|