Commit 31a90612 authored by charlyjazz's avatar charlyjazz
Browse files

Input file to server

parent ff855182
......@@ -2,7 +2,11 @@
static/javascript/bin/bundle.js
/env/
/.idea/
app/static/files/
package-lock.json
*pyc
\ No newline at end of file
*pyc
!app/static/files/.gitkeep
from flask_socketio import SocketIO
from flask import Flask
app = Flask(__name__)
app.config['FILEDIR'] = 'static/files/'
socketio = SocketIO(app)
\ No newline at end of file
from events import socketio
from flask import Flask
from config import DevelopmentConfig
def create_app():
app = Flask(__name__)
app.config.from_object(DevelopmentConfig)
socketio.init_app(app)
from views import app as application
app.register_blueprint(application)
return app
\ No newline at end of file
import os, string, random
basedir = os.path.abspath(os.path.dirname(__file__))
class Config(object):
SECRET_KEY = ''.join(random.choice(string.ascii_uppercase + string.digits) for x in xrange(32))
class DevelopmentConfig(Config):
FILEDIR = basedir + '/static/files/'
\ No newline at end of file
from . import socketio
from flask import current_app
from flask_socketio import SocketIO
from flask import current_app, request
import os, uuid, json
@socketio.on('start-transfer', namespace='/uploads')
socketio = SocketIO()
@socketio.on('connected')
def connected():
print "%s connected" % (request.sid)
@socketio.on('disconnect')
def disconnect():
print "%s disconnected" % (request.sid)
@socketio.on('start-transfer')
def start_transfer(filename, size):
"""Process an upload request from the client."""
_, ext = os.path.splitext(filename)
if ext in ['.exe', '.bin', '.js', '.sh', '.py', '.php']:
return False # reject the upload
id = uuid.uuid4().hex # server-side filename
with open(current_app.config['FILEDIR'] + id + '.json', 'wt') as f:
json.dump({'filename': filename, 'size': size}, f)
......@@ -17,7 +31,7 @@ def start_transfer(filename, size):
return id + ext # allow the upload
@socketio.on('write-chunk', namespace='/uploads')
@socketio.on('write-chunk')
def write_chunk(filename, offset, data):
"""Write a chunk of data sent by the client."""
if not os.path.exists(current_app.config['FILEDIR'] + filename):
......
This diff is collapsed.
......@@ -8,36 +8,13 @@ class App extends Component {
constructor(props) {
super(props);
this.state = {
progress: 0
}
this.state = {}
}
progressDown = () => {
this.setState({
progress: this.state.progress - 1
})
};
progressUp = () => {
this.setState({
progress: this.state.progress + 1
})
};
render() {
return (
<div className="App">
<DropFileInput />
<Line percent={this.state.progress}
strokeWidth="1"
strokeColor="#48bd96"
strokeLinecap='square'
trailColor="#2fb9e224"/>
<button onClick={this.progressUp}>Up</button>
<button onClick={this.progressDown}>Down</button>
</div>
);
}
......
import io from '../helpers/io'
function readFileChunk (ctx, offset) {
let length = 0;
let end_offset = ctx.props.file.size + length; // TODO: What is length?
if (end_offset > ctx.props.file.size)
end_offset = ctx.props.file.size;
let r = new FileReader();
r.onload = function(file, offset, length, event) {
if (event.target.error != null) {
onReadError(ctx, 'Error in readFileChunk');
}
else {
onReadSuccess(ctx, end_offset, event.target.result);
}
}.bind(r, ctx.props.file, offset, length);
r.readAsArrayBuffer(ctx.props.file.slice(offset, end_offset));
}
const onReadSuccess = (ctx, offset, data) => {
// Read success callback
if (ctx.state.done) return;
io.emit('write-chunk', ctx.state.server_filename, offset, data, function(offset, ack) {
if (!ack) onReadError(ctx, 'Transfer aborted by server')
}.bind(this, offset));
let end_offset = offset + length,
color = '#48bd9666',
width = parseInt(300 * end_offset / ctx.props.file.size);
ctx.setState({
progress: {
...ctx.state.progress,
percent: width,
color: color
}
});
if (end_offset < ctx.props.file.size) {
readFileChunk(ctx, ctx.props.chunk_size);
}
else {
ctx.state.done = true;
}
};
function onReadError(ctx, message) {
// Read error callback
console.log(message);
ctx.setState({
progress: {
...ctx.state.progress,
color: '#ff000073'
}
});
ctx.setState({done: true});
}
module.exports = {
readFileChunk,
onReadSuccess,
onReadError
};
\ No newline at end of file
import React, { Component } from 'react';
import File from './File';
import { readFileChunk, onReadSuccess, onReadError } from '../actions'
export default class DropFileInput extends Component {
constructor(props) {
......@@ -9,7 +7,8 @@ export default class DropFileInput extends Component {
this.state = {
chunk_size: 64 * 1024,
files: []
files: [],
uploading: false
}
}
......@@ -25,11 +24,17 @@ export default class DropFileInput extends Component {
}, () => {console.log(this.state)} )
}
};
toggleUpload = () => {
this.setState({
uploading: !this.state.uploading
})
};
render() {
let files = this.state.files.map((file, index) => {
return <File file={file} key={index}/>
return <File file={file} key={index} chunk_size={this.state.chunk_size} uploading={this.state.uploading}/>
});
return (
......@@ -43,8 +48,8 @@ export default class DropFileInput extends Component {
{files}
</div>
<div className="Div-Button">
<button>
Upload File{this.state.files.length > 1 && "s"}
<button onClick={this.toggleUpload}>
{!this.state.uploading ? 'Upload File' : 'Uploading'}
</button>
</div>
</div>
......
import React, { Component } from 'react'
import { Line } from 'rc-progress'
import { readFileChunk, onReadSuccess, onReadError } from '../actions'
import io from '../helpers/io'
export default class File extends Component {
constructor(props) {
super(props);
this.state = {
uploading: props.uploading,
done: false,
server_filename: '',
progress: {
percent: 0
}
};
this.uploadFile = () => readFileChunk(this, 0);
this.onReadError = () => onReadError(this, 'Upload rejected by server');
}
componentWillReceiveProps(nextProps) {
const that = this;
if (nextProps.uploading) {
io.emit('start-transfer', this.props.file.name, this.props.file.size, function(filename) {
if (!filename) {
// The server rejected the transfer
that.onReadError();
}
else {
that.setState({server_filename: filename}, () => {
that.uploadFile();
});
}
}.bind(this.props.file));
}
}
render() {
return (
<div className="File">
<span className="File-name">Name: {this.props.file.name}</span>
<span className="File-type">Type: {this.props.file.type}</span>
{ this.props.uploading &&
<Line percent={this.state.progress.percent}
strokeColor={this.state.progress.color}
strokeWidth="1"
strokeLinecap='square'
trailColor="#2fb9e224"/>
}
</div>
)
}
}
var io = require('socket.io-client')('http://' + document.domain + ':' + location.port);
io.on('connect', function() {
io.emit('connected');
console.log('connected')
});
export default io;
\ No newline at end of file
from flask import render_template, Blueprint
app = Blueprint('main', __name__)
@app.route('/')
def index():
return render_template('index.html')
\ No newline at end of file
......@@ -4,7 +4,6 @@ Flask-SocketIO==2.9.2
itsdangerous==0.24
Jinja2==2.9.6
MarkupSafe==1.0
pkg-resources==0.0.0
python-engineio==1.7.0
python-socketio==1.8.1
six==1.11.0
......
from flask import render_template
from . import app
from app import create_app, socketio
@app.route('/')
def index():
return render_template('index.html')
\ No newline at end of file
app = create_app()
socketio.run(app, debug=True, port=8000)
#!/bin/sh
source bin/activate
pip install -r requirements.txt
export FLASK_DEBUG=1
export FLASK_APP=server.py
flask run
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment