ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/repos/DecentralizedMedia/DecentralizedMedia.cpp
Revision: 529
Committed: 2005-06-27T18:01:23-07:00 (19 years, 11 months ago) by douglas
File size: 5963 byte(s)
Log Message:
Updated to new api::Path changes.

File Contents

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

Properties

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