Browse Source

add favicons

main
matthew 2 years ago
parent
commit
3ee70af7e0
  1. 17
      searching-front/app/core/components/WebsiteCard/WebsiteCard.tsx
  2. 16
      searching-front/app/core/components/WebsiteCard/styles.module.css
  3. 2
      searching-front/app/core/layouts/Layout/styles.module.css
  4. 1
      searching-front/app/search-requests/queries/getSearchResult.ts
  5. 3
      searching-front/services/modules/elastic/index.ts
  6. 23
      searching-front/services/modules/parser/index.ts
  7. 3
      searching-front/services/parser.ts

17
searching-front/app/core/components/WebsiteCard/WebsiteCard.tsx

@ -1,18 +1,33 @@
import { cleanUrlForUi } from "app/core/helpers/common" import { cleanUrlForUi } from "app/core/helpers/common"
import { useEffect, useState } from "react"
import s from "./styles.module.css" import s from "./styles.module.css"
interface Props { interface Props {
url: string url: string
title: string title: string
description: string description: string
faviconUrl?: string
} }
const WebsiteCard = (props: Props) => { const WebsiteCard = (props: Props) => {
const faviconUrl = props.faviconUrl;
const [faviconLoaded, setFaviconLoaded] = useState(false)
useEffect(() => {
if (faviconUrl) {
const faviconNode = document.createElement("img")
faviconNode.src = faviconUrl;
faviconNode.onload = () => {
setFaviconLoaded(true)
}
}
}, [faviconUrl])
const urlObj = new URL(props.url) const urlObj = new URL(props.url)
urlObj.searchParams.set("from", "Searching.ton") urlObj.searchParams.set("from", "Searching.ton")
const url = urlObj.toString(); const url = urlObj.toString()
return ( return (
<div className={s.root}> <div className={s.root}>
{faviconLoaded &&<img className={(s.favicon)} src={faviconUrl} />}
<a target="_blank" className={s.titleLink} href={url}> <a target="_blank" className={s.titleLink} href={url}>
{props.title} {props.title}
</a> </a>

16
searching-front/app/core/components/WebsiteCard/styles.module.css

@ -4,6 +4,7 @@
border-radius: 12px; border-radius: 12px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
position: relative;
} }
.root:not(:last-of-type) { .root:not(:last-of-type) {
@ -34,3 +35,18 @@
.description { .description {
font-size: 13px; font-size: 13px;
} }
.favicon {
width: 16px;
height: 16px;
border-radius: 50%;
position: absolute;
left: -24px;
top: 16px;
}
@media only screen and (max-width: 700px) {
.favicon {
left: -16px;
}
}

2
searching-front/app/core/layouts/Layout/styles.module.css

@ -8,7 +8,7 @@
margin-top: 20px; margin-top: 20px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding: 0 20px;
flex: 1; flex: 1;
/* margin: auto; */ /* margin: auto; */
} }

1
searching-front/app/search-requests/queries/getSearchResult.ts

@ -22,6 +22,7 @@ const processResult = ({ bodyText, ...res }: Object, search: string) => {
return { return {
...res, ...res,
description: res.description || bodyToDescription(bodyText, search), description: res.description || bodyToDescription(bodyText, search),
faviconUrl: res.faviconUrl,
} }
} }

3
searching-front/services/modules/elastic/index.ts

@ -11,6 +11,7 @@ export interface ElasticIndexParams {
h1?: string h1?: string
bodyText: string bodyText: string
description?: string description?: string
faviconUrl?: string
} }
export interface ElasticSearchParams { export interface ElasticSearchParams {
text: string text: string
@ -102,6 +103,7 @@ class Elastic {
public index = async (params: ElasticIndexParams) => { public index = async (params: ElasticIndexParams) => {
const indexName = getIndexNameByText(params.title + params.bodyText) const indexName = getIndexNameByText(params.title + params.bodyText)
console.log('index',params)
await this.client.index({ await this.client.index({
index: indexName, index: indexName,
id: params.url, id: params.url,
@ -111,6 +113,7 @@ class Elastic {
h1: params.h1, h1: params.h1,
bodyText: params.bodyText, bodyText: params.bodyText,
description: params.description, description: params.description,
faviconUrl: params.faviconUrl,
}, },
}) })
} }

23
searching-front/services/modules/parser/index.ts

@ -23,9 +23,29 @@ const isInvalidLink = (link: string) => {
return link.match(/\./) && !(link.match(/\.html/) || link.match(/\.htm/)) return link.match(/\./) && !(link.match(/\.html/) || link.match(/\.htm/))
} }
const getFaviconUrl = (dom:JSDOM, domain:string) => {
try{
const node = dom.window.document.querySelector("[rel=icon][type*=image]") as HTMLLinkElement;;
const href = node?.href;
let url;
if(href){
try {
url = new URL(href);
} catch(e){
url = new URL(domain+href);
url.pathname = url.pathname.replace('//','/');
}
return url.toString();
}
} catch(e){
return undefined
}
}
class Parser { class Parser {
constructor() {} constructor() {}
parseUrl = async (url: string) => { parseUrl = async (url: string, domain:string) => {
try { try {
const { data, headers } = await axios.get(url,{ const { data, headers } = await axios.get(url,{
@ -66,6 +86,7 @@ class Parser {
.querySelector("meta[name='description']") .querySelector("meta[name='description']")
?.getAttribute("content") || "", ?.getAttribute("content") || "",
url, url,
faviconUrl: getFaviconUrl(dom, domain)
}, },
subPages, subPages,
} }

3
searching-front/services/parser.ts

@ -15,8 +15,7 @@ const indexWebsite = async (domain: string, path: string, subpages: SubPages = {
const subpagesLength = Object.keys(subpages).length; const subpagesLength = Object.keys(subpages).length;
if (!subpages[path]) { if (!subpages[path]) {
const url = domain + path; const url = domain + path;
const parseInfo = await Parser.parseUrl(url) const parseInfo = await Parser.parseUrl(url,domain);
console.log(parseInfo)
subpages[path] = true subpages[path] = true
let pages = {} let pages = {}
if (parseInfo !== SHOULD_NOT_PARSE && subpagesLength < 50) { if (parseInfo !== SHOULD_NOT_PARSE && subpagesLength < 50) {

Loading…
Cancel
Save