~jonas-drange/ubuntu-push/state-State

« back to all changes in this revision

Viewing changes to sounds/sounds.go

  • Committer: Tarmac
  • Author(s): jonas-drange
  • Date: 2015-12-09 16:12:15 UTC
  • mfrom: (419.1.7 lp1413818)
  • Revision ID: tarmac-20151209161215-hoibw2ynh8ufwbku
[r=dobey] use Notifications dbus API to play sounds

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
        "launchpad.net/ubuntu-push/logger"
32
32
)
33
33
 
34
 
type Sound struct {
 
34
type Sound interface {
 
35
        // Present() presents the notification audibly if applicable.
 
36
        Present(app *click.AppId, nid string, notification *launch_helper.Notification) bool
 
37
        // GetSound() returns absolute path to the file the given notification will play.
 
38
        GetSound(app *click.AppId, nid string, notification *launch_helper.Notification) string
 
39
}
 
40
 
 
41
type sound struct {
35
42
        player   string
36
43
        log      logger.Logger
37
44
        acc      accounts.Accounts
40
47
        dataFind func(string) (string, error)
41
48
}
42
49
 
43
 
func New(log logger.Logger, acc accounts.Accounts, fallback string) *Sound {
44
 
        return &Sound{
 
50
func New(log logger.Logger, acc accounts.Accounts, fallback string) *sound {
 
51
        return &sound{
45
52
                player:   "paplay",
46
53
                log:      log,
47
54
                acc:      acc,
51
58
        }
52
59
}
53
60
 
54
 
func (snd *Sound) Present(app *click.AppId, nid string, notification *launch_helper.Notification) bool {
 
61
func (snd *sound) Present(app *click.AppId, nid string, notification *launch_helper.Notification) bool {
55
62
        if notification == nil {
56
63
                panic("please check notification is not nil before calling present")
57
64
        }
58
65
 
 
66
        absPath := snd.GetSound(app, nid, notification)
 
67
        if absPath == "" {
 
68
                return false
 
69
        }
 
70
 
 
71
        snd.log.Debugf("[%s] playing sound %s using %s", nid, absPath, snd.player)
 
72
        cmd := exec.Command(snd.player, absPath)
 
73
        err := cmd.Start()
 
74
        if err != nil {
 
75
                snd.log.Debugf("[%s] unable to play: %v", nid, err)
 
76
                return false
 
77
        }
 
78
        go func() {
 
79
                err := cmd.Wait()
 
80
                if err != nil {
 
81
                        snd.log.Debugf("[%s] error playing sound %s: %v", nid, absPath, err)
 
82
                }
 
83
        }()
 
84
        return true
 
85
}
 
86
 
 
87
// Returns the absolute path of the sound to be played for app, nid and notification.
 
88
func (snd *sound) GetSound(app *click.AppId, nid string, notification *launch_helper.Notification) string {
 
89
 
59
90
        if snd.acc.SilentMode() {
60
91
                snd.log.Debugf("[%s] no sounds: silent mode on.", nid)
61
 
                return false
 
92
                return ""
62
93
        }
63
94
 
64
95
        fallback := snd.acc.MessageSoundFile()
69
100
        sound := notification.Sound(fallback)
70
101
        if sound == "" {
71
102
                snd.log.Debugf("[%s] notification has no Sound: %#v", nid, sound)
72
 
                return false
 
103
                return ""
73
104
        }
74
105
        absPath := snd.findSoundFile(app, nid, sound)
75
106
        if absPath == "" {
76
107
                snd.log.Debugf("[%s] unable to find sound %s", nid, sound)
77
 
                return false
78
 
        }
79
 
        snd.log.Debugf("[%s] playing sound %s using %s", nid, absPath, snd.player)
80
 
        cmd := exec.Command(snd.player, absPath)
81
 
        err := cmd.Start()
82
 
        if err != nil {
83
 
                snd.log.Debugf("[%s] unable to play: %v", nid, err)
84
 
                return false
85
 
        }
86
 
        go func() {
87
 
                err := cmd.Wait()
88
 
                if err != nil {
89
 
                        snd.log.Debugf("[%s] error playing sound %s: %v", nid, absPath, err)
90
 
                }
91
 
        }()
92
 
        return true
 
108
        }
 
109
        return absPath
93
110
}
94
111
 
95
112
// Removes all cruft from path, ensures it's a "forward" path.
96
 
func (snd *Sound) cleanPath(path string) (string, error) {
 
113
func (snd *sound) cleanPath(path string) (string, error) {
97
114
        cleaned := filepath.Clean(path)
98
115
        if strings.Contains(cleaned, "../") {
99
116
                return "", errors.New("Path escaping xdg attempt")
101
118
        return cleaned, nil
102
119
}
103
120
 
104
 
func (snd *Sound) findSoundFile(app *click.AppId, nid string, sound string) string {
 
121
func (snd *sound) findSoundFile(app *click.AppId, nid string, sound string) string {
105
122
        // XXX also support legacy appIds?
106
123
        // first, check package-specific
107
124
        sound, err := snd.cleanPath(sound)