1
Fork 0
mirror of https://github.com/pds-nest/nest.git synced 2025-02-16 12:43:58 +00:00

Merge remote-tracking branch 'origin/main' into main

This commit is contained in:
Lorenzo Balugani 2021-05-27 10:57:45 +02:00
commit bd84c317c5
26 changed files with 263 additions and 82 deletions

View file

@ -2,6 +2,7 @@
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="HtmlRequiredLangAttribute" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="InconsistentLineSeparators" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="JupyterPackageInspection" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="LessResolvedByNameOnly" enabled="true" level="WARNING" enabled_by_default="true" />

View file

@ -167,19 +167,6 @@ class TestRepositoryPatch:
})
assert r.status_code == 204
'''
def test_unknown_type(self, flask_client: Client, admin_headers):
r = flask_client.patch(f'/api/v1/repositories/1', headers=admin_headers,
json={
"name": "string",
"close": "string",
"open": "string",
"evaluation_mode": 99
})
assert r.status_code == 400
assert r.json["result"] == "failure" '''
class TestRepositoryDelete:

View file

@ -207,4 +207,3 @@ class TestOneAlertOfARepository:
def test_delete_alert_for_success(self, flask_client: Client, user_headers):
r = flask_client.delete(f'/api/v1/alert/1', headers=user_headers)
assert r.status_code == 204

View file

@ -4,6 +4,7 @@ from nest_backend.database import *
import tweepy as tw
from datetime import datetime, timedelta
import smtplib
from nest_backend.app import app, extension_sqlalchemy
ext.init_app(app=app)
@ -24,12 +25,13 @@ def authenticate():
def search_repo_conditions(repository_id):
api = authenticate()
geocode = "44.3591600,11.7132000,20km"
repo = Repository.query.filter_by(id=repository_id).first()
if repo is None:
print("Non esiste una repository con questo id")
return False
conditions = [use for use in repo.conditions]
if len(conditions) == 0:
return False
evaluation_mode = repo.evaluation_mode
conditions_type = dict()
# Dividing condition into condition types
@ -234,7 +236,14 @@ def send_test_tweet():
api = authenticate()
api.update_status("Test")
def search_all_repo():
active_repos = Repository.query.filter_by(is_active=True)
for repo_id in [active_repo.id for active_repo in active_repos]:
search_repo_conditions(repo_id)
is_repo_alert_triggered(repo_id)
if __name__ == "__main__":
search_repo_conditions(16)
with app.app_context():
ext.create_all(app=app)
search_all_repo()

View file

@ -1,5 +1,4 @@
import React from "react"
import Layout from "./components/interactive/Layout"
import { BrowserRouter } from "react-router-dom"
import GlobalTheme from "./components/providers/GlobalTheme"
import GlobalServer from "./components/providers/GlobalServer"
@ -7,6 +6,10 @@ import GlobalUser from "./components/providers/GlobalUser"
import PageSwitcher from "./PageSwitcher"
import GlobalLanguage from "./components/providers/GlobalLanguage"
import ErrorBoundary from "./components/boundaries/ErrorBoundary"
import Sidebar from "./components/interactive/Sidebar"
import WebsiteWithSidebar from "./components/base/layout/WebsiteWithSidebar"
import Window from "./components/base/layout/Window"
import RequireSize from "./components/base/RequireSize"
/**
@ -22,11 +25,17 @@ export default function App() {
<GlobalUser>
<GlobalTheme>
<BrowserRouter>
<Layout>
<ErrorBoundary>
<PageSwitcher/>
</ErrorBoundary>
</Layout>
<Window>
<RequireSize width={1366} height={768}>
<WebsiteWithSidebar
sidebar={<Sidebar/>}
>
<ErrorBoundary>
<PageSwitcher/>
</ErrorBoundary>
</WebsiteWithSidebar>
</RequireSize>
</Window>
</BrowserRouter>
</GlobalTheme>
</GlobalUser>

View file

@ -16,6 +16,9 @@ export default {
appFullName: "Noi Estraiamo Statistiche Tweet",
welcomeToNest: "Benvenuto a N.E.S.T.!",
resolutionTooSmall: "Per visualizzare correttamente questa applicazione è richiesto uno schermo con risoluzione 1366x768 o superiore.", // TODO: Tradurre
ignore: "Visualizza comunque", // TODO: Tradurre
server: "Scegli un server",
baseURL: "Base URL",
notLoggedIn: "Accesso non effettuato",

View file

@ -0,0 +1,28 @@
import React, { useState } from "react"
import { useWindowSize } from "@react-hook/window-size/throttled"
import Alert from "./Alert"
import useStrings from "../../hooks/useStrings"
import Button from "./Button"
import { faExclamationTriangle } from "@fortawesome/free-solid-svg-icons"
import makeIcon from "../../utils/makeIcon"
import BodyFlex from "./layout/BodyFlex"
export default function RequireSize({ children, width, height, ...props }) {
const [windowWidth, windowHeight] = useWindowSize()
const [warn, setWarn] = useState(true)
const strings = useStrings()
if(warn && (windowWidth < width || windowHeight < height)) {
return <BodyFlex {...props}>
<Alert color={"Red"}>
{strings.resolutionTooSmall}
</Alert>
<Button color={"Yellow"} onClick={() => setWarn(false)} style={{alignSelf: "center"}}>
{makeIcon(faExclamationTriangle)} {strings.ignore}
</Button>
</BodyFlex>
}
return children
}

View file

@ -0,0 +1,28 @@
import React from "react"
import Style from "./WebsiteWithSidebar.module.css"
import classNames from "classnames"
/**
* The base page layout, consisting of a {@link Sidebar} on the left and the page contents on the remaining space.
*
* @param sidebar - The sidebar to display.
* @param children - The page contents.
* @param className - Additional class(es) to be added to the grid container.
* @param props - Additional props to be passed to the grid container.
* @returns {JSX.Element}
* @constructor
*/
export default function WebsiteWithSidebar({ sidebar, children, className, ...props }) {
return (
<div className={classNames(Style.WebsiteWithSidebar, className)} {...props}>
<aside className={Style.Sidebar}>
{sidebar}
</aside>
<main className={Style.Main}>
{children}
</main>
</div>
)
}

View file

@ -0,0 +1,19 @@
.WebsiteWithSidebar {
height: 100%;
width: 100%;
display: grid;
grid-template-areas:
"a b";
grid-template-columns: auto 1fr;
grid-gap: 10px;
}
.Sidebar {
grid-area: a;
}
.Main {
grid-area: b;
}

View file

@ -0,0 +1,15 @@
import React, { useContext } from "react"
import Style from "./Window.module.css"
import classNames from "classnames"
import ContextTheme from "../../../contexts/ContextTheme"
export default function Window({ children, className, ...props }) {
const {theme} = useContext(ContextTheme)
return (
<div className={classNames(Style.Window, theme, className)} {...props}>
{children}
</div>
)
}

View file

@ -0,0 +1,9 @@
.Window {
width: 100vw;
height: 100vh;
color: var(--fg-primary);
background-color: var(--bg-primary);
padding: 10px;
}

View file

@ -1,15 +1,29 @@
import React from "react"
import React, { useMemo } from "react"
import BoxFullScrollable from "../base/BoxFullScrollable"
import SummaryAlert from "./SummaryAlert"
import useStrings from "../../hooks/useStrings"
import Empty from "./Empty"
export default function BoxAlerts({ alerts, destroy, running, ...props }) {
const strings = useStrings()
const content = useMemo(
() => {
if(alerts.length === 0) {
return <Empty/>
}
return alerts.map(alert => (
<SummaryAlert alert={alert} destroy={() => destroy(alert["id"])} running={running}/>
))
},
[alerts, running, destroy]
)
return (
<BoxFullScrollable header={strings.alertTitle} {...props}>
{alerts.map(alert => <SummaryAlert alert={alert} destroy={() => destroy(alert["id"])} running={running}/>)}
{content}
</BoxFullScrollable>
)
}

View file

@ -1,28 +0,0 @@
import React, { useContext } from "react"
import Style from "./Layout.module.css"
import classNames from "classnames"
import Sidebar from "../interactive/Sidebar"
import ContextTheme from "../../contexts/ContextTheme"
/**
* The base page layout, consisting of a {@link Sidebar} on the left and the page contents on the remaining space.
*
* @param children - The page contents.
* @param className - Additional class(es) to be added to the grid container.
* @param props - Additional props to be passed to the grid container.
* @returns {JSX.Element}
* @constructor
*/
export default function Layout({ children, className, ...props }) {
const { theme } = useContext(ContextTheme)
return (
<div className={classNames(theme, Style.Layout, className)} {...props}>
<Sidebar className={Style.LayoutSidebar}/>
<main className={Style.LayoutContent}>
{children}
</main>
</div>
)
}

View file

