Permalink
Browse files

start work to let users generate torrents

  • Loading branch information...
hcliff committed Jan 30, 2013
1 parent 1b70b9f commit cb47a18b0653ef41ebd456bdd093703d295e507c

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -1,2 +1,2 @@
<!DOCTYPE html>
-<html><head><title>Ampere, abusus non tollit usum</title><link href="favicon.ico" rel="shortcut-icon" type="image/x-icon"><link href="css/bootstrap.css" rel="stylesheet" type="text/css"><script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.2.2/bootstrap.min.js" type="text/javascript"></script><script src="http://cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.10/socket.io.min.js" type="text/javascript"></script><script src="http://hcliff.github.com/ampere/js/humane.js" type="text/javascript"></script><script src="http://hcliff.github.com/ampere/js/datachannel.js" type="text/javascript"></script></head><body><div class="modal hide" id="create-modal"><div class="modal-header"><h3>Create a torrent</h3><button class="close" data-dismiss="modal" type="button"></div><form class="modal-body form-horizontal" id="create-form"><div class="control-group"><label class="control-label" for="name">name</label><div class="controls"><input id="name" name="name" placeholder="My great torrent" type="text"></div></div><div class="control-group"><label class="control-label" for="tracker">tracker</label><div class="controls"><input id="tracker" name="tracker" placeholder="http://" type="url"></div></div><div class="control-group"><label class="control-label" for="files">files</label><div class="controls"><div class="files"></div><span class="help-inline">Drag files from your computer to add them</span></div></div></form><div class="modal-footer"><a class="btn" data-dismiss="modal">close</a><input class="btn btn-primary" form="create-form" type="submit" value="create"></div></div><div class="modal hide" id="add-modal"><div class="modal-header"><h3>Add a torrent</h3><button class="close" data-dismiss="modal" type="button"></div><form class="modal-body form-horizontal" id="add-form"><div class="control-group"><label class="control-label" for="metainfo">.torrent</label><div class="controls"><input id="metainfo" name="metainfo" type="file"><span class="help-block">Or drag a file from your computer</span></div></div></form><div class="modal-footer"><a class="btn" data-dismiss="modal">close</a><input class="btn btn-primary" form="add-form" type="submit" value="create"></div></div><div class="modal hide" id="seed-modal"><div class="modal-header"><h3>Seed a torrent</h3><button class="close" data-dismiss="modal" type="button"></div><form class="modal-body form-horizontal" id="seed-form"><div class="control-group"><label class="control-label" for="metainfo">.torrent</label><div class="controls"><input id="metainfo" name="metainfo" type="file"></div></div><div class="control-group"><label class="control-label" for="files">.torrent</label><div class="controls"><input id="files" name="files" type="file"></div></div></form><div class="modal-footer"><a class="btn" data-dismiss="modal">close</a><input class="btn btn-primary" form="seed-form" type="submit" value="create"></div></div><div class="modal hide" id="about-modal"><div class="modal-header"><h3>Ampere</h3><button class="close" data-dismiss="modal" type="button"></div><div class="modal-body"><pre>Ampere was built by <a href="http://github.com/hcliff" target="_blank">Henry Clifford</a></pre><pre>Building on the efforts of others<ul><li><a href="https://github.com/piranna" target="_blank">Piranna</a></li><li><a href="http://nakkaya.com" target="_blank">Nakkaya</a></li></ul></pre><pre>Ampere is licensed under the MIT license</pre><pre>You can contribute or fork ampere <a href="http://github.com/hcliff/ampere" target="_blank">on github</a></pre></div></div><div class="navbar navbar-fixed-top"><div class="navbar-inner"><div class="container-fluid"><a class="brand">Ampere</a><div class="nav-collapse pull-right"><ul class="nav"><li><a data-toggle="modal" href="#add-modal" role="button">Add Torrent</a></li><li><a data-toggle="modal" href="#create-modal" role="button">Create Torrent</a></li><li><a data-toggle="modal" href="#seed-modal" role="button">Seed Torrent</a></li><li><a data-toggle="modal" href="#about-modal" role="button">About</a></li></ul></div></div></div></div><div class="container-fluid"><a href="http://hcliff.github.com/ampere/Rescue%20You.mp3.torrent" id="demo-torrent"><div class="row-fluid"><div class="info"><img class="promo" src="http://hcliff.github.com/ampere/the_weeknd.jpg"><div class="wrapper"><strong>Click here to start a demo torrent</strong><small>A song from The Weeknds debute mixtape, released for free, 4mb</small></div></div></div></a><div class="row-fluid"><ul class="nav nav-tabs"><li class="active"><a data-toggle="tab" id="downloading-tab">Downloading <span class="badge" id="downloading-count">0</span></a></li><li><a data-toggle="tab" id="completed-tab">Completed <span class="badge" id="completed-count">0</span></a></li></ul><div class="tab-content"><div class="tab-pane-active" id="hom"><table class="table table-striped body"><thead><tr><th class="flex2 name">Name</th><th class="flex1 size">Size</th><th class="flex5 progress-td">Progress</th><th class="flex1 speed">Speed</th><th class="actions"></th></tr></thead><tbody></table></div></div></div></div><script src="http://hcliff.github.com/ampere/cljs/bootstrap.js" type="text/javascript"></script></body></html>
+<html><head><title>Ampere, abusus non tollit usum</title><link href="favicon.ico" rel="shortcut-icon" type="image/x-icon"><link href="css/bootstrap.css" rel="stylesheet" type="text/css"><script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.2.2/bootstrap.min.js" type="text/javascript"></script><script src="http://cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.10/socket.io.min.js" type="text/javascript"></script><script src="http://hcliff.github.com/ampere/js/humane.js" type="text/javascript"></script><script src="http://hcliff.github.com/ampere/js/datachannel.js" type="text/javascript"></script></head><body><div class="modal hide" id="create-modal"><div class="modal-header"><h3>Create a torrent</h3><button class="close" data-dismiss="modal" type="button"></div><form class="modal-body form-horizontal" id="create-form"><div class="control-group"><label class="control-label" for="name">name</label><div class="controls"><input id="name" name="name" placeholder="My great torrent" type="text"></div></div><div class="control-group"><label class="control-label" for="tracker">tracker</label><div class="controls"><input id="tracker" name="tracker" type="url" value="http://ec2-184-73-103-94.compute-1.amazonaws.com:8010"></div></div><div class="control-group"><label class="control-label" for="files">files</label><div class="controls"><div class="files"></div><span class="help-inline">Drag files from your computer to add them</span></div></div></form><div class="modal-footer"><a class="btn" data-dismiss="modal">close</a><input class="btn btn-primary" form="create-form" type="submit" value="create"></div></div><div class="modal hide" id="add-modal"><div class="modal-header"><h3>Add a torrent</h3><button class="close" data-dismiss="modal" type="button"></div><form class="modal-body form-horizontal" id="add-form"><div class="control-group"><label class="control-label" for="metainfo">.torrent</label><div class="controls"><input id="metainfo" name="metainfo" type="file"><span class="help-block">Or drag a file from your computer</span></div></div></form><div class="modal-footer"><a class="btn" data-dismiss="modal">close</a><input class="btn btn-primary" form="add-form" type="submit" value="create"></div></div><div class="modal hide" id="seed-modal"><div class="modal-header"><h3>Seed a torrent</h3><button class="close" data-dismiss="modal" type="button"></div><form class="modal-body form-horizontal" id="seed-form"><div class="control-group"><label class="control-label" for="metainfo">.torrent</label><div class="controls"><input id="metainfo" name="metainfo" type="file"></div></div><div class="control-group"><label class="control-label" for="files">.torrent</label><div class="controls"><input id="files" name="files" type="file"></div></div></form><div class="modal-footer"><a class="btn" data-dismiss="modal">close</a><input class="btn btn-primary" form="seed-form" type="submit" value="create"></div></div><div class="modal hide" id="about-modal"><div class="modal-header"><h3>Ampere</h3><button class="close" data-dismiss="modal" type="button"></div><div class="modal-body"><pre>Ampere was built by <a href="http://github.com/hcliff" target="_blank">Henry Clifford</a></pre><pre>Building on the efforts of others<ul><li><a href="https://github.com/piranna" target="_blank">Piranna</a></li><li><a href="http://nakkaya.com" target="_blank">Nakkaya</a></li></ul></pre><pre>Ampere is licensed under the MIT license</pre><pre>You can contribute or fork ampere <a href="http://github.com/hcliff/ampere" target="_blank">on github</a></pre></div></div><div class="navbar navbar-fixed-top"><div class="navbar-inner"><div class="container-fluid"><a class="brand">Ampere</a><div class="nav-collapse pull-right"><ul class="nav"><li><a data-toggle="modal" href="#add-modal" role="button">Add Torrent</a></li><li><a data-toggle="modal" href="#create-modal" role="button">Create Torrent</a></li><li><a data-toggle="modal" href="#seed-modal" role="button">Seed Torrent</a></li><li><a data-toggle="modal" href="#about-modal" role="button">About</a></li></ul></div></div></div></div><div class="container-fluid"><div class="row-fluid" id="alerts"></div><a href="http://hcliff.github.com/ampere/Rescue%20You.mp3.torrent" id="demo-torrent"><div class="row-fluid"><div class="info"><img class="promo" src="http://hcliff.github.com/ampere/the_weeknd.jpg"><div class="wrapper"><strong>Click here to start a demo torrent</strong><small>A song from The Weeknds debute mixtape, released for free, 4mb</small></div></div></div></a><div class="row-fluid"><ul class="nav nav-tabs"><li class="active"><a data-toggle="tab" id="downloading-tab">Downloading <span class="badge" id="downloading-count">0</span></a></li><li><a data-toggle="tab" id="completed-tab">Completed <span class="badge" id="completed-count">0</span></a></li></ul><div class="tab-content"><div class="tab-pane-active" id="hom"><table class="table table-striped body"><thead><tr><th class="flex2 name">Name</th><th class="flex1 size">Size</th><th class="flex5 progress-td">Progress</th><th class="flex1 speed">Speed</th><th class="actions"></th></tr></thead><tbody></table></div></div></div></div><script src="http://hcliff.github.com/ampere/cljs/bootstrap.js" type="text/javascript"></script></body></html>
View
@@ -22,13 +22,13 @@
return the result"
[f c1]
(async [success-callback]
- (let [results (atom [])]
+ (let [results (atom {})
+ c1 (map-indexed vector c1)]
; Apply the given function to every collection element
- (doseq [item c1]
+ (doseq [[index item] c1]
((f item) (fn [data]
- (swap! conj results data)
+ (swap! results assoc index data)
; If every item has finished its async function
- (.log js/console "hurrarh!" data (count results) (count collection))
- (if (= (count results) (count collection))
- (success-callback @results)))))
- results)))
+ (.log js/console "hurrarh!" data (count @results) (count c1))
+ (if (= (count @results) (count c1))
+ (success-callback (vals @results)))))))))
@@ -43,7 +43,7 @@
ICounted
; Return the number of bits in the bitfield
- (-count [_] (* 8 (count byte-array)))
+ (-count [_] (- (* 8 (count byte-array)) i))
)
@@ -19,8 +19,12 @@
; Does this file contain a given block index
(-lookup [this k]
(-lookup this k nil))
+ ; H.C todo, impliment nth-child and clean this up
(-lookup [this k not-found]
- (-contains-key? this k))
+ ; (js* "debugger;")
+ (if (-contains-key? this k)
+ true
+ not-found))
Fn
IFn
@@ -33,9 +37,9 @@
IAssociative
(-contains-key? [this k]
- "Check if a block-index is required by this file"
- (if-not (nil? meta)
- (<= (meta :block-start) k (meta :piece-end))))
+ "Check if a piece-index is required by this file"
+ (and (not (nil? meta))
+ (<= (meta :piece-start) k (meta :piece-end))))
IHash
(-hash [o]
@@ -72,7 +76,7 @@
)
-(defn piece
+(defn blocks->piece
"Build a piece from its component blocks"
[blocks]
(let [blocks (sort :begin blocks)
@@ -82,4 +86,7 @@
; Then add all the pieces at their correct offset
(doseq [block blocks]
(.set byte-array (block :data) (block :begin)))
- (Piece. nil byte-array nil)))
+ (piece byte-array)))
+
+(defn piece [byte-array]
+ (Piece. nil byte-array nil))
@@ -4,20 +4,24 @@
[torrent-client.client.bitfield :as bitfield]
[goog.events :as events]
[goog.events.FileDropHandler :as FileDropHandler]
+ [goog.Uri :as Uri]
+ [goog.Uri.QueryData :as QueryData]
[goog.string :as gstring]
[clojure.string :as string]
[waltz.state :as state]
- [crate.core :as crate])
+ [crate.core :as crate]
+ [crate.form :as form])
(:use
- [jayq.core :only [$ on attr document-ready empty text]]
+ [jayq.core :only [$ on attr document-ready empty text val prepend]]
+ [jayq.util :only [clj->js]]
[torrent-client.jayq.core :only [append input-files event-files modal tab css]]
[torrent-client.client.waltz :only [machine]]
[torrent-client.client.pieces :only [files]]
[torrent-client.client.torrents :only [torrents]]
[crate.binding :only [bound]]
[goog.format :only [numBytesToString]])
(:use-macros
- [async.macros :only [let-async]]
+ [async.macros :only [async let-async]]
[waltz.macros :only [in out defstate defevent]]
[crate.def-macros :only [defpartial]]))
@@ -42,12 +46,14 @@
(def $document ($ js/document))
(def $window ($ js/window))
+(def $body ($ "body"))
(def $add-modal ($ "#add-modal"))
(def $add-form ($ "#add-form"))
(def $create-modal ($ "#create-modal"))
(def $create-form ($ "#create-form"))
(def $seed-modal ($ "#seed-modal"))
(def $seed-form ($ "#seed-form"))
+(def $alerts ($ "#alerts"))
(def $torrents ($ "tbody"))
(def $demo-torrent ($ "#demo-torrent"))
@@ -99,13 +105,43 @@
(.modal $create-modal "hide")
(.modal $add-modal "hide")))
+(dispatch/react-to #{:torrent-built} (fn [_ [metainfo data]]
+ (.modal $add-modal "hide")
+ (.modal $create-modal "hide")
+ ; See the magnet spec for an explanation of these values
+ ; http://en.wikipedia.org/wiki/Magnet_URI_scheme
+ (let [base-url "http://hcliff.github.com/ampere"
+ querystring {
+ :tr (metainfo :announce)
+ :xt (str "urn:btih" (hash metainfo))
+ :dn (metainfo :name)}
+ querydata (QueryData/createFromMap (clj->js querystring))
+
+ ; Build the .torrent for the user to download
+ torrent-file (js/Blob. data)
+
+ ; Render the modal dialog
+ modal-content {
+ :magnet-url (str (.setQueryData (Uri/parse base-url) querydata))
+ :torrent-file-url (.createObjectURL (.-URL js/window) torrent-file)
+ :torrent-file-name (str (metainfo :name) ".torrent")
+ :name (metainfo :name)}
+ $built-modal ($ (built-modal modal-content))]
+ ; Unlike other modals there can be multiple built modals
+ ; so it must be created as a partial
+ (prepend $body $built-modal)
+ (.modal $built-modal "show"))))
+
(on $create-form :submit (fn [e]
(.preventDefault e)
+ (.log js/console "tracker" (val ($ "[name=tracker]" $create-form)))
(dispatch/fire :create-torrent {
:name (val ($ "[name=name]" $create-form))
:tracker (val ($ "[name=tracker]" $create-form))
:files @create-form-files})
- (modal $create-modal "hide")))
+ (modal $create-modal "hide")
+ (let [building-alert (alert "Building your file...")]
+ (append $alerts building-alert))))
(on $create-modal :hide (fn [e]
; Clear input values
@@ -155,20 +191,38 @@
(.send xhr))))
;;************************************************
-;; Templating
+;; Templates
;;************************************************
-(def elements (atom {}))
-
-(dispatch/react-to #{:started-torrent} (fn [_ torrent]
- (let [element (torrent-row torrent)]
- ; Render the torrent row and add it to the atom
- (swap! elements assoc (@torrent :pretty-info-hash) element)
- (append $torrents element))))
+(defpartial alert [content]
+ [:div.alert
+ [:button.close {:type "button" :data-dismiss "alert"} "×"]
+ content])
(defpartial torrent-file-badge [content]
[:span.label (.-name content)])
+
+(defpartial built-modal [content]
+ [:div.modal
+ [:div.modal-header
+ [:h3 (str (content :name) " is ready to share!")]
+ [:button.close {:type "button" :data-dismiss "modal"}]]
+ [:form#create-form.modal-body.form-horizontal
+ [:div.control-group
+ (form/label {:class "control-label"} "link" "download link")
+ [:div.controls
+ (form/text-field {:value (content :magnet-url) :class "input-xlarge"} "link")]]
+ [:div.control-group
+ [:div.controls
+ [:a#built-download {
+ :download (content :torrent-file-name)
+ :title (str "download " (content :torrent-file-name))
+ :href (content :torrent-file-url)}
+ "or download the .torrent"]]]]
+ [:div.modal-footer
+ [:a.btn {:data-dismiss "modal"} "close"]]])
+
(defn bound-class
"Given a func that returns boolean display a css class"
[torrent func class-name & [negative-class-name]]
@@ -232,6 +286,18 @@
[:i.icon-trash]]
]]])
+;;************************************************
+;; Rendering content
+;;************************************************
+
+(def elements (atom {}))
+
+(dispatch/react-to #{:started-torrent} (fn [_ torrent]
+ (let [element (torrent-row torrent)]
+ ; Render the torrent row and add it to the atom
+ (swap! elements assoc (@torrent :pretty-info-hash) element)
+ (append $torrents element))))
+
(defn active? [torrent]
"Take either a collection or atom and return it's active status"
(if-not (coll? torrent)
Oops, something went wrong.

0 comments on commit cb47a18

Please sign in to comment.