This commit is contained in:
2025-05-21 04:18:42 +03:30
commit d5aff06ada
18 changed files with 4718 additions and 0 deletions

16
plugins/README.md Normal file
View File

@@ -0,0 +1,16 @@
# Plugins Folder
Plugins define behavior that is common to all the routes in your
application. Authentication, caching, templates, and all the other cross
cutting concerns should be handled by plugins placed in this folder.
Files in this folder are typically defined through the
[`fastify-plugin`](https://github.com/fastify/fastify-plugin) module,
making them non-encapsulated. They can define decorators and set hooks
that will then be used in the rest of your application.
Check out:
* [The hitchhiker's guide to plugins](https://fastify.dev/docs/latest/Guides/Plugins-Guide/)
* [Fastify decorators](https://fastify.dev/docs/latest/Reference/Decorators/).
* [Fastify lifecycle](https://fastify.dev/docs/latest/Reference/Lifecycle/).

96
plugins/corn.js Normal file
View File

@@ -0,0 +1,96 @@
'use strict'
const fp = require('fastify-plugin')
const fastifyCron = require('fastify-cron')
const cheerio = require('cheerio');
const { log } = require('console');
const fs = require('fs');
const axios = require('axios');
const akharin = 'https://akharinkhodro.ir/price/%D9%82%DB%8C%D9%85%D8%AA-%D8%AE%D9%88%D8%AF%D8%B1%D9%88/';
const hamrah = 'https://www.hamrah-mechanic.com/carprice/';
module.exports = fp(async function (fastify, opts) {
fastify.register(fastifyCron, {
jobs: [
{
cronTime: '0 0 0 * * *', ///'*/5 * * * * *'
onTick: async () => {
fastify.log.info('⏰ Cron Job ran at ' + new Date().toISOString())
try {
const { data } = await axios.get(akharin, {
headers: { 'User-Agent': 'Mozilla/5.0' },
});
const $ = cheerio.load(data);
const cars = [];
let td = $('tr')
let result = []
td.each((i, tr) => {
let listOfLine = $(tr).text().trim().split('\n')
if (listOfLine.length > 1) {
if (listOfLine[0] !== "نام خودرو") {
result.push({
carName: listOfLine[0],
marketPrice: listOfLine[1].trim().split(" ")[0] === "بدون" ? null : listOfLine[1].trim().split(" ")[0],
newCarPrice: listOfLine[2].trim().split(" ")[0]
})
}
}
})
fs.writeFileSync(`./json/akharin/${new Date().getFullYear()}-${new Date().getMonth()}-${new Date().getDay()}-akharin-cars.json`, JSON.stringify(result, null, 2), 'utf-8');
console.log(`${new Date().getFullYear()}-$${new Date().getMonth()}-${new Date().getDay()}-akharin-cars.json => new:`, cars.length);
} catch (err) {
console.error('crawler stop:', err.message);
} },
start: true
},{
cronTime: '0 0 0 * * *', ///'*/5 * * * * *'
onTick: async () => {
fastify.log.info('⏰ Cron Job ran at hamrah ' + new Date().toISOString())
try {
const { data } = await axios.get(hamrah, {
headers: { 'User-Agent': 'Mozilla/5.0' },
});
const $ = cheerio.load(data);
const cars = [];
const result = []
let sectionName = $('div.carsBrandPriceList_brand__name__Ohntn')
let tables = $('tbody tr');
tables.each((i, tr) => {
const tds = $(tr).find('td');
const modelDivs = $(tds[0]).find('div');
const priceDivs = $(tds[1]).find('div');
const carName = $(modelDivs[0]).text().trim(); // مدل اصلی مثل Q5 E-tron
const typeAndYear = $(modelDivs[1]).text().replace(/\s+/g, ' ').trim(); // تیپ 40- فول-2024
const marketPrice = $(priceDivs[0]).text().trim(); // قیمت
result.push({carName , typeAndYear , marketPrice})
});
// ذخیره‌سازی در فایل JSON
fs.writeFileSync(`./json/hamrah/${new Date().getFullYear()}-${new Date().getMonth()}-${new Date().getDay()}-hamrah-cars.json`, JSON.stringify(result, null, 2), 'utf-8');
console.log(`${new Date().getFullYear()}-$${new Date().getMonth()}-${new Date().getDay()}-akharin-cars.json => new:`, cars.length);
} catch (err) {
console.error('❌ خطا در کراول:', err.message);
} },
start: true
}
]
})
})

14
plugins/sensible.js Normal file
View File

@@ -0,0 +1,14 @@
'use strict'
const fp = require('fastify-plugin')
/**
* This plugins adds some utilities to handle http errors
*
* @see https://github.com/fastify/fastify-sensible
*/
module.exports = fp(async function (fastify, opts) {
fastify.register(require('@fastify/sensible'), {
errorHandler: false
})
})

12
plugins/support.js Normal file
View File

@@ -0,0 +1,12 @@
'use strict'
const fp = require('fastify-plugin')
// the use of fastify-plugin is required to be able
// to export the decorators to the outer scope
module.exports = fp(async function (fastify, opts) {
fastify.decorate('someSupport', function () {
return 'hugs'
})
})