@ -1,23 +0,0 @@
.Layout {
height: 100vh;
width: 100vw;
padding: 16px;
background-color: var(--bg-primary);
color: var(--fg-primary);
display: grid;
grid-template-areas:
"a b";
grid-template-columns: 250px 1fr;
grid-gap: 10px;
}
.LayoutSidebar {
grid-area: a;
}
.LayoutContent {
grid-area: b;
}

View file

@ -31,7 +31,7 @@ export default function Sidebar({ className, ...props }) {
</>
:
<>
<ButtonSidebar to={"/login"} icon={faKey}>{strings.login}</ButtonSidebar>
<ButtonSidebar to={"/"} icon={faKey}>{strings.login}</ButtonSidebar>
</>
}
{

View file

@ -3,7 +3,7 @@
flex-direction: column;
gap: 25px;
width: 100%;
width: 250px;
height: 100%;
background-color: var(--bg-light);

View file

@ -31,7 +31,7 @@ export default function SummaryTweet({ tweet, ...props }) {
<SummaryLeft
icon={icon}
title={`@${tweet["poster"]}`}
subtitle={new Date(tweet["insert_time"]).toLocaleString()}
subtitle={tweet["post_time"] ? new Date(tweet["post_time"]).toLocaleString() : null}
onClick={() => window.open(`https://twitter.com/${tweet["poster"]}/status/${tweet["snowflake"]}`)}
/>
<SummaryText>

109
package-lock.json generated
View file

@ -13,6 +13,7 @@
"@fortawesome/free-regular-svg-icons": "^5.15.3",
"@fortawesome/free-solid-svg-icons": "^5.15.3",
"@fortawesome/react-fontawesome": "^0.1.14",
"@react-hook/window-size": "^3.0.7",
"@react-leaflet/core": ">=1.0.0 <1.1.0 || ^1.1.1",
"@steffo/nest-react-wordcloud": "1.2.11",
"@testing-library/jest-dom": "^5.11.10",
@ -2379,6 +2380,68 @@
"url": "https://opencollective.com/popperjs"
}
},
"node_modules/@react-hook/debounce": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@react-hook/debounce/-/debounce-3.0.0.tgz",
"integrity": "sha512-ir/kPrSfAzY12Gre0sOHkZ2rkEmM4fS5M5zFxCi4BnCeXh2nvx9Ujd+U4IGpKCuPA+EQD0pg1eK2NGLvfWejag==",
"dependencies": {
"@react-hook/latest": "^1.0.2"
},
"peerDependencies": {
"react": ">=16.8"
}
},
"node_modules/@react-hook/event": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/@react-hook/event/-/event-1.2.3.tgz",
"integrity": "sha512-WMBwLnYY2rubLeecsi4skl1imfx0oiXTgazV/1ByPT6WkmLvxUao3hC+mxps5D/+JK4Fq3uG9OWU/dn5jMtXyg==",
"dependencies": {
"@react-hook/passive-layout-effect": "^1.2.0"
},
"peerDependencies": {
"react": ">=16.8"
}
},
"node_modules/@react-hook/latest": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@react-hook/latest/-/latest-1.0.3.tgz",
"integrity": "sha512-dy6duzl+JnAZcDbNTfmaP3xHiKtbXYOaz3G51MGVljh548Y8MWzTr+PHLOfvpypEVW9zwvl+VyKjbWKEVbV1Rg==",
"peerDependencies": {
"react": ">=16.8"
}
},
"node_modules/@react-hook/passive-layout-effect": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@react-hook/passive-layout-effect/-/passive-layout-effect-1.2.1.tgz",
"integrity": "sha512-IwEphTD75liO8g+6taS+4oqz+nnroocNfWVHWz7j+N+ZO2vYrc6PV1q7GQhuahL0IOR7JccFTsFKQ/mb6iZWAg==",
"peerDependencies": {
"react": ">=16.8"
}
},
"node_modules/@react-hook/throttle": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@react-hook/throttle/-/throttle-2.2.0.tgz",
"integrity": "sha512-LJ5eg+yMV8lXtqK3lR+OtOZ2WH/EfWvuiEEu0M3bhR7dZRfTyEJKxH1oK9uyBxiXPtWXiQggWbZirMCXam51tg==",
"dependencies": {
"@react-hook/latest": "^1.0.2"
},
"peerDependencies": {
"react": ">=16.8"
}
},
"node_modules/@react-hook/window-size": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/@react-hook/window-size/-/window-size-3.0.7.tgz",
"integrity": "sha512-bK5ed/jN+cxy0s1jt2CelCnUt7jZRseUvPQ22ZJkUl/QDOsD+7CA/6wcqC3c0QweM/fPBRP6uI56TJ48SnlVww==",
"dependencies": {
"@react-hook/debounce": "^3.0.0",
"@react-hook/event": "^1.2.1",
"@react-hook/throttle": "^2.2.0"
},
"peerDependencies": {
"react": ">=16.8"
}
},
"node_modules/@react-leaflet/core": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@react-leaflet/core/-/core-1.0.2.tgz",
@ -24512,6 +24575,52 @@
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.9.2.tgz",
"integrity": "sha512-VZMYa7+fXHdwIq1TDhSXoVmSPEGM/aa+6Aiq3nVVJ9bXr24zScr+NlKFKC3iPljA7ho/GAZr+d2jOf5GIRC30Q=="
},
"@react-hook/debounce": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@react-hook/debounce/-/debounce-3.0.0.tgz",
"integrity": "sha512-ir/kPrSfAzY12Gre0sOHkZ2rkEmM4fS5M5zFxCi4BnCeXh2nvx9Ujd+U4IGpKCuPA+EQD0pg1eK2NGLvfWejag==",
"requires": {
"@react-hook/latest": "^1.0.2"
}
},
"@react-hook/event": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/@react-hook/event/-/event-1.2.3.tgz",
"integrity": "sha512-WMBwLnYY2rubLeecsi4skl1imfx0oiXTgazV/1ByPT6WkmLvxUao3hC+mxps5D/+JK4Fq3uG9OWU/dn5jMtXyg==",
"requires": {
"@react-hook/passive-layout-effect": "^1.2.0"
}
},
"@react-hook/latest": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@react-hook/latest/-/latest-1.0.3.tgz",
"integrity": "sha512-dy6duzl+JnAZcDbNTfmaP3xHiKtbXYOaz3G51MGVljh548Y8MWzTr+PHLOfvpypEVW9zwvl+VyKjbWKEVbV1Rg==",
"requires": {}
},
"@react-hook/passive-layout-effect": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@react-hook/passive-layout-effect/-/passive-layout-effect-1.2.1.tgz",
"integrity": "sha512-IwEphTD75liO8g+6taS+4oqz+nnroocNfWVHWz7j+N+ZO2vYrc6PV1q7GQhuahL0IOR7JccFTsFKQ/mb6iZWAg==",
"requires": {}
},
"@react-hook/throttle": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@react-hook/throttle/-/throttle-2.2.0.tgz",
"integrity": "sha512-LJ5eg+yMV8lXtqK3lR+OtOZ2WH/EfWvuiEEu0M3bhR7dZRfTyEJKxH1oK9uyBxiXPtWXiQggWbZirMCXam51tg==",
"requires": {
"@react-hook/latest": "^1.0.2"
}
},
"@react-hook/window-size": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/@react-hook/window-size/-/window-size-3.0.7.tgz",
"integrity": "sha512-bK5ed/jN+cxy0s1jt2CelCnUt7jZRseUvPQ22ZJkUl/QDOsD+7CA/6wcqC3c0QweM/fPBRP6uI56TJ48SnlVww==",
"requires": {
"@react-hook/debounce": "^3.0.0",
"@react-hook/event": "^1.2.1",
"@react-hook/throttle": "^2.2.0"
}
},
"@react-leaflet/core": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@react-leaflet/core/-/core-1.0.2.tgz",

View file

@ -11,6 +11,7 @@
"@fortawesome/free-regular-svg-icons": "^5.15.3",
"@fortawesome/free-solid-svg-icons": "^5.15.3",
"@fortawesome/react-fontawesome": "^0.1.14",
"@react-hook/window-size": "^3.0.7",
"@react-leaflet/core": ">=1.0.0 <1.1.0 || ^1.1.1",
"@steffo/nest-react-wordcloud": "1.2.11",
"@testing-library/jest-dom": "^5.11.10",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View file

@ -1,12 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<html>
<head>
<meta charset="utf-8"/>
<link href="%PUBLIC_URL%/favicon.ico" rel="icon"/>
<meta content="width=device-width, initial-scale=1" name="viewport"/>
<meta content="#34607A" name="theme-color"/>
<meta
content="Tweet analyzer frontend"
content="Tweet gatherer, analyzer and visualizer"
name="description"
/>
<link href="%PUBLIC_URL%/logo192.png" rel="apple-touch-icon"/>

BIN
public/logo1024.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 17 KiB

BIN
public/logo670.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
public/logo768.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View file

@ -1,3 +1,4 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:
Disallow: /