How do I integrate Plupload with Flask? - javascript

I created a Flask application that handles large video uploads, and manipulates them. My app works just fine, until I deploy it onto a web hosting (I use PythonAnywhere).
PythonAnywhere limits uploads to be a maximum of 100MB in size, which is way too small for my app, since client-side uploads could reach 6GB in size.
My idea is to split the users' videos to chunks of under 100MB each before I save the video they uploaded.
I came across this JavaScript API named Plupload, which suits my situation and would solve my problem.
The issue is, that I am not familiar with JavaScript to the level that I would be able to figure out how to integrate Plupload with my current Flask app; thus, I need help with it.
Bits and pieces of my current files, enough for a Minimal, Reproducible Example.
templates/upload.html:
<script>
function myfunction(event) {
const video = document.createElement('video')
video.src = URL.createObjectURL(event.files[0]);
var url = event.value
if (url.substring(url.lastIndexOf('.') + 1).toLowerCase() == 'mp4') {
// pass
} else {
window.alert("Only h264 codec .mp4 filetypes, and 1920x1080 dimension videos that are under 6GB in size are supported. Please upload another file.")
return
}
if (event.files[0].size / 1024 / 1024 / 1024 >= 6) {
window.alert("Only h264 codec .mp4 filetypes, and 1920x1080 dimension videos that are under 6GB in size are supported. Please upload another file.")
return
}
video.addEventListener( "loadeddata", function (e) {
var width = this.videoWidth,
height = this.videoHeight;
console.log(`${width}x${height}`)
if (width === 1920 && height === 1080) {
var modal = document.getElementById("myModal");
modal.style.display = "block";
document.forms["myform"].submit();
} else {
window.alert("Only h264 codec .mp4 filetypes, and 1920x1080 dimension videos that are under 6GB in size are supported. Please upload another file.")
}
}, false );
}
</script>
<form id='myform' name='myform' action = "{{ url_for('upload') }}" method = "POST"
enctype = "multipart/form-data">
<label for="file" class="custom-file-upload">
<i class="button button2">Upload Match Video</i>
</label>
<input id="file" type="file" name="file" accept=".mp4" onchange="myfunction(this)" style="display: none"/>
</form>
flask_app.py:
#app.route('/upload', methods=['GET', 'POST'])
def upload():
if request.method == "GET":
return render_template('upload.html', static_folder='static')
f = request.files['file']
session['filename'] = secure_filename(f.filename)
session['path_to_video'] = os.path.join(app.config['UPLOAD_FOLDER'], session['filename'])
f.save(session['path_to_video'])
return redirect("/video")
Directory structure:
app/
static/
uploaded_file.mp4
templates/
upload.html
flask_app.py
My goal:
app/
static/
uploaded_file_chunk1.mp4
uploaded_file_chunk2.mp4
uploaded_file_chunk3.mp4
templates/
upload.html
flask_app.py

Related

how to save an mp3 file on live website in ASP.net?

I get the complete video data from youtube link which I then convert to MP3 format. All of this works on localhost but is not working on the when I put it on live.
View:
<form method="post" style="display:inline" action="#Url.Action("DownloadVideoFunc","Home",new {#link=item.Link})">
#Html.Hidden("returnURL", this.Request.RawUrl)
<button onclick="CallToastFunction();" type="submit" class="btn btn-outline-primary">
Download MP3 too
</button>
</form>
This is the controller function:
var youTube = YouTube.Default; // starting point for YouTube actions
var video = youTube.GetVideo(link); // gets a Video object with info about the video
var path= Path.GetTempPath();
System.IO.File.WriteAllBytes(path + video.FullName, video.GetBytes());//#"D:\"
var inputFile = new MediaFile { Filename = path + video.FullName };
var outputFile = new MediaFile { Filename = $"{path + video.Title}.mp3" };
using (var engine = new Engine())
{
engine.GetMetadata(inputFile);
engine.Convert(inputFile, outputFile);
}
System.IO.File.Delete(path + video.FullName);
It doesn't save the files and gives error. I can work with any JS function or C# function for getting the file to download.

Javascript: Use <input type="file"/> to compute SHA256 file hash

