Selaa lähdekoodia

File upload, need some style

Antoine Leroyer 11 vuotta sitten
vanhempi
commit
b98eef535c
7 muutettua tiedostoa jossa 204 lisäystä ja 10 poistoa
  1. 1 0
      lib/rSeed.rb
  2. 5 3
      lib/rSeed/server.rb
  3. 44 0
      public/css/dropbox.css
  4. 21 1
      public/js/custom.js
  5. 127 0
      public/js/dropbox.js
  6. 5 6
      views/index.haml
  7. 1 0
      views/layout.haml

+ 1 - 0
lib/rSeed.rb

@@ -17,6 +17,7 @@ require "yaml"
 require "rest_client"
 require "nokogiri"
 require "open-uri"
+require "base64"
  
 require "rSeed/server"
 require "rSeed/config"

+ 5 - 3
lib/rSeed/server.rb

@@ -142,10 +142,12 @@ module RSeed
     post '/add/:type' do
       case params[:type]
       when 'file'
-        File.open(@config.get("data_path") + "/" + params[:torrentFile][:filename], "w") do |f|
-          f.write(params['torrentFile'][:tempfile].read)
+        filename = "#{@config.get("data_path")}/#{params[:filename]}"
+        encoding = Base64.decode64(params[:data]).to_s.encoding.name
+        File.open("#{filename}", "w:#{encoding}") do |f|
+          f.puts Base64.decode64(params[:data])
         end
-        return "Torrent added !" if @rtorrent.add(params[:torrentFile][:filename])
+        200 if @rtorrent.add("#{File.join(settings.root, filename)}")
       when 'link'
         return "Torrent added !" if @rtorrent.add(params[:link])
       when 't411'

+ 44 - 0
public/css/dropbox.css

@@ -0,0 +1,44 @@
+#dropbox {
+position: relative;
+}
+ 
+#dropbox > input {
+position: absolute;
+top: 0px;
+right: 0px;
+bottom: 0px;
+left: 0px;
+width: 100%;
+height: 100%;
+opacity: 0;
+}
+ 
+#dropbox > input:hover, #dropbox:hover {
+cursor: pointer;
+}
+
+
+#dropbox {
+  padding: 15px 0px;
+  border: 2px solid #ddd;
+  text-align: center;
+  color: #999;
+  font-size: 1.3em;
+  font-family: Arial, sans-serif;
+  transition: background-color 0.15s;
+}
+ 
+#dropbox.active {
+  border-color: #3a3;
+  color: #777;
+  background-color: #dfd;
+}
+ 
+.upload-progress {
+  margin-bottom: 10px;
+}
+ 
+.upload-progress .desc {
+  font-size: 0.85em;
+  color: #555;
+}

+ 21 - 1
public/js/custom.js

@@ -56,7 +56,7 @@ $(document).ready(function() {
         alertify.success( data );
     });
   });
-  
+
   refreshList();
   refreshUpDownTotal();
   diskInfo();
