libept  0.5.25
desktop.h
Go to the documentation of this file.
1 
3 #include <wibble/string.h>
4 
5 #include <ept/token.h>
6 #include <ept/core/desktopfile.h>
7 #include <ept/core/source.h>
8 
9 #include <set>
10 #include <vector>
11 #include <fstream>
12 #include <sstream>
13 #include <iterator>
14 #include <functional>
15 
16 #include <dirent.h>
17 
18 #ifndef EPT_CORE_DESKTOP_H
19 #define EPT_CORE_DESKTOP_H
20 
21 namespace ept {
22 namespace core {
23 namespace desktop {
24 
26 
27 template< PropertyId > struct PropertyType {};
28 template<> struct PropertyType< Name > { typedef std::string T; };
29 template<> struct PropertyType< Group > { typedef std::string T; };
30 template<> struct PropertyType< ShortDescription > { typedef std::string T; };
31 template<> struct PropertyType< Package > { typedef ept::Token T; };
32 template<> struct PropertyType< Icon > { typedef std::string T; };
33 
34 typedef std::set< std::string > Categories;
35 
36 struct Category {
37  std::string name;
38  operator std::string() const { return name; }
39 };
40 
41 inline std::istream &operator >>( std::istream &i, Category &cat ) {
42  char c;
43  cat.name = "";
44  while ( i.peek() != EOF ) {
45  c = i.get();
46  if ( c == ';' ) return i;
47  cat.name += c;
48  }
49  return i;
50 }
51 
52 struct Entry : wibble::mixin::Comparable< Entry > {
53  Entry() {}
54  Entry( std::string n, std::string g,
55  std::string p, std::string d , std::string i )
56  : m_name( n ),
57  m_package( p ),
58  m_description( d ),
59  m_icon( i )
60  { setCategories( g ); }
61 
62  void load( std::string file ) {
63  m_id = file;
64  std::ifstream i( file.c_str() );
65  if ( !i.is_open() )
66  return; // throw?
67  desktop::File e;
68  i >> e;
69  i.close();
70  desktop::File::Group &g = e.group( "Desktop Entry" );
71  m_name = g.entry( "Name" ).value;
72  m_description = g.entry( "Comment" ).value;
73  if ( m_description == "" )
74  m_description = g.entry( "GenericName" ).value;
75  m_package = g.entry( "X-AppInstall-Package" ).value;
76  // m_group = g.entry( "Categories" ).value;
77  m_icon = g.entry( "Icon" ).value;
78  setCategories( g.entry( "Categories" ).value );
79  }
80 
81  void setCategories( std::string s ) {
82  std::istringstream i( s );
83  m_categories.clear();
84  std::remove_copy_if(
85  std::istream_iterator< Category >( i ),
86  std::istream_iterator< Category >(),
87  std::inserter( m_categories, m_categories.begin() ),
88  std::bind1st( std::equal_to< std::string >(), "" ) );
89  }
90 
91  Categories categories() const { return m_categories; }
92  bool inCategory( std::string c ) const {
93  return m_categories.find( c ) != m_categories.end();
94  }
95  std::string id() const { return m_id; }
96  std::string name() const { return m_name; }
97  std::string package() const { return m_package; }
98  std::string description() const { return m_description; }
99  std::string icon() const { return m_icon; }
100  bool operator< ( const Entry &o ) const {
101  if ( m_name < o.m_name ) return true;
102  if ( m_name == o.m_name )
103  if ( m_package < o.m_package ) return true;
104  return false;
105  }
106 protected:
110 };
111 
112 struct InternalList {
113  std::string dir;
114  std::string current;
115  mutable Entry entry;
116  off_t offset;
117  mutable bool loaded;
118 
119  InternalList() : dir( "" ), offset( -2 ), loaded( false ) {}
120  InternalList( std::string d ) : dir( d ), offset( -1 ), loaded( false )
121  {
122  firstFile();
123  }
124 
125  Entry head() const {
126  if (!loaded)
127  entry.load( current );
128  loaded = true;
129  return entry;
130  }
131 
132  bool empty() const {
133  return (offset == -2);
134  }
135 
136  void firstFile() {
137  offset = -1;
138  nextFile();
139  }
140 
141  InternalList tail() const {
142  InternalList r = *this;
143  r.nextFile();
144  return r;
145  }
146 
147  void nextFile() {
148  loaded = false;
149  DIR *d = opendir( dir.c_str() );
150  if ( !d ) {
151  offset = -2;
152  closedir( d );
153  return;
154  }
155 
156  if ( offset != -1 )
157  seekdir( d, offset );
158 
159  dirent *ent = 0;
160  while ( ( ent = readdir( d ) ) != 0 ) {
161  std::string name( ent->d_name );
162  if ( name == "." || name == ".." )
163  continue;
164  if ( !wibble::str::endsWith( name, ".desktop" ) )
165  continue;
166  current = dir + "/" + name;
167  offset = telldir( d );
168  closedir( d );
169  return;
170  }
171  closedir( d );
172  offset = -2;
173  }
174 };
175 
176 struct Setup {
177  typedef ept::Token Token;
178  typedef Entry Internal;
181 };
182 
183 struct GroupPolicy {
184  virtual std::string group( const Entry &e )
185  {
186  return wibble::str::fmt( e.categories() );
187  }
188  virtual ~GroupPolicy() {}
189 };
190 
191 struct Source : core::Source< Source, Setup, PropertyType >
192 {
193  std::string m_dir;
194 
197 
198  Source( std::string dir ) : m_dir( dir ),
200 
202  return InternalList( m_dir );
203  }
204 
206  Token t;
207  t._id = std::string( "desktop:" ) + i.id();
208  return t;
209  }
210 
212  Entry e;
213  e.load( t.desktop() );
214  return e;
215  }
216 
218  m_policy = p;
219  }
220 
221  template< PropertyId p >
223 
224  struct IsInGroup {
225  std::string g;
226  IsInGroup( std::string _g = "" ) : g( _g ) {}
227  bool operator()( Token, std::string gr ) const {
228  return gr == g;
229  }
230  };
231 
232  PropertyFilter< Group, IsInGroup >::T group( std::string id )
233  {
234  return propertyFilter< Group >( IsInGroup( id ) );
235  }
236 
237 };
238 
239 template<> inline std::string Source::getInternal< Name >( Entry e ) {
240  return e.name();
241 }
242 
243 template<> inline std::string Source::getInternal< Icon >( Entry e ) {
244  return e.icon();
245 }
246 
247 template<> inline ept::Token Source::getInternal< Package >( Entry e ) {
248  ept::Token t;
249  t._id = e.package();
250  return t;
251 }
252 
253 template<> inline std::string Source::getInternal< Group >( Entry e ) {
254  return m_policy->group( e );
255 }
256 
257 template<> inline std::string Source::getInternal< ShortDescription >( Entry e ) {
258  return e.description();
259 }
260 
261 }
262 }
263 }
264 
265 #endif
bool inCategory(std::string c) const
Definition: desktop.h:92
PropertyId
Definition: desktop.h:25
Setup::Token Token
Definition: source.h:15
Definition: desktop.h:183
std::string m_name
Definition: desktop.h:107
std::string g
Definition: desktop.h:225
GroupPolicy * m_policy
Definition: desktop.h:196
Source(std::string dir)
Definition: desktop.h:198
desktop::PropertyId PropertyId
Definition: desktop.h:179
ept::Token Token
Definition: desktop.h:177
Definition: desktop.h:112
Entry entry
Definition: desktop.h:115
Definition: desktopfile.h:15
std::string m_dir
Definition: desktop.h:193
void load(std::string file)
Definition: desktop.h:62
Definition: desktopfile.h:22
Definition: desktop.h:176
std::string id() const
Definition: desktop.h:95
Definition: desktop.h:25
Definition: desktop.h:25
std::istream & operator>>(std::istream &i, Category &cat)
Definition: desktop.h:41
Definition: desktop.h:52
Definition: desktop.h:25
bool m_free
Definition: desktop.h:108
Definition: desktop.h:224
Entry()
Definition: desktop.h:53
std::string name() const
Definition: desktop.h:96
Entry head() const
Definition: desktop.h:125
std::string T
Definition: desktop.h:30
PropertyFilter< Group, IsInGroup >::T group(std::string id)
Definition: desktop.h:232
InternalList(std::string d)
Definition: desktop.h:120
Categories m_categories
Definition: desktop.h:109
bool loaded
Definition: desktop.h:117
std::string name
Definition: desktop.h:37
Definition: desktop.h:36
InternalList()
Definition: desktop.h:119
Entry(std::string n, std::string g, std::string p, std::string d, std::string i)
Definition: desktop.h:54
Entry lookupToken(Token t)
Definition: desktop.h:211
Entry & entry(std::string k)
Definition: desktopfile.h:25
bool operator()(Token, std::string gr) const
Definition: desktop.h:227
Definition: token.h:10
PropertyType< p >::T getInternal(Entry)
std::string current
Definition: desktop.h:114
std::string m_icon
Definition: desktop.h:107
InternalList tail() const
Definition: desktop.h:141
Categories categories() const
Definition: desktop.h:91
IsInGroup(std::string _g="")
Definition: desktop.h:226
Definition: desktop.h:191
virtual std::string group(const Entry &e)
Definition: desktop.h:184
Definition: desktop.h:25
void setCategories(std::string s)
Definition: desktop.h:81
void setGroupPolicy(GroupPolicy *p)
Definition: desktop.h:217
std::string value
Definition: desktopfile.h:18
std::set< std::string > Categories
Definition: desktop.h:34
std::string T
Definition: desktop.h:28
std::string icon() const
Definition: desktop.h:99
bool m_supported
Definition: desktop.h:108
std::string _id
Definition: token.h:11
std::string T
Definition: desktop.h:32
std::string m_description
Definition: desktop.h:107
std::string dir
Definition: desktop.h:113
std::string package() const
Definition: desktop.h:97
desktop::InternalList InternalList
Definition: desktop.h:180
AptInternalList< Internal > InternalList
Definition: core/apt.h:381
std::string m_id
Definition: desktop.h:107
Definition: desktop.h:25
std::string m_package
Definition: desktop.h:107
Definition: desktop.h:27
bool operator<(const Entry &o) const
Definition: desktop.h:100
Definition: source.h:13
ept::Token T
Definition: desktop.h:31
Token getToken(Entry i)
Definition: desktop.h:205
off_t offset
Definition: desktop.h:116
std::string description() const
Definition: desktop.h:98
virtual ~GroupPolicy()
Definition: desktop.h:188
std::string T
Definition: desktop.h:29
InternalList listInternal()
Definition: desktop.h:201
GroupPolicy m_defaultPolicy
Definition: desktop.h:195
void nextFile()
Definition: desktop.h:147
Entry Internal
Definition: desktop.h:178
bool empty() const
Definition: desktop.h:132
void firstFile()
Definition: desktop.h:136