diff --git a/service.py b/service.py index 84543ef..760242c 100644 --- a/service.py +++ b/service.py @@ -126,6 +126,9 @@ class MongoDriver(MeshArgsParse): sys.exit(1) self.dbStore = self.dbClient[self.args.mongo_db] self.dbService = DbService(self.dbStore) + + from tileManager import TileManager + self.tileManager = TileManager(self) async def dbSaveRadio(self, new_from_radio): '''try: diff --git a/tileManager.py b/tileManager.py new file mode 100644 index 0000000..78f65f6 --- /dev/null +++ b/tileManager.py @@ -0,0 +1,44 @@ +import aiohttp +from pymongo.asynchronous.database import AsyncDatabase + +from logger import logger +from time import time + +class TileManager: + domain = 'a.tile.openstreetmap.org' + format = "png" + + def __init__(self, core): + self.core = core + self.dbStore:AsyncDatabase = self.core.dbStore + + def generateHeaders(self): + return { + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36", + "Referer": "http://localhost:4200/", + "Accept": "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8" + } + + async def grabTile(self, z:int, x:int, y:int): + #grab from db + collection = self.dbStore['openstreetmap'] + query = {"x":x, "y":y, "z": z} + t = await collection.find_one(query) + if t: + return t["img"] + else: + #ищем картинку чтож поделать + url = f"https://{self.domain}/{z}/{x}/{y}.{self.format}" + async with aiohttp.ClientSession() as session: + async with session.get(url, ssl=False, headers=self.generateHeaders()) as resp: + # Read the entire response body as bytes + img = await resp.read() + logger.info(url, resp.status) + if resp.status == 200: + query['ts'] = time() + query['img'] = img + query['format'] = self.format + await collection.insert_one(query) + return img + else: + raise Exception("cannot get img") \ No newline at end of file diff --git a/ui/angular.json b/ui/angular.json index 7774b5c..9381d73 100644 --- a/ui/angular.json +++ b/ui/angular.json @@ -29,7 +29,8 @@ ], "styles": [ "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css", - "src/styles.scss" + "src/styles.scss", + "./node_modules/leaflet/dist/leaflet.css" ], "scripts": [] }, @@ -101,6 +102,7 @@ ], "styles": [ "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css", + "./node_modules/leaflet/dist/leaflet.css", "src/styles.scss" ], "scripts": [] diff --git a/ui/package-lock.json b/ui/package-lock.json index b58db08..8e80359 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -19,6 +19,7 @@ "@angular/platform-browser-dynamic": "^14.2.0", "@angular/router": "^14.2.0", "chart.js": "^4.5.1", + "leaflet": "^1.9.4", "rxjs": "~7.5.0", "tslib": "^2.3.0", "zone.js": "~0.11.4" @@ -28,6 +29,7 @@ "@angular/cli": "~14.2.13", "@angular/compiler-cli": "^14.2.0", "@types/jasmine": "~4.0.0", + "@types/leaflet": "^1.9.21", "jasmine-core": "~4.3.0", "karma": "~6.4.0", "karma-chrome-launcher": "~3.1.0", @@ -3343,6 +3345,13 @@ "@types/send": "*" } }, + "node_modules/@types/geojson": { + "version": "7946.0.16", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", + "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/http-errors": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", @@ -3374,6 +3383,16 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/leaflet": { + "version": "1.9.21", + "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.21.tgz", + "integrity": "sha512-TbAd9DaPGSnzp6QvtYngntMZgcRk+igFELwR2N99XZn7RXUdKgsXMR+28bUO0rPsWp8MIu/f47luLIQuSLYv/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/geojson": "*" + } + }, "node_modules/@types/mime": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", @@ -8099,6 +8118,12 @@ "node": ">= 8" } }, + "node_modules/leaflet": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz", + "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==", + "license": "BSD-2-Clause" + }, "node_modules/less": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/less/-/less-4.1.3.tgz", diff --git a/ui/package.json b/ui/package.json index d26780d..296f1f9 100644 --- a/ui/package.json +++ b/ui/package.json @@ -21,6 +21,7 @@ "@angular/platform-browser-dynamic": "^14.2.0", "@angular/router": "^14.2.0", "chart.js": "^4.5.1", + "leaflet": "^1.9.4", "rxjs": "~7.5.0", "tslib": "^2.3.0", "zone.js": "~0.11.4" @@ -30,6 +31,7 @@ "@angular/cli": "~14.2.13", "@angular/compiler-cli": "^14.2.0", "@types/jasmine": "~4.0.0", + "@types/leaflet": "^1.9.21", "jasmine-core": "~4.3.0", "karma": "~6.4.0", "karma-chrome-launcher": "~3.1.0", diff --git a/ui/src/app/app-routing.module.ts b/ui/src/app/app-routing.module.ts index 20dc854..84ecb41 100644 --- a/ui/src/app/app-routing.module.ts +++ b/ui/src/app/app-routing.module.ts @@ -4,8 +4,10 @@ import {NodesListComponent} from "./components/nodes/nodes-list.component"; import {BotCommandsComponent} from "./components/botCommands/BotCommands.component"; import {MessageHistoryComponent} from "./components/messages/MessageHistory.component"; import {NetworkStatusComponent} from "./components/packet/NetworkStatus.component"; +import {NodesMapComponent} from "./components/nodes/nodes-map.component"; const routes: Routes = [ + {path: "nodes/map", component: NodesMapComponent}, {path: "nodes/:type", component: NodesListComponent}, {path: "messages", component: MessageHistoryComponent}, {path: "network/status/:num", component: NetworkStatusComponent}, diff --git a/ui/src/app/app.component.ts b/ui/src/app/app.component.ts index a259c8b..37f630d 100644 --- a/ui/src/app/app.component.ts +++ b/ui/src/app/app.component.ts @@ -26,6 +26,7 @@ export class AppComponent implements OnInit { {name: "История сообщений", url:"messages"}, {name: "Прямые ноды", url:"nodes/direct"}, {name: "Все ноды", url:"nodes/list"}, + {name: "Карта сети", url: "nodes/map"} //{name: "Все ноды", url:""}, ] diff --git a/ui/src/app/app.module.ts b/ui/src/app/app.module.ts index 04e02a0..4a38dd5 100644 --- a/ui/src/app/app.module.ts +++ b/ui/src/app/app.module.ts @@ -25,6 +25,7 @@ import {MatSelectModule} from "@angular/material/select"; import {NetworkStatusComponent} from "./components/packet/NetworkStatus.component"; import {MatRadioModule} from "@angular/material/radio"; import {DatePipe} from "@angular/common"; +import {NodesMapComponent} from "./components/nodes/nodes-map.component"; @NgModule({ declarations: [ @@ -33,7 +34,8 @@ import {DatePipe} from "@angular/common"; MessageHistoryComponent, NodesListComponent, AuthDialog, - NetworkStatusComponent + NetworkStatusComponent, + NodesMapComponent ], imports: [ BrowserModule, diff --git a/ui/src/app/components/nodes/nodes-map.component.ts b/ui/src/app/components/nodes/nodes-map.component.ts new file mode 100644 index 0000000..c4dffeb --- /dev/null +++ b/ui/src/app/components/nodes/nodes-map.component.ts @@ -0,0 +1,69 @@ +import {Component, OnInit} from "@angular/core"; +import * as L from 'leaflet'; +import {HttpClient} from "@angular/common/http"; +import {NodeDTO} from "../../entities/NodeDTO"; +import {Subscription} from "rxjs"; + +@Component({ + selector: "app-nodes-map", + styleUrls: ['nodes.styles.scss'], + template: ` +