1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-09-19 02:11:32 +02:00

Compare commits

..

35 Commits
0.0.1 ... 0.0.2

Author SHA1 Message Date
Christian Muehlhaeuser
e24aea480e * Cleaned up Jabber auth. 2011-03-28 07:13:30 +02:00
Christian Muehlhaeuser
4d23dea891 * Updated OS X sparkle templates. 2011-03-28 06:52:57 +02:00
Christian Muehlhaeuser
6c49b2683e * Changed win32-sparkle behaviour: It'll now look for beta versions if you run Tomahawk with --debug. 2011-03-28 05:28:05 +02:00
Christian Muehlhaeuser
32ed0c748b * Updated sparkle templates. 2011-03-25 00:08:28 +00:00
Christian Muehlhaeuser
23d4a03aca * Prepare version 0.0.2. 2011-03-24 23:54:35 +00:00
Christian Muehlhaeuser
6a2c2b147d * Merged back my fixes. 2011-03-28 05:01:28 +02:00
Jeff Mitchell
5a08079740 Recovering from faulty merge...
Revert "* Fixed SIP plugins always reconnecting when the SettingsDialog was closed."

This reverts commit 057825bf97.
2011-03-27 22:45:31 -04:00
Jeff Mitchell
3f1274b90a Recovering from faulty merge...
Revert "* Forgot to add one file."

