- Notifications
You must be signed in to change notification settings - Fork7
xdccJS is a Node.js library and client to download files from XDCC bots on IRC
License
JiPaix/xdccJS
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
xdccJS is a complete implementation of theXDCC protocol for nodejs.
It can also be used as acommand-line downloader !
- Batch downloads :
1-3, 5, 32-35, 101
- Resume file and auto-retry
- Pipes!
- Passive DCC
- Checkadvanced examples and see what else you can do
- API
- Getting Started
- List of options
- Download
- (Auto) disconnect from IRC
- Advanced IRC commands and middlewares
- CLI
There's three different way to import/require xdccJS depending on which environment it is running:
constXDCC=require('xdccjs')constxdccJS=newXDCC.default({/*..options..*/})
importXDCCfrom'xdccjs'constxdccJS=newXDCC.default({/*..options..*/})
importXDCCfrom'xdccjs'constxdccJS=newXDCC({/*..options..*/})
constXDCC=require('xdccjs')constxdccJS=newXDCC.default({host:'irc.server.net',port:6667,chan:['#welcome','#fansub'],nickname:'Leon',path:'/home/leon/downloads'})xdccJS.on('ready',()=>{xdccJS.download('XDCC|BOT_RED',5)xdccJS.download('XDCC|BOT_GREEN','1-3, 55, 100-200')xdccJS.download('XDCC|BOT_BLUE',[12,7,10,20])xdccJS.download('XDCC|BOT_ALPHA',['5','6'])})
Every parameter is optional, except forhost
.
constopts={host:'irc.server.net',// IRC hostname - requiredport:6660,// IRC port - default: 6667tls:{enable:true,// Enable TLS Support - default: falserejectUnauthorized:true,// Reject self-signed certificates - default: false},nickname:'ItsMeJiPaix',// Nickname - default: xdccJS + randomnickServ:'complex_password',// Your NickServ password (no spaces) - default: undefined (disabled)chan:['#candy','#fruits'],// Array of channels - default : [ ] (no chan)path:'downloads',// Download path or 'false' - default: false (which enables piping)retry:2,// Nb of retries before skip - default: 1timeout:50,// Nb of seconds before a download is considered timed out - default: 30verbose:true,// Display download progress and jobs status - default: falserandomizeNick:false,// Add random numbers at end of nickname - default: truepassivePort:[5000,5001,5002],// Array of port(s) to use with Passive DCC - default: [5001]botNameMatch:false,// Block downloads if the bot's name does not match the request - default: truethrottle:500,// Throttle download speed to n KiB/s - default: undefined (disabled)queue:/soMething(.*)maTching/g// - default: undefined (disabled)// ^ Regex matching the bot's message when you're request is moved to a queue}
xdccJS.config( parameters? : object)change parameters during runtime
If there's a file downloadingthrottle
andpassivePort
won't be applied until the next download
xdccJS.config({passivePort:[5000,5001,5002],throttle:800,nickname:'TrustMe',chan:['#candy','#fruits'],path:'download/subfolder',botNameMatch:false,retry:5,timeout:50,verbose:false,randomizeNick:true,queue:/soMething(.*)maTching/g})
xdccJS.download( bot : string,packets : string | number | number[] | string[],options?: {ipv6?: boolean **throttle?: number })
download()
is asynchronous and returns aJob
options
are optional, per joboptions.ipv6
parameter is only required when if a bot's is ipv6AND uses passive DCC
xdccJS.on('ready',async()=>{constblue=awaitxdccJS.download('XDCC|BLUE','1-3, 8, 55')constyellow=awaitxdccJS.download('XDCC|YELLOW',4)constred=awaitxdccJS.download('XDCC|RED',[12,7,10,20])constpurple=awaitxdccJS.download('XDCC|PURPLE',['1','3','10','20'])})
xdccJS will timeout any request after a certain amount of time when no file is sent (seeOptions.timeout), Which is exactly what happens when a bot puts you into queue.
To avoid this behavior you need to provide aregex matching the bot "queue message".
If you are clueless about regexes tryregexlearn.com interactive tutorial.
constopts={host:'irc.server.com',timeout:20// defaut is 30queue:/request(.*)queued(.*)\d+\/\d+$/gi//=> excepted bot queue message: "Your request has been queued: position x/x"}constxdccJS=newXDCC(opts)xdccJS.on('ready',async()=>{constqueued=awaitxdccJS.download('BOT_WITH_LARGE_QUEUE','1-5')//=> if the bot sends a message matching the regex, download won't fail})
Job
s aredownload()
instances which are tied to the target nickname.
callingdownload()
multiple times for the same target will update current job.
xdccJS.on('ready',async()=>{// jobs are automatically updatedconstbotA_1=awaitxdccJS.download('BOT-A',1)constbotA_2=awaitxdccJS.download('BOT-A',2)constbotA_3=awaitxdccJS.download('BOT-A',3)// botA_1 === botA_2 === botA_3// but each "target" has its own jobconstbotB_1=awaitxdccJS.download('DIFFERENT_TARGET',4)// botA_1 !== botB_1// once a job's done, its lifetime endsbotA_1.on('done',async()=>{constbotA_5=awaitxdccJS.download('BOT-A',5)// botA_1 !== botA_5})// Job options are overwritableawaitxdccJS.download('BOT-B',1,{throttle:500})awaitxdccJS.download('BOT-B',2,{throttle:1000})// => Both packets, 1 and 2, will be throttled at 1000 (latest)})
xdccJS.jobs( bot : string | undefined)
// find job by botnameconstjob=awaitxdccJS.jobs('bot-name')// retrieve all jobs at onceconstarrayOfJobs=awaitxdccJS.jobs()
- Get job progress status :
letstatus=job1.show()letisdone=job1.isDone()console.log(status)//=> { name: 'a-bot', queue: [98], now: 62, success: ['file.txt'], failed: [50] }console.log(isdone)//=> false
- Cancel a Job
job2.cancel()
- Events to track progress (seeevents documentation)
job.on('downloaded',(fileInfo)=>{//=> a file has been downloaded})job.on('done',()=>{//=> job has finished downloading all requested packages})// more below..
Most events are accessible both from xdccJS or a Job scope
FYI: those examples are for the sake of showing xdccJS capabilities, if you need download status to be displayed in a nice way just start xdccJS with parameterverbose = true
[xdccJS].on('ready' ) :xdccJS is ready to download
xdccJS.on('ready',async()=>{// download() here})
[xdccJS |Job].on('downloading' ) :Data is being received (a file is downloading)
xdccJS.on('downloading',(fileInfo,received,percentage,eta)=>{console.log(fileInfo)//=> { file: 'filename.pdf', filePath: '/path/to/filename.pdf', length: 5844849 }console.log(`downloading: '${fileInfo.file}'`)//=> downloading: 'your file.pdf'})job.on('downloading',(fileInfo,received,percentage,eta)=>{console.log(`${percentage}% -${eta} ms remaining`)//=> 10.55% - 153500 ms remaining})
[xdccJS |Job].on('downloaded' ) :A file successfully downloaded
xdccJS.on('downloaded',(fileInfo)=>{console.log(fileInfo.filePath)//=> /home/user/xdccJS/downloads/myfile.pdf})job.on('downloaded',(fileInfo)=>{console.log('Job1 has downloaded:'+fileInfo.filePath)//=> Job1 has downloaded: /home/user/xdccJS/downloads/myfile.pdfconsole.log(fileInfo)//=> { file: 'filename.pdf', filePath: '/home/user/xdccJS/downloads/myfile.pdf', length: 5844849 }})
[xdccJS |Job].on('done' ) :A job has no remaining package in queue
xdccJS.on('done',(job)=>{console.log(job.show())//=> { name: 'a-bot', queue: [98], now: 62, success: ['file.txt'], failed: [50] }})job.on('done',(job)=>{console.log('Job2 is done!')console.log(job.show())//=> { name: 'a-bot', queue: [98], now: 62, success: ['file.txt'], failed: [50] }})
[xdccJS |Job].on('pipe' ) :A pipe is available (seepipe documentation)
xdccJS.on('pipe',(stream,fileInfo)=>{stream.pipe(somewhere)console.log(fileInfo)//=> { file: 'filename.pdf', filePath: 'pipe', length: 5844849 }})job.on('pipe',(stream,fileInfo)=>{stream.pipe(somewhere)console.log(fileInfo)//=> { file: 'filename.pdf', filePath: 'pipe', length: 5844849 }})
[xdccJS].on('error' ) :Connection Errors
xdccJS.on('error',(err)=>{errinstanceofError//=> trueconsole.error(err.message)//=> UNREACHABLE HOST 1.1.1.1:6667})
[Job].on('error' ) :Job interrupted/canceled or connexion with bot unreachable
job.on('error',(message,fileInfo)=>{console.error(message)//=> timeout: no response from XDCC|BLUEconsole.log(fileInfo)//=> { file: 'filename.pdf', filePath: 'pipe', length: 5844849 }})
[Job].on('cancel' ) :Job canceled by user
job.on('cancel',(message)=>{console.error(message)//=> "cancelled by user"})
[xdccJS].on('debug' ) :debug message
xdccJS.on('debug',(message)=>{console.info(message)})
In order to use pipes xdccJS need to be initialized with path option set to false
// This example will start vlc.exe then play the video while it's downloading.constopts={host:'irc.server.net',path:false,}constxdccJS=newXDCC(opts)// Start VLCconst{ spawn}=require('child_process')constvlcPath=path.normalize('C:\\Program Files\\VideoLAN\\VLC\\vlc.exe')constvlc=spawn(vlcPath,['-'])xdccJS.on('ready',async()=>{constJob=awaitxdccJS.download('bot',155)// send data to VLC that plays the fileJob.on('pipe',stream=>{stream.pipe(vlc.stdin)})})
// event triggered when all jobs are done.xdccJS.on('can-quit',()=>{xdccJS.quit()// this is how you disconnect from IRC})
@kiwiirc/irc-framework is embed into xdccJS.
Check their client APIdocumentation
xdccJS.on('ready',()=>{// change nicknamexdccJS.changeNick('new-nickname')// listen to kick eventsxdccJS.on('kick',(info)=>{//=> do something..})})
An extended version of this example is availablehere
npm install xdccjs -g
-V, --version output the version number-h, --host <server> IRC server hostname - required--port <number> IRC server port - default: 6667-n, --nickname <nickname> Your nickname - default: xdccJS--no-randomize Disable nickname randomization - default: randomize-c, --channel <chans...> Channel(s) to join - optional-p, --path <path> Download path - optional-b, --bot <botname> XDCC bot nickname - required-d, --download <packs...> Packs to download - required--throttle <number> Throttle download speed (KiB/s) - default disabled--nickserv <password> Authenticate to NickServ - default: disabled--passive-port <number> Port to use for passive dccs - optional--ipv6 Use IPv6, only required if bot use both passive dcc and IPv6 - default: disabled-r, --retry <number> Number of attempts before skipping pack - optional-t --timeout <number> Time in seconds before a download is considered timed out - optional-w, --wait <number> Time to wait before sending download request - optional--no-bot-name-match Allow downloads from bot with nickname that doesn't match the request - optional--queue <RegExp> Regex to determine if the bot queued the request - optional--tls enable SSL/TLS - optional--no-insecure Reject self-signed SSL/TLS certificates - optional--save-profile <string> save current options as a profile - optional--delete-profile <string> delete profile - optional--set-profile <string> set profile as default - optional--list-profile list all available profiles - optional-q, --quiet Disable console output - optional--help display help for command
xdccJS --host irc.server.net --bot"XDCC-BOT|BLUE" --download 1-5,100-105 --path"/home/user/downloads"
Alternatively, if you want to pipe the file just ommit the--path
option :
xdccJS --host irc.server.net --bot"XDCC-BOT|RED" --download 110| vlc -
I recommend using double quotation marks between thebot name
anddownload path
as they often both include unescaped characeters or whitespaces,They are mandatory when using between--queue
's regex (seeexamples below)
You can use profiles to automatically load predefined options on startup
Save a predefined set of options:
# save a profile with name "my_profile"xdccJS --save-profile"my_profile" --host"irc.server.net" --port"6669" --path"C:/Users/JiPaix/Desktop"
# use "my_profile" settingsxdccJS --bot"XDCC|BOT" --download"1132-1137"
You can override profile settings:
# use "my_profile" profile, change download pathxdccJS --bot"XDCC|BOT" --download"1132-1137" --path"/home/user/new/path"
If a profile provide at least a--host
you can use thelazy mode:
xdccJS"/msg XDCC|BOT xdcc send 1132-1337"# quotes are important here
xdccJS --save-profile"my_profile" --host"irc.server.net" --port 6669 --path"C:/Users/username/Desktop"
Saved profile are automatically set as default.
xdccJS --set-profile"my_profile"
xdccJS --delete-profile"my_profile"
xdcJS --list-profile
- hashtags for channels and packs are optional :
--channel"#my-channel" --download"#132"# is the same as --channel"my-channel" --download"132"
- given options prevails over the one provided by profiles :
- except for
--host
, which results in xdccJS ignoring the current profile - example:
# current profile has --wait 5, but this time you need --wait 50 xdccJS --bot"mybot" --download"125-130" --wait 50``````bash# ignores ALL profile options xdccJS --host"irc.mywnewserver.org"
- options
--bot
and--path
often contains special characters and/or whitespaces : # this wont work --path /home/user/my folder --bot XDCC|BOT --download 123-125# fixed --path"/home/user/my folder" --bot"XDCC|BOT" --download 123-125
- an example with
--queue
regex: xdccJS --host"irc.server.com" --bot"SOME_BOT" --download"1-100" --queue"/request(.*)queued(.*)\d+\/\d+$/gi"# excepted bot queue message: "Your request has been queued: position x/x"
- seewhy is queue important
Full documentation is availablehere
About
xdccJS is a Node.js library and client to download files from XDCC bots on IRC