res.sendFile("path") is not accepting firebase storage video URL - html

I'm working on the video stream web app like youtube in firebase hosting and storage in nodejs.
I'm able to host the video player by getting the firebase storage download url location from client side and can play the video. But I don't want my users to see the url by inspecting the web page. For that I made a app.get("/video/videoID") in nodejs express and getting the download url server side, and I'm able to get the download URL. But I'm not able to send the URL to my video player. I tried res.sendFile("URL path"); but it is saying that the "Path should be absolute". I understand that the path should come from the server local machine.
Is there any way where I can send the URL to my video source path from server?
HTML file:
<video width="100%" controls><source src="/video/songID" type="video/mp4">Your browser does not support HTML video.</video>
Server code:
app.get("/video/:songKey", function(req, res, next) {
var fDb = admin.database();
var ref = fDb.ref("videos");
ref.orderByKey().equalTo(req.params.songKey).on('child_added', async (snapshot) => {
var refPath = snapshot.val().video_ref_path; // This is the firebase storage ref path stored in realtime database
var storage = admin.storage();
var songFile = storage.bucket("<bucket-name>").file(refPath);
var [meta] = await songFile.getMetadata();
var token = meta.metadata.firebaseStorageDownloadTokens;
var link = `https://firebasestorage.googleapis.com/v0/b/<bucket_name>/o/${encodeURIComponent(
refPath
)}?alt=media&token=${token}`
res.sendFile(link); //This line is giving error saying path needs absolute path
// If I use res.send(link) call the web location I'm able to get the file URL
});
});
Any help with this is appreciated and thankful. BTW I'm new to nodejs and learning it.
Thanks in Advance

res.sendFile() is meant to send the contents of locally (to the server) stored files.
You probably want to use res.redirect(), which is meant to redirect the browser to another URL.

Related

Unable to access cookie in nodeJS after redirected from HTML page