This reverts commit 0bf3a1b8e7.
2011-03-27 22:45:14 -04:00
Christian Muehlhaeuser
21f49bbfcb * Updated changelog. 2011-03-28 04:01:43 +02:00
Christian Muehlhaeuser
0bf3a1b8e7 * Forgot to add one file. 2011-03-28 03:31:53 +02:00
Christian Muehlhaeuser
057825bf97 * Fixed SIP plugins always reconnecting when the SettingsDialog was closed. 2011-03-28 03:31:10 +02:00
Jeff Mitchell
608b90867a Don't rescan the local collection if the settings dialog is closed with success but the path hasn't changed 2011-03-27 19:10:30 -04:00
Jeff Mitchell
21e6fb8c09 Update ChangeLog 2011-03-27 19:00:52 -04:00
Jeff Mitchell
63550ce712 Don't attempt to reconnect over and over with twitter if the peer hasn't changed status 2011-03-27 18:55:02 -04:00
Dominik Schmidt
b378f934ec Add changelog message in stable too, i'm sorry :p 2011-03-28 00:19:15 +02:00
Leo Franchi
87fa7e0f50 Add to changelog 2011-03-27 17:58:00 -04:00
Jeff Mitchell
c4302e5f49 Show legal indemnity warning, and link to the legal page on the web site. Only displays the first time you go online (unless you don't accept it, of course). 2011-03-27 16:09:56 -04:00
Jeff Mitchell
474b9bc604 Merge branch 'stable' of github.com:tomahawk-player/tomahawk into stable 2011-03-27 13:57:13 -04:00
Jeff Mitchell
719255e4c9 Revamp twitter config widget again -- use a drop down box for message type. Also display name of saved user. 2011-03-27 13:56:49 -04:00
Dominik Schmidt
6bde5655cd Hopefully fixed jabber auth completely now 2011-03-27 19:11:29 +02:00
Jeff Mitchell
26d4da4612 Don't just look at a user's latest tweet -- look at the latest tweet that matches our regex. Alternately for DMs look at latest matching regex or matching TOMAHAWKPEER format. Also some consolidation. 2011-03-27 10:48:00 -04:00
Jeff Mitchell
db53aabcf2 You can now send global, mentions, or private (direct message) Got Tomahawk? tweets 2011-03-27 10:47:11 -04:00
Dominik Schmidt
da409f9fa7 Set CLUCENE_MIN_VERSION default value to the version we need, needed until macro_optional_find_package is fixed to support versions 2011-03-27 16:25:29 +02:00
Dominik Schmidt
99e1b6f327 Make the subscription request box non-blocking. 2011-03-27 04:29:09 +02:00
Dominik Schmidt
5056aadcd2 Don't open more than one SubscriptionRequest window and auto-ack only contacts that the user is already subscribed to 2011-03-27 01:24:42 +01:00
Jeff Mitchell
9558270d86 Display a helpful message when someone gives non-JSON data to the xmpp bot 2011-03-26 16:51:33 -04:00
Dominik Schmidt
9496885d63 Don't ask the user again to ack the subscription request in sip_jabber if the requesting contact is already on the roster 2011-03-26 19:58:31 +01:00
Dominik Schmidt
15cbeb30da Merge branch 'stable' of git://github.com/tomahawk-player/tomahawk into stable 2011-03-26 18:26:36 +01:00
Dominik Schmidt
4677d761ac Make the sip plugin aware of subscription requests again 2011-03-26 18:26:31 +01:00
Christian Muehlhaeuser
581814f482 Merge branch 'stable' of github.com:tomahawk-player/tomahawk into stable 2011-03-26 07:21:02 +01:00
Christian Muehlhaeuser
6da813d4c3 * Updated stable README. 2011-03-26 07:19:15 +01:00
Jeff Mitchell
422f9a9022 Possibly fix crash related to twitter authentication 2011-03-25 18:23:17 -04:00
Leo Franchi
631c39163d don't install a static lib 2011-03-25 17:45:32 -04:00
Leo Franchi
8f46db649f add some eliding so playlists with long name don't increase the window size
minor cleanup in ElidedLabel
2011-03-25 16:07:11 -04:00
Christian Muehlhaeuser
4f77de3bbc * Changed domme's email address. 2011-03-25 07:08:34 +01:00
38 changed files with 707 additions and 247 deletions

View File

@@ -5,7 +5,7 @@ Tomahawk is primarily authored by:
Contributors include:
* Leo Franchi <lfranchi@kde.org>
* Dominik Schmidt <domme@rautelinux.org>
* Dominik Schmidt <dev@dominik-schmidt.de>
* Jeff Mitchell <mitchell@kde.org>
* J Herskowitz <jherskow@gmail.com>
* Alejandro Wainzinger <aikawarazuni@gmail.com>

View File

@@ -7,7 +7,7 @@ CMAKE_MINIMUM_REQUIRED( VERSION 2.8 )
SET( ORGANIZATION_NAME "Tomahawk" )
SET( ORGANIZATION_DOMAIN "tomahawk-player.org" )
SET( APPLICATION_NAME "Tomahawk" )
SET( VERSION "0.0.1" )
SET( VERSION "0.0.2" )
# set paths

View File

@@ -13,7 +13,7 @@ INCLUDE(CheckSymbolExists)
INCLUDE(FindLibraryWithDebug)
if(NOT CLUCENE_MIN_VERSION)
set(CLUCENE_MIN_VERSION "0.9.19")
set(CLUCENE_MIN_VERSION "0.9.23")
endif(NOT CLUCENE_MIN_VERSION)
IF(EXISTS ${PROJECT_CMAKE}/CLuceneConfig.cmake)

View File

@@ -1,2 +1,20 @@
Version 0.0.2:
* Don't reconnect to Jabber if the settings dialog is closed successfully
but the Jabber settings haven't changed.
* Don't run a rescan of the local collection if the settings dialog is
closed successfully but the path hasn't changed.
* Don't attempt to connect to unavailable Twitter peers over and over.
* Find Twitter peers if the peer's Got Tomahawk? tweet is not their latest
tweet.
* Got Tomahawk? tweets can now be sent directly to specific users or in
private direct messages.
* Display a helpful message when someone sends a normal instant message to
the Tomahawk XMPP presence.
* Incompatible change: Twitter SIP protocol has changed slightly. 0.0.1
clients will not be able to talk to newer clients.
* Hopefully fixed crashes during Twitter authentication.
* Don't let long playlist or summary names force a large Tomahawk window.
* Tomahawk now asks you to authorize new contacts.
Version 0.0.1:
* First public release.
* First public release.

10
README
View File

@@ -30,7 +30,7 @@ QJson (Qt JSON library)
$ ./configure && make
$ sudo make install
libEchonest 1.1.1
libEchonest 1.1.4
---------------
See: http://projects.kde.org/projects/playground/libs/libechonest/
@@ -95,7 +95,7 @@ Dependencies
libogg 1.1.4 http://xiph.org/ogg/
libflac++ 1.2.0 http://flac.sourceforge.net/
liblastfm 0.3.3 http://github.com/mxcl/liblastfm/
libechonest 1.1.1 http://projects.kde.org/projects/playground/libs/libechonest/
libechonest 1.1.4 http://projects.kde.org/projects/playground/libs/libechonest/
Third party libraries that we ship with our source:
@@ -106,11 +106,7 @@ Dependencies
To build the app:
-----------------
$ mkdir build && cd build
Pick one of the following two choices. If uncertain pick the second one, you probably want a GUI.
$ cmake -Dgui=no .. # enables headless mode, build without GUI
$ cmake .. # normal build including GUI
$ cmake ..
$ make
To run the app:

View File

@@ -13,9 +13,9 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleVersion</key>
<string>0.0.1.0</string>
<string>0.0.2.0</string>
<key>CFBundleShortVersionString</key>
<string>0.0.1</string>
<string>0.0.2</string>
<key>CFBundleSignature</key>
<string>tomahawk</string>
<key>CFBundleIconFile</key>

View File

@@ -2,16 +2,24 @@
<rss version="2.0" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<title>Tomahawk Player Changelog</title>
<link>http://download.tomahawk-player.org/sparkle</link>
<description>Most recent changes with links to updates.</description>
<link>http://www.gettomahawk.com</link>
<description>Tomahawk Player Beta</description>
<language>en</language>
<item>
<title>Version 0.0.1 (Tomahawk Player - It Lives!)</title>
<title>Version 0.0.1 (Tomahawk Player Beta - It Lives?)</title>
<sparkle:releaseNotesLink>
https://github.com/tomahawk-player/tomahawk/raw/master/ChangeLog
https://github.com/tomahawk-player/tomahawk/raw/0.0.1/ChangeLog
</sparkle:releaseNotesLink>
<pubDate>Fri, 04 Mar 2011 16:05:15 -0500</pubDate>
<enclosure url="http://download.tomahawk-player.org/sparkle-debug/updates/tomahawk-beta-0.0.1.tar.bz2" sparkle:version="0.0.1" length="10627176" type="application/octet-stream" sparkle:dsaSignature="MC0CFAyYNZq58X7hPC7Qn+DtotVgym7pAhUA5hkLGllYxjOwwCf7i2LxUsvGyps=" />
<pubDate>Fri, 25 Mar 2011 00:00:01 +0100</pubDate>
<enclosure url="http://download.tomahawk-player.org/sparkle-debug/updates/tomahawk-0.0.1.tar.bz2" sparkle:version="0.0.1" length="10627176" type="application/octet-stream" sparkle:dsaSignature="MC0CFAyYNZq58X7hPC7Qn+DtotVgym7pAhUA5hkLGllYxjOwwCf7i2LxUsvGyps=" />
</item>
<item>
<title>Version 0.0.2 (Tomahawk Player Beta - It Lives?)</title>
<sparkle:releaseNotesLink>
https://github.com/tomahawk-player/tomahawk/raw/stable/ChangeLog
</sparkle:releaseNotesLink>
<pubDate>Mon, 28 Mar 2011 06:13:01 +0100</pubDate>
<enclosure url="http://download.tomahawk-player.org/sparkle/updates/tomahawk-0.0.2.tar.bz2" sparkle:version="0.0.2" length="19835237" type="application/octet-stream" sparkle:dsaSignature="MCwCFGb6yhKUO3+lH3eNaURvwtctLVMUAhQM8mp8yEwcU3ZoaJMTqb387dYccA==" />
</item>
</channel>
</rss>

View File

@@ -2,16 +2,24 @@
<rss version="2.0" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<title>Tomahawk Player Changelog</title>
<link>http://download.tomahawk-player.org/sparkle</link>
<description>Most recent changes with links to updates.</description>
<link>http://www.gettomahawk.com</link>
<description>Tomahawk Player</description>
<language>en</language>
<item>
<title>Version 0.0.1 (Tomahawk Player - It Lives!)</title>
<sparkle:releaseNotesLink>
https://github.com/tomahawk-player/tomahawk/raw/master/ChangeLog
https://github.com/tomahawk-player/tomahawk/raw/0.0.1/ChangeLog
</sparkle:releaseNotesLink>
<pubDate>Fri, 04 Mar 2011 16:05:15 -0500</pubDate>
<pubDate>Fri, 25 Mar 2011 00:00:01 +0100</pubDate>
<enclosure url="http://download.tomahawk-player.org/sparkle/updates/tomahawk-0.0.1.tar.bz2" sparkle:version="0.0.1" length="10627176" type="application/octet-stream" sparkle:dsaSignature="MC0CFAyYNZq58X7hPC7Qn+DtotVgym7pAhUA5hkLGllYxjOwwCf7i2LxUsvGyps=" />
</item>
<item>
<title>Version 0.0.2 (Tomahawk Player - It Lives!)</title>
<sparkle:releaseNotesLink>
https://github.com/tomahawk-player/tomahawk/raw/stable/ChangeLog
</sparkle:releaseNotesLink>
<pubDate>Mon, 28 Mar 2011 06:13:01 +0100</pubDate>
<enclosure url="http://download.tomahawk-player.org/sparkle/updates/tomahawk-0.0.2.tar.bz2" sparkle:version="0.0.2" length="19835237" type="application/octet-stream" sparkle:dsaSignature="MCwCFGb6yhKUO3+lH3eNaURvwtctLVMUAhQM8mp8yEwcU3ZoaJMTqb387dYccA==" />
</item>
</channel>
</rss>

View File

@@ -1 +1 @@
TO DO
See http://github.com/tomahawk-player/tomahawk/blob/stable/ChangeLog

View File

@@ -1 +1 @@
94
96

View File

@@ -35,7 +35,7 @@
!define VER_MAJOR "0"
!define VER_MINOR "0"
!define VER_BUILD "1"
!define VER_BUILD "2"
!define VERSION "${VER_MAJOR}.${VER_MINOR}.${VER_BUILD}"

View File

@@ -3,15 +3,15 @@
<channel>
<title>Tomahawk Player</title>
<link>http://www.gettomahawk.com</link>
<description>Tomahawk Player</description>
<description>Tomahawk Player Beta</description>
<language>en</language>
<item>
<title>Version 0.0.1 (Tomahawk Player - It Lives!)</title>
<title>Version 0.0.1 (Tomahawk Player Beta - It Lives?)</title>
<sparkle:releaseNotesLink>
https://github.com/tomahawk-player/tomahawk/blob/master/ChangeLog
https://github.com/tomahawk-player/tomahawk/raw/stable/ChangeLog
</sparkle:releaseNotesLink>
<pubDate>Fri, 04 Mar 2011 16:05:15 -0500</pubDate>
<enclosure url="http://download.tomahawk-player.org/sparklewin/updates/tomahawk-beta-0.0.1.exe" sparkle:version="0.0.1" />
<pubDate>Fri, 25 Mar 2011 00:00:01 +0100</pubDate>
<enclosure url="http://download.tomahawk-player.org/tomahawk-beta-0.0.1.exe" sparkle:version="0.0.1" />
</item>
</channel>
</rss>

View File

@@ -8,10 +8,10 @@
<item>
<title>Version 0.0.1 (Tomahawk Player - It Lives!)</title>
<sparkle:releaseNotesLink>
https://github.com/tomahawk-player/tomahawk/blob/master/ChangeLog
https://github.com/tomahawk-player/tomahawk/raw/0.0.1/ChangeLog
</sparkle:releaseNotesLink>
<pubDate>Fri, 04 Mar 2011 16:05:15 -0500</pubDate>
<enclosure url="http://download.tomahawk-player.org/sparklewin/updates/tomahawk-0.0.1.exe" sparkle:version="0.0.1" />
<pubDate>Fri, 25 Mar 2011 00:00:01 +0100</pubDate>
<enclosure url="http://download.tomahawk-player.org/tomahawk-0.0.1.exe" sparkle:version="0.0.1" />
</item>
</channel>
</rss>

View File

@@ -23,6 +23,7 @@
#include "dynamic/GeneratorInterface.h"
#include "dynamic/DynamicControl.h"
#include "utils/tomahawkutils.h"
#include "utils/elidedlabel.h"
#include <QLabel>
#include <QStackedLayout>
@@ -85,7 +86,7 @@ CollapsibleControls::init()
m_summaryLayout->setMargin( 0 );
m_summaryWidget->setContentsMargins( 3, 0, 0, 0 );
m_summary = new QLabel( m_summaryWidget );
m_summary = new ElidedLabel( m_summaryWidget );
QFont f = m_summary->font();
f.setPointSize( f.pointSize() + 1 );
f.setBold( true );

View File

@@ -27,7 +27,7 @@ class QPaintEvent;
class QHBoxLayout;
class QTimeLine;
class QToolButton;
class QLabel;
class ElidedLabel;
class QStackedLayout;
namespace Tomahawk
{
@@ -67,7 +67,7 @@ private:
QWidget* m_summaryWidget;
QHBoxLayout* m_summaryLayout;
QLabel* m_summary;
ElidedLabel* m_summary;
QStackedLayout* m_expandL;
QToolButton* m_summaryExpand;

View File

@@ -43,7 +43,7 @@ InfoBar::InfoBar( QWidget* parent )
boldFont.setPixelSize( 12 );
ui->descriptionLabel->setFont( boldFont );
ui->descriptionLabel->setMargin( 2 );
ui->descriptionLabel->setMargin( 10 );
QPalette whitePal = ui->captionLabel->palette();
whitePal.setColor( QPalette::Foreground, Qt::white );
@@ -52,6 +52,8 @@ InfoBar::InfoBar( QWidget* parent )
ui->descriptionLabel->setPalette( whitePal );
ui->captionLabel->setText( QString() );
ui->captionLabel->setMargin( 6 );
ui->descriptionLabel->setText( QString() );
ui->imageLabel->setText( QString() );

View File

@@ -74,7 +74,7 @@
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="captionLabel">
<widget class="ElidedLabel" name="captionLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
@@ -87,7 +87,7 @@
</widget>
</item>
<item>
<widget class="QLabel" name="descriptionLabel">
<widget class="ElidedLabel" name="descriptionLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
@@ -119,6 +119,13 @@
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>ElidedLabel</class>
<extends>QLabel</extends>
<header>utils/elidedlabel.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@@ -44,6 +44,7 @@ public:
public slots:
virtual bool connectPlugin( bool startup = false ) = 0;
virtual void disconnectPlugin() = 0;
virtual void checkSettings() = 0;
virtual void addContact( const QString &jid, const QString& msg = QString() ) = 0;
virtual void sendMsg( const QString& to, const QString& msg ) = 0;

View File

@@ -89,6 +89,17 @@ TomahawkSettings::hasScannerPath() const
return contains( "scannerpath" );
}
void
TomahawkSettings::setAcceptedLegalWarning( bool accept )
{
setValue( "acceptedLegalWarning", accept );
}
bool
TomahawkSettings::acceptedLegalWarning() const
{
return value( "acceptedLegalWarning", false ).toBool();
}
bool
TomahawkSettings::httpEnabled() const

View File

@@ -45,6 +45,9 @@ public:
void setScannerPath( const QString& path );
bool hasScannerPath() const;
bool acceptedLegalWarning() const;
void setAcceptedLegalWarning( bool accept );
/// UI settings
QByteArray mainWindowGeometry() const;
void setMainWindowGeometry( const QByteArray& geom );

View File

@@ -22,6 +22,7 @@
#include <QPainter>
#include <QFontMetrics>
#include <QApplication>
#include <QRect>
ElidedLabel::ElidedLabel( QWidget* parent, Qt::WindowFlags flags )
@@ -65,16 +66,16 @@ ElidedLabel::setText( const QString& text )
Qt::Alignment
ElidedLabel::alignment() const
{
return align;
return m_align;
}
void
ElidedLabel::setAlignment( Qt::Alignment alignment )
{
if ( this->align != alignment )
if ( m_align != alignment )
{
this->align = alignment;
m_align = alignment;
update(); // no geometry change, repaint is sufficient
}
}
@@ -83,27 +84,40 @@ ElidedLabel::setAlignment( Qt::Alignment alignment )
Qt::TextElideMode
ElidedLabel::elideMode() const
{
return mode;
return m_mode;
}
void
ElidedLabel::setElideMode( Qt::TextElideMode mode )
{
if ( this->mode != mode )
if ( m_mode != mode )
{
this->mode = mode;
m_mode = mode;
updateLabel();
}
}
void
ElidedLabel::setMargin( int margin )
{
m_margin = margin;
}
int
ElidedLabel::margin() const
{
return m_margin;
}
void
ElidedLabel::init( const QString& txt )
{
m_text = txt;
align = Qt::AlignLeft;
mode = Qt::ElideMiddle;
m_align = Qt::AlignLeft;
m_mode = Qt::ElideMiddle;
m_margin = 0;
setContentsMargins( 0, 0, 0, 0 );
}
@@ -128,7 +142,7 @@ ElidedLabel::sizeHint() const
QSize
ElidedLabel::minimumSizeHint() const
{
switch ( mode )
switch ( m_mode )
{
case Qt::ElideNone:
return sizeHint();
@@ -149,8 +163,10 @@ ElidedLabel::paintEvent( QPaintEvent* event )
QFrame::paintEvent( event );
QPainter p( this );
QRect r = contentsRect();
const QString elidedText = fontMetrics().elidedText( m_text, mode, r.width() );
p.drawText( r, align, elidedText );
r.adjust( m_margin, m_margin, -m_margin, -m_margin );
const QString elidedText = fontMetrics().elidedText( m_text, m_mode, r.width() );
p.drawText( r, m_align, elidedText );
}
@@ -176,7 +192,7 @@ void
ElidedLabel::mousePressEvent( QMouseEvent* event )
{
QFrame::mousePressEvent( event );
time.start();
m_time.start();
}
@@ -184,6 +200,6 @@ void
ElidedLabel::mouseReleaseEvent( QMouseEvent* event )
{
QFrame::mouseReleaseEvent( event );
if ( time.elapsed() < qApp->doubleClickInterval() )
if ( m_time.elapsed() < qApp->doubleClickInterval() )
emit clicked();
}

View File

@@ -44,6 +44,9 @@ public:
Qt::TextElideMode elideMode() const;
void setElideMode( Qt::TextElideMode mode );
void setMargin( int margin );
int margin() const;
virtual QSize sizeHint() const;
virtual QSize minimumSizeHint() const;
@@ -64,10 +67,11 @@ protected:
virtual void paintEvent( QPaintEvent* event );
private:
QTime time;
QTime m_time;
QString m_text;
Qt::Alignment align;
Qt::TextElideMode mode;
Qt::Alignment m_align;
Qt::TextElideMode m_mode;
int m_margin;
};
#endif // ELIDEDLABEL_H

View File

@@ -44,6 +44,9 @@ ScanManager::ScanManager( QObject* parent )
s_instance = this;
connect( TomahawkSettings::instance(), SIGNAL( changed() ), SLOT( onSettingsChanged() ) );
if ( TomahawkSettings::instance()->hasScannerPath() )
m_currScannerPath = TomahawkSettings::instance()->scannerPath();
}
@@ -76,8 +79,12 @@ ScanManager::~ScanManager()
void
ScanManager::onSettingsChanged()
{
if ( TomahawkSettings::instance()->hasScannerPath() )
runManualScan( TomahawkSettings::instance()->scannerPath() );
if ( TomahawkSettings::instance()->hasScannerPath() &&
m_currScannerPath != TomahawkSettings::instance()->scannerPath() )
{
m_currScannerPath = TomahawkSettings::instance()->scannerPath();
runManualScan( m_currScannerPath );
}
}

