gulp map of source file and its destination path - path

Is it possible to have something like a map of source files and it's destination path.
config.yml something like
entries:
- source:"node_modules/jquery2/dist/jquery.js"
destination: "jquery/2/jquery.js"
- source: "node_modules/jquery3/dist/jquery.js"
destination: "jquery/3/jquery.js"
and than gulp task like this
function javascripts() {
return gulp.src(PATHS.javascripts)
//.pipe($.debug({title: 'dest'}))
.pipe($.sourcemaps.init())
.pipe($.if(PRODUCTION, $.uglify()
.on('error', e => { console.log(e); })
))
.pipe($.if(!PRODUCTION, $.sourcemaps.write()))
.pipe($.rename(function (path) {
path.dirname = path.dirname.replace('src/assets/', '');
}))
/*.pipe(gulp.dest( function(file) {
echo file.dirname;
//var path = file.base.replace('src/assets/js/', '');
return ($.if(PRODUCTION, PATHS.production , PATHS.staging ))
}))*/
//.pipe($.flatten({ includeParents: 3} ))
.pipe($.if(PRODUCTION,
gulp.dest(PATHS.production),
gulp.dest(PATHS.staging)
));
}
We need to create something like CDN of script versions.

Related

how to display a file using react-native

So, I have those "cards" to which are attached files.
I want to be able to display the content of these files (when possible; I do not expect to show binary files obviously, but text, pdf, images,...) to the user.
Upon a longPress on an attachment, the openAttachment() function is be called. That function downloads the file from the server if necessary and then (tries to) open it:
// Opens an attachment
const openAttachment = async (attachment) => {
try {
// Download file if not already done
const fileInfo = await FileSystem.getInfoAsync(FileSystem.cacheDirectory + attachment.name)
let uri
if (!fileInfo.exists) {
console.log('Downloading attachment')
resp = await FileSystem.downloadAsync(
server.value + `/index.php/apps/deck/api/v1.0/boards/${route.params.boardId}/stacks/${route.params.stackId}/cards/${route.params.cardId}/attachments/${attachment.id}`,
FileSystem.cacheDirectory + attachment.name,
{
headers: {
'Authorization': token.value
},
},
)
console.log(resp)
uri = await FileSystem.getContentUriAsync(resp.uri)
} else {
console.log('File already in cache')
uri = await FileSystem.getContentUriAsync(fileInfo.uri)
}
console.log('Opening file ' + uri)
Sharing.shareAsync(uri);
} catch {
Toast.show({
type: 'error',
text1: i18n.t('error'),
text2: error.message,
})
console.log(error)
}
}
The issue always arrise at the Sharing.shareAsync(uri); line: Whatever I put there, it fails:
Sharing.shareAsync(uri) does not seem to be supported on my platform: https://docs.expo.dev/versions/latest/sdk/sharing/
Linking.openURL(uri) does not support the file:// scheme (the uri is in the form file:///var/mobile/Containers/Data/Application/5C1CB402-5ED1-4E17-B907-46111AE3FB7C/Library/Caches/test.pdf)
await WebBrowser.openBrowserAsync(uri) (from expo-web-browser) does not seem to be able to open local files
How am I supposed to do to display those files? Anyone has an idea?
Cyrille
I found a solution using react-native-file-viewer
// Opens an attachment
const openAttachment = async (attachment) => {
try {
// Download file if not already done
const fileInfo = await FileSystem.getInfoAsync(FileSystem.cacheDirectory + "attachment.name")
let uri
if (!fileInfo.exists) {
console.log('Downloading attachment')
const resp = await FileSystem.downloadAsync(
server.value + `/index.php/apps/deck/api/v1.0/boards/${route.params.boardId}/stacks/${route.params.stackId}/cards/${route.params.cardId}/attachments/${attachment.id}`,
FileSystem.cacheDirectory + attachment.name,
{
headers: {
'Authorization': token.value
},
},
)
console.log(resp)
uri = await FileSystem.getContentUriAsync(resp.uri)
} else {
console.log('File already in cache')
uri = await FileSystem.getContentUriAsync(fileInfo.uri)
}
console.log('opening file', uri)
FileViewer.open(uri)
} catch(error) {
Toast.show({
type: 'error',
text1: i18n.t('error'),
text2: error.message,
})
console.log(error)
}
}

ios converting file to blob in CDVWKWebViewEngine ionic cordova angularJS

Just trying my luck here.
I've been tasked to update a Ionic 1, AngularJS, Cordova app for the changes in iOS camera and file permissions.
In most areas on the app I can simply convertFileSrc and trustAsResourceUrl to retrieve and display in the app. In the scenario below I need to convert the new safe ionic path to a blob for posting.
original file path format:
file:///var/mobile/Containers/Data/Application/10298A9F-7E24-48C4-912D-996EA731F2B0/Library/NoCloud/cdv_photo_001.jpg
after sanitising:
ionic://localhost/app_file/var/mobile/Containers/Data/Application/10298A9F-7E24-48C4-912D-996EA731F2B0/Library/NoCloud/cdv_photo_001.jpg
below is what I've tried so far:
function getDirectory(path) {
return path.substr(0, path.lastIndexOf('/'));
}
function getFilename(path) {
return path.substr(path.lastIndexOf('/') + 1);
}
function getImage(path) {
const pathStr = path;
if (window.ionic.Platform.isIOS() && typeof path === 'string') {
const fixedURL = window.Ionic.WebView.convertFileSrc(path);
path = $sce.trustAsResourceUrl(fixedURL);
}
if (typeof navigator.camera === 'undefined') {
return window.fetch(path, { method: 'GET' })
.then(function(response) {
return response.blob();
});
}
const filename = getFilename(`${path}`);
const directory = getDirectory(`${path}`);
return $cordovaFile.readAsArrayBuffer(directory, filename)
.catch(function(error) {
const err = {
message: 'read failed for image',
filename,
directory,
error
};
$log.error(`getImage, Error: ${JSON.stringify(err)}`);
return $q.reject(err);
})
.then(function(data) {
return new Blob([data], { type: 'image/jpeg' });
});
}
for anyone else who might need to do this in the future I figured out that it was the location of saved files casuing the problem.
In the cordova getPicture config I just needed to add
saveToPhotoAlbum: true
from there the file can just be pulled with the fetch api within the need for $cordovaFile:
return window.fetch(path, { method: 'GET' })
.then(function(response) {
return response.blob();
});

Download image not working on IOS device - React Native

I implemented functionality for download image in React Native using RNFetchBlob Its Working fine with android but on IOS device it's not working.
Following is my react native code for download functionality.
downloadImg = (url) => {
var that = this;
async function requestCameraPermission() {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
{
title: 'Test App',
message: 'Test App needs access to your gallery ',
}
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
that.actualDownload(url);
} else {
Alert.alert('Permission Denied!', 'You need to give storage permission to download the file');
}
}
if (Platform.OS === 'android') {
requestCameraPermission();
} else {
this.actualDownload(url);
}
}
actualDownload = (url) => {
var date = new Date();
var image_URL = url;
var ext = this.getExtention(image_URL);
ext = "." + ext[0];
const { config, fs } = RNFetchBlob;
let PictureDir = Platform.OS === 'ios' ? fs.dirs.DocumentDir : fs.dirs.PictureDir;
let options = {
fileCache: true,
addAndroidDownloads: {
useDownloadManager: true,
notification: true,
path: PictureDir + "/Images/image_" + Math.floor(date.getTime()
+ date.getSeconds() / 2) + ext,
description: 'Image'
}
}
config(options).fetch('GET', image_URL).then((res) => {
console.log("Thank you","Image Downloaded Successfully.");
});
}
the addAndroidDownloads only works for android. when you use the addAndroidDownloads the path in config is not useless. but for ios, the path has to be added.
try the following code, and you can add progress for ios.
actualDownload = (url) => {
var date = new Date();
var image_URL = url;
var ext = this.getExtention(image_URL);
ext = "." + ext[0];
const { config, fs } = RNFetchBlob;
let PictureDir = Platform.OS === 'ios' ? fs.dirs.DocumentDir : fs.dirs.PictureDir;
let options = {
fileCache: true,
path: PictureDir + "/Images/image_" + Math.floor(date.getTime() // add it
addAndroidDownloads: {
useDownloadManager: true,
notification: true,
path: PictureDir + "/Images/image_" + Math.floor(date.getTime()
+ date.getSeconds() / 2) + ext,
description: 'Image'
}
}
config(options).fetch('GET', image_URL).then((res) => {
console.log("Thank you","Image Downloaded Successfully.");
});
}
here are the document says:
When using DownloadManager, fileCache and path properties in config will not take effect, because Android DownloadManager can only store files to external storage, also notice that Download Manager can only support GET method, which means the request body will be ignored.
That method works for ios as well. The notification doesn't come. If you want to check that it is downloaded or not, you can check it by logging the path in terminal(Mac) or cmd(Windows) and access it through the terminal itself.
It might not be visible in finder(Mac) or file explorer(Windows).
You can follow the path that you log from the function in this way:
cd ~/Library/Developer/CoreSimulator/Devices...

How to upload file in angular 2

This is the function I am using to upload file but is is giving me the error : Length is undefined. what I have to change in this code. where to give path of file to upload.
fileChange(event) {
let fileList: FileList = event.target.files;
if(fileList) {
let file: File = fileList[0];
let formData:FormData = new FormData();
formData.append('uploadFile', file, file.name);
let headers = new Headers();
/** No need to include Content-Type in Angular 4 */
headers.append('Content-Type', 'multipart/form-data');
headers.append('Accept', 'application/json');
let options = new RequestOptions({ headers: headers });
this.http.post(`assets/Files/info.txt`, formData, options)
.map(res => res.json())
.catch(error => Observable.throw(error))
.subscribe(
data => console.log(fileList),
error => console.log(error)
)
}
}
you need to use xhr request to transfer files
fileChange(event: EventTarget) {
let eventObj: MSInputMethodContext = <MSInputMethodContext> event;
let target: HTMLInputElement = <HTMLInputElement> eventObj.target;
let files: FileList = target.files;
if(files) {
let file: File = files[0];
this.upload(file)
}
}
public upload(filedata: File) {
let url = 'your url'
if (typeof filedata != 'undefined') {
return new Promise((resolve, reject) => {
let formData: any = new FormData();
let xhr = new XMLHttpRequest();
formData.append('icondata', filedata, filedata.name);
xhr.open('POST', url, true);
xhr.setRequestHeader('Authorization', 'JWT ' + localStorage.getItem('id_token'));
xhr.send(formData);
xhr.onreadystatechange = function () {
if (xhr.readyState == XMLHttpRequest.DONE) {
resolve(JSON.parse(xhr.responseText));
}
}
});
}
}
I understand that this is not the functionality you want to have but with no backend you can not upload files to be persistent, they should be stored somewhere. If you just wanna manipulate file names for instance, skip the express part in my answer. I personally used this code which I altered to upload multiple files.
In your Component :
import {FormArray, FormBuilder, FormControl, FormGroup} from "#angular/forms";
declare FormBuilder in the constructor:
constructor (private http: Http, private fb: FormBuilder) {}
in ngOnInit() set a variable as follows :
this.myForm = this.fb.group({chosenfiles: this.fb.array([])});
this is the code for the upload method :
// invoke the upload to server method
// TODO
// Should be in a service (injectable)
upload() {
const formData: any = new FormData();
const files: Array<File> = this.filesToUpload;
//console.log(files);
const chosenf = <FormArray> this.myForm.controls["chosenfiles"];
// iterate over the number of files
for(let i =0; i < files.length; i++){
formData.append("uploads[]", files[i], files[i]['name']);
// store file name in an array
chosenf.push(new FormControl(files[i]['name']));
}
this.http.post('http://localhost:3003/api/upload', formData)
.map(files => files.json())
.subscribe(files => console.log('upload completed, files are : ', files));
}
the method responsible for the file change :
fileChangeEvent(fileInput: any) {
this.filesToUpload = <Array<File>>fileInput.target.files;
const formData: any = new FormData();
const files: Array<File> = this.filesToUpload;
console.log(files);
const chosenf = <FormArray> this.myForm.controls["chosenfiles"];
// iterate over the number of files
for(let i =0; i < files.length; i++){
formData.append("uploads[]", files[i], files[i]['name']);
// store file name in an array
chosenf.push(new FormControl(files[i]['name']));
}
}
Template is something like this
<input id="cin" name="cin" type="file" (change)="fileChangeEvent($event)" placeholder="Upload ..." multiple/>
Notice multiple responsible for allowing multiple selections
The express API which will handle the request uses multer after an npm install
var multer = require('multer');
var path = require('path');
specify a static directory which will hold the files
// specify the folder
app.use(express.static(path.join(__dirname, 'uploads')));
As specified by multer
PS: I did not investigate multer, as soon as i got it working, i moved to another task but feel free to remove unnecessary code.
var storage = multer.diskStorage({
// destination
destination: function (req, file, cb) {
cb(null, './uploads/')
},
filename: function (req, file, cb) {
cb(null, file.originalname);
}
});
var upload = multer({ storage: storage });
And finally the endpoint
app.post("/api/upload", upload.array("uploads[]", 12), function (req, res) {
console.log('files', req.files);
res.send(req.files);
});

How can i read a file from iCloud in an iOS-device with cordova?

I want to read the content of a PDF file stored in iCloud.
I pick the file with the FilePicker Phonegap iOS Plugin (https://github.com/jcesarmobile/FilePicker-Phonegap-iOS-Plugin).
The plugin gives me the temporary path where the file is copied.
I want to read it whith the Cordova File Plugin (https://github.com/apache/cordova-plugin-file)
but I did something wrong and the log is always giving me an error.
Here is the code:
$scope.successCallback = function (path) {
var fileName = path.substr(path.lastIndexOf('/') + 1);
var fileDir = path.substr(0,path.lastIndexOf('/') + 1)
console.log("FilePath: " + path);
$cordovaFile.readAsDataURL(fileDir, fileName)
.then(function (data) {
var index = data.indexOf("base64,");
if(index > 0)
{
data = data.substr(index+7);
}
console.log("Data OK=" + data);
}, function (error) {
console.log("Error reading file: " + JSON.stringify(error));
});
}
window.FilePicker.pickFile($scope.successCallback, $scope.errorCallback);
And that's the output:
$FilePath: /private/var/mobile/Containers/Data/Application/22E33EF4-832B-4911-92A6-312927C42A7C/tmp/DocumentPickerIncoming/file.pdf
$Error reading file: {"code":5,"message":"ENCODING_ERR"}
What am I doing wrong?
I realized that in the File Path was a "tmp" folder.
According of this, I changed the "fileDir" in order to matching the cordova.file properties map to physical paths on a real device which is referred in the iOS File System Layout of the documentation of cordova-plugin-file.
Now it works :)
Here is the final code:
$scope.successCallback = function (path) {
var fileName = path.substr(path.lastIndexOf('/') + 1);
var fileDir = cordova.file.tempDirectory + "DocumentPickerIncoming/";
console.log("FilePath: " + path);
$cordovaFile.readAsDataURL(fileDir, fileName)
.then(function (data) {
var index = data.indexOf("base64,");
if(index > 0)
{
data = data.substr(index+7);
}
console.log("Data OK=" + data);
}, function (error) {
console.log("Error reading file: " + JSON.stringify(error));
});
}
window.FilePicker.pickFile($scope.successCallback, $scope.errorCallback);

Resources