ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/repos/DecentralizedMedia/DecentralizedMedia.cpp
Revision: 802
Committed: 2006-06-22T04:12:17-07:00 (19 years ago) by douglas
File size: 4044 byte(s)
Log Message:
Hmm, I wonder why I never did this before...

File Contents

# Content
1 // Decentralized Media
2 //
3 // Douglas Thrift
4 //
5 // $Id$
6
7 #include <cxx/standard.hh>
8
9 #include <api/exename.hpp>
10 #include <api/pcre/regex.hpp>
11 #include <app/simple.hpp>
12 #include <dbi/driver.hpp>
13 #include <hop/bind.hpp>
14 #include <ios/helpers.hpp>
15 #include <net/http/request.hpp>
16 #include <net/http/response.hpp>
17 #include <xml/document.hpp>
18 #include <xml/parse.hpp>
19
20 #include "DecentralizedMedia.hpp"
21
22 int Main(const app::Options& options)
23 {
24 api::Pcre::RegEx configuration_(_B("^-configuration=(.+)$")), extension(_B("^-extension=(.+)$")), local(_B("^-local=(.+)$")), player_("^-player=(\\d+)$");
25 cse::String configuration(_B("DecentralizedMedia.xml"));
26 ext::RedBlackSet<cse::String> extensions;
27 ext::RedBlackSet<api::Path> locals;
28 int player(0);
29
30 _foreach (const app::ArgumentList, arg, app::GetArguments())
31 {
32 api::Pcre::RegEx::Match match;
33
34 if (match = configuration_(*arg))
35 configuration = match[1];
36 else if (match = extension(*arg))
37 extensions.Insert(match[1]);
38 else if (match = local(*arg))
39 locals.Insert(api::Path(match[1]).GetRealPath());
40 else if (match = player_(*arg))
41 player = lexical_cast<int>(match[1]);
42 else
43 {
44 api::Cout << _B("Usage: ") << api::GetExecutablePath().GetName() << _B(" [-configuration=.+] [-extension=.+] [-local=.+] [-player=\\d+]") << ios::NewLine;
45
46 return 1;
47 }
48 }
49
50 if (extensions.IsEmpty())
51 extensions.Insert(_B("mp3"));
52
53 {
54 api::Path media(_B("Media"));
55
56 if (!media.Exists())
57 media.CreateDirectory();
58
59 locals.Insert(media.GetRealPath());
60 }
61
62 _S<DecentralizedMedia> media(configuration, extensions, locals, player);
63
64 media.Block();
65
66 return 0;
67 }
68
69 DecentralizedMedia::DecentralizedMedia(const cse::String& configuration, const ext::RedBlackSet<cse::String>& extensions, const ext::RedBlackSet<api::Path>& locals, int player) : waf::Server(_B("Web")), connector(new _H<Connector>(configuration)), extensions(extensions), library(connector), player(connector, player)
70 {
71 {
72 _L<cse::String> args;
73
74 _foreach (const ext::RedBlackSet<cse::String>, extension, extensions)
75 args.InsertLast(_S<ios::String>() << "-extension=" << *extension);
76
77 _foreach (const ext::RedBlackSet<api::Path>, local, locals)
78 args.InsertLast(_S<ios::String>() << "-local=" << *local);
79
80 _S<api::Process> media(_B("Util/media"), args);
81
82 Media(*media.GetReader());
83
84 media.Join();
85 }
86
87 AddPort(6996);
88 }
89
90 void DecentralizedMedia::Process(const net::Http::Request& request, net::Http::Response& response)
91 {
92 api::Cout << request.client_ << _B(" ");
93
94 if (request.method_ == _B("EXTENSIONS"))
95 {
96 api::Cout << "EXTENSIONS" << ios::NewLine;
97
98 response.SetStatus(200);
99
100 _foreach (const ext::RedBlackSet<cse::String>, extension, extensions)
101 response << *extension << ios::NewLineNoFlush;
102 }
103 else if (request.method_ == _B("MEDIA"))
104 {
105 api::Cout << "MEDIA" << ios::NewLine;
106
107 if (!request.content_.IsEmpty())
108 {
109 api::InternetAddress host(request.client_);
110
111 host.SetPort(6996);
112
113 Media(*request.content_, host);
114
115 response.SetStatus(204);
116 }
117 else
118 response.SetStatus(411);
119 }
120 else
121 waf::Server::Process(request, response);
122 }
123
124 void DecentralizedMedia::Media(ios::Reader& media, const api::Address& host)
125 {
126 _R<xml::Document> document(xml::Parse(media));
127 api::Pcre::RegEx share("^[0-9a-f]+$");
128
129 _foreach (const xml::NodeSet, folder, *document/"media"/"folder")
130 {
131 cse::String path(**folder/"path");
132
133 if (api::Pcre::RegEx::Match match = share(path))
134 {
135 _R<Share> share(new _H<Share>(connector, host, match[0]));
136
137 path = share->path.GetPath();
138
139 player.Add(share);
140 }
141
142 Media(*folder, path, path);
143 }
144 }
145
146 void DecentralizedMedia::Media(const _R<xml::Node>& folder, const api::Path& path, const api::Path& root)
147 {
148 MediaFolder(connector, path, root);
149
150 _foreach (const xml::NodeSet, file, *folder/"file")
151 MediaFile(connector, path.GetChild(**file/"path"), **file/"artist", **file/"title", **file/"album", **file/"genre", root);
152
153 _foreach (const xml::NodeSet, folder_, *folder/"folder")
154 Media(*folder_, path.GetChild(**folder_/"path"), root);
155 }

Properties

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