1 /****************************************************************************************
2 * Copyright (c) 2009 Nikolaj Hald Nielsen <nhn@kde.org> *
3 * *
4 * This program is free software; you can redistribute it and/or modify it under *
5 * the terms of the GNU General Public License as published by the Free Software *
6 * Foundation; either version 2 of the License, or (at your option) any later *
7 * version. *
8 * *
9 * This program is distributed in the hope that it will be useful, but WITHOUT ANY *
10 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A *
11 * PARTICULAR PURPOSE. See the GNU General Public License for more details. *
12 * *
13 * You should have received a copy of the GNU General Public License along with *
14 * this program. If not, see <http://www.gnu.org/licenses/>. *
15 ****************************************************************************************/
16
17 #include "AmarokUrl.h"
18
19 #include "AmarokUrlHandler.h"
20 #include "BookmarkGroup.h"
21 #include "core-impl/storage/StorageManager.h"
22 #include "core/support/Debug.h"
23 #include <core/storage/SqlStorage.h>
24
25 #include <QUrl>
26 #include <QUrlQuery>
27
AmarokUrl()28 AmarokUrl::AmarokUrl()
29 : m_id( -1 )
30 , m_parent( 0 )
31 {}
32
AmarokUrl(const QString & urlString,const BookmarkGroupPtr & parent)33 AmarokUrl::AmarokUrl( const QString & urlString, const BookmarkGroupPtr &parent )
34 : m_id( -1 )
35 , m_parent( parent )
36 {
37 initFromString( urlString );
38 }
39
AmarokUrl(const QStringList & resultRow,const BookmarkGroupPtr & parent)40 AmarokUrl::AmarokUrl( const QStringList & resultRow, const BookmarkGroupPtr &parent )
41 : m_parent( parent )
42 {
43 m_id = resultRow[0].toInt();
44 m_name = resultRow[2];
45 const QString urlString = resultRow[3];
46 m_description = resultRow[4];
47 m_customValue = resultRow[5];
48
49 initFromString( urlString );
50 }
51
~AmarokUrl()52 AmarokUrl::~AmarokUrl()
53 {}
54
initFromString(const QString & urlString)55 void AmarokUrl::initFromString( const QString & urlString )
56 {
57 //first, strip amarok://
58 QString strippedUrlString = urlString;
59 strippedUrlString = strippedUrlString.replace( QLatin1String("amarok://"), QLatin1String("") );
60
61 //separate path from arguments
62 QStringList parts = strippedUrlString.split( QLatin1Char('?') );
63
64 QString commandAndPath = parts.at( 0 );
65
66 QString argumentsString;
67 if ( parts.size() == 2 )
68 argumentsString = parts.at( 1 );
69
70 if ( !argumentsString.isEmpty() )
71 {
72 parts = argumentsString.split( '&' );
73
74 foreach( const QString &argument, parts )
75 {
76
77 QStringList argParts = argument.split( '=' );
78 debug() << "argument: " << argument << " unescaped: " << unescape( argParts.at( 1 ) );
79 setArg( argParts.at( 0 ), unescape( argParts.at( 1 ) ) );
80 }
81 }
82
83 //get the command
84
85 parts = commandAndPath.split( QLatin1Char('/') );
86 m_command = parts.takeFirst();
87
88 m_path = parts.join( QLatin1Char('/') );
89
90 m_path = unescape( m_path );
91 }
92
setCommand(const QString & command)93 void AmarokUrl::setCommand( const QString & command )
94 {
95 m_command = command;
96 }
97
command() const98 QString AmarokUrl::command() const
99 {
100 return m_command;
101 }
102
103 QString
prettyCommand() const104 AmarokUrl::prettyCommand() const
105 {
106 return The::amarokUrlHandler()->prettyCommand( command() );
107 }
108
args() const109 QMap<QString, QString> AmarokUrl::args() const
110 {
111 return m_arguments;
112 }
113
setArg(const QString & name,const QString & value)114 void AmarokUrl::setArg( const QString &name, const QString &value )
115 {
116 m_arguments.insert( name, value );
117 }
118
run()119 bool AmarokUrl::run()
120 {
121 DEBUG_BLOCK
122 return The::amarokUrlHandler()->run( *this );
123 }
124
url() const125 QString AmarokUrl::url() const
126 {
127 QUrl url;
128 url.setScheme( QStringLiteral("amarok") );
129 url.setHost( m_command );
130 url.setPath( '/' + m_path ); // the path must begin by /
131 QUrlQuery query;
132
133 foreach( const QString &argName, m_arguments.keys() )
134 query.addQueryItem( argName, m_arguments[argName] );
135
136 url.setQuery( query );
137 return url.toEncoded();
138 }
139
saveToDb()140 bool AmarokUrl::saveToDb()
141 {
142 DEBUG_BLOCK
143
144 if ( isNull() )
145 return false;
146
147 const int parentId = m_parent ? m_parent->id() : -1;
148
149 auto sql = StorageManager::instance()->sqlStorage();
150
151 if( m_id != -1 )
152 {
153 //update existing
154 debug() << "Updating bookmark";
155 QString query = QStringLiteral("UPDATE bookmarks SET parent_id=%1, name='%2', url='%3', description='%4', custom='%5' WHERE id=%6;");
156 query = query.arg( QString::number( parentId ), sql->escape( m_name ), sql->escape( url() ),
157 sql->escape( m_description ), sql->escape( m_customValue ), QString::number( m_id ) );
158 StorageManager::instance()->sqlStorage()->query( query );
159 }
160 else
161 {
162 //insert new
163 debug() << "Creating new bookmark in the db";
164 QString query = QStringLiteral("INSERT INTO bookmarks ( parent_id, name, url, description, custom ) VALUES ( %1, '%2', '%3', '%4', '%5' );");
165 query = query.arg( QString::number( parentId ), sql->escape( m_name ), sql->escape( url() ),
166 sql->escape( m_description ), sql->escape( m_customValue ) );
167 m_id = StorageManager::instance()->sqlStorage()->insert( query, nullptr );
168 }
169
170 return true;
171 }
172
setName(const QString & name)173 void AmarokUrl::setName( const QString & name )
174 {
175 m_name = name;
176 }
177
name() const178 QString AmarokUrl::name() const
179 {
180 return m_name;
181 }
182
setDescription(const QString & description)183 void AmarokUrl::setDescription( const QString & description )
184 {
185 m_description = description;
186 }
187
description() const188 QString AmarokUrl::description() const
189 {
190 return m_description;
191 }
192
removeFromDb()193 void AmarokUrl::removeFromDb()
194 {
195 QString query = QStringLiteral("DELETE FROM bookmarks WHERE id=%1");
196 query = query.arg( QString::number( m_id ) );
197 StorageManager::instance()->sqlStorage()->query( query );
198 }
199
rename(const QString & name)200 void AmarokUrl::rename( const QString &name )
201 {
202 m_name = name;
203 if ( m_id != -1 )
204 saveToDb();
205 }
206
reparent(const BookmarkGroupPtr & parent)207 void AmarokUrl::reparent( const BookmarkGroupPtr &parent )
208 {
209 m_parent = parent;
210 saveToDb();
211 }
212
setCustomValue(const QString & custom)213 void AmarokUrl::setCustomValue( const QString & custom )
214 {
215 m_customValue = custom;
216 }
217
customValue() const218 QString AmarokUrl::customValue() const
219 {
220 return m_customValue;
221 }
222
escape(const QString & in)223 QString AmarokUrl::escape( const QString & in )
224 {
225 return QUrl::toPercentEncoding( in.toUtf8() );
226 }
227
unescape(const QString & in)228 QString AmarokUrl::unescape( const QString & in )
229 {
230 return QUrl::fromPercentEncoding( in.toUtf8() );
231 }
232
isNull() const233 bool AmarokUrl::isNull() const
234 {
235 return m_command.isEmpty();
236 }
237
path() const238 QString AmarokUrl::path() const
239 {
240 return m_path;
241 }
242
setPath(const QString & path)243 void AmarokUrl::setPath( const QString &path )
244 {
245 m_path = path;
246 }
247
248
249
250