1 | #!/usr/bin/env python3␊ |
2 | ␊ |
3 | #␊ |
4 | # This program is free software: you can redistribute it and/or modify␊ |
5 | # it under the terms of the GNU General Public License as published by␊ |
6 | # the Free Software Foundation, either version 3 of the License, or␊ |
7 | # (at your option) any later version.␊ |
8 | #␊ |
9 | # This program is distributed in the hope that it will be useful,␊ |
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of␊ |
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the␊ |
12 | # GNU General Public License for more details.␊ |
13 | #␊ |
14 | # You should have received a copy of the GNU General Public License␊ |
15 | # along with this program. If not, see <https://www.gnu.org/licenses/>.␊ |
16 | #␊ |
17 | ␊ |
18 | '''␊ |
19 | Display random picture from unsplash.com in a popup␊ |
20 | ␊ |
21 | * Click : open/close popup␊ |
22 | * Popup item click : display who clicked␊ |
23 | * ScrollUp/ScrollDown/Double click : display next picture␊ |
24 | * Right click : exit␊ |
25 | '''␊ |
26 | ␊ |
27 | import urllib.request␊ |
28 | import sys␊ |
29 | import signal␊ |
30 | from genericmonitor import *␊ |
31 | ␊ |
32 | ␊ |
33 | class PicturePopup(GenericMonitor):␊ |
34 | ␊ |
35 | def __init__(self):␊ |
36 | self.scrolling = False␊ |
37 | self.item = None␊ |
38 | self.imgs_idx = 0␊ |
39 | self.setupMonitor()␊ |
40 | ␊ |
41 | def run(self):␊ |
42 | self.display_next_img()␊ |
43 | self.runMainLoop()␊ |
44 | ␊ |
45 | def display_next_img(self):␊ |
46 | filedata = urllib.request.urlopen('https://source.unsplash.com/random')␊ |
47 | # Get redirected URL without parameters␊ |
48 | url = filedata.url.split('?')[0]␊ |
49 | filedata = urllib.request.urlopen(url + '?fit=max&width=500&height=500')␊ |
50 | datatowrite = filedata.read()␊ |
51 | with open('/tmp/cat2.jpg', 'wb') as f:␊ |
52 | f.write(datatowrite)␊ |
53 | widget = GenericMonitorTextWidget('#%d' % self.imgs_idx, 'color:purple')␊ |
54 | url_widget = GenericMonitorTextWidget(url, 'color:white;font-weight:bold', signals={'on-click':'signal'}) # No name here␊ |
55 | picture_widget = GenericMonitorPictureWidget('/tmp/cat2.jpg', name='NestedWidget', signals={'on-click':'signal'})␊ |
56 | popup = GenericMonitorPopup([url_widget, picture_widget])␊ |
57 | signals = {␊ |
58 | 'on-click':'toggle-popup',␊ |
59 | # Could also use this behavior [bugged since GNOME 42]␊ |
60 | # 'on-enter':'open-popup',␊ |
61 | # 'on-leave':'close-popup',␊ |
62 | 'on-dblclick':'signal',␊ |
63 | 'on-rightclick':'signal',␊ |
64 | 'on-scroll':'signal',␊ |
65 | }␊ |
66 | self.item = GenericMonitorItem('picturepopup', [widget], signals, popup)␊ |
67 | group = GenericMonitorGroup('PicturePopup', [self.item])␊ |
68 | self.notify(group)␊ |
69 | self.imgs_idx += 1␊ |
70 | ␊ |
71 | def _forMe(self, sender):␊ |
72 | return str(sender).endswith(self.item.getFullName())␊ |
73 | ␊ |
74 | def onClick(self, sender):␊ |
75 | if not self._forMe(sender): return␊ |
76 | print('Click from {}'.format(sender))␊ |
77 | ␊ |
78 | def _onScroll(self, sender):␊ |
79 | if not self._forMe(sender): return␊ |
80 | if self.scrolling: return␊ |
81 | self.scrolling = True␊ |
82 | self.display_next_img()␊ |
83 | self.scrolling = False␊ |
84 | ␊ |
85 | def onScrollUp(self, sender):␊ |
86 | self._onScroll(sender)␊ |
87 | ␊ |
88 | def onScrollDown(self, sender):␊ |
89 | self._onScroll(sender)␊ |
90 | ␊ |
91 | def onDblClick(self, sender):␊ |
92 | self.onScrollUp(sender)␊ |
93 | ␊ |
94 | def onRightClick(self, sender):␊ |
95 | if not self._forMe(sender): return␊ |
96 | if self.item:␊ |
97 | self.deleteItems([self.item.getFullName()])␊ |
98 | self.stopMainLoop()␊ |
99 | ␊ |
100 | def signal_handler(sig, frame):␊ |
101 | picture.deleteGroups(['PicturePopup'])␊ |
102 | sys.exit(0)␊ |
103 | signal.signal(signal.SIGINT, signal_handler)␊ |
104 | ␊ |
105 | picture = PicturePopup()␊ |
106 | picture.run()␊ |