@@ -116,3 +116,23 @@ function bytesToSize(bytes, speed) {
 function poppupAddTorrent(){
   window.open("/add", "Ajout d'un torrent", config='height=100, width=400, toolbar=no, menubar=no, scrollbars=no, resizable=no, location=no, directories=no, status=no');
 }
+
+
+
+
+
+// Dropbox for files.
+var box = document.getElementById('dropbox')
+  
+var dropbox = new Dropbox(box, '/add/file')
+// Optional settings and callbacks
+dropbox.max_size = 2 // MB
+dropbox.max_concurrent = 1 // Do not upload more than two files at a time
+dropbox.mime_types = /(torrent)/i // Only allow pngs, jpgs, and gifs
+dropbox.success = function(file, response) {
+  alertify.success(file.name + ' added !');
+  $('#addModal').foundation('reveal', 'close');
+}
+dropbox.error = function(file, status, response) {
+  alertify.error(file.name + ' failed to upload');
+}

+ 127 - 0
public/js/dropbox.js

@@ -0,0 +1,127 @@
+function Dropbox(dropbox, url) {
+  this.box = dropbox;
+  this.url = url;
+  this.queue = [];
+  this.num_current_uploads = 0;
+   
+  // Add clickable file picker
+  this.picker = document.createElement('input');
+  this.picker.setAttribute('type', 'file');
+  this.box.appendChild(this.picker);
+  // Add progress bar container
+  this.uploads = document.createElement('div');
+  this.box.parentNode.insertBefore(this.uploads, this.box.nextSibling);
+   
+  // Optional defaults
+  this.max_concurrent = 2; // Queue uploads after n concurrent
+  this.max_size = null; // Max size in MB
+  this.success = null; // Callback on successful upload, passed the response body
+  this.error = null; // Callback on upload failure, passed the error text
+  this.mime_types = null; // A regex to match file mime types
+ 
+  var _this = this;
+  // Init drag and drop handlers
+  this.box.addEventListener("dragenter", function(e) { _this.drag(e, true) }, false);
+  this.box.addEventListener("dragleave", function(e) { _this.drag(e, false) }, false);
+  this.box.addEventListener("dragover", noop, false);
+  this.box.addEventListener("drop", function(e) { _this.drop(e) }, false);
+  this.picker.addEventListener("change", function(e) { _this.drop(e) })
+}
+ 
+Dropbox.prototype.drop = function(e) {
+  this.drag(e, false);
+  var files = (e.dataTransfer || e.target).files;
+  for ( var i=0; i<files.length; i++ )
+    this.handle_file(files[i]);
+}
+ 
+Dropbox.prototype.drag = function(e, active) {
+  noop(e);
+  this.box.className = active ? this.box.className += ' active' : this.box.className.replace(/ ?active/, '');
+}
+ 
+Dropbox.prototype.handle_file = function(file) {
+  // Bad file type
+  if ( this.mime_types && !file.type.match(this.mime_types) ) {
+    alertify.error(file.name + ' is not an allowed file type');
+  // Too large
+  } else if ( this.max_size && (file.size / 1024 / 1024) > this.max_size ) {
+    alertify.error(file.name + ' is too large; maximum is ' + this.max_size.toFixed(2) + ' MB');
+  } else {
+    file.label = this.add_label(file);
+    // Enqueue it
+    if ( this.max_concurrent > -1 && this.num_current_uploads >= this.max_concurrent )
+    this.queue.push(file);
+    // Upload it
+    else this.process_file(file);
+  }
+}
+ 
+Dropbox.prototype.process_file = function(file) {
+  this.num_current_uploads += 1;
+  var _this = this;
+  var reader = new FileReader();
+  reader.onload = function(e) {
+    var file_contents = e.target.result.split(',')[1];
+    _this.upload_file(file, file_contents);
+  }
+  reader.readAsDataURL(file);
+}
+ 
+Dropbox.prototype.upload_file = function(file, file_contents) {
+  // Build form
+  var data = new FormData();
+  data.append('filename', file.name);
+  data.append('mimetype', file.type);
+  data.append('data', file_contents);
+  data.append('size', file.size);
+ 
+  var _this = this;
+  var xhr = new XMLHttpRequest();
+  // Update progress bar (if available)
+  if ( xhr.upload ) xhr.upload.addEventListener('progress', function(e) { _this.handle_upload_progress(e, file.label) }, false)
+  xhr.open('POST', this.url);
+  xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
+  xhr.onreadystatechange = function(e) {
+    if ( xhr.readyState === 4 ) {
+      // Success
+      if (xhr.status === 200) {
+        file.label.getElementsByClassName('percent')[0].innerHTML = '100%';
+        if ( _this.success ) _this.success(file, xhr.responseText);
+      // Error
+      } else {
+        file.label.getElementsByClassName('percent')[0].innerHTML = 'Error';
+        if ( _this.error ) _this.error(file, xhr.statusText, xhr.responseText);
+      }
+      // Pop next upload off the queue
+      _this.num_current_uploads -= 1;
+      if ( _this.queue.length > 0 ) _this.process_file(_this.queue.shift())
+      // Remove the label in 1 second
+      setTimeout(function() { _this.uploads.removeChild(file.label) }, 1000);
+    }
+  }
+  xhr.send(data)
+}
+ 
+Dropbox.prototype.handle_upload_progress = function(e, label) {
+  if ( e.lengthComputable ) {
+    var progress = label.getElementsByTagName('progress')[0];
+    progress.setAttribute('value', e.loaded);
+    progress.setAttribute('max', e.total);
+    label.getElementsByClassName('percent')[0].innerHTML = ((e.loaded / e.total) * 100).toFixed(0) + '%';
+  }
+}
+ 
+Dropbox.prototype.add_label = function(file) {
+  var size = (file.size / 1024 / 1024).toFixed(2);
+  var label = document.createElement('div');
+  label.setAttribute('class', 'upload-progress');
+  label.innerHTML = '<progress value="0" max="100"></progress> <span class="desc">' + file.name + ' - <span class="percent">0%</span> (' + size + ' MB)</span>';
+  this.uploads.insertBefore(label, null);
+  return label;
+}
+ 
+function noop(e) {
+  e.stopPropagation();
+  e.preventDefault();
+}

+ 5 - 6
views/index.haml

@@ -77,12 +77,10 @@
         %p rTorrent doesn't support self-signed cert (for HTTPS).
         %p To use Magnet link be sure DHT is activated in your .rtorrent.rc
     #panel-file.content
-      %form#form-add-file{action: "/"}
-        .row
-          .large-12.columns
-            %input{type: "file"}
-          .large-12.columns
-            %input{type: "submit", value: "Send .torrent"}
+      .row
+        #dropbox.large-12.columns
+          Drag and drop files ! ...or juste click here.
+        #log
     #panel-search.content
       %form#search-engine{action: "/"}
         .row
@@ -101,6 +99,7 @@
 %script{:src => '/js/vendor/jquery.js'}
 %script{:src => '/js/foundation.min.js'}
 %script{:src => '/js/alertify.min.js'}
+%script{:src => '/js/dropbox.js'}
 %script{:src => '/js/custom.js'}
 %script
   $(document).foundation();

+ 1 - 0
views/layout.haml

@@ -6,6 +6,7 @@
     %link{:rel => :stylesheet, :href => "/fonts/foundation-icons/foundation-icons.css", :type => "text/css"}
     %link{:rel => :stylesheet, :href => "/css/alertify.core.css", :type => "text/css"}
     %link{:rel => :stylesheet, :href => "/css/alertify.foundation.css", :type => "text/css"}
+    %link{:rel => :stylesheet, :href => "/css/dropbox.css", :type => "text/css"}
     %script{:type => 'text/javascript', :src => '/js/modernizr.js'}
     %body
       %section{:role => 'main'}