void Pages::registration(Document *doc){ if(path != "/register") return; std::string name = cgi("name"), email = cgi("email"), pw = cgi("pw"); if(Session::user()) doc->redirect("/"); else if(cgi.getEnvironment().getRequestMethod() != "POST") form(doc); else if(name.empty()) form(doc, "Please specify a display name."); else if(email.empty()) form(doc, "Please specify an email address."); else if(!validEmail(email)) form(doc, "Invalid email address."); else if(pw.empty()) form(doc, "Please specify a password."); else if(pw != cgi("pwconf")) form(doc, "Passwords mismatch."); else{ if(DB::query("SELECT EXISTS (SELECT 1 FROM users WHERE lower(name) = lower($1) OR lower(email) = lower($2))", name, email)[0][0] == "t") return form(doc, "Sorry, name or email already in use."); DB::Result r = DB::query( "INSERT INTO users (name, password, email, registration, last_login) " "VALUES ($1, crypt($2, gen_salt('bf')), $3, 'now', 'now') " "RETURNING id", name, pw, email); if(r.empty()) return form(doc, "Erm, something went wrong. Please try again."); User u = User(number(r[0][0]), name); log("New user: "******" (" + number(u.id) + ")"); doc->addHttp("Set-Cookie: sid=" + Session::login(u) + ";Max-Age=2592000\n"); // 30 days doc->redirect(u.url() + "?welcome=1"); } }
Track::Track(int tid){ id = 0; if(tid <= 0) return; DB::Result r = DB::query( "SELECT tracks.title, tracks.user_id, users.name, tracks.visible, tracks.date FROM tracks, users " "WHERE tracks.id = " + number(tid) + " AND tracks.user_id = users.id"); if(!r.empty()){ id = tid; title = r[0][0]; artist = User(number(r[0][1]), r[0][2]); visible = r[0][3] == "t"; date = r[0][4]; } }
ExtendedTrack::ExtendedTrack(int tid){ id = 0; if(tid<=0) return; DB::Result r = DB::query( "SELECT tracks.title, tracks.user_id, users.name, users.email, tracks.visible, tracks.date, extract(epoch from tracks.date)," " tracks.notes, tracks.airable, tracks.license, array_to_string(tracks.tags, ',') FROM tracks, users " "WHERE tracks.id = " + number(tid) + " AND tracks.user_id = users.id"); if(!r.empty()){ id = tid; title = r[0][0]; artist.id = number(r[0][1]); artist.name = r[0][2]; artist.email = r[0][3]; visible = r[0][4] == "t"; date = r[0][5]; timestamp = r[0][6]; // Ext notes = r[0][7]; airable = r[0][8] == "t"; license = r[0][9]; // Tags std::string tstr = r[0][10]; std::string buf; for(std::string::const_iterator i=tstr.begin(); i!=tstr.end(); i++){ if(*i == ','){ if(!buf.empty()){ tags.push_back(buf); buf.clear(); } } else buf += *i; } if(!buf.empty()) tags.push_back(buf); // last tag } }
int main(int argc, char **argv){ if(argc != 3){ cerr << "Usage: nowplaying.json ARTIST TRACK" << endl; return 1; } DB::connect(); User u(argv[1]); std::string tid; if(u){ DB::Result r = DB::query("SELECT id FROM tracks WHERE user_id=" + number(u.id()) + " AND title=$1",argv[2]); if(!r.empty()) tid = r[0][0]; } cout << "{"; if(!tid.empty()) cout << field("id",tid); cout << field("title", jstring(argv[2])) << field("artist" , "{" + (u?field("id",number(u.id())):"") + field("name",jstring(argv[1]),true) + "}" , true) << "}"; DB::close(); return 0; }
void Pages::track(Document *doc){ std::string sub; int tid = route("track", path, sub); bool post = cgi.getEnvironment().getRequestMethod() == "POST"; if(!tid) return; if(sub == ""){ ExtendedTrack t(tid); if(!t) return; doc->setHtml("html/track.tpl", t.title); doc->rootDict()->SetValueAndShowSection("TID", number(t.id), "HAS_OEMBED"); t.fill(doc->dict()); t.player(doc->dict(), true); Audio(&t).fill(doc->dict()); doc->dict()->ShowSection(Youtube(t.artist.id) ? "HAS_YOUTUBE" : "NO_YOUTUBE"); Dict *embed = doc->dict()->AddIncludeDictionary("EMBED_CODE"); embed->SetFilename("html/embed-code.tpl"); embed->SetIntValue("WIDTH", 150); t.Track::fill(embed); Dict *uploader = doc->dict()->AddIncludeDictionary("UPLOADER"); uploader->SetFilename("html/uploader.tpl"); uploader->SetValue("ACTION", t.url() + "/upload"); int hits = Stat::push("trackView", t.artist.id, tid); doc->dict()->SetValue("HIT_COUNT", number(hits)); int unique_hits = Stat::get("trackView", 0, tid, true); doc->dict()->SetValue("UNIQUE_HIT_COUNT", number(unique_hits)); doc->rootDict()->ShowSection("REQUIRES_STATS_JS"); Session::fill(doc->dict()); EventList::track(t).fill(doc->dict(), "EVENTS", false); doc->dict()->ShowSection(Follower(Session::user().id).favorited(tid) ? "IS_FAVORITE" : "NOT_FAVORITE"); if(Session::user()){ DB::Result playlists = DB::query( "SELECT id, name FROM playlists WHERE user_id = " + number(Session::user().id) + " ORDER BY name ASC"); if(!playlists.empty()){ doc->dict()->ShowSection("HAS_PLAYLISTS"); for(DB::Result::const_iterator i=playlists.begin(); i!=playlists.end(); i++){ Dict *playlist = doc->dict()->AddSectionDictionary("PLAYLIST"); playlist->SetValue("PLAYLIST_ID", i->at(0)); playlist->SetValue("PLAYLIST_NAME", i->at(1)); } } } } else if(sub == "delete"){ Track t(tid); if(!t) return; if(!t.artist.self()) doc->redirect(t.url()); else if(!post || cgi("confirm") != "Delete" || Session::nonce() != cgi("nonce")){ Session::newNonce(); doc->setHtml("html/delete.tpl", "Track deletion"); doc->dict()->SetValue("WHAT", t.title); doc->dict()->SetValue("CANCEL_URL", t.url()); } else{ log("Deleting track: " + t.title + " (" + number(t.id) + ")"); Art art(t.id); if(art) art.remove(); Audio(&t).unlink(); Playlist::removeTrack(t.id); DB::query("DELETE FROM events WHERE track_id = " + number(t.id)); DB::query("DELETE FROM featured_tracks WHERE track_id = " + number(t.id)); DB::query("DELETE FROM favorites WHERE type = 'track' AND ref = " + number(t.id)); DB::query("DELETE FROM user_features WHERE type = 'track' AND ref = " + number(t.id)); DB::query("DELETE FROM tracks WHERE id = " + number(t.id)); doc->redirect(Session::user().url()); } } else if(sub == "publish"){ Track t(tid); if(!t) return; if(tid != number(cgi("tid"))) return doc->redirect(t.url()); if(t.artist.self() && !t.visible && post){ DB::query("UPDATE tracks SET visible = 't', date = 'now' WHERE id = " + number(t.id)); Event e; e.type = Event::Publish; e.source = t.artist; e.track = t; e.push(); std::vector<std::string> emails = Follower(t.artist.id).followers(); std::string maildata = "From: EqBeats notification <*****@*****.**>\n" "Message-ID: notify-t" + number(t.id) + "\n" "Subject: " + filter("EqBeats notification: " + t.artist.name + " - " + t.title) + "\n" "Precedence: bulk\n\n" + t.artist.name + " just published a new track : " + t.title + "\n" "Listen to it here : " + eqbeatsUrl() + t.url() + "\n\n" "You're receiving this email because you're following " + t.artist.name + " on EqBeats.\n" "If you don't want to receive these notifications anymore, go to " + eqbeatsUrl() + t.artist.url() + " and click \"Stop following\"."; for(std::vector<std::string>::const_iterator i = emails.begin(); i!=emails.end(); i++) sendMail(i->c_str(), maildata.c_str()); } doc->redirect(t.url()); } }
void Pages::passwordReset(Document *doc){ if(path != "/account/reset") return; if(Session::user()) doc->redirect("/account"); // Coming from an email if(!cgi("token").empty()){ DB::Result r = DB::query("SELECT user_id FROM resets WHERE token = $1", cgi("token")); if(r.empty()) form(doc, "Sorry, looks like your token has expired. You could always try again."); else{ DB::query("DELETE FROM resets WHERE token = $1", cgi("token")); std::string pw = randomString(16); int uid = number(r[0][0]); Account a(uid); DB::query("UPDATE users SET password = crypt($1, gen_salt('bf')) WHERE id = " + number(a.id), pw); std::string sid = Session::login(a); doc->setHtml("html/account.tpl", "Your account"); doc->addHttp("Set-Cookie: sid=" + sid + ";Max-Age=2592000;Path=/\n"); // 30 days doc->dict()->SetValueAndShowSection("MESSAGE", "Your password has been reset to " + pw + ". You can now change it below.", "MESSAGE"); doc->dict()->SetValue("OLD_PASSWORD", pw); a.fill(doc->dict()); } } // Sending the token else if(cgi.getEnvironment().getRequestMethod() == "POST" && !cgi("email").empty()){ DB::Result r = DB::query("SELECT id FROM users WHERE lower(email) = lower($1)", cgi("email")); if(r.empty()) form(doc, "Sorry, we couldn't find any account with this email address. Try again?"); else{ std::string token = randomString(32); while(DB::query("INSERT INTO resets (user_id, token) VALUES ($1, $2) RETURNING 1", r[0][0], token).empty()) token = randomString(32); sendMail(cgi("email").c_str(), ((std::string)"From: EqBeats <*****@*****.**>\n" "Subject: Resetting your password on EqBeats\n\n" "Hi.\n\n" "Someone, hopefully you, requested a password reset on your account at EqBeats. " "If you want to reset your password, please click this link : " + eqbeatsUrl() + "/account/reset?token=" + token + "\n" "If you didn't request it, please ignore this email.\n\n" "Cheers.").c_str()); doc->setHtml("html/password-reset.tpl", "Password reset"); doc->dict()->SetValueAndShowSection("MESSAGE", "A reset link has been sent to your email address. " "If there's any more problems (can't access your email, etc...), " "feel free to drop us a line at [email protected].", "MESSAGE"); } } // Not coming from a form nor an email else form(doc); }