Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0057532

Browse files
authored
MSS: Add more way of customization to the output argument of save()
1 parent 5096ba1 commit 0057532

File tree

10 files changed

+89
-51
lines changed

10 files changed

+89
-51
lines changed

CHANGELOG

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
History:
22

3-
<see Git checkin messages for history>
3+
<see Git checking messages for history>
44

55
dev 2017/xx/xx
66
- add the 'Say Thanks' button
77
- doc: several fixes (fix #22)
88
- tests: a lot of tests added for better coverage
9+
- MSS: add more way of customization to the output argument of save()
910
- MSS: possibility to use custom class to handle screen shot data
1011
- Mac: handle screenshot's width not divisible by 16 (fix #14, #19, #21)
1112
- Mac: properly support all display scaling and resolutions (fix #23)
@@ -51,10 +52,10 @@ dev 2017/xx/xx
5152
- Linux: prevent segfault when DISPLAY is set but no X server started
5253
- Linux: prevent segfault when Xrandr is not loaded
5354
- Linux: get_pixels() insanely fast, use of MSS library (C code)
54-
- Windows: fix #6, screenshot not correct on Windows 8
55+
- Windows: fix #6, screen shot not correct on Windows 8
5556

5657
1.0.2 2016/04/22
57-
- MSS: fix inexistant alias
58+
- MSS: fix non existent alias
5859

5960
1.0.1 2016/04/22
6061
- MSS: fix #7, libpng warning (ignoring bad filter type)

docs/source/api.rst

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ Methods
3737

3838
.. method:: grab(monitor) -> ScreenShot
3939

40-
:param dict monitor: monitor's informations.
40+
:param dict monitor: monitor's information.
4141
:exception NotImplementedError: Subclasses need to implement this.
4242
:rtype: ScreenShot
4343

@@ -46,22 +46,32 @@ Methods
4646
.. note::
4747

4848
``monitor`` can be a ``tuple`` like ``PIL.Image.grab()`` accepts,
49-
it will be converted to the approriate ``dict``.
49+
it will be converted to the appropriate ``dict``.
5050

51-
.. method:: save(mon=1, output='screenshot.png', callback=None) -> generator
51+
.. method:: save(mon=1, output='mon-{mon}.png', callback=None) -> generator
5252

5353
:param int mon: the monitor's number.
54-
:param str output: the output's file name. ``%d``, if present, will be replaced by the monitor number.
55-
:param callable callback: callback called before saving the screenshot to a file. Takes the ``output`` argument as parameter.
54+
:param str output: the output's file name.
55+
:param callable callback: callback called before saving the screen shot to a file. Takes the ``output`` argument as parameter.
5656
:return generator: Created file(s).
5757

58-
Grab a screenshot and save it to a file.
58+
Grab a screen shot and save it to a file.
59+
The ``output`` parameter can take several keywords to customize the filename:
60+
61+
- ``{mon}``: the monitor number
62+
- ``{top}``: the screen shot y-coordinate of the upper-left corner
63+
- ``{left}``: the screen shot x-coordinate of the upper-left corner
64+
- ``{width}``: the screen shot's width
65+
- ``{height}``: the screen shot's height
66+
- ``{date}``: the current date using the default formatter
67+
68+
As it is using the `py::format()` function, you can specify formatting options like ``{date:%Y-%m-%s}``.
5969

6070
.. method:: shot() -> str
6171

6272
:return str: The created file.
6373

64-
Helper to save the screenshot of the first monitor, by default.
74+
Helper to save the screen shot of the first monitor, by default.
6575
You can pass the same arguments as for ``save``.
6676

6777
.. versionadded:: 3.0.0
@@ -83,7 +93,7 @@ Methods
8393
:param int height: the monitor's height.
8494
:rtype: ScreenShot
8595

86-
Instanciate a new class given only screenshot's data and size.
96+
Instanciate a new class given only screen shot's data and size.
8797

8898
.. method:: pixels(coord_x, coord_y) -> Tuple[int, int, int]
8999

@@ -120,7 +130,7 @@ Properties
120130
If the monitor has rotation, you have to deal with it
121131
inside this method.
122132

123-
This method has to fill ``self._monitors`` with all informations
133+
This method has to fill ``self._monitors`` with all information
124134
and use it as a cache:
125135

126136
- ``self._monitors[0]`` is a dict of all monitors together
@@ -145,19 +155,19 @@ Properties
145155

146156
.. attribute:: pos
147157

148-
The screen shot's coodinates.
158+
The screen shot's coordinates.
149159

150160
:type: NamedTuple
151161

152162
.. attribute:: top
153163

154-
The screen shot's top coodinate.
164+
The screen shot's top coordinate.
155165

156166
:type: int
157167

158168
.. attribute:: left
159169

160-
The screen shot's left coodinate.
170+
The screen shot's left coordinate.
161171
:type: int
162172

163173
.. attribute:: size

docs/source/developers.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ Enable the developer mode::
3333

3434
$ python -m pip install -e .
3535

36-
Lauch the test suit::
36+
Launch the test suit::
3737

3838
$ py.test
3939

docs/source/examples/callback.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,5 @@ def on_exists(fname):
2525

2626

2727
with mss.mss() as sct:
28-
filename = sct.shot(output='mon-%d.png', callback=on_exists)
28+
filename = sct.shot(output='mon-{mon}.png', callback=on_exists)
2929
print(filename)

docs/source/examples/custom_cls_image.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class SimpleScreenShot(object):
1616
or add new methods.
1717
"""
1818

19-
def __init__(self, data, monitor):
19+
def __init__(self, data, monitor, **kwargs):
2020
self.data = data
2121
self.monitor = monitor
2222

docs/source/support.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Feel free to try MSS on a system we had not tested, and let report us by creatin
1111
+----------+-----------+-------------+-----------+
1212
| **3.6** | **True** | **True** | **True** |
1313
+----------+-----------+-------------+-----------+
14-
| 3.5 | True | True | True |
14+
| 3.5 | True | True | True |
1515
+----------+-----------+-------------+-----------+
1616
| 3.4 | True | True | True |
1717
+----------+-----------+-------------+-----------+
@@ -31,7 +31,7 @@ Future
3131
Others
3232
======
3333

34-
Tested succesfully on Pypy 5.1.0 on Windows, but speed is terrible.
34+
Tested successfully on Pypy 5.1.0 on Windows, but speed is terrible.
3535

3636

3737
Abandoned

docs/source/where.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ This is a non exhaustive list where MSS is integrated or has inspired:
99
- `NativeShot <https://addons.mozilla.org/en-US/firefox/addon/nativeshot/>`_ (Mozilla Firefox module);
1010
- `Pombo <https://github.com/BoboTiG/pombo>`_;
1111
- `Stitch <https://nathanlopez.github.io/Stitch/>`_, a Python Remote Administration Tool (RAT);
12-
- `and you pherhaps? <https://github.com/BoboTiG/python-mss/issues>`_
12+
- `and you perhaps? <https://github.com/BoboTiG/python-mss/issues>`_

mss/base.py

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
Source: https://github.com/BoboTiG/python-mss
55
"""
66

7+
from datetime import datetime
8+
79
from .exception import ScreenShotError
810
from .screenshot import ScreenShot
911
from .tools import to_png
@@ -59,28 +61,36 @@ def monitors(self):
5961
}
6062
6163
Note: monitor can be a tuple like PIL.Image.grab() accepts,
62-
it must be converted to the approriate dict.
64+
it must be converted to the appropriate dict.
6365
"""
6466

6567
raise NotImplementedError('Subclasses need to implement this!')
6668

67-
def save(self, mon=0, output='monitor-%d.png', callback=None):
69+
def save(self, mon=0, output='monitor-{mon}.png', callback=None):
6870
# type: (int, str, Callable[[str], None]) -> Iterator[str]
6971
"""
70-
Grab a screenshot and save it to a file.
72+
Grab a screen shot and save it to a file.
7173
72-
:param int mon: The monitor to screenshot (default=0).
73-
-1: grab one screenshot of all monitors
74-
0: grab one screenshot by monitor
75-
N: grab the screenshot of the monitor N
74+
:param int mon: The monitor to screen shot (default=0).
75+
-1: grab one screen shot of all monitors
76+
0: grab one screen shot by monitor
77+
N: grab the screen shot of the monitor N
7678
7779
:param str output: The output filename.
78-
%d, if present, will be replaced by
79-
the monitor number.
8080
81-
:param callable callback: Callback called before saving
82-
the screenshot to a file.
83-
Take the ``output`` argument as parameter.
81+
It can take several keywords to customize the filename:
82+
- `{mon}`: the monitor number
83+
- `{top}`: the screen shot y-coordinate of the upper-left corner
84+
- `{left}`: the screen shot x-coordinate of the upper-left corner
85+
- `{width}`: the screen shot's width
86+
- `{height}`: the screen shot's height
87+
- `{date}`: the current date using the default formatter
88+
89+
As it is using the `format()` function, you can specify
90+
formatting options like `{date:%Y-%m-%s}`.
91+
92+
:param callable callback: Callback called before saving the
93+
screen shot to a file. Take the `output` argument as parameter.
8494
8595
:return generator: Created file(s).
8696
"""
@@ -90,27 +100,24 @@ def save(self, mon=0, output='monitor-%d.png', callback=None):
90100
raise ScreenShotError('No monitor found.')
91101

92102
if mon == 0:
93-
# One screenshot by monitor
94-
for i, monitor in enumerate(monitors[1:], 1):
95-
fname = output
96-
if '%d' in output:
97-
fname = output.replace('%d', str(i))
103+
# One screen shot by monitor
104+
for idx, monitor in enumerate(monitors[1:], 1):
105+
fname = output.format(mon=idx, date=datetime.now(), **monitor)
98106
if callable(callback):
99107
callback(fname)
100108
sct = self.grab(monitor)
101109
to_png(sct.rgb, sct.size, fname)
102110
yield fname
103111
else:
104-
# A screenshot of all monitors together or
105-
# a screenshot of the monitor N.
106-
mon_number = 0 if mon == -1 else mon
112+
# A screen shot of all monitors together or
113+
# a screen shot of the monitor N.
114+
mon = 0 if mon == -1 else mon
107115
try:
108-
monitor = monitors[mon_number]
116+
monitor = monitors[mon]
109117
except IndexError:
110118
raise ScreenShotError('Monitor does not exist.', locals())
111119

112-
if '%d' in output:
113-
output = output.replace('%d', str(mon_number))
120+
output = output.format(mon=mon, date=datetime.now(), **monitor)
114121
if callable(callback):
115122
callback(output)
116123
sct = self.grab(monitor)
@@ -119,7 +126,7 @@ def save(self, mon=0, output='monitor-%d.png', callback=None):
119126

120127
def shot(self, **kwargs):
121128
"""
122-
Helper to save the screenshot of the 1st monitor, by default.
129+
Helper to save the screen shot of the 1st monitor, by default.
123130
You can pass the same arguments as for ``save``.
124131
"""
125132

mss/screenshot.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,33 +68,33 @@ def __array_interface__(self):
6868
@classmethod
6969
def from_size(cls, data, width, height):
7070
# type: (bytearray, int, int) -> ScreenShot
71-
""" Instanciate a new class given only screenshot's data and size. """
71+
""" Instantiate a new class given only screen shot's data and size. """
7272

7373
monitor = {'left': 0, 'top': 0, 'width': width, 'height': height}
7474
return cls(data, monitor)
7575

7676
@property
7777
def top(self):
7878
# type: () -> int
79-
""" Conveniant accessor to the top position. """
79+
""" Convenient accessor to the top position. """
8080
return self.pos.top
8181

8282
@property
8383
def left(self):
8484
# type: () -> int
85-
""" Conveniant accessor to the left position. """
85+
""" Convenient accessor to the left position. """
8686
return self.pos.left
8787

8888
@property
8989
def width(self):
9090
# type: () -> int
91-
""" Conveniant accessor to the width size. """
91+
""" Convenient accessor to the width size. """
9292
return self.size.width
9393

9494
@property
9595
def height(self):
9696
# type: () -> int
97-
""" Conveniant accessor to the height size. """
97+
""" Convenient accessor to the height size. """
9898
return self.size.height
9999

100100
@property

tests/test_save.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# coding: utf-8
22

33
import os.path
4-
import mss
4+
from datetime import datetime
55

66

77
def test_at_least_2_monitors(sct):
@@ -31,3 +31,23 @@ def on_exists(fname):
3131

3232
filename = sct.shot(output='mon1.png', callback=on_exists)
3333
assert os.path.isfile(filename)
34+
35+
36+
def test_output_format(sct):
37+
filename = sct.shot(mon=1, output='mon-{mon}.png')
38+
assert filename == 'mon-1.png'
39+
assert os.path.isfile(filename)
40+
41+
fmt = 'sct-{top}x{left}_{width}x{height}.png'
42+
filename = sct.shot(mon=1, output=fmt)
43+
assert filename == fmt.format(**sct.monitors[1])
44+
assert os.path.isfile(filename)
45+
46+
fmt = 'sct_{mon}-{date}.png'
47+
filename = sct.shot(mon=1, output=fmt)
48+
assert os.path.isfile(filename)
49+
50+
fmt = 'sct_{date:%Y-%m-%d}.png'
51+
filename = sct.shot(mon=1, output=fmt)
52+
assert filename == fmt.format(date=datetime.now())
53+
assert os.path.isfile(filename)

0 commit comments

Comments
 (0)