Subversion Repositories tpanel

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
11 andreas 1
/*
21 andreas 2
 * Copyright (C) 2019 to 2021 by Andreas Theofilu <andreas@theosys.at>
11 andreas 3
 *
4
 * This program is free software; you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program; if not, write to the Free Software Foundation,
16
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
17
 */
18
 
19
#include <chrono>
21 andreas 20
#if __GNUC__ < 9 && !defined(__ANDROID__)
11 andreas 21
   #if __cplusplus < 201703L
22
      #warning "Your C++ compiler seems to have no support for C++17 standard!"
23
   #endif
24
   #include <experimental/filesystem>
25
   namespace fs = std::experimental::filesystem;
26
#else
27
   #include <filesystem>
21 andreas 28
#  ifdef __ANDROID__
29
   namespace fs = std::__fs::filesystem;
30
#  else
11 andreas 31
   namespace fs = std::filesystem;
21 andreas 32
#  endif
11 andreas 33
#endif
34
#include "tconfig.h"
35
#include "terror.h"
36
#include "tdirectory.h"
37
 
38
using namespace std;
39
using namespace dir;
40
using namespace chrono_literals;
41
 
42
int TDirectory::readDir()
43
{
44
	DECL_TRACER("Directory::readDir()");
45
 
46
	if (path.empty())
47
		return 0;
48
 
49
	int count = 0;
50
 
51
	try
52
	{
53
		for(auto& p: fs::directory_iterator(path))
54
		{
55
			DFILES_T dr;
56
			string f = fs::path(p.path()).filename();
57
 
58
			if (f.at(0) == '.')
59
				continue;
60
 
61
			if (path.find("__system/") == string::npos && f.find("__system") != string::npos)
62
				continue;
63
#if __GNUC__ < 9
64
			if (path.find("scripts") != string::npos && fs::is_directory(p.path()))
65
#else
66
			if (path.find("scripts") != string::npos && p.is_directory())
67
#endif
68
				continue;
69
 
70
			count++;
71
			dr.count = count;
72
#if __GNUC__ < 9
73
			time_t ti = fs::last_write_time(p.path()).time_since_epoch().count();
74
#else
75
			time_t ti = p.last_write_time().time_since_epoch().count();
76
#endif
77
			dr.date = (ti / 1000000000) + 6437664000;
78
 
79
#if __GNUC__ < 9
80
			if (fs::is_directory(p.path()))
81
#else
82
			if (p.is_directory())
83
#endif
84
				dr.size = 0;
85
			else
86
#if __GNUC__ < 9
87
				dr.size = fs::file_size(p.path());
88
#else
89
				dr.size = p.file_size();
90
#endif
91
 
92
			if (strip)
93
				dr.name = f;
94
			else
95
				dr.name = p.path();
96
 
97
			dr.attr = 0;
98
 
99
#if __GNUC__ < 9
100
			if (fs::is_directory(p.path()))
101
#else
102
			if (p.is_directory())
103
#endif
104
				dr.attr = dr.attr | ATTR_DIRECTORY;
105
#if __GNUC__ < 9
106
			else if (fs::is_regular_file(p.path()))
107
#else
108
			else if (p.is_regular_file())
109
#endif
110
			{
111
				if (dr.name.find(".png") != string::npos || dr.name.find(".PNG") != string::npos ||
112
						dr.name.find(".jpg") != string::npos || dr.name.find(".JPG") != string::npos)
113
					dr.attr = dr.attr | ATTR_GRAPHIC;
114
				else if (dr.name.find(".wav") != string::npos || dr.name.find(".WAV") != string::npos ||
115
						dr.name.find(".mp3") != string::npos || dr.name.find(".MP3") != string::npos)
116
					dr.attr = dr.attr | ATTR_SOUND;
117
				else
118
					dr.attr = dr.attr | ATTR_TEXT;
119
			}
120
 
121
#if __GNUC__ < 9
122
			if (fs::is_symlink(p.path()))
123
#else
124
			if (p.is_symlink())
125
#endif
126
				dr.attr |= ATTR_LINK;
127
 
128
			entries.push_back(dr);
129
 
23 andreas 130
            if (TStreamError::checkFilter(HLOG_DEBUG))
11 andreas 131
			{
132
				char buf[4096];
133
				char d, g, l;
134
 
135
				d = l = '_';
136
				g = ' ';
137
 
138
				if (dr.attr & ATTR_DIRECTORY)
139
					d = 'D';
140
 
141
				if (dr.attr & ATTR_GRAPHIC)
142
					g = 'g';
143
				else if (dr.attr & ATTR_SOUND)
144
					g = 's';
145
				else if (dr.attr & ATTR_TEXT)
146
					g = 't';
147
 
148
				if (dr.attr & ATTR_LINK)
149
					l = 'L';
150
 
151
				struct tm *t = localtime(&dr.date);
152
 
153
				if (t == nullptr)
154
					snprintf(buf, sizeof(buf), "%c%c%c %8zu 0000-00-00 00:00:00 %s", d, g, l, dr.size, dr.name.c_str());
155
				else
156
					snprintf(buf, sizeof(buf), "%c%c%c %8zu %4d-%02d-%02d %02d:%02d:%02d %s", d, g, l, dr.size, t->tm_year + 1900, t->tm_mon+1, t->tm_mday,
157
                         t->tm_hour, t->tm_min, t->tm_sec, dr.name.c_str());
158
 
159
				MSG_TRACE("Buffer: " << buf);
160
			}
161
		}
162
 
163
		done = true;
164
		MSG_TRACE("Read " << count << " entries.");
165
	}
166
	catch(exception& e)
167
	{
168
		MSG_ERROR("Error: " << e.what());
169
		entries.clear();
170
		return 0;
171
	}
172
 
173
	return count;
174
}
175
 
176
int TDirectory::readDir (const std::string &p)
177
{
178
	DECL_TRACER("Directory::readDir (const std::string &p)");
179
 
180
	path.assign(p);
181
 
182
	if (done)
183
		entries.clear();
184
 
185
	done = false;
186
	return readDir();
187
}
188
 
189
size_t TDirectory::getNumEntries()
190
{
191
	DECL_TRACER("Directory::getNumEntries()");
192
 
193
	if (done)
194
		return entries.size();
195
 
196
	return 0;
197
}
198
 
199
DFILES_T TDirectory::getEntry (size_t pos)
200
{
201
	DECL_TRACER("Directory::getEntry (size_t pos)");
202
 
203
	if (!done || pos >= entries.size())
204
	{
205
		DFILES_T d;
206
		d.attr = 0;
207
		d.count = 0;
208
		d.date = 0;
209
		d.size = 0;
210
		return d;
211
	}
212
 
213
	return entries.at(pos);
214
}
215
 
216
string TDirectory::stripPath (const string &p, size_t idx)
217
{
218
	DECL_TRACER("Directory::stripPath (const string &p, size_t idx)");
219
 
220
	if (!done || idx > entries.size())
221
		return "";
222
 
223
	size_t pos;
224
	DFILES_T dr = getEntry(idx);
225
 
226
	if ((pos = dr.name.find(p)) == string::npos)
227
		return "";
228
 
229
	return dr.name.substr(pos + p.length());
230
}
231
 
232
string TDirectory::stripPath (const string &p, const string &s)
233
{
234
	DECL_TRACER("Directory::stripPath (const string &p, const string &s)");
235
 
236
	size_t pos;
237
 
238
	if ((pos = s.find(p)) == string::npos)
239
		return "";
240
 
241
	return s.substr(pos + p.length());
242
}
243
 
244
size_t TDirectory::getFileSize (const string &f)
245
{
246
	DECL_TRACER("Directory::getFileSize (const string &f)");
247
	size_t s = 0;
248
 
249
	try
250
	{
251
		if (!fs::path(f).has_filename())
252
			return s;
253
 
254
		s = fs::file_size(f);
255
	}
256
	catch(exception& e)
257
	{
258
		MSG_ERROR("Error: " << e.what());
259
		s = 0;
260
	}
261
 
262
	return s;
263
}
264
 
265
bool TDirectory::isFile (const string &f)
266
{
267
	DECL_TRACER("Directory::isFile (const string &f)");
268
 
269
	try
270
	{
271
		return fs::is_regular_file(f);
272
	}
273
	catch(exception& e)
274
	{
275
		MSG_ERROR("Error: " << e.what());
276
	}
277
 
278
	return false;
279
}
280
 
281
bool TDirectory::isDirectory (const string &f)
282
{
283
	DECL_TRACER("Directory::isDirectory (const string &f)");
284
 
285
	try
286
	{
287
		return fs::is_directory(f);
288
	}
289
	catch(exception& e)
290
	{
291
		MSG_ERROR("Error: " << e.what());
292
	}
293
 
294
	return false;
295
}
296
 
297
bool TDirectory::exists (const string &f)
298
{
299
	DECL_TRACER("Directory::exists (const string &f)");
300
 
301
	try
302
	{
303
		return fs::exists(f);
304
	}
305
	catch(exception& e)
306
	{
307
		MSG_ERROR("Error: " << e.what());
308
	}
309
 
310
	return false;
311
}
312
 
313
bool TDirectory::checkDot (const string &s)
314
{
315
	DECL_TRACER("Directory::checkDot (const string &s)");
316
 
317
	size_t pos = s.find_last_of("/");
318
	string f = s;
319
 
320
	if (pos != string::npos)
321
		f = s.substr(pos + 1);
322
 
323
	if (f.at(0) == '.')
324
		return true;
325
 
326
	return false;
327
}