aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src-qt5/desktop-utils/lumina-mediaplayer/PianoBarProcess.cpp178
-rw-r--r--src-qt5/desktop-utils/lumina-mediaplayer/PianoBarProcess.h103
-rw-r--r--src-qt5/desktop-utils/lumina-mediaplayer/lumina-mediaplayer.desktop10
-rw-r--r--src-qt5/desktop-utils/lumina-mediaplayer/lumina-mediaplayer.pro97
-rw-r--r--src-qt5/desktop-utils/lumina-mediaplayer/mainUI.ui157
5 files changed, 545 insertions, 0 deletions
diff --git a/src-qt5/desktop-utils/lumina-mediaplayer/PianoBarProcess.cpp b/src-qt5/desktop-utils/lumina-mediaplayer/PianoBarProcess.cpp
new file mode 100644
index 00000000..667ebefb
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-mediaplayer/PianoBarProcess.cpp
@@ -0,0 +1,178 @@
+//===========================================
+// Lumina-Desktop source code
+// Copyright (c) 2017, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#include "PianoBarProcess.h"
+
+#include <QTime>
+#include <QDir>
+#include <QFile>
+#include <QTextStream>
+
+#include <LUtils.h>
+
+PianoBarProcess::PianoBarProcess(QWidget *parent) : QObject(parent){
+ setupProcess();
+
+}
+
+PianoBarProcess::~PianoBarProcess(){
+
+}
+
+// ===== PUBLIC ======
+//Interaction functions
+bool PianoBarProcess::isSetup(); //email/password already saved for use or not
+void PianoBarProcess::setLogin(QString email, QString pass);
+void PianoBarProcess::closePianoBar(); //"q"
+
+QString PianoBarProcess::currentStation(); //Re-direct for the "autostartStation()" function;
+QStringList PianoBarProcess::stations();
+void PianoBarProcess::setCurrentStation(QString station);
+
+void PianoBarProcess::deleteCurrentStation(); //"d"
+void PianoBarProcess::createNewStation(); //"c"
+void PianoBarProcess::createStationFromCurrentSong(); //"v"
+void PianoBarProcess::changeStation(); //"s"
+
+//Settings Manipulation
+QString PianoBarProcess::audioQuality(){ // "audio_quality" = [low, medium, high]
+
+}
+
+void PianoBarProcess::setAudioQuality(QString); // [low, medium, high]
+QString PianoBarProcess::autostartStation(); //"autostart_station" = ID
+void PianoBarProcess::setAutostartStation(QString);
+QString PianoBarProcess::proxy(); //"proxy" = URL (example: "http://USER:PASSWORD@HOST:PORT/" )
+void PianoBarProcess::setProxy(QString);
+QString PianoBarProcess::controlProxy(); //"control_proxy" = URL (example: "http://USER:PASSWORD@HOST:PORT/" )
+void PianoBarProcess::setControlProxy(QString);
+
+// ====== PUBLIC SLOTS ======
+void PianoBarProcess::play(); // "P"
+void PianoBarProcess::pause(); //"S"
+
+void PianoBarProcess::volumeDown(); //"("
+void PianoBarProcess::volumeUp(); //")"
+
+void PianoBarProcess::skipSong(); //"n"
+void PianoBarProcess::loveSong(); // "+"
+void PianoBarProcess::tiredSong(); // "t"
+void PianoBarProcess::banSong(); //"-"
+void PianoBarProcess::bookmarkSong(); //"b"
+
+void PianoBarProcess::explainSong(); //"e"
+
+void PianoBarProcess::requestHistory(); // "h"
+void PianoBarProcess::requestSongInfo(); //"i"
+void PianoBarProcess::requestUpcoming(); //"u"
+
+// ====== PRIVATE ======
+void PianoBarProcess::GenerateSettings(){
+ currentSettings << "audio_quality = medium";
+ currentSettings << "autoselect = 1"; //automatically select the last item in a list (station selection only)
+ currentSettings << "format_list_song = %r::::%t::::%a"; //[rating, title, artist]
+ currentSettings << "format_nowplaying_song = %r::::%t::::%a::::%l::::%u::::%s"; // [rating, title, artist, album, details url, station (if not quickmix)]
+ currentSettings << "format_nowplaying_station = %n::::%i"; //[name, id]
+}
+
+void PianoBarProcess::loadSettings(){
+ currentSettings.clear();
+ QFile file(settingspath);
+ if(!file.exists()){ return; }
+ if(file.open(QIODevice::ReadOnly)){
+ QTextStream in(&file);
+ currentSettings = in.readAll().split("\n");
+ file.close();
+ }
+}
+
+QString PianoBarProcess::settingValue(QString var){
+ for(int i=0; i<currentSettings.length(); i++){
+ if(currentSettings[i].startsWith(var+" = ")){ return currentSettings[i].section(" = ", 1,-1); }
+ }
+ return "";
+}
+
+void PianoBarProcess::setSettingValue(QString var,QString val){
+ bool changed = false;
+ for(int i=0; i<currentSettings.length() && !changed; i++){
+ if(currentSettings[i].startsWith(var+" = ")){ currentSettings[i] = var+" = "+val; changed = true; }
+ }
+ if(!changed){ currentSettings << var+" = "+val; }
+}
+
+void PianoBarProcess::saveSettingsFile(){
+ //Ensure the parent directory exists first
+ QDir dir(settingspath.section("/",0,-2));
+ if(!dir.exists()){ dir.mkpath(dir.absolutePath()); }
+ //Now save the settings
+ QFile file(settingspath);
+ if(file.open(QIODevice::WriteOnly | QIODevice::Truncate)){
+ QTextStream out(&file);
+ out << currentSettings.join("\n");
+ file.close();
+ }
+}
+
+void PianoBarProcess::setupProcess(){
+ PROC = new QProcess(this);
+ //Ensure this process always points to the right configuration directory/files
+ QString configdir = getenv("XDG_CONFIG_HOME");
+ if(configdir.isEmpty()){ configdir = QDir::homePath()+"/.config/lumina-desktop"; }
+ else{ configdir.append("/lumina-desktop"); }
+ QProcessEnvironment penv;
+ penv.insert("XDG_CONFIG_HOME",configdir);
+ settingspath = configdir+"/pianobar/config";
+ PROC->setProcessEnvironment(penv);
+ //Now setup the rest of the process
+ PROC->setProcessChannelMode(QProcess::MergedChannels);
+ QString bin = "pianobar";
+ LUtils::isValidBinary(bin); //will change "bin" to the full path
+ PROC->setProgram(bin);
+ connect(PROC, SIGNAL(readyRead()), this, SLOT(ProcUpdate()) );
+}
+
+// ====== PRIVATE SLOTS ======
+void PianoBarProcess::ProcUpdate(){
+ QStringList info = QString(PROC->readAllStandardOutput()).split("\n");
+ //NOTE: Need to have a cache of info lines which can carry over between updates as needed (for questions, etc)
+ qDebug() << "Got Update:" << info;
+ for(int i=0; i<info.length(); i++){
+ if(info[i].startsWith("|>")){
+ //Now playing line (station, or song)
+ QStringList data = info[i].section(">",1,-1).simplified().split("::::"); //Make sure to chop the line prefix off first
+ if(data.length()==2){ //station
+ cstation = data[0]; //save the name for later
+ emit NowPlayingStation(data[0], data[1]);
+ //Automatically save this station for autostart next time (make toggle-able later)
+ if(data[1]!=autostartStation()){ setAutostartStation(data[1]); }
+
+ }else if(data.length()==6){ //song
+ emit NowPlayingSong( data[0]=="<3", data[1], data[2], data[3], data[4], data[5] );
+ }
+ }else if(info[i].startsWith("(i) ")){ //informational line
+ emit NewInformation(info[i].section(" ",1,-1));
+ }else if(info[i].startsWith("[?] ")){ //waiting for reply to question
+ if(info[i].contains("Select Station:"){
+ //Find the number before this line which corresponds to the cstation variable/name
+ for(j=i-1; j>=0; j--){
+ if(info[j].contains(")" && info[j].contains(cstation) ){
+ PROC->write(info[j].section(")",0,0).simplified() + "\r\n");
+ break;
+ }
+ }
+ }
+
+ }else if(info[i].startsWith("#")){
+ //Time Stamp
+ QTime stamp = QTime::fromString(info[i].section("/",0,0).section("-",1,-1), "mm:ss");
+ int curS = 60*stamp.minutes() + stamp.seconds(); //time remaining
+ stamp = QTime::fromString(info[i].section("/",1,-1), "mm:ss");
+ int totS = 60*stamp.minutes() + stamp.sections(); //time total
+ emit TimeUpdate(totS-curS, totS);
+ }
+ }
+}
diff --git a/src-qt5/desktop-utils/lumina-mediaplayer/PianoBarProcess.h b/src-qt5/desktop-utils/lumina-mediaplayer/PianoBarProcess.h
new file mode 100644
index 00000000..83404e0c
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-mediaplayer/PianoBarProcess.h
@@ -0,0 +1,103 @@
+//===========================================
+// Lumina-Desktop source code
+// Copyright (c) 2017, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+// This is a interface to the "pianobar" utility for streaming
+// audio from the Pandora radio service
+//===========================================
+#ifndef _LUMINA_PIANOBAR_PROCESS_H
+#define _LUMINA_PIANOBAR_PROCESS_H
+
+#include <QObject>
+#include <QWidget>
+#include <QProcess>
+
+
+// #define PIANOBAR_FIFO QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/pianobar/ctl"
+// #define PIANOBAR_CONFIG QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/pianobar/config"
+
+class PianoBarProcess : public QObject{
+ Q_OBJECT
+public:
+ enum State {Stopped, Running, Paused};
+
+ PianoBarProcess(QWidget *parent);
+ ~PianoBarProcess();
+
+ State currentState();
+
+ //Interaction functions
+ bool isSetup(); //email/password already saved for use or not
+ void setLogin(QString email, QString pass);
+ void closePianoBar(); //"q"
+
+ QString currentStation(); //Re-direct for the "autostartStation()" function;
+ QStringList stations();
+ void setCurrentStation(QString station);
+
+ void deleteCurrentStation(); //"d"
+ void createNewStation(); //"c"
+ void createStationFromCurrentSong(); //"v"
+ void changeStation(); //"s"
+
+ //Settings Manipulation
+ QString audioQuality(); // "audio_quality" = [low, medium, high]
+ void setAudioQuality(QString); // [low, medium, high]
+ QString autostartStation(); //"autostart_station" = ID
+ void setAutostartStation(QString);
+ QString proxy(); //"proxy" = URL (example: "http://USER:PASSWORD@HOST:PORT/" )
+ void setProxy(QString);
+ QString controlProxy(); //"control_proxy" = URL (example: "http://USER:PASSWORD@HOST:PORT/" )
+ void setControlProxy(QString);
+
+public slots:
+ void play(); // "P"
+ void pause(); //"S"
+
+ void volumeDown(); //"("
+ void volumeUp(); //")"
+
+ void skipSong(); //"n"
+ void loveSong(); // "+"
+ void tiredSong(); // "t"
+ void banSong(); //"-"
+ void bookmarkSong(); //"b"
+
+ void explainSong(); //"e"
+
+ void requestHistory(); // "h"
+ void requestSongInfo(); //"i"
+ void requestUpcoming(); //"u"
+
+
+private:
+ //Process
+ QProcess PROC;
+ void setupProcess();
+
+ //Settings file management
+ QStringList currentSettings; //cache of the settings file (file is really small);
+ QString settingsPath; //location of the settings file
+ void GenerateSettings();
+ void loadSettings();
+ QString settingValue(QString);
+ void setSettingValue(QString,QString);
+ void saveSettingsFile();
+
+ //Cached Info
+ QString cstation; //current station
+ QStringList stationNames;
+
+private slots:
+ void ProcUpdate();
+
+
+signals:
+ void NewInformation(QString); //random status updates/information
+ void NowPlayingStation(QString, QString); //[name, id]
+ void NowPlayingSong(bool, QString,QString,QString, QString, QString); //[isLoved, title, artist, album, detailsURL, fromStation]
+ void TimeUpdate(int, int); //[current secs, total secs];
+};
+#endif
diff --git a/src-qt5/desktop-utils/lumina-mediaplayer/lumina-mediaplayer.desktop b/src-qt5/desktop-utils/lumina-mediaplayer/lumina-mediaplayer.desktop
new file mode 100644
index 00000000..180f4562
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-mediaplayer/lumina-mediaplayer.desktop
@@ -0,0 +1,10 @@
+[Desktop Entry]
+Exec=lumina-mediaplayer %f
+Icon=audio-x-generic
+Terminal=false
+Type=Application
+StartupNotify=true
+Categories=Utility;
+MimeType=
+Name=Lumina Media Player
+Comment=Play Multimedia Content
diff --git a/src-qt5/desktop-utils/lumina-mediaplayer/lumina-mediaplayer.pro b/src-qt5/desktop-utils/lumina-mediaplayer/lumina-mediaplayer.pro
new file mode 100644
index 00000000..7d91b770
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-mediaplayer/lumina-mediaplayer.pro
@@ -0,0 +1,97 @@
+include("$${PWD}/../../OS-detect.pri")
+
+QT += core gui
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets concurrent
+
+
+TARGET = lumina-mediaplayer
+TEMPLATE = app
+
+
+target.path = $${L_BINDIR}
+
+#include all the special classes from the Lumina tree
+include(../../core/libLumina/LUtils.pri) #includes LUtils
+include(../../core/libLumina/LuminaXDG.pri)
+
+SOURCES += main.cpp\
+ mainUI.cpp
+
+HEADERS += mainUI.h
+
+FORMS += mainUI.ui
+
+TRANSLATIONS = i18nl-mediap_af.ts \
+ i18nl-mediap_ar.ts \
+ i18nl-mediap_az.ts \
+ i18nl-mediap_bg.ts \
+ i18nl-mediap_bn.ts \
+ i18nl-mediap_bs.ts \
+ i18nl-mediap_ca.ts \
+ i18nl-mediap_cs.ts \
+ i18nl-mediap_cy.ts \
+ i18nl-mediap_da.ts \
+ i18nl-mediap_de.ts \
+ i18nl-mediap_el.ts \
+ i18nl-mediap_en_GB.ts \
+ i18nl-mediap_en_ZA.ts \
+ i18nl-mediap_es.ts \
+ i18nl-mediap_et.ts \
+ i18nl-mediap_eu.ts \
+ i18nl-mediap_fa.ts \
+ i18nl-mediap_fi.ts \
+ i18nl-mediap_fr.ts \
+ i18nl-mediap_fr_CA.ts \
+ i18nl-mediap_gl.ts \
+ i18nl-mediap_he.ts \
+ i18nl-mediap_hi.ts \
+ i18nl-mediap_hr.ts \
+ i18nl-mediap_hu.ts \
+ i18nl-mediap_id.ts \
+ i18nl-mediap_is.ts \
+ i18nl-mediap_it.ts \
+ i18nl-mediap_ja.ts \
+ i18nl-mediap_ka.ts \
+ i18nl-mediap_ko.ts \
+ i18nl-mediap_lt.ts \
+ i18nl-mediap_lv.ts \
+ i18nl-mediap_mk.ts \
+ i18nl-mediap_mn.ts \
+ i18nl-mediap_ms.ts \
+ i18nl-mediap_mt.ts \
+ i18nl-mediap_nb.ts \
+ i18nl-mediap_nl.ts \
+ i18nl-mediap_pa.ts \
+ i18nl-mediap_pl.ts \
+ i18nl-mediap_pt.ts \
+ i18nl-mediap_pt_BR.ts \
+ i18nl-mediap_ro.ts \
+ i18nl-mediap_ru.ts \
+ i18nl-mediap_sk.ts \
+ i18nl-mediap_sl.ts \
+ i18nl-mediap_sr.ts \
+ i18nl-mediap_sv.ts \
+ i18nl-mediap_sw.ts \
+ i18nl-mediap_ta.ts \
+ i18nl-mediap_tg.ts \
+ i18nl-mediap_th.ts \
+ i18nl-mediap_tr.ts \
+ i18nl-mediap_uk.ts \
+ i18nl-mediap_uz.ts \
+ i18nl-mediap_vi.ts \
+ i18nl-mediap_zh_CN.ts \
+ i18nl-mediap_zh_HK.ts \
+ i18nl-mediap_zh_TW.ts \
+ i18nl-mediap_zu.ts
+
+dotrans.path=$${L_SHAREDIR}/lumina-desktop/i18n/
+dotrans.extra=cd i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
+
+desktop.files=lumina-mediaplayer.desktop
+desktop.path=$${L_SHAREDIR}/applications/
+
+INSTALLS += target desktop
+
+WITH_I18N{
+ INSTALLS += dotrans
+}
diff --git a/src-qt5/desktop-utils/lumina-mediaplayer/mainUI.ui b/src-qt5/desktop-utils/lumina-mediaplayer/mainUI.ui
new file mode 100644
index 00000000..d662b20c
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-mediaplayer/mainUI.ui
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>385</width>
+ <height>410</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>MainWindow</string>
+ </property>
+ <widget class="QWidget" name="centralwidget">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QFrame" name="frame_type">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QRadioButton" name="radio_local">
+ <property name="text">
+ <string>Local Files</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="radio_pandora">
+ <property name="text">
+ <string>Pandora Radio</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QStackedWidget" name="stackedWidget">
+ <widget class="QWidget" name="page_local"/>
+ <widget class="QWidget" name="page_pandora">
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tab_pandora_playing">
+ <attribute name="title">
+ <string>Now Playing</string>
+ </attribute>
+ </widget>
+ <widget class="QWidget" name="tab_pandora_settings">
+ <attribute name="title">
+ <string>Settings</string>
+ </attribute>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="menubar">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>385</width>
+ <height>22</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QStatusBar" name="statusbar"/>
+ <widget class="QToolBar" name="toolBar">
+ <property name="windowTitle">
+ <string>toolBar</string>
+ </property>
+ <property name="movable">
+ <bool>false</bool>
+ </property>
+ <property name="allowedAreas">
+ <set>Qt::TopToolBarArea</set>
+ </property>
+ <property name="floatable">
+ <bool>false</bool>
+ </property>
+ <attribute name="toolBarArea">
+ <enum>TopToolBarArea</enum>
+ </attribute>
+ <attribute name="toolBarBreak">
+ <bool>false</bool>
+ </attribute>
+ <addaction name="actionPlay"/>
+ <addaction name="actionPause"/>
+ <addaction name="actionStop"/>
+ <addaction name="actionNext"/>
+ <addaction name="actionBack"/>
+ <addaction name="actionVolUp"/>
+ <addaction name="actionVolDown"/>
+ </widget>
+ <action name="actionPlay">
+ <property name="text">
+ <string>Play</string>
+ </property>
+ </action>
+ <action name="actionPause">
+ <property name="text">
+ <string>Pause</string>
+ </property>
+ </action>
+ <action name="actionStop">
+ <property name="text">
+ <string>Stop</string>
+ </property>
+ </action>
+ <action name="actionNext">
+ <property name="text">
+ <string>Next</string>
+ </property>
+ </action>
+ <action name="actionBack">
+ <property name="text">
+ <string>Back</string>
+ </property>
+ </action>
+ <action name="actionVolUp">
+ <property name="text">
+ <string>VolUp</string>
+ </property>
+ </action>
+ <action name="actionVolDown">
+ <property name="text">
+ <string>VolDown</string>
+ </property>
+ </action>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
bgstack15