Add preliminary(!) support for bidirectional communication with i3bar
Novelty use only.
This commit is contained in:
parent
279c3504c2
commit
657bdb826a
@ -1,6 +1,7 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
import threading
|
||||||
|
|
||||||
from .core import util, io
|
from .core import util, io
|
||||||
from .core.modules import *
|
from .core.modules import *
|
||||||
@ -18,8 +19,12 @@ def main():
|
|||||||
|
|
||||||
class Status:
|
class Status:
|
||||||
def __init__(self, standalone=False, interval=1, input_stream=sys.stdin):
|
def __init__(self, standalone=False, interval=1, input_stream=sys.stdin):
|
||||||
|
self.standalone = standalone
|
||||||
if standalone:
|
if standalone:
|
||||||
self.io = io.StandaloneIO(interval)
|
self.io = io.StandaloneIO(interval)
|
||||||
|
self.ce_thread = threading.Thread(target=self.run_command_endpoint)
|
||||||
|
self.ce_thread.daemon = True
|
||||||
|
self.ce_thread.start()
|
||||||
else:
|
else:
|
||||||
self.io = io.IOHandler(input_stream)
|
self.io = io.IOHandler(input_stream)
|
||||||
|
|
||||||
@ -31,6 +36,13 @@ class Status:
|
|||||||
if module:
|
if module:
|
||||||
self.modules.append(module, *args, **kwargs)
|
self.modules.append(module, *args, **kwargs)
|
||||||
|
|
||||||
|
def run_command_endpoint(self):
|
||||||
|
for j in io.JSONIO(io=io.IOHandler(sys.stdin, io.DevNull()), skiplines=1).read():
|
||||||
|
if j["command"] == "block_clicked":
|
||||||
|
module = self.modules.get_by_id(j["instance"])
|
||||||
|
if module:
|
||||||
|
module.on_click()
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
for j in io.JSONIO(self.io).read():
|
for j in io.JSONIO(self.io).read():
|
||||||
for module in self.modules:
|
for module in self.modules:
|
||||||
|
@ -2,7 +2,13 @@
|
|||||||
import time
|
import time
|
||||||
import json
|
import json
|
||||||
import sys
|
import sys
|
||||||
|
import threading
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
|
import io
|
||||||
|
|
||||||
|
class DevNull(io.TextIOBase):
|
||||||
|
def write(self, string):
|
||||||
|
pass
|
||||||
|
|
||||||
class IOHandler:
|
class IOHandler:
|
||||||
def __init__(self, inp=sys.stdin, out=sys.stdout):
|
def __init__(self, inp=sys.stdin, out=sys.stdout):
|
||||||
@ -50,7 +56,7 @@ class StandaloneIO(IOHandler):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
n = -1
|
n = -1
|
||||||
proto = ('{"version":1}', "[", "[]", ",[]", )
|
proto = ('{"version":1,"bidirectional":1}', "[", "[]", ",[]", )
|
||||||
|
|
||||||
def __init__(self, interval=1):
|
def __init__(self, interval=1):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
@ -62,6 +68,7 @@ class StandaloneIO(IOHandler):
|
|||||||
time.sleep(self.interval)
|
time.sleep(self.interval)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
return
|
return
|
||||||
|
|
||||||
yield self.read_line()
|
yield self.read_line()
|
||||||
|
|
||||||
def read_line(self):
|
def read_line(self):
|
||||||
@ -70,10 +77,10 @@ class StandaloneIO(IOHandler):
|
|||||||
return self.proto[min(self.n, len(self.proto)-1)]
|
return self.proto[min(self.n, len(self.proto)-1)]
|
||||||
|
|
||||||
class JSONIO:
|
class JSONIO:
|
||||||
def __init__(self, io):
|
def __init__(self, io, skiplines=2):
|
||||||
self.io = io
|
self.io = io
|
||||||
self.io.write_line(self.io.read_line())
|
for i in range(skiplines):
|
||||||
self.io.write_line(self.io.read_line())
|
self.io.write_line(self.io.read_line())
|
||||||
|
|
||||||
def read(self):
|
def read(self):
|
||||||
"""Iterate over all JSON input (Generator)"""
|
"""Iterate over all JSON input (Generator)"""
|
||||||
|
@ -18,8 +18,12 @@ class Module(SettingsBase):
|
|||||||
if self.output:
|
if self.output:
|
||||||
if "name" not in self.output:
|
if "name" not in self.output:
|
||||||
self.output["name"] = self.__name__
|
self.output["name"] = self.__name__
|
||||||
|
self.output["instance"] = str(id(self))
|
||||||
json.insert(0, self.output)
|
json.insert(0, self.output)
|
||||||
|
|
||||||
|
def on_click(self):
|
||||||
|
pass
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return self.__class__.__name__
|
return self.__class__.__name__
|
||||||
|
|
||||||
|
@ -51,6 +51,13 @@ class ModuleList(collections.UserList):
|
|||||||
module.registered(self.status_handler)
|
module.registered(self.status_handler)
|
||||||
super().append(module)
|
super().append(module)
|
||||||
|
|
||||||
|
def get_by_id(self, find_id):
|
||||||
|
find_id = int(find_id)
|
||||||
|
for module in self:
|
||||||
|
if int(id(module)) == find_id:
|
||||||
|
return module
|
||||||
|
return None
|
||||||
|
|
||||||
class PrefixedKeyDict(collections.UserDict):
|
class PrefixedKeyDict(collections.UserDict):
|
||||||
def __init__(self, prefix):
|
def __init__(self, prefix):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
@ -8,6 +8,7 @@ import urllib.request, urllib.parse, urllib.error
|
|||||||
import re
|
import re
|
||||||
import http.cookiejar
|
import http.cookiejar
|
||||||
import xml.etree.ElementTree as ET
|
import xml.etree.ElementTree as ET
|
||||||
|
import webbrowser
|
||||||
|
|
||||||
from i3pystatus import IntervalModule
|
from i3pystatus import IntervalModule
|
||||||
|
|
||||||
@ -85,3 +86,6 @@ class ModsDeChecker(IntervalModule):
|
|||||||
self.logged_in = True
|
self.logged_in = True
|
||||||
self.opener.addheaders.append(("Cookie", "{}={}".format(cookie.name, cookie.value)))
|
self.opener.addheaders.append(("Cookie", "{}={}".format(cookie.name, cookie.value)))
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def on_click(self):
|
||||||
|
webbrowser.open_new_tab("http://forum.mods.de/bb/")
|
@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
from urllib.request import urlopen
|
from urllib.request import urlopen
|
||||||
|
import webbrowser
|
||||||
|
|
||||||
import lxml.html
|
import lxml.html
|
||||||
from lxml.cssselect import CSSSelector
|
from lxml.cssselect import CSSSelector
|
||||||
@ -37,6 +38,9 @@ class DHL(TrackerAPI):
|
|||||||
ret["status"] = self.intrarow_status_selector(last_row)[0].text.strip()
|
ret["status"] = self.intrarow_status_selector(last_row)[0].text.strip()
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
def get_url(self):
|
||||||
|
return self.url
|
||||||
|
|
||||||
class ParcelTracker(IntervalModule):
|
class ParcelTracker(IntervalModule):
|
||||||
interval = 20
|
interval = 20
|
||||||
|
|
||||||
@ -59,3 +63,6 @@ class ParcelTracker(IntervalModule):
|
|||||||
"full_text": self.format.format(**fdict).strip(),
|
"full_text": self.format.format(**fdict).strip(),
|
||||||
"instance": self.name,
|
"instance": self.name,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def on_click(self):
|
||||||
|
webbrowser.open_new_tab(self.instance.get_url())
|
||||||
|
2
setup.py
2
setup.py
@ -3,7 +3,7 @@
|
|||||||
from setuptools import setup
|
from setuptools import setup
|
||||||
|
|
||||||
setup(name="i3pystatus",
|
setup(name="i3pystatus",
|
||||||
version="3.8.2",
|
version="3.9",
|
||||||
description="Like i3status, this generates status line for i3bar / i3wm",
|
description="Like i3status, this generates status line for i3bar / i3wm",
|
||||||
url="http://github.com/enkore/i3pystatus",
|
url="http://github.com/enkore/i3pystatus",
|
||||||
license="MIT",
|
license="MIT",
|
||||||
|
Loading…
Reference in New Issue
Block a user