Compare commits

...

3 Commits

Author SHA1 Message Date
weakmap@gmail.com
5cceae11cc upgrading dependencies | adding sqlite for later analysis 2024-11-01 17:03:43 +01:00
weakmap@gmail.com
a4c5bfcbf7 fixing tests 2024-10-03 16:09:19 +02:00
weakmap@gmail.com
6d2ab5f958 making sure immowelt does not include suggested ranges 2024-10-03 16:03:47 +02:00
7 changed files with 915 additions and 1308 deletions

View File

@@ -0,0 +1,25 @@
import { markdown2Html } from '../../services/markdown.js';
import Database from 'better-sqlite3';
export const send = ({ serviceName, newListings, jobKey }) => {
const db = new Database('db/listings.db');
const fields = ['serviceName', 'jobKey', 'id', 'size', 'rooms', 'price', 'address', 'title', 'link', 'description'];
db.prepare(`CREATE TABLE IF NOT EXISTS listing (${fields.join(' TEXT, ')} TEXT);`).run();
const insert = db.prepare(`INSERT INTO listing (${fields.join(', ')}) VALUES (@${fields.join(', @')})`);
newListings.map((listing) => {
let insertListing = {};
fields.map((field) => {
insertListing[field] = listing[field];
});
insertListing.serviceName = serviceName;
insertListing.jobKey = jobKey;
insert.run(insertListing);
});
return Promise.resolve();
};
export const config = {
id: 'sqlite',
name: 'Sqlite',
description: 'This adapter stores listings in a local sqlite3 database.',
config: {},
readme: markdown2Html('lib/notification/adapter/sqlite.md'),
};

View File

@@ -0,0 +1,7 @@
### Sqlite Adapter
This adapter stores search results in a sqlite database located in db/listings.db. This file can be used for further analysis later on.
Fields are:
```
['serviceName', 'jobKey', 'id', 'size', 'rooms', 'price', 'address', 'title', 'link', 'description']
```

View File

@@ -1,42 +1,43 @@
import utils, {buildHash} from '../utils.js'; import utils, { buildHash } from '../utils.js';
let appliedBlackList = []; let appliedBlackList = [];
function normalize(o) { function normalize(o) {
const id = buildHash(o.id, o.price); const id = buildHash(o.id, o.price);
return Object.assign(o, {id}); return Object.assign(o, { id });
} }
function applyBlacklist(o) { function applyBlacklist(o) {
const titleNotBlacklisted = !utils.isOneOf(o.title, appliedBlackList); const titleNotBlacklisted = !utils.isOneOf(o.title, appliedBlackList);
const descNotBlacklisted = !utils.isOneOf(o.description, appliedBlackList); const descNotBlacklisted = !utils.isOneOf(o.description, appliedBlackList);
return titleNotBlacklisted && descNotBlacklisted; return titleNotBlacklisted && descNotBlacklisted;
} }
const config = { const config = {
url: null, url: null,
crawlContainer: 'div[data-testid="serp-card-testid"]', crawlContainer:
sortByDateParam: 'sd=DESC&sf=TIMESTAMP', 'div[data-testid="serp-card-testid"]:not(div[data-testid="serp-enlargementlist-testid"] div[data-testid="serp-card-testid"])',
crawlFields: { sortByDateParam: 'order=DateDesc',
id: 'a@id', crawlFields: {
price: 'div[data-testid="cardmfe-price-testid"] | removeNewline | trim', id: 'a@id',
size: 'div[data-testid="cardmfe-keyfacts-testid"] | removeNewline | trim', price: 'div[data-testid="cardmfe-price-testid"] | removeNewline | trim',
title: '.css-1cbj9xw', size: 'div[data-testid="cardmfe-keyfacts-testid"] | removeNewline | trim',
link: 'a@href', title: '.css-1cbj9xw',
address: 'div[data-testid="cardmfe-description-box-address"] | removeNewline | trim', link: 'a@href',
}, address: 'div[data-testid="cardmfe-description-box-address"] | removeNewline | trim',
paginate: '#pnlPaging #nlbPlus@href', },
normalize: normalize, paginate: '#pnlPaging #nlbPlus@href',
filter: applyBlacklist, normalize: normalize,
filter: applyBlacklist,
}; };
export const init = (sourceConfig, blacklist) => { export const init = (sourceConfig, blacklist) => {
config.enabled = sourceConfig.enabled; config.enabled = sourceConfig.enabled;
config.url = sourceConfig.url; config.url = sourceConfig.url;
appliedBlackList = blacklist || []; appliedBlackList = blacklist || [];
}; };
export const metaInformation = { export const metaInformation = {
name: 'Immowelt', name: 'Immowelt',
baseUrl: 'https://www.immowelt.de/', baseUrl: 'https://www.immowelt.de/',
id: 'immowelt', id: 'immowelt',
}; };
export {config}; export { config };

View File

@@ -1,6 +1,6 @@
{ {
"name": "fredy", "name": "fredy",
"version": "10.1.0", "version": "10.2.0",
"description": "[F]ind [R]eal [E]states [d]amn eas[y].", "description": "[F]ind [R]eal [E]states [d]amn eas[y].",
"scripts": { "scripts": {
"start": "node index.js", "start": "node index.js",
@@ -55,13 +55,13 @@
"Firefox ESR" "Firefox ESR"
], ],
"dependencies": { "dependencies": {
"@douyinfe/semi-ui": "2.65.0", "@douyinfe/semi-ui": "2.68.3",
"@rematch/core": "2.2.0", "@rematch/core": "2.2.0",
"@rematch/loading": "2.1.2", "@rematch/loading": "2.1.2",
"@sendgrid/mail": "8.1.3", "@sendgrid/mail": "8.1.4",
"@vitejs/plugin-react": "4.3.1", "@vitejs/plugin-react": "4.3.3",
"better-sqlite3": "8.6.0", "better-sqlite3": "^11.5.0",
"body-parser": "1.20.2", "body-parser": "1.20.3",
"cookie-session": "2.1.0", "cookie-session": "2.1.0",
"handlebars": "4.7.8", "handlebars": "4.7.8",
"highcharts": "11.4.8", "highcharts": "11.4.8",
@@ -69,10 +69,10 @@
"lodash": "4.17.21", "lodash": "4.17.21",
"lowdb": "6.0.1", "lowdb": "6.0.1",
"markdown": "^0.5.0", "markdown": "^0.5.0",
"nanoid": "5.0.7", "nanoid": "5.0.8",
"node-fetch": "3.3.2", "node-fetch": "3.3.2",
"node-mailjet": "6.0.6", "node-mailjet": "6.0.6",
"query-string": "8.2.0", "query-string": "9.1.1",
"react": "18.3.1", "react": "18.3.1",
"react-dom": "18.3.1", "react-dom": "18.3.1",
"react-redux": "9.1.2", "react-redux": "9.1.2",
@@ -81,27 +81,27 @@
"redux": "5.0.1", "redux": "5.0.1",
"redux-thunk": "3.1.0", "redux-thunk": "3.1.0",
"restana": "4.9.9", "restana": "4.9.9",
"serve-static": "1.15.0", "serve-static": "1.16.2",
"slack": "11.0.2", "slack": "11.0.2",
"string-similarity": "^4.0.4", "string-similarity": "^4.0.4",
"vite": "5.4.3", "vite": "5.4.10",
"x-ray": "2.3.4" "x-ray": "2.3.4"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "7.25.2", "@babel/core": "7.26.0",
"@babel/eslint-parser": "7.25.1", "@babel/eslint-parser": "7.25.9",
"@babel/preset-env": "7.25.4", "@babel/preset-env": "7.26.0",
"@babel/preset-react": "7.24.7", "@babel/preset-react": "7.25.9",
"chai": "5.1.1", "chai": "5.1.2",
"eslint": "8.56.0", "eslint": "8.56.0",
"eslint-config-prettier": "8.8.0", "eslint-config-prettier": "8.8.0",
"eslint-plugin-react": "7.35.2", "eslint-plugin-react": "7.37.2",
"esmock": "2.6.7", "esmock": "2.6.9",
"history": "5.3.0", "history": "5.3.0",
"husky": "4.3.8", "husky": "4.3.8",
"less": "4.2.0", "less": "4.2.0",
"lint-staged": "13.2.2", "lint-staged": "13.2.2",
"mocha": "10.7.3", "mocha": "10.8.2",
"prettier": "3.3.3", "prettier": "3.3.3",
"redux-logger": "3.0.6" "redux-logger": "3.0.6"
} }

View File

@@ -13,7 +13,7 @@
"enabled": true "enabled": true
}, },
"immowelt": { "immowelt": {
"url": "https://www.immowelt.de/liste/duesseldorf/wohnungen/kaufen?d=true&rmi=3&sd=DESC&sf=TIMESTAMP&sp=1", "url": "https://www.immowelt.de/classified-search?distributionTypes=Buy,Buy_Auction,Compulsory_Auction&estateTypes=House,Apartment&locations=AD08DE2350",
"enabled": true "enabled": true
}, },
"immoscout": { "immoscout": {

View File

@@ -1,7 +1,7 @@
[ [
{ {
"url": "https://www.immowelt.de/liste/40589/wohnungen/mieten?d=true&sd=DESC&sf=PRIMARY_PRICE_AMOUNT&sp=1", "url": "https://www.immowelt.de/classified-search?distributionTypes=Buy,Buy_Auction,Compulsory_Auction&estateTypes=House,Apartment&locations=AD08DE2350",
"shouldBecome": "https://www.immowelt.de/liste/40589/wohnungen/mieten?d=true&sd=DESC&sf=TIMESTAMP&sp=1", "shouldBecome": "https://www.immowelt.de/classified-search?distributionTypes=Buy,Buy_Auction,Compulsory_Auction&estateTypes=House,Apartment&locations=AD08DE2350&order=DateDesc",
"id": "immowelt" "id": "immowelt"
}, },
{ {

2094
yarn.lock

File diff suppressed because it is too large Load Diff