get file type after downloading from IPFS - filenames

I'm using ipfs to download files... but ipfs does not have filenames or extensions.
How can I properly set the extension for the saved file, based on the downloaded data?

You can add files with ipfs add -w to "wrap" them in a directory. This will preserve the filename.
There are also plans to record metadata like mime types along with files but, unfortunately, progress has gotten a bit stuck on this front.

There is no way to conclusively get the file extension in IPFS, so instead, you can look at the contents of the file to infer its file type (using file-type, for example)
When you have the full contents of the file in a buffer, you can do:
import {fileTypeFromBuffer} from 'file-type';
let buffer = /* buffer of file from IPFS */;
// undefined or string of file extension
let ext = (await fileTypeFromBuffer(buffer))?.ext;

If you wan't to do this in a React app on the frontend this works :
let contentType = await fetch(imageUrl)
.then(response => {
return response.blob().then(blob => {
return {
contentType: response.headers.get("Content-Type"),
raw: blob
}
})
})
.then(data => {
return data.contentType
})
file-type is intended for use in Node apps, not on the client side.
If you try to use a library intended for Node then you will get errors that relate to the library's internal dependencies on built-in Node modules which are not available in the browser. You should use a different library for making HTTP requests from the browser; I'd suggest using the browser's built-in fetch.

you must get the program file type, then import the extension name on the program name you downloaded from the buffer
i hope you understand this

Related

How can we change the chrome default download directory in Testcafe?

Kindly provide the steps to set the download file path in Testcafe.
If you need to find and check a downloaded file, you can use the following ways:
Use the RequestLogger: Check the Downloaded File Name and Content example
Obtain a "Downloads" folder path from the system environment variables or use the downloads-folder package:
import fs from 'fs';
import downloadsFolder from 'downloads-folder';
fixture('fixture')
.page('http://example.com/');
test('test', async t => {
await t.click('#download');
const filePath = downloadsFolder() + '/my-file.txt';
await t.expect(fs.existsSync(filePath)).ok();
});
Also, TestCafe internal API allows you to change the downloads path: https://stackoverflow.com/a/65732040/10684943. Note that this approach is not recommended. Use it at your own risk.

How can I ensure this vue application doesn't exceed the recommended 244kb in production?

