root/trunk/src/core/src/helpers/filesystem.cpp @ 2253

Revision 2253, 14.4 KB (checked in by jeremyz, 23 months ago)

Filesystem: drumkit_path=>drumkit_path_search, drumkit_location=>drumkit_dir_search + fix comments

Line 
1
2#include <hydrogen/config.h>
3#include <hydrogen/helpers/filesystem.h>
4
5#include <QtCore/QDir>
6#include <QtCore/QFile>
7#include <QtCore/QFileInfo>
8#include <QtCore/QCoreApplication>
9
10// directories
11#define LOCAL_DATA_PATH "/data"
12#define IMG             "/img"
13#define DOC             "/doc"
14#define I18N            "/i18n"
15#define SONGS           "/songs"
16#define PATTERNS        "/patterns"
17#define DRUMKITS        "/drumkits"
18#define PLAYLISTS       "/playlists"
19#define DEMOS           "/demo_songs"
20#define XSD             "/xsd"
21
22// files
23#define GUI_CONFIG      "/gui.conf"
24#define CORE_CONFIG     "/core.conf"
25#define CLICK_SAMPLE    "/click.wav"
26#define EMPTY_SAMPLE    "/emptySample.wav"
27#define EMPTY_SONG      "/DefaultSong.h2song"
28
29// filters
30#define SONG_FILTER     "*.h2song"
31#define PATTERN_FILTER  "*.h2pattern"
32#define DRUMKIT_XML     "drumkit.xml"
33#define DRUMKIT_XSD     "drumkit.xsd"
34#define PATTERN_XSD     "pattern.xsd"
35
36namespace H2Core {
37
38Logger* Filesystem::__logger = 0;
39const char* Filesystem::__class_name = "Filesystem";
40QString Filesystem::__sys_data_path;
41QString Filesystem::__usr_data_path;
42
43/* TODO QCoreApplication is not instanciated */
44bool Filesystem::bootstrap( Logger* logger ) {
45    if( __logger==0 && logger!=0 ) {
46        __logger = logger;
47    } else {
48        return false;
49    }
50
51#ifdef Q_OS_MACX
52#ifdef H2CORE_HAVE_BUNDLE
53    //Bundle: Prepare hydrogen to use path names which are used in app bundles: http://en.wikipedia.org/wiki/Application_Bundle
54    __sys_data_path = QCoreApplication::applicationDirPath().append( "/../Resources/data" ) ;
55#else
56    __sys_data_path = QCoreApplication::applicationDirPath().append( "/data" ) ;
57#endif
58    __usr_data_path = QDir::homePath().append( "/Library/Application Support/Hydrogen" );
59#elif WIN32
60    __sys_data_path = QCoreApplication::applicationDirPath().append( "/data" ) ;
61    __usr_data_path = QCoreApplication::applicationDirPath().append( "/hydrogen/data" ) ;
62#else
63    __sys_data_path = SYS_DATA_PATH;
64    __usr_data_path = QDir::homePath().append( "/"USR_DATA_PATH );
65#endif
66
67    if( !dir_readable( __sys_data_path ) ) {
68        __sys_data_path = QCoreApplication::applicationDirPath().append( LOCAL_DATA_PATH );
69        ERRORLOG( QString("will use local data path : %1").arg(__sys_data_path));
70    }
71    return check_sys_paths() && check_usr_paths();
72}
73
74bool Filesystem::check_permissions( const QString& path, const int perms, bool silent ) {
75    QFileInfo fi( path );
76    if( ( perms & is_file ) && ( perms & is_writable ) && !fi.exists() ) {
77        QFileInfo folder( path.left( path.lastIndexOf( "/" ) ) );
78        if( !folder.isDir() ) {
79            if( !silent ) ERRORLOG( QString( "%1 is not a directory" ).arg( folder.fileName() ) );
80            return false;
81        }
82        if( !folder.isWritable() ) {
83            if( !silent ) ERRORLOG( QString( "%1 is not writable" ).arg( folder.fileName() ) );
84            return false;
85        }
86        return true;
87    }
88    if( ( perms & is_dir ) && !fi.isDir() ) {
89        if( !silent ) ERRORLOG( QString( "%1 is not a directory" ).arg( path ) );
90        return false;
91    }
92    if( ( perms & is_file ) && !fi.isFile() ) {
93        if( !silent ) ERRORLOG( QString( "%1 is not a file" ).arg( path ) );
94        return false;
95    }
96    if( ( perms & is_readable ) && !fi.isReadable() ) {
97        if( !silent ) ERRORLOG( QString( "%1 is not readable" ).arg( path ) );
98        return false;
99    }
100    if( ( perms & is_writable ) && !fi.isWritable() ) {
101        if( !silent ) ERRORLOG( QString( "%1 is not writable" ).arg( path ) );
102        return false;
103    }
104    if( ( perms & is_executable ) && !fi.isExecutable() ) {
105        if( !silent ) ERRORLOG( QString( "%1 is not executable" ).arg( path ) );
106        return false;
107    }
108    return true;
109}
110
111bool Filesystem::file_exists( const QString& path, bool silent ) {
112    return check_permissions( path, is_file, silent );
113}
114bool Filesystem::file_readable( const QString& path, bool silent ) {
115    return check_permissions( path, is_file|is_readable, silent );
116}
117bool Filesystem::file_writable( const QString& path, bool silent ) {
118    return check_permissions( path, is_file|is_writable, silent );
119}
120bool Filesystem::file_executable( const QString& path, bool silent ) {
121    return check_permissions( path, is_file|is_executable, silent );
122}
123bool Filesystem::dir_readable(  const QString& path, bool silent ) {
124    return check_permissions( path, is_dir|is_readable|is_executable, silent );
125}
126bool Filesystem::dir_writable(  const QString& path, bool silent ) {
127    return check_permissions( path, is_dir|is_writable, silent );
128}
129
130bool Filesystem::mkdir( const QString& path ) {
131    if ( !QDir( "/" ).mkpath( QDir( path ).absolutePath() ) ) {
132        ERRORLOG( QString( "unable to create directory : %1" ).arg( path ) );
133        return false;
134    }
135    return true;
136}
137
138bool Filesystem::path_usable( const QString& path, bool create, bool silent ) {
139    if( !QDir( path ).exists() ) {
140        if( !silent ) INFOLOG( QString( "create user directory : %1" ).arg( path ) );
141        if( create && !QDir( "/" ).mkpath( path ) ) {
142            if( !silent ) ERRORLOG( QString( "unable to create user directory : %1" ).arg( path ) );
143            return false;
144        }
145    }
146    return dir_readable( path, silent ) && dir_writable( path, silent );
147}
148
149bool Filesystem::write_to_file( const QString& dst, const QString& content ) {
150    if ( !file_writable( dst ) ) {
151        ERRORLOG( QString( "unable to write to %1" ).arg( dst ) );
152        return false;
153    }
154    QFile file( dst );
155    if ( !file.open( QIODevice::WriteOnly ) ) {
156        ERRORLOG( QString( "unable to write to %1" ).arg( dst ) );
157        return false;
158    }
159    file.write( content.toUtf8().data() );
160    file.close();
161}
162
163bool Filesystem::file_copy( const QString& src, const QString& dst, bool overwrite ) {
164    if( file_exists( dst, true ) && !overwrite ) {
165        WARNINGLOG( QString( "do not overwrite %1 with %2 has it already exists" ).arg( dst ).arg( src ) );
166        return true;
167    }
168    if ( !file_readable( src ) ) {
169        ERRORLOG( QString( "unable to copy %1 to %2, %1 is not readable" ).arg( src ).arg( dst ) );
170        return false;
171    }
172    if ( !file_writable( dst ) ) {
173        ERRORLOG( QString( "unable to copy %1 to %2, %2 is not writable" ).arg( src ).arg( dst ) );
174        return false;
175    }
176    INFOLOG( QString( "copy %1 to %2" ).arg( src ).arg( dst ) );
177    return QFile::copy( src,dst );
178}
179
180bool Filesystem::rm( const QString& path, bool recursive ) {
181    if ( check_permissions( path, is_file, true ) ) {
182        QFile file( path );
183        bool ret = file.remove();
184        if( !ret ) {
185            ERRORLOG( QString( "unable to remove file %1" ).arg( path ) );
186        }
187        return ret;
188    }
189    if ( !check_permissions( path, is_dir, true )  ) {
190        ERRORLOG( QString( "%1 is neither a file nor a directory ?!?!" ).arg( path ) );
191        return false;
192    }
193    if ( !recursive ) {
194        ERRORLOG( QString( "unable to remove directory %1 without recursive parameter set to true" ).arg( path ) );
195        return false;
196    }
197    return rm_fr( path );
198}
199
200bool Filesystem::rm_fr( const QString& path ) {
201    bool ret = true;
202    QDir dir( path );
203    QFileInfoList entries = dir.entryInfoList( QDir::NoDotAndDotDot | QDir::AllEntries );
204    for ( int idx = 0; ( ( idx < entries.size() ) && ret ); idx++ ) {
205        QFileInfo entryInfo = entries[idx];
206        if ( entryInfo.isDir() && !entryInfo.isSymLink() ) {
207            ret = rm_fr( entryInfo.absoluteFilePath() );
208        } else {
209            QFile file( entryInfo.absoluteFilePath() );
210            if ( !file.remove() ) {
211                ERRORLOG( QString( "unable to remove %1" ).arg( entryInfo.absoluteFilePath() ) );
212                ret = false;
213            }
214        }
215    }
216    if ( !dir.rmdir( dir.absolutePath() ) ) {
217        ERRORLOG( QString( "unable to remove %1" ).arg( dir.absolutePath() ) );
218        ret = false;
219    }
220    return ret;
221}
222
223bool Filesystem::check_sys_paths() {
224    if(  !dir_readable( __sys_data_path ) ) return false;
225    if(  !dir_readable( img_dir() ) ) return false;
226    if(  !dir_readable( xsd_dir() ) ) return false;
227    if(  !dir_readable( doc_dir() ) ) return false;
228    if(  !dir_readable( i18n_dir() ) ) return false;
229    if(  !dir_readable( demos_dir() ) ) return false;
230    if( !file_readable( click_file() ) ) return false;
231    if( !file_readable( empty_song() ) ) return false;
232    if( !file_readable( empty_sample() ) ) return false;
233    if( !file_readable( sys_gui_config() ) ) return false;
234    if( !file_readable( sys_core_config() ) ) return false;
235    if(  !dir_readable( sys_drumkits_dir() ) ) return false;
236    if( !file_readable( drumkit_xsd() ) ) return false;
237    if( !file_readable( pattern_xsd() ) ) return false;
238    INFOLOG( QString( "system wide data path %1 is usable." ).arg( __sys_data_path ) );
239    return true;
240}
241
242
243bool Filesystem::check_usr_paths() {
244    if( !path_usable( __usr_data_path ) ) return false;
245    if( !path_usable( songs_dir() ) ) return false;
246    if( !path_usable( patterns_dir() ) ) return false;
247    if( !path_usable( playlists_dir() ) ) return false;
248    if( !path_usable( usr_drumkits_dir() ) ) return false;
249    INFOLOG( QString( "user path %1 is usable." ).arg( __usr_data_path ) );
250    return true;
251}
252
253QString Filesystem::sys_data_path() {
254    return __sys_data_path;
255}
256QString Filesystem::usr_data_path() {
257    return __usr_data_path;
258}
259
260// FILES
261QString Filesystem::sys_core_config() {
262    return __sys_data_path + CORE_CONFIG;
263}
264QString Filesystem::usr_core_config() {
265    return __usr_data_path + CORE_CONFIG;
266}
267QString Filesystem::sys_gui_config() {
268    return __sys_data_path + GUI_CONFIG;
269}
270QString Filesystem::usr_gui_config() {
271    return __usr_data_path + GUI_CONFIG;
272}
273QString Filesystem::empty_sample() {
274    return __sys_data_path + EMPTY_SAMPLE;
275}
276QString Filesystem::empty_song() {
277    return __sys_data_path + EMPTY_SONG;
278}
279QString Filesystem::click_file() {
280    return __sys_data_path + CLICK_SAMPLE;
281}
282QString Filesystem::usr_click_file() {
283    if( file_readable( __usr_data_path + CLICK_SAMPLE, true ) ) return __usr_data_path + CLICK_SAMPLE;
284    return click_file();
285}
286QString Filesystem::drumkit_xsd( ) {
287    return xsd_dir() + "/" + DRUMKIT_XSD;
288}
289QString Filesystem::pattern_xsd( ) {
290    return xsd_dir() + "/" + PATTERN_XSD;
291}
292
293// DIRS
294QString Filesystem::img_dir() {
295    return __sys_data_path + IMG;
296}
297QString Filesystem::doc_dir() {
298    return __sys_data_path + DOC;
299}
300QString Filesystem::i18n_dir() {
301    return __sys_data_path + I18N;
302}
303QString Filesystem::songs_dir() {
304    return __usr_data_path + SONGS;
305}
306QString Filesystem::patterns_dir() {
307    return __usr_data_path + PATTERNS;
308}
309QString Filesystem::sys_drumkits_dir() {
310    return __sys_data_path + DRUMKITS;
311}
312QString Filesystem::usr_drumkits_dir() {
313    return __usr_data_path + DRUMKITS;
314}
315QString Filesystem::playlists_dir() {
316    return __usr_data_path + PLAYLISTS;
317}
318QString Filesystem::demos_dir() {
319    return __sys_data_path + DEMOS;
320}
321QString Filesystem::xsd_dir() {
322    return __sys_data_path + XSD;
323}
324
325// DRUMKITS
326QStringList Filesystem::drumkits_list( const QString& path ) {
327    QStringList ok;
328    QStringList possible = QDir( path ).entryList( QDir::Dirs | QDir::NoDotAndDotDot );
329    for( int i=0; i<possible.size(); i++ ) {
330        if ( file_readable( path+"/"+possible[i]+"/"+DRUMKIT_XML, true ) )
331            ok << possible[i];
332        else {
333            ERRORLOG( QString( "drumkit %1 is not usable" ).arg( path+"/"+possible[i] ) );
334        }
335    }
336    return ok;
337}
338QStringList Filesystem::sys_drumkits_list( ) {
339    return drumkits_list( sys_drumkits_dir() ) ;
340}
341QStringList Filesystem::usr_drumkits_list( ) {
342    return drumkits_list( usr_drumkits_dir() ) ;
343}
344bool Filesystem::drumkit_exists( const QString& dk_name ) {
345    if( usr_drumkits_list().contains( dk_name ) ) return true;
346    return sys_drumkits_list().contains( dk_name );
347}
348QString Filesystem::drumkit_path_search( const QString& dk_name ) {
349    if( usr_drumkits_list().contains( dk_name ) ) return usr_drumkits_dir() + "/" + dk_name;
350    if( sys_drumkits_list().contains( dk_name ) ) return sys_drumkits_dir() + "/" + dk_name;
351    ERRORLOG( QString( "drumkit %1 not found" ).arg( dk_name ) );
352    return "";
353}
354QString Filesystem::drumkit_dir_search( const QString& dk_name ) {
355    if( usr_drumkits_list().contains( dk_name ) ) return usr_drumkits_dir();
356    if( sys_drumkits_list().contains( dk_name ) ) return sys_drumkits_dir();
357    ERRORLOG( QString( "drumkit %1 not found" ).arg( dk_name ) );
358    return "";
359}
360bool Filesystem::drumkit_valid( const QString& dk_path ) {
361    return file_readable( dk_path + "/" + DRUMKIT_XML );
362}
363QString Filesystem::drumkit_file( const QString& dk_path ) {
364    return dk_path + "/" + DRUMKIT_XML;
365}
366
367// PATTERNS
368QStringList Filesystem::patterns_list( ) {
369    return QDir( patterns_dir() ).entryList( QStringList( PATTERN_FILTER ), QDir::Files | QDir::NoDotAndDotDot );
370}
371
372// SONGS
373QStringList Filesystem::songs_list( ) {
374    return QDir( songs_dir() ).entryList( QStringList( SONG_FILTER ), QDir::Files | QDir::NoDotAndDotDot );
375}
376bool Filesystem::song_exists( const QString& sg_name ) {
377    return QDir( songs_dir() ).exists( sg_name );
378}
379
380void Filesystem::info() {
381    INFOLOG( QString( "Images dir                 : %1" ).arg( img_dir() ) );
382    INFOLOG( QString( "Documentation dir          : %1" ).arg( doc_dir() ) );
383    INFOLOG( QString( "Internationalization dir   : %1" ).arg( i18n_dir() ) );
384    INFOLOG( QString( "Demos dir                  : %1" ).arg( demos_dir() ) );
385    INFOLOG( QString( "XSD dir                    : %1" ).arg( xsd_dir() ) );
386    INFOLOG( QString( "System drumkit dir         : %1" ).arg( sys_drumkits_dir() ) );
387    INFOLOG( QString( "System wide core cfg file  : %1" ).arg( sys_core_config() ) );
388    INFOLOG( QString( "System wide gui cfg file   : %1" ).arg( sys_gui_config() ) );
389    INFOLOG( QString( "Empty sample               : %1" ).arg( empty_sample() ) );
390    INFOLOG( QString( "Empty song                 : %1" ).arg( empty_song() ) );
391    INFOLOG( QString( "Click file                 : %1" ).arg( click_file() ) );
392    INFOLOG( QString( "User drumkit dir           : %1" ).arg( usr_drumkits_dir() ) );
393    INFOLOG( QString( "Songs dir                  : %1" ).arg( songs_dir() ) );
394    INFOLOG( QString( "Patterns dir               : %1" ).arg( patterns_dir() ) );
395    INFOLOG( QString( "Playlists dir              : %1" ).arg( playlists_dir() ) );
396    INFOLOG( QString( "User core cfg file         : %1" ).arg( usr_core_config() ) );
397    INFOLOG( QString( "User gui cfg file          : %1" ).arg( usr_gui_config() ) );
398}
399
400};
401
402/* vim: set softtabstop=4 expandtab: */
Note: See TracBrowser for help on using the browser.