Ticket #1984: sound.5.diff
| File sound.5.diff, 11.0 kB (added by ressu@…, 2 years ago) |
|---|
-
(a) /dev/null vs. (b) src/common/sound.py
=== added file 'src/common/sound.py'
a b 1 ## common/gst.py 2 ## 3 ## Contributors for this file: 4 ## - Sami Haahtinen <ressu@ressukka.net> 5 ## 6 ## Copyright (C) 2006 Sami Haahtinen <ressu@ressukka.net> 7 ## 8 ## This program is free software; you can redistribute it and/or modify 9 ## it under the terms of the GNU General Public License as published 10 ## by the Free Software Foundation; version 2 only. 11 ## 12 ## This program is distributed in the hope that it will be useful, 13 ## but WITHOUT ANY WARRANTY; without even the implied warranty of 14 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 ## GNU General Public License for more details. 16 17 import gajim 18 import os 19 20 class GajimPlayer: 21 player = None 22 23 def __init__(self): 24 # For now, lets default to GStreamer, winsound, and then try External player 25 # FIXME: This really needs elegance! 26 if not gajim.config.get('sounds_on'): 27 raise NoSound 28 29 try: 30 if not gajim.config.get('use_gstreamer'): 31 raise self.PlayerUnavailable 32 self.player = GajimGstPlayer() 33 except self.PlayerUnavailable: 34 try: 35 self.player = GajimWin32Player() 36 except self.PlayerUnavailable: 37 try: 38 self.player = GajimExtPlayer() 39 except self.PlayerUnavailable: 40 self.player = None # Make sure that player is still set to None 41 raise NoSound 42 43 class NoSound(Exception): 44 '''Notifies the system that we should be silent''' 45 46 class BeepOnly(Exception): 47 '''Notifies the system that we should just beep''' 48 49 class PlayerUnavailable(Exception): 50 '''Notifies that the player is unavailable''' 51 52 def event_to_soundfile(self, event): 53 '''Returns the full file path for sound file of an event''' 54 # Check if we should play sound at all 55 if self.player is None: 56 raise NoSound 57 58 # Get soundevent 59 path_to_soundfile = gajim.config.get_per('soundevents', event, 'path') 60 61 if path_to_soundfile is None or not os.path.exists(path_to_soundfile): 62 raise NoSound 63 64 return path_to_soundfile 65 66 def play(self, soundfile): 67 if soundfile == 'beep': 68 beep() 69 70 if self.player is None: 71 return 72 73 self.player.play_sound(soundfile) 74 75 def beep(self): 76 '''Play a single beep''' 77 # FIXME: There must be a better way 78 print "\a" 79 80 # FIXME: This class hasn't gotten any testing! 81 class GajimWin32Player: 82 '''User native Win32 layer to play sounds''' 83 84 def __init__(self): 85 try: 86 import winsound 87 except ImportError: 88 # gst module is not available... 89 raise GajimPlayer.PlayerUnavailable, "Winsound library not available" 90 91 def play_sound(self,soundfile): 92 try: 93 winsound.PlaySound(soundfile, winsound.SND_FILENAME|winsound.SND_ASYNC) 94 except: 95 pass 96 97 class GajimExtPlayer: 98 '''Use external application to play the sounds''' 99 100 def __init__(self): 101 self.player = gajim.config.get('soundplayer') 102 if self.player == '': 103 raise GajimPlayer.PlayerUnavailable, "External player not set" 104 # FIXME: We should check if the player exists! 105 106 def play_sound(self,soundfile): 107 soundfile = soundfile.replace('"', '\\"') 108 command = self.player + ' "' + soundfile + '" &' 109 os.system(command) 110 111 class GajimGstPlayer: 112 '''Player that plays sound events through the GStreamer framework''' 113 114 def __init__(self): 115 try: 116 import gst 117 except ImportError: 118 # gst module is not available... 119 raise GajimPlayer.PlayerUnavailable, "Python Gstreamer modules not available" 120 self.gst = gst 121 self.GstBin = self.gst.parse_launch("playbin") 122 123 # Create a sink for video, if someone decides to use a video file ;) 124 fakesink = self.gst.element_factory_make("fakesink") 125 self.GstBin.set_property("video-sink", fakesink) 126 127 # Attach a message handler to the pipeline 128 bus = self.GstBin.get_bus() 129 bus.add_signal_watch() 130 bus.connect('message', self.gstevent) 131 132 def play_sound(self,soundfile): 133 self.GstBin.set_state(self.gst.STATE_NULL) 134 135 # since playbin takes input in URI format, add file:// prefix 136 sounduri = "file://" + os.path.abspath(soundfile) 137 self.GstBin.set_property('uri', sounduri) 138 139 self.GstBin.set_state(self.gst.STATE_PLAYING) 140 141 def gstevent(self, bus, message): 142 t = message.type 143 if t == self.gst.MESSAGE_EOS: 144 self.reset_player() 145 146 def reset_player(self): 147 '''Simply Reset the player''' 148 self.GstBin.set_state(self.gst.STATE_NULL) 149 150 def play_event(event): 151 global Player 152 try: 153 try: 154 soundfile = Player.event_to_soundfile(event) 155 except NameError: 156 Player = GajimPlayer() 157 soundfile = Player.event_to_soundfile(event) 158 except GajimPlayer.NoSound: 159 # No sound. 160 return 161 162 # Ok, we should be clear to play the sound 163 Player.play(soundfile) -
src/common/config.py
=== modified file 'src/common/config.py'
202 202 'chat_merge_consecutive_nickname': [opt_bool, False, _('Merge consecutive nickname in chat window')], 203 203 'chat_merge_consecutive_nickname_indent': [opt_str, ' ', _('Indentation when using merge consecutive nickame')], 204 204 'gc_nicknames_colors': [ opt_str, '#a34526:#c000ff:#0012ff:#388a99:#38995d:#519938:#ff8a00:#94452d:#244b5a:#32645a', _('List of colors that will be used to color nicknames in groupchats'), True ], 205 'use_gstreamer': [opt_bool, False, _('Try to use gstreamer as the sound system'), True], 205 206 } 206 207 207 208 __options_per_key = { -
src/common/helpers.py
=== modified file 'src/common/helpers.py'
30 30 from xmpp_stringprep import nodeprep, resourceprep, nameprep 31 31 32 32 try: 33 import winsound # windows-only built-in module for playing wav34 33 import win32api 35 34 import win32con 36 35 except: … … 414 413 except: 415 414 pass 416 415 417 def play_sound(event):418 if not gajim.config.get('sounds_on'):419 return420 path_to_soundfile = gajim.config.get_per('soundevents', event, 'path')421 if path_to_soundfile == 'beep':422 print '\a' # make a speaker beep423 return424 if path_to_soundfile is None or not os.path.exists(path_to_soundfile):425 return426 if os.name == 'nt':427 try:428 winsound.PlaySound(path_to_soundfile,429 winsound.SND_FILENAME|winsound.SND_ASYNC)430 except:431 pass432 elif os.name == 'posix':433 if gajim.config.get('soundplayer') == '':434 return435 player = gajim.config.get('soundplayer')436 # we add the path in "" so we have good parsing from shell437 path_to_soundfile = path_to_soundfile.replace('"', '\\"') # escape "438 command = player + ' "' + path_to_soundfile + '" &'439 #FIXME: when we require 2.4+ use subprocess module440 os.system(command)441 442 416 def get_file_path_from_dnd_dropped_uri(uri): 443 417 path = urllib.url2pathname(uri) # escape special chars 444 418 path = path.strip('\r\n\x00') # remove \r\n and NULL -
src/config.py
=== modified file 'src/config.py'
37 37 from common import helpers 38 38 from common import gajim 39 39 from common import connection 40 from common import sound 40 41 41 42 #---------- PreferencesWindow class -------------# 42 43 class PreferencesWindow: … … 978 979 if not iter: 979 980 return 980 981 snd_event_config_name = model[iter][3] 981 helpers.play_sound(snd_event_config_name)982 sound.play_event(snd_event_config_name) 982 983 983 984 def on_open_advanced_editor_button_clicked(self, widget, data = None): 984 985 if gajim.interface.instances.has_key('advanced_config'): -
src/gajim.py
=== modified file 'src/gajim.py'
40 40 from chat_control import ChatControlBase 41 41 42 42 from common import exceptions 43 from common import sound 43 44 44 45 try: 45 46 import gtk … … 617 618 msg = array[1] 618 619 # do not play sound when standalone chatstate message (eg no msg) 619 620 if msg and gajim.config.get_per('soundevents', 'message_sent', 'enabled'): 620 helpers.play_sound('message_sent')621 sound.play_event('message_sent') 621 622 622 623 def handle_event_subscribe(self, account, array): 623 624 #('SUBSCRIBE', account, (jid, text, user_nick)) user_nick is JEP-0172 -
src/groupchat_control.py
=== modified file 'src/groupchat_control.py'
35 35 36 36 from common import gajim 37 37 from common import helpers 38 from common import sound 38 39 39 40 from chat_control import ChatControl 40 41 from chat_control import ChatControlBase … … 530 531 531 532 if kind == 'incoming': # it's a message NOT from us 532 533 # highlighting and sounds 533 (highlight, sound ) = self.highlighting_for_message(text, tim)534 (highlight, sound_event) = self.highlighting_for_message(text, tim) 534 535 gc_class=self.__class__ 535 536 if gc_class.gc_custom_colors.has_key(contact): 536 537 other_tags_for_name.append('gc_nickname_color_' + \ … … 548 549 self.parent_win.redraw_tab(self, 'attention') 549 550 other_tags_for_name.append('bold') 550 551 other_tags_for_text.append('marked') 551 if sound == 'received':552 helpers.play_sound('muc_message_received')553 elif sound == 'highlight':554 helpers.play_sound('muc_message_highlight')552 if sound_event == 'received': 553 sound.play_event('muc_message_received') 554 elif sound_event == 'highlight': 555 sound.play_event('muc_message_highlight') 555 556 556 557 self.check_and_possibly_add_focus_out_line() 557 558 … … 561 562 def highlighting_for_message(self, text, tim): 562 563 '''Returns a 2-Tuple. The first says whether or not to highlight the 563 564 text, the second, what sound to play.''' 564 highlight, sound = (None, None)565 highlight, sound_event = (None, None) 565 566 566 567 # Do we play a sound on every muc message? 567 568 if gajim.config.get_per('soundevents', 'muc_message_received', 'enabled'): 568 569 if gajim.config.get('notify_on_all_muc_messages'): 569 sound = 'received'570 sound_event = 'received' 570 571 571 572 # Are any of the defined highlighting words in the text? 572 573 if self.needs_visual_notification(text): 573 574 highlight = True 574 575 if gajim.config.get_per('soundevents', 'muc_message_highlight', 575 576 'enabled'): 576 sound = 'highlight'577 sound_event = 'highlight' 577 578 578 579 # Is it a history message? Don't want sound-floods when we join. 579 580 if tim != time.localtime(): 580 sound = None581 582 return (highlight, sound )581 sound_event = None 582 583 return (highlight, sound_event) 583 584 584 585 def check_and_possibly_add_focus_out_line(self): 585 586 '''checks and possibly adds focus out line for room_jid if it needs it -
src/notify.py
=== modified file 'src/notify.py'
24 24 25 25 from common import gajim 26 26 from common import helpers 27 from common import sound 27 28 28 29 import dbus_support 29 30 if dbus_support.supported: … … 164 165 if (do_sound): 165 166 if (event == 'new_message'): 166 167 if first: 167 helpers.play_sound('first_message_received')168 sound.play_event('first_message_received') 168 169 else: 169 helpers.play_sound('next_message_received')170 sound.play_event('next_message_received') 170 171 elif (event == 'contact_connected' or event == 'contact_disconnected'): 171 helpers.play_sound(event)172 sound.play_event(event) 172 173 173 174 174 175 def popup(event_type, jid, account, msg_type = '', path_to_image = None,
