Jim wrote:
I am running this on Mint 18.
This is the third script I have written to open and position windows in
workspaces. The first two work, but trying to open ebook-viewe r
(calibre) with a specific book produces the following error.
If I run the same command in the terminal it works without an error.
Exception in thread Thread-4:
Traceback (most recent call last):
File "/usr/lib/python3.5/threading.py", line 914, in _bootstrap_inner
self.run()
File "/usr/lib/python3.5/threading.py", line 862, in run
self._target(*self._args, **self._kwargs)
File "/home/jfb/MyProgs/Scripts/place_windows_OO_WS3.py", line 24, in
open_it
subprocess.call([self.program])
File "/usr/lib/python3.5/subprocess.py", line 557, in call
with Popen(*popenargs, **kwargs) as p:
File "/usr/lib/python3.5/subprocess.py", line 947, in __init__
restore_signals, start_new_session)
File "/usr/lib/python3.5/subprocess.py", line 1551, in _execute_child
raise child_exception_type(errno_num, err_msg)
FileNotFoundError: [Errno 2] No such file or directory: 'ebook-viewer
/home/jfb/Documents/eBooks/Javascript/GOOGLE_SHEETS/googlespreadsheetprogramming.epub'
Code:
# place_windows_OO_WS3.py
import subprocess
from subprocess import Popen,PIPE
import threading
import time
class Place():
def __init__(self):
self.programs = ['jedit', 'google-chrome', 'doublecmd',
'ebook-viewer
/home/jfb/Documents/eBooks/Javascript/GOOGLE_SHEETS/googlespreadsheetprogramming.epub']
self.classname = {'jedit' : 'sun-awt-X11-XFramePeer',
'google-chrome':'google-chrome',
'doublecmd':'doublecmd',
'calibre-ebook-viewer': 'libprs500'}
self.open_and_move()
def open_it(self):
subprocess.call([self.program])
def open_and_move(self):
for self.program in self.programs:
opener = threading.Thread(target=self.open_it)
opener.start()
time.sleep(2)
p = Popen(['xdotool', 'search', '--classname',
self.classname[self.program]], stdout=subprocess.PIPE)
if self.classname[self.program] == 'sun-awt-X11-XFramePeer':
wid = str(p.stdout.read())
wid = wid[len(wid) - 11 : len(wid) - 3]
x = '0'
y = '0'
print('***jedit***')
elif self.classname[self.program] == 'google-chrome':
wid = str(p.stdout.read())
wid = wid[len(wid) - 11 : len(wid) - 3]
x = '1924'
y = '0'
print('***google***')
elif self.classname[self.program] == 'doublecmd':
wid = str(p.stdout.read())
wid = wid[len(wid) - 11 : len(wid) - 3]
x = '1924'
y = '537'
print('***double***')
else:
wid = str(p.stdout.read())
wid = wid[len(wid) - 11 : len(wid) - 3]
x = '2540' #'1924'
y = '537'
print('***calibre***')
subprocess.call(['xdotool', 'windowmove', str(wid), x, y])
I did some googling and it seems that subprocess does not have a length
limit in linux. Could someone tell me how to correct the above error.
Not directly related to your question, but I think you should have one
instance of your Place class per program. That way you keep related
information together and avoid the need to look it up in a dict or find it
with a long chain of if ... elif ... tests. For example:
# untested
import subprocess
import threading
import time
DELAY = 3.0 # seconds
class Place:
def __init__(self, cmd, classname=None, name=None, x=0, y=0):
if classname is None:
classname = cmd[0]
if name is None:
name = cmd[0]
self.cmd = cmd
self.classname = classname
self.name = name
self.x = x
self.y = y
def open_it(self):
subprocess.call(self.cmd)
def open_and_move(self):
opener = threading.Thread(target=self.open_it)
opener.start()
time.sleep(DELAY)
output = subprocess.Popen(
['xdotool', 'search', '--classname', self.classname],
stdout=subprocess.PIPE
).communicate()[0]
wid = output.split()[-1].decode()
subprocess.call(
[
'xdotool', 'windowmove',
wid, str(self.x), str(self.y)
]
)
print("***{}***".format(self.name))
EBOOK = (
"/home/jfb/Documents/eBooks/Javascript/"
"GOOGLE_SHEETS/googlespreadsheetprogramming.epub"
)
programs = [
Place(["jedit"], classname="sun-awt-X11-XFramePeer"),
Place(["google-chrome"], x=1924),
Place(["doublecmd"], x=1924, y=537),
Place(
["ebook-viewer", EBOOK],
classname="libprs500", name="calibre",
x=2540, y=537
)
]
for program in programs:
program.open_and_move()
Now when you add a new program you just append a new `Place` instance to the
`programs` list.