Dont throw EncodingFoundException unless asked to. Should remove the occassional...
[beagle.git] / Filters / FilterExternal.cs
blob82e1352c40921588c201521d9f6e3f84d5029326
1 //
2 // FilterExternal.cs
3 //
4 // Copyright (C) 2006 Novell, Inc.
5 //
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a
9 // copy of this software and associated documentation files (the "Software"),
10 // to deal in the Software without restriction, including without limitation
11 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 // and/or sell copies of the Software, and to permit persons to whom the
13 // Software is furnished to do so, subject to the following conditions:
15 // The above copyright notice and this permission notice shall be included in
16 // all copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 // DEALINGS IN THE SOFTWARE.
27 // The purpose of this filter is to allow users to easily extract text
28 // content from structured files using an external program. See
29 // external-filters.txt for more information.
31 using System;
32 using System.Collections;
33 using System.IO;
34 using System.Diagnostics;
35 using System.Xml;
36 using System.Xml.Serialization;
38 using Beagle.Daemon;
39 using Beagle.Util;
41 namespace Beagle.Filters {
43 public class ExternalFilterInfo {
45 [XmlElement ("mimetype")]
46 public string [] MimeTypes;
48 [XmlElement ("extension")]
49 public string [] Extensions;
51 [XmlElement ("command")]
52 public string Command;
54 [XmlElement ("arguments")]
55 public string Arguments;
58 [XmlRoot ("external-filters")]
59 public class ExternalFilterInfoContainer {
60 [XmlElement ("filter")]
61 public ExternalFilterInfo [] Items;
64 public class FilterExternal : Beagle.Daemon.Filter {
66 private ExternalFilterInfo [] filters = null;
68 public FilterExternal ()
70 string path = Path.Combine (Path.Combine (ExternalStringsHack.SysConfDir, "beagle"), "external-filters.xml");
72 try {
73 FileStream fs = File.Open (path, FileMode.Open, FileAccess.Read, FileShare.Read);
74 XmlSerializer serializer = new XmlSerializer (typeof (ExternalFilterInfoContainer));
75 ExternalFilterInfoContainer container = (ExternalFilterInfoContainer) serializer.Deserialize (fs);
76 fs.Close ();
77 this.filters = container.Items;
78 } catch (FileNotFoundException) {
79 // Probably not an error if the file isn't there.
81 } catch (DirectoryNotFoundException) {
82 // The directory isn't there either, not an error.
84 } catch (InvalidOperationException ex) {
85 // Something wrong with the XML
86 Logger.Log.Error ("Unable to parse {0}: {1}", path, ex.Message);
88 } catch (XmlException ex) {
89 // Something else wrong with the XML
90 Logger.Log.Error ("Unable to parse {0}: {1}", path, ex.Message);
93 if (this.filters == null)
94 return;
96 foreach (ExternalFilterInfo efi in this.filters) {
97 if (efi.MimeTypes != null) {
98 foreach (string s in efi.MimeTypes)
99 AddSupportedFlavor (FilterFlavor.NewFromMimeType (s));
102 if (efi.Extensions != null) {
103 foreach (string s in efi.Extensions)
104 AddSupportedFlavor (FilterFlavor.NewFromExtension (s));
109 private ExternalFilterInfo GetFilterInfo (string extension, string mime_type)
111 if (this.filters == null || this.filters.Length == 0)
112 return null;
114 if (extension != null) {
115 foreach (ExternalFilterInfo efi in this.filters) {
116 if (efi.Extensions == null)
117 continue;
119 if (ArrayFu.IndexOfString (efi.Extensions, extension) != -1)
120 return efi;
124 if (mime_type != null) {
125 foreach (ExternalFilterInfo efi in this.filters) {
126 if (efi.MimeTypes == null)
127 continue;
129 if (ArrayFu.IndexOfString (efi.MimeTypes, mime_type) != -1)
130 return efi;
134 return null;
137 protected override void DoPull ()
139 ExternalFilterInfo efi = GetFilterInfo (this.Extension, this.MimeType);
141 if (efi == null) {
142 Logger.Log.Warn ("Unable to find a match for extension {0}, mime type {1} when one should have matched", this.Extension, this.MimeType);
143 Error ();
146 // FIXME: Need to deal with quotation marks in the XML file, probably.
147 string[] tmp_argv = efi.Arguments.Split (' ');
148 string[] argv = new string [tmp_argv.Length + 1];
150 argv [0] = efi.Command;
152 int j = 1;
153 for (int i = 0; i < tmp_argv.Length; i++) {
154 if (tmp_argv [i] == String.Empty)
155 continue;
157 if (tmp_argv [i] == "%s")
158 argv [j] = FileInfo.FullName;
159 else
160 argv [j] = tmp_argv [i];
161 j++;
164 SafeProcess pc = new SafeProcess ();
165 pc.Arguments = argv;
166 pc.RedirectStandardOutput = true;
168 try {
169 pc.Start ();
170 } catch (SafeProcessException e) {
171 Log.Warn (e.Message);
172 Error ();
173 return;
176 StreamReader pout = new StreamReader (pc.StandardOutput);
178 string str;
179 while ((str = pout.ReadLine ()) != null) {
180 AppendText (str);
181 AppendStructuralBreak ();
184 pout.Close ();
185 pc.Close ();
186 Finished ();