settings: provide a way to use alternative location for configuration file

..and whole data folder.
This commit is contained in:
Andrzej Rybczak
2011-11-13 20:08:03 +01:00
parent 62157909d5
commit a98a1800a7
15 changed files with 155 additions and 100 deletions

View File

@@ -12,7 +12,7 @@ INCLUDES= $(all_includes)
# the library search path.
ncmpcpp_LDFLAGS = $(all_libraries)
noinst_HEADERS = browser.h charset.h clock.h conv.h curl_handle.h display.h \
error.h global.h help.h helpers.h home.h lastfm.h lastfm_service.h lyrics.h \
error.h global.h help.h helpers.h lastfm.h lastfm_service.h lyrics.h \
lyrics_fetcher.h media_library.h menu.h mpdpp.h outputs.h playlist_editor.h screen.h \
scrollpad.h search_engine.h sel_items_adder.h server_info.h settings.h song.h \
song_info.h tag_editor.h tiny_tag_editor.h tolower.h visualizer.h window.h

View File

@@ -538,7 +538,9 @@ void Browser::ChangeBrowseMode()
itsBrowseLocally = !itsBrowseLocally;
ShowMessage("Browse mode: %s", itsBrowseLocally ? "Local filesystem" : "MPD music dir");
itsBrowsedDir = itsBrowseLocally ? home_path : "/";
itsBrowsedDir = itsBrowseLocally ? Config.GetHomeDirectory() : "/";
if (itsBrowseLocally && *itsBrowsedDir.rbegin() == '/')
itsBrowsedDir.resize(itsBrowsedDir.length()-1);
w->Reset();
GetDirectory(itsBrowsedDir);
RedrawHeader = 1;

View File

@@ -21,6 +21,8 @@
#ifndef _GLOBAL_H
#define _GLOBAL_H
#include <sys/time.h>
#include "ncmpcpp.h"
#include "mpdpp.h"
#include "screen.h"

View File

