I am using firebase functions to crop certain area of pdf and convert them to image using ghostscript
[The wrapper https://www.npmjs.com/package/node-gs and compiled version of gs v9.2 "https://github.com/sina-masnadi/node-gs/tarball/master" ]
and this is the code i am using :
const functions = require('firebase-functions');
const { Storage } = require('#google-cloud/storage');
const gcs = new Storage();
const spawn = require('child-process-promise').spawn;
const path = require('path');
const os = require('os');
const fs = require('fs');
var gs = require('gs');
const THUMB_MAX_HEIGHT = 200;
const THUMB_MAX_WIDTH = 200;
const THUMB_SUFFIX = '-thumb';
//This function triggers whenever any pdf is uploaded to the firebase storage
//and attempts to generate
exports.makePreviews = functions.storage.object().onFinalize(async (object, event) => {
//Checking for pdf files
if (!object.name.endsWith('.pdf')) return false;
const filePath = object.name;
//slicing name and path
const splitFileName = object.name.split(".");
console.log(splitFileName);
const fileID = splitFileName;
//creating temporary path strings for gcp file system
const fileName = path.basename(filePath);
const tempFilePath = path.join(os.tmpdir(), fileName);
const newName1 = path.basename(filePath, '.pdf') + '01.jpeg';
const tempNewPath1 = path.join(os.tmpdir(), newName1);
const newName2 = path.basename(filePath, '.pdf') + '02.jpeg';
const tempNewPath2 = path.join(os.tmpdir(), newName2);
const thumbName = path.basename(filePath, '.pdf') + THUMB_SUFFIX + '.jpeg';
const tempThumbPath = path.join(os.tmpdir(), thumbName);
//downloading file from firebase storage
const bucket = gcs.bucket(object.bucket);
return bucket.file(filePath).download({
destination: tempFilePath
}).then(async () => {
console.log('PDF downloaded locally to', tempFilePath);
//generating two preview JPEGS
await new Promise((resolve, reject) => {
gs()
.safer()
.batch()
.nopause()
.option('-dTextAlphaBits=4')
.option('-dGraphicsAlphaBits=4')
.option('-dDEVICEWIDTHPOINTS=238')
.option('-dDEVICEHEIGHTPOINTS=149.5')
.option('-dFIXEDMEDIA')
.res(600)
.option('-dDownScaleFactor=2')
.executablePath('gs')
.device('jpeg')
.output(tempNewPath2)
.option('-c "<</PageOffset[-308.5 40]>> setpagedevice"')
.option('-sPDFPassword=01011977')
.input(tempFilePath)
.exec((err, stdout, stderr) => {
if (!err) {
console.log('Part One Exceuted');
bucket.upload(tempNewPath1, {
destination: 'files/' + fileID + '.jpeg'
}).then(() => {
console.log('stdout', stdout);
console.log('stderr', stderr);
}).catch(err => {
console.log(err);
});
resolve();
} else {
console.log('gs error:', err);
reject(err);
}
});
});
await new Promise((resolve, reject) => {
gs()
.safer()
.batch()
.nopause()
.option('-dTextAlphaBits=4')
.option('-dGraphicsAlphaBits=4')
.option('-dDEVICEWIDTHPOINTS=238')
.option('-dDEVICEHEIGHTPOINTS=149.5')
.option('-dFIXEDMEDIA')
.res(600)
.option('-dDownScaleFactor=2')
.executablePath('gs')
.device('jpeg')
.output(tempNewPath2)
.option('-c "<</PageOffset[-308.5 40]>> setpagedevice"')
.option('-sPDFPassword=01011977')
.input(tempFilePath)
.exec((err, stdout, stderr) => {
if (!err) {
console.log('gs Part two excuted');
bucket.upload(tempNewPath1, {
destination: 'files/' + fileID + '-2.jpeg'
}).then(() => {
console.log('stdout', stdout);
console.log('stderr', stderr);
})
.catch(err => {
console.log(err);
});
resolve();
} else {
console.log('gs error:', err);
reject(err);
}
});
});
//generating thumbnail from the first JPEG
return spawn('convert', [tempNewPath1, '-thumbnail', `${THUMB_MAX_WIDTH}x${THUMB_MAX_HEIGHT}>`, tempThumbPath], {
capture: ['stdout', 'stderr']
});
}).then(async () => {
console.log('PNG created at', tempNewPath1 + 'and' + tempNewPath2);
console.log('Thumbnail created at', tempThumbPath);
//uploading the files back to firebase storage
return bucket.upload(tempThumbPath, {
destination: 'files/' + fileID + 'thumb.jpeg'
});
}).then(() => {
//once the files have been uploaded delete the local temporary
//files to free up disk space.
fs.unlinkSync(tempNewPath1);
fs.unlinkSync(tempNewPath2);
fs.unlinkSync(tempThumbPath);
return fs.unlinkSync(tempFilePath);
}).catch((err) => {
console.log('exception:', err);
return err;
});
});
deploying the above code, The Log:
[ 'PAN_01011977', 'pdf' ]
PDF downloaded locally to /tmp/PAN_01011977.pdf
gs command: -dSAFER,-dBATCH,-dNOPAUSE,-dTextAlphaBits=4,-dGraphicsAlphaBits=4,-dDEVICEWIDTHPOINTS=238,-dDEVICEHEIGHTPOINTS=149.5,-dFIXEDMEDIA,-r600,-dDownScaleFactor=2,-sDEVICE=jpeg,-sOutputFile=/tmp/PAN_0101197702.jpeg,-c "<</PageOffset[-308.5 40]>> setpagedevice",-sPDFPassword=01011977,/tmp/PAN_01011977.pdf
Part One Exceuted
gs command: -dSAFER,-dBATCH,-dNOPAUSE,-dTextAlphaBits=4,-dGraphicsAlphaBits=4,-dDEVICEWIDTHPOINTS=238,-dDEVICEHEIGHTPOINTS=149.5,-dFIXEDMEDIA,-r600,-dDownScaleFactor=2,-sDEVICE=jpeg,-sOutputFile=/tmp/PAN_0101197702.jpeg,-c "<</PageOffset[-308.5 40]>> setpagedevice",-sPDFPassword=01011977,/tmp/PAN_01011977.pdf
{ Error: ENOENT: no such file or directory, stat '/tmp/PAN_0101197701.jpeg'
errno: -2,
code: 'ENOENT',
syscall: 'stat',
path: '/tmp/PAN_0101197701.jpeg' }
gs Part two excuted
{ Error: ENOENT: no such file or directory, stat '/tmp/PAN_0101197701.jpeg'
errno: -2,
code: 'ENOENT',
syscall: 'stat',
path: '/tmp/PAN_0101197701.jpeg' }
and the error :
and the error log
exception: { ChildProcessError: `convert /tmp/PAN_0101197701.jpeg -thumbnail 200x200> /tmp/PAN_01011977-thumb.jpeg` failed with code 1
at ChildProcess.<anonymous> (/srv/node_modules/child-process-promise/lib/index.js:132:23)
at emitTwo (events.js:126:13)
at ChildProcess.emit (events.js:214:7)
at maybeClose (internal/child_process.js:915:16)
at Process.ChildProcess._handle.onexit (internal/child_process.js:209:5)
name: 'ChildProcessError',
code: 1,
childProcess:
ChildProcess {
domain:
Domain {
domain: null,
_events: [Object],
_eventsCount: 1,
_maxListeners: undefined,
members: [Array] },
_events: { error: [Function], close: [Function] },
_eventsCount: 2,
_maxListeners: undefined,
_closesNeeded: 3,
_closesGot: 3,
connected: false,
signalCode: null,
exitCode: 1,
killed: false,
spawnfile: 'convert',
_handle: null,
spawnargs:
[ 'convert',
'/tmp/PAN_0101197701.jpeg',
'-thumbnail',
'200x200>',
'/tmp/PAN_01011977-thumb.jpeg' ],
pid: 14,
stdin:
Socket {
connecting: false,
_hadError: false,
_handle: null,
_parent: null,
_host: null,
_readableState: [Object],
readable: false,
domain: [Object],
_events: [Object],
_eventsCount: 2,
_maxListeners: undefined,
_writableState: [Object],
writable: false,
allowHalfOpen: false,
_bytesDispatched: 0,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: null,
_server: null,
_idleNext: null,
_idlePrev: null,
_idleTimeout: -1,
[Symbol(asyncId)]: 4540,
[Symbol(bytesRead)]: 0 },
stdout:
Socket {
connecting: false,
_hadError: false,
_handle: null,
_parent: null,
_host: null,
_readableState: [Object],
readable: false,
domain: [Object],
_events: [Object],
_eventsCount: 3,
_maxListeners: undefined,
_writableState: [Object],
writable: false,
allowHalfOpen: false,
_bytesDispatched: 0,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: null,
_server: null,
_idleNext: null,
_idlePrev: null,
_idleTimeout: -1,
write: [Function: writeAfterFIN],
[Symbol(asyncId)]: 4541,
[Symbol(bytesRead)]: 0 },
stderr:
Socket {
connecting: false,
_hadError: false,
_handle: null,
_parent: null,
_host: null,
_readableState: [Object],
readable: false,
domain: [Object],
_events: [Object],
_eventsCount: 3,
_maxListeners: undefined,
_writableState: [Object],
writable: false,
allowHalfOpen: false,
_bytesDispatched: 0,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: null,
_server: null,
_idleNext: null,
_idlePrev: null,
_idleTimeout: -1,
write: [Function: writeAfterFIN],
[Symbol(asyncId)]: 4542,
[Symbol(bytesRead)]: 232 },
stdio: [ [Object], [Object], [Object] ] },
stdout: '',
stderr: 'convert-im6.q16: unable to open image `/tmp/PAN_0101197701.jpeg\': No such file or directory # error/blob.c/OpenBlob/2701.\nconvert-im6.q16: no images defined `/tmp/PAN_01011977-thumb.jpeg\' # error/convert.c/ConvertImageCommand/3258.\n' }
Error serializing return value: TypeError: Converting circular structure to JSON
Function execution took 9561 ms, finished with status: 'ok'
The problem is in using the below option in gs without this the function works but it didn't crops the pdf just converts to full page image.
//.option('-c "<</PageOffset [ -64.2 40 ]>> setpagedevice"')
//.option('-c "<</PageOffset [ -308.5 40 ]>> setpagedevice"')
How can i use the above option ?
Edit
Tried to terminate -c with -f but no luck
$ node index.js
gs command: -dSAFER,-dBATCH,-dNOPAUSE,-dTextAlphaBits=4,-dGraphicsAlphaBits=4,-dDEVICEWIDTHPOINTS=238,-dDEVICEHEIGHTPOINTS=149.5,-dFIXEDMEDIA,-r150,-dDownScaleFactor=2,-sPDFPassword=01011977,-sDEVICE=jpeg,-sOutputFile=/home/jcol/Desktop/gs_offline/functions/output.jpeg,-c <</PageOffset[-64.2 40]>>setpagedevice,-f,/home/jcol/Desktop/gs_offline/functions/pan.pdf
Suceess
GPL Ghostscript 9.20 (2016-09-26)
Copyright (C) 2016 Artifex Software, Inc. All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
Processing pages 1 through 1.
Page 1
Loading NimbusSans-Regular font from %rom%Resource/Font/NimbusSans-Regular... 4244908 2808684 2600016 1250276 3 done.
In the absence of an example file (and ideally the actual command line being sent to Ghostscript) as well as the lack of the back channel output (stout and stderr) the only observation I can make is that the 'option' you refer to (actually a piece of PostScript programming) introduces PostScript input with the -c switch but does not terminate it with -f. That means anything which folows this on the comand line will be treated as more PostScript, which is likely to either lead to an error or a 'hang', awaiting more input.
For Future Readers
And For Newbies like ME
There was some confusion in using libraries in NODEJS as i was new to it.
Firstly i was using some gs-wrapper from some tutorials which was not on NPM and that was the cause of the error as that didn't for some reason supported commands.
After some Research i came to Node-gs from npm and i checked Node-GS API at their page in NPM and it had dedicated option for command option.
Now why i posted this Answer :
The NODE-GS library is the only to support serverless architecture like Firebsae Functions. But error handling in this is worst as this only spawns Ghostscirpt directly from the Executable.
For Example if you provide wrong password for PDF then the library just going to push Ghostscript Unrecoverable Error in error Message.
(I know if you are using Ghostscirpt in serverless functions you're smart enough to check if password is correct or not on client side but just for example)
At the time of writing this i found Ghostscript4JS for NODE which uses C++ API of Ghostscript but unfortunately this library doesn't supports serverless architecture as the library depends on system installed Ghostscirpt but the developer said it has some some plans on it.
Check if the library now supported serverless Architecture.
And in the end the struggle as a newbie i had to go through was find portable version of Ghostscirpt to use with NODE-GS and you can find it here Ghostscript Releases
For Firebase Function Users
Firebase functions is built upon Ubuntu Bionic 18.04 arch x64 so you have to use x86_64 version of Ghostscript and The latest at the time of writing is Ghostscript 9.52
B-Bye :)
Related
I am trying to use the createChatInviteLink API method to create a chat invite.
This is the response I get when I try to access it through my browser:
{"ok":true,
"result":{"invite_link":"https://t.me/+4MooeJCENSORED",
"creator":{"id":CENSORED,"is_bot":true,"first_name":"CENSORED","username":"CENSORED"},
"expire_date":1674321925,
"creates_join_request":true,
"is_primary":false,
"is_revoked":false}}
However, none of that useful response shows up when I try the same exact query through my web app. Instead, I get this:
RESPONSE Response {
size: 0,
timeout: 0,
[Symbol(Body internals)]: {
body: PassThrough {
_readableState: [ReadableState],
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
_writableState: [WritableState],
allowHalfOpen: true,
[Symbol(kCapture)]: false,
[Symbol(kCallback)]: null
},
disturbed: false,
error: null
},
[Symbol(Response internals)]: {
url: 'https://api.telegram.org/botCENSORED/createChatInviteLink?chat_id=CENSORED&expire_date=1674422960&creates_join_request=true',
status: 200,
statusText: 'OK',
headers: Headers { [Symbol(map)]: [Object: null prototype] },
counter: 0
}
}
Is there a specific part of the response I need to access? Even response.body isn't returning anything useful.
This is the code that tries to fetch the response:
export async function generateGroupInviteURL(
botToken: string,
groupId: string
) {
const fiveMinutesLaterTimestamp = Math.round(new Date().getTime() / 1000) + 300;
fetch(
`https://api.telegram.org/bot${botToken}/createChatInviteLink?chat_id=${groupId}&expire_date=${fiveMinutesLaterTimestamp}&creates_join_request=true`
).then((res) => {
console.log("RESPONSE", res);
});
}
Any ideas on what I'm doing wrong or need to be doing to access the useful part?
In a react-native project using Realm-js, I've just created a clone of the app, integrated all libs, and copied over all src directories.
The app builds installs and runs on Android.
When i go through the authentication flow (which utilizes realm to store auth data), i ultimately get an error:
[ Error: RealmObject cannot be called as a function ]
login function:
async function login(username, password) {
try {
const result = await Api.login({
username: username,
pass: password,
});
const userAuthResult = await Db.updateAuth(result);
setUserAuth(userAuthResult);
} catch (err) {
console.log('[ ERROR ]:', err)
if (!err.message || err.message.includes('Network Error')) {
throw new Error('Connection error');
}
throw new Error('Wrong username or password');
}
}
and ive narrowed down the issue to Db.updateAuth(...)
updateAuth:
export const updateAuth = (params) => {
console.log(' [ HERE 1 ]')
const auth = {
id: params.id,
token: params.token,
refreshToken: params.refresh_token,
tokenExpiresAt: Math.floor(Date.now() / 1000) + 600, //params.expires_at,
federatedToken: params.federatedToken ?? '',
federatedTokenExpiresAt: params.federatedTokenExpiresAt ?? 0,
username: params.username,
name: params.name,
roleName: params.role_name,
roleId: params.role_id,
lastLogin: Math.floor(Date.now() / 1000),
};
console.log(' [ HERE 2 ]')
realm.write(() => {
console.log(' [ HERE 3 ]')
realm.create('Authorizations', auth, 'modified'); // PROBLEM
});
return auth;
};
inspecting the schema, i found theres no federatedToken propereties, yet in the auth update object, there are two. not sure why it wouldnt be throwing an error in the original non-cloned app.
authorizations schema:
AuthorizationsSchema.schema = {
name: 'Authorizations',
primaryKey: 'id',
properties: {
id: 'int',
token: 'string',
refreshToken: 'string',
tokenExpiresAt: 'int',
username: 'string',
name: 'string',
roleName: 'string',
roleId: 'int',
lastLogin: 'int',
},
};
Realm.js (class declaration) -> https://pastebin.pl/view/c903b2e2
from realm instantiation:
let realm = new Realm({
schema: [
schema.AccountSchema,
schema.AuthorizationsSchema,
schema.AvailableServiceSchema,
schema.FederatedTokensSchema,
schema.NoteSchema,
schema.PhotoSchema,
schema.PhotoUploadSchema,
schema.PrintQueueSchema,
schema.ProductSchema,
schema.ReportSchema,
schema.ServicesSchema,
schema.UploadQueueJobSchema,
schema.InvoicesSchema,
schema.TestSchema
],
schemaVersion: 60,
deleteRealmIfMigrationNeeded: true,
//path: './myrealm/data',
});
this logs the 1, 2, and 3 statements. The issue seems to come from the 'problem' line. Im not sure what exactly this error means, as there doesnt seem to be anything in realm's repo about it, and in the app this was cloned from, there was no issue with this line. I can also see other lines are throwing similar errors later on the user flows
Anyone know what this is about? or where i can learn more?
React-native: v64.2
realm-js: 10.6.0 (app cloned from was v10.2.0)
MacOS: 11.3 (M1 architecture)
in order to create you have the first call, the realm.write a method like this.
const storeInDataBase = (res,selectedfile) => {
try{
realm.write(() => {
var ID =
realm.objects(DocumentConverstionHistory).sorted('HistoryID', true).length > 0
? realm.objects(DocumentConverstionHistory).sorted('HistoryID', true)[0]
.HistoryID + 1
: 1;
realm.create(DocumentConverstionHistory, {
HistoryID: ID,
Name:`${selectedfile.displayname}.pdf`,
Uri:`file://${res.path()}`,
Date: `${new Date()}`
});
})
}catch(err){
alert(err.message)
}
}
Here is the schema file
export const DATABASENAME = 'documentconverter.realm';
export const DocumentConverstionHistory = "DocumentConverstionHistory"
export const DocumentConverstionHistorySchema = {
name: "DocumentConverstionHistory",
primaryKey: 'HistoryID',
properties: {
HistoryID: {type: 'int'},
Name: {type: 'string'},
Uri: {type: 'string?'},
Type: {type: 'string?'},
Size: {type: 'string?'},
Date: {type: 'date?'}
}
};
I am trying to collect and transfer payments using firebase cloud functions in my react native app. I'm using the stripe.accounts.create and stripe.paymentIntents.create functions as well as library axios. I'm really not too sure how to create the connect account and pass the account id created into the payment intent method. I get the following error in the firebase logs 'code: 'StripeInvalidRequestError: Can only apply an application_fee_amount when the PaymentIntent is attempting a direct payment (using an OAuth key or Stripe-Account header) or destination payment (using transfer_data[destination])'
when trying to run my code below. Can someone please assist? I don't think the connectAcc.id is null since I can see it in my stripe dashboard logs in the response body where the account is created:
Response body
{
"id": "acct_**********U5",
"object": "account",
"business_profile": {
"mcc": "5734",
"name": null,
"product_description": null,
"support_address": null,
"support_email": null,
"support_phone": null,
"support_url": null,
index.js file
const stripe = require('stripe')('**SK_LIVE**');
exports.payWithStripe = functions.https.onRequest((request, response) => {
const connectAcc = stripe.accounts.create({
type: 'custom',
email: 'name#gmail.com',
country: 'GB',
business_type: 'individual',
business_profile: {
mcc: '5734',
url: 'site.com',
},
individual: {
first_name: 'First',
last_name: 'Last',
dob : {
day: 1,
month: 10,
year: 1990
},
email: 'name#gmail.com',
phone: '+44xxxxxxx',
address: {
city: 'city',
country: 'GB',
line1: '1',
line2: 'Street Rd',
postal_code: 'XXX XXX'
}
},
tos_acceptance: {
date: Math.floor(Date.now() / 1000),
ip: request.connection.remoteAddress,
},
capabilities: {
card_payments: {requested: true},
transfers: {requested: true},
},
external_account: {
object: 'bank_account',
country: 'GB',
currency: 'gbp',
account_number: 'xxxxx',
routing_number: 'xxxxx',
accounter_holder_name: 'First Last',
account_holder_type: 'individual',
}
})
stripe.paymentIntents.create({
amount: request.body.amount,
currency: request.body.currency,
payment_method_types: ['card'],
payment_method: request.body.payment_method.id,
application_fee_amount: 20,
on_behalf_of: connectAcc.id,
transfer_data: {
destination: connectAcc.id,
},
confirm: true,
description: 'UniHome'
}
).then((charge) => {
response.send(charge);
})
.catch(err =>{
console.log(err);
})
});
Thanks.
connectAcc is not an account object — it's a Promise. That's what Stripe's SDK returns.
You'd have to resolve the Promise first, like:
let connectAcc = await stripe.accounts.create(...); let id = connectAcc.id or stripe.accounts.create(...).then(function(acct){let id = acct.id;} )
I am trying to make this example work. It is supposed to create two nodes with mdns support. Mdns is supposed to announce the peer every second, each peer is setup to print a statement once a peer is found.
When running it, the console output is merely empty. It prints out some garbage error in my concern: (node:51841) ExperimentalWarning: Readable[Symbol.asyncIterator] is an experimental feature. This feature could change at any time
How do i enable debugging log so that i can try to understand what is going on under the hood ?
I would like to verify the mdns announce packets are issued, and possibly received, or not.
Alternatively, i am trying to use the bootstrap module to begin over wan peers, though expect it to be much slower, thus i would prefer to use mdns.
I tried to add various configuration and modules without much success, it is not clear to me if i am required to use the gossip module if i only want to announce some data on the dht. stuff like that.
any help is appreciated.
const Libp2p = require('libp2p')
const MulticastDNS = require('libp2p-mdns')
const KadDHT = require('libp2p-kad-dht')
const Bootstrap = require('libp2p-bootstrap')
const TCP = require('libp2p-tcp')
const Mplex = require('libp2p-mplex')
const { NOISE } = require('libp2p-noise')
const GossipSub = require('libp2p-gossipsub')
const { FaultTolerance } = require('libp2p/src/transport-manager')
const CID = require('cids')
const all = require('it-all')
const delay = require('delay')
const bootstrapers = [
'/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ',
'/ip4/104.236.176.52/tcp/4001/p2p/QmSoLnSGccFuZQJzRadHn95W2CrSFmZuTdDWP8HXaHca9z',
'/ip4/104.236.179.241/tcp/4001/p2p/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM',
'/ip4/162.243.248.213/tcp/4001/p2p/QmSoLueR4xBeUbY9WZ9xGUUxunbKWcrNFTDAadQJmocnWm',
'/ip4/128.199.219.111/tcp/4001/p2p/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu',
'/ip4/104.236.76.40/tcp/4001/p2p/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64',
'/ip4/178.62.158.247/tcp/4001/p2p/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd',
'/ip4/178.62.61.185/tcp/4001/p2p/QmSoLMeWqB7YGVLJN3pNLQpmmEk35v6wYtsMGLzSr5QBU3',
'/ip4/104.236.151.122/tcp/4001/p2p/QmSoLju6m7xTh3DuokvT3886QRYqxAzb1kShaanJgW36yx'
]
const createNode = () => {
return Libp2p.create({
addresses: {
listen: ['/ip4/0.0.0.0/tcp/0']
},
modules: {
transport: [ TCP ],
streamMuxer: [ Mplex ],
connEncryption: [ NOISE ],
// peerDiscovery: [ MulticastDNS ],
// peerDiscovery: [ MulticastDNS ],
peerDiscovery: [ Bootstrap, MulticastDNS ],
dht: KadDHT,
pubsub: GossipSub
},
transportManager: {
faultTolerance: FaultTolerance.NO_FATAL
},
config: {
peerDiscovery: {
autoDial: true,
[MulticastDNS.tag]: {
broadcast: true,
interval: 1000,
enabled: true
},
[Bootstrap.tag]: {
interval: 1000,
enabled: true,
list: bootstrapers
},
[GossipSub.tag]: {
enabled: true,
emitSelf: true,
signMessages: true,
strictSigning: true
},
mdns: {
broadcast: true,
interval: 1000,
enabled: true
},
bootstrap: {
interval: 1000,
enabled: true,
list: bootstrapers
},
pubsub: {
enabled: true,
emitSelf: true,
signMessages: true,
strictSigning: true
},
},
dht: {
enabled: true
}
}
})
}
( async () => {
const [node1, node2] = await Promise.all([
createNode(),
createNode()
])
node1.on('peer:discovery', (peer) => console.log('Discovered:', peer.id.toB58String()))
node2.on('peer:discovery', (peer) => console.log('Discovered:', peer.id.toB58String()))
await Promise.all([
node1.start(),
node2.start()
])
// const cid = new CID('QmTp9VkYvnHyrqKQuFPiuZkiX9gPcqj6x5LJ1rmWuSySnL')
// await node1.contentRouting.provide(cid)
// await delay(3000)
// console.log("looking for providers...")
// const providers = await all(node2.contentRouting.findProviders(cid, { timeout: 5000 }))
// console.log('Found provider:', providers[0].id.toB58String())
})()
edit: found out i could use DEBUG environment variable to print debug statements, thouhg i still have problems with event system.
Logging
To enable debugging, configure the DEBUG environment variable. Start with DEBUG=*, it prints log lines like:
mss:select select: read "/noise" +1ms
libp2p:upgrader encrypting outbound connection to {"id":"QmRiNVP5NSGJPHLo256vNMTYW9VzsTKYm4dRG3GoJj37ah"} +12ms
libp2p:noise Stage 0 - Initiator starting to send first message. +14ms
Select stuff you want to print out using DEBUG=*noise ...
events
The probleme in OP code is that the peer:discovery event has an argument of type PeerID, not Peer. Thus the statements console.log('Discovered:', peer.id.toB58String()) is incorrect and should be replaced with console.log('Discovered:', peer.toB58String())
But one may have noticed the OP did not provide any error messages related to that. That happens because those event handlers are handled with an error silencer.
I am unsure what is going on, though, runnning below code will not trigger the exception with the "yo" message.
node1.on('peer:discovery', (peerID) => {
console.log(node1.peerId.toB58String(), "discovered:", peerID.toB58String())
throw "yo"
})
Related source code
const Libp2p = require('libp2p')
const MulticastDNS = require('libp2p-mdns')
const KadDHT = require('libp2p-kad-dht')
const Bootstrap = require('libp2p-bootstrap')
const TCP = require('libp2p-tcp')
const Mplex = require('libp2p-mplex')
const { NOISE } = require('libp2p-noise')
const CID = require('cids')
const all = require('it-all')
const delay = require('delay')
const bootstrapers = [
'/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ',
'/ip4/104.236.176.52/tcp/4001/p2p/QmSoLnSGccFuZQJzRadHn95W2CrSFmZuTdDWP8HXaHca9z',
'/ip4/104.236.179.241/tcp/4001/p2p/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM',
'/ip4/162.243.248.213/tcp/4001/p2p/QmSoLueR4xBeUbY9WZ9xGUUxunbKWcrNFTDAadQJmocnWm',
'/ip4/128.199.219.111/tcp/4001/p2p/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu',
'/ip4/104.236.76.40/tcp/4001/p2p/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64',
'/ip4/178.62.158.247/tcp/4001/p2p/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd',
'/ip4/178.62.61.185/tcp/4001/p2p/QmSoLMeWqB7YGVLJN3pNLQpmmEk35v6wYtsMGLzSr5QBU3',
'/ip4/104.236.151.122/tcp/4001/p2p/QmSoLju6m7xTh3DuokvT3886QRYqxAzb1kShaanJgW36yx'
]
const createNode = () => {
return Libp2p.create({
addresses: {
listen: ['/ip4/0.0.0.0/tcp/0']
},
modules: {
transport: [ TCP ],
streamMuxer: [ Mplex ],
connEncryption: [ NOISE ],
// peerDiscovery: [ MulticastDNS ],
peerDiscovery: [ MulticastDNS ],
// peerDiscovery: [ Bootstrap, MulticastDNS ],
dht: KadDHT,
// pubsub: GossipSub
},
// transportManager: {
// faultTolerance: FaultTolerance.NO_FATAL
// },
config: {
peerDiscovery: {
autoDial: true,
[MulticastDNS.tag]: {
broadcast: true,
interval: 1000,
enabled: true
},
[Bootstrap.tag]: {
interval: 1000,
enabled: true,
list: bootstrapers
},
},
dht: {
enabled: true
}
}
})
}
( async () => {
const [node1, node2] = await Promise.all([
createNode(),
createNode()
])
node1.on('peer:discovery', (peerID) => {
console.log(node1.peerId.toB58String(), "discovered:", peerID.toB58String())
})
node2.on('peer:discovery', (peerID) => {
console.log(node2.peerId.toB58String(), "discovered:", peerID.toB58String())
})
node1.on('error', console.error)
node2.on('error', console.error)
await Promise.all([
node1.start(),
node2.start()
])
})()
I am trying to test my app and followed this link http://lathonez.github.io/2016/ionic-2-e2e-testing/ i merged my app with firebase. Everything worked good, but when i run npm run e2e browser opens and close immediately in my terminal pops an error.
I followed this link http://lathonez.github.io/2016/ionic-2-e2e-testing/
Actually my issue is that i could not able to see any action takes place in my e2e browser could some on help me
protractorconfig.js
exports.config = {
baseUrl: 'http://192.168.1.2:8100/',
specs: [
'../app/pages/home/home.e2e.ts',
'../app/pages/Admin/admin.e2e.ts',
//'../app/pages/Listing/lisitngPage.e2e.ts'
],
exclude: [],
framework: 'jasmine2',
allScriptsTimeout: 110000,
jasmineNodeOpts: {
showTiming: true,
showColors: true,
isVerbose: false,
includeStackTrace: false,
defaultTimeoutInterval: 400000
},
directConnect: true,
chromeOnly: true,
capabilities: {
'browserName': 'chrome',
'chromeOptions': {
'args': ['--disable-web-security']
}
},
onPrepare: function() {
var SpecReporter = require('jasmine-spec-reporter');
jasmine.getEnv().addReporter(new SpecReporter({displayStacktrace: true}));
browser.ignoreSynchronization = false;
},
useAllAngular2AppRoots: true
};
gulpfile.ts
import { join } from 'path';
const config: any = {
gulp: require('gulp'),
appDir: 'app',
testDir: 'test',
testDest: 'www/build/test',
typingsDir: 'typings',
};
const imports: any = {
gulp: require('gulp'),
runSequence: require('run-sequence'),
ionicGulpfile: require(join(process.cwd(), 'gulpfile.js')),
};
const gulp: any = imports.gulp;
const runSequence: any = imports.runSequence;
// just a hook into ionic's build
gulp.task('build-app', (done: Function) => {
runSequence(
'build',
(<any>done)
);
});
// compile E2E typescript into individual files, project directoy structure is replicated under www/build/test
gulp.task('build-e2e', ['clean-test'], () => {
let typescript: any = require('gulp-typescript');
let tsProject: any = typescript.createProject('tsconfig.json');
let src: Array<any> = [
join(config.typingsDir, '/index.d.ts'),
join(config.appDir, '**/*e2e.ts'),
];
let result: any = gulp.src(src)
.pipe(typescript(tsProject));
return result.js
.pipe(gulp.dest(config.testDest));
});
// delete everything used in our test cycle here
gulp.task('clean-test', () => {
let del: any = require('del');
// You can use multiple globbing patterns as you would with `gulp.src`
return del([config.testDest]).then((paths: Array<any>) => {
console.log('Deleted', paths && paths.join(', ') || '-');
});
});
// run jasmine unit tests using karma with PhantomJS2 in single run mode
gulp.task('karma', (done: Function) => {
let karma: any = require('karma');
let karmaOpts: {} = {
configFile: join(process.cwd(), config.testDir, 'karma.config.js'),
singleRun: true,
};
new karma.Server(karmaOpts, done).start();
});
// run jasmine unit tests using karma with Chrome, Karma will be left open in Chrome for debug
gulp.task('karma-debug', (done: Function) => {
let karma: any = require('karma');
let karmaOpts: {} = {
configFile: join(process.cwd(), config.testDir, 'karma.config.js'),
singleRun: false,
browsers: ['Chrome'],
reporters: ['mocha'],
};
new karma.Server(karmaOpts, done).start();
});
// run tslint against all typescript
gulp.task('lint', () => {
let tslint: any = require('gulp-tslint');
return gulp.src(join(config.appDir, '**/*.ts'))
.pipe(tslint())
.pipe(tslint.report('verbose'));
});
// build unit tests, run unit tests, remap and report coverage
gulp.task('unit-test', (done: Function) => {
runSequence(
['lint', 'html'],
'karma',
(<any>done)
);
});