Socket
Socket
Sign inDemoInstall

4chan-full

Package Overview
Dependencies
139
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.0.7 to 1.0.8

22

getArchive.js

@@ -6,15 +6,15 @@ let { JSDOM } = require("jsdom");

function parseBody(siteBodyHTML="") {
function parseBody(siteBodyHTML = "") {
let dom = new JSDOM(siteBodyHTML);
let document = dom.window.document;
let doc = dom.window.document;
let trs = Array.from(document.querySelectorAll("#arc-list tr"));
let trs = Array.from(doc.querySelectorAll("#arc-list tr"));
trs.shift();
let board = boardTitleToBoardNameInfo(document.querySelector(".boardTitle").textContent);
let board = boardTitleToBoardNameInfo(doc.querySelector(".boardTitle").textContent);
let result = {
board,
threads: trs.map(e=>{
threads: trs.map(e => {
let id = parseInt(e.cells[0].textContent);

@@ -24,3 +24,3 @@ return {

teaser: e.cells[1].textContent,
thread(dataPipe="") {
thread(dataPipe = "") {
return getThread(board.name, id, dataPipe);

@@ -38,9 +38,13 @@ }

async function getBody(board="", dataPipe="") {
async function getBody(board = "", dataPipe = "") {
let archiveURL = `https://boards.4channel.org/${board}/archive`;
let bodyHTML = await got.get(dataPipe+archiveURL, {resolveBodyOnly: true});
let bodyHTML = await got.get(dataPipe + archiveURL, { resolveBodyOnly: true });
return bodyHTML;
}
async function getArchive(board="", dataPipe="") {
/**
* @param {String} board Board code
* @param {String} dataPipe DataPipe url
*/
async function getArchive(board = "", dataPipe = "") {
let bodyHTML = await getBody(board, dataPipe);

@@ -47,0 +51,0 @@ let parsedBody = parseBody(bodyHTML);

let { JSDOM } = require("jsdom");
let got = require("got").default;
let { fileTextToSizeInfo, boardTitleToBoardNameInfo } = require("./utils");
let { fileTextToSizeInfo, boardTitleToBoardNameInfo, fileElementToFileObject, parsePostMessage } = require("./utils");
let getThread = require("./getThread");
let getArchive = require("./getArchive");
function parseBody(siteBodyHTML="") {
function parseBody(siteBodyHTML = "") {
let dom = new JSDOM(siteBodyHTML);
let document = dom.window.document;
let doc = dom.window.document;
let board = boardTitleToBoardNameInfo(document.querySelector(".boardTitle").textContent);
let board = boardTitleToBoardNameInfo(doc.querySelector(".boardTitle").textContent);
let result = {
let result = {
board,
threads: Array.from(document.querySelectorAll(".thread")).map(e=>{
let id = parseInt(e.id.replace(/[^0-9]/g,""));
threads: Array.from(doc.querySelectorAll(".thread")).map(e => {
let id = parseInt(e.id.replace(/[^0-9]/g, ""));
return {
id,
thread(dataPipe="") {
thread(dataPipe = "") {
return getThread(board.name, id, dataPipe);
},
subject: e.querySelector(".op .desktop .subject").textContent,
message: e.querySelector(".postMessage") ? e.querySelector(".postMessage").textContent.replace(/(>>\d+)/gm, " [$1] ") : "",
message: e.querySelector(".postMessage") ? parsePostMessage(e.querySelector(".postMessage").textContent) : "",
date: parseInt(e.querySelector(".dateTime").getAttribute("data-utc")),
file: e.querySelector(".file") ? {
exists: true,
url: "https:"+e.querySelector(".fileText a").getAttribute("href"),
name: e.querySelector(".fileText a").title ? e.querySelector(".fileText a").title : e.querySelector(".fileText a").textContent,
size: fileTextToSizeInfo(e.querySelector(".fileText").textContent)
} : {exists: false}
file: fileElementToFileObject(e.querySelector(".file"))
}
}),
page: parseInt(document.querySelector(".pages strong").textContent),
hasNextPage: Boolean(document.querySelector(".next .pageSwitcherForm"))
page: parseInt(doc.querySelector(".pages strong").textContent),
hasNextPage: Boolean(doc.querySelector(".next .pageSwitcherForm")),
archive(dataPipe = "") {
return getArchive(board.code, dataPipe);
}
}

@@ -42,5 +41,5 @@

async function getBody(board="", page=1, dataPipe="") {
async function getBody(board = "", page = 1, dataPipe = "") {
let threadURL = `https://boards.4channel.org/${board}/${page <= 1 ? "" : page}`;
let bodyHTML = await got.get(dataPipe+threadURL, {resolveBodyOnly: true});
let bodyHTML = await got.get(dataPipe + threadURL, { resolveBodyOnly: true });
return bodyHTML;

@@ -50,8 +49,7 @@ }

/**
*
* @param {String} board
* @param {Number} page
* @param {String} dataPipe
* @param {String} board Board code
* @param {Number} page Page number
* @param {String} dataPipe DataPipe url
*/
async function getBoard(board="", page=1, dataPipe="") {
async function getBoard(board = "", page = 1, dataPipe = "") {
let bodyHTML = await getBody(board, page, dataPipe);

@@ -58,0 +56,0 @@ let bodyJSON = parseBody(bodyHTML);

@@ -1,4 +0,4 @@

let {JSDOM} = require("jsdom");
let { JSDOM } = require("jsdom");
let got = require("got").default;
let {convertSafetyType} = require("./utils");
let { convertSafetyType } = require("./utils");
let getThread = require("./getThread");

@@ -13,5 +13,5 @@

let dom = new JSDOM(siteBodyHTML);
let document = dom.window.document;
let doc = dom.window.document;
let result = Array.from(document.querySelectorAll(".c-thread")).map(e => {
let result = Array.from(doc.querySelectorAll(".c-thread")).map(e => {
let id = parseInt(e.querySelector("a").getAttribute("href").split("/")[5]);

@@ -25,3 +25,3 @@ let boardName = e.querySelector(".c-board").textContent;

id,
thread(dataPipe="") {
thread(dataPipe = "") {
return getThread(boardName, id, dataPipe);

@@ -55,3 +55,4 @@ },

/**
* @param {SafetyType} type
* @param {SafetyType} type Safety Type
* @param {String} dataPipe DataPipe URL
*/

@@ -58,0 +59,0 @@ async function getPopularThreads(type = "WORKSAFE", dataPipe = "") {

@@ -5,11 +5,11 @@ let { JSDOM } = require("jsdom");

function parseBody(siteBodyHTML="") {
function parseBody(siteBodyHTML = "") {
let dom = new JSDOM(siteBodyHTML);
let document = dom.window.document;
let doc = dom.window.document;
let statsArray = Array.from(document.querySelectorAll("#site-stats .stat-cell")).map(i=>i.childNodes[1].textContent.trim());
let statsArray = Array.from(doc.querySelectorAll("#site-stats .stat-cell")).map(i => i.childNodes[1].textContent.trim());
let result = {
totalPosts: parseInt(statsArray[0].replace(/\,/g,"")),
currentUsers: parseInt(statsArray[1].replace(/\,/g,"")),
totalPosts: parseInt(statsArray[0].replace(/\,/g, "")),
currentUsers: parseInt(statsArray[1].replace(/\,/g, "")),
activeContent: reverseFormatFileSizeKB(statsArray[2])

@@ -25,8 +25,11 @@ };

async function getBody(dataPipe="") {
let bodyHTML = await got.get(dataPipe+"https://www.4chan.org/", {resolveBodyOnly: true});
async function getBody(dataPipe = "") {
let bodyHTML = await got.get(dataPipe + "https://www.4chan.org/", { resolveBodyOnly: true });
return bodyHTML;
}
async function getStats(dataPipe="") {
/**
* @param {String} dataPipe DataPipe URL
*/
async function getStats(dataPipe = "") {
let bodyHTML = await getBody(dataPipe);

@@ -33,0 +36,0 @@ let parsedBody = parseBody(bodyHTML);

let { JSDOM } = require("jsdom");
let got = require("got").default;
let { fileTextToSizeInfo, boardTitleToBoardNameInfo } = require("./utils");
let { fileTextToSizeInfo, boardTitleToBoardNameInfo, fileElementToFileObject, parsePostMessage } = require("./utils");
function parseBody(siteBodyHTML="") {
function parseBody(siteBodyHTML = "") {
let dom = new JSDOM(siteBodyHTML);
let document = dom.window.document;
let doc = dom.window.document;
let result = {
subject: document.querySelector(".subject").textContent,
board: boardTitleToBoardNameInfo(document.querySelector(".boardTitle").textContent),
posts: Array.from(document.querySelectorAll(".postContainer")).map(e => {
subject: doc.querySelector(".subject").textContent,
board: boardTitleToBoardNameInfo(doc.querySelector(".boardTitle").textContent),
posts: Array.from(doc.querySelectorAll(".postContainer")).map(e => {
let fileSizeInfo = [];

@@ -17,13 +17,8 @@ if (e.querySelector(".file")) fileSizeInfo = fileTextToSizeInfo(e.querySelector(".fileText").textContent);

id: parseInt(e.id.replace(/[^0-9]/g, "")),
message: e.querySelector(".postMessage") ? e.querySelector(".postMessage").textContent.replace(/(>>\d+)/gm, " [$1] ") : "",
file: e.querySelector(".file") ? {
name: e.querySelector(".fileText a").getAttribute("title") ? e.querySelector(".fileText a").getAttribute("title") : e.querySelector(".fileText a").textContent,
url: "https:" + e.querySelector(".fileText a").getAttribute("href"),
exists: true,
size: fileTextToSizeInfo(e.querySelector(".fileText").textContent)
} : { exists: false },
message: e.querySelector(".postMessage") ? parsePostMessage(e.querySelector(".postMessage").textContent) : "",
file: fileElementToFileObject(e.querySelector(".file")),
date: parseInt(e.querySelector(".dateTime").getAttribute("data-utc"))
}
}),
isArchived: Boolean(document.querySelector(".closed"))
isArchived: Boolean(doc.querySelector(".closed"))
};

@@ -36,9 +31,14 @@

async function getBody(board="", threadId=0, dataPipe="") {
async function getBody(board = "", threadId = 0, dataPipe = "") {
let threadURL = `https://boards.4channel.org/${board}/thread/${threadId}`;
let bodyHTML = await got.get(dataPipe+threadURL, {resolveBodyOnly: true});
let bodyHTML = await got.get(dataPipe + threadURL, { resolveBodyOnly: true });
return bodyHTML;
}
async function getThread(board="", threadId=0, dataPipe="") {
/**
* @param {String} board Board code
* @param {Number} threadId Thread id
* @param {String} dataPipe DataPipe URL
*/
async function getThread(board = "", threadId = 0, dataPipe = "") {
let bodyHTML = await getBody(board, threadId, dataPipe);

@@ -45,0 +45,0 @@ let bodyJSON = parseBody(bodyHTML);

@@ -6,2 +6,3 @@ let getBoard = require("./getBoard");

let boards = require("./_boards.min");
let utils = require("./utils");

@@ -13,5 +14,6 @@ let FCHF = {

getArchive,
boards
boards,
utils
}
module.exports = FCHF;
{
"name": "4chan-full",
"version": "1.0.7",
"description": "www.4chan.org non-official read only api",
"main": "index.js",
"_from": "4chan-full",
"_id": "4chan-full@1.0.72",
"_inBundle": false,
"_integrity": "sha512-pwIjr/EC5gI28qjaxXyMHqI/qVoQuJc2wp8vM9lRrdtAG1waEJTRkclz0U9Cg374tOq/1F1oEUDCCnpazM51sw==",
"_location": "/4chan-full",
"_phantomChildren": {},
"_requested": {
"type": "tag",
"registry": true,
"raw": "4chan-full",
"name": "4chan-full",
"escapedName": "4chan-full",
"rawSpec": "",
"saveSpec": null,
"fetchSpec": "latest"
},
"_requiredBy": [
"#USER",
"/"
],
"_resolved": "https://registry.npmjs.org/4chan-full/-/4chan-full-1.0.72.tgz",
"_shasum": "0e3267f40a1af1fb47595a5e1556bccf47abfc6f",
"_spec": "4chan-full",
"_where": "D:\\BDT\\Desktop\\Projelerim\\JavaScript\\4chan-full",
"author": {
"name": "Kıraç Armağan Önal"
},
"bugs": {
"url": "https://github.com/Armagann/4chan-full/issues"
},
"bundleDependencies": false,
"dependencies": {

@@ -10,6 +37,6 @@ "got": "^11.4.0",

},
"deprecated": false,
"description": "www.4chan.org non-official read only api",
"devDependencies": {},
"scripts": {
"test": "node test.js"
},
"homepage": "https://github.com/Armagann/4chan-full#readme",
"keywords": [

@@ -23,4 +50,5 @@ "4chan",

],
"author": "Kıraç Armağan Önal",
"license": "Apache-2.0",
"main": "index.js",
"name": "4chan-full",
"repository": {

@@ -30,6 +58,6 @@ "type": "git",

},
"bugs": {
"url": "https://github.com/Armagann/4chan-full/issues"
"scripts": {
"test": "node test.js"
},
"homepage": "https://github.com/Armagann/4chan-full#readme"
"version": "1.0.8"
}
> # 4CHAN-FULL 🎉
>
> www.4chan.org non-official read only api.

@@ -7,2 +8,3 @@

## Installation
```diff

@@ -15,2 +17,3 @@ npm install 4chan-full

### Possibilities
- [Get Thread](https://example.com/ "Example Result") (`.getThread(boardCode, threadId)`)

@@ -26,2 +29,3 @@ - [Get Board](https://example.com/ "Example Result") (`.getBoard(boardCode, page)`)

### Example `Basic Thread Files Downloader Example`
```js

@@ -36,39 +40,65 @@ // To be honest there is no good examples to use. :D

// | | |
FCHF.getThread("w","2148861", "https://kao-datapipe-2.herokuapp.com/").then(thread=>{
console.log("subject", thread.subject)
console.log("isArchived", thread.isArchived)
thread.posts.forEach((post, index)=>{
console.log(index, "", post.message)
if (post.file.exists) {
// Size in KB
console.log(post.file.url, post.file.name, post.file.size.size, post.file.size.width, post.file.size.height);
setTimeout(()=>{
download("https://kao-datapipe-1.herokuapp.com/"+post.file.url, "wallpapers", {
filename: post.file.name
})
}, (index*(Math.random()*1000))+1)
}
FCHF.getThread("w", "2148861", "https://kao-datapipe-2.herokuapp.com/").then(
(thread) => {
console.log("subject", thread.subject);
console.log("isArchived", thread.isArchived);
thread.posts.forEach((post, index) => {
console.log(index, "", post.message);
if (post.file.exists) {
console.log(
post.file.url,
post.file.name,
// Size in KB
post.file.size.size,
post.file.size.width,
post.file.size.height
);
setTimeout(() => {
download(
"https://kao-datapipe-1.herokuapp.com/" + post.file.url,
"wallpapers",
{
filename: post.file.name,
}
);
}, index * (Math.random() * 1000) + 1);
}
});
});
}
);
```
---
---
### Update 1.0.6
### Update 1.0.8
You can get thread directly from getBoard response or getPopularThreads response. **Example:**
- Thread's `message` property is changed is no longer a string its a Object that object contains full raw message and quotes of the message if exists. The new message format:
```js
FCHF.getBoard().then(async board=>{
let firstThread = await board.threads[0].thread();
console.log(firstThread);
})
{
content: "hey bro! >>46831",
quotes: [
{
id: "46831",
index: 9
}
]
}
```
### Update 1.0.7
- In file object changed property `exists` to `isExists`
- Added file object to `isSpoiler` property
- Now you can get board's archive directly form getBoard
### Update 1.0.6
You can get thread directly from getBoard response or getPopularThreads response. **Example:**
```js
FCHF.getBoard().then(async (board) => {
let firstThread = await board.threads[0].thread();
console.log(firstThread);
});
```
let FCHF = require("./index");
FCHF.getBoard("w",1,"https://kao-datapipe-2.herokuapp.com/").then(async data=>{
let thread = await data.threads[0].thread("https://kao-datapipe-1.herokuapp.com/");
console.log(thread.posts);
// FCHF.getBoard("jp",1,"https://kao-datapipe-2.herokuapp.com/").then(async data=>{
// let thread = await data.threads[0].thread("https://kao-datapipe-1.herokuapp.com/");
// console.log(thread)
// })
FCHF.getThread("jp",26175111,"https://kao-datapipe-2.herokuapp.com/").then(thread=>{
console.log(thread.posts.map(f=>f.file))
})
let safetyKeyValues = [{
keys: ["ws", "WORKSAFE", 0],
value: "ws"
},
{
keys: ["nws", "nsfw", "NOTSAFE", "NOTWORKSAFE", 1],
value: "nws"
},
{
keys: ["all", "ALL", "COMBINED", 2],
value: "all"
}
keys: ["ws", "WORKSAFE", 0],
value: "ws"
},
{
keys: ["nws", "nsfw", "NOTSAFE", "NOTWORKSAFE", 1],
value: "nws"
},
{
keys: ["all", "ALL", "COMBINED", 2],
value: "all"
}
];

@@ -25,6 +25,7 @@

let based = safetyKeyValues.find(i => i.keys.some(i => i == type));
if (!based) throw new Error(`Invalid safety type. (Only possible: ${safetyKeyValues.map(i=>i.keys).join(", ")})`);
if (!based) throw new Error(`Invalid safety type. (Only possible: ${safetyKeyValues.map(i => i.keys).join(", ")})`);
return based.value;
}
/** @returns {{code: string, name: string}} */
function boardTitleToBoardNameInfo(boardTitle = "") {

@@ -38,3 +39,4 @@ let boardTitleSplitted = boardTitle.split("-").map(i => i.trim());

function reverseFormatFileSizeKB(fileSizeText="0 GB") {
/** @returns {number} */
function reverseFormatFileSizeKB(fileSizeText = "0 GB") {
let splitted = fileSizeText.split(" ");

@@ -60,2 +62,3 @@ let factor = NaN;

/** @returns {{size: string, width: number, height: number}} */
function fileTextToSizeInfo(ft = "") {

@@ -72,2 +75,24 @@ let info = ft.slice(ft.lastIndexOf("(") + 1, ft.lastIndexOf(")")).split(", ");

/** @returns {{name?:string,url?:string,isExists:boolean,size:{size: string, width: number, height: number}, isSpoiler: boolean}} */
function fileElementToFileObject(e) {
if (!e) return { isExists: false };
let isSpoiler = Boolean(e.querySelector(".imgspoiler"));
return {
name: isSpoiler ? e.querySelector(".fileText").getAttribute("title") : (e.querySelector(".fileText a").getAttribute("title") ? e.querySelector(".fileText a").getAttribute("title") : e.querySelector(".fileText a").textContent),
url: "https:" + e.querySelector(".fileText a").getAttribute("href"),
isExists: true,
size: fileTextToSizeInfo(e.querySelector(".fileText").textContent),
isSpoiler
}
}
/** @returns {{content: string, quotes: Array<{id: string, index: number}>}} */
function parsePostMessage(t = "") {
let matches = Array.from(t.matchAll(/>>(\d+)/gmi));
return {
content: t,
quotes: matches.map(i => ({ id: i[0], index: i.index }))
}
}
let utils = {

@@ -77,5 +102,7 @@ fileTextToSizeInfo,

convertSafetyType,
reverseFormatFileSizeKB
reverseFormatFileSizeKB,
fileElementToFileObject,
parsePostMessage
}
module.exports = utils;
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc