Source

sleepytime / itunesleep.py

#! /usr/bin/python

import Tkinter
import time
import win32com.client

class main(object):
    def pauseitunes(self):
        self.status = "Pausing iTunes"
        self.updatedisplay()
        volume = self.itunes.SoundVolume
        volstep = max((volume/20, 1))
        for x in xrange(20):
            self.itunes.SoundVolume -= volstep
            time.sleep(0.125)
        self.itunes.SoundVolume = 0
        self.itunes.Pause()
        self.itunes.SoundVolume = volume
        self.status = "Paused iTunes"
        self.updatedisplay()

    def __init__(self):
        self._itunes = None
        
        self.sleepat = None

        self.root = Tkinter.Tk()

        self.hour = Tkinter.Label(self.root, text="00", font=('Lucida Console', 48))
        self.hourup = Tkinter.Button(self.root, text="+", command=self.inchour)
        self.hourdown = Tkinter.Button(self.root, text="-", command=self.dechour)

        self.minute = Tkinter.Label(self.root, text="00", font=('Lucida Console', 48))
        self.minuteup = Tkinter.Button(self.root, text="+", command=self.incminute)
        self.minutedown = Tkinter.Button(self.root, text="-", command=self.decminute)

        self.second = Tkinter.Label(self.root, text="00", font=('Lucida Console', 48))
        self.secondup = Tkinter.Button(self.root, text="+", command=self.incsecond)
        self.seconddown = Tkinter.Button(self.root, text="-", command=self.decsecond)

        self._status = Tkinter.Label(self.root, text="Ready.")

        self.playbutton = Tkinter.Button(self.root, text="PL", command=self.itunes.PlayPause)

        self.hour.grid(row=0, column=0, rowspan=2)
        self.hourup.grid(row=0, column=1)
        self.hourdown.grid(row=1, column=1)

        self.minute.grid(row=0, column=2, rowspan=2)
        self.minuteup.grid(row=0, column=3)
        self.minutedown.grid(row=1, column=3)

        self.second.grid(row=0, column=4, rowspan=2)
        self.secondup.grid(row=0, column=5)
        self.seconddown.grid(row=1, column=5)

        self._status.grid(row=2, column=0, columnspan=5)
        self.playbutton.grid(row=2, column=5, columnspan=1)

        self.root.after(100, self.tick)

        self.root.title("iTunes Sleepytime")
        self.root.resizable(0, 0)
        self.root.grid()
        self.root.mainloop()

    def inchour(self):
        if self.sleepat is None or self.sleepat < time.time():
            self.sleepat = time.time()
        self.sleepat += (60*60)
        self.updatedisplay()

    def dechour(self):
        if self.sleepat is None or self.sleepat < time.time():
            self.sleepat = time.time()
        self.sleepat -= (60*60)
        self.updatedisplay()

    def incminute(self):
        if self.sleepat is None or self.sleepat < time.time():
            self.sleepat = time.time()
        self.sleepat += 60
        self.updatedisplay()

    def decminute(self):
        if self.sleepat is None or self.sleepat < time.time():
            self.sleepat = time.time()
        self.sleepat -= 60
        self.updatedisplay()

    def incsecond(self):
        if self.sleepat is None or self.sleepat < time.time():
            self.sleepat = time.time()
        self.sleepat += 1
        self.updatedisplay()

    def decsecond(self):
        if self.sleepat is None or self.sleepat < time.time():
            self.sleepat = time.time()
        self.sleepat -= 1
        self.updatedisplay()

    def updatedisplay(self):
        if self.sleepat is not None:
            timeleft = (self.sleepat - time.time()) + 1.0
            if timeleft > 0:
                hours = int(timeleft / (60*60))
                minutes = int((timeleft % (60*60))/60)
                seconds = int(timeleft % 60)
                self.hour.config(text="%02i"%hours)
                self.minute.config(text="%02i"%minutes)
                self.second.config(text="%02i"%seconds)
                sleepstring = []
                if hours:
                    sleepstring.append("%i hour%s" % (hours, "" if hours == 1
                        else "s"))
                if minutes:
                    sleepstring.append("%i minute%s" % (minutes, "" if minutes == 1
                        else "s"))
                if hours == 0 and minutes <= 10:
                    sleepstring.append("%i second%s" % (seconds, "" if seconds == 1
                        else "s"))
                self.status = "Pausing iTunes in " + ", ".join(sleepstring)
        else:
            self.hour.config(text="--")
            self.minute.config(text="--")
            self.second.config(text="--")
        self.playbutton.config(text="||" if self.itunes.PlayerState else ">")
        self.root.update()

    @apply
    def status():
        def get_(self):
            return self._status['text']
        def set_(self, value):
            self._status.config(text=str(value))
        return property(get_, set_)

    @property
    def itunes(self):
        if self._itunes is None:
            self._itunes = win32com.client.Dispatch("iTunes.Application")
        return self._itunes

    def tick(self):
        self.updatedisplay()
        if self.sleepat is not None:
            if self.sleepat < time.time():
                self.sleepat = None
                self.root.after(50, self.pauseitunes)
        self.root.after(200, self.tick)


if __name__ == "__main__":
    main()