Motivation: I want to make a browser-based hashing utility so users can compute file hashes without installing software.
The approach I'm considering is a static page with "a file upload button" (except no upload takes place): the user picks a file, and the script computes and displays its hash.
So let's say we have this element on the page:
<input id="file-hasher" type="file" />
This creates a button that allows the users of the web page to select a file via an OS "File open..." dialog in the browser.
Let's say the user clicks said button, selects a file in the dialog, then clicks the "Ok" button to close the dialog.
The selected file name is now stored in:
document.getElementById("file-hasher").value
Here, I'm hoping to use a library like https://github.com/bitwiseshiftleft/sjcl/ to compute the hash of the chosen file. Is there a way to do this or does the browser's security model get in the way?
Yes, you can select a file using the file element, and take a hash of the file locally, 'in-browser', using javascript. The browser's security model does not prevent this; and the hash function from the native Web Crypto API can be used, so there is no need for any external crypto libraries.
Here is a working example:
function hashfile() {
readbinaryfile(fileselector.files[0])
.then(function(result) {
result = new Uint8Array(result);
return window.crypto.subtle.digest('SHA-256', result);
}).then(function(result) {
result = new Uint8Array(result);
var resulthex = Uint8ArrayToHexString(result);
divresult.innerText = 'result: ' + resulthex;
});
}
function readbinaryfile(file) {
return new Promise((resolve, reject) => {
var fr = new FileReader();
fr.onload = () => {
resolve(fr.result)
};
fr.readAsArrayBuffer(file);
});
}
function Uint8ArrayToHexString(ui8array) {
var hexstring = '',
h;
for (var i = 0; i < ui8array.length; i++) {
h = ui8array[i].toString(16);
if (h.length == 1) {
h = '0' + h;
}
hexstring += h;
}
var p = Math.pow(2, Math.ceil(Math.log2(hexstring.length)));
hexstring = hexstring.padStart(p, '0');
return hexstring;
}
<h2>File Hash</h2>
<div>
Select file to take hash of:
<br/>
<input type="file" id="fileselector" onchange="javascript:hashfile();">
</div>
<br/>
<div id="divresult"></div>
The standard browser security model allows you to have the user pick a file and do what you will with it. I'm an older guy and thought surely this kinda mingling with a user's parts would require additional hoops/consent. So #ceving 's answer was best: "Do it and you will see."
Here's a link to a good article: https://humanwhocodes.com/blog/2012/05/08/working-with-files-in-javascript-part-1/
Apologies for not trying first before posting.

Angular upload image and display to user

