ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/repos/DecentralizedMedia/DecentralizedMedia.cpp
Revision: 531
Committed: 2005-06-28T17:54:16-07:00 (19 years, 11 months ago) by douglas
File size: 5828 byte(s)
Log Message:
Hmm?

File Contents

# Content
1 // Decentralized Media
2 //
3 // Douglas Thrift
4 //
5 // $Id$
6
7 #include <menes/standard.hh>
8
9 #include <menes-api/pcre/regex.hpp>
10 #include <menes-app/simple.hpp>
11 #include <menes-dbi/driver.hpp>
12 #include <menes-dbi/resultset.hpp>
13 #include <menes-etl/fnbind.hpp>
14 #include <menes-ios/helpers.hpp>
15 #include <menes-net/http/request.hpp>
16 #include <menes-net/http/response.hpp>
17 #include <menes-xml/document.hpp>
18 #include <menes-xml/parse.hpp>
19
20 #include "DecentralizedMedia.hpp"
21
22 int Main(const app::Options& options)
23 {
24 ext::RedBlackSet<ext::String> extensions;
25 ext::RedBlackSet<api::Path> locals;
26 api::Pcre::RegEx extension(_B("^-extension=(.+)$")), local(_B("^-local=(.+)$"));
27
28 _foreach (const app::ArgumentList, arg, app::GetArguments())
29 {
30 api::Pcre::RegEx::Match match;
31
32 if (match = extension(*arg))
33 extensions.Insert(match[1]);
34 else if (match = local(*arg))
35 locals.Insert(api::Path(match[1]).GetRealPath());
36 }
37
38 if (extensions.IsEmpty())
39 extensions.Insert(_B("mp3"));
40
41 {
42 api::Path media(_B("Media"));
43
44 if (!media.Exists())
45 media.CreateDirectory();
46
47 locals.Insert(media.GetRealPath());
48 }
49
50 _S<DecentralizedMedia> media(extensions, locals);
51
52 media.Block();
53
54 return 0;
55 }
56
57 DecentralizedMedia::DecentralizedMedia(const ext::RedBlackSet<ext::String>& extensions, const ext::RedBlackSet<api::Path>& locals) : waf::Server(_B("Web")), process(bmp.IsRunning() ? NULL : new api::Process(_B("/usr/X11R6/bin/beep-media-player"))), connection(dbi::GetDriver("dbi::PgSql::Driver")->Connect("", "douglas", "", "media")), extensions(extensions)
58 {
59 if (!process.IsEmpty())
60 {
61 process->ClearReader();
62 process->ClearWriter();
63 }
64
65 connection->Execute(_B("UPDATE files SET live = FALSE"));
66
67 {
68 _L<ext::String> args;
69
70 _foreach (const ext::RedBlackSet<ext::String>, extension, extensions)
71 args.InsertLast(_S<ios::String>() << "-extension=" << *extension);
72
73 _foreach (const ext::RedBlackSet<api::Path>, local, locals)
74 args.InsertLast(_S<ios::String>() << "-local=" << *local);
75
76 _S<api::Process> media(_B("Util/media"), args);
77
78 Media(*media.GetReader());
79
80 media.Join();
81 }
82
83 {
84 _L<ext::String> args;
85
86 args.InsertLast(_B("-s"));
87 args.InsertLast(_B("object/DecentralizedMedia.hh.gch"));
88
89 _S<api::Process> make(CFG_GNU_MAKE, args);
90
91 make.ClearWriter();
92
93 _S<ios::String> error;
94
95 ios::ReadToWrite(*make.GetReader(), error);
96
97 if (make.Join() != 0)
98 throw ext::StringException(error);
99 }
100
101 AddPort(6996);
102 }
103
104 DecentralizedMedia::~DecentralizedMedia()
105 {
106 if (!process.IsEmpty())
107 {
108 _H<api::Thread> thread(new api::Thread(etl::BindAll(&DecentralizedMedia::Destroy, this)));
109
110 bmp.Quit();
111
112 thread->Join();
113 }
114 }
115
116 _L<ext::String> DecentralizedMedia::GetArtists() const
117 {
118 _H<dbi::ResultSet> artists_(connection->Execute(_B("SELECT DISTINCT artist FROM files WHERE live = TRUE")));
119 _L<ext::String> artists;
120
121 while (artists_->MoveNext())
122 artists.InsertLast(artists_->GetString(_B("artist")));
123
124 return artists;
125 }
126
127 _L<ext::String> DecentralizedMedia::GetTitles() const
128 {
129 _H<dbi::ResultSet> titles_(connection->Execute(_B("SELECT DISTINCT title FROM files WHERE live = TRUE")));
130 _L<ext::String> titles;
131
132 while (titles_->MoveNext())
133 titles.InsertLast(titles_->GetString(_B("title")));
134
135 return titles;
136 }
137
138 _L<ext::String> DecentralizedMedia::GetAlbums() const
139 {
140 _H<dbi::ResultSet> albums_(connection->Execute(_B("SELECT DISTINCT album FROM files WHERE live = TRUE")));
141 _L<ext::String> albums;
142
143 while (albums_->MoveNext())
144 albums.InsertLast(albums_->GetString(_B("album")));
145
146 return albums;
147 }
148
149 _L<ext::String> DecentralizedMedia::GetGenres() const
150 {
151 _H<dbi::ResultSet> genres_(connection->Execute(_B("SELECT DISTINCT album FROM files WHERE live = TRUE")));
152 _L<ext::String> genres;
153
154 while (genres_->MoveNext())
155 genres.InsertLast(genres_->GetString(_B("genre")));
156
157 return genres;
158 }
159
160 _L<MediaFolder> DecentralizedMedia::GetFolders() const
161 {
162 _H<dbi::ResultSet> paths(connection->Execute(_B("SELECT DISTINCT root FROM files WHERE live = TRUE")));
163 _L<MediaFolder> folders;
164
165 while (paths->MoveNext())
166 folders.InsertLast(MediaFolder(connection, paths->GetString(_B("path"))));
167
168 return folders;
169 }
170
171 void DecentralizedMedia::Process(const net::Http::Request& request, net::Http::Response& response)
172 {
173 if (request.method_ == _B("EXTENSIONS"))
174 {
175 api::Cout << "EXTENSIONS" << ios::NewLine;
176
177 response.SetStatus(200);
178
179 _foreach (const ext::RedBlackSet<ext::String>, extension, extensions)
180 response << *extension << ios::NewLineNoFlush;
181 }
182 else if (request.method_ == _B("MEDIA"))
183 {
184 api::Cout << "MEDIA" << ios::NewLine;
185
186 if (!request.content_.IsEmpty())
187 {
188 Media(*request.content_);
189
190 response.SetStatus(204);
191 }
192 else
193 response.SetStatus(411);
194 }
195 else
196 waf::Server::Process(request, response);
197 }
198
199 void DecentralizedMedia::Media(ios::Reader& media)
200 {
201 _H<xml::Document> document(xml::Parse(media));
202 api::Pcre::RegEx share("^[0-9a-f]+$");
203
204 _foreach (const xml::NodeSet, folder, *document/"media"/"folder")
205 {
206 ext::String path(**folder/"path");
207
208 if (api::Pcre::RegEx::Match match = share(path))
209 {
210 _H<Share> share(new Share(connection, _B("192.168.2.8"), match[0]));
211
212 path = share->path.GetPath();
213
214 // XXX: these are probably going to need read/write locking
215 sharesByPath[path] = share;
216 sharesByHost[_B("192.168.2.8")][match[0]] = share;
217
218 share->Mount();
219 }
220
221 Media(*folder, path, path);
222 }
223 }
224
225 void DecentralizedMedia::Media(const _H<xml::Node>& folder, const api::Path& path, const api::Path& root)
226 {
227 MediaFolder(connection, path, root);
228
229 _foreach (const xml::NodeSet, file, *folder/"file")
230 MediaFile(connection, path.GetChild(**file/"path"), **file/"artist", **file/"title", **file/"album", **file/"genre", root);
231
232 _foreach (const xml::NodeSet, folder_, *folder/"folder")
233 Media(*folder_, path.GetChild(**folder_/"path"), root);
234 }

Properties

Name Value
svn:eol-style native
svn:keywords Id