I'm trying to make a post call via an html page. On 2nd application, i'm trying to access a cookie named cookie_test (can be set manually or via code in browser).
Under Application tab(Storage --> cookies), i'm able to see the cookie, but somehow i'm getting undefined in console log when trying to access it from 2nd application (refer 2nd code).
browser cookie screenshot
Application One (test.html is the only file in it & i'm trying to make a post call)
<form action="http://localhost:3000/page-two" method="POST">
<input type="submit" value="Go to P2">
</form>
Application Two (NodeJS/Express:
index.js)
var express = require('express');
var router = express.Router();
router.post('/', function (req, res, next) {
console.log("COOKIE-TEST::::::", req.cookies.cookie_test)
res.render("page_two", { cookie_data: req.cookies.cookie_test });
});
module.exports = router;
Note: Within node application, cookies are accessible & works as expected. Issues seems to happen during redirection.
I was able to solve the issue by setting the cookie parameters as secure(true) & sameSite(none). Make sure to use latest version of express for sameSite property. This setting allowed my 2nd application to access it's cookies, irrespective of getting redirected from any source (in my case Application one).
A couple of things to check.
First, your nodejs app needs the cookie-parser middleware if it is to receive any cookies from users' browsers. It looks like this.
var cookieParser = require('cookie-parser')
...
var express = require('express')
express.use(cookieParser())
...
You didn't mention how you set the cookie from your post route. You would do that like this with a call to res.cookie():
router.post('/', function (req, res, next) {
console.log("COOKIE-TEST::::::", req.cookies.cookie_test)
const testCookieVal = req.cookies.cookie_test || 'some default value'
res.cookie('cookie_test', testCookieVal)
res.render("page_two", { cookie_data: someCookieVal })
});
It's not clear how you set the cookie you're trying to retrieve in your post route. You should understand that your Application One html file is served from the file:// origin, and Application Two is served from the https://localhost:3000 origin. Browsers never send cookies associated with web pages served from one origin in requests to other origins.

Snapchat download all memories at once

Over the years on snapchat I have saved lots of photos that I would like to retrieve now, The problem is they do not make it easy to export, but luckily if you go online you can request all the data (thats great)
I can see all my photos download link and using the local HTML file if I click download it starts downloading.
Here's where the tricky part is, I have around 15,000 downloads I need to do and manually clicking each individual one will take ages, I've tried extracting all of the links through the download button and this creates lots of Urls (Great) but the problem is, if you past the url into the browser then ("Error: HTTP method GET is not supported by this URL") appears.
I've tried a multitude of different chrome extensions and none of them show the actually download, just the HTML which is on the left-hand side.
The download button is a clickable link that just starts the download in the tab. It belongs under Href A
I'm trying to figure out what the best way of bulk downloading each of these individual files is.
So, I just watched their code by downloading my own memories. They use a custom JavaScript function to download your data (a POST request with ID's in the body).
You can replicate this request, but you can also just use their method.
Open your console and use downloadMemories(<url>)
Or if you don't have the urls you can retrieve them yourself:
var links = document.getElementsByTagName("table")[0].getElementsByTagName("a");
eval(links[0].href);
UPDATE
I made a script for this:
https://github.com/ToTheMax/Snapchat-All-Memories-Downloader
Using the .json file you can download them one by one with python:
req = requests.post(url, allow_redirects=True)
response = req.text
file = requests.get(response)
Then get the correct extension and the date:
day = date.split(" ")[0]
time = date.split(" ")[1].replace(':', '-')
filename = f'memories/{day}_{time}.mp4' if type == 'VIDEO' else f'memories/{day}_{time}.jpg'
And then write it to file:
with open(filename, 'wb') as f:
f.write(file.content)
I've made a bot to download all memories.
You can download it here
It doesn't require any additional installation, just place the memories_history.json file in the same directory and run it. It skips the files that have already been downloaded.
Short answer
Download a desktop application that automates this process.
Visit downloadmysnapchatmemories.com to download the app. You can watch this tutorial guiding you through the entire process.
In short, the app reads the memories_history.json file provided by Snapchat and downloads each of the memories to your computer.
App source code
Long answer (How the app described above works)
We can iterate over each of the memories within the memories_history.json file found in your data download from Snapchat.
For each memory, we make a POST request to the URL stored as the memories Download Link. The response will be a URL to the file itself.
Then, we can make a GET request to the returned URL to retrieve the file.
Example
Here is a simplified example of fetching and downloading a single memory using NodeJS:
Let's say we have the following memory stored in fakeMemory.json:
{
"Date": "2022-01-26 12:00:00 UTC",
"Media Type": "Image",
"Download Link": "https://app.snapchat.com/..."
}
We can do the following:
// import required libraries
const fetch = require('node-fetch'); // Needed for making fetch requests
const fs = require('fs'); // Needed for writing to filesystem
const memory = JSON.parse(fs.readFileSync('fakeMemory.json'));
const response = await fetch(memory['Download Link'], { method: 'POST' });
const url = await response.text(); // returns URL to file
// We can now use the `url` to download the file.
const download = await fetch(url, { method: 'GET' });
const fileName = 'memory.jpg'; // file name we want this saved as
const fileData = download.body; // contents of the file
// Write the contents of the file to this computer using Node's file system
const fileStream = fs.createWriteStream(fileName);
fileData.pipe(fileStream);
fileStream.on('finish', () => {
console.log('memory successfully downloaded as memory.jpg');
});

Read file at startup Chrome extension/kiosk app

I'm currently developing my first Chrome app that we'll be used as a Kiosk app later.
I'm trying to read a file at the startup of the app, that file is a config file (.json). It contains values that will be passed inside a URL once the app has launched (ie: www.google.com/key=keyValueInTheJsonFile).
I used https://developer.chrome.com/apps/fileSystem (the method "chooseEntry" especially) to be able to read a file, but in my case I would like to directly specify the path/name of the file and not ask the user to select a file. Like that I can pass the values to the redirected URL at the startup.
Any idea of how I could possibly do that?
Thanks!
If your file is in the package you can read it using simple XHR or Fetch.
You can't use web filesystem since it has different purpose and Chrome filesystem (user's FS) won't work here either since it needs a user interaction.
Use function getURL to get a full URL to the resource and then make XHR call:
var rUrl = chrome.runtime.getURL('file.json');
fetch(rUrl).then((response) => {
return response.json();
})
.then((fileContent) => {
// the content
})
.catch((cause) => console.log(cause));

Drop-down options filled from json file in Meteor

I have a local json file in my client folder that contains information for <option>s in a <select> tag.
I tried using ajax to fill up <option>s but my app keeps crashing.
What is the proper way to get information out of a local json file in meteor?
To get information from the server you need to use a Meteor method.
To read local file you need to use assets.
For example, assuming your file is /private/options.json:
server side
Meteor.methods({
getOptions: function() {
return Assets.getText('options.json');
},
});
client side
var loadOptions = function() {
Meteor.call('getOptions', function(error, result){
fillOptions(JSON.parse(result));
});
};
I had the same problem, I needed to load labels for the client.
Instead of calling the server, the client can directly perform a HTTP call and retrieve the file.
Put your file into the public directory
Use the HTTP API to get your file
HTTP.get('/yourFile.json', {}, function(error, result) {
var parsedFile = JSON.parse(result.content);
});
If you are using Iron router be sure to wait for the result before displaying your page with a waitOn.
As the call is asynchronous, it might take some time to get your result.

upload images with html5's drag 'n' drop. server side?

I am implementing a drag'n'drop code for uploading images. I'm a newbie on this technology/API.
I'm using the drag'n'drop API of the HTML5. I also use Apache as http server and node.js as websocket server. I found lots of tutorials for the client side implementation.
This is maybe a silly question, but what about the server side? I guess I have to implement a code on server side to handle the incoming image's upload and storage...
Any ideas?Or links?
Thanks
EDIT
I will use these APIs : drag'n'drop, FormData, XHR progress event and FileReader. I will create code based on this tutorial. I have not implemented anything specific yet, I'm still experimenting.
The file saving on the server side is used as normally!
After using drag&drop you will get the file-objects in javascript and you can do what you want with them, either XHR-post them, use them in a normal form-POST or convert to a data-URI and post it to the server as base64 text.
i.e
element.ondrop = function(ev) {
var files = ev.dataTransfer.files
// post the files via XHR POST
var formData = new FormData()
// im lazy, use a supported loop
for (file of files) {
formData.append("file", file)
}
var req = new XMLHttpRequest()
req.open('POST', '/saveimage/')
req.send(formData)
}
Will post the files just as you had used a normal non-drag and drop action.
For a better answer on how to save files we need some info about what language and framework your website uses.