5.1.5 • Published 1 year ago

xdccjs v5.1.5

Weekly downloads
5
License
MIT
Repository
github
Last release
1 year ago

Features :

xdccJS is a complete implementation of the XDCC protocol for nodejs.
It can also be used as a command-line downloader !

Table of contents

Installation

NPM

API

Getting started

There's three different way to import/require xdccJS depending on which environment it is running:

CommonJS

const XDCC = require('xdccjs')
const xdccJS = new XDCC.default({/*..options..*/})

Modules

import XDCC from 'xdccjs'
const xdccJS = new XDCC.default({/*..options..*/})

TypeScript

import XDCC from 'xdccjs'
const xdccJS = new XDCC({/*..options..*/})

Example

const XDCC = require('xdccjs')

const xdccJS = new XDCC.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'])
})

Options

Every parameter is optional, except for host.

const opts = {
  host: 'irc.server.net', // IRC hostname                                                   - required
  port: 6660, // IRC port                                                                   - default: 6667
  tls: {
    enable: true, // Enable TLS Support                                                     - default: false
    rejectUnauthorized: true, // Reject self-signed certificates                            - default: false
  },
  nickname: 'ItsMeJiPaix', // Nickname                                                      - default: xdccJS + random
  nickServ: '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: 1
  timeout: 50, // Nb of seconds before a download is considered timed out                   - default: 30
  verbose: true, // Display download progress and jobs status                               - default: false
  randomizeNick: false, // Add random numbers at end of nickname                            - default: true
  passivePort: [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: true
  throttle: 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    
}

Config

xdccJS.config( parameters? : object ) change parameters during runtime
If there's a file downloading throttle and passivePort 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
})

Download

xdccJS.download( bot : string, packets : string | number | number[] | string[], options?: { ipv6?: boolean ** throttle?: number } )
download() is asynchronous and returns a Job
options are optional, per job options.ipv6 parameter is only required when if a bot's is ipv6 AND uses passive DCC

xdccJS.on('ready', async () => {
  const blue = await xdccJS.download('XDCC|BLUE', '1-3, 8, 55')
  const yellow = await xdccJS.download('XDCC|YELLOW', 4)
  const red = await xdccJS.download('XDCC|RED', [12, 7, 10, 20])
  const purple = await xdccJS.download('XDCC|PURPLE', ['1', '3', '10', '20'])
})

Download queue detection

xdccJS will timeout any request after a certain amount of time when no file is sent (see Options.timeout), Which is exactly what happens when a bot puts you into queue.

To avoid this behavior you need to provide a regex matching the bot "queue message".

If you are clueless about regexes try regexlearn.com interactive tutorial.

const opts = {
  host: 'irc.server.com',
  timeout: 20 // defaut is 30
  queue: /request(.*)queued(.*)\d+\/\d+$/gi
  //=> excepted bot queue message: "Your request has been queued: position x/x"
}
const xdccJS = new XDCC(opts)

xdccJS.on('ready', async () =>{
  const queued = await xdccJS.download('BOT_WITH_LARGE_QUEUE', '1-5')
  //=> if the bot sends a message matching the regex, download won't fail
})

Jobs

Jobs are download() instances which are tied to the target nickname.
calling download() multiple times for the same target will update current job.

xdccJS.on('ready', async () => {
  // jobs are automatically updated
  const botA_1 = await xdccJS.download('BOT-A', 1)
  const botA_2 = await xdccJS.download('BOT-A', 2)
  const botA_3 = await xdccJS.download('BOT-A', 3)
  // botA_1 === botA_2 === botA_3


  // but each "target" has its own job
  const botB_1 = await xdccJS.download('DIFFERENT_TARGET', 4)
  // botA_1 !== botB_1

  // once a job's done, its lifetime ends
  botA_1.on('done', async () => {
    const botA_5 = await xdccJS.download('BOT-A', 5)
    // botA_1 !== botA_5
  })

  // Job options are overwritable
  await xdccJS.download('BOT-B', 1, { throttle: 500 })
  await xdccJS.download('BOT-B', 2, { throttle: 1000 })
  // => Both packets, 1 and 2, will be throttled at 1000 (latest)
})

You can also retrieve on going jobs

xdccJS.jobs( bot : string | undefined )

// find job by botname
const job = await xdccJS.jobs('bot-name')

// retrieve all jobs at once
const arrayOfJobs = await xdccJS.jobs()

Jobs offer three options :

  1. Get job progress status :
    let status = job1.show()
    let isdone = job1.isDone()
    console.log(status)
    //=> { name: 'a-bot', queue: [98], now: 62, success: ['file.txt'], failed: [50] }
    console.log(isdone)
    //=> false
  2. Cancel a Job
    job2.cancel()
  3. Events to track progress (see events documentation)

    job.on('downloaded', (fileInfo) => {
      //=> a file has been downloaded
    })
    
    job.on('done', () => {
      //=> job has finished downloading all requested packages
    })
    
    // more below..

