Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Only one python program running (like Firefox)?

When I open Firefox, then run the command:

firefox http://somewebsite

the url opens in a new tab of Firefox (same thing happens with Chromium as well). Is there some way to replicate this behavior in Python? For example, calling:

processStuff.py file/url

then calling:

processStuff.py anotherfile

should not start two different processes, but send a message to the currently running program. For example, you could have info in one tabbed dialog box instead of 10 single windows.

Adding bounty for anyone who can describe how Firefox/Chromium do this in a cross-platform way.

like image 809
NoBugs Avatar asked Aug 09 '11 06:08

NoBugs


People also ask

Does Python run in a browser?

Python might be the most popular programming language in the world, but unlike other frontrunner JavaScript, you can't run Python code in the browser.

Can any computer run a Python program?

To start programming, you need an operating system (OS). Python is cross-platform and will work on Windows, macOS, and Linux.


2 Answers

The way Firefox does it is: the first instance creates a socket file (or a named pipe on Windows). This serves both as a way for the next instances of Firefox to detect and communicate with the first instance, and forward it the URL before dying. A socket file or named pipe being only accessible from processes running on the local system (as files are), no network client can have access to it. As they are files, firewalls will not block them either (it's like writing on a file).

Here is a naive implementation to illustrate my point. On first launch, the socket file lock.sock is created. Further launches of the script will detect the lock and send the URL to it:

import socket
import os

SOCKET_FILENAME = 'lock.sock'

def server():
    print 'I\'m the server, creating the socket'
    s = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
    s.bind(SOCKET_FILENAME)

    try:
        while True:
            print 'Got a URL: %s' % s.recv(65536)
    except KeyboardInterrupt, exc:
        print 'Quitting, removing the socket file'
        s.close
        os.remove(SOCKET_FILENAME)

def client():
    print 'I\'m the client, opening the socket'
    s = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
    s.connect(SOCKET_FILENAME)
    s.send('http://stackoverflow.com')
    s.close()

def main():
    if os.path.exists(SOCKET_FILENAME):
        try:
            client()
        except (socket.error):
            print "Bad socket file, program closed unexpectedly?"
            os.remove(SOCKET_FILENAME)
            server()
    else:
        server()

main()

You should implement a proper protocol (send proper datagrams instead of hardcoding the length for instance), maybe using SocketServer, but this is beyond this question. The Python Socket Programming Howto might also help you. I have no Windows machine available, so I cannot confirm that it works on that platform.

like image 93
ndfred Avatar answered Sep 30 '22 05:09

ndfred


You could create a data directory where you create a "locking file" once your program is running, after having checked if the file doesn't exist yet.

If it exists, you should try to communicate with the existing process, which creates a socket or a pipe or something like this and communicates its address or its path in an appropriate way.

There are many different ways to do so, depending on which platform the program runs.

like image 32
glglgl Avatar answered Sep 30 '22 06:09

glglgl