2 * Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de>
4 * http://cgit.babelmonkeys.de/cgit.cgi/mpdbot/
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice is present in all copies.
10 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
11 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
12 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
13 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
14 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
15 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
16 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
17 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
18 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
19 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
20 * POSSIBILITY OF SUCH DAMAGE.
23 #import <ObjFW/ObjFW.h>
24 #import <ObjXMPP/ObjXMPP.h>
28 #define NS_PUBSUB @"http://jabber.org/protocol/pubsub"
29 #define NS_TUNE @"http://jabber.org/protocol/tune"
31 @implementation PEPThread: OFThread
45 sock = [[OFTCPSocket alloc] init];
46 [sock connectToHost: mpd_host
50 [of_stderr writeFormat: @"Connection failed, retrying"
51 @" in %" PRIi64 @" seconds\n", pause];
52 [OFThread sleepForTimeInterval: pause];
60 - (OFMutableDictionary*)MPD_responseFromSocket: (OFTCPSocket*)sock_
63 OFMutableDictionary *response = [OFMutableDictionary dictionary];
64 while ((answer = [sock_ readLine]) && ![answer hasPrefix: @"OK"]) {
66 index = [answer indexOfFirstOccurrenceOfString: @":"];
67 if (index == OF_INVALID_INDEX)
69 [response setObject: [answer substringFromIndex: index + 2
70 toIndex: answer.length]
71 forKey: [answer substringFromIndex: 0
80 OFDictionary *environment = [OFApplication environment];
81 OFString *mpd_port_string;
82 mpd_host = [environment objectForKey: @"MPD_HOST"];
84 mpd_host = @"localhost";
85 mpd_port_string = [environment objectForKey: @"MPD_PORT"];
86 if (mpd_port_string && [mpd_port_string decimalValue] <= UINT16_MAX)
87 mpd_port = (uint16_t) [mpd_port_string decimalValue];
91 [self MPD_responseFromSocket: sock];
93 OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
95 OFMutableDictionary *response;
98 OFXMLElement *pubsub, *publish, *item, *tune;
100 tuneIQ = [XMPPIQ IQWithType: @"set"
101 ID: [object generateStanzaID]];
102 pubsub = [OFXMLElement elementWithName: @"pubsub"
103 namespace: NS_PUBSUB];
104 [tuneIQ addChild: pubsub];
105 publish = [OFXMLElement elementWithName: @"publish"
106 namespace: NS_PUBSUB];
107 [publish addAttributeWithName: @"node"
108 stringValue: NS_TUNE];
109 [pubsub addChild: publish];
110 item = [OFXMLElement elementWithName: @"item"
111 namespace: NS_PUBSUB];
112 [publish addChild: item];
113 tune = [OFXMLElement elementWithName: @"tune"
115 [item addChild: tune];
116 [sock writeLine: @"status"];
117 response = [self MPD_responseFromSocket: sock];
118 if ([[response objectForKey: @"state"]
120 [sock writeLine: @"currentsong"];
121 response = [self MPD_responseFromSocket: sock];
123 [response objectForKey: @"Artist"]))
124 [tune addChild: [OFXMLElement
125 elementWithName: @"artist"
127 stringValue: answer]];
128 if ((answer = [response objectForKey: @"Time"]))
129 [tune addChild: [OFXMLElement
130 elementWithName: @"length"
132 stringValue: answer]];
134 [response objectForKey: @"Album"]))
135 [tune addChild: [OFXMLElement
136 elementWithName: @"source"
138 stringValue: answer]];
140 [response objectForKey: @"Title"]))
141 [tune addChild: [OFXMLElement
142 elementWithName: @"title"
144 stringValue: answer]];
146 [response objectForKey: @"Track"]))
147 [tune addChild: [OFXMLElement
148 elementWithName: @"track"
150 stringValue: answer]];
152 [object sendStanza: tuneIQ];
153 [sock writeLine: @"idle player"];
154 [self MPD_responseFromSocket: sock];
157 [self MPD_responseFromSocket: sock];