Events

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 parameter verbose = 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) => {
        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) => {
  console.log(percentage) //=> 10.55
})
```

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.pdf
  console.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 (see pipe 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) => {
          err instanceof Error //=> true
          console.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|BLUE
          console.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)
      })

Pipes

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.
const opts = {
  host: 'irc.server.net',
  path: false, 
}

const xdccJS = new XDCC(opts)

// Start VLC const { spawn } = require('child_process') const vlcPath = path.normalize('C:\Program Files\VideoLAN\VLC\vlc.exe') const vlc = spawn(vlcPath, '-')

xdccJS.on('ready', async () => { const Job = await xdccJS.download('bot', 155) // send data to VLC that plays the file Job.on('pipe', stream => { stream.pipe(vlc.stdin) }) })

## Disconnect
```js
// event triggered when all jobs are done.
xdccJS.on('can-quit', () => {
  xdccJS.quit() // this is how you disconnect from IRC
})

Advanced IRC commands

@kiwiirc/irc-framework is embed into xdccJS.
Check their client API documentation

xdccJS.on('ready', () => {
  // change nickname
  xdccJS.changeNick('new-nickname')
  // listen to kick events
  xdccJS.on('kick', (info) => {
    //=> do something..
  })
})

An extended version of this example is available here

Command-line Interface

Installation

npm install xdccjs -g

CLI Options

-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

Usage

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 the bot name and download path as they often both include unescaped characeters or whitespaces, They are mandatory when using between --queue's regex (see examples below)

Profiles

You can use profiles to automatically load predefined options on startup

How to use profiles

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" settings
xdccJS --bot "XDCC|BOT" --download "1132-1137"

You can override profile settings:

# use "my_profile" profile, change download path
xdccJS --bot "XDCC|BOT" --download "1132-1137" --path "/home/user/new/path"

If a profile provide at least a --host you can use the lazy mode:

xdccJS "/msg XDCC|BOT xdcc send 1132-1337" # quotes are important here

Save Profile

xdccJS --save-profile "my_profile" --host "irc.server.net" --port 6669 --path "C:/Users/username/Desktop"

Saved profile are automatically set as default.

Change default profile

xdccJS --set-profile "my_profile"

Delete profile

xdccJS --delete-profile "my_profile"

List available profiles

 xdcJS --list-profile 

FYI

  • 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"
  • see why is queue important

Documentation

Full documentation is available here

5.0.0

1 year ago

4.7.0

1 year ago

5.1.5

1 year ago

5.1.2

1 year ago

4.6.2

1 year ago

4.6.5

1 year ago

4.5.7

2 years ago

4.4.21

2 years ago

4.4.20

2 years ago

4.5.64

2 years ago

4.5.69

2 years ago

4.5.33

2 years ago

4.5.31

2 years ago

4.5.35

2 years ago

4.5.28

2 years ago

4.5.0

2 years ago

4.4.14

2 years ago

4.4.18

2 years ago

4.4.17

2 years ago

4.4.16

2 years ago

4.4.15

2 years ago

4.4.19

2 years ago

4.3.209

2 years ago

4.4.0

2 years ago

4.4.13

2 years ago

4.4.8

2 years ago

4.3.10

3 years ago

4.3.14

3 years ago

4.3.20

3 years ago

4.3.1

3 years ago

4.3.0

3 years ago

4.2.9

3 years ago

4.2.8

3 years ago

4.2.7

3 years ago

4.2.6

3 years ago

4.2.5

3 years ago

4.2.4

3 years ago

4.2.1

3 years ago

4.2.0

4 years ago

4.1.6

4 years ago

4.1.5

4 years ago

4.1.4

4 years ago

4.1.3

4 years ago

4.1.2

4 years ago

4.1.0

4 years ago

4.1.1

4 years ago

4.0.5

4 years ago

4.0.4

4 years ago

4.0.3

4 years ago

4.0.2

4 years ago

4.0.1

4 years ago

4.0.0

4 years ago

3.4.3

4 years ago

3.4.2

4 years ago

3.4.1

4 years ago

3.4.0

4 years ago

3.3.3

4 years ago

3.3.2

4 years ago

3.3.1

4 years ago

3.3.0

4 years ago

3.2.2

4 years ago

3.2.4

4 years ago

3.2.3

4 years ago

3.2.1

4 years ago

3.2.0

4 years ago

3.1.2

4 years ago

3.1.1

4 years ago

3.0.2

4 years ago

3.1.0

4 years ago

3.0.1

4 years ago

3.0.0

4 years ago

2.9.0

4 years ago

2.8.0

4 years ago

2.7.0

4 years ago

2.6.85

4 years ago

2.6.83

4 years ago

2.6.84

4 years ago

2.6.82

4 years ago

2.6.81

4 years ago

2.6.5

4 years ago

2.6.4

4 years ago

2.6.7

4 years ago

2.6.6

4 years ago

2.6.8

4 years ago

2.6.3

4 years ago

2.6.2

4 years ago

2.6.1

4 years ago

2.6.0

4 years ago

2.5.5

4 years ago

2.5.41

4 years ago

2.5.4

4 years ago

2.5.3

4 years ago

2.5.2

4 years ago

2.5.0

4 years ago

2.4.3

4 years ago

2.4.2

4 years ago

2.4.1

4 years ago

2.4.0

4 years ago

2.3.4

4 years ago

2.3.3

4 years ago

2.3.2

4 years ago

2.3.1

4 years ago

2.3.0

4 years ago

2.2.0

4 years ago

2.1.1

4 years ago

2.1.0

4 years ago

1.2.0

4 years ago

2.0.0

4 years ago

1.1.3

4 years ago

1.1.2

4 years ago

1.1.1

4 years ago

1.0.2

4 years ago

1.1.0

4 years ago

1.0.3

4 years ago

1.0.1

4 years ago

1.0.0

4 years ago