View File

@@ -53,6 +53,7 @@ private:
MusicScanner* m_scanner;
QThread* m_musicScannerThreadController;
QString m_currScannerPath;
};
#endif

View File

@@ -28,6 +28,7 @@
#include "network/controlconnection.h"
#include "sourcelist.h"
#include "tomahawksettings.h"
#include "tomahawk/tomahawkapp.h"
#include "config.h"
@@ -58,8 +59,7 @@ SipHandler::plugins() const
void
SipHandler::onSettingsChanged()
{
disconnectPlugins();
connectPlugins();
checkSettings();
}
@@ -165,9 +165,33 @@ SipHandler::pluginLoaded( const QString& name ) const
}
void
SipHandler::checkSettings()
{
foreach( SipPlugin* sip, m_plugins )
{
sip->checkSettings();
}
}
void
SipHandler::connectPlugins( bool startup, const QString &pluginName )
{
#ifndef TOMAHAWK_HEADLESS
if ( !TomahawkSettings::instance()->acceptedLegalWarning() )
{
int result = QMessageBox::question(
TomahawkApp::instance()->mainWindow(), "Legal Warning",
"By pressing OK below, you agree that your use of Tomahawk will be in accordance with any applicable laws, including copyright and intellectual property laws, in effect in your country of residence, and indemify the Tomahawk developers and project from liability should you choose to break those laws.\n\nFor more information, please see http://gettomahawk.com/legal",
"I Do Not Agree", "I Agree"
);
if ( result != 1 )
return;
else
TomahawkSettings::instance()->setAcceptedLegalWarning( true );
}
#endif
foreach( SipPlugin* sip, m_plugins )
{
if ( pluginName.isEmpty() || ( !pluginName.isEmpty() && sip->name() == pluginName ) )

View File

@@ -39,6 +39,7 @@ public:
public slots:
void addContact( const QString& id ) { qDebug() << Q_FUNC_INFO << id; }
void checkSettings();
void connectPlugins( bool startup = false, const QString &pluginName = QString() );
void disconnectPlugins( const QString &pluginName = QString() );
void toggleConnect();

View File

@@ -76,12 +76,13 @@ JabberPlugin::connectPlugin( bool startup )
if ( startup && !TomahawkSettings::instance()->jabberAutoConnect() )
return false;
QString jid = TomahawkSettings::instance()->jabberUsername();
QString server = TomahawkSettings::instance()->jabberServer();
QString password = TomahawkSettings::instance()->jabberPassword();
unsigned int port = TomahawkSettings::instance()->jabberPort();
m_currentUsername = TomahawkSettings::instance()->jabberUsername();
m_currentServer = TomahawkSettings::instance()->jabberServer();
m_currentPassword = TomahawkSettings::instance()->jabberPassword();
m_currentPort = TomahawkSettings::instance()->jabberPort();
QString server = m_currentServer;
QStringList splitJid = jid.split( '@', QString::SkipEmptyParts );
QStringList splitJid = m_currentUsername.split( '@', QString::SkipEmptyParts );
if ( splitJid.size() < 2 )
{
qDebug() << "JID did not have an @ in it, could not find a server part";
@@ -91,14 +92,14 @@ JabberPlugin::connectPlugin( bool startup )
if ( server.isEmpty() )
server = splitJid[1];
if ( port < 1 || port > 65535 || jid.isEmpty() || password.isEmpty() )
if ( m_currentPort < 1 || m_currentPort > 65535 || m_currentUsername.isEmpty() || m_currentPassword.isEmpty() )
{
qDebug() << "Jabber credentials look wrong, not connecting";
return false;
}
delete p;
p = new Jabber_p( jid, password, server, port );
p = new Jabber_p( m_currentUsername, m_currentPassword, server, m_currentPort );
QObject::connect( p, SIGNAL( peerOnline( QString ) ), SIGNAL( peerOnline( QString ) ) );
QObject::connect( p, SIGNAL( peerOffline( QString ) ), SIGNAL( peerOffline( QString ) ) );
@@ -174,4 +175,30 @@ JabberPlugin::showAddFriendDialog()
addContact( id );
}
void
JabberPlugin::checkSettings()
{
bool reconnect = false;
if ( m_currentUsername != TomahawkSettings::instance()->jabberUsername() )
reconnect = true;
if ( m_currentPassword != TomahawkSettings::instance()->jabberPassword() )
reconnect = true;
if ( m_currentServer != TomahawkSettings::instance()->jabberServer() )
reconnect = true;
if ( m_currentPort != TomahawkSettings::instance()->jabberPort() )
reconnect = true;
m_currentUsername = TomahawkSettings::instance()->jabberUsername();
m_currentPassword = TomahawkSettings::instance()->jabberPassword();
m_currentServer = TomahawkSettings::instance()->jabberServer();
m_currentPort = TomahawkSettings::instance()->jabberPort();
if ( reconnect && ( p || TomahawkSettings::instance()->jabberAutoConnect() ) )
{
disconnectPlugin();
connectPlugin( false );
}
}
Q_EXPORT_PLUGIN2( sip, JabberPlugin )

View File

@@ -59,6 +59,8 @@ public slots:
p = 0;
}
void checkSettings();
void sendMsg( const QString& to, const QString& msg )
{
if ( p )
@@ -87,6 +89,11 @@ private:
Jabber_p* p;
QMenu* m_menu;
QAction* m_addFriendAction;
QString m_currentUsername;
QString m_currentPassword;
QString m_currentServer;
unsigned int m_currentPort;
};
#endif

View File

@@ -24,8 +24,11 @@
#include <QString>
#include <QRegExp>
#include <QThread>
#include <QVariant>
#include <utils/tomahawkutils.h>
#include <gloox/capabilities.h>
#include <QMessageBox>
#include <qjson/parser.h>
using namespace gloox;
using namespace std;
@@ -148,6 +151,7 @@ Jabber_p::go()
m_client->registerPresenceHandler( this );
m_client->registerConnectionListener( this );
m_client->rosterManager()->registerRosterListener( this, false ); // false means async
m_client->logInstance().registerLogHandler( LogLevelWarning, LogAreaAll, this );
m_client->registerMessageHandler( this );
@@ -428,6 +432,15 @@ Jabber_p::handleMessage( const Message& m, MessageSession * /*session*/ )
//sendMsg( from, QString("You said %1").arg(msg) );
QJson::Parser parser;
bool ok;
QVariant v = parser.parse( msg.toAscii(), &ok );
if ( !ok || v.type() != QVariant::Map )
{
sendMsg( from, QString( "I'm sorry -- I'm just an automatic presence used by Tomahawk Player (http://gettomahawk.com). If you are getting this message, the person you are trying to reach is probably not signed on, so please try again later!" ) );
return;
}
emit msgReceived( from, msg );
}
@@ -598,10 +611,86 @@ bool
Jabber_p::handleSubscriptionRequest( const JID& jid, const std::string& /*msg*/ )
{
qDebug() << Q_FUNC_INFO << jid.bare().c_str();
StringList groups;
groups.push_back( "Tomahawk" );
m_client->rosterManager()->subscribe( jid, "", groups, "" );
return true;
// check if the requester is already on the roster
RosterItem *item = m_client->rosterManager()->getRosterItem(jid);
if(item) qDebug() << Q_FUNC_INFO << jid.bare().c_str() << "subscription status:" << static_cast<int>( item->subscription() );
if(item &&
(
item->subscription() == gloox::S10nNoneOut || // Contact and user are not subscribed to each other, and user has sent contact a subscription request but contact has not replied yet.
item->subscription() == gloox::S10nTo || // User is subscribed to contact (one-way).
item->subscription() == gloox::S10nToIn // User is subscribed to contact, and contact has sent user a subscription request but user has not replied yet.
)
)
{
qDebug() << Q_FUNC_INFO << jid.bare().c_str() << "already on the roster so we assume ack'ing subscription request is okay...";
// ack the request
m_client->rosterManager()->ackSubscriptionRequest( jid, true );
// return anything, the result is ignored
return false;
}
// we don't have to check for an already open check box because gloox doesnt call this method until a former request was ack'ed
qDebug() << Q_FUNC_INFO << jid.bare().c_str() << "open subscription request box";
// preparing the confirm box for the user
QMessageBox *confirmBox = new QMessageBox(
QMessageBox::Question,
tr( "Authorize User" ),
QString( tr( "Do you want to grant <b>%1</b> access to your Collection?" ) ).arg( QLatin1String( jid.bare().c_str() ) ),
QMessageBox::Yes | QMessageBox::No,
0
);
// add confirmBox to m_subscriptionConfirmBoxes
m_subscriptionConfirmBoxes.insert( jid, confirmBox );
// display the box and wait for the answer
confirmBox->open( this, SLOT( onSubscriptionRequestConfirmed( int ) ) );
return false;
}
void
Jabber_p::onSubscriptionRequestConfirmed( int result )
{
qDebug() << Q_FUNC_INFO << result;
QList< QMessageBox* > confirmBoxes = m_subscriptionConfirmBoxes.values();
JID jid;
foreach( QMessageBox* currentBox, confirmBoxes )
{
if( currentBox == sender() )
{
jid = m_subscriptionConfirmBoxes.key( currentBox );
}
}
qDebug() << Q_FUNC_INFO << "box confirmed for" << jid.bare().c_str();
// we got an answer, deleting the box
m_subscriptionConfirmBoxes.remove( jid );
sender()->deleteLater();
QMessageBox::StandardButton allowSubscription = static_cast<QMessageBox::StandardButton>( result );
if ( allowSubscription == QMessageBox::Yes )
{
qDebug() << Q_FUNC_INFO << jid.bare().c_str() << "accepted by user, adding to roster";
StringList groups;
groups.push_back( "Tomahawk" );
m_client->rosterManager()->subscribe( jid, "", groups, "" );
}
else
{
qDebug() << Q_FUNC_INFO << jid.bare().c_str() << "declined by user";
}
m_client->rosterManager()->ackSubscriptionRequest( jid, allowSubscription == QMessageBox::Yes );
}

