Click to See Complete Forum and Search --> : Python is neat, and so are random desktop images.


Rob 'Feztaa' Park
09-27-2001, 10:01 PM
Hey all, I just coded (addmittedly, with help from ESR :)) a neat little Python script to randomize my (blackbox) desktop image.

Actually, it started out as a bash script, but it was ungodly slow, and ESR suggested I write it in Python, and gave me some starting hints. I then came up with this:

#!/usr/bin/python

import random, glob, os

# Get listing of images
images = glob.glob('/home/feztaa/images/desktop/*')

# Choose a random image
chosen = images[random.randrange(0,len(images))]

# Make it the desktop image

os.execv("/usr/X11R6/bin/bsetbg", ["-c", chosen])

And that's it! Of course, you might want to change the paths there...

In my blackbox style file, I have this script set as my rootCommand, so I get a random image every time I load up blackbox.

Heh, just thought I'd share :)

[ 27 September 2001: Message edited by: Rob 'Feztaa' Park ]

EscapeCharacter
09-27-2001, 10:07 PM
<homer simpson>
*yank* thats mine now, hehehehe
</homer simpson>
nice im gonna steal that if you dont mind :)

Rob 'Feztaa' Park
09-27-2001, 10:16 PM
Go ahead, that's why I posted it :)

I think it's funny that the python script is 3 lines long, and the original bash on was probably 3 or 4 times as long to do the same thing :)

jemfinch
09-27-2001, 11:18 PM
This is what I've been using for sometime now...


#!/usr/bin/env python

import os, sys, random

sys.stdin.close()
sys.stdout.close()
sys.stderr.close()

if os.access('/home/jfincher/.bgfix', os.F_OK) and len(sys.argv) < 2:
sys.exit(0)

BGEXTS = ['.jpg', '.png']
BGDIRS = ['/home/jfincher/pics/backgrounds/stretched']


if len(sys.argv) >= 2:
pic = sys.argv[1]
else:
for adir in BGDIRS:
pics = []
realdirlist = []
dirlist = os.listdir(adir)
dirlist = map(lambda x: '%s/%s' % (adir, x), dirlist)
for ext in BGEXTS:
realdirlist.extend(filter(lambda x: x[-len(ext):] == ext, dirlist))
pics.extend(realdirlist)
pic = pics[random.randrange(len(pics))]

os.execl('/usr/X11R6/bin/wmsetbg', 'wmsetbg', '-display', ':0.0', pic)


I wrote it awhile back, so it's got some ugly stuff, but hey, it works, I'm not complaining :)

Jeremy

MrNewbie
09-28-2001, 09:49 AM
Jemfinch, do those python statements close stdin, stdout and stderr

sys.stdin.close()
sys.stdout.close()
sys.stderr.close()
?
Is there a python statement to close all streams temporarily because I'm going to need something like that soon for a script I wanna make and I don't mind what language it's in.

jemfinch
09-28-2001, 10:32 AM
Originally posted by MrNewbie:
[QB]Jemfinch, do those python statements close stdin, stdout and stderr

sys.stdin.close()
sys.stdout.close()
sys.stderr.close()


Yes, they do.


Is there a python statement to close all streams temporarily because I'm going to need something like that soon for a script I wanna make and I don't mind what language it's in.

Not that I know of, but stdin, stdout, and stderr are the only file descriptors most processes should have when they first begin to run.

Jeremy

MrNewbie
09-28-2001, 01:09 PM
Hmm, thanks. Python seems pretty cool from what I've seen, and kind of reads like english, like:

for adir in BGDIRS:

Rob 'Feztaa' Park
09-28-2001, 09:47 PM
jemfinch:

Lol, nice program.

I'm not really sure what all of that is supposed to do, but I prefer mine because it's only three lines of code :)

Granted, I cut quite a few corners when coding it. The script assumes that the directory given contains only desktop images of whatever type is supported by bsetbg (mine are all jpegs, they work), that bsetbg exists, etc etc. It's probably not the best for distribution (ie, people who don't know what they're doing won't adjust it for his or her system, and get errors), but I like it because it's efficient :)

Rob 'Feztaa' Park
09-29-2001, 02:21 AM
Hey jemfinch, think you could help me with this?

When you execute os.execl, (or execv in my case), it kills the python script. In other words, the python script goes away and the program that you ran with it takes over the pid, and runs like that.

The problem there is that I want to run os.execv twice in one script (and the script is magically stopping after the first one).

Do you know if it would be possible to fork a child process and then run os.execv on that? I'm not sure how to do that.

jemfinch
09-29-2001, 02:25 AM
Originally posted by Rob 'Feztaa' Park:
Do you know if it would be possible to fork a child process and then run os.execv on that? I'm not sure how to do that.

Yep. Check out os.fork.

Jeremy

Rob 'Feztaa' Park
09-29-2001, 02:39 PM
Yeah, but after I do the os.fork, how do I make the os.execv happen on the forked process and not on the original process?

Maybe I'm looking in the wrong place, but the documentation on these functions is pretty scarce.

jemfinch
09-29-2001, 03:53 PM
Originally posted by Rob 'Feztaa' Park:
Yeah, but after I do the os.fork, how do I make the os.execv happen on the forked process and not on the original process?

Maybe I'm looking in the wrong place, but the documentation on these functions is pretty scarce.

The first place you'll want to check is the interpreter.


>>> import os
>>> print os.fork.__doc__
fork() -> pid
Fork a child process.

Return 0 to child process and PID of child to parent process.
>>>


So you need to put your fork in an if statement, like this:


if os.fork() = 0:
os.execl(...)

continue_parent_program()


Jeremy

Rob 'Feztaa' Park
09-29-2001, 07:18 PM
Wow, it worked. I would have never thought of that.

Thanks :)

Rob 'Feztaa' Park
09-29-2001, 07:26 PM
Just for reference, my program now looks like this:

#!/usr/bin/python
#Author: Rob Park
#Title: Desktop Image Randomizer
#Email: fezziker@home.com
#Credits: Eric S. Raymond, and jemfinch
# for their help with Python
#######################################

import random, glob, os

# Set the bg to black while waiting for the image to be chosen and set
if os.fork() == 0:
os.execv("/usr/X11R6/bin/bsetbg", ["bsetbg", "-solid", "black"])

# Get listing of images
images = glob.glob('/home/feztaa/images/desktop/*')

# Choose a random one
chosen = images[random.randrange(0,len(images))]

# Make it the desktop image
os.execv("/usr/X11R6/bin/bsetbg", ["bsetbg", "-c", chosen])

and that's it :)