From: Florian Zeitz Date: Sat, 9 Jul 2011 01:49:23 +0000 (+0200) Subject: Add Makefile X-Git-Url: http://cgit.babelmonkeys.de/?p=mpdbot.git;a=commitdiff_plain;h=58c9d40544119cc2f5861b9c68b4744d08735012 Add Makefile --- diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..27613d6 --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +CPPFLAGS += -Wall -g +LIBS += -lobjxmpp + +.SILENT: + +all: + objfw-compile $(CPPFLAGS) $(LIBS) -o mpdbot src/*.m + +clean: + rm src/*.o diff --git a/PEPThread.h b/PEPThread.h deleted file mode 100644 index d3a0d14..0000000 --- a/PEPThread.h +++ /dev/null @@ -1,6 +0,0 @@ -@interface PEPThread: OFThread -- (void)MPD_connect; -- (OFMutableDictionary*)MPD_responseFromSocket: (OFTCPSocket*)sock; - -OFTCPSocket *sock; -@end diff --git a/PEPThread.m b/PEPThread.m deleted file mode 100644 index 496ebe6..0000000 --- a/PEPThread.m +++ /dev/null @@ -1,133 +0,0 @@ -#import -#import - -#import "PEPThread.h" - -#define NS_PUBSUB @"http://jabber.org/protocol/pubsub" -#define NS_TUNE @"http://jabber.org/protocol/tune" - -@implementation PEPThread: OFThread -- (void)dealloc -{ - [sock release]; - - [super dealloc]; -} - -- (void)MPD_connect -{ - int64_t pause = 1; - while(1) { - @try { - [sock release]; - sock = [[OFTCPSocket alloc] init]; - [sock connectToHost: @"localhost" - port: 6600]; - return; - } @catch (id e) { - of_log(@"Connection failed, retrying in %" PRIi64 - " seconds", pause); - [OFThread sleepForTimeInterval: pause]; - if (pause < 120) - pause *= 2; - [e release]; - } - } -} - -- (OFMutableDictionary*)MPD_responseFromSocket: (OFTCPSocket*)sock -{ - OFString *answer; - OFMutableDictionary *response = [OFMutableDictionary dictionary]; - while ((answer = [sock readLine]) && ![answer hasPrefix: @"OK"]) { - size_t index; - index = [answer indexOfFirstOccurrenceOfString: @":"]; - if (index == OF_INVALID_INDEX) - continue; - [response setObject: [answer substringFromIndex: index + 2 - toIndex: answer.length] - forKey: [answer substringFromIndex: 0 - toIndex: index]]; - } - - return response; -} - -- (id)main -{ - [self MPD_connect]; - [self MPD_responseFromSocket: sock]; - while (1) { - OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; - @try { - OFMutableDictionary *response; - OFString *answer; - XMPPIQ *tuneIQ; - OFXMLElement *pubsub, *publish, *item, *tune; - - tuneIQ = [XMPPIQ IQWithType: @"set" - ID: [object generateStanzaID]]; - pubsub = [OFXMLElement elementWithName: @"pubsub" - namespace: NS_PUBSUB]; - [tuneIQ addChild: pubsub]; - publish = [OFXMLElement elementWithName: @"publish" - namespace: NS_PUBSUB]; - [publish addAttributeWithName: @"node" - stringValue: NS_TUNE]; - [pubsub addChild: publish]; - item = [OFXMLElement elementWithName: @"item" - namespace: NS_PUBSUB]; - [publish addChild: item]; - tune = [OFXMLElement elementWithName: @"tune" - namespace: NS_TUNE]; - [item addChild: tune]; - [sock writeLine: @"status"]; - response = [self MPD_responseFromSocket: sock]; - if ([[response objectForKey: @"state"] - isEqual: @"play"]) { - [sock writeLine: @"currentsong"]; - response = [self MPD_responseFromSocket: sock]; - if ((answer = - [response objectForKey: @"Artist"])) - [tune addChild: [OFXMLElement - elementWithName: @"artist" - namespace: NS_TUNE - stringValue: answer]]; - if ((answer = [response objectForKey: @"Time"])) - [tune addChild: [OFXMLElement - elementWithName: @"length" - namespace: NS_TUNE - stringValue: answer]]; - if ((answer = - [response objectForKey: @"Album"])) - [tune addChild: [OFXMLElement - elementWithName: @"source" - namespace: NS_TUNE - stringValue: answer]]; - if ((answer = - [response objectForKey: @"Title"])) - [tune addChild: [OFXMLElement - elementWithName: @"title" - namespace: NS_TUNE - stringValue: answer]]; - if ((answer = - [response objectForKey: @"Track"])) - [tune addChild: [OFXMLElement - elementWithName: @"track" - namespace: NS_TUNE - stringValue: answer]]; - } - [object sendStanza: tuneIQ]; - [sock writeLine: @"idle player"]; - [self MPD_responseFromSocket: sock]; - } @catch (id e) { - [self MPD_connect]; - [self MPD_responseFromSocket: sock]; - [e release]; - } - [pool release]; - } - - return nil; -} -@end diff --git a/mpdbot.m b/mpdbot.m deleted file mode 100644 index ea84079..0000000 --- a/mpdbot.m +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2010, 2011, Jonathan Schleifer - * Copyright (c) 2011, Florian Zeitz - * - * https://webkeks.org/hg/objxmpp/ - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice is present in all copies. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#import -#import - -#import "PEPThread.h" - -#define NS_DISCO_INFO @"http://jabber.org/protocol/disco#info" - -@interface AppDelegate: OFObject -#ifdef OF_HAVE_OPTIONAL_PROTOCOLS - -#endif - -OFString *discoID; -PEPThread *pepper; -@end - -OF_APPLICATION_DELEGATE(AppDelegate) - -@implementation AppDelegate -- (void)applicationDidFinishLaunching -{ - XMPPConnection *conn; - OFArray *arguments = [OFApplication arguments]; - - conn = [[XMPPConnection alloc] init]; - [conn setDelegate: self]; - - if ([arguments count] != 3) { - of_log(@"Invalid count of command line arguments!"); - [OFApplication terminateWithStatus: 1]; - } - - [conn setDomain: [arguments objectAtIndex: 0]]; - [conn setUsername: [arguments objectAtIndex: 1]]; - [conn setPassword: [arguments objectAtIndex: 2]]; - [conn setResource: @"ObjXMPP"]; - - @try { - [conn connect]; - [conn handleConnection]; - } @catch (id e) { - of_log(@"%@", e); - } -} - -- (void)connectionWasAuthenticated: (XMPPConnection*)conn -{ - of_log(@"Auth successful"); -} - -- (void)connection: (XMPPConnection*)conn - wasBoundToJID: (XMPPJID*)jid -{ - XMPPPresence *pres; - XMPPIQ *disco; - - of_log(@"Bound to JID: %@", [jid fullJID]); - - pres = [XMPPPresence presence]; - [pres addPriority: 0]; - [pres addStatus: @"Hello I'm MPDbot!"]; - [conn sendStanza: pres]; - - discoID = [[conn generateStanzaID] retain]; - disco = [XMPPIQ IQWithType: @"get" - ID: discoID]; - disco.to = [XMPPJID JIDWithString: [[conn JID] bareJID]]; - [disco addChild: [OFXMLElement - elementWithName: @"query" - namespace: NS_DISCO_INFO]]; - - [conn sendStanza: disco]; -} - -- (BOOL)connection: (XMPPConnection*)conn - didReceiveIQ: (XMPPIQ*)iq -{ - OFXMLElement *query = [iq elementForName: @"query" - namespace: NS_DISCO_INFO]; - if ([[iq ID] isEqual: discoID]) { - for (OFXMLElement *identity - in [query elementsForName: @"identity" - namespace: NS_DISCO_INFO]) { - if ([[[identity attributeForName: @"category"] - stringValue] isEqual: @"pubsub"] && - [[[identity attributeForName: @"type"] stringValue] - isEqual: @"pep"]) { - pepper = [[PEPThread alloc] - initWithObject: conn]; - [pepper start]; - return YES; - } - } - } - - return NO; -} - -- (void)connection: (XMPPConnection*)conn - didReceiveMessage: (XMPPMessage*)msg -{ - of_log(@"Message: %@", msg); -} - -- (void)connection: (XMPPConnection*)conn - didReceivePresence: (XMPPPresence*)pres -{ - of_log(@"Presence: %@", pres); -} - -- (void)connectionWasClosed: (XMPPConnection*)conn -{ - of_log(@"Connection was closed!"); -} -@end diff --git a/src/PEPThread.h b/src/PEPThread.h new file mode 100644 index 0000000..d3a0d14 --- /dev/null +++ b/src/PEPThread.h @@ -0,0 +1,6 @@ +@interface PEPThread: OFThread +- (void)MPD_connect; +- (OFMutableDictionary*)MPD_responseFromSocket: (OFTCPSocket*)sock; + +OFTCPSocket *sock; +@end diff --git a/src/PEPThread.m b/src/PEPThread.m new file mode 100644 index 0000000..496ebe6 --- /dev/null +++ b/src/PEPThread.m @@ -0,0 +1,133 @@ +#import +#import + +#import "PEPThread.h" + +#define NS_PUBSUB @"http://jabber.org/protocol/pubsub" +#define NS_TUNE @"http://jabber.org/protocol/tune" + +@implementation PEPThread: OFThread +- (void)dealloc +{ + [sock release]; + + [super dealloc]; +} + +- (void)MPD_connect +{ + int64_t pause = 1; + while(1) { + @try { + [sock release]; + sock = [[OFTCPSocket alloc] init]; + [sock connectToHost: @"localhost" + port: 6600]; + return; + } @catch (id e) { + of_log(@"Connection failed, retrying in %" PRIi64 + " seconds", pause); + [OFThread sleepForTimeInterval: pause]; + if (pause < 120) + pause *= 2; + [e release]; + } + } +} + +- (OFMutableDictionary*)MPD_responseFromSocket: (OFTCPSocket*)sock +{ + OFString *answer; + OFMutableDictionary *response = [OFMutableDictionary dictionary]; + while ((answer = [sock readLine]) && ![answer hasPrefix: @"OK"]) { + size_t index; + index = [answer indexOfFirstOccurrenceOfString: @":"]; + if (index == OF_INVALID_INDEX) + continue; + [response setObject: [answer substringFromIndex: index + 2 + toIndex: answer.length] + forKey: [answer substringFromIndex: 0 + toIndex: index]]; + } + + return response; +} + +- (id)main +{ + [self MPD_connect]; + [self MPD_responseFromSocket: sock]; + while (1) { + OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; + @try { + OFMutableDictionary *response; + OFString *answer; + XMPPIQ *tuneIQ; + OFXMLElement *pubsub, *publish, *item, *tune; + + tuneIQ = [XMPPIQ IQWithType: @"set" + ID: [object generateStanzaID]]; + pubsub = [OFXMLElement elementWithName: @"pubsub" + namespace: NS_PUBSUB]; + [tuneIQ addChild: pubsub]; + publish = [OFXMLElement elementWithName: @"publish" + namespace: NS_PUBSUB]; + [publish addAttributeWithName: @"node" + stringValue: NS_TUNE]; + [pubsub addChild: publish]; + item = [OFXMLElement elementWithName: @"item" + namespace: NS_PUBSUB]; + [publish addChild: item]; + tune = [OFXMLElement elementWithName: @"tune" + namespace: NS_TUNE]; + [item addChild: tune]; + [sock writeLine: @"status"]; + response = [self MPD_responseFromSocket: sock]; + if ([[response objectForKey: @"state"] + isEqual: @"play"]) { + [sock writeLine: @"currentsong"]; + response = [self MPD_responseFromSocket: sock]; + if ((answer = + [response objectForKey: @"Artist"])) + [tune addChild: [OFXMLElement + elementWithName: @"artist" + namespace: NS_TUNE + stringValue: answer]]; + if ((answer = [response objectForKey: @"Time"])) + [tune addChild: [OFXMLElement + elementWithName: @"length" + namespace: NS_TUNE + stringValue: answer]]; + if ((answer = + [response objectForKey: @"Album"])) + [tune addChild: [OFXMLElement + elementWithName: @"source" + namespace: NS_TUNE + stringValue: answer]]; + if ((answer = + [response objectForKey: @"Title"])) + [tune addChild: [OFXMLElement + elementWithName: @"title" + namespace: NS_TUNE + stringValue: answer]]; + if ((answer = + [response objectForKey: @"Track"])) + [tune addChild: [OFXMLElement + elementWithName: @"track" + namespace: NS_TUNE + stringValue: answer]]; + } + [object sendStanza: tuneIQ]; + [sock writeLine: @"idle player"]; + [self MPD_responseFromSocket: sock]; + } @catch (id e) { + [self MPD_connect]; + [self MPD_responseFromSocket: sock]; + [e release]; + } + [pool release]; + } + + return nil; +} +@end diff --git a/src/mpdbot.m b/src/mpdbot.m new file mode 100644 index 0000000..ea84079 --- /dev/null +++ b/src/mpdbot.m @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2010, 2011, Jonathan Schleifer + * Copyright (c) 2011, Florian Zeitz + * + * https://webkeks.org/hg/objxmpp/ + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice is present in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +#import +#import + +#import "PEPThread.h" + +#define NS_DISCO_INFO @"http://jabber.org/protocol/disco#info" + +@interface AppDelegate: OFObject +#ifdef OF_HAVE_OPTIONAL_PROTOCOLS + +#endif + +OFString *discoID; +PEPThread *pepper; +@end + +OF_APPLICATION_DELEGATE(AppDelegate) + +@implementation AppDelegate +- (void)applicationDidFinishLaunching +{ + XMPPConnection *conn; + OFArray *arguments = [OFApplication arguments]; + + conn = [[XMPPConnection alloc] init]; + [conn setDelegate: self]; + + if ([arguments count] != 3) { + of_log(@"Invalid count of command line arguments!"); + [OFApplication terminateWithStatus: 1]; + } + + [conn setDomain: [arguments objectAtIndex: 0]]; + [conn setUsername: [arguments objectAtIndex: 1]]; + [conn setPassword: [arguments objectAtIndex: 2]]; + [conn setResource: @"ObjXMPP"]; + + @try { + [conn connect]; + [conn handleConnection]; + } @catch (id e) { + of_log(@"%@", e); + } +} + +- (void)connectionWasAuthenticated: (XMPPConnection*)conn +{ + of_log(@"Auth successful"); +} + +- (void)connection: (XMPPConnection*)conn + wasBoundToJID: (XMPPJID*)jid +{ + XMPPPresence *pres; + XMPPIQ *disco; + + of_log(@"Bound to JID: %@", [jid fullJID]); + + pres = [XMPPPresence presence]; + [pres addPriority: 0]; + [pres addStatus: @"Hello I'm MPDbot!"]; + [conn sendStanza: pres]; + + discoID = [[conn generateStanzaID] retain]; + disco = [XMPPIQ IQWithType: @"get" + ID: discoID]; + disco.to = [XMPPJID JIDWithString: [[conn JID] bareJID]]; + [disco addChild: [OFXMLElement + elementWithName: @"query" + namespace: NS_DISCO_INFO]]; + + [conn sendStanza: disco]; +} + +- (BOOL)connection: (XMPPConnection*)conn + didReceiveIQ: (XMPPIQ*)iq +{ + OFXMLElement *query = [iq elementForName: @"query" + namespace: NS_DISCO_INFO]; + if ([[iq ID] isEqual: discoID]) { + for (OFXMLElement *identity + in [query elementsForName: @"identity" + namespace: NS_DISCO_INFO]) { + if ([[[identity attributeForName: @"category"] + stringValue] isEqual: @"pubsub"] && + [[[identity attributeForName: @"type"] stringValue] + isEqual: @"pep"]) { + pepper = [[PEPThread alloc] + initWithObject: conn]; + [pepper start]; + return YES; + } + } + } + + return NO; +} + +- (void)connection: (XMPPConnection*)conn + didReceiveMessage: (XMPPMessage*)msg +{ + of_log(@"Message: %@", msg); +} + +- (void)connection: (XMPPConnection*)conn + didReceivePresence: (XMPPPresence*)pres +{ + of_log(@"Presence: %@", pres); +} + +- (void)connectionWasClosed: (XMPPConnection*)conn +{ + of_log(@"Connection was closed!"); +} +@end