(Back)port some changes from beagle-lucene-1-9-lockfile-branch: allow ext: queries...
[beagle.git] / Filters / FilterRPM.cs
blob71daa0e1f6f0db96e2485a3620a2702c13ea6f35
1 //
2 // FilterRPM.cs
3 //
4 // Copyright (C) 2006 Debajyoti Bera <dbera.web@gmail.com>
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 using System;
28 using System.IO;
29 using System.Text;
30 using System.Collections;
31 using System.Diagnostics;
32 using System.Xml;
34 using Beagle.Daemon;
35 using Beagle.Util;
37 namespace Beagle.Filters {
38 public class FilterRPM : FilterPackage {
40 private class RpmPropertyInfo {
41 public string property_name;
42 public bool is_keyword;
44 public RpmPropertyInfo (string property_name, bool is_keyword)
46 this.property_name = property_name;
47 this.is_keyword = is_keyword;
51 private static Hashtable hash_property_list;
52 static FilterRPM ()
54 hash_property_list = new Hashtable ();
56 // mapping between rpm tagname and beagle property name
57 hash_property_list ["Release"] = new RpmPropertyInfo ("fixme:release", true);
58 hash_property_list ["License"] = new RpmPropertyInfo ("dc:rights", true);
59 hash_property_list ["Os"] = new RpmPropertyInfo ("fixme:os", true);
60 hash_property_list ["Arch"] = new RpmPropertyInfo ("fixme:arch", true);
61 hash_property_list ["Changelogtext"] = new RpmPropertyInfo ("fixme:changelog", false);
64 public FilterRPM ()
66 AddSupportedFlavor (FilterFlavor.NewFromMimeType ("application/x-rpm"));
69 protected override void PullPackageProperties ()
71 SafeProcess pc = new SafeProcess ();
72 pc.Arguments = new string [] { "rpm", "-qp", "--queryformat", "[%{*:xml}\n]", FileInfo.FullName };
73 pc.RedirectStandardOutput = true;
74 pc.RedirectStandardError = true;
76 try {
77 pc.Start ();
78 } catch (SafeProcessException e) {
79 Log.Warn (e.Message);
80 Error ();
81 return;
84 XmlTextReader reader = new XmlTextReader (new StreamReader (pc.StandardOutput));
85 reader.WhitespaceHandling = WhitespaceHandling.None;
87 try {
88 ParseRpmTags (reader);
89 } catch (XmlException e) {
90 Logger.Log.Warn (e, "FilterRPM: Error parsing output of rpmquery");
91 Error ();
92 } finally {
93 reader.Close ();
94 pc.Close ();
98 private void ParseRpmTags (XmlTextReader reader)
100 reader.Read ();
101 while (reader.Read ()) {
102 if (reader.IsEmptyElement || ! reader.IsStartElement ())
103 continue;
104 else if (reader.Name != "rpmTag") {
105 reader.Skip ();
106 continue;
108 string attr_name = reader ["name"];
109 //Logger.Log.Debug ("Read element:" + reader.Name + " - " + attr_name);
111 ReadStringValues (reader, attr_name);
115 private void ReadStringValues (XmlTextReader reader, string attr_name)
117 RpmPropertyInfo prop_info = (RpmPropertyInfo) hash_property_list [attr_name];
118 if (attr_name != "Basenames" &&
119 attr_name != "Name" &&
120 attr_name != "Version" &&
121 attr_name != "Summary" &&
122 attr_name != "Description" &&
123 attr_name != "Size" &&
124 attr_name != "Packager" &&
125 attr_name != "Group" &&
126 attr_name != "Url" &&
127 prop_info == null)
128 return;
130 reader.ReadStartElement ();
132 while (reader.IsStartElement ()) {
133 //Logger.Log.Debug (" Reading value for:" + reader.Name);
134 if (reader.IsEmptyElement)
135 reader.Skip ();
137 string content = HtmlAgilityPack.HtmlEntity.DeEntitize (reader.ReadInnerXml ());
139 switch (attr_name) {
140 case "Name":
141 PackageName = content;
142 break;
144 case "Version":
145 PackageVersion = content;
146 break;
148 case "Summary":
149 Summary = content;
150 break;
152 case "Description":
153 AppendText (content);
154 AppendWhiteSpace ();
155 break;
157 case "Basenames":
158 AddProperty (Beagle.Property.NewUnstored ("fixme:files", content));
159 break;
161 case "Size":
162 Size = content;
163 break;
165 case "Group":
166 Category = content.Replace ('/', ' ');
167 break;
169 case "Url":
170 Homepage = content;
171 break;
173 case "Packager":
174 // FIXME: Not a correct way to extract name-email info.
175 string[] name_email = content.Split ('<');
176 PackagerName = name_email [0];
177 if (name_email.Length > 1)
178 PackagerEmail = name_email [1].Replace ('>', ' ');
179 break;
181 default:
182 if (prop_info == null)
183 break;
184 if (prop_info.is_keyword)
185 AddProperty (Beagle.Property.NewUnsearched (prop_info.property_name, content));
186 else
187 AddProperty (Beagle.Property.New (prop_info.property_name, content));
188 break;
192 //Logger.Log.Debug (" Done reading values. Now at " +
193 // (reader.IsStartElement () ? "" : "/") + reader.Name);