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

# 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 _breakpoint();
25 ext::RedBlackSet<ext::String> extensions;
26 ext::RedBlackSet<api::Path> locals;
27 api::Pcre::RegEx extension(_B("^-extension=(.+)$")), local(_B("^-local=(.+)$"));
28
29 _foreach (const app::ArgumentList, arg, app::GetArguments())
30 {
31 api::Pcre::RegEx::Match match;
32
33 if (match = extension(*arg))
34 extensions.Insert(match[1]);
35 else if (match = local(*arg))
36 locals.Insert(api::Path(match[1]).GetRealPath());
37 }
38
39 if (extensions.IsEmpty())
40 extensions.Insert(_B("mp3"));
41
42 {
43 api::Path media(_B("Media"));
44
45 if (!media.Exists())
46 media.CreateDirectory();
47
48 locals.Insert(media.GetRealPath());
49 }
50
51 _S<DecentralizedMedia> media(extensions, locals);
52
53 media.Block();
54
55 return 0;
56 }
57
58 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 {
60 if (!process.IsEmpty())
61 {
62 process->ClearReader();
63 process->ClearWriter();
64 }
65
66 connection->Execute(_B("UPDATE files SET live = FALSE"));
67
68 {
69 _L<ext::String> args;
70
71 _foreach (const ext::RedBlackSet<ext::String>, extension, extensions)
72 args.InsertLast(_S<ios::String>() << "-extension=" << *extension);
73
74 _foreach (const ext::RedBlackSet<api::Path>, local, locals)
75 args.InsertLast(_S<ios::String>() << "-local=" << *local);
76
77 _S<api::Process> media(_B("Util/media"), args);
78
79 Media(*media.GetReader());
80
81 media.Join();
82 }
83
84 {
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 AddPort(6996);
103 }
104
105 DecentralizedMedia::~DecentralizedMedia()
106 {
107 if (!process.IsEmpty())
108 {
109 _H<api::Thread> thread(new api::Thread(etl::BindAll(&DecentralizedMedia::Destroy, this)));
110
111 bmp.Quit();
112
113 thread->Join();
114 }
115 }
116
117 _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 void DecentralizedMedia::Process(const net::Http::Request& request, net::Http::Response& response)
173 {
174 if (request.method_ == _B("EXTENSIONS") || request.method_ == _B("GET") && request.uri_.GetUri().IsEmpty())
175 {
176 api::Cout << "EXTENSIONS" << ios::NewLine;
177
178 response.SetStatus(200);
179
180 _foreach (const ext::RedBlackSet<ext::String>, extension, extensions)
181 response << *extension << ios::NewLineNoFlush;
182 }
183 else if (request.method_ == _B("MEDIA") || request.method_ == _B("POST") && request.uri_.GetUri().IsEmpty())
184 {
185 api::Cout << "MEDIA" << ios::NewLine;
186
187 if (!request.content_.IsEmpty())
188 {
189 Media(*request.content_);
190
191 response.SetStatus(204);
192 }
193 else
194 response.SetStatus(402);
195 }
196 else
197 waf::Server::Process(request, response);
198 }
199
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 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 }
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