diff options
author | wr61 <wr61@e10066b5-e1e2-0310-b819-94efdf66514b> | 2005-03-02 19:18:07 +0000 |
---|---|---|
committer | wr61 <wr61@e10066b5-e1e2-0310-b819-94efdf66514b> | 2005-03-02 19:18:07 +0000 |
commit | a70f588db6ca2d5c26454704c14926736d4f57cb (patch) | |
tree | dd5984ca7a247d254b5a84046f33747c853e9670 | |
parent | b723a7eddc7d5a70b4af4c641f44cd4904cbe63f (diff) | |
download | vdr-plugin-muggle-a70f588db6ca2d5c26454704c14926736d4f57cb.tar.gz vdr-plugin-muggle-a70f588db6ca2d5c26454704c14926736d4f57cb.tar.bz2 |
embedded is now default
git-svn-id: https://vdr-muggle.svn.sourceforge.net/svnroot/vdr-muggle/branches/0.1.3-wr@529 e10066b5-e1e2-0310-b819-94efdf66514b
-rw-r--r-- | Makefile | 22 | ||||
-rw-r--r-- | mg_mysql.c | 107 | ||||
-rw-r--r-- | mg_mysql.h | 3 | ||||
-rw-r--r-- | mg_order.c | 2 | ||||
-rw-r--r-- | mg_order.h | 1 | ||||
-rw-r--r-- | mg_selection.c | 22 | ||||
-rw-r--r-- | mg_sync.c | 10 | ||||
-rw-r--r-- | muggle.c | 12 | ||||
-rwxr-xr-x | mugglei.c | 30 | ||||
-rw-r--r-- | vdr_menu.c | 37 | ||||
-rw-r--r-- | vdr_menu.h | 14 |
11 files changed, 174 insertions, 86 deletions
@@ -14,6 +14,10 @@ PLUGIN = muggle # HAVE_VORBISFILE=1 # HAVE_FLAC=1 +#if you want to use a dedicated Mysql server instead of the embedded code, +#define this in $VDRDIR/Make.config: +# HAVE_SERVER +# ### The version number of this plugin (taken from the main source file): VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ print $$6 }' | sed -e 's/[";]//g') @@ -51,17 +55,21 @@ INCLUDES += -I$(VDRDIR) -I$(VDRDIR)/include -I$(DVBDIR)/include \ DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"' -MIFLAGS += -I/usr/include/taglib -lmysqlclient - ### The object files (add further files here): OBJS = $(PLUGIN).o i18n.o mg_valmap.o mg_mysql.o mg_sync.o mg_order.o mg_content.o mg_selection.o vdr_actions.o vdr_menu.o mg_tools.o \ vdr_decoder_mp3.o vdr_stream.o vdr_decoder.o vdr_player.o \ vdr_setup.o mg_setup.o -LIBS = -lmad -lmysqlclient -ltag -MILIBS = -lmysqlclient -ltag -# MILIBS = -lmysqld -lpthread -lz -lcrypt -lnsl -lm -lpthread -lrt -lwrap -ltag +LIBS = -lmad -ltag +MILIBS = -ltag + +ifdef HAVE_SERVER +SQLLIBS = `mysql_config --libs` +DEFINES += -DHAVE_SERVER +else +SQLLIBS = `mysql_config --libmysqld-libs` +endif ifdef HAVE_VORBISFILE DEFINES += -DHAVE_VORBISFILE @@ -96,11 +104,11 @@ mg_tables.h: scripts/genres.txt scripts/languages.txt scripts/musictypes.txt scr scripts/gentables libvdr-$(PLUGIN).so: $(OBJS) - $(CXX) $(CXXFLAGS) -shared $(OBJS) $(LIBS) -o $@ + $(CXX) $(CXXFLAGS) -shared $(OBJS) $(LIBS) $(SQLLIBS) -o $@ @cp $@ $(LIBDIR)/$@.$(VDRVERSION) mugglei: mg_tools.o mugglei.o mg_sync.o mg_mysql.o mg_setup.o - $(CXX) $(CXXFLAGS) $^ $(MILIBS) -o $@ + $(CXX) $(CXXFLAGS) $^ $(MILIBS) $(SQLLIBS) -o $@ install: @cp ../../lib/libvdr-muggle*.so.* /usr/lib/vdr/ @@ -10,19 +10,85 @@ #include "mg_mysql.h" #include "mg_tools.h" +#include <assert.h> #include <stdarg.h> +#include <sys/stat.h> +#include <sys/types.h> #include "vdr_setup.h" bool needGenre2; static bool needGenre2_set; +class mysqlhandle_t { + public: + mysqlhandle_t(); + ~mysqlhandle_t(); + private: + char *m_datadir; +}; + +char *server_args[] = +{ + "muggle", + "--key_buffer_size=32M" +}; +char *server_groups[] = +{ + "embedded", + "server", + "muggle_SERVER", + 0 +}; + +mysqlhandle_t::mysqlhandle_t() +{ +#ifndef HAVE_SERVER + mgDebug(1,"calling mysql_server_init"); + if (mysql_server_init(sizeof(server_args) / sizeof(char *), + server_args, server_groups)) + mgDebug(3,"mysql_server_init failed"); +#endif +} + +mysqlhandle_t::~mysqlhandle_t() +{ +#ifndef HAVE_SERVER + mgDebug(3,"calling mysql_server_end"); + mysql_server_end(); + free(m_datadir); +#endif +} + +static mysqlhandle_t* mysqlhandle; + +mgmySql::mgmySql() +{ + m_database_found=false; + m_hasfolderfields=false; + if (!mysqlhandle) + mysqlhandle = new mysqlhandle_t; + m_db = 0; + Connect(); +} + +mgmySql::~mgmySql() +{ + if (m_db) + { + mgDebug(3,"%X: closing DB connection",this); + mysql_close (m_db); + m_db = 0; + } +} -char *db_cmds[] = +static char *db_cmds[] = { "DROP DATABASE IF EXISTS GiantDisc", "CREATE DATABASE GiantDisc", +#ifdef HAVE_SERVER "grant all privileges on GiantDisc.* to vdr@localhost;", +#endif "use GiantDisc;", "drop table if exists album;", "CREATE TABLE album ( " @@ -189,24 +255,6 @@ char *db_cmds[] = }; -mgmySql::mgmySql() -{ - m_db = 0; - m_database_found=false; - m_hasfolderfields=false; - Connect(); -} - -mgmySql::~mgmySql() -{ - if (m_db) - { - mysql_close (m_db); - m_db = 0; - } -} - - MYSQL_RES* mgmySql::exec_sql( string query) { @@ -363,6 +411,12 @@ mgmySql::sql_Cstring( const char *s, char *buf) } bool +mgmySql::ServerConnected () const +{ + return m_db; +} + +bool mgmySql::Connected () const { return m_database_found; @@ -371,12 +425,10 @@ mgmySql::Connected () const void mgmySql::Connect () { - if (m_db) - { - mysql_close (m_db); - m_db = 0; - } + assert(!m_db); +#ifdef HAVE_SERVER if (the_setup.DbHost == "") return; +#endif m_db = mysql_init (0); if (!m_db) return; @@ -429,6 +481,7 @@ mgmySql::Connect () m_database_found=true; break; } + mysql_free_result(rows); } if (m_database_found) Use(); @@ -477,3 +530,9 @@ mgmySql::CreateFolderFields() } } +void +database_end() +{ + delete mysqlhandle; + mysqlhandle=0; +} @@ -16,6 +16,8 @@ using namespace std; +void database_end(); // must be done explicitly + /*! * \brief an abstract database class * @@ -55,6 +57,7 @@ class mgmySql long thread_id() { return mysql_thread_id(m_db);} long affected_rows() { return mysql_affected_rows(m_db);} + bool ServerConnected() const; bool Connected() const; bool HasFolderFields() const { return m_hasfolderfields;} void Connect(); @@ -2,7 +2,7 @@ #include "mg_tools.h" #include "i18n.h" #include <stdio.h> - +#include <assert.h> const char * EMPTY = "XNICHTGESETZTX"; @@ -3,7 +3,6 @@ #include <stdlib.h> #include <typeinfo> #include <string> -#include <assert.h> #include <list> #include <vector> #include <sstream> diff --git a/mg_selection.c b/mg_selection.c index 173ff82..223cebc 100644 --- a/mg_selection.c +++ b/mg_selection.c @@ -14,17 +14,23 @@ #include <sys/stat.h> #include <stdio.h> #include <fts.h> +#include <assert.h> #include "i18n.h" #include "mg_selection.h" #include "vdr_setup.h" #include "mg_tools.h" +#include "mg_sync.h" #include <mpegfile.h> #include <flacfile.h> #include <id3v2tag.h> #include <fileref.h> +#if VDRVERSNUM >= 10307 +#include <vdr/interface.h> +#include <vdr/skins.h> +#endif //! \brief adds string n to string s, using a comma to separate them static string comma (string & s, string n); @@ -568,6 +574,22 @@ mgSelection::setOrder(mgOrder* o) void mgSelection::InitFrom(mgValmap& nv) { + if (m_db.ServerConnected() && !m_db.Connected()) + { + char *b; + asprintf(&b,tr("Create database %s?"),the_setup.DbName); + if (Interface->Confirm(b)) + { + char *argv[2]; + argv[0]="."; + argv[1]=0; + m_db.Create(); + mgSync *s = new mgSync; + s->Sync(argv); + delete s; + } + free(b); + } InitSelection(); m_fall_through = nv.getbool("FallThrough"); m_Directory = nv.getstr("Directory"); @@ -99,12 +99,14 @@ mgSync::getAlbum(const char *c_album,const char *c_artist,const char *c_director // how many artists will the album have after adding this one? asprintf(&b,"SELECT distinct album.artist FROM tracks, album %s " " union select %s",where,c_artist); - m_db.exec_sql (b); + MYSQL_RES *rows = m_db.exec_sql (b); free(b); long new_album_artists = m_db.affected_rows(); + mysql_free_result(rows); if (new_album_artists>1) // is the album multi artist? { asprintf(&b,"SELECT album.cddbid FROM tracks, album %s",where); + free(result); result=m_db.sql_Cstring(m_db.get_col0(b)); free(b); asprintf(&b,"UPDATE album SET artist='Various Artists' WHERE cddbid=%s",result); @@ -116,6 +118,7 @@ mgSync::getAlbum(const char *c_album,const char *c_artist,const char *c_director } else { // no usable album found + free(result); asprintf(&result,"'%ld-%9s",random(),c_artist+1); char *p=strchr(result,0)-1; if (*p!='\'') @@ -132,7 +135,8 @@ mgSync::getAlbum(const char *c_album,const char *c_artist,const char *c_director mgSync::mgSync() { - if (!m_db.Connected()) + m_genre_rows=0; + if (!m_db.Connected()) return; m_genre_rows = m_db.exec_sql ("SELECT id,genre from genre"); MYSQL_ROW rx; @@ -142,7 +146,7 @@ mgSync::mgSync() mgSync::~mgSync() { - mysql_free_result(m_genre_rows); + if (m_genre_rows) mysql_free_result(m_genre_rows); } void @@ -86,12 +86,14 @@ mgMuggle::CommandLineHelp (void) " -u UUUU, --user=UUUU specify database user (default is )\n" " -w WWWW, --password=WWWW specify database password (default is empty)\n" " -t TTTT, --toplevel=TTTT specify toplevel directory for music (default is /mnt/music)\n" - " -g, --giantdisc enable full Giantdisc compatibility mode\n"; + " -g, --giantdisc enable full Giantdisc compatibility mode\n" + " -v, --verbose specify debug level. The higher the more. Default is 1\n"; } bool mgMuggle::ProcessArgs (int argc, char *argv[]) { + mgSetDebugLevel (1); mgDebug (1, "mgMuggle::ProcessArgs"); // Implement command line argument processing here if applicable. @@ -113,7 +115,7 @@ bool mgMuggle::ProcessArgs (int argc, char *argv[]) c, option_index = 0; while ((c = - getopt_long (argc, argv, "gh:s:n:p:t:u:w:", long_options, + getopt_long (argc, argv, "gh:s:n:p:t:u:w:v:", long_options, &option_index)) != -1) { switch (c) @@ -148,6 +150,11 @@ bool mgMuggle::ProcessArgs (int argc, char *argv[]) the_setup.DbPass = strcpyrealloc (the_setup.DbPass, optarg); } break; + case 'v': + { + mgSetDebugLevel (atol(optarg)); + } + break; case 't': { if (optarg[strlen (optarg) - 1] != '/') @@ -187,7 +194,6 @@ bool mgMuggle::Initialize (void) bool mgMuggle::Start (void) { // Start any background activities the plugin shall perform. - mgSetDebugLevel (99); RegisterI18n (Phrases); return true; } @@ -39,22 +39,6 @@ using namespace std; int SysLogLevel = 1; -static char *server_args[] = -{ - "this_program", /* this string is not used */ - "--datadir=.", - "--key_buffer_size=32M" -}; - -static char *server_groups[] = -{ - "embedded", - "server", - "this_program_SERVER", - (char *)NULL -}; - -string host, user, pass, dbname, sck; bool import_assorted, delete_mode, create_mode; void showmessage(const char *msg) @@ -69,11 +53,6 @@ const char *I18nTranslate(const char *s,const char *Plugin) int main( int argc, char *argv[] ) { mgSetDebugLevel(1); - if( mysql_server_init(sizeof(server_args) / sizeof(char *), - server_args, server_groups) ) - { - exit(1); - } if( argc < 2 ) { // we need at least a filename! @@ -159,12 +138,13 @@ int main( int argc, char *argv[] ) } break; } } - - mgSync sync; + mgSync *sync = new mgSync; // because we want to delete it before database_end if (create_mode) - sync.Create(); + sync->Create(); if (optind<argc) - sync.Sync(argv+optind,delete_mode); + sync->Sync(argv+optind,delete_mode); + delete sync; + database_end(); return 0; } @@ -10,6 +10,7 @@ */ #include <stdio.h> +#include <assert.h> #include <typeinfo> #include <string> @@ -258,9 +259,9 @@ mgMainMenu::SaveState() nmain.put("CurrentOrder",m_current_order); DumpOrders(nmain); mgValmap nsel("tree"); - m_treesel.DumpState(nsel); + m_treesel->DumpState(nsel); mgValmap ncol("collection"); - m_collectionsel.DumpState(ncol); + m_collectionsel->DumpState(ncol); nmain.Write(f); nsel.Write(f); ncol.Write(f); @@ -311,25 +312,28 @@ mgMainMenu::mgMainMenu ():cOsdMenu ("",25) UsingCollection = nmain.getbool("UsingCollection"); InitMapFromSetup(nsel); InitMapFromSetup(ncol); - m_treesel.setOrder(getOrder(m_current_order)); - m_treesel.InitFrom (nsel); - m_treesel.CreateCollection(default_collection); + m_treesel = new mgSelection; + m_treesel->setOrder(getOrder(m_current_order)); + m_treesel->InitFrom (nsel); + m_treesel->CreateCollection(default_collection); if (default_collection!=play_collection) - m_treesel.CreateCollection(play_collection); + m_treesel->CreateCollection(play_collection); vector<mgKeyTypes> kt; kt.push_back(keyCollection); mgOrder o; o.setKeys(kt); - m_collectionsel.setOrder(&o); - m_collectionsel.InitFrom (ncol); - m_playsel.setOrder(&o); - m_playsel.InitFrom(ncol); + m_collectionsel = new mgSelection; + m_collectionsel->setOrder(&o); + m_collectionsel->InitFrom (ncol); + m_playsel = new mgSelection; + m_playsel->setOrder(&o); + m_playsel->InitFrom(ncol); // initialize - if (m_playsel.level()!=1) + if (m_playsel->level()!=1) { - m_playsel.leave_all(); - m_playsel.enter(play_collection); + m_playsel->leave_all(); + m_playsel->enter(play_collection); } UseNormalSelection (); unsigned int posi = selection()->gotoPosition(); @@ -429,6 +433,9 @@ mgMainMenu::LoadExternalCommands() mgMainMenu::~mgMainMenu() { + delete m_treesel; + delete m_collectionsel; + delete m_playsel; delete m_Status; delete moveselection; delete m_root; @@ -799,9 +806,9 @@ otherkeys: AddMenu (newmenu,newposition); if (UsingCollection) - forcerefresh |= m_collectionsel.cacheIsEmpty(); + forcerefresh |= m_collectionsel->cacheIsEmpty(); else - forcerefresh |= m_treesel.cacheIsEmpty(); + forcerefresh |= m_treesel->cacheIsEmpty(); forcerefresh |= (newposition>=0); @@ -63,9 +63,9 @@ class mgStatus : public cStatus class mgMainMenu:public cOsdMenu { private: - mgSelection m_treesel; - mgSelection m_playsel; - mgSelection m_collectionsel; + mgSelection *m_treesel; + mgSelection *m_playsel; + mgSelection *m_collectionsel; char *m_message; void showMessage(); void LoadExternalCommands(); @@ -202,21 +202,21 @@ class mgMainMenu:public cOsdMenu mgSelection* selection () { if (UsingCollection) - return &m_collectionsel; + return m_collectionsel; else - return &m_treesel; + return m_treesel; } //! \brief the collection selection mgSelection* collselection() { - return &m_collectionsel; + return m_collectionsel; } //! \brief the "now playing" selection mgSelection* playselection () { - return &m_playsel; + return m_playsel; } //! \brief true if the cursor is placed in the collection list |