Apart from the scripts own console (which does nothing) I want to open two consoles and print the variables con1 and con2 in different consoles, How can I achieve this.
con1 = 'This is Console1'
con2 = 'This is Console2'
I've no idea how to achieve this and spent several hours trying to do so with modules such as subprocess but with no luck. I'm on windows by the way.
Edit:
Would the threading module do the job? or is multiprocessing needed?
Eg:
If you don't want to reconsider your problem and use a GUI such as in #Kevin's answer then you could use subprocess module to start two new consoles concurrently and display two given strings in the opened windows:
#!/usr/bin/env python3
import sys
import time
from subprocess import Popen, PIPE, CREATE_NEW_CONSOLE
messages = 'This is Console1', 'This is Console2'
# open new consoles
processes = [Popen([sys.executable, "-c", """import sys
for line in sys.stdin: # poor man's `cat`
sys.stdout.write(line)
sys.stdout.flush()
"""],
stdin=PIPE, bufsize=1, universal_newlines=True,
# assume the parent script is started from a console itself e.g.,
# this code is _not_ run as a *.pyw file
creationflags=CREATE_NEW_CONSOLE)
for _ in range(len(messages))]
# display messages
for proc, msg in zip(processes, messages):
proc.stdin.write(msg + "\n")
proc.stdin.flush()
time.sleep(10) # keep the windows open for a while
# close windows
for proc in processes:
proc.communicate("bye\n")
Here's a simplified version that doesn't rely on CREATE_NEW_CONSOLE:
#!/usr/bin/env python
"""Show messages in two new console windows simultaneously."""
import sys
import platform
from subprocess import Popen
messages = 'This is Console1', 'This is Console2'
# define a command that starts new terminal
if platform.system() == "Windows":
new_window_command = "cmd.exe /c start".split()
else: #XXX this can be made more portable
new_window_command = "x-terminal-emulator -e".split()
# open new consoles, display messages
echo = [sys.executable, "-c",
"import sys; print(sys.argv[1]); input('Press Enter..')"]
processes = [Popen(new_window_command + echo + [msg]) for msg in messages]
# wait for the windows to be closed
for proc in processes:
proc.wait()
You can get something like two consoles using two Tkinter Text widgets.
from Tkinter import *
import threading
class FakeConsole(Frame):
def __init__(self, root, *args, **kargs):
Frame.__init__(self, root, *args, **kargs)
#white text on black background,
#for extra versimilitude
self.text = Text(self, bg="black", fg="white")
self.text.pack()
#list of things not yet printed
self.printQueue = []
#one thread will be adding to the print queue,
#and another will be iterating through it.
#better make sure one doesn't interfere with the other.
self.printQueueLock = threading.Lock()
self.after(5, self.on_idle)
#check for new messages every five milliseconds
def on_idle(self):
with self.printQueueLock:
for msg in self.printQueue:
self.text.insert(END, msg)
self.text.see(END)
self.printQueue = []
self.after(5, self.on_idle)
#print msg to the console
def show(self, msg, sep="\n"):
with self.printQueueLock:
self.printQueue.append(str(msg) + sep)
#warning! Calling this more than once per program is a bad idea.
#Tkinter throws a fit when two roots each have a mainloop in different threads.
def makeConsoles(amount):
root = Tk()
consoles = [FakeConsole(root) for n in range(amount)]
for c in consoles:
c.pack()
threading.Thread(target=root.mainloop).start()
return consoles
a,b = makeConsoles(2)
a.show("This is Console 1")
b.show("This is Console 2")
a.show("I've got a lovely bunch of cocounts")
a.show("Here they are standing in a row")
b.show("Lorem ipsum dolor sit amet")
b.show("consectetur adipisicing elit")
Result:
I don't know if it suits you, but you can open two Python interpreters using Windows start command:
from subprocess import Popen
p1 = Popen('start c:\python27\python.exe', shell=True)
p2 = Popen('start c:\python27\python.exe', shell=True)
Of course there is problem that now Python runs in interactive mode which is not what u want (you can also pass file as parameter and that file will be executed).
On Linux I would try to make named pipe, pass the name of the file to python.exe and write python commands to that file. 'Maybe' it will work ;)
But I don't have an idea how to create named pipe on Windows. Windows API ... (fill urself).
pymux
pymux gets close to what you want: https://github.com/jonathanslenders/pymux
Unfortunately it is mostly a CLI tool replacement for tmux and does not have a decent programmatic API yet.
But hacking it up to expose that API is likely the most robust option if you are serious about this.
The README says:
Parts of pymux could become a library, so that any prompt_toolkit application can embed a vt100 terminal. (Imagine a terminal emulator embedded in pyvim.)
If you are on windows you can use win32console module to open a second console for your thread or subprocess output. This is the most simple and easiest way that works if you are on windows.
Here is a sample code:
import win32console
import multiprocessing
def subprocess(queue):
win32console.FreeConsole() #Frees subprocess from using main console
win32console.AllocConsole() #Creates new console and all input and output of subprocess goes to this new console
while True:
print(queue.get())
#prints any output produced by main script passed to subprocess using queue
queue = multiprocessing.Queue()
multiprocessing.Process(Target=subprocess, args=[queue]).start()
while True:
print("Hello World")
#and whatever else you want to do in ur main process
You can also do this with threading. You have to use queue module if you want the queue functionality as threading module doesn't have queue
Here is the win32console module documentation
I used jfs' response. Here is my embellishment/theft of jfs response.
This is tailored to run on Win10 and also handles Unicode:
# https://stackoverflow.com/questions/19479504/how-can-i-open-two-consoles-from-a-single-script
import sys, time, os, locale
from subprocess import Popen, PIPE, CREATE_NEW_CONSOLE
class console(Popen) :
NumConsoles = 0
def __init__(self, color=None, title=None):
console.NumConsoles += 1
cmd = "import sys, os, locale"
cmd += "\nos.system(\'color " + color + "\')" if color is not None else ""
title = title if title is not None else "console #" + str(console.NumConsoles)
cmd += "\nos.system(\"title " + title + "\")"
# poor man's `cat`
cmd += """
print(sys.stdout.encoding, locale.getpreferredencoding() )
endcoding = locale.getpreferredencoding()
for line in sys.stdin:
sys.stdout.buffer.write(line.encode(endcoding))
sys.stdout.flush()
"""
cmd = sys.executable, "-c", cmd
# print(cmd, end="", flush=True)
super().__init__(cmd, stdin=PIPE, bufsize=1, universal_newlines=True, creationflags=CREATE_NEW_CONSOLE, encoding='utf-8')
def write(self, msg):
self.stdin.write(msg + "\n" )
if __name__ == "__main__":
myConsole = console(color="c0", title="test error console")
myConsole.write("Thank you jfs. Cool explanation")
NoTitle= console()
NoTitle.write("default color and title! This answer uses Windows 10")
NoTitle.write(u"♥♥♥♥♥♥♥♥")
NoTitle.write("♥")
time.sleep(5)
myConsole.terminate()
NoTitle.write("some more text. Run this at the python console.")
time.sleep(4)
NoTitle.terminate()
time.sleep(5)
Do you know about screen/tmux?
How about tmuxp? For example, you can try to run cat in split panes and use "sendkeys" to send output (but dig the docs, may be there is even easier ways to achieve this).
As a side bonus this will work in the text console or GUI.
Related
Ok, so the situation is this: I am building a macOS GUI App using Python and wx (wxphoenix). The user can use the GUI (say: script1) to launch a file-deletion process (contained in script2). In order to run successfully script2 needs to run with sudo rights.
script2 will itterate over a long list of files and delete them. But I need it to communicate with the GUI contained in script1 after each round so that script1 can update the progressbar.
In it's absolute most basic form my current working setup looks like this:
Script1:
import io
from threading import Thread
import subprocess
import wx
# a whole lot of wx GUI stuff
def get_password():
"""Retrieve user password via a GUI"""
# A wx solution using wx.PasswordEntryDialog()
# Store password in a variable
return variable
class run_script_with_sudo(Thread):
"""Launch a script with administrator privileges"""
def __init__(self, path_to_script, wx_pubsub_sendmessage):
"""Set variables to self"""
self.path = path_to_script
self.sender = wx_pubsub_sendmessage
self.password = get_password()
Thread.__init__(self)
self.start()
def run(self):
"""Run thread"""
prepare_script = subprocess.Popen(["echo", password], stdout=subprocess.PIPE)
prepare_script.wait()
launch_script = subprocess.Popen(['sudo', '-S', '/usr/local/bin/python3.6', '-u', self.path], stdin=prepare_script.stdout, stdout=subprocess.PIPE)
for line in io.TextIOWrapper(launch_script.stdout, encoding="utf-8"):
print("Received line: ", line.rstrip())
# Tell progressbar to add another step:
wx.CallAfter(self.sender, "update", msg="")
Script2:
import time
# This is a test setup, just a very simple loop that produces an output.
for i in range(25):
time.sleep(1)
print(i)
The above setup works in that script1 receives the output of script2 in real-time and acts on it. (So in the given example: after each second script1 adds another step to the progress bar until it reaches 25 steps).
What I want to achieve = not storing the password in a variable and using macOS it's native GUI to retrieve the password.
However when I change:
prepare_script = subprocess.Popen(["echo", password], stdout=subprocess.PIPE)
prepare_script.wait()
launch_script = subprocess.Popen(['sudo', '-S', '/usr/local/bin/python3.6', '-u', self.path], stdin=prepare_script.stdout, stdout=subprocess.PIPE)
for line in io.TextIOWrapper(launch_script.stdout, encoding="utf-8"):
print("Received line: ", line.rstrip())
# Tell progressbar to add another step:
wx.CallAfter(self.sender, "update", msg="")
Into:
command = r"""/usr/bin/osascript -e 'do shell script "/usr/local/bin/python3.6 -u """ + self.path + """ with prompt "Sart Deletion Process " with administrator privileges'"""
command_list = shlex.split(command)
launch_script = subprocess.Popen(command_list, stdout=subprocess.PIPE)
for line in io.TextIOWrapper(launch_script.stdout, encoding="utf-8"):
print("Received line: ", line.rstrip())
# Tell progressbar to add another step:
wx.CallAfter(self.sender, "update", msg="")
It stops working because osascript apparently runs in a non-interactive shell. This means script2 doesn't sent any output until it is fully finished, causing the progress bar in script1 to stall.
My question thus becomes: How can I make sure to use macOS native GUI to ask for the sudo password, thus preventing having to store it in a variable, while still maintaining the possibility to catch the stdout from the privileged script in an interactive / real-time stream.
Hope that makes sense.
Would appreciate any insights!
My question thus becomes: How can I make sure to use macOS native GUI
to ask for the sudo password, thus preventing having to store it in a
variable, while still maintaining the possibility to catch the stdout
from the privileged script in an interactive / real-time stream.
I have found a solution myself, using a named pipe (os.mkfifo()).
That way, you can have 2 python scripts communicate with each other while 1 of them is launched with privileged rights via osascript (meaning: you get a native GUI window that asks for the users sudo password).
Working solution:
mainscript.py
import os
from pathlib import Path
import shlex
import subprocess
import sys
from threading import Thread
import time
class LaunchDeletionProcess(Thread):
def __init__(self):
Thread.__init__(self)
def run(self):
launch_command = r"""/usr/bin/osascript -e 'do shell script "/usr/local/bin/python3.6 -u /path/to/priviliged_script.py" with prompt "Sart Deletion Process " with administrator privileges'"""
split_command = shlex.split(launch_command)
print("Thread 1 started")
testprogram = subprocess.Popen(split_command)
testprogram.wait()
print("Thread1 Finished")
class ReadStatus(Thread):
def __init__(self):
Thread.__init__(self)
def run(self):
while not os.path.exists(os.path.expanduser("~/p1")):
time.sleep(0.1)
print("Thread 2 started")
self.wfPath = os.path.expanduser("~/p1")
rp = open(self.wfPath, 'r')
response = rp.read()
self.try_pipe(response)
def try_pipe(self, response):
rp = open(self.wfPath, 'r')
response = rp.read()
print("Receiving response: ", response)
rp.close()
if response == str(self.nr_of_steps-1):
print("Got to end")
os.remove(os.path.expanduser("~/p1"))
else:
time.sleep(1)
self.try_pipe(response)
if __name__ == "__main__":
thread1 = LaunchDeletionProcess()
thread2 = ReadStatus()
thread1.start()
thread2.start()
priviliged_script.py
import os
import time
import random
wfPath = os.path.expanduser("~/p1")
try:
os.mkfifo(wfPath)
except OSError:
print("error")
pass
result = 10
nr = 0
while nr < result:
random_nr = random.random()
wp = open(wfPath, 'w')
print("writing new number: ", random_nr)
wp.write("Number: " + str(random_nr))
wp.close()
time.sleep(1)
nr += 1
wp = open(wfPath, 'w')
wp.write("end")
wp.close()
On Windows there is a WinAPI: FindWindow that you can use to get window handle of a existing window and use this handle to send message to it. Is there a python module can do that too? Find a window & communicate with it?
If this module do exist, could the same mechainsm be able applied on Ubuntu too?
Thanks a lot!
You can execute your commands with a subprocess:
import subprocess
import time
process = subprocess.Popen("echo 'start' & sleep 60 & echo 'stop'", shell=True)
time.sleep(60) # Maybe you want a timer...
The you have two options of closing, use terminate or kill methods in the Popen returned object or simulate a Ctrl. + C
import subprocess
import time
process = subprocess.Popen(cmd, shell=True)
time.sleep(5)
process.terminate() # Or kill
Simulate de ctrl + c:
import subprocess
import time
import os
import signal
process = subprocess.Popen(cmd, shell=True)
time.sleep(5)
os.kill(process.pid, signal.SIGINT) # Ctrl. + C
If you want to get the output you can use:
process.communicate()[0].strip()
Which gives you a string.
If you want a console GUI, you can use a command like:
gnome-terminal -x sh yourCommand
Or the equivalent for the terminal you have installed.
To get an output of a command we could do this
os.popen("ls").read()
But suppose I have a command that I don't want to wait for it to return. In fact, I want to keep it running, and occasionally spit out some output.
(Eg., java PrintEvery5) (Suppose the PrintEvery5 would print a line every 5 seconds).
How do subscribe to the process/thread and grab the output of this?
I've tried the following, which didn't seem to work.
### file: deqthread.py
import threading, os, subprocess
class DeqThread(threading.Thread):
def __init__(self):
super(DeqThread, self).__init__()
self.f=os.popen("java PrintEvery5")
def run(self):
print("in run")
def readResult(self):
return self.f.read()
thread1 = DeqThread()
thread1.start()
while True:
print(thread1.readResult())
Running python deqthread.py, I don't see any output. THe whole thing just hangs there.
When I try this, I could see the output. (ie., it keeps printing to the console),
$python <ENTER>
>>> import os
>>> os.system("java PrintEvery5")
So what do I need to change in my deqthread.py file so that I can get output out of my command?
Have you tried using the the check_output method in subprocess module? It allows you to run a command with arguments and return its output as a byte string.
import subprocess
output = subprocess.check_output(["echo", "Hello Java!"])
print output
So __init__ could become:
def __init__(self):
super(DeqThread, self).__init__()
And readResult could become:
def readResult(self):
def readResult(self):
output = subprocess.check_output(["echo", "Hello Java!"])
return output
See documentation here:
https://docs.python.org/2/library/subprocess.html
Use subprocess.Popen(), then redirect stdout to subprocess.PIPE. Finally, get the output from the stdout member of sub-process instance. The example shows as below:
foo.py:
import time
count = 5
while count > 0:
print 'Hello'
count -= 1
time.sleep(1)
main.py:
import subprocess
p = subprocess.Popen(['python.exe', 'foo.py'],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
for line in iter(p.stdout.readline, ''):
print("OUTPUT: " + line.rstrip())
I have a need from a Tkinter GUI to be able to start a long-running Linux script but at the same time I want to be able to have a stop-button enable so I can stop the process. Neither Tkinter nor popen are threadsafe. I thought of simply either placing the popen function in a thread or possibly just enabling a button in a thread. I am currently using Red Hat Linux 5.9 which uses Python 2.4.3, but I have later versions available online that I could use. In the program, below note that I reconfigure the start button to a stop button, but that does not work because the start button function is active, but it indicates my intent. Note that the stop function simply does an os.kill() on the child.
#!/usr/bin/python
import subprocess
import sys
import Tkinter
import tkMessageBox
import signal
import os
import time
class popentest:
def __init__(self):
self.mainWindow = Tkinter.Tk()
def __createUI(self, mainWindow):
mainWindow.protocol("WM_DELETE_WINDOW", self.OnExitWindow)
## Local variables.
sleep=5
iter=5
self.pid=0
self.mainWindow.title("Test popen")
self.start=Tkinter.Button(mainWindow, text=u"Start", command=self.onStart)
self.start.grid()
self.kwit = Tkinter.Button(mainWindow,text=u"Quit !",
command=self.onQuit)
self.kwit.grid()
self.lIter=Tkinter.Label(mainWindow, text="Iterations: ")
self.iterE=Tkinter.Entry(mainWindow, width=2)
self.lSleep = Tkinter.Label(mainWindow, text="Sleep time")
self.sleepEntry = Tkinter.Entry(mainWindow, width=3)
self.lIter.grid()
self.iterE.grid()
self.lSleep.grid()
self.sleepEntry.grid()
self.iterE.insert(0, str(iter))
self.sleepEntry.insert(0,str(sleep))
def startPopen(self):
self.__createUI(self.mainWindow)
self.mainWindow.mainloop()
def execute(self, numIters, sleep):
self.p = subprocess.Popen(['./testpopen.sh',str(numIters), str(sleep)], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
self.pid=self.p.pid
print str(self.p.pid)+" started"
for line in iter(self.p.stdout.readline, ''):
print line
self.p.stdout.close()
self.pid=0
self.start.configure(text=u"Start", command=self.onStart)
def onStart(self):
numIters=self.iterE.get()
sleep=self.sleepEntry.get()
if not numIters.isdigit():
tkMessageBox.showerror(
"invalid entry",
"Iteration (%s)must be numeric\n" % numIters)
return
elif not sleep.isdigit():
tkMessageBox.showerror(
"invalid entry",
"Sleep(%s) is not numeric\n" % sleep)
return
numIters=int(numIters)
sleep=int(sleep)
if numIters <= 0 or sleep <=0 :
tkMessageBox.showerror(
"invalid entry",
"Either iteration (%d) or sleep(%d) is <= 0\n" % (numIters, sleep))
else:
print "configuring start to stop"
self.start.configure(text=u"Stop", command=self.onStop)
time.sleep(1)
self.execute(numIters, sleep)
def onStop(self):
print "configuring stop to start"
os.kill(p.pid, signal.SIGTERM)
self.start.configure(text=u"Start", command=self.onStart)
def OnExitWindow(self):
if self.pid != 0 :
os.kill(self.pid, signal.SIGKILL)
self.mainWindow.destroy()
def onQuit(self):
if self.pid != 0 :
os.kill(self.pid, signal.SIGKILL)
self.mainWindow.destroy()
if __name__ == "__main__":
remote = popentest()
remote.startPopen()
You can start your process using Popen, using a non-blocking pipe to communicate
with the process - this way, you can receive its output asynchronously. I already
used an enhanced version of Popen, code was from an ActiveState Python cookbook recipe.
I could not find the recipe on the web anymore, but as I still have the code I pasted it here:
https://gist.github.com/mguijarr/6874724
Then, in your Tkinter code, you can use a timer to check periodically for the
state of the process (terminated, or not) and to get output:
self.p = EnhancedPopen.Popen(['./testpopen.sh',str(numIters), str(sleep)],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True,universal_newlines=True)
self.mainWindow.after(100, self.check_process)
def check_process(self):
# get stdout output
output = EnhancedPopen.recv_some(self.p, e=0, stderr=0)
...
if self.p.poll() is not None:
# process terminated
...
return
# set timer again (until process exits)
self.mainWindow.after(100, self.check_process_output)
I'm writing an appindicator for Grive, a daemon for syncing Google Drive files. Since I have little programming experience, I decided to write a Python script that calls Grive as a subprocess instead of integrating it in its C++ source code.
I've adapted Stefaan Lippens' code for asynchronously reading subprocess pipes to both show a notification and change the indicator's icon when something important happens (e.g. a new file is added, or a network error). Notifications work well; however, the indicator's icon changes only when the whole process has finished, which is useless because I need to change it many times after it finishes.
Here is the code I'm using:
async.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
import subprocess
import time
import threading
import Queue
class AsynchronousFileReader(threading.Thread):
'''
Helper class to implement asynchronous reading of a file
in a separate thread. Pushes read lines on a queue to
be consumed in another thread.
'''
def __init__(self, fd, queue):
assert isinstance(queue, Queue.Queue)
assert callable(fd.readline)
threading.Thread.__init__(self)
self._fd = fd
self._queue = queue
def run(self):
'''The body of the tread: read lines and put them on the queue.'''
for line in iter(self._fd.readline, ''):
self._queue.put(line)
def eof(self):
'''Check whether there is no more content to expect.'''
return not self.is_alive() and self._queue.empty()
def run(command, show):
'''
Main function to consume the output of a command.
command = The command to be run
show = Function that will process output
'''
# Launch the command as subprocess.
process = subprocess.Popen(command, shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
# Launch the asynchronous readers of the process' stdout and stderr.
stdout_queue = Queue.Queue()
stdout_reader = AsynchronousFileReader(process.stdout, stdout_queue)
stdout_reader.start()
stderr_queue = Queue.Queue()
stderr_reader = AsynchronousFileReader(process.stderr, stderr_queue)
stderr_reader.start()
# Check the queues if we received some output (until there is nothing more to get).
while not stdout_reader.eof() or not stderr_reader.eof():
# Show what we received from standard output.
while not stdout_queue.empty():
line = stdout_queue.get()
show(line)
# Show what we received from standard error.
while not stderr_queue.empty():
line = stderr_queue.get()
show(line)
# Sleep a bit before asking the readers again.
time.sleep(.1)
# Let's be tidy and join the threads we've started.
stdout_reader.join()
stderr_reader.join()
# Close subprocess' file descriptors.
process.stdout.close()
process.stderr.close()
return True
grive.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
import subprocess
import time
import async
from gi.repository import Gtk
from gi.repository import Gio
from gi.repository import GObject
from gi.repository import Notify
from gi.repository import AppIndicator3 as AppIndicator
GRIVE_FOLDER = "/home/ilhuitemoc/Publike/Google Drive"
def show(line):
line = line.replace("\n", "")
print line
if line.startswith("[gr::expt::MsgTag*] = "):
line = line.replace("[gr::expt::MsgTag*] = ","",1)
n = Notify.Notification.new("Error", line, icon)
n.show()
indicator.set_icon("ubuntuone-client-offline")
if line.startswith("sync "):
line = line.replace("sync ","",1)
line = line.replace('"','<b>',1)
line = line.replace('"','</b>',1)
n = Notify.Notification.new("Sync in progress", line, icon)
n.show()
indicator.set_icon("ubuntuone-client-updating")
if "Finished!" in line:
#n = Notify.Notification.new(line, line, icon)
#n.show()
indicator.set_icon("ubuntuone-client-idle")
def openinfolder(obj):
subprocess.call(["xdg-open",GRIVE_FOLDER])
def openinbrowser(obj):
subprocess.call(["xdg-open","http://drive.google.com/"])
if __name__ == '__main__':
subprocess.call(["killall","pantheon-notify"])
time.sleep(1)
indicator = AppIndicator.Indicator.new('grive', 'ubuntuone-client-offline', AppIndicator.IndicatorCategory.APPLICATION_STATUS)
indicator.set_status(AppIndicator.IndicatorStatus.ACTIVE)
menu = Gtk.Menu()
status = Gtk.MenuItem("Connecting...") #Not finished yet
status.set_sensitive(False)
menu.append(status)
sp = Gtk.SeparatorMenuItem()
menu.append(sp)
mi = Gtk.MenuItem("Open Google Drive folder")
mi.connect('activate',openinfolder)
menu.append(mi)
mi = Gtk.MenuItem("Go to Google Drive webpage")
mi.connect('activate',openinbrowser)
menu.append(mi)
sp = Gtk.SeparatorMenuItem()
menu.append(sp)
mi = Gtk.ImageMenuItem("Quit")
img = Gtk.Image.new_from_stock(Gtk.STOCK_QUIT, Gtk.IconSize.MENU)
mi.set_image(img)
mi.connect('activate',Gtk.main_quit)
menu.append(mi)
menu.show_all()
indicator.set_menu(menu)
Notify.init('grive')
icon = 'google-drive'
#async.run('cd "%s" && grive' % GRIVE_FOLDER, show)
GObject.timeout_add(5*60000, async.run, 'cd "%s" && grive' % GRIVE_FOLDER, show)
#GObject.timeout_add(5000, async.run, "test.sh", show)
Gtk.main()
I think I'm doing something wrong, but it's not obvious to me. Is it right to modify the indicator using a subprocess? Or is any other way I can correctly do this?