#!/usr/bin/python
# -*- coding: UTF8 -*-
# knock clock
# plays a sound file or playlist or stream with mplayer,
# and cancels when you hit the keyboard (which is a giant snooze)
#
# Copyright (c) 2008, Jean-François Fortin Tam
#This program is free software; you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation; either version 3 of the License, or
#(at your option) any later version.
#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#GNU General Public License for more details.
#You should have received a copy of the GNU General Public License
#along with this program. If not, see .
#### SET YOUR PREFERENCE HERE
TARGET = "http://www.somafm.com/groovesalad.pls"
NEED_NETWORK = True #disable this if the target is not an internet radio station
FALLBACK_TARGET = "/usr/share/example-content/ubuntu Sax.ogg" #this is used if the network connection is unavailable
####
import urllib2
import termios, fcntl, sys, os
try:
# try to see if google can be reached, i.e. connection to internet is up
ping = urllib2.urlopen('http://www.google.com')
ping.close()
network_available = True
except IOError:
network_available = False
fd = sys.stdin.fileno()
oldterm = termios.tcgetattr(fd)
newattr = termios.tcgetattr(fd)
newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
termios.tcsetattr(fd, termios.TCSANOW, newattr)
oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)
if network_available:
os.popen2('mplayer '+ "\"" + TARGET + "\"")#, 10*2**20)#ici, 2**20 est une façon pythonique de dire 2 exposant 20. Ce nombre ici servira de taille de buffer pour pas que python coupe le son.
elif network_available == False:
os.popen2('mplayer '+ "\"" + FALLBACK_TARGET + "\"")
### WAIT, et si j'utilisais gnome execute whatever plutôt que popen?
print """
############################## ALARM CLOCK ##############################
#### ####
#### ####
#### PRESS ANY KEY TO STOP THE RACKET ####
#### ####
#### ####
############################## ALARM CLOCK ##############################
"""
from time import sleep
try:
while 1:
sleep(1)
try:
c = sys.stdin.read(1)
print "Got character", `c`
os.popen("killall mplayer && killall gnome-terminal") #FIXME: the sound stops after 30 seconds exactly. See the discussion below:
"""
nekohayo: Buffering problems?
--> OldNugget (n=guido@e177161059.adsl.alicedsl.de) a rejoint #python
thunderbolt: of mplayer?
is foo.mp3 short? Does it work from the command line? Does it work if you use the subprocess module instead, and *don't* use shell interpretation?
nekohayo: Perhaps of popen?
nekohayo: Have you tried using subprocess.Popen instead?
Rhamphoryncus: running the command outside python works without problems (the track is 40 minutes long!)
my goal is basically to be able to play that while being able to continue a "while" loop, so that whenever the user presses any key it kills mplayer (this is my utter newbie attempt at an alarm clock!)
time.sleep(awhile); alarm_command()
nekohayo: Heh. I just go to the department store and buy one.
CSWookie: but then it won't work for different days or play a webradio ;)
nekohayo: My alarm clock works every day.
and you have different schedules every day?
i use my cell phone for an alarm clock
nekohayo: And I've found that music makes a very poor wake-up call. Too pleasant to listen to.
nekohayo: No.
CSWookie: This is the digital era, and you have to disable you alarm clock on the weekends? :P
:)
got so used to using it for the alarm when i didn't have any clock that now i still use it out of habit
purpleposeidon: I don't see how the one affects the other.
Anyway, I don't own a computer.
you irc with webtv or something?
sproingie: This is the work computer.
ah
sproingie: Sometimes, I don't take it home.
computer in the bedroom is a bad plan
So relying on it for an alarm clock is not a good idea.
for those interested in the alarm clock http://rafb.net/p/IbsxQu85.html
a huge hack o_o
nekohayo: use the subprocess module, get /just/ the pid, and then use the pid to kill. I think there's a kill function in os.
purpleposeidon: not sure time.sleep(awhile); alarm_command() applies to this?
hm
but will it make the while loop continue? I'll give it a try
killall is Bad Practice, don't use it.
Well, okay, it's for Emergencies Only.
Vornicus: yeah well I assumed it was truly a hack but did not know of another way
especially that it's for a single user dedicated alarm clock computer running on a live cd in this case :)
I would use a cron job instead of making a script - cron does all the heavy lifting for you.
Well, I would make cron call your alarm clock script, and let your alarm clock script /just/ do the actual alarm functions.
Vornicus: well, that script I wrote is intended to be in a cron job!
the *only* reason for this script to exist is to provide a player that stops as soon as you hit the keyboard keys
just like a real alarm clock's button, you know? :)
Oh, so you did. I got caught up in the other crap.
I just do `sleep [big number] && open blah.mp3` if my ipod is out of commission
I'd pull target from the command line; I'd also have it check an environment variable.
it's just that I don't know what is best to use to achieve that, and I haven't figured out "subprocess" yet
Subprocess kinda sucks still; it needs a lot more helpers, and much clearer documentation.
It's new, so I excuse it.
jeff: I'm trying to make a hacky alarm clock, basically, that will be called from cron. So it's only supposed to launch mplayer, and whenever the user hits any key on the keyboard, it kills it
Chris Halse Rogers: Ok, fair enough.
jeff: is there an easy way to launch such a process while still being able to continue a while loop to monitor the key press?
Chris Halse Rogers: Um...
Chris Halse Rogers: You'd be after POpen, I believe.
jeff: popen did not continue the loop so hitting keys did nothing, but popen2 did
jeff: but now I have the strange problem that sound stops after 30 seconds
jeff: so I was wondering if popen2 was the right thing
jeff: I'm feeling a bit pathetic that I can't make such a simple "script that wraps a kill around mplayer on keypress" work ;)
Chris Halse Rogers: I'm pretty sure that popen2 is what you're after.
Chris Halse Rogers: I'm not sure why it would stop working after 30 seconds, though. Puzzling.
jeff: what might cause that sound being cut then?
Chris Halse Rogers: Is your script still running after 30 secs?
jeff: it seems
Chris Halse Rogers: Because killing the script will obviously kill the mplayer process, too...
Chris Halse Rogers: Hm. Is _mplayer_ still running after those 30 seconds?
jeff: it seems too
Chris Halse Rogers: (IE: is this a problem with mplayer, rather than your script?)
jeff: oh well I tried mplayer with the same command in the terminal, no problem
jeff: with either a web radio or local file
Chris Halse Rogers: Hm.
Chris Halse Rogers: Incidentally, I don't believe the "killall mplayer && killall gnome-terminal" thing will work - the "&&" is a shell construct, and I think popen just runs the command directly, without going through the shell.
jeff: actually I think it works
jeff: I saw it kill my terminals without remorse :)
Chris Halse Rogers: Hm. Oh, well, I obviously misunderstand it :)
jeff: I go by trial and error kind of
jeff: I mostly don't understand the docs ;_;
Chris Halse Rogers: OOooooh. I know what might be the problem.
Chris Halse Rogers: Maybe.
jeff: what might it be?
Chris Halse Rogers: popen2 returns the stdout & stdin streams of your mplayer process.
Chris Halse Rogers: Now, we have 2 options here: (1) - one of these streams is getting full, so mplayer is waiting on a printf, or
(2) The python environment is killing those stream objects because you aren't keeping references to them.
jeff: references? delicious?
Chris Halse Rogers: References, as in "there's no way for you to get at those objects, so python assumes they're unused, so cleans them up".
jeff: and is there a workaround to that?
Chris Halse Rogers: Well, you could go (mplayer_stdout, mplayer_stdin) = popen2("mplayer foo")
Chris Halse Rogers: (IE: keep some references around)
jeff: doesn't seem to work?
jeff: oh wait
Chris Halse Rogers: Right. Well...
Chris Halse Rogers: Maybe you should try increasing the buffer size to something crazy big?
jeff: but what is crazy big in that case?
Chris Halse Rogers: Why not make it a couple of mb. Something like 2**20 should do.
jeff: are those wildcards? ie, 20020 ?
Chris Halse Rogers: No, 2**20 is how you write "2 to the power of 20" in python.
jeff: ooh
***jeff tries thinking in base 2. would that mean 20mibs?
jeff: umm surely not
Chris Halse Rogers: I'm not sure, now :)
Chris Halse Rogers: 2**10 is 1 KB.
Chris Halse Rogers: 2**10 x 2**10 is 1 MB, so 2**20 is 1 MB.
jeff: os.popen2('mplayer '+ TARGET, 10*2**20)
Chris Halse Rogers: That might be it.
jeff: no matter what I put there it still cuts the sound after 30s
Chris Halse Rogers: Um...
Chris Halse Rogers: Hm.
Chris Halse Rogers: I think I'm pretty much out of ideas.
jeff: oh well
jeff: I guess I'll just leave it like that as a limitation
"""
break
except IOError: pass
finally:
termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)