Id like to implement a UI where the user selects an image and that image is instantly displayed back to them for review. The user would have to click "submit" to upload/save the image to their profile.
I am having issues with the "instantly display back to the user part".
I am using angular FormData with the following markup & controller:
MARKUP
<input id="chooseFile" type="file" file-model="picFile" />
<img src="{{uploadedImage}}" /> <!-- this populates with filename but what is the path?? -->
CONTROLLER
angular.element('#chooseFile').change(function(){
var file = $scope.picFile; // this comes up "undefined" since file is still uploading when this is fired
$scope.uploadedImage = file.name;
});
I have 2 primary issues with the above code (described in comments):
1) In the controller, file comes up undefined obviously because even the smallest file takes >0s to upload while the callback is fired pretty much instantaneously. I got it work using $timeout but thats a bit of a lame hack. How can I have the callback wait until the file is uploaded??
2) The idea is to upload the file and display it in the img tag using Angular's data-binding. This works in that src is populated with the filename, but what is the path of the img. Some temporary location in cache or something?? Obviously I havent set a path to move the file yet.
Any help appreciated!
I also needed this feature, some how I manage to display image instantly.
angular.module('HelloWorldApp', [])
.controller('HelloWorldController', function($scope) {
$scope.uploadavtar = function(files) {
//var fd = new FormData();
//Take the first selected file
//fd.append("file", files[0]);
var imagefile = document.querySelector('#file');
if (imagefile.files && imagefile.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#temp_image')
.attr('src', e.target.result);
};
reader.readAsDataURL(imagefile.files[0]);
this.imagefile = imagefile.files[0];
}else{
console.log("Image not selected");
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="HelloWorldApp">
<div ng-controller="HelloWorldController">
<input type="file" id="file" onchange="angular.element(this).scope().uploadavtar(this.files)"/>
</div>
<img src="" id="temp_image" width="100">
<div>
</div>
</div>
I was using laravel + Angularjs so another related post to store image is : https://stackoverflow.com/a/34830307/2815635

CSS selector not working in JSP page embedded JavaScript to set div background

I'm trying to implement an image uploader which will allow users to upload pictures and set them as the background of a div (in this case .mm11 is a post-it style card which contains a 'choose file' and an 'upload file' button and starts off with no background image
I have worked out how to upload the pictures to a folder in my tomcat directory, and I can display them using
<img src='uploads/<%=fileName%>' />
but I'm struggling to set the picture as the background! Any advice would be much appreciated, have been struggling with this for hours..
<div id="uploadsContainer" class="mm11Container" style="top:100px; left: 100px;">
<div id="g" class="mm11 card front face">
<!--button id="uploadbutton" type="button">Upload Image11</button-->
<form action="
<%# page import="java.io.*,java.util.*, javax.servlet.*" %>
<%# page import="javax.servlet.http.*" %>
<%# page import="org.apache.commons.fileupload.*" %>
<%# page import="org.apache.commons.fileupload.disk.*" %>
<%# page import="org.apache.commons.fileupload.servlet.*" %>
<%# page import="org.apache.commons.io.output.*" %>
<%
File file ;
String fileName = "";
int maxFileSize = 5000 * 1024;
int maxMemSize = 5000 * 1024;
ServletContext context = pageContext.getServletContext();
String filePath = context.getInitParameter("file-upload");
// Verify the content type
String contentType = request.getContentType();
//if (contentType.indexOf("multipart/form-data") >= 0) {
DiskFileItemFactory factory = new DiskFileItemFactory();
// maximum size that will be stored in memory
factory.setSizeThreshold(maxMemSize);
// Location to save data that is larger than maxMemSize.
factory.setRepository(new File("uploads/"));
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setHeaderEncoding("ISO-8858-2");
// maximum file size to be uploaded.
upload.setSizeMax( maxFileSize );
try {
// Parse the request to get file items.
List fileItems = upload.parseRequest(request);
// Process the uploaded file items
Iterator iter = fileItems.iterator();
while ( iter.hasNext () ) {
FileItem fi = (FileItem)iter.next();
if ( !fi.isFormField () ) {
// Get the uploaded file parameters
String fieldName = fi.getFieldName();
fileName = fi.getName();
boolean isInMemory = fi.isInMemory();
long sizeInBytes = fi.getSize();
// Write the file
if( fileName.lastIndexOf("\\") >= 0 ){
file = new File( filePath + fileName.substring( fileName.lastIndexOf("\\"))) ;
}
else {
file = new File( filePath + fileName.substring(fileName.lastIndexOf("\\")+1)) ;
}
fi.write( file ) ;
}
}
} catch(Exception ex) {
System.out.println(ex);
}
%>"
method="post" enctype="multipart/form-data">
<input class="uploads" type="file" name="file" size="50"/>
<input class="uploadFile" type="submit" value="Upload File"/>
<script type="text/javascript">
/*$(this).parents().eq(2).css('background-size', '100%');$(this).parents().eq(2).empty().css('background-image', 'uploads/<%=fileName%>');*/
$('.mm11').css('background-image', 'uploads/<%=fileName%>');
alert("here filename = "+'uploads/<%=fileName%>');
</script>
<!--img src='uploads/<%=fileName%>' /-->
</form>
</div>
</div>
I have also tried ajax by replacing the code in the script tags with
var ajx=new XMLHttpRequest();
ajx.onreadystatechange=function()
{
if (ajx.readyState==4 && ajx.status==200)
{
$("#g").css('background-image', 'uploads/<%=fileName%>');
}
}
ajx.open("GET","index.jsp",true);
ajx.send();
But this doesn't work either..to test I was correctly accessing the div, I added this to the css line:
$("#g").empty().css('background-image', 'uploads/<%=fileName%>');
which does clear the div...so why isn't the background image being set??
Another possibly related problem is that if I don't include the line
if (contentType.indexOf("multipart/form-data") >= 0)
(currently commented out), the alert pops up anyway the first time I visit the page, and fileName is set to the last file I tried to upload. However, if I DO include it, I get a Null Pointer Exception as contentType is null...does anyone know what this is about?
Your code:
background-image', 'uploads/<%=fileName%>'
Correct code:
background-image:url("uploads/<%=fileName%");
slightly different.
Hope it helps.

Image size validation

is it possible to validate file image size with jquery class orjavascript ?
Can i do that ? I made some research but did not reach anything
Thank you
If you want to check image file being uploaded on client side, check HTML5 File API. Here are some samples at:
http://www.html5rocks.com/en/tutorials/file/dndfiles/
You can get file size, find it's type and access binary content.
I was using File API to read EXIF headers from image without uploading image to server.
Here is a source code:
https://gist.github.com/980275/85da4a96a3bb23bae97c3eb7ca777acdea7ed791
Try this:
<input type="file" id="loadfile" />
<input type="button" value="find size" onclick="Size()" />
Script:
function Size() {
if ( $.browser.msie ) {
var a = document.getElementById('loadfile').value;
$('#myImage').attr('src',a);
var imgbytes = document.getElementById('myImage').fileSize;
var imgkbytes = Math.round(parseInt(imgbytes)/1024);
alert(imgkbytes+' KB');
}else {
var fileInput = $("#loadfile")[0];
var imgbytes = fileInput.files[0].fileSize; // Size returned in bytes.
var imgkbytes = Math.round(parseInt(imgbytes)/1024);
alert(imgkbytes+' KB');
}
}

Categories