I am currently developing an online code editor. One of the features of the app is cloning or pulling a remote repository and the user also can push his project to the remote repository. Because the app has Github Oauth, with the token I can access private repos too. The cloning of any repo works perfectly. If I clone a repo first the pull and push work perfect too, but if I don't clone, they don't work at all. I have searched a lot on the internet, but I haven't found good examples so I can learn how to properly use this simple-git package.
Does anyone have implemented something similar or have worked with this package again and can share a snippet of code with implementing these 3 functionalities?
These are the functions that I have implemented so far.
//if the repo folder that the user selected exists then pull the changes from the remote else it
//clones the remote
function repo (req,res){
fs.exists(path.join(__dirname,currentpath,repo_fname),async exists => {
if(exists){
//git pull here
const git = simpleGit({ baseDir: path.join(__dirname,currentpath,repo_fname) });
User.findOne({git_user: req.body.git_username})
.exec(async(error , user) => {
await git.addConfig('user.email',user.git_email);
await git.addConfig('user.name',user.git_user);
})
git.addRemote(req.body.username, repolink);
await git.add('./*');
await git.commit("Updated"+ new Date());
await git.pull(req.body.username, req.body.branch)
.then(()=>{
console.log('Pulling Repo finished\n');
res.send({mess: "ok"});
})
.catch((err) => {
console.error('failed: ', err);
res.send({err : "The pulling of the repo failed.Please try again."});});
}else{
//git clone here
try{
fs.mkdirSync(path.join(__dirname,currentpath,repo_fname),{recursive:true});
const git = simpleGit({ baseDir: path.join(__dirname,currentpath,repo_fname) });
const options = ["--single-branch", "--branch" , req.body.branch,'--depth', '1'];
git.clone(repolink, path.join(__dirname,currentpath,repo_fname),options)
.then(() => {
console.log('Cloning Repo finished\n');
res.send({mess: "ok"});
})
.catch((err) => {
console.error('failed: ', err);
res.send({err : "The cloning of the repo failed.Please try again."});});
}catch{
let err= "Error with creating folder"+ folderpath;
console.log(err);
res.send({err: err});
}
}
});}
//pushes the local repo to the remote
async funcion pushrepo (req,res){
const git = simpleGit({ baseDir: path.join(__dirname,currentpath) });
User.findOne({git_user: req.body.git_username})
.exec(async(error , user) => {
awaitgit.addConfig('user.email',user.git_email);
await git.addConfig('user.name',user.git_user);
await git.add('./*');
await git.commit(req.body.commit_msg);
git.addRemote(req.body.username, req.body.repolink);
await git.push(req.body.username, req.body.branch,["--set-upstream","--force"])
.then(()=>{
console.log('Pushing to Repo finished\n');
res.send({mess: "ok"});
})
.catch((err) => {
console.error('failed: ', err);
res.send({err : "The push to the repo failed.Please try again."});
});
});
}
Related
How to download a file with Node.js from google drive api
I don't need anything special. I only want to download a file from a GoogleDrive, and then save it to a given directory of client.
app.get("/download",function(req,res){
const p38290token = new google.auth.OAuth2(CLIENT_ID, CLIENT_SECRET, REDIRECT_URI);
p38290token.setCredentials({ refresh_token: token.acc });
const p38290Id = google.drive({
version: "v3",
auth: p38290token,
});
var dest = fs.createWriteStream("./test.png");
try {
p38290Id.files.get({
fileId: "1daaxy0ymKbMro-e-JnexmGvM4WzW-3Hn",
alt: "media"
}, { responseType: "stream" },
(err, res) => {
res.data
.on("end", () => {
console.log("Done");
})
.on("error", err => {
console.log("Error", err);
})
.pipe(dest); // i want to sent this file to client who request to "/download"
}
)
} catch (error) {
}
})
I want to do that just someone come to www.xyz.com/download and file will be download automatically
The issue seems to be with this line:
var dest = fs.createWriteStream("./test.png");
You are using a file system command which is meant to interact with files on the server. Your question makes it clear that you wish for express to deliver the contents of the file over to the client making the HTTP request.
For that you can just use the res parameter of the route callback function. You declare it on this line:
app.get("/download",function(req,res){
In your case I'd remove the dest variable completely and simply pipe the file to res like so:
.pipe(dest);
Have a look at this answer as well.
I am using ionic with firebase realtime database and capacitor 3. I intend to enable offline capabilities. I have built the app using ionic cap build and then opened in xcode. Then following url https://firebase.google.com/docs/database/ios/offline-capabilities I added the below code in AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
FirebaseApp.configure()
Database.database().isPersistenceEnabled = true
return true
}
Now to test i ran the app with wifi on and got the data from firebase db. after this i killed the app and turned off wifi. However, on launching the app it does not load the data.
Is there anything else i am missing here?
my key pod file has:
target 'App' do
capacitor_pods
# Add your Pods here
pod 'FirebaseCore', '7.11.0' # Add this line
pod 'Firebase/Database', '7.11.0' # Add this line
end
Below is my code that does not work and expected to:
getSeedConfig(){
return new Promise((resolve, reject) =>{
const doc = ref(this.db, 'config/seed');
get(doc).then((snapshot) => {
if (snapshot.exists()) {
resolve(snapshot.val())
} else {
resolve(null)
}
}).catch((error) => {
reject(error)
});
})
}
When using a modern API in JavaScript there are not many cases where you need to return a custom promise anymore.
As far as I can tell this code that you now have:
getSeedConfig(){
return new Promise((resolve, reject) =>{
const doc = ref(this.db, 'config/seed');
get(doc).then((snapshot) => {
if (snapshot.exists()) {
resolve(snapshot.val())
} else {
resolve(null)
}
}).catch((error) => {
reject(error)
});
})
}
Can be shortened to:
getSeedConfig(){
const doc = ref(this.db, 'config/seed');
return get(doc).then((snapshot) => {
return snapshot.val(); // 👈 returns null when the snapshot does not exist
})
}
I'm implementing a youtube video downloader using ytdl-core with Nodejs backend and Reactjs frontend. However, using ytdl-core library I'm able to send to youtube video file to frontend with this codeblock
app.get('/download', (req, res) => {
let { url, itag } = req.query;
let id = ytdl.getURLVideoID(url);
ytdl.getInfo(id, (err, info) => {
if (err) {
console.log(err);
throw err;
}
else{
let audioandvideo = ytdl.filterFormats(info.formats, 'audioandvideo');
let video = audioandvideo.filter(obj => obj.itag === itag);
video = video[0]
res.header('Content-Disposition', `attachment; filename="${info.title}.${video.container}"`);
res.header('Content-Type', 'video/webm');
ytdl(url, {
format: video
}).pipe(res);
}
})
});
However, the file downloads correctly if I redirect the webpage to the route like this
window.location.href = `http://localhost:5000/download?url=${this.state.url}&itag=${itag}`;
This works fine and the video downloads correctly. But as it's a redirection I can't do that in a hosted site. So, I need to use axios to do this.
I did some research and found out some solutions. I tried with js-file-download library following the accepted answer here. It downloads the file to the client directory but the file won't play. This is the codeblock I used for that
downloadVideo(itag){
axios.get(`http://localhost:5000/download`, {
params: { url: this.state.url, itag },
})
.then(response => {
fileDownload(response.data, `video.mp4`);
})
.catch(err => console.log(err));
}
As it's not working I tried another approach mentioned in the previously mentioned StackOverflow answer as well. It also downloads the file but doesn't work as well.
How can I get this fixed? What may be the reason my axios request doesn't work correctly?
EDIT :
downloadVideo(itag){
axios.get(`http://localhost:5000/download`, {
params: { url: this.state.url, itag },
responseType: Blob
})
.then(response => {
fileDownload(response.data, `video.mp4`);
})
.catch(err => console.log(err));
// window.location.href = `http://localhost:5000/download?url=${this.state.url}&itag=${itag}`;
}
This is the frontend code. If I use the commented code block (window.location.href) instead of axios.get the file gets downloaded and it works. But if I use axios.get a file gets downloaded but it seems to be a broken file as it's not playing.
EDITED
I'm facing this issue while trying to create test videos using the TestCase Javascript API.
I'm working with testcafe version 0.22.0 and I already have the prerequisites the request in their documentation.
Basically, the issue is video function doesn't exist in my runner object.
https://devexpress.github.io/testcafe/documentation/using-testcafe/common-concepts/screenshots-and-videos.html#record-videos
createTestCafe('localhost', 1337, 1338)
.then(testcafe => {
runner = testcafe.createRunner();
return testcafe.createBrowserConnection();
})
.then(remoteConnection => {
// Outputs remoteConnection.url so that it can be visited from the remote browser.
runner
.video(artifactsPath, true)
.src(specsPath + '/run-animation.spec.ts')
.browsers(['chrome'])
.reporter('json')
.run()
.then(failedCount => {
console.log('Error: ', failedCount);
})
.catch(error => {
console.log('Error: ', error);
});
});
You are using the old TestCafe version. The 'Recording Video' feature appeared in a version older than 0.22.0.
The latest TestCafe version (1.1.2) exactly contains this feature.
My Firebase web project has been working for several months now. But on Sunday June 3, 2018, my application stopped sending tweets with media (images) attached. Before this, it was working for several months. I have not changed the failing code before the 3rd and I have even reverted to code that worked before that date but the app still fails :(
SDK versions:
I am using the most up to date versions of Firebase tools (3.18.6), and cloud functions (1.0.3). Along with twit (2.2.10) a javascript library for twitter api.
Do note my project was also working on older versions of the above including pre v1.0 cloud functions. Also note, I am still able to send regular text tweets just not ones with any media (image,gif,mp4).
This mainly relates to Twitter's API, but I cannot rule out something funky going on in Firebase's Node.js environment.
How to reproduce:
For simplicity, I will link to the code in a tutorial which I originally used when starting the project.
Setup a twitter account and retrieve all the necessary tokens as outlined in the tutorial. Then simply call the cloud function below and it will attempt to tweet the NASA image of the day.
The function is able to upload the picture to the twitter server and the response I get is expected:
{ media_id: 1004461244487643100,
media_id_string: '1004461244487643136',
media_key: '5_1004461244487643136',
size: 92917,
expires_after_secs: 86400,
image: { image_type: 'image/jpeg', w: 960, h: 1318 } }
However, once it attempts to post the tweet with the media attached, I receive an error
code 324: 'Unsupported raw media category'
which doesn't exist in Twitter's docs: https://developer.twitter.com/en/docs/basics/response-codes.html
Now, Code 324 does exist but in Twitter's docs there is a different description:
"The validation of media ids failed"
Which I have yet to receive. So my media id is valid, so something else is wrong? No where on the internet can I find someone with this exact error.
Link to tutorial code:
https://medium.freecodecamp.org/how-to-build-and-deploy-a-multifunctional-twitter-bot-49e941bb3092
Javascript code that reproduces the issue:
**index.js
'use strict';
const functions = require('firebase-functions');
const request = require('request');
const path = require('path');
const os = require('os');
const fs = require('fs');
const tmpDir = os.tmpdir(); // Ref to the temporary dir on worker machine
const Twit = require('twit');
const T = new Twit({
consumer_key: 'your twitter key'
,consumer_secret: 'your twitter secret'
,access_token: 'your twitter token'
,access_token_secret: 'your twitter token secret'
});
exports.http_testMediaTweet = functions.https.onRequest((req, res) => {
function getPhoto() {
const parameters = {
url: 'https://api.nasa.gov/planetary/apod',
qs: {
api_key: 'DEMO_KEY'
},
encoding: 'binary'
};
request.get(parameters, (err, response, body) => {
if (err) {console.log('err: ' + err)}
body = JSON.parse(body);
var f = path.join(tmpDir, 'nasa.jpg');
saveFile(body, f);
});
}
function saveFile(body, fileName) {
const file = fs.createWriteStream(fileName);
request(body).pipe(file).on('close', err => {
if (err) {
console.log(err)
} else {
console.log('Media saved! '+body.title)
const descriptionText = body.title
uploadMedia(descriptionText, fileName);
}
})
}
function uploadMedia(descriptionText, fileName) {
const filePath = path.join(__dirname, `../${fileName}`)
console.log(`uploadMedia: file PATH ${fileName}`)
T.postMediaChunked({
file_path: fileName
}, (err, data, respone) => {
if (err) {
console.log(err)
} else {
console.log(data)
const params = {
status: descriptionText,
media_ids: data.media_id_string
}
postStatus(params);
}
})
}
function postStatus(params) {
T.post('statuses/update', params, (err, data, respone) => {
if (err) {
console.log(err)
res.status(500).send('Error: ' + err);
} else {
console.log('Status posted!')
res.status(200).send('success');
}
})
}
// Do thing
getPhoto();
});
I was hoping to launch my app next week but this has become a major issue for me. I've tried everything I can think of and consulted the docs for Twitter and the js library but I seem to be doing everything right. Hopefully someone can shed some light on this, thanks.