1 /* Copyright (C) 2000-2006 Thomas Bopp, Thorsten Hampel, Ludger Merkens
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 * $Id: types.pike,v 1.2 2009/08/07 16:14:56 nicke Exp $
19 inherit "/kernel/module";
20 inherit "/base/xml_parser";
21 inherit "/base/xml_data";
27 //! This module reads some configuration files located in the
28 //! servers config/ directory and stores information about all
29 //! mime types and what sTeam class to create for a specific mime type.
30 class types : public module,xml_parser,xml_data{
38 #define MIME_FILE _Server->query_config("config-dir")+"mimetypes.txt"
39 #define CLASS_FILE _Server->query_config("config-dir")+"classtypes.txt"
47 private mapping mMime;
48 private mapping mExts;
49 private array asDefaults = ({ "text/plain", "text/html", "text/wiki", "application/msword", "application/vnd.ms-powerpoint", "image/gif", "image/jpeg", "image/png", "application/pdf" });
51 private mapping mClasses = ([ ]);
53 array get_classes() { return indices(mClasses); }
64 * Register a new class with a filename to create and a mimetype.
65 * This will change the content of the CLASS_FILE.
67 * @param string cl - the class to register
68 * @param string doc_class - the class to clone
69 * @param string mime - the mimetype
70 * @param string desc - the description for this document class.
74 register_class(string cl, string doc_class, string mime, string desc)
76 if ( !_SECURITY->access_register_class(0, 0, CALLER) )
78 mMime[cl] = ({ doc_class, mime, desc });
79 Stdio.File f = Stdio.File(CLASS_FILE, "wct");
80 f->write("<classes>\n");
81 foreach(indices(mMime), string ext) {
82 f->write("\t<type>\n\t\t<ext>"+ext+"</ext>\n\t\t<class>"+
83 mMime[ext][DATA_TYPE]+"</class>\n\t\t<desc>"+
84 mMime[ext][DATA_DESC]+"</desc>\n\t</type>\n");
86 f->write("</classes>\n");
93 * query_document_type, returns an array of document type information
94 * depending on the given filename.
96 * @param filename - the filename
97 * @return the document-type of that file (depends only on extension)
98 * @see query_mime_type
101 query_document_type(string filename)
103 string base_type, file_extension;
107 LOG("query_document_type()");
108 if ( !mappingp(mMime) )
115 ploder = filename / "."; /* explode, hmm */
116 if ( !sizeof(ploder) )
117 return ({ "Document", "gen" });
119 file_extension = ploder[sizeof(ploder)-1];
121 for ( i = strlen(file_extension) - 1; i >= 0; i-- )
122 if ( file_extension[i] >= 'A' && file_extension[i] <= 'Z' )
123 file_extension[i] -= ('A' - 'a');
124 file_extension = lower_case(file_extension);
125 LOG("File Extension:" + file_extension);
126 if ( arrayp(mMime[file_extension]) )
128 return ({ mMime[file_extension][DATA_TYPE],
132 return ({ "Document", file_extension });
136 * Returns the documents extensions for a given mimetype.
138 * @param string mtype - the mimetype
139 * @return array of extensions for this mime type with information
141 array query_document_type_mime(string mtype)
143 if ( arrayp(mExts[mtype]) )
144 return ({ mExts[mtype][DATA_TYPE], "" });
146 return ({ "Document", "" });
150 * Return the array of possible extensions for the given mimetype.
152 * @param string mtype - the mimetype
153 * @return array of extensions for mtype
155 array query_mimetype_extensions(string mtype)
157 array extensions = ({ });
158 if ( !arrayp(mExts[mtype]) )
161 foreach( mExts[mtype], mixed ext ) {
162 extensions += ({ ext[DATA_EXT] });
168 register_extensions(string mtype, string desc, array extensions, void|int def)
172 error("Cannot reregister extension !");
173 mExts[mtype] = extensions;
175 foreach(extensions, string ext) {
177 mMime[ext] = ({ "Document", mtype, desc, i, ext });
179 if ( def && search(asDefaults, mtype) == -1 )
180 asDefaults += ({ mtype });
183 array get_default_mimetypes()
185 return copy_value(asDefaults);
189 * Return the mimetype for a given extension.
191 * @param doc - the document extension
192 * @return the mime-type of the document
193 * @see query_document_type
196 query_mime_type(string doc)
198 if ( ! stringp( doc ) )
199 return MIMETYPE_UNKNOWN;
203 if ( !mappingp(mMime) )
206 data = mMime[lower_case(doc)];
208 return MIMETYPE_UNKNOWN;
210 if ( !stringp(data[DATA_MIME]) )
211 steam_error("Failure in types: Non-string value for mimetype "+doc);
212 if ( data[DATA_MIME] == "" )
213 steam_error("Failure in types: Empty string value for mimetype "+doc);
215 return data[DATA_MIME];
219 * Return the mime description for an extension.
221 * @param doc - the document extension
222 * @return the description of the mime-type
223 * @see query_mime_type
226 query_mime_desc(string doc)
230 if ( !mappingp(mMime) )
233 data = mMime[lower_case(doc)];
237 return data[DATA_DESC];
253 int start, i, j, len;
256 buf = Stdio.read_file(CLASS_FILE);
258 ASSERTINFO(stringp(buf),
259 "Initialization error: class file missing ["+CLASS_FILE+"]\n");
261 //lines = buf / "\n";
263 NodeXML n = parse_data(buf);
265 foreach(n->children, NodeXML type) {
266 NodeXML t = type->get_node("ext");
267 classname = type->get_node("class")->data;
268 if ( stringp(classname) )
269 mClasses[classname] = 1;
270 mMime[t->data] = ({ classname,
272 type->get_node("desc")->data, 0 });
275 // read the mimetypes.txt
276 buf = Stdio.read_file(MIME_FILE);
277 if ( !stringp(buf) ) {
278 FATAL("Initialization error: mime file missing! ["+MIME_FILE +"]\n");
283 for ( i = sizeof(lines) - 1; i >= 0; i-- ) {
284 len = strlen(lines[i]);
285 if ( len == 0 || lines[i][0] == '#' )
287 j = 0; start = -1; tokens = ({ });
289 if ( lines[i][j] == ' ' || lines[i][j] == '\t' ) {
291 tokens += ({ lines[i][start..j-1] });
295 else if ( start == -1 ) {
301 tokens += ({ lines[i][start..] });
303 if ( sizeof(tokens) > 1 ) {
304 for ( j = sizeof(tokens) - 1; j >= 1; j-- ) {
305 data = mMime[tokens[j]];
307 if ( arrayp(data) ) {
308 // remember the priority of extensions
309 // html htm wiki, then html should have priority (lowest j)
310 mMime[tokens[j]][DATA_MIME] = tokens[0];
311 mMime[tokens[j]][DATA_PRIO] = j;
315 ({ "Document", tokens[0], "Generic", j });
320 foreach ( indices(mMime), string ext ) {
321 // mExts mapping holds mimetype:data
322 if ( arrayp(mExts[mMime[ext][DATA_MIME]]) )
323 mExts[mMime[ext][DATA_MIME]] += ({ mMime[ext]+({ ext }) });
325 mExts[mMime[ext][DATA_MIME]] = ({ mMime[ext]+({ ext }) });
328 foreach ( indices(mExts), string mtype ) {
329 if ( sizeof(mExts[mtype]) > 1 ) {
330 array sorter = ({ });
331 foreach(mExts[mtype], mixed ext)
332 sorter += ({ ext[DATA_PRIO] });
333 sort(mExts[mtype], sorter);
341 * Return the whole mapping of saved types. The mapping contains
342 * file extension: informations (array)
344 * @return the mapping with all type definitions
351 return copy_value(mMime);
358 * return the class for a doctype (extension of a file).
360 * @param doc - the doctype (or extension)
363 string query_document_class(string doc)
369 return CLASS_NAME_DOCUMENT;
370 LOG("class is " + data[DATA_TYPE]);
371 return data[DATA_TYPE];
375 * Return the document class for the given mimetype.
376 * The class can be found in the classes/ Folder of sTeam.
378 * @param string mtype - the mimetype
379 * @return string of class type used
381 string query_document_class_mime(string mtype)
383 if ( arrayp(mExts[mtype]) )
384 return mExts[mtype][0][DATA_TYPE];
386 return CLASS_NAME_DOCUMENT;
390 string get_identifier() { return "types"; }