1 /*
2  * Copyright (c) 2003, 2004 Sasha Vasko <sasha@aftercode.net>
3  *
4  * This module 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 2 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
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  *
18  */
19 
20 /*#define DO_CLOCKING      */
21 #define LOCAL_DEBUG
22 #define EVENT_TRACE
23 
24 #include "../../configure.h"
25 #include "../../libAfterStep/asapp.h"
26 #include <unistd.h>
27 #include "../../libAfterStep/screen.h"
28 #include "../../libAfterStep/module.h"
29 #include "../../libAfterStep/aswindata.h"
30 #include "../../libAfterStep/event.h"
31 #include "../../libAfterStep/wmprops.h"
32 #include "../../libAfterStep/parser.h"
33 #include "../../libAfterConf/afterconf.h"
34 
35 #include "ASDocGen.h"
36 #include "xmlproc.h"
37 #include "docfile.h"
38 #include "datadoc.h"
39 
40 /* <li><b><A href="graphics.php?inc=icons/normal/index">normal</A></b></li> */
41 
42 typedef struct ASData2xmlState
43 {
44 	ASFlagType flags ;
45 
46 	xml_elem_t* doc ;
47 	xml_elem_t* curr_section ;
48 
49 }ASData2xmlState;
50 
51 
52 
53 xml_elem_t*
add_tag(xml_elem_t * owner,const char * tag_str,int tag_id)54 add_tag( xml_elem_t* owner, const char *tag_str, int tag_id )
55 {
56 	xml_elem_t* t = xml_elem_new() ;
57 	t->tag = mystrdup( tag_str );
58 	t->tag_id = tag_id ;
59 	LOCAL_DEBUG_OUT( "tag = \"%s\", tag_id = %d", t->tag, t->tag_id );
60 	if( owner != NULL )
61 		xml_insert(owner, t);
62 	LOCAL_DEBUG_OUT( "added to owner = %p", owner );
63 	return t;
64 }
65 
66 #define ADD_TAG(o,t)    add_tag( o, #t, DOCBOOK_##t##_ID)
67 
68 xml_elem_t*
add_data_section_header2xml(ASData2xmlState * xml_state,const char * id)69 add_data_section_header2xml( ASData2xmlState *xml_state, const char *id )
70 {
71 	xml_elem_t* sect = NULL;
72 	xml_elem_t* title = NULL ;
73 
74 	LOCAL_DEBUG_OUT("id = \"%s\", owner = %p, owner->child = %p", id, xml_state->doc, xml_state->doc->child );
75 
76 	sect = ADD_TAG(xml_state->doc,section);
77 
78 	LOCAL_DEBUG_OUT("section=%p", sect );
79 
80 	sect->parm = safemalloc( 4+strlen(id)+32+1 );
81 	sprintf(sect->parm, "id=\"%s\"", id );
82 
83 	LOCAL_DEBUG_OUT("parm = \"%s\"", sect->parm?sect->parm:"(NULL)" );
84 
85 	xml_state->curr_section = sect ;
86 
87 	if( strlen(id) > 0 )
88 	{
89 		title = ADD_TAG(sect,title);
90 		append_CDATA_line( title, id, strlen(id) );
91 		LOCAL_DEBUG_OUT("title = %p", title );
92 	}
93 
94 	return sect;
95 }
96 
97 xml_elem_t*
add_file_info_li(xml_elem_t * varlist,const char * term)98 add_file_info_li( xml_elem_t* varlist, const char *term)
99 {
100 	xml_elem_t* entry ;
101 	xml_elem_t* entry_term ;
102 	xml_elem_t* entry_li ;
103 
104 	entry = ADD_TAG(varlist,varlistentry);
105 	entry_term = ADD_TAG(entry,term);
106 	append_CDATA_line( entry_term, term, strlen(term) );
107 	entry_li = ADD_TAG(entry,listitem);
108 	return entry_li;
109 }
110 
111 void
add_file_info_item(xml_elem_t * varlist,const char * term,const char * info)112 add_file_info_item( xml_elem_t* varlist, const char *term, const char *info )
113 {
114 	xml_elem_t* entry_li = add_file_info_li( varlist, term);
115 	xml_elem_t* entry_p ;
116 
117 	entry_p = ADD_TAG(entry_li,para);
118 	append_CDATA_line( entry_p, info, strlen(info) );
119 }
120 
121 void
make_data_file_info(ASImageListEntry * df,ASXMLInterpreterState * parent_state,Bool preview_saved)122 make_data_file_info( ASImageListEntry *df, ASXMLInterpreterState *parent_state, Bool preview_saved )
123 {
124 #if 1
125 	ASXMLInterpreterState state;
126 	ASData2xmlState		  xml_state ;
127 
128 	xml_elem_t* varlist ;
129 	xml_elem_t* ptr ;
130 
131 	static char *img_type_names[ASIT_Unknown+1] =
132 	{
133 		"Xpm",
134 		"ZCompressedXpm",
135 		"GZCompressedXpm",
136 		"Png",
137 		"Jpeg",
138 		"Xcf",
139 		"Ppm",
140 		"Pnm",
141 		"Bmp",
142 		"Ico",
143 		"Cur",
144 		"Gif",
145 		"Tiff",
146 		"XML",
147 		"Xbm",
148 		"Targa",
149 		"Pcx",
150 		"Unknown"
151 	};
152 
153 	if( !start_doc_file( parent_state->dest_dir, df->name, NULL, parent_state->doc_type, df->name, df->name, df->fullfilename, &state, DOC_CLASS_None, DocClass_Overview ) )
154 			return ;
155 
156 	memset( &xml_state, 0x00, sizeof(xml_state));
157 	xml_state.doc = xml_elem_new();
158 	xml_state.doc->tag = mystrdup(XML_CONTAINER_STR) ;
159 	xml_state.doc->tag_id = XML_CONTAINER_ID ;
160 
161 	LOCAL_DEBUG_OUT( "doc = %p, doc->child = %p", xml_state.doc, xml_state.doc->child );
162 
163 	/* generate file contents : */
164 	add_data_section_header2xml( &xml_state, "Details" );
165 	varlist = ADD_TAG(xml_state.curr_section,variablelist);
166 
167 	if( df->preview )
168 	{
169 		char tmp[64];
170 		sprintf( &tmp[0], "%dx%d", df->preview->width, df->preview->height );
171 		add_file_info_item( varlist, "Size : ", &tmp[0] );
172 	}
173 	add_file_info_item( varlist, "Full path : ", df->fullfilename );
174 	if( df->type < ASIT_Unknown)
175 		add_file_info_item( varlist, "Type : ", img_type_names[df->type]);
176 
177 
178 	if( preview_saved )
179 	{
180 		xml_elem_t* entry_li = add_file_info_li( varlist, "Preview : ");
181 		xml_elem_t*	medobj = ADD_TAG(entry_li,mediaobject);
182 		xml_elem_t*	imgobj = ADD_TAG(medobj,imageobject);
183 		xml_elem_t*	imgdat = ADD_TAG(imgobj,imagedata);
184 
185 		imgdat->parm = safemalloc( 28+strlen(df->name)+32);
186 		sprintf( imgdat->parm, "fileref=\"%s.png\"", df->name );
187 	}
188 
189 	if( df->type == ASIT_XMLScript || !preview_saved )
190 	{
191 		char *doc_str = load_file(df->fullfilename);
192 		if( doc_str )
193 		{
194 			xml_elem_t*	credits_section;
195 			xml_elem_t*	litlayout;
196 
197 			if( df->type == ASIT_XMLScript )
198 			{
199 				credits_section = add_data_section_header2xml( &xml_state,
200 															   (strstr( doc_str,"<body>")!=NULL)?"HTML document : ":"XML text : ");
201 			}else
202 				credits_section = add_data_section_header2xml( &xml_state, "ASCII text: ");
203 
204 			litlayout = ADD_TAG(credits_section,literallayout);
205 			append_CDATA_line( litlayout, doc_str, strlen(doc_str) );
206 			free( doc_str );
207 		}
208 	}
209 
210 	/* now lets write it out into file : */
211 	for (ptr = xml_state.doc->child ; ptr ; ptr = ptr->next)
212 		convert_xml_tag( ptr, NULL, &state );
213 
214 	end_doc_file( &state );
215 	LOCAL_DEBUG_OUT( "xml_elem_delete for doc %p", xml_state.doc );
216 	xml_elem_delete(NULL, xml_state.doc);
217 #endif
218 }
219 
220 int
data_fname_filter(const char * d_name)221 data_fname_filter (const char *d_name)
222 {
223 	int name_len = strlen( d_name );
224 	if( d_name[0] == '.' ||
225 		(name_len >= 7 && strcmp(d_name+name_len-7, ".tar.gz") == 0) ||
226 		(name_len >= 5 && strcmp(d_name+name_len-5, ".mini") == 0) ||
227 		(name_len >= 5 && strcmp(d_name+name_len-5, ".html") == 0))
228 		return False;
229 	printf( "\b%c", d_name[0] );
230 	fflush( stdout );
231 	return True;
232 }
233 
234 
235 
236 void
convert_data_file(const char * source_dir,const char * dst_dir,ASXMLInterpreterState * state,ASData2xmlState * xml_state)237 convert_data_file( const char *source_dir, const char *dst_dir, ASXMLInterpreterState *state, ASData2xmlState *xml_state)
238 {
239 	unsigned int count = 0;
240 	Bool files_sect_added = False ;
241 	ASImageListEntry *curr ;
242 	ASImageListEntry *im_list = get_asimage_list( Scr.asv, source_dir, LOAD_PREVIEW,
243 												  SCREEN_GAMMA, 0, 0,
244 												  0, &count, data_fname_filter );
245 
246 	LOCAL_DEBUG_OUT( "im_list = %p, count = %d", im_list, count );
247 
248 	printf( "\b" );
249 	fflush( stdout );
250 
251 	curr = im_list ;
252 	while( curr )
253 	{
254 		LOCAL_DEBUG_OUT( "curr = %p", curr );
255 		LOCAL_DEBUG_OUT( "curr->name = \"%s\"", curr->name );
256 
257 		if( mystrcasecmp(curr->name, "CREDITS") != 0 )
258 		{
259 			int name_len = strlen( curr->name );
260 			int odir_name_len = dst_dir?strlen( dst_dir )+1:0;
261 			char *preview_name = safemalloc( odir_name_len + name_len + 1 + 3 + 1 );
262 			char *ext_name = safemalloc(odir_name_len + name_len + 1 + 4 + 1 );
263 			Bool preview_saved = False ;
264 
265 			xml_elem_t*	link = NULL ;
266 
267 /*			printf( "[%s]", curr->name );
268 			fflush(stdout);
269 */
270 			if( !files_sect_added )
271 			{
272 				add_data_section_header2xml( xml_state, "Files" );
273 				files_sect_added = True ;
274 			}
275 
276 			LOCAL_DEBUG_OUT( "curr->name = \"%s\", curr->preview = %p", curr->name, curr->preview );
277 			if( odir_name_len > 0 )
278 			{
279 				sprintf( preview_name, "%s/%s.png", dst_dir, curr->name );
280 				sprintf( ext_name, "%s/%s", dst_dir, curr->name );
281 			}else
282 			{
283 				strcpy( preview_name, curr->name );
284 				strcpy( ext_name, curr->name );
285 				strcpy( &(preview_name[name_len]), ".png" );
286 			}
287 			if( curr->preview )
288 			{
289 				ASImageExportParams params ;
290 				if( curr->type != ASIT_Jpeg &&
291 					get_flags( get_asimage_chanmask(curr->preview), SCL_DO_ALPHA) &&
292 					curr->preview->width < 200 && curr->preview->height < 200 )
293 				{
294 					params.png.flags = EXPORT_ALPHA ;
295 					params.png.compression = 6 ;
296 					params.png.type = ASIT_Png ;
297 					preview_saved = ASImage2file( curr->preview, NULL, preview_name,ASIT_Png, &params );
298 				}else
299 				{
300 					params.jpeg.flags = EXPORT_ALPHA ;
301 					params.jpeg.quality = 100 ;
302 					params.jpeg.type = ASIT_Jpeg ;
303 					preview_saved = ASImage2file( curr->preview, NULL, preview_name,ASIT_Jpeg, &params );
304 				}
305 
306 				if( !preview_saved )
307 					show_warning( "failed to save \"%s\" as png preview - skipping", curr->name );
308 			}
309 			if( preview_saved )
310 			{
311 				link = ADD_TAG(xml_state->curr_section,ulink);
312 
313 				if( link )
314 				{
315 					xml_elem_t*	medobj = ADD_TAG(link,mediaobject);
316 					xml_elem_t*	imgobj = ADD_TAG(medobj,imageobject);
317 					xml_elem_t*	imgdat = ADD_TAG(imgobj,imagedata);
318 
319 					imgdat->parm = safemalloc( 28+name_len+32);
320 					sprintf( imgdat->parm, "fileref=\"%s.png\"", curr->name );
321 				}
322 			}else
323 			{
324 				xml_elem_t*	p = ADD_TAG(xml_state->curr_section,para);
325 				link = ADD_TAG(p,ulink);
326 				append_CDATA_line( link, curr->name,name_len );
327 			}
328 			if( link )
329 			{
330 				link->parm = safemalloc( 6+name_len+32);
331 				sprintf( link->parm, "url=\"%s\"", curr->name );
332 				LOCAL_DEBUG_OUT( "%s", link->parm );
333 			}
334 
335 			make_data_file_info( curr, state, preview_saved );
336 
337 			printf( "." );
338 			fflush(stdout);
339 
340 	    }
341 		curr = curr->next ;
342 	}
343 	curr = im_list ;
344 	while( curr )
345 	{
346 		if( mystrcasecmp(curr->name, "CREDITS") == 0)
347 		{
348 			char *doc_str = load_file(curr->fullfilename);
349 			if( doc_str )
350 			{
351 				xml_elem_t*	credits_section = add_data_section_header2xml( xml_state, "CREDITS" );
352 				xml_elem_t*	litlayout = ADD_TAG(credits_section,literallayout);
353 
354 				append_CDATA_line( litlayout, doc_str, strlen(doc_str) );
355 				free( doc_str );
356 			}
357 			break;
358 		}
359 		curr = curr->next ;
360 	}
361 	destroy_asimage_list( &im_list );
362 }
363 
364 
365 void
gen_data_doc(const char * source_dir,const char * dest_dir,const char * display_name,const char * display_purpose,ASDocType doc_type)366 gen_data_doc( const char *source_dir, const char *dest_dir,
367 			  const	char *display_name,
368 			  const char *display_purpose,
369 			  ASDocType doc_type )
370 {
371 	ASXMLInterpreterState state;
372 	ASData2xmlState		  xml_state ;
373 	char *slash ;
374 	char *short_fname ;
375 	struct direntry  **list = NULL;
376 	int list_len, i ;
377 	xml_elem_t* dir_header_section = NULL ;
378 	xml_elem_t* dir_header_varlist = NULL ;
379 	xml_elem_t* ptr ;
380 
381 
382 	if( (slash = strrchr( source_dir, '/' )) != NULL )
383 		short_fname = mystrdup( slash+1 );
384 	else
385 		short_fname = mystrdup( source_dir );
386 
387 	memset( &xml_state, 0x00, sizeof(xml_state) );
388  	if( !start_doc_file( dest_dir, "index", NULL, doc_type, short_fname, display_name, display_purpose, &state, DOC_CLASS_None, DocClass_Overview ) )
389 			return ;
390 
391 	xml_state.doc = xml_elem_new();
392 	xml_state.doc->tag = mystrdup(XML_CONTAINER_STR) ;
393 	xml_state.doc->tag_id = XML_CONTAINER_ID ;
394 
395 	LOCAL_DEBUG_OUT( "doc = %p, doc->child = %p", xml_state.doc, xml_state.doc->child );
396 	list_len = my_scandir ((char*)source_dir, &list, ignore_dots, direntry_compar_alpha);
397 	for (i = 0; i < list_len; i++)
398 	{
399 		if (S_ISDIR (list[i]->d_mode) && strcasecmp(list[i]->d_name, "doc") != 0 )
400 		{
401 			char *subdir = make_file_name( source_dir, list[i]->d_name );
402 			char *dest_subdir = dest_dir?make_file_name( dest_dir, list[i]->d_name ):mystrdup(list[i]->d_name);
403 			char *subdir_display_name = make_file_name( display_name, list[i]->d_name );
404 			xml_elem_t* entry ;
405 			xml_elem_t* entry_term ;
406 			xml_elem_t* entry_link ;
407 
408 			if( dir_header_section == NULL )
409 			{
410 				dir_header_section = add_data_section_header2xml( &xml_state, "Subdirectories" );
411 				dir_header_varlist = ADD_TAG(dir_header_section,variablelist);
412 			}
413 
414 			entry = ADD_TAG(dir_header_varlist,varlistentry);
415 			entry_term = ADD_TAG(entry,term);
416 			entry_link = ADD_TAG(entry_term,ulink);
417 			entry_link->parm = safemalloc( 12+strlen(list[i]->d_name)+32 );
418 			sprintf( entry_link->parm,"url=\"%s/index\"", list[i]->d_name );
419 			append_CDATA_line( entry_link, list[i]->d_name, strlen(list[i]->d_name) );
420 
421 			gen_data_doc( subdir, dest_subdir,
422 			  			  subdir_display_name, subdir, doc_type );
423 
424 			free( subdir );
425 			free( dest_subdir );
426 			free( subdir_display_name );
427 		}
428 		free(list[i]);
429 	}
430 	if( list )
431 		free( list );
432 	printf( "\nCataloguing %s  ", source_dir );
433 	fflush( stdout );
434 
435 	convert_data_file( source_dir, dest_dir, &state, &xml_state );
436 
437 	/*xml_print(xml_state.doc); */
438 
439 	for (ptr = xml_state.doc->child ; ptr ; ptr = ptr->next)
440 		convert_xml_tag( ptr, NULL, &state );
441 	end_doc_file( &state );
442 
443 	LOCAL_DEBUG_OUT( "xml_elem_delete for doc %p", xml_state.doc );
444 	xml_elem_delete(NULL, xml_state.doc);
445 	free( short_fname );
446 }
447 
448 
449