There is a vue file here that imports a json file that has about 9000 records in it.
How do I ensure that the json file is not compiled with the component?
A simple way would be to put the JSON file you want to access in the public folder (Webpack won't process anything in this folder). Then use AJAX to call the file at run time.
This will avoid expanding your app bundle, but Vue may still show that you're including a large resource. This approach would also allow you to split the data into smaller chunks and load them as needed in your app.
Here's an example, assuming the data file is located at /public/data/mydata.json. Also, I suggest using Axios to make the AJAX stuff easier.
import axios from 'axios'
export default {
name: 'Vue Component',
created() {
this.fetchData();
},
methods: {
fetchData() {
axios.get('/data/mydata.json').then(response => {
// do something with response.data
})
}
}
}
Use dynamic import. Like this:
import(
/* webpackChunkName: "my_json" */
'./src/my.json'
).then(({default: myJson}) => {
// do whatever you like here~
console.log(myJson);
});
doc:
https://webpack.js.org/guides/code-splitting/#dynamic-imports
If the json file is too big, you will still get the size exceeding warning.
But the json file would load async, so it would not cause any performance problem.
🔽 🔽 🔽 if you really don't want to see the warning, try this: 🔽 🔽 🔽
Use copy-webpack-plugin,it can copy your json file to dist folder, which means you can fire a XHR get request to load the json file, like this axios.get('/my.json').
By doing this, you can get the FULL control about when to load the file.

Can I send XLS/XLSX files using Express res.sendFile()?

I've posted too many questions about this but I keep hitting a wall so I keep asking. Can you send an XLS or XLSX file using Express' res.sendFile()?
Here's the code I'm using:
res.sendFile(
path.join(__dirname, '../testing/'),
`${fileName}`,
(err, data) => {
if (err) throw err;
}
);
Even though fileName has the value of filename.xlsx, it never uses the XLSX file; it always defaults to index.html. I always get the following error:
[Error: ENOENT: no such file or directory, stat '/Users/username/Documents/app/testing/index.html']
sendFile neither knows nor cares that you're trying to send an XLS/XLSX file. It only knows that you're trying to send a file.
So, yes, you can, but you have to call sendFile properly. 😜
You've put the filename as a separate argument (which will be parsed as the options argument), instead of putting it in the path argument.
res.sendFile(
path.join(__dirname, '..', 'testing', fileName),
(err, data) => {
if (err) throw err;
}
);
Notice that I took the liberty of removing the apparently redundant expression template literal stuff. I've also split '../testing/' up for you: you're supposed to put discrete components into path.join as much as possible, for clarity.

React-native: download and unzip large language file

A multilingual react-native app. Each language bundle is ~50MB. It doesn't make sense to include all of them in a bundle. So, what do I do about it?
I assume the right way to go here is to download the respective language files upon language selection.
What do I do with it next? Do I suppose to store it using AsyncStorage or what?
Briefly explaining, you will:
Store JSON as ZIP in Google Storage (save memory/bandwidth/time)
Unzip file to JSON (in RN)
Store JSON in AsyncStorage (in RN)
Retrieve from AsyncStorage (in RN)
[Dependencies Summary] You can do this, using these deps:
react-native
react-native-async-storage
rn-fetch-blob
react-native-zip-archive
Tip: Always store big language json in zip format (this can save up to 90% of size).
I made a quick test here: one 3.52MB json file, turned out a 26KB zipped file!
Let's consider that yours stored zip file, can be accessed by using a public url, eg: https://storage.googleapis.com/bucket/folder/lang-file.zip.
Install and link all above RN deps, it's required to get this working.
Import the deps
import RNFetchBlob from 'rn-fetch-blob';
import { unzip } from 'react-native-zip-archive';
import AsyncStorage from '#react-native-community/async-storage';
Download the file using rn-fetch-blob. This can be done using:
RNFetchBlob
.config({
// add this option that makes response data to be stored as a file,
// this is much more performant.
fileCache : true,
})
.fetch('GET', 'http://www.example.com/file/example.zip', {
//some headers ..
})
.then((res) => {
// the temp file path
console.log('The file saved to ', res.path())
// Unzip will be called here!
unzipDownloadFile(res.path(), (jsonFilePath) => {
// Let's store this json.
storeJSONtoAsyncStorage(jsonFilePath);
// Done!
// Now you can read the AsyncStorage everytime you need (using function bellow).
});
});
[function] Unzip the downloaded file, using react-native-zip-archive:
function unzipDownloadFile(target, cb) {
const targetPath = target;
const sourcePath = `${target}.json`;
const charset = 'UTF-8';
unzip(sourcePath, targetPath, charset)
.then((path) => {
console.log(`unzip completed at ${path}`)
return cb(path);
})
.catch((error) => {
console.error(error)
});
}
[function] Store JSON in AsyncStorage:
function storeJSONtoAsyncStorage (path) {
RNFetchBlob.fs.readFile(path, 'utf-8')
.then((data) => {
AsyncStorage.setItem('myJSON', data);
});
}
Retrieve JSON data from AsyncStorage (everytime you want):
AsyncStorage.getItem('myJSON', (err, json) => {
if (err) {
console.log(err);
} else {
const myJSON = JSON.parse(json);
// ... do what you need with you json lang file here...
}
})
That's enough to get dynamic json lang files working in React Native.
I'm using this approach to give a similar feature to my i18n'ed project.
Yes you are right to make the translation file downloadable.
You can store the downloaded file in the document directory of your app.
After that you can use a package to load the translations. For instance
https://github.com/fnando/i18n-js.
I would also suggest taking a look at the i18n library which is a standard tool for internationalisation in JavaScript.
Consider taking a look at this documentations page where you can find an option of loading a translation bundle or setting up a backend provider and hooking into it.
Also, to answer the storage question, if you do not plan on setting up a backend: AsyncStorage would be an appropriate place to store your key - translation text pairs.

Prevent JSON file from becoming part of chunk.js/app.js when I build my vue app

I have a JSON file that I included in my vue app. But the problem is that when I build the app, the JSON file disappears and becomes a part from a js file.
How can I keep it as a JSON file after build, since I want to manipulate it?
If you are using Vue CLI 3, you can place your static files in public directory and reference them by absolute paths.
For more information you can visit the CLI documents.
Update
Place your JSON file in public directory
Import axios or any similar tools you use for AJAX calls.
You need a .env file in your project root. And store your base url in BASE_URL variable. (Read More!)
Add a data property containing your base URL:
data() {
return {
baseUrl: process.env.BASE_URL,
}
},
And then you can access you JSON value with an ajax call:
axios.get(this.baseUrl + 'test.json').then(response => {
console.log(response);
})
I think you want to configure the externals option.