Taisin katsoa selaimen konsolista, en siis CodeSandboxin konsolista vaan selaimen omasta.Mistä muuten Paapaa, näit tuon virheilmoituksen? Minä en huomannut kuin tuon postaamani konsolista.
Tervetuloa webbikehityksen maailmaan Opittavaa on loputtoman paljon, että kaikki palaset loksahtaa paikoilleen. Mutta kyllä mä rohkaisen opettelemaan tuotakin puolta. Lisää isosti ymmärrystä kaiken toiminnasta. Eikä noiden konffaaminen ole mitään ylitsepääsemättömän vaikeaa. Mutta Dockerin opettelua vaatii. Tässä pari loistavaa kurssia, ensimmäinen vain Dockeriin, toinen webbidevaukseen yleisesti:Varmaan joo, mutta kun tämä on harrastus, johon on rajallinen määrä aikaa käytössä + minua ei oikeastaan kiinnosta nuo DevOps-hommat
Öö, mikäs ihmeen kommentti tuo oikein on?? Tietenkin pystyy, mitä muuta kuvittelet? Docker vain helpottaa sitä asennusta ja ylläpitoa. Jos sua ei nappaa sen opettelu, niin siitä vaan asentamaan ja konffaamaan kaikki itse. Ja toivomaan, että osaat tehdä saman uudestaan kun se serveri menee nurin ja pitää aloittaa alusta, jos et sitä infran pystyttämistä ole automatisoinut. Lopulta huomaat kyllä, miksi ne kontit on keksitty. Voit sitten tulla lainaamaan tätä viestiäni.Kumma kun näitä servereitä pystyttiin ennen pyörittämään ilman Dockeria, mutta ei enää.
type ColumnFilterElementType = React.ReactNode | ((options: ColumnFilterElementTemplateOptions) => React.ReactNode);
const nationalityFilterTemplate: ColumnFilterElementType = (options) => ...
Tässä tapauksessa kääntäjä tietää, että jos määrittelet funktion juuri tuolla tyypillä, ei ole mitään muuta mahdollisuutta kuin että se parametrin tyyppi on ColumnFilterElementTemplateOptions. Se on ainoa tulkinta tyypin perusteella. TS osaa päätellä varsin paljon, eikä sille tarvitse eksplisiittisesti kertoa kaikkea. Joskus on useampi tulkinta, ja silloin pitää antaa lisää ohjausta, että kääntäjä käyttää oikeaa tyypitystä. Esim:En kyllä ymmärrä, miksi tuo toimii. Annetaan siis funktiolle tyyppi ja se jotenkin maagisesti johtaa siihen, että kääntäjä tietää parametrin tyypin?
const strings = ['foo', 'bar']; // tyyppi string[]
const fooBars: Array<'foo' | 'bar'> = ['foo', 'bar']
$ sudo ufw status
Status: active
To Action From
-- ------ ----
Nginx Full ALLOW Anywhere
OpenSSH ALLOW Anywhere
3000 ALLOW Anywhere
5000 ALLOW Anywhere
Nginx Full (v6) ALLOW Anywhere (v6)
OpenSSH (v6) ALLOW Anywhere (v6)
3000 (v6) ALLOW Anywhere (v6)
5000 (v6) ALLOW Anywhere (v6)
Kyllä tuo äkkiseltään näyttäisi olevan ihan oikein. Voit tietysti varmistaa asian logeista 'sudo ufw logging on' jos ei jo ole päällä. Oletuksena ufw:n logit löytynevät /var/log/syslog:sta.Äh, ei tuo certbot-himmeli sitten ihan putkeen mennytkään. Nyt ufw blokkaa yhteydet porttiin 3000, yritti sitten http:llä tai https:llä. Sama juttu portin 5000 kanssa. Yritin sallia nuo portit, mutta ei auta:
3000/tcp:täkin kokeilin yhtä laihoin tuloksin. Ilmeisestikin systeemi hyväksyy nyt vain 80- ja 443-portit.Koodi:$ sudo ufw status Status: active To Action From -- ------ ---- Nginx Full ALLOW Anywhere OpenSSH ALLOW Anywhere 3000 ALLOW Anywhere 5000 ALLOW Anywhere Nginx Full (v6) ALLOW Anywhere (v6) OpenSSH (v6) ALLOW Anywhere (v6) 3000 (v6) ALLOW Anywhere (v6) 5000 (v6) ALLOW Anywhere (v6)
sudo ss -l -t -u
komennolla vielä varmistat, että siellä joku on 3000/5000 porttia kuuntelemassa.Varsin mielenkiintoista. Ja varmaan ufw:n restart on tullut kokeiltua ?Juu, tsekkasin nimenomaan logeista ja siellä tuo blokkaus näkyi.
sudo ufw status verbose
antaa vähäsen lisää infoa tuohon statukseen, mutta en kyllä heti keksi, että mikä tuossa väärin voisi olla.$ sudo ss -l -t -u
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
udp UNCONN 0 0 127.0.0.53%lo:domain 0.0.0.0:*
udp UNCONN 0 0 135.181.155.80%eth0:bootpc 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.53%lo:domain 0.0.0.0:*
tcp LISTEN 0 128 0.0.0.0:ssh 0.0.0.0:*
tcp LISTEN 0 511 0.0.0.0:https 0.0.0.0:*
tcp LISTEN 0 80 127.0.0.1:mysql 0.0.0.0:*
tcp LISTEN 0 511 0.0.0.0:http 0.0.0.0:*
tcp LISTEN 0 128 [::]:ssh [::]:*
tcp LISTEN 0 511 [::]:https [::]:*
tcp LISTEN 0 511 [::]:http [::]:*
Njoo, reloadkin kelpaa, mutta itse olen ollut joskus menneisyydessä havaitsevinani ufw:n kanssa, että väkivaltainen restart hoitaa homman paremmin kotiin ja jäänyt tapa päälleTarkoitat varmaan reloadia? Juu.
Mutta sanoisin että kuuntelijat on:
Koodi:$ sudo ss -l -t -u Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process udp UNCONN 0 0 127.0.0.53%lo:domain 0.0.0.0:* udp UNCONN 0 0 135.181.155.80%eth0:bootpc 0.0.0.0:* tcp LISTEN 0 4096 127.0.0.53%lo:domain 0.0.0.0:* tcp LISTEN 0 128 0.0.0.0:ssh 0.0.0.0:* tcp LISTEN 0 511 0.0.0.0:https 0.0.0.0:* tcp LISTEN 0 80 127.0.0.1:mysql 0.0.0.0:* tcp LISTEN 0 511 0.0.0.0:http 0.0.0.0:* tcp LISTEN 0 128 [::]:ssh [::]:* tcp LISTEN 0 511 [::]:https [::]:* tcp LISTEN 0 511 [::]:http [::]:*
nationality = relationship(
'Country', foreign_keys=[nationality_id], uselist=False, viewonly=True)
@hybrid_property
def nationalityname(self) -> Union[str, None]:
if self.nationality:
return self.nationality.name
else:
return None
authors = relationship("Person",
secondary='join(Part, Contributor, Part.id == Contributor.part_id)',
primaryjoin='and_(Person.id == Contributor.person_id,\
Contributor.role_id == 1, Part.shortstory_id == ShortStory.id)',
uselist=True, order_by='Person.alt_name', viewonly=True,
foreign_keys=[Contributor.part_id, Contributor.person_id, Contributor.role_id])
@hybrid_property
def author_str(self) -> str:
if self._author_str != '':
return self._author_str
if len(self.authors) > 0:
self._author_str = ' & '.join([x.name for x in self.authors])
return self._author_str
Exception has occurred: AttributeError (note: full exception trace is shown but execution is paused at: nationalityname)
Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with Person.nationality has an attribute 'name'
if column == 'name':
if op == 'eq':
sql = sql + ' AND person.name = value'
else if op == 'ne':
sql = sql + ' AND person.name != value'
...
if column == 'dob':
if op == 'eq':
...
Jos korvaat sen ihan normaalilla checkboxilla, niin toimii ihan oikein. Eli tuo kirjasto käyttäytyy aika jännästi.Pitääpä kysellä Discordin puolelta sitten.
{
"Hoffmann, E. T. A.": [
{
author_str: "Hoffmann, E. T. A.",
bookseriesnum: "",
bookseriesorder: 0,
descr_attr: null,
description: null,
editions: [
{
coll_info: "",
coverimage: 1,
dustcover: 1,
editionnum: 1,
id: 3453,
images: [
],
imported_string: "\n<b>Kissa Murr</b>. (Lebensansichten des Katerns Murr, 1820-22). Suom Teijo Havu. Oy Suomen Kirja 1946. [F].",
isbn: "",
misc: "Oy Suomen",
pages: null,
printedin: null,
publisher: {
description: null,
fullname: "Valtion kustannusliike Oy Kirja",
id: 397,
image_attr: null,
image_src: null,
name: "Kirja",
},
pubseriesnum: null,
pubyear: 1946,
size: null,
subtitle: "",
title: "Kissa Murr",
version: null,
},
],
id: 3014,
imported_string: "\n<b>Kissa Murr</b>. (Lebensansichten des Katerns Murr, 1820-22). Suom Teijo Havu. Oy Suomen Kirja 1946. [F].",
misc: "Oy Suomen",
orig_title: "Lebensansichten des Katerns Murr",
pubyear: 1820,
subtitle: "",
title: "Kissa Murr",
},
// Leikattu neljä taulukon arvoa pois
],
}
let works: Record<string, IWork[]> = {};
{works && Object.entries(works).
sort((a, b) => a > b ? 1 : -1).map(([group, ws]) => {
<h3>{group}</h3>
{
ws.map((work: IWork) => (
<Work work={work} />
))
}
})}
map() toimii oikein vain jos palautat sieltä jotain. Sulla pitää olla siis return-lauseke siellä. Ja tähän lisähuomio, että nuolifunktiossa on implisiittinen return, jos käytät sen lyhyttä muotoa (eli ilman aaltosulkeita). Tuossa viestissäsi on aaltosulkeet eli nuolifunktiossa on ihan oma koodiblokkinsa, jolloin sulla on pakko olla siellä return jotta se tekee sen mäppäyksen oikein. Se puuttuu, joten koodi ei toimi.Siis eikö se ulomman mapin outputti ole tuossa [group, ws] -tuplessa?
const foobar = foo.map(x => <h3>x.bar</h3>); // OK, implisiittinen return
const foobar = foo.map(x => {
return <h3>x.bar</h3> // OK, eksplisiittinen return
});
Koodin yksinkertaistaminen vaikuttaa kahteen asiaan. 1. löydät ihan itse ne bugisi. 2. Me muut löydämme nopeammin ne bugisi. Pyri siis minimaaliseen hajoavaan esimerkkiin:Sortin poisto ei vaikuta asiaan
for(i=i;i<10;i++) {
doobedoo(i);
}
Kuten kirjoitin jo 2 kertaa, se auttaa muita ratkaisemaan sun ongelmasi kun et tuo tänne pitkiä koodinpätkiä vaan minimaalisia. Jos ei muuta, niin se on kohteliasta.Koodin yksinkertaistaminen ei olisi auttanut, koska en olisi älynnyt noita aaltosulkuja poistaa kuitenkaan / en olisi edelleenkään tajunnut että aaltosulut on se ongelma.
Ei toi vänkääminen tee asiasta yhtään sen järkevämpää. Sulla oli myös muutamakymmentä riviä inputtia, jonka olisi voinut typistää minimiin. Yhä edelleen, kannattaa sisäistää tämä:Minun esimerkkissäni oli 5 riviä koodia, en ajattelut että se olisi liian pitkä... tai oikeastaan varsinaista koodia on 3 riviä.
In computing, a minimal reproducible example (abbreviated MRE) is a collection of source code and other data files which allow a bug or problem to be demonstrated and reproduced. The important feature of a minimal reproducible example is that it is as small and as simple as possible, such that it is just sufficient to demonstrate the problem, but without any additional complexity or dependencies which will make resolution harder.
Ottaisin tuon Sf-bibliografia otsikon kokonaan pois. Tuo SuomiSF-teksti on liian lähellä noita navigaation linkkejä ja nuo alhaalla olevat kortit vaatii lisää paddingiä ympärilleen.Tällaista etusivua olen vähän hahmotellut. Ihan en ole tyytyväinen, mutta en osaa sanoa, että mitä pitäisi parantaa. Kenelläkään antaa vinkkejä?
Nyt ehkä vähän hassusti Share ja imgur ovat isoimmat tekstit leiskassa. SuomiSF voisi olla isoin elementti (ja ehkä tuo pelkkä sininen tausta tekstille on vähän kökkö. Menupalkki voisi olla ihan vaan yläreunassa, ellei tuohon tyhjään valkoiseen tilaan ole tarkoitus tulla jotain sisältöä.Tuon SuomiSF-tekstin olisi siis tarkoitus olla jonkunlainen kuva/logo.