1 |
<?php |
2 |
//------------------------------------------------------------------------------------------------- |
3 |
//$Header$ |
4 |
//------------------------------------------------------------------------------------------------- |
5 |
//This source code and any program in which it is compiled/used is provided under the MIT |
6 |
//LICENSE (full license text below). |
7 |
//------------------------------------------------------------------------------------------------- |
8 |
//Copyright (c) 2016 David T. Ashley |
9 |
// |
10 |
//Permission is hereby granted, free of charge, to any person obtaining a copy of this software and |
11 |
//associated documentation files (the "Software"), to deal in the Software without restriction, |
12 |
//including without limitation the rights to use, copy, modify, merge, publish, distribute, |
13 |
//sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
14 |
//furnished to do so, subject to the following conditions: |
15 |
// |
16 |
//The above copyright notice and this permission notice shall be included in all copies or |
17 |
//substantial portions of the Software. |
18 |
// |
19 |
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT |
20 |
//NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
21 |
//NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
22 |
//DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
23 |
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
24 |
//------------------------------------------------------------------------------------------------- |
25 |
//-------------------------------------------------------------------------------- |
26 |
//C O N F I G U R A T I O N |
27 |
//-------------------------------------------------------------------------------- |
28 |
//Configuration switch combinations were not tested. E-mail me any program |
29 |
//corrections (dashley@gmail.com). |
30 |
define ("CFG_PROGNAME", "indexfile_make.php"); |
31 |
//Program name. |
32 |
define ("CFG_CONSOLE_STD_LINE_LEN", 78); |
33 |
//Number of characters per line preferred for console output. |
34 |
define ("CFG_THUMBNAIL_FILENAME_SUFFIX", "_small"); |
35 |
//String added just before the filename extension to choose thumbnail names |
36 |
//based on name of full-sized image. |
37 |
define ("CFG_INDEXFILE_NAME", "index2.php"); |
38 |
//Name of the file containing the index. PHP code is assumed, but the |
39 |
//file can be harvested for the HTML. |
40 |
define ("CFG_INDEXFILE_PICREF_INDENT", 3); |
41 |
//The number of spaces to indent each reference to a picture. |
42 |
define ("CFG_FILEEXTENSIONS_PHOTO", "jpg/jpeg"); |
43 |
//The file extensions that will be recognized as photos. |
44 |
define ("CFG_FILEEXTENSIONS_LINK", "mov"); |
45 |
//File extensions that will be linked to. All others will be mentioned |
46 |
//in the generated output but not linked to. |
47 |
//-------------------------------------------------------------------------------- |
48 |
//Repeats a character to the console output a certain number of times. |
49 |
function rep_char_con($c, $n) |
50 |
{ |
51 |
while ($n--) |
52 |
echo $c; |
53 |
} |
54 |
//-------------------------------------------------------------------------------- |
55 |
//Writes a standard thick horizontal line to the console. |
56 |
function hor_line_thick() |
57 |
{ |
58 |
rep_char_con("=", CFG_CONSOLE_STD_LINE_LEN); |
59 |
echo "\n"; |
60 |
} |
61 |
//-------------------------------------------------------------------------------- |
62 |
//Writes a standard thin horizontal line to the console. |
63 |
function hor_line_thin() |
64 |
{ |
65 |
rep_char_con("-", CFG_CONSOLE_STD_LINE_LEN); |
66 |
echo "\n"; |
67 |
} |
68 |
//-------------------------------------------------------------------------------- |
69 |
//Returns an array of all files in the working directory. |
70 |
//If no files can be found, returns FALSE. |
71 |
function get_file_names_in_dir() |
72 |
{ |
73 |
//Get directory list. |
74 |
$rv = scandir ("."); |
75 |
|
76 |
//If the list is empty, something went wrong. Return FALSE. |
77 |
if ($rv === FALSE) |
78 |
return FALSE; |
79 |
|
80 |
return $rv; |
81 |
} |
82 |
//-------------------------------------------------------------------------------- |
83 |
//Accepts a non-negative integer as an integer or a string. Adds commas in the |
84 |
//right places to make it more human readable. |
85 |
function int_nonneg_commanate($in_ui) |
86 |
{ |
87 |
//Ensure the integer is an integer from PHP's point of view. |
88 |
$in_ui = (int)$in_ui; |
89 |
|
90 |
//If a negative number was passed in, clip it. |
91 |
if ($in_ui < 0) |
92 |
$in_ui = 0; |
93 |
|
94 |
//Make a proper numerical string with commas out of it. |
95 |
$s_ui = number_format($in_ui); |
96 |
|
97 |
return $s_ui; |
98 |
} |
99 |
//-------------------------------------------------------------------------------- |
100 |
//Returns TRUE if a file name appears to be a valid full-sized image name, |
101 |
//or FALSE otherwise. |
102 |
function is_full_sized_image_file_name($in_filename) |
103 |
{ |
104 |
//Convert the string name to all lower case. This will do for |
105 |
//comparisons and tests. |
106 |
$s = strtolower($s); |
107 |
|
108 |
//Attempt to split the name into a base and an extension. Any failure |
109 |
//means it is an unsuitable name. |
110 |
$extension_start = strrpos($in_filename, "."); |
111 |
//Find position of last "." in string. This should precede the |
112 |
//file extension. |
113 |
|
114 |
if ($extension_start === FALSE) |
115 |
{ |
116 |
//Bad name. Unsuitable. |
117 |
return FALSE; |
118 |
} |
119 |
|
120 |
//Calculate the base and extension. |
121 |
$filename_base = substr($in_filename, 0, $extension_start); |
122 |
$filename_extension = substr($in_filename, $extension_start + 1); |
123 |
|
124 |
//If the extension is neither "jpg" nor "jpeg", it is unsuitable. |
125 |
if (($filename_extension != "jpg") && ($filename_extension != "jpeg")) |
126 |
return FALSE; |
127 |
|
128 |
//If the filename base is empty, the filename is unsuitable. |
129 |
if (strlen($filename_base) == 0) |
130 |
return FALSE; |
131 |
|
132 |
//If the last characters of the base are the CFG_THUMBNAIL_FILENAME_SUFFIX, |
133 |
//the name is unsuitable. |
134 |
if (strlen($filename_base) >= strlen(CFG_THUMBNAIL_FILENAME_SUFFIX)) |
135 |
{ |
136 |
if (substr($filename_base, strlen($filename_base) - strlen(CFG_THUMBNAIL_FILENAME_SUFFIX)) |
137 |
== CFG_THUMBNAIL_FILENAME_SUFFIX) |
138 |
return FALSE; |
139 |
} |
140 |
|
141 |
//Looks good. |
142 |
return TRUE; |
143 |
} |
144 |
//-------------------------------------------------------------------------------- |
145 |
//As a function of the file name, creates the file name for the thumbnail. |
146 |
function file_name_to_thumbnail_name($in_filename) |
147 |
{ |
148 |
$extension_start = strrpos($in_filename, "."); |
149 |
//Find position of last "." in string. This should precede the |
150 |
//file extension. |
151 |
if ($extension_start === FALSE) |
152 |
{ |
153 |
//"." not found. Should not happen. Filenames were checked in advance. |
154 |
echo "Fatal internal error at line " . __LINE__ . "\n"; |
155 |
exit(1); |
156 |
} |
157 |
|
158 |
$filename_prefix = substr($in_filename, 0, $extension_start); |
159 |
$filename_extension = substr($in_filename, $extension_start); |
160 |
|
161 |
$rv = $filename_prefix . CFG_THUMBNAIL_FILENAME_SUFFIX . $filename_extension; |
162 |
|
163 |
return $rv; |
164 |
} |
165 |
//-------------------------------------------------------------------------------- |
166 |
//Writes the index file preamble to the index file. This is very much |
167 |
//dependent on how the thumbnails will be used. This is currently customized |
168 |
//for what Dave Ashley does. |
169 |
function write_index_file_preamble($handle, $idstring) |
170 |
{ |
171 |
fwrite($handle, "<" . "?" . "php\n"); |
172 |
fwrite($handle, "require_once(\"style/std/stdwpstyle.inc\");\n"); |
173 |
fwrite($handle, "?" . ">" . "\n"); |
174 |
fwrite($handle, "<" . "?" . "php\n"); |
175 |
fwrite($handle, " $" . "thispage = new StdWpStyle();\n"); |
176 |
fwrite($handle, "\n"); |
177 |
fwrite($handle, " $" . "thispage->static_page_header_title_std(\"" . $idstring . "\",\n"); |
178 |
fwrite($handle, " \"" . $idstring . "\",\n"); |
179 |
fwrite($handle, " \"\");\n"); |
180 |
fwrite($handle, " $" . "thispage->static_page_photo_thumbnail_explanation(TRUE, TRUE);\n"); |
181 |
fwrite($handle, "?" . ">" . "\n"); |
182 |
for ($i = 0; $i < CFG_INDEX_PARAGRAPH_INDENT; $i++) |
183 |
{ |
184 |
fwrite($handle, " "); |
185 |
} |
186 |
fwrite($handle, "\n<p align=\"center\">\n"); |
187 |
} |
188 |
//-------------------------------------------------------------------------------- |
189 |
//Writes the index file postamble to the index file. This is very much |
190 |
//dependent on how the thumbnails will be used. This is currently customized |
191 |
//for what Dave Ashley does. |
192 |
function write_index_file_postamble($handle) |
193 |
{ |
194 |
for ($i = 0; $i < CFG_INDEX_PARAGRAPH_INDENT; $i++) |
195 |
{ |
196 |
fwrite($handle, " "); |
197 |
} |
198 |
fwrite($handle, "</p>\n\n"); |
199 |
fwrite($handle, "<" . "?" . "php\n"); |
200 |
fwrite($handle, " $" . "thispage->static_page_footer_std();\n"); |
201 |
fwrite($handle, "?" . ">" . "\n"); |
202 |
} |
203 |
//-------------------------------------------------------------------------------- |
204 |
//Writes a line to the index file corresponding to a linked larger picture |
205 |
//reprsented by a thumbnail. |
206 |
function write_index_line( $handle, |
207 |
$filename, |
208 |
$thumbnailname, |
209 |
$filename_filesize, |
210 |
$filename_xdim, |
211 |
$filename_ydim, |
212 |
$thumbnailname_filesize, |
213 |
$thumbnailname_xdim, |
214 |
$thumbnailname_ydim) |
215 |
{ |
216 |
//<a href="dscn1258.jpg"><img border="0" src="dscn1258_small.jpg" alt="dscn1258.jpg (4932338 bytes)" width="125" height="93"></a> |
217 |
//Indent. |
218 |
for ($i = 0; $i < CFG_INDEX_LINK_INDENT; $i++) |
219 |
{ |
220 |
fwrite($handle, " "); |
221 |
} |
222 |
|
223 |
fwrite($handle, "<a href=\""); |
224 |
fwrite($handle, $filename); |
225 |
fwrite($handle, "\"><img border=\"0\" src=\""); |
226 |
fwrite($handle, $thumbnailname); |
227 |
fwrite($handle, "\" alt=\""); |
228 |
fwrite($handle, $filename); |
229 |
fwrite($handle, " ("); |
230 |
fwrite($handle, int_nonneg_commanate($filename_filesize)); |
231 |
fwrite($handle, " bytes)\" "); |
232 |
fwrite($handle, "title=\""); |
233 |
fwrite($handle, $filename); |
234 |
fwrite($handle, " ("); |
235 |
fwrite($handle, int_nonneg_commanate($filename_filesize)); |
236 |
fwrite($handle, " bytes)\" width=\""); |
237 |
fwrite($handle, $thumbnailname_xdim); |
238 |
fwrite($handle, "\" height=\""); |
239 |
fwrite($handle, $thumbnailname_ydim); |
240 |
fwrite($handle, "\"></a>"); |
241 |
fwrite($handle, "\n"); |
242 |
} |
243 |
//-------------------------------------------------------------------------------- |
244 |
//Write introductory message. |
245 |
hor_line_thick(); |
246 |
echo CFG_PROGNAME . " Copyright (C) 2015 David T. Ashley\n"; |
247 |
echo "This program comes with ABSOLUTELY NO WARRANTY; and is licensed under\n"; |
248 |
echo "the GNU General Public License, Version 3. A copy of this license is\n"; |
249 |
echo "provided in the source code of this program.\n"; |
250 |
hor_line_thin(); |
251 |
//----------------------------------------------------------------------------- |
252 |
//Get the date, time, and PID strings that will be used for the rest of the |
253 |
//script. |
254 |
$scr_datestring = date("Ymd_His"); |
255 |
$scr_pid = getmypid(); |
256 |
if ($scr_pid === FALSE) |
257 |
$scr_pid = 0; |
258 |
//----------------------------------------------------------------------------- |
259 |
//If the index file exists, rename it out of the way. This is to prevent |
260 |
//the loss of information. |
261 |
if (file_exists(CFG_INDEXFILE_NAME)) |
262 |
{ |
263 |
rename(CFG_INDEXFILE_NAME, $scr_datestring . "_" . $scr_pid . ".php"); |
264 |
} |
265 |
//----------------------------------------------------------------------------- |
266 |
//Open the index file and write the preamble. |
267 |
$indexfile_handle = fopen(CFG_INDEXFILE_NAME, "w"); |
268 |
if ($indexfile_handle === FALSE) |
269 |
{ |
270 |
echo "FATAL: unable to open index file.\n"; |
271 |
exit(1); |
272 |
} |
273 |
write_index_file_preamble($indexfile_handle, $scr_datestring . "_" . $scr_pid); |
274 |
//----------------------------------------------------------------------------- |
275 |
//Get and emit the names of everything in the directory. |
276 |
$file_list = get_file_names_in_dir(); |
277 |
if ($file_list === FALSE) |
278 |
{ |
279 |
echo "List of files from PHP function scandir() is empty.\n"; |
280 |
echo "Serious internal error, or nothing to do. Script cannot continue.\n"; |
281 |
hor_line_thick(); |
282 |
exit(1); |
283 |
} |
284 |
else |
285 |
{ |
286 |
echo "Files in working directory (unsorted, unfiltered, " |
287 |
. |
288 |
count($file_list) |
289 |
. |
290 |
" files):\n"; |
291 |
for ($i = 0; $i < count($file_list); $i++) |
292 |
echo " " . sprintf("[%5d]", $i) . " " . $file_list[$i] . "\n"; |
293 |
} |
294 |
hor_line_thin(); |
295 |
//----------------------------------------------------------------------------- |
296 |
//Remove the standard directory entries "." and ".." from the list, and |
297 |
//remove any directories. |
298 |
$temp_list = $file_list; |
299 |
unset($file_list); |
300 |
$n = 0; |
301 |
for ($i = 0; $i < count($temp_list); $i++) |
302 |
{ |
303 |
//echo "Checking " . $temp_list[$i] . "\n"; |
304 |
|
305 |
if (strcmp($temp_list[$i], ".") == 0) |
306 |
{ |
307 |
//. entry, not a file. |
308 |
} |
309 |
else if (strcmp($temp_list[$i], "..") == 0) |
310 |
{ |
311 |
//.. entry, not a file. |
312 |
} |
313 |
else if (is_file($temp_list[$i])) |
314 |
{ |
315 |
//This is a regular file. |
316 |
$file_list[] = $temp_list[$i]; |
317 |
$n++; |
318 |
} |
319 |
} |
320 |
|
321 |
if ($n == 0) |
322 |
$file_list = FALSE; |
323 |
|
324 |
unset($n); |
325 |
unset($temp_list); |
326 |
//----------------------------------------------------------------------------- |
327 |
//If there is nothing to do, end the script. |
328 |
if ($file_list === FALSE) |
329 |
{ |
330 |
echo "No files to process.\n"; |
331 |
hor_line_thick(); |
332 |
exit(0); |
333 |
} |
334 |
//----------------------------------------------------------------------------- |
335 |
//Sort the list. This is a non-event. The only rationale for sorting is that |
336 |
//it ensures that the same set of files will be processed in the same order, |
337 |
//regardless of the order provided by the underlying OS internals. |
338 |
sort($file_list); |
339 |
//----------------------------------------------------------------------------- |
340 |
//Emit the names we now have. |
341 |
echo "Files in working directory (directory entries removed, sorted, " |
342 |
. |
343 |
count($file_list) |
344 |
. |
345 |
" files):\n"; |
346 |
for ($i = 0; $i < count($file_list); $i++) |
347 |
echo " " . sprintf("[%5d]", $i) . " " . $file_list[$i] . "\n"; |
348 |
hor_line_thin(); |
349 |
|
350 |
//----------------------------------------------------------------------------- |
351 |
//For each file in the list, process it. There are different processing |
352 |
//actions for each one. |
353 |
for ($i = 0; $i < count($file_list); $i++) |
354 |
{ |
355 |
if (is_full_sized_image_file_name($file_list[$i])) |
356 |
{ |
357 |
$thumbnail_name = file_name_to_thumbnail_name($file_list[$i]); |
358 |
|
359 |
$image_data = getimagesize($file_list[$i]); |
360 |
$thumbnail_data = getimagesize($thumbnail_name); |
361 |
|
362 |
write_index_line( $indexfile_handle, |
363 |
$file_list[$i], |
364 |
$thumbnail_name, |
365 |
filesize($file_list[$i]), |
366 |
$image_data[0], |
367 |
$image_data[1], |
368 |
filesize($thumbnail_name), |
369 |
$thumbnail_data[0], |
370 |
$thumbnail_data[1]); |
371 |
|
372 |
} |
373 |
} |
374 |
|
375 |
//----------------------------------------------------------------------------- |
376 |
//Complete and close up the index file. |
377 |
write_index_file_postamble($indexfile_handle); |
378 |
fclose($indexfile_handle); |
379 |
|
380 |
// $i = 0; |
381 |
// $completed = 0; |
382 |
// while (($completed < CFG_MAX_THUMBNAILS_PER_INVOCATION) && ($i < count($file_list))) |
383 |
// { |
384 |
// if (is_full_sized_image_file_name($file_list[$i])) |
385 |
// { |
386 |
// $thumbnail_name = file_name_to_thumbnail_name($file_list[$i]); |
387 |
// |
388 |
// if (file_exists($thumbnail_name)) |
389 |
// { |
390 |
// echo " " . sprintf("[%5d]", $i) . " " . $file_list[$i] . " : skipping because corresponding thumbnail exists.\n"; |
391 |
// hor_line_thin(); |
392 |
// } |
393 |
// else |
394 |
// { |
395 |
// echo " " . sprintf("[%5d]", $i) . " " . $file_list[$i] . " : creating thumbnail.\n"; |
396 |
// |
397 |
// echo "Creating thumbnail \"" . |
398 |
// $thumbnail_name . |
399 |
// "\" from image \"" . |
400 |
// $file_list[$i] . |
401 |
// "\".\n"; |
402 |
// |
403 |
// create_thumbnail($file_list[$i], |
404 |
// $thumbnail_name, |
405 |
// $filename_filesize, |
406 |
// $filename_xdim, |
407 |
// $filename_ydim, |
408 |
// $thumbnail_filesize, |
409 |
// $thumbnail_xdim, |
410 |
// $thumbnail_ydim); |
411 |
// |
412 |
// echo "Conversion complete.\n"; |
413 |
// echo " Full-sized image file size/xdim/ydim = " . |
414 |
// $filename_filesize . "/" . $filename_xdim . "/" . $filename_ydim . |
415 |
// ",\n"; |
416 |
// echo " Thumbnail image filesize/xdim/ydim = " . |
417 |
// $thumbnail_filesize . "/" . $thumbnail_xdim . "/" . $thumbnail_ydim . |
418 |
// ",\n"; |
419 |
// |
420 |
// hor_line_thin(); |
421 |
// $completed++; |
422 |
// } |
423 |
// } |
424 |
// else |
425 |
// { |
426 |
// //Unsuitable base name. Can't use it. |
427 |
// echo " " . sprintf("[%5d]", $i) . " " . $file_list[$i] . " : skipping due to unsuitable name.\n"; |
428 |
// hor_line_thin(); |
429 |
// } |
430 |
// |
431 |
// $i++; |
432 |
// } |
433 |
// |
434 |
// //Emit a message about whether the program should be run again. I am aware of |
435 |
// //the uncovered case--where the last thumbnail was made on the last iteration |
436 |
// //of this invocation--but I will leave it uncovered for now. All that happens |
437 |
// //is the user runs the program unnecessarily one more time. |
438 |
// if ($completed == 0) |
439 |
// { |
440 |
// echo "No thumbnails were created--this program is done creating thumbnails.\n"; |
441 |
// echo "It is not necessary to run this program again.\n"; |
442 |
// hor_line_thin(); |
443 |
// } |
444 |
// else |
445 |
// { |
446 |
// echo $completed . " thumbnail(s) were created. Please run this program repeatedly again\n"; |
447 |
// echo "until no more thumbnails are created.\n"; |
448 |
// hor_line_thin(); |
449 |
// } |
450 |
//-------------------------------------------------------------------------------- |
451 |
echo CFG_PROGNAME . " execution ends.\n"; |
452 |
hor_line_thick(); |
453 |
//-------------------------------------------------------------------------------- |
454 |
//End of File |
455 |
//-------------------------------------------------------------------------------- |
456 |
?> |