@@ -125,6 +125,7 @@ void ParseArgv(int argc, char **argv)
<< "Usage: ncmpcpp [OPTION]...\n"
<< " -h, --host connect to server at host [localhost]\n"
<< " -p, --port connect to server at port [6600]\n"
<< " -c, --config use alternative configuration file\n"
<< " -s, --screen <name> specify the startup screen\n"
<< " -?, --help show this help message\n"
<< " -v, --version display version information\n"
@@ -142,7 +143,7 @@ void ParseArgv(int argc, char **argv)
}
if (!ConnectToMPD())
exit(0);
exit(1);
if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "--screen"))
{
@@ -258,6 +259,11 @@ void ParseArgv(int argc, char **argv)
Mpd.SetVolume(Mpd.GetVolume()+atoi(argv[i]));
quit = 1;
}
else if (!strcmp(argv[i], "-c") || !strcmp(argv[i], "--config"))
{
// this is used in NcmpcppConfig::CheckForCommandLineConfigFilePath, ignoring here.
++i;
}
else
{
std::cout << "ncmpcpp: invalid option: " << argv[i] << std::endl;

View File

@@ -1,47 +0,0 @@
/***************************************************************************
* Copyright (C) 2008-2011 by Andrzej Rybczak *
* electricityispower@gmail.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef _HOME_H
#define _HOME_H
#include <cstdlib>
#include <string>
#ifdef WIN32
# define _WIN32_IE 0x0400
# include <shlobj.h>
inline std::string _GetHomeFolder()
{
char path[300];
return SHGetSpecialFolderPath(0, path, CSIDL_PERSONAL, 0) ? path : "";
}
# define GET_HOME_FOLDER _GetHomeFolder()
#else
# define GET_HOME_FOLDER getenv("HOME") ? getenv("HOME") : "";
#endif // WIN32
const std::string home_path = GET_HOME_FOLDER;
#undef GET_HOME_FOLDER
#endif

View File

@@ -166,7 +166,7 @@ void Lastfm::SetTitleAndFolder()
{
itsTitle = U("Artist info - ");
itsTitle += TO_WSTRING(itsArgs.find("artist")->second);
itsFolder = home_path + HOME_FOLDER + "artists";
itsFolder = Config.ncmpcpp_directory + "artists";
}
}

View File

@@ -20,11 +20,6 @@
#include <cassert>
#include <cerrno>
#ifdef WIN32
# include <io.h>
#else
# include <sys/stat.h>
#endif // WIN32
#include <fstream>
#include "browser.h"
@@ -37,19 +32,11 @@
#include "settings.h"
#include "song.h"
#ifdef WIN32
# define LYRICS_FOLDER HOME_FOLDER"\\lyrics\\"
#else
# define LYRICS_FOLDER "/.lyrics"
#endif // WIN32
using Global::MainHeight;
using Global::MainStartY;
using Global::myScreen;
using Global::myOldScreen;
std::string Lyrics::itsFolder = home_path + LYRICS_FOLDER;
#ifdef HAVE_CURL_CURL_H
LyricsFetcher **Lyrics::itsFetcher = 0;
std::set<MPD::Song *> Lyrics::itsDownloaded;
@@ -288,7 +275,7 @@ std::string Lyrics::GenerateFilename(const MPD::Song &s)
file += locale_to_utf_cpy(s.GetTitle());
file += ".txt";
EscapeUnallowedChars(file);
filename = itsFolder;
filename = Config.lyrics_directory;
filename += "/";
filename += file;
}
@@ -308,11 +295,7 @@ void Lyrics::Load()
itsSong.Localize();
itsFilename = GenerateFilename(itsSong);
mkdir(itsFolder.c_str()
# ifndef WIN32
, 0755
# endif // !WIN32
);
CreateDir(Config.lyrics_directory);
w->Clear();
w->Reset();

View File

@@ -91,7 +91,6 @@ class Lyrics : public Screen<Scrollpad>
MPD::Song itsSong;
std::string itsFilename;
static std::string itsFolder;
static std::string GenerateFilename(const MPD::Song &s);
};

View File

@@ -238,10 +238,11 @@ namespace
}
}
int main(int argc, char *argv[])
int main(int argc, char **argv)
{
setlocale(LC_ALL, "");
CreateConfigDir();
Config.CheckForCommandLineConfigFilePath(argv, argc);
Config.SetDefaults();
Key.SetDefaults();
@@ -265,13 +266,15 @@ int main(int argc, char *argv[])
ParseArgv(argc, argv);
if (!ConnectToMPD())
return -1;
exit(1);
CreateDir(Config.ncmpcpp_directory);
// always execute these commands, even if ncmpcpp use exit function
atexit(do_at_exit);
// redirect std::cerr output to ~/.ncmpcpp/error.log file
errorlog.open((config_dir + "error.log").c_str(), std::ios::app);
errorlog.open((Config.ncmpcpp_directory + "error.log").c_str(), std::ios::app);
cerr_buffer = std::cerr.rdbuf();
std::cerr.rdbuf(errorlog.rdbuf());

View File

@@ -20,9 +20,13 @@
#ifdef WIN32
# include <io.h>
# define _WIN32_IE 0x0400
# include <shlobj.h>
#else
# include <sys/stat.h>
#endif // WIN32
#include <cstdlib>
#include <string>
#include <fstream>
#include <iostream>
#include <stdexcept>
@@ -46,9 +50,6 @@
# include <langinfo.h>
#endif
const std::string config_file = config_dir + "config";
const std::string keys_config_file = config_dir + "keys";
NcmpcppConfig Config;
NcmpcppKeys Key;
@@ -148,9 +149,9 @@ namespace
}
}
void CreateConfigDir()
void CreateDir(const std::string &dir)
{
mkdir(config_dir.c_str()
mkdir(dir.c_str()
# ifndef WIN32
, 0755
# endif // !WIN32
@@ -476,7 +477,7 @@ void NcmpcppConfig::SetDefaults()
void NcmpcppKeys::Read()
{
std::ifstream f(keys_config_file.c_str());
std::ifstream f((Config.ncmpcpp_directory + "keys").c_str());
std::string key, name;
if (!f.is_open())
@@ -666,12 +667,60 @@ void NcmpcppKeys::Read()
f.close();
}
NcmpcppConfig::NcmpcppConfig()
{
# ifdef WIN32
ncmpcpp_directory = GetHomeDirectory() + "ncmpcpp/";
lyrics_directory = ncmpcpp_directory + "lyrics/";
# else
ncmpcpp_directory = GetHomeDirectory() + ".ncmpcpp/";
lyrics_directory = GetHomeDirectory() + ".lyrics/";
# endif // WIN32
config_file_path = ncmpcpp_directory + "config";
}
const std::string &NcmpcppConfig::GetHomeDirectory()
{
if (!home_directory.empty())
return home_directory;
# ifdef WIN32
char path[MAX_PATH];
SHGetSpecialFolderPath(0, path, CSIDL_PERSONAL, 0);
home_directory = path ? path : "";
replace(home_directory.begin(), home_directory.end(), '\\', '/');
# else
char *home = getenv("HOME");
home_directory = home ? home : "<unknown>";
# endif // WIN32
if (!home_directory.empty() && *home_directory.rbegin() != '/')
home_directory += '/';
return home_directory;
}
void NcmpcppConfig::CheckForCommandLineConfigFilePath(char **argv, int argc)
{
if (argc < 3)
return;
for (int i = 1; i < argc; ++i)
{
if (!strcmp(argv[i], "-c") || !strcmp(argv[i], "--config"))
{
if (++i >= argc)
continue;
config_file_path = argv[i];
}
}
}
void NcmpcppConfig::Read()
{
std::ifstream f(config_file.c_str());
std::ifstream f(config_file_path.c_str());
std::string cl, v, name;
while (f.is_open() && !f.eof())
if (!f.is_open())
return;
while (!f.eof())
{
getline(f, cl);
if (!cl.empty() && cl[0] != '#')
@@ -679,7 +728,23 @@ void NcmpcppConfig::Read()
name = GetOptionName(cl);
v = GetLineValue(cl);
if (name == "mpd_host")
if (name == "ncmpcpp_directory")
{
if (!v.empty())
{
MakeProperPath(v);
ncmpcpp_directory = v;
}
}
else if (name == "lyrics_directory")
{
if (!v.empty())
{
MakeProperPath(v);
lyrics_directory = v;
}
}
else if (name == "mpd_host")
{
if (!v.empty())
mpd_host = v;
@@ -688,10 +753,8 @@ void NcmpcppConfig::Read()
{
if (!v.empty())
{
// if ~ is used at the beginning, replace it with user's home folder
if (v[0] == '~')
v.replace(0, 1, home_path);
mpd_music_dir = v + "/";
MakeProperPath(v);
mpd_music_dir = v;
}
}
else if (name == "visualizer_fifo_path")
@@ -1322,3 +1385,13 @@ void NcmpcppConfig::Read()
*song_in_columns_to_string_format.rbegin() = '}';
}
void NcmpcppConfig::MakeProperPath(std::string &dir)
{
if (dir.empty())
return;
if (dir[0] == '~')
dir.replace(0, 1, home_directory);
replace(dir.begin(), dir.end(), '\\', '/');
if (*dir.rbegin() != '/')
dir += '/';
}

View File

@@ -25,17 +25,8 @@
#include <mpd/client.h>
#include "home.h"
#include "ncmpcpp.h"
#ifdef WIN32
# define HOME_FOLDER "\\ncmpcpp\\"
#else
# define HOME_FOLDER "/.ncmpcpp/"
#endif // WIN32
const std::string config_dir = home_path + HOME_FOLDER;
class BasicScreen; // forward declaration for screens sequence
struct Column
@@ -151,9 +142,17 @@ struct NcmpcppKeys
struct NcmpcppConfig
{
NcmpcppConfig();
const std::string &GetHomeDirectory();
void CheckForCommandLineConfigFilePath(char **argv, int argc);
void SetDefaults();
void Read();
std::string ncmpcpp_directory;
std::string lyrics_directory;
std::string mpd_host;
std::string mpd_music_dir;
std::string visualizer_fifo_path;
@@ -280,12 +279,18 @@ struct NcmpcppConfig
BasicScreen *startup_screen;
std::list<BasicScreen *> screens_seq;
private:
void MakeProperPath(std::string &dir);
std::string home_directory;
std::string config_file_path;
};
extern NcmpcppKeys Key;
extern NcmpcppConfig Config;
void CreateConfigDir();
void CreateDir(const std::string &dir);
void SetWindowsDimensions(size_t &header_height, size_t &footer_start_y, size_t &footer_height);
#endif

View File

@@ -44,7 +44,7 @@ using Global::MainStartY;
TagEditor *myTagEditor = new TagEditor;
const std::string TagEditor::PatternsFile = config_dir + "patterns.list";
std::string TagEditor::PatternsFile = "patterns.list";
std::list<std::string> TagEditor::Patterns;
size_t TagEditor::LeftColumnWidth;
@@ -63,6 +63,7 @@ size_t TagEditor::FParserHeight;
void TagEditor::Init()
{
PatternsFile = Config.ncmpcpp_directory + "patterns.list";
SetDimensions(0, COLS);
Albums = new Menu<string_pair>(0, MainStartY, LeftColumnWidth, MainHeight, Config.titles_visibility ? "Albums" : "", Config.main_color, brNone);

View File

@@ -117,7 +117,7 @@ class TagEditor : public Screen<Window>
std::string itsBrowsedDir;
std::string itsHighlightedDir;
static const std::string PatternsFile;
static std::string PatternsFile;
static std::list<std::string> Patterns;
static size_t MiddleColumnWidth;