1 /* This file is part of Clementine.
2 Copyright 2011, 2013, Alan Briolat <alan.briolat@gmail.com>
3 Copyright 2013, Ross Wolfson <ross.wolfson@gmail.com>
4 Copyright 2014, Krzysztof Sobiecki <sobkas@gmail.com>
5 Copyright 2014, John Maguire <john.maguire@gmail.com>
6
7 Clementine is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 Clementine is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Clementine. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "subsonicsettingspage.h"
22 #include "ui_subsonicsettingspage.h"
23
24 #include <QSettings>
25
26 #include "core/logging.h"
27 #include "internet/core/internetmodel.h"
28 #include "ui/iconloader.h"
29
SubsonicSettingsPage(SettingsDialog * dialog)30 SubsonicSettingsPage::SubsonicSettingsPage(SettingsDialog* dialog)
31 : SettingsPage(dialog),
32 ui_(new Ui_SubsonicSettingsPage),
33 service_(InternetModel::Service<SubsonicService>()) {
34 ui_->setupUi(this);
35 setWindowIcon(IconLoader::Load("subsonic", IconLoader::Provider));
36
37 connect(ui_->server, SIGNAL(editingFinished()),
38 SLOT(ServerEditingFinished()));
39 connect(ui_->login, SIGNAL(clicked()), SLOT(Login()));
40 connect(ui_->login_state, SIGNAL(LogoutClicked()), SLOT(Logout()));
41 connect(service_, SIGNAL(LoginStateChanged(SubsonicService::LoginState)),
42 SLOT(LoginStateChanged(SubsonicService::LoginState)));
43
44 ui_->login_state->AddCredentialField(ui_->server);
45 ui_->login_state->AddCredentialField(ui_->username);
46 ui_->login_state->AddCredentialField(ui_->password);
47 ui_->login_state->AddCredentialField(ui_->usesslv3);
48 ui_->login_state->AddCredentialField(ui_->verifycert);
49 ui_->login_state->AddCredentialGroup(ui_->server_group);
50
51 ui_->login_state->SetAccountTypeText(
52 tr("Streaming from a Subsonic server requires a valid server license "
53 "after the 30-day trial period."));
54 ui_->login_state->SetAccountTypeVisible(true);
55 }
56
~SubsonicSettingsPage()57 SubsonicSettingsPage::~SubsonicSettingsPage() { delete ui_; }
58
Load()59 void SubsonicSettingsPage::Load() {
60 QSettings s;
61 s.beginGroup(SubsonicService::kSettingsGroup);
62
63 ui_->server->setText(s.value("server").toString());
64 ui_->username->setText(s.value("username").toString());
65 ui_->password->setText(s.value("password").toString());
66 ui_->usesslv3->setChecked(s.value("usesslv3").toBool());
67 ui_->verifycert->setChecked(s.value("verifycert", true).toBool());
68
69 // If the settings are complete, SubsonicService will have used them already
70 // and
71 // we can tell the user if they worked
72 if (ui_->server->text() != "" && ui_->username->text() != "") {
73 LoginStateChanged(service_->login_state());
74 }
75 }
76
Save()77 void SubsonicSettingsPage::Save() {
78 QSettings s;
79 s.beginGroup(SubsonicService::kSettingsGroup);
80
81 s.setValue("server", ui_->server->text());
82 s.setValue("username", ui_->username->text());
83 s.setValue("password", ui_->password->text());
84 s.setValue("usesslv3", ui_->usesslv3->isChecked());
85 s.setValue("verifycert", ui_->verifycert->isChecked());
86 }
87
LoginStateChanged(SubsonicService::LoginState newstate)88 void SubsonicSettingsPage::LoginStateChanged(
89 SubsonicService::LoginState newstate) {
90 const bool logged_in = newstate == SubsonicService::LoginState_Loggedin;
91
92 ui_->login_state->SetLoggedIn(
93 logged_in ? LoginStateWidget::LoggedIn : LoginStateWidget::LoggedOut,
94 QString("%1 (%2)").arg(ui_->username->text()).arg(ui_->server->text()));
95 ui_->login_state->SetAccountTypeVisible(!logged_in);
96
97 switch (newstate) {
98 case SubsonicService::LoginState_BadServer:
99 ui_->login_state->SetAccountTypeText(
100 tr("Could not connect to Subsonic, check server URL. "
101 "Example: http://localhost:4040/"));
102 break;
103
104 case SubsonicService::LoginState_BadCredentials:
105 ui_->login_state->SetAccountTypeText(tr("Wrong username or password."));
106 break;
107
108 case SubsonicService::LoginState_OutdatedClient:
109 ui_->login_state->SetAccountTypeText(tr(
110 "Incompatible Subsonic REST protocol version. Client must upgrade."));
111 break;
112
113 case SubsonicService::LoginState_OutdatedServer:
114 ui_->login_state->SetAccountTypeText(tr(
115 "Incompatible Subsonic REST protocol version. Server must upgrade."));
116 break;
117
118 case SubsonicService::LoginState_Unlicensed:
119 ui_->login_state->SetAccountTypeText(
120 tr("The trial period for the Subsonic server is over. "
121 "Please donate to get a license key. Visit subsonic.org for "
122 "details."));
123 break;
124
125 case SubsonicService::LoginState_OtherError:
126 ui_->login_state->SetAccountTypeText(
127 tr("An unspecified error occurred."));
128 break;
129
130 case SubsonicService::LoginState_ConnectionRefused:
131 ui_->login_state->SetAccountTypeText(
132 tr("Connection refused by server, check server URL. "
133 "Example: http://localhost:4040/"));
134 break;
135
136 case SubsonicService::LoginState_HostNotFound:
137 ui_->login_state->SetAccountTypeText(
138 tr("Host not found, check server URL. "
139 "Example: http://localhost:4040/"));
140 break;
141
142 case SubsonicService::LoginState_Timeout:
143 ui_->login_state->SetAccountTypeText(
144 tr("Connection timed out, check server URL. "
145 "Example: http://localhost:4040/"));
146 break;
147
148 case SubsonicService::LoginState_SslError:
149 ui_->login_state->SetAccountTypeText(
150 tr("SSL handshake error, verify server configuration. "
151 "SSLv3 option below may workaround some issues."));
152 break;
153
154 case SubsonicService::LoginState_IncompleteCredentials:
155 ui_->login_state->SetAccountTypeText(tr(
156 "Incomplete configuration, please ensure all fields are populated."));
157 break;
158
159 case SubsonicService::LoginState_RedirectLimitExceeded:
160 ui_->login_state->SetAccountTypeText(
161 tr("Redirect limit exceeded, verify server configuration."));
162 break;
163
164 case SubsonicService::LoginState_RedirectNoUrl:
165 ui_->login_state->SetAccountTypeText(
166 tr("HTTP 3xx status code received without URL, "
167 "verify server configuration."));
168 break;
169
170 default:
171 break;
172 }
173 }
174
ServerEditingFinished()175 void SubsonicSettingsPage::ServerEditingFinished() {
176 QString input = ui_->server->text();
177 QUrl url = QUrl::fromUserInput(input);
178
179 // Veto things that don't get guessed as an HTTP URL, the result will be
180 // unhelpful
181 if (!url.scheme().startsWith("http")) {
182 return;
183 }
184
185 // If the user specified a /rest location, remove it since we're going to
186 // re-add it later
187 url = SubsonicService::ScrubUrl(url);
188
189 ui_->server->setText(url.toString());
190 qLog(Debug) << "URL fixed:" << input << "to" << url;
191 }
192
Login()193 void SubsonicSettingsPage::Login() {
194 ui_->login_state->SetLoggedIn(LoginStateWidget::LoginInProgress);
195 service_->Login(ui_->server->text(), ui_->username->text(),
196 ui_->password->text(), ui_->usesslv3->isChecked(),
197 ui_->verifycert->isChecked());
198 }
199
Logout()200 void SubsonicSettingsPage::Logout() {
201 ui_->username->setText("");
202 ui_->password->setText("");
203 }
204