Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: basicxman/watchfirstnow
base: ec7a2cbf4f
...
head fork: basicxman/watchfirstnow
compare: 30845ed5d2
  • 5 commits
  • 11 files changed
  • 0 commit comments
  • 1 contributor
Commits on Jan 06, 2012
@basicxman Initial scores retrieved via Twitter @frcfms. 0185a94
Commits on Feb 29, 2012
@basicxman Removed client side score retrieval, added Google Ads. a018e2c
Commits on Mar 05, 2012
@basicxman Added features.
justin.tv, ASF and Granite State specific RTMP stream types.
Added Google Analytics.
Added sponsor anchor.
1babb1b
Commits on Mar 06, 2012
@basicxman Parsed FMS tweets for Rebound Rumble. 2f962d9
Commits on Mar 07, 2012
@basicxman Added regional links to each stream. 30845ed
View
4 .gitignore
@@ -1,4 +1,6 @@
.sass-cache
-streams.js
+streams.js*
application.css
application.js
+last_twitter_id
+frcfms.json
View
75 css/application.scss
@@ -80,6 +80,47 @@ body, div, h3, a, span, ul, li {
}
#blank-stream { display: none; }
+#blank-score { display: none; }
+
+div#scores {
+ position: fixed;
+ right: 0px;
+ top: 35px;
+ ul {
+ li + li {
+ padding-top: 20px;
+ }
+
+ li {
+ list-style: none;
+ width: 200px;
+ div.match-info {
+ float: left;
+ width: 40px;
+ font-size: 18px;
+
+ .mn.P { color: #666; }
+ .mn.Q { color: #333; }
+ .mn.E { color: #000; }
+ }
+
+ div.match-teams {
+ float: right;
+ div { padding: 0px 10px; }
+ .rs, .bs { font-weight: bold; }
+ .red-alliance {
+ float: left;
+ width: 80px;
+ color: red;
+ }
+ .blue-alliance {
+ float: left;
+ color: blue;
+ }
+ }
+ }
+ }
+}
.stream {
.stream-controls {
@@ -128,7 +169,7 @@ $base: #f9f9f9;
height: 100%;
overflow: auto;
- ul {
+ > ul {
#toggle-sidebar {
font-size: 18px;
}
@@ -148,6 +189,28 @@ $base: #f9f9f9;
vertical-align: middle;
}
+ ul {
+ display: none;
+ z-index: 2000;
+ position: absolute;
+ left: 200px;
+ li {
+ width: 200px;
+ display: table;
+ cursor: pointer;
+ a {
+ display: table-cell;
+ vertical-align: middle;
+ text-decoration: none;
+ color: #000;
+ }
+ }
+ }
+
+ &:hover {
+ ul { display: block; }
+ }
+
&:nth-child(odd) {
background-color: $base;
}
@@ -224,3 +287,13 @@ $base: #f9f9f9;
background: url(../images/resize.png) no-repeat right bottom;
}
}
+
+#footer-help {
+ position: fixed;
+ bottom: 0px;
+ padding: 20px;
+}
+
+.meta {
+ display: none;
+}
View
BIN  images/github_logo.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
71 index.html
@@ -4,7 +4,7 @@
<meta charset=utf-8 />
<title>Watch FIRST Now</title>
<link rel="stylesheet" type="text/css" href="css/application.css" />
- <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Droid+Sans" type="text/css" />
+ <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Droid+Sans:400,700" type="text/css" />
</head>
<body>
@@ -20,6 +20,45 @@
</div>
</div>
+ <div id="meta">
+ <ul>
+ <li><a href="" target="_blank" class="match-results">Match Results</a></li>
+ <li><a href="" target="_blank" class="rankings">Rankings</a></li>
+ <li><a href="" target="_blank" class="awards">Awards</a></li>
+ <li><a href="" target="_blank" class="qualifications">Qualifications</a></li>
+ <li><a href="" target="_blank" class="eliminations">Eliminations</a></li>
+ </ul>
+ </div>
+
+ <div id="scores">
+ <ul>
+ <li id="blank-score">
+ <div class="match-info">
+ <span class="ec"></span><br />
+ <span class="mn"></span>
+ </div>
+
+ <div class="match-teams">
+ <div class="red-alliance">
+ <span class="rs"></span><br />
+ <span class="rt"></span>
+ </div>
+ <div class="blue-alliance">
+ <span class="bs"></span><br />
+ <span class="bt"></span>
+ </div>
+ <div style="clear: both;"></div>
+ </div>
+ <div style="clear: both;"></div>
+ </li>
+ </ul>
+ </div>
+
+ <div id="footer-help">
+ <p>
+ </p>
+ </div>
+
<div id="stream-container">
<div id="blank-stream" class="stream">
<div class="stream-title"><span></span><div class="unlocked"></div><div class="close"></div></div>
@@ -38,6 +77,36 @@
</div>
</div>
+ <div style="position: fixed; bottom: 0px; left: 0px;">
+ <a href="http://github.com" target="_blank" title="Sponsored by GitHub">Sponsored in part by<br /><img src="images/github_logo.png" /></a>
+ </div>
+
+ <div style="position: fixed; bottom: 0px; right: 0px;">
+<script type="text/javascript"><!--
+google_ad_client = "ca-pub-0465126076790352";
+/* WatchFIRSTNow */
+google_ad_slot = "7934051176";
+google_ad_width = 728;
+google_ad_height = 90;
+//-->
+</script>
+<script type="text/javascript"
+src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
+</script>
+ </div>
+<script type="text/javascript">
+
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-29655917-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+
+</script>
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.7.0/jquery-ui.min.js"></script>
<script type="text/javascript" src="js/application.js"></script>
View
38 js/application.coffee
@@ -23,12 +23,12 @@ window.setOpenDialogCookie = ->
window.setOpen = ->
setOpenDialogCookie.call($(this))
id = $(this).attr("id")
- $("#toggle-#{id} span").text("~ #{$("#toggle-#{id}").text()}")
+ $("#toggle-#{id} span").text("~ #{$("#toggle-#{id} span").text()}")
window.setClose = ->
id = $(this).attr("id")
setCookie(id, "close")
- $("#toggle-#{id} span").text($("#toggle-#{id}").text().substring(2))
+ $("#toggle-#{id} span").text($("#toggle-#{id} span").text().substring(2))
window.resizeStream = (event) ->
height = $(this).height() - $(this).children(".stream-controls").height()
@@ -42,6 +42,11 @@ window.streamCallback = (data) ->
$.streams = data
executeStreams()
+window.scoresCallback = (data) ->
+ for tweet in data.reverse()
+ displayScore(parseTweet(tweet.text))
+ $.latestTweet = tweet.id_str
+
changeVideoSize = (stream, width, height) ->
dY = stream.dialog("option", "height") - stream.children(".stream-embed").height()
stream.css("width", width)
@@ -49,11 +54,28 @@ changeVideoSize = (stream, width, height) ->
stream.dialog("option", { width: width, height: height + dY })
resizeStream.call(stream)
+addSidebarSubItem = (stream) ->
+ if not stream.eventCode?
+ return ""
+
+ matchResults = "http://www2.usfirst.org/2012comp/Events/#{stream.eventCode}/matchresults.html"
+ rankings = "http://www2.usfirst.org/2012comp/Events/#{stream.eventCode}/rankings.html"
+ awards = "http://www2.usfirst.org/2012comp/Events/#{stream.eventCode}/awards.html"
+ qualifications = "http://www2.usfirst.org/2012comp/events/#{stream.eventCode}/schedulequal.html"
+ eliminations = "http://www2.usfirst.org/2012comp/events/#{stream.eventCode}/scheduleelim.html"
+ elm = $("#meta").clone()
+ elm.find(".match-results").attr("href", matchResults)
+ elm.find(".rankings").attr("href", rankings)
+ elm.find(".awards").attr("href", awards)
+ elm.find(".qualifications").attr("href", qualifications)
+ elm.find(".eliminations").attr("href", eliminations)
+ return elm.html()
+
addSidebarItem = (stream) ->
elm = $("<li class='toggle-stream'></li>");
elm.attr("id", "toggle-stream-#{stream.id}")
- elm.html("<span>#{stream.name}</span>")
- elm.insertAfter("#stream-list li:last")
+ elm.html("<span>#{stream.name}</span>" + addSidebarSubItem(stream))
+ elm.insertAfter("#stream-list > ul > li:last")
addDialog = (id, embed, name, width, height) ->
elm = $("#blank-stream").clone()
@@ -84,7 +106,7 @@ addDialog = (id, embed, name, width, height) ->
elm
addStream = (stream) ->
- elm = addDialog("stream-#{stream.id}", stream.embed, stream.name, 480, 320)
+ elm = addDialog("stream-#{stream.id}", stream.embed, stream.name, 480, 400)
resizeStream.call(elm)
if stream.permalink?
permalink = elm.find(".stream-permalink")
@@ -94,6 +116,8 @@ addStream = (stream) ->
if stream.chat_embed?
chat = addDialog("chat-stream-#{stream.id}", stream.chat_embed, "#{stream.name} Chat", 320, 480)
chat.find(".stream-controls").remove()
+ else
+ elm.find(".toggle-chat").remove()
showChat = (elm) ->
chat = $("#chat-#{elm.attr('id')}")
@@ -124,8 +148,8 @@ loadStream = ->
jQuery ->
loadStream()
- $(".toggle-stream").live "click", (event) ->
- streamID = $(this).attr("id").substring(7)
+ $(".toggle-stream span").live "click", (event) ->
+ streamID = $(this).parent().attr("id").substring(7)
stream = $("##{streamID}")
if stream.dialog("isOpen")
newState = "close"
View
57 lib/main.rb
@@ -24,16 +24,68 @@ def write
end
end
- def add_source(url, name)
+ def add_source(url, name, event_code)
+ stream = {
+ "id" => @streams["lastid"] + 1,
+ "eventCode" => eventCode
+ }
if url =~ /ustream/
- @streams["streams"] << ustream(url, name)
+ stream.merge! ustream(url, name)
+ elsif url =~ /justin/
+ stream.merge! justintv(url, name)
+ elsif url =~ /\.asf/
+ stream.merge! asf(url, name)
+ elsif url =~ /granite/
+ stream.merge! << granite_state(name)
else
return
end
+ @streams["streams"] << stream
@streams["lastid"] += 1
end
+ def granite_state(name)
+ view_path = File.expand_path("rtmp.erb", VIEWS_PATH)
+ embed = r(view_path)
+
+ {
+ "name" => name,
+ "embed" => embed,
+ }
+ end
+
+ def asf(url, name)
+ @embedurl = url
+ view_path = File.expand_path("asf.erb", VIEWS_PATH)
+ embed = r(view_path)
+
+ {
+ "name" => name,
+ "embed" => embed,
+ }
+ end
+
+ def justintv(url, name)
+ doc = Nokogiri::HTML(open(url))
+ content = doc.inner_html
+
+ @embedurl = doc.inner_html.match(/http:\/\/www-cdn.jtvnw.*?\.swf/)[0]
+ @channelname = url.split("/").last
+
+ embed_view_path = File.expand_path("justintv.erb", VIEWS_PATH)
+ embed = r(embed_view_path)
+ chat_embed_view_path = File.expand_path("justintvchat.erb", VIEWS_PATH)
+ chat_embed = r(chat_embed_view_path)
+
+ {
+ "name" => name,
+ "permalink" => url,
+ "embed" => embed,
+ "chat_embed" => chat_embed,
+ }
+ end
+
def ustream(url, name)
doc = Nokogiri::HTML(open(url))
embed = doc.css("textarea.legacyCode").first.text
@@ -47,7 +99,6 @@ def ustream(url, name)
chat_embed.gsub! "586", "100%"
{
- "id" => @streams["lastid"] + 1,
"name" => name,
"permalink" => url,
"embed" => embed,
View
36 lib/twitter.rb
@@ -0,0 +1,36 @@
+require "net/http"
+require "json"
+
+url = "http://api.twitter.com/1/statuses/user_timeline.json?screen_name=frcfms&count=100"
+if File.exists? "last_twitter_id"
+ url += "&since_id=" + File.read("last_twitter_id")
+end
+
+data = JSON.load(Net::HTTP.get(URI(url)))
+exit if data.length == 0
+File.open("last_twitter_id", "w") { |f| f.write data.first["id_str"] }
+data.sort! { |a, b| a["created_at"] <=> b["created_at"] }
+data.map! do |tweet|
+ text = tweet["text"]
+ {
+ :eventCode => text.match(/#FRC([a-zA-Z0-9]+)\s/)[1],
+ :matchType => text.match(/TY\s([A-Z]{1})/)[1],
+ :matchNumber => text.match(/MC\s([0-9]+)/)[1],
+ :redScore => text.match(/RF\s([0-9]+)/)[1],
+ :blueScore => text.match(/BF\s([0-9]+)/)[1],
+ :redTeams => text.match(/RA\s([0-9]+)\s([0-9]+)\s([0-9]+)/)[1..-1].join("<br />"),
+ :blueTeams => text.match(/BA\s([0-9]+)\s([0-9]+)\s([0-9]+)/)[1..-1].join("<br />"),
+ :redBridge => text.match(/RB\s([0-9]+)/)[1],
+ :blueBridge => text.match(/BB\s([0-9]+)/)[1],
+ :redFouls => text.match(/RFP\s([0-9]+)/)[1],
+ :blueFouls => text.match(/BFP\s([0-9]+)/)[1],
+ :redHybrid => text.match(/RHS\s([0-9]+)/)[1],
+ :blueHybrid => text.match(/BHS\s([0-9]+)/)[1],
+ :redTeleop => text.match(/RTS\s([0-9+])/)[1],
+ :blueTeleop => text.match(/BTS\s([0-9+])/)[1],
+ :coopertition => text.match(/CP\s([0-9+])/)[1]
+ }
+end
+
+data = data + JSON.load(File.read("frcfms.json")) if File.exists? "frcfms.json"
+File.open("frcfms.json", "w") { |f| f.write data.to_json }
View
1  lib/views/asf.erb
@@ -0,0 +1 @@
+<object classid="CLSID:05589FA1-C356-11CE-BF01-00AA0055595A" width="100%" height="100%" id="IFid1" class="ImageFrame_none"> <param name="ShowDisplay" value="0"/> <param name="ShowControls" value="1"/> <param name="AutoStart" value="1"/> <param name="AutoRewind" value="-1"/> <param name="Volume" value="0"/> <param name="FileName" value="<%= @embedurl %>" /> <embed src="<%= @embedurl %>" width="100%" height="100%" type="video/x-ms-wmv" controller="true" autoplay="true" loop="false"/> </object>
View
1  lib/views/justintv.erb
@@ -0,0 +1 @@
+<object type="application/x-shockwave-flash" height="100%" width="100%" id="live_embed_player_flash" data="http://www.justin.tv/widgets/live_embed_player.swf?channel=<%= @channelname %>" bgcolor="#000000"><param name="allowFullScreen" value="true"><param name="allowScriptAccess" value="always"><param name="allowNetworking" value="all"><param name="movie" value="http://www.justin.tv/widgets/live_embed_player.swf"><param name="flashvars" value="hostname=www.justin.tv&amp;channel=<%= @channelname %>&amp;auto_play=true&amp;start_volume=25&amp;enable_javascript=true"><param name="wmode" value="transparent"></object>
View
1  lib/views/justintvchat.erb
@@ -0,0 +1 @@
+<iframe src="http://www.twitch.tv/chat/embed?channel=<%= @channelname %>&popout_chat=true" width="100%" height="100%"></iframe>
View
1  lib/views/rtmp.erb
@@ -0,0 +1 @@
+<object width="100%" height="100%"> <param name="movie" value="http://fpdownload.adobe.com/strobe/FlashMediaPlayback.swf"><param name="flashvars" value="src=rtmp%3A%2F%2F23.21.170.228%2Flive%2Fbox5&amp;autoPlay=true&amp;streamType=live&amp;bufferingOverlay=false"><param name="allowFullScreen" value="true"><param name="allowscriptaccess" value="always"><embed src="http://fpdownload.adobe.com/strobe/FlashMediaPlayback.swf" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="100%" height="100%" flashvars="src=rtmp%3A%2F%2F23.21.170.228%2Flive%2Fbox5&amp;autoPlay=true&amp;streamType=live&amp;bufferingOverlay=false"></object>

No commit comments for this range

Something went wrong with that request. Please try again.