View File

@@ -30,6 +30,7 @@
#include <QSocketNotifier>
#include <QMap>
#include <QNetworkProxy>
#include <QMessageBox>
#include <string>
@@ -76,6 +77,7 @@ class SIPDLLEXPORT Jabber_p :
public gloox::MessageHandler,
public gloox::VCardHandler,
public gloox::PresenceHandler,
public gloox::RosterListener,
gloox::LogHandler
//public gloox::DiscoHandler,
{
@@ -109,6 +111,11 @@ public:
virtual void handleRoster( const gloox::Roster& roster );
virtual void handleRosterError( const gloox::IQ& /*iq*/ );
// not actually used, just needed for the interface to support subscription requests, see handlePresence for presence handling
virtual void handleRosterPresence( const gloox::RosterItem&, const std::string&, gloox::Presence::PresenceType, const std::string& ) {}
virtual void handleSelfPresence( const gloox::RosterItem&, const std::string&, gloox::Presence::PresenceType, const std::string& ) {}
virtual void handlePresence( const gloox::Presence& presence );
virtual bool handleSubscription( const gloox::JID& jid, const std::string& /*msg*/ );
virtual bool handleSubscriptionRequest( const gloox::JID& jid, const std::string& /*msg*/ );
@@ -147,6 +154,7 @@ public slots:
private slots:
void doJabberRecv();
void onSubscriptionRequestConfirmed( int result );
private:
bool presenceMeansOnline( gloox::Presence::PresenceType p );
@@ -158,6 +166,7 @@ private:
QSharedPointer<gloox::VCardManager> m_vcardManager;
QString m_server;
QScopedPointer<QSocketNotifier> m_notifier;
QHash<gloox::JID, QMessageBox*> m_subscriptionConfirmBoxes;
};
#endif // JABBER_H

View File

