Bootstrap project
This commit is contained in:
		
							
								
								
									
										15
									
								
								.eslintrc.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								.eslintrc.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
{
 | 
			
		||||
  "env": {
 | 
			
		||||
    "node": true,
 | 
			
		||||
    "commonjs": true,
 | 
			
		||||
    "es2021": true
 | 
			
		||||
  },
 | 
			
		||||
  "extends": ["plugin:prettier/recommended", "plugin:mocha/recommended"],
 | 
			
		||||
  "parser": "@typescript-eslint/parser",
 | 
			
		||||
  "parserOptions": {
 | 
			
		||||
    "ecmaVersion": 12
 | 
			
		||||
  },
 | 
			
		||||
  "plugins": ["@typescript-eslint", "mocha"],
 | 
			
		||||
  "rules": {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
build/
 | 
			
		||||
node_modules/
 | 
			
		||||
							
								
								
									
										1
									
								
								.prettierrc.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.prettierrc.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
{}
 | 
			
		||||
							
								
								
									
										107
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										107
									
								
								README.md
									
									
									
									
									
								
							@@ -1,32 +1,40 @@
 | 
			
		||||
# easy-rss-parser
 | 
			
		||||
 | 
			
		||||
A lightweight library to give some additions for the [rss-parser package](https://github.com/rbren/rss-parser).
 | 
			
		||||
 | 
			
		||||
# USAGE
 | 
			
		||||
 | 
			
		||||
## Punctual usage
 | 
			
		||||
 | 
			
		||||
You can parse RSS from a URL with some custom data.  
 | 
			
		||||
An example :
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const easyParser = require('easy-rss-parser');
 | 
			
		||||
const easyParser = require("easy-rss-parser");
 | 
			
		||||
const ListenerRss = easyParser.ListenerRss;
 | 
			
		||||
 | 
			
		||||
let listener = new ListenerRss('my-test-service', 'fake.rss.service');
 | 
			
		||||
let listener = new ListenerRss("my-test-service", "fake.rss.service");
 | 
			
		||||
 | 
			
		||||
// make a request to the adr 'fake.rss.service'
 | 
			
		||||
myListener.fetchRSS().then((obj, err) => {
 | 
			
		||||
    // some act
 | 
			
		||||
  // some act
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Recurrent usage
 | 
			
		||||
 | 
			
		||||
You can parse RSS from a URL each n times.  
 | 
			
		||||
An example :
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const easyParser = require('easy-rss-parser');
 | 
			
		||||
const easyParser = require("easy-rss-parser");
 | 
			
		||||
const ListenerRss = easyParser.ListenerRss;
 | 
			
		||||
 | 
			
		||||
let listener = new ListenerRss('my-test-service', 'fake.rss.service', 5*60);
 | 
			
		||||
let listener = new ListenerRss("my-test-service", "fake.rss.service", 5 * 60);
 | 
			
		||||
 | 
			
		||||
let callback_fun = (obj, err) => {
 | 
			
		||||
        // some act
 | 
			
		||||
    };
 | 
			
		||||
  // some act
 | 
			
		||||
};
 | 
			
		||||
// call callback_fun each 5 minutes
 | 
			
		||||
listener.start(callback_fun);
 | 
			
		||||
 | 
			
		||||
@@ -34,76 +42,109 @@ listener.start(callback_fun);
 | 
			
		||||
 | 
			
		||||
listener.stop();
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
# Documentation
 | 
			
		||||
 | 
			
		||||
## ListenerRSSInfo
 | 
			
		||||
 | 
			
		||||
A class to structure listener's data.
 | 
			
		||||
 | 
			
		||||
### Constructor
 | 
			
		||||
`constructor(name, address, timeloop, customfields)`
 | 
			
		||||
- name : the service name
 | 
			
		||||
- address : the service address
 | 
			
		||||
- [optional] timeloop : time to wait between 2 request in seconds (default 5 minutes)
 | 
			
		||||
- [optional] customfields : to notice field who's custom to the service (default blank) 
 | 
			
		||||
  [cf annexe CustomFields](#customfields)
 | 
			
		||||
## ListenerRSS
 | 
			
		||||
### Constructor
 | 
			
		||||
`constructor(listenerRSSInfo)`
 | 
			
		||||
- listenerRSSInfo : object from the ListenerRSSInfo's class.  
 | 
			
		||||
 | 
			
		||||
`constructor(name, address, timeloop, customfields)`
 | 
			
		||||
 | 
			
		||||
- name : the service name
 | 
			
		||||
- address : the service address
 | 
			
		||||
- [optional] timeloop : time to wait between 2 request in seconds (default 5 minutes)
 | 
			
		||||
- [optional] customfields : to notice field who's custom to the service (default blank)
 | 
			
		||||
  [cf annexe CustomFields](#customfields)
 | 
			
		||||
 | 
			
		||||
## ListenerRSS
 | 
			
		||||
 | 
			
		||||
### Constructor
 | 
			
		||||
 | 
			
		||||
`constructor(listenerRSSInfo)`
 | 
			
		||||
 | 
			
		||||
- listenerRSSInfo : object from the ListenerRSSInfo's class.
 | 
			
		||||
 | 
			
		||||
`constructor(name, address, timeloop, customfields)`
 | 
			
		||||
 | 
			
		||||
- name : the service name
 | 
			
		||||
- address : the service address
 | 
			
		||||
- [optional] timeloop : time to wait between 2 request in seconds (default 5 minutes)
 | 
			
		||||
- [optional] customfields : to notice field who's custom to the service (default blank)
 | 
			
		||||
 | 
			
		||||
### fetchRSS()
 | 
			
		||||
 | 
			
		||||
This function allows to make a request to the rss service.
 | 
			
		||||
 | 
			
		||||
#### Return
 | 
			
		||||
Return a promise object who's resolved like `resolve: (value: result_fetch) => void))` where `result_fetch` is a json 
 | 
			
		||||
 | 
			
		||||
Return a promise object who's resolved like `resolve: (value: result_fetch) => void))` where `result_fetch` is a json
 | 
			
		||||
object who's contain the data. [cf Annexe Output](#output)
 | 
			
		||||
 | 
			
		||||
#### Issues
 | 
			
		||||
 | 
			
		||||
Return an error if the server can't be resolved.
 | 
			
		||||
 | 
			
		||||
### start(callbackFun)
 | 
			
		||||
 | 
			
		||||
This function will execute the callbackFun each time loop.
 | 
			
		||||
 | 
			
		||||
#### Parameter
 | 
			
		||||
 | 
			
		||||
The `callbackFun` is the function who's going to be called each time loop. She need to be under the shape :
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
(obj, err) => {
 | 
			
		||||
  /*...*/
 | 
			
		||||
}
 | 
			
		||||
};
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### stop()
 | 
			
		||||
 | 
			
		||||
This function will stop the execution of the callbackFun each time loop.
 | 
			
		||||
 | 
			
		||||
# Annexe
 | 
			
		||||
 | 
			
		||||
## CustomFields
 | 
			
		||||
 | 
			
		||||
This parameter permit to specify some custom fields who's present in the service but not in the RFC.
 | 
			
		||||
For example the YouTube RSS api give some data into the `<media:group>` field. So you can give this info with this :
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
[
 | 
			
		||||
    ['media:group', 'media:group'] 
 | 
			
		||||
]
 | 
			
		||||
[["media:group", "media:group"]];
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
You can also rename the field with the left part :
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
[
 | 
			
		||||
    ['my_custom_media_group_name', 'media:group']
 | 
			
		||||
]
 | 
			
		||||
[["my_custom_media_group_name", "media:group"]];
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
In adition you can rename child element into custom field like this :
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
[
 | 
			
		||||
    ['media:group', 'media:group'],
 | 
			
		||||
    ['description', ['media:group', 'media:description']],
 | 
			
		||||
    ['icon', ['media:group', 'media:thumbnail']]
 | 
			
		||||
]
 | 
			
		||||
  ["media:group", "media:group"],
 | 
			
		||||
  ["description", ["media:group", "media:description"]],
 | 
			
		||||
  ["icon", ["media:group", "media:thumbnail"]],
 | 
			
		||||
];
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
In this case it's useless to specify the parent field, so you can just omit the first line :
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
[
 | 
			
		||||
    ['description', ['media:group', 'media:description']],
 | 
			
		||||
    ['icon', ['media:group', 'media:thumbnail']]
 | 
			
		||||
]
 | 
			
		||||
  ["description", ["media:group", "media:description"]],
 | 
			
		||||
  ["icon", ["media:group", "media:thumbnail"]],
 | 
			
		||||
];
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Output
 | 
			
		||||
 | 
			
		||||
Here an example of what type of json object is output during a fetch :
 | 
			
		||||
 | 
			
		||||
```json
 | 
			
		||||
feedUrl: 'fake.rrs.service'
 | 
			
		||||
title: 'myFakeApiTitle'
 | 
			
		||||
@@ -122,4 +163,4 @@ items:
 | 
			
		||||
            - npm
 | 
			
		||||
            - fakeInfos
 | 
			
		||||
        isoDate: '2015-11-12T21:16:39.000Z'
 | 
			
		||||
```
 | 
			
		||||
```
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2918
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										2918
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										47
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "listener-rss",
 | 
			
		||||
  "version": "1.0.0",
 | 
			
		||||
  "description": "A lightweight library to give some additions for the [rss-parser package](https://github.com/rbren/rss-parser).",
 | 
			
		||||
  "main": "index.js",
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "test": "mocha --require ts-node/register ./tests/**/*-spec.ts"
 | 
			
		||||
  },
 | 
			
		||||
  "repository": {
 | 
			
		||||
    "type": "git",
 | 
			
		||||
    "url": "gitea@zeteo.me:Outils-PeerTube/listener-rss.git"
 | 
			
		||||
  },
 | 
			
		||||
  "keywords": [
 | 
			
		||||
    "rss",
 | 
			
		||||
    "rss-parser"
 | 
			
		||||
  ],
 | 
			
		||||
  "author": "Amaury Joly <amaury.joly@hotmail.com>",
 | 
			
		||||
  "contributors": [
 | 
			
		||||
    "Florent Fayolle <florent.git@zeteo.me>"
 | 
			
		||||
  ],
 | 
			
		||||
  "license": "MIT",
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@types/chai": "^4.2.14",
 | 
			
		||||
    "@types/mocha": "^8.2.0",
 | 
			
		||||
    "@types/node": "^14.14.25",
 | 
			
		||||
    "@typescript-eslint/eslint-plugin": "^4.14.2",
 | 
			
		||||
    "@typescript-eslint/parser": "^4.14.2",
 | 
			
		||||
    "chai": "4.3.0",
 | 
			
		||||
    "eslint": "^7.19.0",
 | 
			
		||||
    "eslint-config-airbnb-base": "^14.2.1",
 | 
			
		||||
    "eslint-config-prettier": "7.2.0",
 | 
			
		||||
    "eslint-plugin-import": "^2.22.1",
 | 
			
		||||
    "eslint-plugin-mocha": "8.0.0",
 | 
			
		||||
    "eslint-plugin-prettier": "3.3.1",
 | 
			
		||||
    "mocha": "8.2.1",
 | 
			
		||||
    "prettier": "2.2.1",
 | 
			
		||||
    "proxyquire": "2.1.3",
 | 
			
		||||
    "sinon": "9.2.4",
 | 
			
		||||
    "sinon-chai": "3.5.0",
 | 
			
		||||
    "ts-node": "9.1.1",
 | 
			
		||||
    "tsc-watch": "^4.2.9",
 | 
			
		||||
    "typescript": "^4.1.3"
 | 
			
		||||
  },
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "rss-parser": "3.11.0"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										85
									
								
								src/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								src/index.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,85 @@
 | 
			
		||||
import Parser from "rss-parser";
 | 
			
		||||
 | 
			
		||||
const DEFAULT_TIMELOOP = 5 * 60; // default timeloop is 5 min
 | 
			
		||||
 | 
			
		||||
class ListenerRss {
 | 
			
		||||
  name = "";
 | 
			
		||||
  address = "";
 | 
			
		||||
  timeloop = DEFAULT_TIMELOOP; // time in seconds
 | 
			
		||||
  customfields = [];
 | 
			
		||||
 | 
			
		||||
  // private fields
 | 
			
		||||
  parser: Parser;
 | 
			
		||||
  loopRunning = false;
 | 
			
		||||
 | 
			
		||||
  constructor(
 | 
			
		||||
    name: String,
 | 
			
		||||
    address: String,
 | 
			
		||||
    timeloop: number,
 | 
			
		||||
    customfields: String[][]
 | 
			
		||||
  ) {
 | 
			
		||||
    this.parser = new Parser();
 | 
			
		||||
    // if (name !== undefined && name instanceof ListenerInfo) {
 | 
			
		||||
    //   // constructor with 1 arg
 | 
			
		||||
    //   this.setData({name});
 | 
			
		||||
    // } else if (address !== undefined && typeof address === "string") {
 | 
			
		||||
    //   // construct with between 2 and 4 args
 | 
			
		||||
    //   this.setData(new ListenerInfo(name, address, timeloop, customfields));
 | 
			
		||||
    // } else throw new Error("the constructor must have args");
 | 
			
		||||
    // this.setParser();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // setParser() {
 | 
			
		||||
  //   // set parser
 | 
			
		||||
  //   this.parser = new Parser(
 | 
			
		||||
  //     this.customfields !== undefined
 | 
			
		||||
  //       ? {
 | 
			
		||||
  //         customFields: {
 | 
			
		||||
  //           item: this.customfields.map((elt) => {
 | 
			
		||||
  //             return Array.isArray(elt[1]) ? elt[1][0] : elt[1];
 | 
			
		||||
  //           }),
 | 
			
		||||
  //         },
 | 
			
		||||
  //       }
 | 
			
		||||
  //       : {}
 | 
			
		||||
  //   ); // if customfield is set -> let's set the parser with, else let the option empty
 | 
			
		||||
  // }
 | 
			
		||||
 | 
			
		||||
  // setData({name: String, address: String, timeloop: number = DEFAULT_TIMELOOP}) {
 | 
			
		||||
  //   // Set data
 | 
			
		||||
  //   this.name = name;
 | 
			
		||||
  //   this.address = address;
 | 
			
		||||
  //   this.timeloop =
 | 
			
		||||
  //     this.timeloop === undefined ? DEFAULT_TIMELOOP : infos._timeloop;
 | 
			
		||||
  //   this.customfields = infos._customfields === undefined ? [] : infos._customfields;
 | 
			
		||||
  // }
 | 
			
		||||
 | 
			
		||||
  // fetchRSS() {
 | 
			
		||||
  //   return this.parser.parseURL(this.address).catch((err) => {
 | 
			
		||||
  //     throw new Error("bad address or no access : " + err);
 | 
			
		||||
  //   });
 | 
			
		||||
  // }
 | 
			
		||||
 | 
			
		||||
  // /**
 | 
			
		||||
  //  * @brief call the callback function each looptime
 | 
			
		||||
  //  * @param callback function who's going to be called with the latest get
 | 
			
		||||
  //  */
 | 
			
		||||
  // start(callback) {
 | 
			
		||||
  //   this.loopRunning = true;
 | 
			
		||||
 | 
			
		||||
  //   (async () => {
 | 
			
		||||
  //     while (this.loopRunning === true) {
 | 
			
		||||
  //       this.fetchRSS().then((obj, err) => callback(obj, err));
 | 
			
		||||
  //       await new Promise((res) => setTimeout(res, 2000));
 | 
			
		||||
  //     }
 | 
			
		||||
  //   })();
 | 
			
		||||
  // }
 | 
			
		||||
 | 
			
		||||
  // /**
 | 
			
		||||
  //  * @brief stop the async function
 | 
			
		||||
  //  */
 | 
			
		||||
  // stop() {
 | 
			
		||||
  //   this.loopRunning = false;
 | 
			
		||||
  // }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = ListenerRss;
 | 
			
		||||
							
								
								
									
										9
									
								
								tests/index-spec.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								tests/index-spec.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
const { expect } = require("chai");
 | 
			
		||||
 | 
			
		||||
describe("Calculator", function () {
 | 
			
		||||
  describe("Add", function () {
 | 
			
		||||
    it("Should return 3 when a = 1 and b = 2", () => {
 | 
			
		||||
      expect(2 + 1).to.equal(3);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										17
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
{
 | 
			
		||||
  "compilerOptions": {
 | 
			
		||||
    "target": "es2018",
 | 
			
		||||
    "module": "es2015",
 | 
			
		||||
    "lib": ["es6"],
 | 
			
		||||
    "allowJs": true,
 | 
			
		||||
    "outDir": "build",
 | 
			
		||||
    "rootDir": "src",
 | 
			
		||||
    "strict": true,
 | 
			
		||||
    "moduleResolution": "node",
 | 
			
		||||
    "noImplicitAny": true,
 | 
			
		||||
    "esModuleInterop": true,
 | 
			
		||||
    "resolveJsonModule": false,
 | 
			
		||||
    "skipLibCheck": true,
 | 
			
		||||
    "forceConsistentCasingInFileNames": true
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user