PageRenderTime 42ms CodeModel.GetById 51ms RepoModel.GetById 1ms app.codeStats 0ms

/alarm.py

https://github.com/jabbalaci/Bash-Utils
Python | 195 lines | 149 code | 26 blank | 20 comment | 19 complexity | 45012e5d7026fd2bdedddf4a1823c4cd MD5 | raw file
  1. #!/usr/bin/env python3
  2. """
  3. Alarm script
  4. ============
  5. Author: Laszlo Szathmary, 2011 (jabba.laci@gmail.com)
  6. Website: https://ubuntuincident.wordpress.com/2011/04/17/alarm-script/
  7. GitHub: https://github.com/jabbalaci/Bash-Utils
  8. A simple alarm script that plays a list of MP3s at a given time.
  9. Very useful if you leave your computer switched on during the night.
  10. Usage:
  11. ------
  12. ./alarm.py -p
  13. Play music. First do this to adjust volume! If the volume is low,
  14. you won't hear it in the morning.
  15. ./alarm.py -t 7h15
  16. Set alarm time. The format is HhM, where H is the hour (24-hour system),
  17. M is the minute, 'h' is the separator.
  18. ./alarm.py
  19. Set alarm with the default time. In my case it's 6h55.
  20. Last update: 2017-01-08 (yyyy-mm-dd)
  21. """
  22. import os
  23. import sys
  24. from datetime import datetime
  25. from optparse import OptionParser
  26. from random import shuffle
  27. from time import sleep
  28. from lib import fs, podium
  29. import config as cfg
  30. MUSIC_DIR = '/media/jabba/JIVE/mp3/sfa_scifi'
  31. if podium.get_short_fingerprint() in ['91d6c2', '863604']:
  32. MUSIC_DIR = '/trash/mp3'
  33. TRAVERSE_RECURSIVELY = True
  34. MPLAYER = cfg.MPLAYER
  35. MPLAYER_OPTIONS = '-endpos 00:00:60' # play first 60 seconds; disabled when -p is used
  36. DEFAULT_TIME = '6h55'
  37. fs.check_if_available(MPLAYER, "Error: {} is not available!".format(MPLAYER))
  38. class CollectMp3:
  39. """Collect music files recursively in a given directory."""
  40. def __init__(self, music_dir):
  41. self.music_dir = music_dir
  42. self.songs = []
  43. def traverse(self, directory):
  44. """Traverse directory recursively. Symlinks are skipped."""
  45. content = [os.path.join(directory, x) for x in os.listdir(directory)]
  46. dirs = sorted([x for x in content if os.path.isdir(x)])
  47. files = sorted([x for x in content if os.path.isfile(x)])
  48. for f in files:
  49. if os.path.islink(f):
  50. continue
  51. ext = os.path.splitext(f)[1]
  52. if ext in ('.mp3', '.flac', '.ogg', '.flv'):
  53. self.songs.append(f)
  54. if TRAVERSE_RECURSIVELY:
  55. for d in dirs:
  56. if os.path.islink(d):
  57. continue
  58. self.traverse(d)
  59. def collect(self):
  60. """Collect songs, shuffle order, and print a little statistics."""
  61. self.traverse(self.music_dir)
  62. if self.get_number_of_songs() == 0:
  63. print("Error: there are no songs available.")
  64. sys.exit(-1)
  65. # else
  66. shuffle(self.songs)
  67. header = "number of songs: {0}".format(self.get_number_of_songs())
  68. sep = '#' * (len(header) + 2 + 2)
  69. print(sep)
  70. print('#', header, '#')
  71. print(sep)
  72. print()
  73. def get_number_of_songs(self):
  74. return len(self.songs)
  75. def get_songs(self):
  76. return self.songs
  77. collector = CollectMp3(MUSIC_DIR)
  78. #############################################################################
  79. def play_music():
  80. songs = collector.get_songs()
  81. for f in songs:
  82. val = os.system("{mplayer} {options} \"{song}\"".format(mplayer=MPLAYER, options=MPLAYER_OPTIONS, song=f))
  83. if val == 2: # interrupted with CTRL-C
  84. sys.exit(val)
  85. def set_alarm(hour, minute):
  86. sep = "=" * 18
  87. print(sep)
  88. print("| alarm at {0:2}h{1:02} |".format(hour, minute))
  89. print(sep)
  90. alarm_time = hour * 100 + minute
  91. while True:
  92. now = datetime.now()
  93. time = datetime.time(now)
  94. current_time = time.hour * 100 + time.minute
  95. if (current_time >= alarm_time) and (current_time - alarm_time <= 100):
  96. play_music()
  97. sys.exit(0)
  98. else:
  99. sys.stdout.write('.'); sys.stdout.flush()
  100. try:
  101. sleep(10)
  102. except KeyboardInterrupt:
  103. print()
  104. break # break out of 'while True'
  105. def check_alarm(alarm_time):
  106. msg = "{0} error: there is a problem with the alarm time.".format(sys.argv[0])
  107. try:
  108. alarm_time = alarm_time.lower()
  109. if 'h' not in alarm_time:
  110. alarm_time += 'h'
  111. hour, minute = alarm_time.split('h')
  112. if not minute:
  113. minute = '0'
  114. hour = int(hour)
  115. minute = int(minute)
  116. if not ((0 <= hour <= 23) and (0 <= minute <= 59)):
  117. print(msg, file=sys.stderr)
  118. sys.exit(1)
  119. except ValueError:
  120. print(msg, file=sys.stderr)
  121. sys.exit(1)
  122. return hour, minute
  123. def main(default=DEFAULT_TIME):
  124. parser = OptionParser(usage='%prog [options]')
  125. parser.add_option('-t',
  126. '--time',
  127. action='store',
  128. default=default,
  129. type='string',
  130. dest='alarm_time',
  131. help='Alarm time, ex.: 6h55.')
  132. parser.add_option('-p',
  133. '--play',
  134. action='store_true',
  135. default=False,
  136. dest='is_play',
  137. help='Play music. Useful for adjusting the volume.')
  138. options, arguments = parser.parse_args()
  139. if options.is_play:
  140. global MPLAYER_OPTIONS
  141. MPLAYER_OPTIONS = ''
  142. print('# MPLAYER_OPTIONS is disabled')
  143. collector.collect()
  144. if options.is_play:
  145. play_music() # play and
  146. sys.exit(0) # quit
  147. # else
  148. if options.alarm_time:
  149. hour, minute = check_alarm(options.alarm_time)
  150. set_alarm(hour, minute)
  151. #############################################################################
  152. if __name__ == "__main__":
  153. main()