@@ -33,6 +33,7 @@
#include <database/database.h>
#include <network/servent.h>
static QString s_gotTomahawkRegex = QString( "^(@[a-zA-Z0-9]+ )?(Got Tomahawk\\?) (\\{[a-fA-F0-9\\-]+\\}) (.*)$" );
TwitterPlugin::TwitterPlugin()
: SipPlugin()
@@ -130,16 +131,30 @@ TwitterPlugin::connectPlugin( bool /*startup*/ )
return m_cachedPeers.isEmpty();
}
delete m_twitterAuth.data();
if ( refreshTwitterAuth() )
{
QTweetAccountVerifyCredentials *credVerifier = new QTweetAccountVerifyCredentials( m_twitterAuth.data(), this );
connect( credVerifier, SIGNAL( parsedUser(const QTweetUser &) ), SLOT( connectAuthVerifyReply(const QTweetUser &) ) );
credVerifier->verify();
}
return true;
}
bool
TwitterPlugin::refreshTwitterAuth()
{
m_twitterAuth = QWeakPointer<TomahawkOAuthTwitter>( new TomahawkOAuthTwitter( this ) );
TomahawkSettings *settings = TomahawkSettings::instance();
if ( m_twitterAuth.isNull() )
return false;
m_twitterAuth.data()->setNetworkAccessManager( TomahawkUtils::nam() );
m_twitterAuth.data()->setOAuthToken( settings->twitterOAuthToken().toLatin1() );
m_twitterAuth.data()->setOAuthTokenSecret( settings->twitterOAuthTokenSecret().toLatin1() );
QTweetAccountVerifyCredentials *credVerifier = new QTweetAccountVerifyCredentials( m_twitterAuth.data(), this );
connect( credVerifier, SIGNAL( parsedUser(const QTweetUser &) ), SLOT( connectAuthVerifyReply(const QTweetUser &) ) );
credVerifier->verify();
return true;
}
@@ -153,6 +168,7 @@ TwitterPlugin::disconnectPlugin()
m_twitterAuth.data()->deleteLater();
m_cachedPeers.empty();
m_attemptedConnects.empty();
delete m_twitterAuth.data();
m_isOnline = false;
}
@@ -189,8 +205,17 @@ TwitterPlugin::connectAuthVerifyReply( const QTweetUser &user )
}
else
{
qDebug() << "TwitterPlugin auth pointer was null!";
m_isAuthed = false;
if ( refreshTwitterAuth() )
{
QTweetAccountVerifyCredentials *credVerifier = new QTweetAccountVerifyCredentials( m_twitterAuth.data(), this );
connect( credVerifier, SIGNAL( parsedUser(const QTweetUser &) ), SLOT( connectAuthVerifyReply(const QTweetUser &) ) );
credVerifier->verify();
}
else
{
qDebug() << "TwitterPlugin auth pointer was null!";
m_isAuthed = false;
}
}
}
}
@@ -201,6 +226,21 @@ TwitterPlugin::checkTimerFired()
if ( !isValid() )
return;
if ( m_twitterAuth.isNull() )
{
if ( refreshTwitterAuth() )
{
QTweetAccountVerifyCredentials *credVerifier = new QTweetAccountVerifyCredentials( m_twitterAuth.data(), this );
connect( credVerifier, SIGNAL( parsedUser(const QTweetUser &) ), SLOT( connectAuthVerifyReply(const QTweetUser &) ) );
credVerifier->verify();
}
else
{
qDebug() << "TwitterPlugin auth went null somehow and could not refresh";
return;
}
}
if ( m_cachedFriendsSinceId == 0 )
m_cachedFriendsSinceId = TomahawkSettings::instance()->twitterCachedFriendsSinceId();
@@ -224,6 +264,21 @@ TwitterPlugin::connectTimerFired()
{
if ( !isValid() || m_cachedPeers.isEmpty() )
return;
if ( m_twitterAuth.isNull() )
{
if ( refreshTwitterAuth() )
{
QTweetAccountVerifyCredentials *credVerifier = new QTweetAccountVerifyCredentials( m_twitterAuth.data(), this );
connect( credVerifier, SIGNAL( parsedUser(const QTweetUser &) ), SLOT( connectAuthVerifyReply(const QTweetUser &) ) );
credVerifier->verify();
}
else
{
qDebug() << "TwitterPlugin auth went null somehow and could not refresh";
return;
}
}
QString myScreenName = TomahawkSettings::instance()->twitterScreenName();
QList<QString> peerlist = m_cachedPeers.keys();
@@ -242,16 +297,65 @@ TwitterPlugin::connectTimerFired()
}
}
void
TwitterPlugin::parseGotTomahawk( const QRegExp &regex, const QString &screenName, const QString &text )
{
QString myScreenName = TomahawkSettings::instance()->twitterScreenName();
qDebug() << "TwitterPlugin found an exact matching Got Tomahawk? mention or direct message from user " << screenName;
if ( text.startsWith( '@' ) && regex.captureCount() >= 2 && regex.cap( 1 ) != QString( '@' + myScreenName ) )
{
qDebug() << "TwitterPlugin skipping mention because it's directed @someone that isn't us";
return;
}
QString node;
for ( int i = 0; i < regex.captureCount(); ++i )
{
if ( regex.cap( i ) == QString( "Got Tomahawk?" ) )
{
QString nodeCap = regex.cap( i + 1 );
nodeCap.chop( 1 );
node = nodeCap.mid( 1 );
}
}
if ( node.isEmpty() )
{
qDebug() << "TwitterPlugin could not parse node out of the tweet";
return;
}
else
qDebug() << "TwitterPlugin parsed node " << node << " out of the tweet";
if ( screenName == myScreenName && node == Database::instance()->dbid() )
{
qDebug() << "My screen name and my dbid found; ignoring";
return;
}
QHash< QString, QVariant > peerData;
if( m_cachedPeers.contains( screenName ) )
{
peerData = m_cachedPeers[screenName].toHash();
//force a re-send of info but no need to re-register
peerData["resend"] = QVariant::fromValue< bool >( true );
}
peerData["node"] = QVariant::fromValue< QString >( node );
QMetaObject::invokeMethod( this, "registerOffer", Q_ARG( QString, screenName ), QGenericArgument( "QHash< QString, QVariant >", (const void*)&peerData ) );
}
void
TwitterPlugin::friendsTimelineStatuses( const QList< QTweetStatus > &statuses )
{
qDebug() << Q_FUNC_INFO;
QRegExp regex( QString( "^(@[a-zA-Z0-9]+ )?(Got Tomahawk\\?) (\\{[a-fA-F0-9\\-]+\\}) (.*)$" ), Qt::CaseSensitive, QRegExp::RegExp2 );
QRegExp regex( s_gotTomahawkRegex, Qt::CaseSensitive, QRegExp::RegExp2 );
QString myScreenName = TomahawkSettings::instance()->twitterScreenName();
QHash< QString, QTweetStatus > latestHash;
foreach ( QTweetStatus status, statuses )
{
if ( !regex.exactMatch( status.text() ) )
continue;
if ( !latestHash.contains( status.user().screenName() ) )
latestHash[status.user().screenName()] = status;
else
@@ -266,49 +370,7 @@ TwitterPlugin::friendsTimelineStatuses( const QList< QTweetStatus > &statuses )
if ( status.id() > m_cachedFriendsSinceId )
m_cachedFriendsSinceId = status.id();
if ( regex.exactMatch( status.text() ) )
{
qDebug() << "TwitterPlugin found an exact tweet from friend " << status.user().screenName();
if ( status.text().startsWith( '@' ) && regex.captureCount() >= 2 && regex.cap( 1 ) != QString( '@' + myScreenName ) )
{
qDebug() << "TwitterPlugin skipping tweet because it's directed @someone that isn't us";
continue;
}
QString node;
for ( int i = 0; i < regex.captureCount(); ++i )
{
if ( regex.cap( i ) == QString( "Got Tomahawk?" ) )
{
QString nodeCap = regex.cap( i + 1 );
nodeCap.chop( 1 );
node = nodeCap.mid( 1 );
}
}
if ( node.isEmpty() )
{
qDebug() << "TwitterPlugin could not parse node out of the tweet";
continue;
}
else
qDebug() << "TwitterPlugin parsed node " << node << " out of the tweet";
if ( status.user().screenName() == myScreenName && node == Database::instance()->dbid() )
{
qDebug() << "My screen name and my dbid found; ignoring";
continue;
}
QHash< QString, QVariant > peerData;
if( m_cachedPeers.contains( status.user().screenName() ) )
{
peerData = m_cachedPeers[status.user().screenName()].toHash();
//force a re-send of info but no need to re-register
peerData["resend"] = QVariant::fromValue< bool >( true );
}
peerData["node"] = QVariant::fromValue< QString >( node );
QMetaObject::invokeMethod( this, "registerOffer", Q_ARG( QString, status.user().screenName() ), QGenericArgument( "QHash< QString, QVariant >", (const void*)&peerData ) );
}
parseGotTomahawk( regex, status.user().screenName(), status.text() );
}
TomahawkSettings::instance()->setTwitterCachedFriendsSinceId( m_cachedFriendsSinceId );
@@ -321,12 +383,14 @@ void
TwitterPlugin::mentionsStatuses( const QList< QTweetStatus > &statuses )
{
qDebug() << Q_FUNC_INFO;
QRegExp regex( QString( "^(@[a-zA-Z0-9]+ )?(Got Tomahawk\\?) (\\{[a-fA-F0-9\\-]+\\}) (.*)$" ), Qt::CaseSensitive, QRegExp::RegExp2 );
QString myScreenName = TomahawkSettings::instance()->twitterScreenName();
QRegExp regex( s_gotTomahawkRegex, Qt::CaseSensitive, QRegExp::RegExp2 );
QHash< QString, QTweetStatus > latestHash;
foreach ( QTweetStatus status, statuses )
{
if ( !regex.exactMatch( status.text() ) )
continue;
if ( !latestHash.contains( status.user().screenName() ) )
latestHash[status.user().screenName()] = status;
else
@@ -340,50 +404,8 @@ TwitterPlugin::mentionsStatuses( const QList< QTweetStatus > &statuses )
{
if ( status.id() > m_cachedMentionsSinceId )
m_cachedMentionsSinceId = status.id();
if ( regex.exactMatch( status.text() ) )
{
qDebug() << "TwitterPlugin found an exact matching mention from user " << status.user().screenName();
if ( status.text().startsWith( '@' ) && regex.captureCount() >= 2 && regex.cap( 1 ) != QString( '@' + myScreenName ) )
{
qDebug() << "TwitterPlugin skipping mention because it's directed @someone that isn't us";
continue;
}
QString node;
for ( int i = 0; i < regex.captureCount(); ++i )
{
if ( regex.cap( i ) == QString( "Got Tomahawk?" ) )
{
QString nodeCap = regex.cap( i + 1 );
nodeCap.chop( 1 );
node = nodeCap.mid( 1 );
}
}
if ( node.isEmpty() )
{
qDebug() << "TwitterPlugin could not parse node out of the tweet";
continue;
}
else
qDebug() << "TwitterPlugin parsed node " << node << " out of the tweet";
if ( status.user().screenName() == myScreenName && node == Database::instance()->dbid() )
{
qDebug() << "My screen name and my dbid found; ignoring";
continue;
}
QHash< QString, QVariant > peerData;
if( m_cachedPeers.contains( status.user().screenName() ) )
{
peerData = m_cachedPeers[status.user().screenName()].toHash();
//force a re-send of info but no need to re-register
peerData["resend"] = QVariant::fromValue< bool >( true );
}
peerData["node"] = QVariant::fromValue< QString >( node );
QMetaObject::invokeMethod( this, "registerOffer", Q_ARG( QString, status.user().screenName() ), QGenericArgument( "QHash< QString, QVariant >", (const void*)&peerData ) );
}
parseGotTomahawk( regex, status.user().screenName(), status.text() );
}
TomahawkSettings::instance()->setTwitterCachedMentionsSinceId( m_cachedMentionsSinceId );
@@ -418,9 +440,26 @@ TwitterPlugin::directMessages( const QList< QTweetDMStatus > &messages )
{
qDebug() << Q_FUNC_INFO;
QRegExp regex( s_gotTomahawkRegex, Qt::CaseSensitive, QRegExp::RegExp2 );
QString myScreenName = TomahawkSettings::instance()->twitterScreenName();
QHash< QString, QTweetDMStatus > latestHash;
foreach ( QTweetDMStatus status, messages )
{
if ( !regex.exactMatch( status.text() ) )
{
QStringList splitList = status.text().split(':');
if ( splitList.length() != 5 )
continue;
if ( splitList[0] != "TOMAHAWKPEER" )
continue;
if ( !splitList[1].startsWith( "Host=" ) || !splitList[2].startsWith( "Port=" ) || !splitList[3].startsWith( "Node=" ) || !splitList[4].startsWith( "PKey=" ) )
continue;
int port = splitList[2].mid( 5 ).toInt();
if ( port == 0 )
continue;
}
if ( !latestHash.contains( status.senderScreenName() ) )
latestHash[status.senderScreenName()] = status;
else
@@ -435,50 +474,48 @@ TwitterPlugin::directMessages( const QList< QTweetDMStatus > &messages )
qDebug() << "TwitterPlugin checking direct message from " << status.senderScreenName() << " with content " << status.text();
if ( status.id() > m_cachedDirectMessagesSinceId )
m_cachedDirectMessagesSinceId = status.id();
QStringList splitList = status.text().split(':');
qDebug() << "TwitterPlugin found " << splitList.length() << " parts to the message; the parts are:";
foreach( QString part, splitList )
qDebug() << part;
if ( splitList.length() != 5 )
continue;
if ( splitList[0] != "TOMAHAWKPEER" )
continue;
if ( !splitList[1].startsWith( "Host=" ) || !splitList[2].startsWith( "Port=" ) || !splitList[3].startsWith( "Node=" ) || !splitList[4].startsWith( "PKey=" ) )
continue;
int port = splitList[2].mid( 5 ).toInt();
if ( port == 0 )
continue;
QString host = splitList[1].mid( 5 );
QString node = splitList[3].mid( 5 );
QString pkey = splitList[4].mid( 5 );
QStringList splitNode = node.split('*');
if ( splitNode.length() != 2 )
if ( regex.exactMatch( status.text() ) )
parseGotTomahawk( regex, status.sender().screenName(), status.text() );
else
{
qDebug() << "Old-style node info found, ignoring";
continue;
}
qDebug() << "TwitterPlugin found a peerstart message from " << status.senderScreenName() << " with host " << host << " and port " << port << " and pkey " << pkey << " and node " << splitNode[0] << " destined for node " << splitNode[1];
QStringList splitList = status.text().split(':');
qDebug() << "TwitterPlugin found " << splitList.length() << " parts to the message; the parts are:";
foreach( QString part, splitList )
qDebug() << part;
//validity is checked above
int port = splitList[2].mid( 5 ).toInt();
QString host = splitList[1].mid( 5 );
QString node = splitList[3].mid( 5 );
QString pkey = splitList[4].mid( 5 );
QStringList splitNode = node.split('*');
if ( splitNode.length() != 2 )
{
qDebug() << "Old-style node info found, ignoring";
continue;
}
qDebug() << "TwitterPlugin found a peerstart message from " << status.senderScreenName() << " with host " << host << " and port " << port << " and pkey " << pkey << " and node " << splitNode[0] << " destined for node " << splitNode[1];
QHash< QString, QVariant > peerData = ( m_cachedPeers.contains( status.senderScreenName() ) ) ?
m_cachedPeers[status.senderScreenName()].toHash() :
QHash< QString, QVariant >();
peerData["host"] = QVariant::fromValue< QString >( host );
peerData["port"] = QVariant::fromValue< int >( port );
peerData["pkey"] = QVariant::fromValue< QString >( pkey );
peerData["node"] = QVariant::fromValue< QString >( splitNode[0] );
peerData["dirty"] = QVariant::fromValue< bool >( true );
QHash< QString, QVariant > peerData = ( m_cachedPeers.contains( status.senderScreenName() ) ) ?
m_cachedPeers[status.senderScreenName()].toHash() :
QHash< QString, QVariant >();
peerData["host"] = QVariant::fromValue< QString >( host );
peerData["port"] = QVariant::fromValue< int >( port );
peerData["pkey"] = QVariant::fromValue< QString >( pkey );
peerData["node"] = QVariant::fromValue< QString >( splitNode[0] );
peerData["dirty"] = QVariant::fromValue< bool >( true );
QMetaObject::invokeMethod( this, "registerOffer", Q_ARG( QString, status.senderScreenName() ), QGenericArgument( "QHash< QString, QVariant >", (const void*)&peerData ) );
QMetaObject::invokeMethod( this, "registerOffer", Q_ARG( QString, status.senderScreenName() ), QGenericArgument( "QHash< QString, QVariant >", (const void*)&peerData ) );
if ( Database::instance()->dbid().startsWith( splitNode[1] ) )
{
qDebug() << "TwitterPlugin found message destined for this node; destroying it";
if ( !m_directMessageDestroy.isNull() )
m_directMessageDestroy.data()->destroyMessage( status.id() );
if ( Database::instance()->dbid().startsWith( splitNode[1] ) )
{
qDebug() << "TwitterPlugin found message destined for this node; destroying it";
if ( !m_directMessageDestroy.isNull() )
m_directMessageDestroy.data()->destroyMessage( status.id() );
}
}
}
TomahawkSettings::instance()->setTwitterCachedDirectMessagesSinceId( m_cachedDirectMessagesSinceId );
@@ -547,14 +584,16 @@ TwitterPlugin::registerOffer( const QString &screenName, const QHash< QString, Q
qDebug() << "TwitterPlugin did not send offer because external address is " << Servent::instance()->externalAddress() << " and external port is " << Servent::instance()->externalPort();
}
if ( m_isOnline && _peerData.contains( "host" ) && _peerData.contains( "port" ) && _peerData.contains( "pkey" ) )
QMetaObject::invokeMethod( this, "makeConnection", Q_ARG( QString, screenName ), QGenericArgument( "QHash< QString, QVariant >", (const void*)&_peerData ) );
if ( peersChanged )
{
m_cachedPeers[screenName] = QVariant::fromValue< QHash< QString, QVariant > >( _peerData );
TomahawkSettings::instance()->setTwitterCachedPeers( m_cachedPeers );
m_attemptedConnects[screenName] = false;
}
if ( m_isOnline && _peerData.contains( "host" ) && _peerData.contains( "port" ) && _peerData.contains( "pkey" ) )
QMetaObject::invokeMethod( this, "makeConnection", Q_ARG( QString, screenName ), QGenericArgument( "QHash< QString, QVariant >", (const void*)&_peerData ) );
}
void
@@ -575,6 +614,11 @@ void
TwitterPlugin::makeConnection( const QString &screenName, const QHash< QString, QVariant > &peerData )
{
qDebug() << Q_FUNC_INFO;
if ( m_attemptedConnects.contains( screenName ) && m_attemptedConnects[screenName] )
{
qDebug() << "Already attempted to connect to this peer with no change in their status, not trying again for now";
return;
}
if ( !peerData.contains( "host" ) || !peerData.contains( "port" ) || !peerData.contains( "pkey" ) || !peerData.contains( "node" ) )
{
qDebug() << "TwitterPlugin could not find host and/or port and/or pkey for peer " << screenName;
@@ -587,6 +631,7 @@ TwitterPlugin::makeConnection( const QString &screenName, const QHash< QString,
peerData["pkey"].toString(),
friendlyName,
peerData["node"].toString() );
m_attemptedConnects[screenName] = true;
}
void
@@ -611,4 +656,11 @@ TwitterPlugin::directMessageDestroyed( const QTweetDMStatus& message )
qDebug() << "TwitterPlugin destroyed message " << message.text();
}
void
TwitterPlugin::checkSettings()
{
disconnectPlugin();
connectPlugin( false );
}
Q_EXPORT_PLUGIN2( sip, TwitterPlugin )

View File

@@ -59,8 +59,8 @@ public:
public slots:
virtual bool connectPlugin( bool startup );
void disconnectPlugin();
void checkSettings();
void sendMsg( const QString& to, const QString& msg )
{
@@ -91,6 +91,9 @@ private slots:
void makeConnection( const QString &screenName, const QHash< QString, QVariant > &peerdata );
private:
bool refreshTwitterAuth();
void parseGotTomahawk( const QRegExp &regex, const QString &screenName, const QString &text );
QWeakPointer< TomahawkOAuthTwitter > m_twitterAuth;
QWeakPointer< QTweetFriendsTimeline > m_friendsTimeline;
QWeakPointer< QTweetMentions > m_mentions;
@@ -105,6 +108,7 @@ private:
qint64 m_cachedMentionsSinceId;
qint64 m_cachedDirectMessagesSinceId;
QHash< QString, QVariant > m_cachedPeers;
QHash< QString, bool > m_attemptedConnects;
QSet<QString> m_keyCache;
bool m_finishedFriends;
bool m_finishedMentions;

View File

@@ -26,38 +26,50 @@
#include "tomahawkoauthtwitter.h"
#include <qtweetaccountverifycredentials.h>
#include <qtweetstatusupdate.h>
#include <qtweetdirectmessagenew.h>
#include <QMessageBox>
TwitterConfigWidget::TwitterConfigWidget(SipPlugin* plugin, QWidget *parent) :
QWidget(parent),
ui(new Ui::TwitterConfigWidget),
m_plugin(plugin)
TwitterConfigWidget::TwitterConfigWidget( SipPlugin* plugin, QWidget *parent ) :
QWidget( parent ),
ui( new Ui::TwitterConfigWidget ),
m_plugin( plugin )
{
ui->setupUi(this);
connect(ui->twitterAuthenticateButton, SIGNAL(pressed()),
this, SLOT(authDeauthTwitter()));
connect(ui->twitterTweetGotTomahawkButton, SIGNAL(pressed()),
this, SLOT(startPostGotTomahawkStatus()));
ui->setupUi( this );
connect( ui->twitterAuthenticateButton, SIGNAL( pressed() ),
this, SLOT( authDeauthTwitter() ) );
connect( ui->twitterTweetGotTomahawkButton, SIGNAL( pressed() ),
this, SLOT( startPostGotTomahawkStatus() ) );
connect( ui->twitterTweetComboBox, SIGNAL( currentIndexChanged( int ) ),
this, SLOT( tweetComboBoxIndexChanged( int ) ) );
ui->twitterTweetComboBox->setCurrentIndex( 0 );
ui->twitterUserTweetLineEdit->setReadOnly( true );
ui->twitterUserTweetLineEdit->setEnabled( false );
TomahawkSettings* s = TomahawkSettings::instance();
if ( s->twitterOAuthToken().isEmpty() || s->twitterOAuthTokenSecret().isEmpty() || s->twitterScreenName().isEmpty() )
{
ui->twitterStatusLabel->setText("Status: No saved credentials");
ui->twitterAuthenticateButton->setText( "Authenticate" );
ui->twitterInstructionsInfoLabel->setVisible( false );
ui->twitterGlobalTweetLabel->setVisible( false );
ui->twitterTweetGotTomahawkButton->setVisible( false );
ui->twitterUserTweetLineEdit->setVisible( false );
ui->twitterTweetComboBox->setVisible( false );
emit twitterAuthed( false );
}
else
{
ui->twitterStatusLabel->setText("Status: Credentials saved");
ui->twitterStatusLabel->setText("Status: Credentials saved for " + s->twitterScreenName() );
ui->twitterAuthenticateButton->setText( "De-authenticate" );
ui->twitterInstructionsInfoLabel->setVisible( true );
ui->twitterGlobalTweetLabel->setVisible( true );
ui->twitterTweetGotTomahawkButton->setVisible( true );
ui->twitterUserTweetLineEdit->setVisible( true );
ui->twitterTweetComboBox->setVisible( true );
emit twitterAuthed( true );
}
@@ -112,10 +124,13 @@ TwitterConfigWidget::authenticateVerifyReply( const QTweetUser &user )
s->setTwitterCachedFriendsSinceId( 0 );
s->setTwitterCachedMentionsSinceId( 0 );
ui->twitterStatusLabel->setText("Status: Credentials saved");
ui->twitterStatusLabel->setText("Status: Credentials saved for " + s->twitterScreenName() );
ui->twitterAuthenticateButton->setText( "De-authenticate" );
ui->twitterInstructionsInfoLabel->setVisible( true );
ui->twitterGlobalTweetLabel->setVisible( true );
ui->twitterTweetGotTomahawkButton->setVisible( true );
ui->twitterUserTweetLineEdit->setVisible( true );
ui->twitterTweetComboBox->setVisible( true );
m_plugin->connectPlugin( false );
@@ -132,7 +147,6 @@ TwitterConfigWidget::authenticateVerifyError( QTweetNetBase::ErrorCode code, con
return;
}
void
TwitterConfigWidget::deauthenticateTwitter()
{
@@ -145,14 +159,45 @@ TwitterConfigWidget::deauthenticateTwitter()
ui->twitterStatusLabel->setText("Status: No saved credentials");
ui->twitterAuthenticateButton->setText( "Authenticate" );
ui->twitterInstructionsInfoLabel->setVisible( false );
ui->twitterGlobalTweetLabel->setVisible( false );
ui->twitterTweetGotTomahawkButton->setVisible( false );
ui->twitterUserTweetLineEdit->setVisible( false );
ui->twitterTweetComboBox->setVisible( false );
emit twitterAuthed( false );
}
void
TwitterConfigWidget::tweetComboBoxIndexChanged( int index )
{
if( ui->twitterTweetComboBox->currentText() == "Global Tweet" )
{
ui->twitterUserTweetLineEdit->setReadOnly( true );
ui->twitterUserTweetLineEdit->setEnabled( false );
}
else
{
ui->twitterUserTweetLineEdit->setReadOnly( false );
ui->twitterUserTweetLineEdit->setEnabled( true );
}
if( ui->twitterTweetComboBox->currentText() == "Direct Message" )
ui->twitterTweetGotTomahawkButton->setText( "Send Message!" );
else
ui->twitterTweetGotTomahawkButton->setText( "Tweet!" );
}
void
TwitterConfigWidget::startPostGotTomahawkStatus()
{
m_postGTtype = ui->twitterTweetComboBox->currentText();
if ( m_postGTtype != "Global Tweet" && ( ui->twitterUserTweetLineEdit->text().isEmpty() || ui->twitterUserTweetLineEdit->text() == "@" ) )
{
QMessageBox::critical( 0, QString("Tweetin' Error"), QString("You must enter a user name for this type of tweet.") );
return;
}
qDebug() << "Posting Got Tomahawk status";
TomahawkSettings* s = TomahawkSettings::instance();
if ( s->twitterOAuthToken().isEmpty() || s->twitterOAuthTokenSecret().isEmpty() || s->twitterScreenName().isEmpty() )
@@ -170,7 +215,6 @@ TwitterConfigWidget::startPostGotTomahawkStatus()
credVerifier->verify();
}
void
TwitterConfigWidget::postGotTomahawkStatusAuthVerifyReply( const QTweetUser &user )
{
@@ -186,14 +230,36 @@ TwitterConfigWidget::postGotTomahawkStatusAuthVerifyReply( const QTweetUser &use
twitAuth->setNetworkAccessManager( TomahawkUtils::nam() );
twitAuth->setOAuthToken( s->twitterOAuthToken().toLatin1() );
twitAuth->setOAuthTokenSecret( s->twitterOAuthTokenSecret().toLatin1() );
QTweetStatusUpdate *statUpdate = new QTweetStatusUpdate( twitAuth, this );
connect( statUpdate, SIGNAL( postedStatus(const QTweetStatus &) ), SLOT( postGotTomahawkStatusUpdateReply(const QTweetStatus &) ) );
connect( statUpdate, SIGNAL( error(QTweetNetBase::ErrorCode, const QString&) ), SLOT( postGotTomahawkStatusUpdateError(QTweetNetBase::ErrorCode, const QString &) ) );
QString uuid = QUuid::createUuid();
statUpdate->post( QString( "Got Tomahawk? {" ) + Database::instance()->dbid() + QString( "} (" ) + uuid.mid( 1, 8 ) + QString( ")" ) + QString( " http://gettomahawk.com" ) );
if ( m_postGTtype != "Direct Message" )
{
QTweetStatusUpdate *statUpdate = new QTweetStatusUpdate( twitAuth, this );
connect( statUpdate, SIGNAL( postedStatus(const QTweetStatus &) ), SLOT( postGotTomahawkStatusUpdateReply(const QTweetStatus &) ) );
connect( statUpdate, SIGNAL( error(QTweetNetBase::ErrorCode, const QString&) ), SLOT( postGotTomahawkStatusUpdateError(QTweetNetBase::ErrorCode, const QString &) ) );
QString uuid = QUuid::createUuid();
QString message = QString( "Got Tomahawk? {" ) + Database::instance()->dbid() + QString( "} (" ) + uuid.mid( 1, 8 ) + QString( ")" ) + QString( " http://gettomahawk.com" );
if ( m_postGTtype == "@Mention" )
{
QString user = ui->twitterUserTweetLineEdit->text();
if ( user.startsWith( "@" ) )
user.remove( 0, 1 );
message = QString( "@" ) + user + QString( " " ) + message;
}
statUpdate->post( message );
}
else
{
QTweetDirectMessageNew *statUpdate = new QTweetDirectMessageNew( twitAuth, this );
connect( statUpdate, SIGNAL( parsedDirectMessage(const QTweetDMStatus &)), SLOT( postGotTomahawkDirectMessageReply(const QTweetDMStatus &) ) );
connect( statUpdate, SIGNAL( error(QTweetNetBase::ErrorCode, const QString&) ), SLOT( postGotTomahawkStatusUpdateError(QTweetNetBase::ErrorCode, const QString &) ) );
QString uuid = QUuid::createUuid();
QString message = QString( "Got Tomahawk? {" ) + Database::instance()->dbid() + QString( "} (" ) + uuid.mid( 1, 8 ) + QString( ")" ) + QString( " http://gettomahawk.com" );
QString user = ui->twitterUserTweetLineEdit->text();
if ( user.startsWith( "@" ) )
user.remove( 0, 1 );
statUpdate->post( user, message );
}
}
void
TwitterConfigWidget::postGotTomahawkStatusUpdateReply( const QTweetStatus& status )
{
@@ -203,6 +269,14 @@ TwitterConfigWidget::postGotTomahawkStatusUpdateReply( const QTweetStatus& statu
QMessageBox::information( 0, QString("Tweeted!"), QString("Your tweet has been posted!") );
}
void
TwitterConfigWidget::postGotTomahawkDirectMessageReply( const QTweetDMStatus& status )
{
if ( status.id() == 0 )
QMessageBox::critical( 0, QString("Tweetin' Error"), QString("There was an error posting your direct message -- sorry!") );
else
QMessageBox::information( 0, QString("Tweeted!"), QString("Your message has been posted!") );
}
void
TwitterConfigWidget::postGotTomahawkStatusUpdateError( QTweetNetBase::ErrorCode code, const QString& errorMsg )

View File

@@ -22,6 +22,7 @@
#include "sip/SipPlugin.h"
#include <qtweetstatus.h>
#include <qtweetdmstatus.h>
#include <qtweetuser.h>
#include <qtweetnetbase.h>
@@ -37,7 +38,7 @@ class TwitterConfigWidget : public QWidget
Q_OBJECT
public:
explicit TwitterConfigWidget(SipPlugin* plugin = 0, QWidget *parent = 0);
explicit TwitterConfigWidget( SipPlugin* plugin = 0, QWidget *parent = 0 );
~TwitterConfigWidget();
signals:
@@ -50,14 +51,17 @@ private slots:
void authenticateVerifyError( QTweetNetBase::ErrorCode code, const QString &errorMsg );
void postGotTomahawkStatusAuthVerifyReply( const QTweetUser &user );
void postGotTomahawkStatusUpdateReply( const QTweetStatus &status );
void postGotTomahawkDirectMessageReply( const QTweetDMStatus &status );
void postGotTomahawkStatusUpdateError( QTweetNetBase::ErrorCode, const QString &errorMsg );
void tweetComboBoxIndexChanged( int index );
private:
void authenticateTwitter();
void deauthenticateTwitter();
Ui::TwitterConfigWidget *ui;
SipPlugin *m_plugin;
QString m_postGTtype;
};
#endif // TWITTERCONFIGWIDGET_H

View File

@@ -65,9 +65,9 @@
<item>
<widget class="QLabel" name="twitterInstructionsInfoLabel">
<property name="text">
<string>Here's how it works: just press the button below to tweet &quot;Got Tomahawk?&quot; and some necessary information. Then be (very) patient. Twitter is an asynchronous protocol so it can take a bit!
<string>Here's how it works: just press one of the buttons below to tweet &quot;Got Tomahawk?&quot; and some necessary information. Then be (very) patient. Twitter is an asynchronous protocol so it can take a bit!
If connections to peers seem to have been lost, just press the button again to re-post a tweet for resynchronization.</string>
If connections to peers seem to have been lost, just press the appropriate button again to re-post a tweet for resynchronization.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
@@ -75,11 +75,98 @@ If connections to peers seem to have been lost, just press the button again to r
</widget>
</item>
<item>
<widget class="QPushButton" name="twitterTweetGotTomahawkButton">
<property name="text">
<string>Press here to have Tomahawk post a tweet</string>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>10</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QVBoxLayout" name="twitterTweetVLayout">
<item>
<widget class="QLabel" name="twitterGlobalTweetLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Select the kind of tweet you would like, then press the button to post it:</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="twitterGlobalTweetHLayout">
<item>
<widget class="QComboBox" name="twitterTweetComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>Global Tweet</string>
</property>
</item>
<item>
<property name="text">
<string>@Mention</string>
</property>
</item>
<item>
<property name="text">
<string>Direct Message</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QLineEdit" name="twitterUserTweetLineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>250</width>
<height>0</height>
</size>
</property>
<property name="placeholderText">
<string>e.g. @tomahawkplayer</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="twitterTweetGotTomahawkButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Tweet!</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<spacer name="twitterVertSpacer">

View File

@@ -52,8 +52,8 @@ public:
public slots:
virtual bool connectPlugin( bool startup );
void disconnectPlugin();
void checkSettings() {}
void sendMsg( const QString& to, const QString& msg )
{

View File

@@ -152,11 +152,12 @@ TomahawkWindow::TomahawkWindow( QWidget* parent )
connect(checkForUpdates, SIGNAL( triggered( bool ) ), SLOT( checkForUpdates() ) );
#elif defined( WIN32 )
QUrl updaterUrl;
#ifdef DEBUG_BUILD
if ( qApp->arguments().contains( "--debug" ) )
updaterUrl.setUrl( "http://download.tomahawk-player.org/sparklewin-debug" );
#else
else
updaterUrl.setUrl( "http://download.tomahawk-player.org/sparklewin" );
#endif
qtsparkle::Updater* updater = new qtsparkle::Updater( updaterUrl, this );
updater->SetNetworkAccessManager( TomahawkUtils::nam() );
updater->SetVersion( VERSION );

View File

@@ -102,5 +102,3 @@ target_link_libraries( qxtweb-standalone
# ${QT_LIBRARIES}
# "${CMAKE_CURRENT_SOURCE_DIR}/libqxtweb-standalone.a"
# )
INSTALL( TARGETS qxtweb-standalone DESTINATION lib${LIB_SUFFIX} )