-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathposts.ndjson
60 lines (60 loc) · 428 KB
/
posts.ndjson
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
{"_type":"post","_createdAt":"2013-12-23T00:04:00.000+01:00","publishedAt":"2013-12-23T00:04:00.000+01:00","title":"Megújulunk","body":[{"_type":"block","markDefs":[{"_key":"6db1fdb488b6","_type":"link","href":"http://jekyllrb.com/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Már régóta esedékes, hogy a blogunkon némi ráncfelvarrást eszközöljünk. Ennek fényében most egy egészen új irányba visszük el a blogot. Az eddigi wordpress-en futó oldalt lecseréljük és ezentúl "},{"_type":"span","marks":["6db1fdb488b6"],"text":"jekyll"},{"_type":"span","marks":[],"text":"-lel generált statikus tartalom lesz."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Sajnos jelenleg a régi blog tartalma nem elérhető, mert a domainünket áthoztuk wadonról brianre (az utóbbi a Kir-Dev szervere, amin a VIR is fut). A régi bejegyzéseket idővel át fogjuk menteni az új blogra."}]},{"_type":"block","markDefs":[{"_key":"67be207d4c50","_type":"link","href":"https://www.facebook.com/kirdevteam"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Nem csak külsőleg újulunk meg. Terveink szerint a jelenleg "},{"_type":"span","marks":["67be207d4c50"],"text":"facebookon"},{"_type":"span","marks":[],"text":" futó rovatok átkerülnek ide. Sőt remélhetőleg a számuk is rohamosan bővül majd. Egyelőre három rovat fut:"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"Dráma kedd"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"Security szombat"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"Frontend vasárnap"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A rovatok mellett természetesen megmarad a blog eddigi tájékoztató funkciója is. Az általunk üzemeltetett szolgáltatásokkal kapcsolatos hírek továbbra is megjelennek majd a blogon és a nagyobb frissítésekről részletesebb leírást is közlünk, ahogy eddig is."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://i.gifer.com/origin/59/5920cf7e6956dfb73d862478d4d00d1e.gif","alt":"null"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":["strong"],"text":"Boldog karácsonyt mindenkinek!"}]}]}
{"_type":"post","_createdAt":"2013-12-27T13:15:00.000+01:00","publishedAt":"2013-12-27T13:15:00.000+01:00","title":"Hexagonal Rails","body":[{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A bejgli mámor lassan múlik és kísérőnek mi lehetne jobb, mint egy előadás némi szoftver architektúráról. Ne ijesszen el senkit, hogy a címben a Railst említi. Ebben a fél órás előadásban vázolt irányok és ötletek bármilyen objektum orientált nyelven és környezetben használhatóak."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az benne az ijesztő, hogy félelmetesen egyszerű dolgokról van szó. Visszanyúl az OO egyik legelső építőkockájáig és új fénybe helyezi. Akár magadtól is rájöhettél volna, de az adatvezérelt tervezés és fejlesztés teljesen kitölti a látóteredet."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Érdemes elgondolkodni a előadásban elhangzottakon és megnézni, hogy hogyan tudnád átültetni ezeket a mindennapi fejlesztéseidbe."}]}]}
{"_type":"post","_createdAt":"2013-12-29T20:28:00.000+01:00","publishedAt":"2013-12-29T20:28:00.000+01:00","title":"Mi is az a DOM?","body":[{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ha vasárnap akkor újra front-end. Szeretnétek tudni, hogy mi az a DOM? A következő linken egy kis összefoglalást találhattok erről a különös de mégis hasznos modellről. Akinek pedig mindez nem elég annak az oldal alján további olvasnivalók is megbújnak."}]},{"_type":"block","markDefs":[{"_key":"3b045dba9cd8","_type":"link","href":"http://css-tricks.com/dom/"}],"style":"normal","children":[{"_type":"span","marks":["3b045dba9cd8"],"text":"What is the DOM?"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"További kellemes ünnepeket!"}]}]}
{"_type":"post","_createdAt":"2013-12-29T00:30:00.000+01:00","publishedAt":"2013-12-29T00:30:00.000+01:00","title":"PÉK 2.6.2 release","body":[{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ma éjjel frissítettük a PÉK alkalmazásunkat. Két kisebb hibát sikerült javítani:"}]},{"_type":"block","markDefs":[{"_key":"ffdc7ddc513e","_type":"link","href":"https://github.com/kir-dev/korok/issues/73"}],"style":"normal","level":1,"listItem":"number","children":[{"_type":"span","marks":[],"text":"A felhasználók szobák szerinti keresése nem működött, ha nagybetűt is tartalmazott a keresőkifejezés. Vonatkozó issue: "},{"_type":"span","marks":["ffdc7ddc513e"],"text":"#73"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"number","children":[{"_type":"span","marks":[],"text":"Az értékelés leadásnál lehetőség volt egy gyors dupla klikkel két értékelést létrehozni. Ez ahhoz vezetett, hogy az "},{"_type":"span","marks":["em"],"text":"Értékelések"},{"_type":"span","marks":[],"text":" oldal elérhetetlenné vált. Ez a hiba csak a körvezetőket érintette, de az értékelés leadási időszakban lehet, hogy megspórolunk ezzel pár izgalmas percet mindenkinek."}]},{"_type":"block","markDefs":[{"_key":"01a9aac14cec","_type":"link","href":"https://github.com/kir-dev/korok/tree/sch-pek-2.6.2"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az új verzió "},{"_type":"span","marks":["em"],"text":"2.6.2"},{"_type":"span","marks":[],"text":" és a hozzá tartozó kód elérhető githubon a "},{"_type":"span","marks":["01a9aac14cec"],"text":"sch-pek-2.6.2"},{"_type":"span","marks":[],"text":" tag alatt."}]}]}
{"_type":"post","_createdAt":"2014-01-03T22:00:00.000+01:00","publishedAt":"2014-01-03T22:00:00.000+01:00","title":"A HTML5 Boilerplate","body":[{"_type":"block","markDefs":[{"_key":"873064e5afc1","_type":"link","href":"http://html5boilerplate.com/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A HTML5 Boilerplate egy front-end template, amit arra találtak ki, hogy gyors, robusztus és alkalmazkodó weboldalakat tudj készíteni az új HTML5 funkcionalitásokkal. Ez egy nyílt forrású projekt, amit Paul Irish és Divya Manian készített és tökéletes arra, hogy valódi cross-browser weboldalakat hozz létre, amik működnek a régebbi verziókkal is. A projekt letölthető a "},{"_type":"span","marks":["873064e5afc1"],"text":"HTML5 Boilerplate"},{"_type":"span","marks":[],"text":" weboldaláról teljes csomagként vagy egy kisebb változatban, amely nem tartalmazza a dokumentációt. Az utóbbi csak azoknak ajánlott akik már dolgoztak vele korábban. A cikkben igyekszünk bemutatni a projekt képességeit."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Mi található a csomagban?"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Megtalálható minden olyan elem amelyre szükséged lehet a fejlesztés során beleértve a dokumentációkat is az egyes részekhez."}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"HTML"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"CSS"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"JavaScript"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":".htaccess (Apache web szerver konfiguráció)"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"crossdomain.xml"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"Egyéb (gitignore és hasonló fájlok)"}]},{"_type":"block","markDefs":[{"_key":"7a4e01a2de08","_type":"link","href":"http://modernizr.com/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A "},{"_type":"span","marks":["7a4e01a2de08"],"text":"Modernizr"},{"_type":"span","marks":[],"text":" (erről részletesebben egy másik bejegyzésben írunk majd) is megtalálható a csomagban ami képes detektálni a böngészők által támogatott HTML5 és CSS3 funkciókat. Segít abban is, hogy az oldal dizájnja alkalmazkodjon a böngésző képességeihez."}]},{"_type":"block","markDefs":[{"_key":"5fa08477f353","_type":"link","href":"http://necolas.github.io/normalize.css/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A "},{"_type":"span","marks":["5fa08477f353"],"text":"Normalize.css"},{"_type":"span","marks":[],"text":" betöltésével a böngészők sokkal konzisztensebben renderelik az oldalt. Csak azokat a stílusokat célozza meg amelyeket szükséges és a többit érintetlenül hagyja. Érdemes átnézni a tartalmát mivel ha bármilyen problémánk akad fejlesztés közben akkor jusson eszünkbe, hogy a saját stílusainkon kívűl ez is beleszól abba, hogyan jelenlenek meg az elemek."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Hogyan kezdd el használni?"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Általában egy weboldal készítése mindig azzal kezdődik, hogy létrehozod az alap struktúrát, feltöltöd tartalommal, stílust és funkcionalitásokat hozol létre majd pedig nekiállsz tesztelni. Itt kapsz készen egy ilyen struktúrát amit majd elkezdhetsz használni. Nézzük meg kicsit közelebbről:"}]},{"_type":"code","code":". ├── css │ ├── main.css │ └── normalize.css ├── doc ├── img ├── js │ ├── main.js │ ├── plugins.js │ └── vendor │ ├── jquery.min.js │ └── modernizr.min.js ├── .htaccess ├── 404.html ├── index.html ├── humans.txt ├── robots.txt ├── crossdomain.xml ├── favicon.ico ","language":"text"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A "},{"_type":"span","marks":["strong"],"text":"css"},{"_type":"span","marks":[],"text":" könyvtárban fogjuk tárolni az oldal összes "},{"_type":"span","marks":["code"],"text":"*.css"},{"_type":"span","marks":[],"text":" állományát. A "},{"_type":"span","marks":["code"],"text":"normalize.css"},{"_type":"span","marks":[],"text":" és "},{"_type":"span","marks":["code"],"text":"main.css"},{"_type":"span","marks":[],"text":" tartalmazzák a HTML5 Boilerplateben alapértelmezett stílusokat, általános segéd osztályokat, media query placeholdereket és print stílusokat."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A "},{"_type":"span","marks":["strong"],"text":"doc"},{"_type":"span","marks":[],"text":" könyvtárban találhatod a projekthez tartozó dokumentációkat illetve ajánlásokat, érdemes egyszer átolvasnod ezeket, hogy jobban kiigazodj a struktúrában illetve könnyebben tudd használni a fejlesztés során."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az "},{"_type":"span","marks":["strong"],"text":"img"},{"_type":"span","marks":[],"text":" könyvtárba helyezd az összes képet amelyet a weboldaladon meg akarsz majd jeleníteni. A későbbiekben könnyedén tudsz majd hivatkozni a mappában található képekre."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A "},{"_type":"span","marks":["strong"],"text":"js"},{"_type":"span","marks":[],"text":" mappában tárold az oldalon futó scripteket. A gyökerébe a saját scriptjeidet helyezd el míg a vendor könyvtárba azokat tedd amelyek egyéb forrásból származnak. Így könnyebb rendszerezni a fájlokat és nem lesz egy nagy ömlesztett átláthatatlan rengeteg."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A "},{"_type":"span","marks":["code"],"text":"*.html"},{"_type":"span","marks":[],"text":" fájlokat az egész struktúrának a gyökerében tárold, ezek lesznek azok az oldalak amelyeket majd a tartalom megjelenítésére fogsz használni. Ugyanitt található a "},{"_type":"span","marks":["code"],"text":"favicon.ico"},{"_type":"span","marks":[],"text":" (az a kis icon amit a böngésződ megjelenít pl.: a tabokon az oldal neve mellett) a "},{"_type":"span","marks":["code"],"text":"robots.txt"},{"_type":"span","marks":[],"text":" illetve a "},{"_type":"span","marks":["code"],"text":"humans.txt"},{"_type":"span","marks":[],"text":" is, amelyekből az előbbi a keresőrobotok számára szolgáltat információkat az oldalról, a második pedig információt tartalmaz azokról az emberekről akik a weboldal létrehozásában segítettek."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A számodra ismeretlen vagy nem használatos kódrészleteket nyugodtan kommentezd ki vagy töröld ha a továbbiakban már nem lesz szükéged rá. Amennyiben szükségesnek érzed nyugodtan módosíthatod ezeket a fájlokat (pl.: az eddig megszokott módszereiddel teljesen ellentétesen használ dolgokat) hiszen ez az egész inkább tekinthető egy ajánlásnak mint kőbe vésett betartandó szabályoknak amiken nem lehet módosítani."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Segéd CSS osztályok"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Nézzük az "},{"_type":"span","marks":["code"],"text":".ir"},{"_type":"span","marks":[],"text":" CSS osztályt (image replacement). Ezt az összes olyan elemnek a stílusához hozzáadhatod melyeket képekkel akarsz helyettesíteni. A szélességet és a magasságát kötelező megadni annak érdekében, hogy a kép látszódjon."}]},{"_type":"code","code":".ir { background-image: url(http://yoursite.com/images/logo.jpg); background-size: 100% auto; width: 450px; height: 450px; } ","language":"css"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A következő segéd CSS osztályokat foglalja magába a sablon:"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":["code"],"text":".hidden"},{"_type":"span","marks":[],"text":" (add hozzá azokhoz az elemekhez amelyeket el akarsz rejteni)"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":["code"],"text":".visuallyhidden"},{"_type":"span","marks":[],"text":" (elrejti a szöveget a böngészőben de a képernyő olvasók még látják)"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":["code"],"text":".invisible"},{"_type":"span","marks":[],"text":" (úgy rejti el az elemet, hogy közben nem befolyásolja az oldal felépítését)"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":["code"],"text":".clearfix"},{"_type":"span","marks":[],"text":" (biztosítja, hogy a lebegtetett ("},{"_type":"span","marks":["code"],"text":"float"},{"_type":"span","marks":[],"text":") gyereket az adott elem tartalmazza)"}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Hova írjam a kódomat?"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A projekt kommentezett így sok helyen ezeket a részeket megjelölték a készítők. A "},{"_type":"span","marks":["code"],"text":"main.css"},{"_type":"span","marks":[],"text":" fájlba egy kommentel van jelölve, hogy a saját stílusaidat hol definiáld:"}]},{"_type":"code","code":"/* ====================================================== Author's custom styles ====================================================== */ ","language":"text"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ugyanígy megvan az "},{"_type":"span","marks":["code"],"text":"index.html"},{"_type":"span","marks":[],"text":"-ben is, hogy hova kezdd el írni az oldaladnak a kódját:"}]},{"_type":"code","code":"<!-- Add your site or application content here --> ","language":"text"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az oldaladon futó JavaScript kódokat érdemes a "},{"_type":"span","marks":["code"],"text":"main.js"},{"_type":"span","marks":[],"text":" fájlba írni, ez a fájl teljesen üres. Mielőtt nekilátsz egy új projektnek mindenképp érdemes teljesen átnézned az egészet illetve elolvasnod a szükséges dokumentációkat is."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Media query"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A "},{"_type":"span","marks":["code"],"text":"main.css"},{"_type":"span","marks":[],"text":"-ben megtalálhatóak azok a placeholderek amelyek ahhoz kellenek, hogy különböző méretű képernyőket támogassunk (Reszponzív Web Design). A dokumentáció azt ajánlja, hogy az oldalad tartalmához igazodjanak ezek a media query-k és ne a képernyő méretének tükrében hozzuk őket létre. A \"mobile first\" megközelítés nagyon fontos viszont nem mindenki szeretné támogatni a különböző eszközöket. Ilyenkor csak egyszerűen vedd ki a placeholdert a CSS-ből."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A HTML5 Boilerplate egy remek template arra, hogy bármilyen új projektet elkezdj. Rengeteg böngésző létezik amelyekhez támogatást nyújt és egy vázat ahhoz, hogy weboldalakat hozz létre mobilra, tabletre és desktopra."}]}]}
{"_type":"post","_createdAt":"2014-01-05T04:03:00.000+01:00","publishedAt":"2014-01-05T04:03:00.000+01:00","title":"Modernizr","body":[{"_type":"block","markDefs":[{"_key":"c3bb3deffe46","_type":"link","href":"http://kir-dev.sch.bme.hu/2014/01/03/a-html5-boilerplate/"},{"_key":"dbea15ae26c2","_type":"link","href":"http://modernizr.com/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Pár napja olvashattatok a "},{"_type":"span","marks":["c3bb3deffe46"],"text":"HTML5 Boilerplate"},{"_type":"span","marks":[],"text":" cikkünkben a "},{"_type":"span","marks":["dbea15ae26c2"],"text":"Modernizr"},{"_type":"span","marks":[],"text":" JavaScript library-ról. A Modernizr-t (nem nincs benne typo) arra használjuk, hogy ellenőrizzük vele a felhasználó böngészőjének HTML5 és CSS3 képességeit. Remek érzés a böngészők legújabb funkcionalitásait használni mindaddig, amíg nem kell támogatni a régebbi verziókat is. A library az oldal betöltésekor gyorsan detektálja mire képes a kliens és az elérhető funkciókról információkat szolgáltat, amik lekérdezhetőek a saját scriptekben."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Hogyan használd?"}]},{"_type":"block","markDefs":[{"_key":"a6e49d89904f","_type":"link","href":"http://modernizr.com/download/#-fontface-backgroundsize-borderimage-borderradius-boxshadow-flexbox-hsla-multiplebgs-opacity-rgba-textshadow-cssanimations-csscolumns-generatedcontent-cssgradients-cssreflections-csstransforms-csstransforms3d-csstransitions-applicationcache-canvas-canvastext-draganddrop-hashchange-history-audio-video-indexeddb-input-inputtypes-localstorage-postmessage-sessionstorage-websockets-websqldatabase-webworkers-geolocation-inlinesvg-smil-svg-svgclippaths-touch-webgl-shiv-cssclasses-addtest-prefixed-teststyles-testprop-testallprops-hasevent-prefixes-domprefixes-load"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Először is töltsd le a scriptet a honlapjáról vagy közvetlenül "},{"_type":"span","marks":["a6e49d89904f"],"text":"innen"},{"_type":"span","marks":[],"text":". Az oldalad "},{"_type":"span","marks":["code"],"text":"<head>"},{"_type":"span","marks":[],"text":" részében töltsd be a letöltött scriptet."}]},{"_type":"code","code":"<script src=\"modernizr.min.js\" type=\"text/javascript\"></script> ","language":"html"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A következő lépésben add hozzá a "},{"_type":"span","marks":["code"],"text":"no-js"},{"_type":"span","marks":[],"text":" class-t a "},{"_type":"span","marks":["code"],"text":"<html>"},{"_type":"span","marks":[],"text":" taghez."}]},{"_type":"code","code":"<html class=\"no-js\"></html> ","language":"html"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Joggal kérdezhetitek, hogy miért adjuk hozzá ezt a class-t. Ez lesz az alapértelmezett állapota az oldalnak. Ha a Javascript (js) nincs engedélyezve, a Modernizr egyáltalán nem fog működni (sőt talán más funkciói sem az oldaladnak) ezért jó, hogy ha van egy fallback erre az esetre. Ha a JavaScript engedélyezve van, akkor az oldal betöltése után a class dinamikusan lecserélődik a támogatott funkciókra. Vizsgáld meg az oldal forrását (dev toolbarban), valahogy így kell kinézzen:"}]},{"_type":"code","code":"<html class=\"js canvas canvastext geolocation rgba hsla no-multiplebgs borderimage borderradius boxshadow opacity no-cssanimations csscolumns no-cssgradients no-cssreflections csstransforms no-csstransforms3d no-csstransitions video audio cufon-active fontface cufon-ready\" ></html> ","language":"html"},{"_type":"block","markDefs":[],"style":"h3","children":[{"_type":"span","marks":[],"text":"Mit jelent ez a sok kifejezés?"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Azok a támogatott funkciók, amelyek előtt nem található meg a "},{"_type":"span","marks":["code"],"text":"no"},{"_type":"span","marks":[],"text":" prefix. A Modernizr által visszaadott információk alapján el tudjuk dönteni, hogy például a css színátmeneteket használhatjuk vagy sem: "},{"_type":"span","marks":["code"],"text":"no-cssgradients"},{"_type":"span","marks":[],"text":" - láthatjuk, hogy jelen esetben nem támogatott ez a funkció. Egy példa a hivatalos dokumentációból:"}]},{"_type":"code","code":"/* In your CSS: */ .no-audio #music { display: none; /* Don't show Audio options */ } .audio #music button { /* Style the Play and Pause buttons nicely */ } ","language":"css"},{"_type":"code","code":"<!-- In your HTML: --> <div id=\"music\"> <audio> <source src=\"audio.ogg\" /> <source src=\"audio.mp3\" /> </audio> <button id=\"play\">Play</button> <button id=\"pause\">Pause</button> </div> ","language":"html"},{"_type":"block","markDefs":[],"style":"h3","children":[{"_type":"span","marks":[],"text":"Modernizr.load()"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A "},{"_type":"span","marks":["code"],"text":"Modernizr.load"},{"_type":"span","marks":[],"text":" használható arra is, hogy JavaScript fájlokat töltsünk be. Nézzünk meg egy példát erre is:"}]},{"_type":"code","code":"Modernizr.load({ test: Modernizr.geolocation, yep: 'geo.js', nope: 'geo-polyfill.js' }) ","language":"js"},{"_type":"block","markDefs":[{"_key":"f2145d3c7d26","_type":"link","href":"https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ebben a példában különböző scripteket töltünk be annak függvényében, hogy a böngésző támogatja-e a "},{"_type":"span","marks":["code"],"text":"test"},{"_type":"span","marks":[],"text":"-ben található funkciót. Ezzel azt érheted el, hogy a felhasználók számára nem működő felesleges kódokat nem kell betöltened, ezáltal növeli a teljesítményét az oldalnak. Szerencsére ez semmit nem lassít a betöltésen és néha még gyorsíthat is rajta, mert a betöltés aszinkron módon történik, párhuzamosan. További érdekesség a "},{"_type":"span","marks":["code"],"text":"-polyfill"},{"_type":"span","marks":[],"text":" suffix. Ezek általában olyan scripteket jelölnek, amelyek különböző funkcionalitásokat állítanak helyre vagy nyújtanak a régebbi böngészőkben (HTML5 fallbackkel). Akiket érdekelnek ezek a scriptek a Modernizr "},{"_type":"span","marks":["f2145d3c7d26"],"text":"GitHub repojában"},{"_type":"span","marks":[],"text":" megtalálhatóak."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"HTML5"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A Modernizr lehetővé teszi, hogy használd az új HTML5 elemeket (header, hgroup, footer, video stb.) és stílusokat adj nekik. Ez nem jelenti azt, hogy hirtelen minden HTML5 specifikus elem működni kezd IE-ben, de tudsz hozzájuk stílusokat rendelni, az IE megérti ezeket és nem fogja eldobni őket. Betöltés közben egy kicsi JavaScript kódot futtat a háttérben, hogy beállítsa az elemeket."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"JavaScript"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"JavaScriptből is vizsgálhatod a különböző funkciókat. Elég egy feltételt írnod és máris láthatod, hogy az adott funkció támogatott-e:"}]},{"_type":"code","code":"if (Modernizr.audio) { /* properties for browsers that support audio */ } else { /* properties for browsers that does not support audio */ } ","language":"js"},{"_type":"block","markDefs":[{"_key":"88d208bcde95","_type":"link","href":"http://modernizr.com/docs/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A "},{"_type":"span","marks":["88d208bcde95"],"text":"hivatalos dokumentációban"},{"_type":"span","marks":[],"text":" elolvasható az összes ellenőrizhető tulajdonság ami CSS-ből vagy JavaScriptből haszálható."}]}]}
{"_type":"post","_createdAt":"2014-01-06T22:45:00.000+01:00","publishedAt":"2014-01-06T22:45:00.000+01:00","title":"Hogy is van ez az új Kir-Dev blog?","body":[{"_type":"block","markDefs":[{"_key":"d1b60d41e822","_type":"link","href":"/post/2013-12-23-megujulunk"},{"_key":"c4b137bf0c21","_type":"link","href":"http://jekyllrb.com/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Már az "},{"_type":"span","marks":["d1b60d41e822"],"text":"első bejegyzésben"},{"_type":"span","marks":[],"text":" is említettem, hogy az új blogunkat a "},{"_type":"span","marks":["c4b137bf0c21"],"text":"Jekyll"},{"_type":"span","marks":[],"text":" blog \"motor\" hatja."}]},{"_type":"block","markDefs":[{"_key":"051da71799bb","_type":"link","href":"http://staticsitegenerators.net/"},{"_key":"1ad0ecdadf13","_type":"link","href":"https://github.com/kir-dev/kir-dev.sch.bme.hu"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A statikus oldalakat generáló eszközök a "},{"_type":"span","marks":["051da71799bb"],"text":"fénykorukat élik"},{"_type":"span","marks":[],"text":" manapság. Ahogy nevük is utal rá, ezek az eszközök egy statikus HTML-ekből álló oldalt generálnak. Képesek sablonokat és bejegyzéseket is kezelni (ha nem tudnának, akkor nem sok értelmük lenne...). Elég ha a mi "},{"_type":"span","marks":["1ad0ecdadf13"],"text":"blogunk repoját"},{"_type":"span","marks":[],"text":" nézzük. Pár HTML fájl és egy kitüntettet "},{"_type":"span","marks":["code"],"text":"_posts"},{"_type":"span","marks":[],"text":" mappa. Ennyi az egész, a dolgok nehezét pedig rábízzuk pár automatizált eszközre."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Ötlettől a publikálásig"}]},{"_type":"block","markDefs":[{"_key":"13647075c963","_type":"link","href":"https://github.com/kir-dev/kir-dev.sch.bme.hu/blob/master/README.md"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ha belenéztek a "},{"_type":"span","marks":["13647075c963"],"text":"README"},{"_type":"span","marks":[],"text":" fájlunkba, akkor láthatjátok, hogy egy új bejegyzést nem sokkal bonyolultabb megírni és publikálni, mint egy klasszikus blog esetén."}]},{"_type":"block","markDefs":[{"_key":"4fb6409783a0","_type":"link","href":"http://git-scm.com/book/en/Customizing-Git-Git-Hooks"},{"_key":"9a3919a7bc8f","_type":"link","href":"https://help.github.com/articles/post-receive-hooks"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A történet azután kezd érdekes lenni, hogy egy bejegyzés bekerül a "},{"_type":"span","marks":["code"],"text":"master"},{"_type":"span","marks":[],"text":" branch-re. Léteznek úgynevezett "},{"_type":"span","marks":["4fb6409783a0"],"text":"hookok githez is"},{"_type":"span","marks":[],"text":". Miután a reponk a Githubon van, így nincs közvetlen hozzáférésünk a ezekhez, de szerencsére a Github ezt is elegánsan "},{"_type":"span","marks":["9a3919a7bc8f"],"text":"megoldotta"},{"_type":"span","marks":[],"text":"."}]},{"_type":"block","markDefs":[{"_key":"d05850e93e45","_type":"link","href":"https://github.com/adeven/gohub"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Egy webhook beregisztrálásával minden "},{"_type":"span","marks":["code"],"text":"push"},{"_type":"span","marks":[],"text":"-ról értesülünk. A webhooknak egy URL-t kell megadni, amit meg tud hívni (a részletek ez előző linken találhatóak). Itt jön képbe egy újabb kis eszköz. A "},{"_type":"span","marks":["d05850e93e45"],"text":"gohub"},{"_type":"span","marks":[],"text":" nevű mini webszerver, ami figyeli a beérkező hívásokat (nyugi, csak bizonyos IP-kről:) és egy shell parancsot futtat le. Esetünkben ez az oldal teljes újragenerálása, amit aztán Apache-on keresztül szolgálunk ki."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Lényegében tehát a következő történik:"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"number","children":[{"_type":"span","marks":[],"text":"megszületik az új bejegyzés"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"number","children":[{"_type":"span","marks":[],"text":"a "},{"_type":"span","marks":["code"],"text":"master"},{"_type":"span","marks":[],"text":" branch-be push-oljuk"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"number","children":[{"_type":"span","marks":[],"text":"a szerverünkre beesik egy kérés a Githubtól, jelezve, hogy valami történt"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"number","children":[{"_type":"span","marks":[],"text":"lehúzzuk a változtatásokat"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"number","children":[{"_type":"span","marks":[],"text":"automatikusan újra legeneráljuk az oldalt"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"number","children":[{"_type":"span","marks":[],"text":"profit"}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"De mégis miért jó ez?"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A statikus HTML-eknek több előnye is van. A kiszolgálásuk minimális erőforrást igényel és egy Apache-ot beállítani sem túl bonyolult. Nem kell adatbázisokkal és biztonsági mentésekkel bajlódni. Az utóbbiról a git és a Github gondoskodik számunkra. Ezen kívül a blogmotor frissítésével sem kell bajlódni. Nem kell HTTPS és a támadási felületet is minimalizáljuk."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Tagadhatatlan, hogy egy ilyen blog beállítása több kezdeti ráfordítást igényel, de hosszú távon sokkal kevesebb karbantartási munka van vele."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az már csak hab a tortán, hogy az új bejegyzések átnézése és javítása sokkal könnyebbé vált. Az előző Wordpress nem biztosított semmilyen eszközt az együttműködésre a git pedig pont erre van. :)"}]}]}
{"_type":"post","_createdAt":"2014-01-07T23:54:00.000+01:00","publishedAt":"2014-01-07T23:54:00.000+01:00","title":"Böngéssz Pythonban!","body":[{"_type":"block","markDefs":[{"_key":"e2d43d13c0ab","_type":"link","href":"http://wwwsearch.sourceforge.net/mechanize/"},{"_key":"1af89c4ebbcc","_type":"link","href":"http://www.crummy.com/software/BeautifulSoup/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ideje elvinni kicsit más irányba is a blog tartalmát, mivel az utóbbi időben jóformán csak front-end téma került elő. Mindig is foglalkoztatott az, hogy programozottan tudjam böngészni az világhálót. Ne gondoljunk rögtön a teljes internetet bejáró robotra, ezt a feladatot hagyjuk meg a Google-nek. Mi csak egy oldalra koncentrálunk erről szeretnénk lekérni, kiolvasni a tartalmát, megnézni a linkeket, letölteni róla egy-két fájlt, esetleg formokat kitölteni és elküldeni. A segítségünkre lesz a Python mint script nyelv és két modulja; a "},{"_type":"span","marks":["e2d43d13c0ab","em"],"text":"mechanize"},{"_type":"span","marks":[],"text":", és a "},{"_type":"span","marks":["1af89c4ebbcc","em"],"text":"BeautifulSoup"},{"_type":"span","marks":[],"text":". Előbbivel egy böngészőt tudunk szimulálni, utóbbival pedig a HTML oldal elemeit tudjuk feldolgozni."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"mechanize"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Programozott webböngészést tesz lehetővé és képes a böngésző állapotainak a megvalósítására is: navigációs előzmények, HTML form állapotok, cookie-k stb. A "},{"_type":"span","marks":["em"],"text":"mechanize"},{"_type":"span","marks":[],"text":" Andy Lester Perlben írt WWW::Mechanize moduljának Python átirata."}]},{"_type":"block","markDefs":[],"style":"h3","children":[{"_type":"span","marks":[],"text":"Lássuk azt a böngészőt!"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Kifejezetten egyszerű használni a modult, nincs is más dolgunk mint importálni és meghívni a megfelelő függvényeket, amelyek mondhatni önmagukért beszélnek."}]},{"_type":"code","code":"import mechanize import cookielib br = mechanize.Browser() cj = cookielib.LWPCookieJar() br.set_cookiejar(cj) ","language":"python"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Kész is a böngészőnk! Nem is olyan nehéz, és a következőkben ennél csak könnyebb lesz. Mielőtt tovább mennénk, nézzük meg mi történik. Gyakorlatilag létrejön egy "},{"_type":"span","marks":["code"],"text":"Browser"},{"_type":"span","marks":[],"text":" objektumunk és a "},{"_type":"span","marks":["code"],"text":"cookielib"},{"_type":"span","marks":[],"text":" lesz a felelős a "},{"_type":"span","marks":["code"],"text":"Browser"},{"_type":"span","marks":[],"text":" által tárolt cookiek (sütik) kezeléséért. Ez az objektum olyan, mint egy grafikus felület nélküli böngésző. Megvannak a szükséges metódusai, amiket ha kivezetnénk egy felhasználói felületre, akkor egy kész böngészőt kapnánk. Mielőtt még elmerülünk a programozott böngészés világában, nézzük meg milyen beállítási lehetőségei vannak az objektumunknak:"}]},{"_type":"code","code":"# Browser beállítások br.set_handle_equiv(True) br.set_handle_gzip(True) br.set_handle_redirect(True) br.set_handle_referer(True) br.set_handle_robots(False) # Frissítések br.set_handle_refresh(mechanize._http.HTTPRefreshProcessor(), max_time=1) # Debug üzenetek #br.set_debug_http(True) #br.set_debug_redirects(True) #br.set_debug_responses(True) # User-Agent (egy kis csalás :]) br.addheaders = [('User-agent', 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008071615 Fedora/3.0.1-1.fc9 Firefox/3.0.1')] ","language":"python"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A legtöbb egyértelmű, de az utolsó érdekes. A "},{"_type":"span","marks":["code"],"text":"User-Agent"},{"_type":"span","marks":[],"text":" gyakorlatilag egy szoftver, ami a felhasználó nevében tevékenykedik. A böngészőkben, az e-mail kliensekben mind megtalálható. Nagyon sok esetben a User-Agent kliensként viselkedik egy hálózati protokollban a kommunikáció során - például a kliens-szerver architektúrában."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A fentieket ismerve elkezdhetünk játszani a böngészőnkkel. Van egy "},{"_type":"span","marks":["code"],"text":"open(url)"},{"_type":"span","marks":[],"text":" metódusa, amivel oldalakat tudsz megnyitni majd a "},{"_type":"span","marks":["code"],"text":"response()"},{"_type":"span","marks":[],"text":" függvényéből kapjuk meg a választ. Az "},{"_type":"span","marks":["code"],"text":"open()"},{"_type":"span","marks":[],"text":" után közvetlenül meghívva a "},{"_type":"span","marks":["code"],"text":"response().read()"},{"_type":"span","marks":[],"text":" függvényeket láthatjuk a letöltött oldal forrását. A "},{"_type":"span","marks":["code"],"text":"title()"},{"_type":"span","marks":[],"text":" függvénnyel ki tudjuk írni az oldal címét, az "},{"_type":"span","marks":["code"],"text":"info()"},{"_type":"span","marks":[],"text":" függvénnyel a header tartalmát tudjuk megnézni és így tovább. Az oldalon található formokat a "},{"_type":"span","marks":["code"],"text":"forms()"},{"_type":"span","marks":[],"text":" függvénnyel tudjuk lekérni ami egy listát szolgáltat a formok neveivel. Nézzük meg mennyire egyszerű kiválasztani egy formot!"}]},{"_type":"code","code":"# egy oldal letöltése url = \"http://kir-dev.sch.bme.hu\" response = br.open(url) html = br.response().read() print html # Listázza a formokat for f in br.forms(): print f # Kiválasztjuk az első formot br.select_form(nr=0) # A form egy mezőjébe beleírunk valamit majd submitoljuk br.form['q']='random stuff' br.submit() # koilvassuk a kapott választ print br.response().read() ","language":"python"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Remek, de azért egy weboldal több dologból áll, mint puszta formok tömkelegéből. Mindenre van megoldás, követni tudjuk a linkeket, le tudunk tölteni fájlokat, a lehetőségeknek csak a képzeleted szab határt. A letöltésnél vigyázzunk, mert sok helyen a direkt linkeknél ha nincs beállítva a cookie kezelése, akkor feldobhat "},{"_type":"span","marks":["code"],"text":"captchat"},{"_type":"span","marks":[],"text":" a cél oldal (ellenőrző mezők, hogy nem robot vagy-e, itt az a baj, hogy lényegében az vagy). Ezeket a linkeket nem a "},{"_type":"span","marks":["code"],"text":"retrive()"},{"_type":"span","marks":[],"text":" függvénnyel kell letölteni hanem ténylegesen rá is kell kattintani a "},{"_type":"span","marks":["code"],"text":"click_link()"},{"_type":"span","marks":[],"text":" függvénnyel. Ilyenkor ellenőrzésre kerül a már említett cookie tartalma, és máris hozzá tudunk férni a letöltendő fájlhoz (elképzelhető, hogy nem cookie-val van megoldva, ez csak egy megoldás a sok lehetséges közül). A linkeket is lehetőségünk van ugyanúgy kilistázni akárcsak a formokat: "},{"_type":"span","marks":["code"],"text":"for link in br.links(regex)"},{"_type":"span","marks":[],"text":"!"}]},{"_type":"code","code":"# A link létezésének a vizsgálata br.find_link(text='kir-dev') # Ténylegesen rákattintunk a linkre req = br.click_link(text='kir-dev') br.open(req) print br.response().read() print br.geturl() # Vissza br.back() print br.response().read() print br.geturl() # Letöltés f = br.retrieve('kir-dev.sch.bme.hu/eznemletezik.gif')[0] print f fh = open(f) ","language":"python"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Arra is képes, hogy proxy-t állítsunk be a böngészőnek!"}]},{"_type":"code","code":"# Proxy és felhasználónév/jelszó br.set_proxies({\"http\": \"joe:[email protected]:3128\"}) # Proxy br.set_proxies({\"http\": \"myproxy.example.com:3128\"}) # Proxy jelszó br.add_proxy_password(\"joe\", \"password\") ","language":"python"},{"_type":"block","markDefs":[{"_key":"c10867bcab85","_type":"link","href":"http://en.wikipedia.org/wiki/Breadth-first_search"},{"_key":"5df019170080","_type":"link","href":"http://en.wikipedia.org/wiki/Depth-first_search"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A mechanize egy nagyon hasznos eszköz tud lenni a megfelelő ember kezében, képes automatizáltan böngészni a weboldalt, magára az oldalra tekinthetünk egy nagy gráfként, ahol az oldalak a csomópontok, és az élek az oldalon található linkek. Innentől az egésznek a bejárása gyerekjáték a már tanult módszerekkel (segítség: "},{"_type":"span","marks":["c10867bcab85"],"text":"BFS"},{"_type":"span","marks":[],"text":", "},{"_type":"span","marks":["5df019170080"],"text":"DFS"},{"_type":"span","marks":[],"text":")."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"BeautifulSoup"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Képes parse-olni a HTML és XML fájlokat, beleértve az aszimmetrikus tageket is. A segítségével képesek vagyunk feldolgozni a HTML oldalt, keresni benne különböző elemeket (figyelembe véve az attribútumokat is), ezeknek a tartalmát kiszedni, linkeket keresni stb. Érdemes együtt használni a mechanize modullal. Miután a mechanize-zal megnyitottunk egy weboldalt a forrását át kell adjuk a BeautifulSoupnak:"}]},{"_type":"code","code":"response = br.open(url) html = br.response().read() soup = BeautifulSoup.BeautifulSoup(html) ","language":"python"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Innentől kereshetünk az oldalon bármire:"}]},{"_type":"code","code":"soup.findAll('td', attrs={\"class\": \"prodSpecAtribute\"}) # linkek megkeresése az oldalon links = soup.findAll(\"a\") for link in links: print link.contents[0], link.get(\"href\") ","language":"python"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Összességében két nagyon jól elkészített modulról van szó, amelyek képesek megkönnyíteni az életünket, ha már ilyen dolgokba kell belevágnunk. Magára a böngészésre a mechanize modult érdemes használni és az egyéb információk kinyerésére pedig a BeautifulSoupot. Böngésszetek programozottan!"}]}]}
{"_type":"post","_createdAt":"2014-01-20T22:45:00.000+01:00","publishedAt":"2014-01-20T22:45:00.000+01:00","title":"PÉK (majdnem 2.6.3) release","body":[{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A PÉK-et ("},{"_type":"span","marks":["strong"],"text":"P"},{"_type":"span","marks":[],"text":"rofil "},{"_type":"span","marks":["strong"],"text":"é"},{"_type":"span","marks":[],"text":"s "},{"_type":"span","marks":["strong"],"text":"K"},{"_type":"span","marks":[],"text":"örök) a legtöbben a félév végi értékelésleadási időszakban használják, ilyenkor fokozottan próbálunk figyelni a jelentkező hibákra és felhasználói visszajelzésekre."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az utóbbi időben többször is frissítettük az alkalmazást, javítva a jelentkező hibákat. Volt néhány érdekes is, de többnyire apró, a felhasználóknak kellemetlen problémák jelentkeztek."}]},{"_type":"block","markDefs":[{"_key":"6376dab44589","_type":"link","href":"https://github.com/kir-dev/korok/compare/sch-pek-2.6.2...60e0dfa66e7c12722188108159c1c50402ee0e90"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A legutolsó hivatalos release óta "},{"_type":"span","marks":["6376dab44589"],"text":"itt tekinthetitek meg"},{"_type":"span","marks":[],"text":" az elvégzett javításokat."}]},{"_type":"block","markDefs":[{"_key":"51faf3e782b1","_type":"link","href":"https://github.com/kir-dev/korok/issues/82"},{"_key":"8a6e117a42e7","_type":"link","href":"https://korok.sch.bme.hu/korok/showgroup/id/18"},{"_key":"b8b01457b11d","_type":"link","href":"https://profile.sch.bme.hu/profile/show/uid/balo"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A "},{"_type":"span","marks":["51faf3e782b1"],"text":"legérdekesebb hiba"},{"_type":"span","marks":[],"text":" nem szerepel a fenti összefoglalóban. Hosszabb nyomozás után kiderült, hogy konfigurációs problémáról van szó. Az "},{"_type":"span","marks":["8a6e117a42e7"],"text":"SSSL"},{"_type":"span","marks":[],"text":" olyan nagy kör, hogy az értékelés leadásnál a formon több, mint 512 mező volt. Az 512 azért fontos szám, mert a szerver csak ennyi HTTP POST paramétert tartott meg, a többit levágta. Valószínűleg az ilyen módon törölt paraméterek között volt a bejelentkezett felhasználó azonosítója is, így a rendszer nem engedte, hogy a formot beküldhesse, mert úgy érzékelte, mintha nem lenne bejelentkezve. Az ezzel a hibával kapcsolatos éjszakákba nyúló hibakeresést köszönöm "},{"_type":"span","marks":["b8b01457b11d"],"text":"balonak"},{"_type":"span","marks":[],"text":"."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A következő pár hétben még várható pár kisebb-nagyobb átalakítás, a munka főleg a backend oldalon zajlik. A PÉK-kel kapcsolatos jövőbeli terveinket hamarosan egy hosszabb bejegyzésben is kifejtem majd."}]}]}
{"_type":"post","_createdAt":"2014-01-22T20:30:00.000+01:00","publishedAt":"2014-01-22T20:30:00.000+01:00","title":"Egy kicsit a biztonságról","body":[{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Egy weboldal nagyon hasznos annak a közösségnek, akik mindennap használják az általa nyújtott szolgáltatásokat. Egy felhasználói közösséget nagyon nehéz és időigényes felépíteni, viszont a szolgáltatás gyakori kiesésével könnyedén, percek alatt porig lehet rombolni az eddigi munkánknak az eredményét. A felhasználók nem szeretik, ha nem tudják elérni a megszokott funkciókat és a barátaikat, mert valamilyen hiba lépett fel, vagy az oldal ismeretlen okból nem üzemel megfelelően. A kódban található rengeteg hiba mellett (amelyek kiesésekhez vezethetnek) létezik egy sokkal nagyobb probléma is. Egy támadó az oldal mögött található erőforrásokhoz próbálhat hozzáférni, hogy személyes adatokhoz, vagy magához a szerverhez szerezzen részleges, esetleg teljes hozzáférést. Ebben a cikkben egy-két webes sérülékenységekre koncentrálunk és szeretnénk egy kis bevezetést adni a létező támadási formákba illetve az ezekkel szembeni védekezésbe."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"A jó öreg SQL Injection"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az SQL Injection egy kód futtatási technika adatbázist használó alkalmazások támadására. Rosszindulatú SQL kódot írnak be egy beviteli mezőbe, ami majd később végrehajtódik a szerver oldalon. Ez akkor fordulhat elő, hogyha a beviteli mezőben nem szűrjük a megfelelő karaktereket és ezek belekerülnek az SQL kifejezésbe. A megoldás az, hogyha az ilyen karaktereket kiszűrjük a bevitt adatokból, tehát a beviteli mezők validációjával illetve prepared statementek használatával ez a sebezhetőség elkerülhető. Nézzünk egy nagyon egyszerű példát:"}]},{"_type":"code","code":"sql_statement = \"SELECT * FROM users WHERE name='\" + user_name + \"';\" ","language":"sql"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ez az SQL kifejezés a "},{"_type":"span","marks":["code"],"text":"users"},{"_type":"span","marks":[],"text":" táblából kikeresi azt a felhasználót amelyiknek a felhasználó neve megegyezik a "},{"_type":"span","marks":["code"],"text":"user_name"},{"_type":"span","marks":[],"text":" változó tartalmával. Ha viszont egy rosszindulatú felhasználó SQL kódot ír a beviteli mezőbe akkor ez a lekérdezés másképpen fog kiértékelődni."}]},{"_type":"code","code":"' or '1'='1 ","language":"sql"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Amennyiben ez a kódrészlet kerül a "},{"_type":"span","marks":["code"],"text":"user_name"},{"_type":"span","marks":[],"text":" változóba, akkor a kifejezésünk igazként fog kiértékelődni mivel az 1=1 mindig teljesülni fog. A végén pedig így néz majd ki a végrehajtott lekérdezésünk:"}]},{"_type":"code","code":"SELECT * FROM users WHERE name = '' OR '1'='1'; ","language":"sql"},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"XSS - Cross-site scripting"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az XSS lehetőséget nyújt kliens oldali szkriptek beszúrására a weboldalba, ami egy másik felhasználó számára fog megjelenni. Egy tipikus XSS támadásban a támadó egy legitim webalkalmazásba rosszindulatú kliens oldali scriptet helyez el."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBQQT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--5165e870c6bf77488ff82472fb5bf24fe6e26c76/xss.png","alt":"null"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Amikor egy felhasználó meglátogatja a weboldalt akkor a böngészőjében ez a szkript letöltődik és végrehajtódik (gyakorlatilag itt történik meg ténylegesen a beszúrás) és ezek után már a támadó által elhelyezett szkript fog futni a felhasználó böngészőjében. Legtöbbször a "},{"_type":"span","marks":["code"],"text":"<script>"},{"_type":"span","marks":[],"text":" az "},{"_type":"span","marks":["code"],"text":"<img>"},{"_type":"span","marks":[],"text":" és az "},{"_type":"span","marks":["code"],"text":"<iframe>"},{"_type":"span","marks":[],"text":" elemeket támadják. Például a beviteli mezőbe ezt írják be:"}]},{"_type":"code","code":"<script> alert('XSS') </script> ","language":"html"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ezek a szkriptek akár egy egyszerű form elküldésével is felkerülhetnek az oldalra, de komplexebb útvonalon is eljuthatnak a célhoz JSON, vagy XML Web Service-en keresztül. Kétféle megoldás is létezik. Az egyik az, hogy itt is a beviteli mezőkben található adatokat megfelelően ellenőrizzük, amelyben például figyelünk a "},{"_type":"span","marks":["code"],"text":"<script>"},{"_type":"span","marks":[],"text":" tagekre, JavaScript parancsokra, CSS stílusokra és egyéb veszélyes HTML elemekre. A másik pedig az, hogy az outputot kódoljuk. Ilyenkor ha az injektált kódunk a következő: "},{"_type":"span","marks":["code"],"text":"<script>alert(\\\"abc\\\")</script>"},{"_type":"span","marks":[],"text":" akkor a kimeneten megfelelően kell kódolni:"}]},{"_type":"code","code":"<script>alert("abc")</script> ","language":"html"},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"CSRF vagy XSRF - Cross-Site Request Forgery"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A fenti két mozaikszó egyenértékű de sokszor a Sea-Surf kifejezéssel is hivatkoznak erre a sérülékenységre. Míg az XSS-nél a felhasználó weboldalba fektetett bizalmát használták ki addig a CSRF-nél a weboldalnak a felhasználó böngészőjébe fektetett bizalmát használják ki. Az egész arra megy ki, hogy az áldozat rámenjen egy másik weboldalra vagy rákattintson egy URL-re ami rosszindulatú jogosulatlan kéréseket tartalmaz. Az áldozat személyében és jogaival hajtanak végre olyan cselevéseket amelyet a támadó szeretne. Ilyen egy form elküldésének a részletei, vásárlások és fizetések lebonyolítása a támadó számára egy harmadik féltől származó felhasználói fiókon keresztül."}]},{"_type":"block","markDefs":[],"style":"h3","children":[{"_type":"span","marks":[],"text":"Egy egyszerű példa"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ahhoz, hogy végre lehessen hajtani a CSRF támadást a felhasználónak már előtte be kell jelentkeznie a cél oldalra. Feltételezve, hogy az áldozat már autentikálta magát a támadó elhelyez egy linket vagy szkriptet egy másik weboldalra, amit a felhasználó meglátogathat. Így amikor rákattint a másik weboldalra vagy linkre, egy rosszindulatú szkript végrehajtódik anélkül, hogy a felhasználó erről bármi tudomást szerezne. Nézzük meg a következő példát:"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Van egy chat alkalmazás, ahol a támadó egy üzenetet küld egy "},{"_type":"span","marks":["code"],"text":"<img>"},{"_type":"span","marks":[],"text":" taggel. Viszont a forrás attribútumban nem a kép forrása található, hanem egy link ami egy átutalási műveletet hajt végre az áldozat banki felhasználói fiókjával."}]},{"_type":"code","code":"<img src=\"http://bank.example.com/withdraw?account=bob&amount=1000000&for=Fred\" /> ","language":"html"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ez a CSRF támadás a HTTP GET kérést használja ki ugyanakkor lehetőség van a HTTP POST kérések támadására is. Ennek a támadásnak a megelőzésére kitalálták a tokenek használatát. A tokenek hosszú kriptográfiai értéket tartalmaz amelyeket nehéz kitalálni. Ezt akkor generálják, amikor a felhasználói session kezdődik és ehhez a sessionhöz lesz hozzárendelve ez a token. Ez a challange (kihívás) token minden kéréshez hozzá lesz csatolva, amit a szerver használ arra, hogy ellenőrizze a legitimitását a végfelhasználói kéréseknek."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Denial-of-service egyszerűbben DoS"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"\"If everything else fails...\" - ez az egyik legrosszabb támadás típus. Arra irányul, hogy használhatatlanná tegyen egy szervert, vagy egy hálózati erőforrást a felhasználói számára. Akkora mennyiségű kérést küld a szervernek, hogy az már nem tudja a valós kéréseket kiszolgálni vagy pedig annyira lassan, hogy gyakorlatilag elérhetetlenné válik a szolgáltatás. A DoS támadás nem elosztott vagyis egy rendszertől, személytől származik, ha többen vesznek rész egy ilyen támadásban azt már DDoS-nak nevezzük vagyis Distributed Denial-of-Servicenek. Nagyon sok nemzet törvénye bünteti az efféle támadásokat. Egy ilyen támadás megállításhoz nem lesz elég a webalkalmazásunkat közel hibamentesre fejleszteni. Szükség van arra, hogy a hálózat többi eszköze is megfelelően reagáljon. A tűzfalak, switchek, routerek folyamatosan figyelik a hálózati forgalmat és ha úgy látják, akkor közbeavatkoznak. Egy fejlesztő egyedül nem tudja felkészíteni az alkalmazást, hogy ellenálljon az ilyen támadásoknak."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Nem érzem magam biztonságban"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ez nem is baj, ugyanis a fent említett támadások csak nagyon kis halmazát fedik le a valóságban létező és működő támadási formáknak, illetve ezeknek a módszereknek is többféle fajtája van. Tökéletes biztonság sajnos nem létezik, ám a kockázatot tudjuk csökkenteni azzal, hogy védekezünk a már ismert támadási formák ellen."}]}]}
{"_type":"post","_createdAt":"2014-01-23T22:35:00.000+01:00","publishedAt":"2014-01-23T22:35:00.000+01:00","title":"PÉK jelene és jövője, I. rész","body":[{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ezzel a bejegyzéssel indul útjára egy több részes sorozat, amiben megpróbálom bemutatni a PÉK-nek azt az oldalát, amit kevesen látnak és még kevesebben ismernek. Többek között szó lesz a PÉK rövid történetéről, a jelenlegi felépítéséről, a kihívásokról, amiket a körrel szemben támaszt és természetesen a jövőről is. Ha minden jól alakul, akkor a következő pár hónap felettébb izgalmas lesz. Egyelőre csak az elhatározás született meg, konkrétumok még alig látszanak."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Oké, hogy PÉK, de akkor mi az a VIR?"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az évek során bizonyos fogalmak és alkalmazások között elmosódott a határvonal. A PÉK (Profil és Körök) valójában a VIR (Villanykari Információs Rendszer) egy szelete csupán. Anno még KIR-ként (Kollégiumi Információs Rendszer) indult ez a projekt. Ezt tükrözi a körünk neve is (Kir-Dev == Kollégiumi Információs Rendszer fejlesztők, de ez így hosszú is és legalább egy nagyságrenddel kevésbé hangzatos is)."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBPdz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--58e32e21c0436e16d143d778b2a1c207b29b052f/vir_landing.jpg","alt":"VIR nyitóoldal az induláskor"}}]},{"_type":"block","markDefs":[{"_key":"e2b37dd19eb7","_type":"link","href":"https://vir.sch.bme.hu/index.html"},{"_key":"20c8322f856b","_type":"link","href":"http://news.sch.bme.hu/"},{"_key":"5a40e3b3f5d9","_type":"link","href":"https://wiki.sch.bme.hu/"},{"_key":"4e5c23868be8","_type":"link","href":"https://korok.sch.bme.hu"},{"_key":"060f9ab2fe78","_type":"link","href":"https://blog.sch.bme.hu/index.php/kozosseg/2009/11/25/sss-koezoessegi-site-villanykar-modra"},{"_key":"34aafc076e8f","_type":"link","href":"http://stewie.sch.bme.hu/gitweb/?p=archive/andy/aggregator"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A VIR valójában egy meta-projekt, ami "},{"_type":"span","marks":["e2b37dd19eb7"],"text":"több kisebb alkalmazást"},{"_type":"span","marks":[],"text":" fogott össze. Lassan, de biztosan elhalványult az eredeti elképzelés és a kar hallgatóinak többsége elfelejtette, hogy egyáltalán volt ilyen. A VIR alá tartozott a lassan teljesen megszűnő "},{"_type":"span","marks":["20c8322f856b"],"text":"news"},{"_type":"span","marks":[],"text":", az azóta már átalakult "},{"_type":"span","marks":["5a40e3b3f5d9"],"text":"wiki"},{"_type":"span","marks":[],"text":", az eredetileg két alkalmazásként működő "},{"_type":"span","marks":["4e5c23868be8"],"text":"Profil és Körök"},{"_type":"span","marks":[],"text":", valamint az SSO (Single sign-on) is. A megvalósult alkalmazásokon túl az "},{"_type":"span","marks":["060f9ab2fe78"],"text":"SSS-ről (Schönherz Social Services)"},{"_type":"span","marks":[],"text":" is sokat beszéltünk, főleg a körön belül. Emellett egy "},{"_type":"span","marks":["34aafc076e8f"],"text":"RSS aggregátor"},{"_type":"span","marks":[],"text":" is készült volna, ami a Schönherzen belüli hírek automatikus összegyűjtését célozta."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A VIR fogta volna össze a kollégium és tágabb értelemben a kar online életének egy meghatározó részét. A PÉK alatt lévő adatbázisban sok érdekes adat van, sőt ezt még egy kapcsolati hálóval kiegészítve már igazán nagyot lehetett volna álmodni. Ezek a nagyra törő tervek idő és lelkesedés hiányában nem valósultak meg, vagy inkább úgy fogalmaznék, hogy határozatlan időre elnapolódtak."}]},{"_type":"block","markDefs":[{"_key":"0d635ef7286c","_type":"link","href":"https://korok.sch.bme.hu"},{"_key":"d40508decdfc","_type":"link","href":"https://profile.sch.bme.hu"},{"_key":"4a38493d4dea","_type":"link","href":"https://vir.sch.bme.hu"},{"_key":"b9da52e9d83c","_type":"link","href":"https://github.com/kir-dev/korok"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Mára a VIR a legtöbb hallgatónak egyet jelent a PÉK-kel. Ez köszönhető a meg nem valósult fejlesztéseknek is, de főleg annak, hogy kifele sosem kommunikáltuk igazán a határvonalakat. Sőt az sem segített, a legtöbb domain valójában egy alkalmazásra mutat. Például a "},{"_type":"span","marks":["0d635ef7286c"],"text":"korok.sch.bme.hu"},{"_type":"span","marks":[],"text":", a "},{"_type":"span","marks":["d40508decdfc"],"text":"profile.sch.bme.hu"},{"_type":"span","marks":[],"text":", sőt még a "},{"_type":"span","marks":["4a38493d4dea"],"text":"vir.sch.bme.hu"},{"_type":"span","marks":[],"text":" is ugyanarra az alkalmazásra, a "},{"_type":"span","marks":["b9da52e9d83c"],"text":"PÉK"},{"_type":"span","marks":[],"text":"-re mutat."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ezzel az első bejegyzés végére is értünk. A következő részben már tényleg a PÉK- kel fogunk foglalkozni és azzal az úttal, amit bejárt a kezdetektől."}]}]}
{"_type":"post","_createdAt":"2014-01-25T12:20:00.000+01:00","publishedAt":"2014-01-25T12:20:00.000+01:00","title":"PÉK jelene és jövője, II. rész","body":[{"_type":"block","markDefs":[{"_key":"94f3e87e0ecc","_type":"link","href":"/post/2014-01-23-pek-jelen-es-jovo-i"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az "},{"_type":"span","marks":["94f3e87e0ecc"],"text":"előző részben"},{"_type":"span","marks":[],"text":" a VIR és a PÉK különbségére próbáltam rávilágítani. Mielőtt még tényleg rátérnénk a címben említett jelenre és jövőre, még egy picit a múltba kell merülnünk. A múlt fontos szerepet játszik abban, hogy megértsük a PÉK jövőjével kapcsolatos, már-már radikálisnak nevezhető döntéseket."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A PÉK valójában két alkalmazás volt. Ezek ugyan szorosan kapcsolódtak, de különböző céllal születtek."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A Profil egy hallgató Schönherzbeli online identitását képviselte, kihegyezve mindezt a felhasználói azonosításra. A Profil mögött egy LDAP címtár húzódott. Az autentikáció ebből a címtárból történt egészen 2013 nyaráig."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A Profil mellett, vele szorosan együttműködve futott a Körök nevű alkalmazás. Ez valójában a már régen is létező közösségi pontozást nyilvántartó rendszer újragondolása és újraírása. A kör tagjai a JavaEE technológia mellett tették le a voksukat. Ez 2007-2008 táján volt. Lehet vitatkozni, hogy ez jó döntés volt-e vagy sem, de az biztos, hogy az eredeti PHP-ban tákolt rendszernél minden jobb. Azóta ez a technológia határozza meg a kör életét, annak minden örömével és nyűgével - ebbe beleértve a népszerűségét, vagyis inkább annak hiányát is."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az újraírás egyik velejárója, hogy az adatbázist örökölte a rendszer az elődjétől. A konvenciók változtak az idők során, így fordulhatott elő, hogy a tábla és mezőnevek elég kaotikus képet festenek ma. Egy-egy régebbi táblában magyar és angol mezőnevek váltakoznak, néhol még egy mezőn belül is keverednek a nyelvek."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Idővel a két alkalmazás egy kódbázissá olvadt össze, de ebből kifele nem sok látszott, mert a felület megőrizte a kettősséget, ahogy a domainek is (profile.sch és korok.sch). Ezek azóta sem változtak. Az óvatlan szemlélőnek még mindig úgy tűnhet, mintha két különböző alkalmazás lenne. Ez az egyik dolog, amit a közeljövőben szeretnénk kijavítani."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Több mint két év stagnálás után, 2013 nyarán vettük elő újra az alkalmazást. A munkálatok újfent a háttérben folytak. A felhasználók alig vettek észre valamit a dologból (és ez így is van rendjén). A Profil és Körök egyesítése végre teljesen megtörtént. Az egyszerűsítés volt a vesszőparipánk: A LDAP címtárat megszüntettük, Glassfish-ről JBoss-ra váltottunk és a telepítést pár lépésre redukáltuk. Az adatok visszakerültek az adatbázisba, ezzel megszűnt a két adattár közötti szinkronizáció is."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Most értünk el a jelenbe. A következő részben egy gyors áttekintést fogok adni a PÉK jelenlegi felépítéséről."}]}]}
{"_type":"post","_createdAt":"2014-01-26T12:47:00.000+01:00","publishedAt":"2014-01-26T12:47:00.000+01:00","title":"A blog tovább fejlődik","body":[{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Egyre több látogatója van a blogunknak, hogy tényleges adatokkal szolgálhassunk a csúcs eddig a napi ~70 ember volt és havi szinten már ~500 látogatóval büszkélkedhetünk, és még vége sincs a hónapnak. Elsősorban ezt az állandóan frissülő tartalomnak köszönhetjük és lelkes olvasóinknak, akik figyelemmel követik a kör munkáját. Szerettünk volna kicsit kedveskedni azzal, hogy még jobban gatyába rázzuk a blogot."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBOdz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--9cedb6169f208d581436573a547d23618af44650/new_blog.jpg","alt":"Főoldal"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Megszületett az új design. Nincs radikális változás, de kicsit jobban követi a mai trendeket. Az oldal \"reszponzív\", vagyis a kijelző méreteknek megfelelően változik a kinézete. Ezeket az úgynevezett "},{"_type":"span","marks":["code"],"text":"CSS media query"},{"_type":"span","marks":[],"text":"-kel tudtuk elérni, amellyel próbáltuk az összes kijelző méretet jól lefedni. Egyaránt kényelmesen tudjátok olvasni mobilon, tableten és asztali gépen is. Reméljük a jövőben is szívesen követitek a blogunkat, mi pedig továbbra is próbálunk hasznos szakmai cikkeket írni."}]}]}
{"_type":"post","_createdAt":"2014-01-27T20:50:00.000+01:00","publishedAt":"2014-01-27T20:50:00.000+01:00","title":"PÉK jelene és jövője, III. rész","body":[{"_type":"block","markDefs":[{"_key":"92d178ab3123","_type":"link","href":"/post/2014-01-23-pek-jelen-es-jovo-i"},{"_key":"54e72013d7bb","_type":"link","href":"/post/2014-01-25-pek-jelen-es-jovo-ii"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Most, hogy már tisztában vagyunk a "},{"_type":"span","marks":["92d178ab3123"],"text":"PÉK és a VIR különbségével"},{"_type":"span","marks":[],"text":", valamint a "},{"_type":"span","marks":["54e72013d7bb"],"text":"PÉK múltjával"},{"_type":"span","marks":[],"text":", ideje rátérni a jelenére is. Nézzük meg, hogyan épül fel az alkalmazás és ez milyen problémákhoz vezet!"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Mielőtt belefognék, meg kell jegyeznem, hogy a PÉK hagyományosan egy tanuló projekt volt a körön belül, emiatt sok egyetemi beadandót élt már meg. Fejlesztői sokszor ezen keresztül ismerkedtek meg a JavaEE világával és a webfejlesztéssel is. Ennek az eredménye, hogy néhol a kódbázis hagy némi kívánni valót maga után."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Kívülről befelé"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Haladjunk kívülről befelé. Nézzük meg, hogy mi is hajtja a PÉK-et."}]},{"_type":"block","markDefs":[{"_key":"57a2193962c6","_type":"link","href":"https://profile.sch.bme.hu/profile/show/uid/balo"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Maga az alkalmazás JBoss-on fut, jelenleg talán ez a legjobb választás a most elérhető alkalmazásszerverek közül, de még így is gyakran fejfájást okoz. Sok szempontból nagyon szigorú, például a PostgreSQL drivert "},{"_type":"span","marks":["57a2193962c6"],"text":"balo"},{"_type":"span","marks":[],"text":" csak hosszabb küzdés után tudta működésre bírni."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Néhány hiányossága és hibája ellenére mégis úgy érzem, hogy jó döntés volt Glassfish-ről átállni az elmúlt nyár folyamán."}]},{"_type":"block","markDefs":[{"_key":"f218bae37c33","_type":"link","href":"https://github.com/kir-dev/korok/issues/67"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az alkalmazás alatt egy PostgreSQL adatbázisszerver működik. Ezt igazából csak a teljesség kedvéért említem meg, mert a "},{"_type":"span","marks":["f218bae37c33"],"text":"#67-es issue"},{"_type":"span","marks":[],"text":" lezárásával a PostgreSQL specifikus dolgok majdnem teljesen eltűnnek a rendszerből."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az egyszerűsítés lassan a projekt mottójává válik. Az elmúlt nyár előtt nem volt egyszerű akár csak egy lokális példányt összelőni, nemhogy a kódhoz hozzányúlni. A célunk az, hogy az utánunk következő körtagok merjenek hozzányúlni és ne a "},{"_type":"span","marks":["em"],"text":"teljes"},{"_type":"span","marks":[],"text":" újraírás legyen az első gondolatuk."}]},{"_type":"block","markDefs":[{"_key":"afb8d27a6154","_type":"link","href":"https://github.com/kir-dev/vir-auth"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ugyan csak lazán tartozik a PÉK-hez, de ide sorolnám még az OpenAM-et, ami az SSO szolgáltatásunkat hajtja. "},{"_type":"span","marks":["afb8d27a6154"],"text":"Saját autentikációs modult"},{"_type":"span","marks":[],"text":" fejlesztettünk hozzá, így már képes adatbázisból is beléptetni a felhasználókat. Ez az adatbázis közös a PÉK-kel, ez is a nyári egyszerűsítések folyamán történt (korábban LDAP-ból történt az autentikáció). Az LDAP komponens megszüntetése egy fájó, de szükséges lépés volt. A PÉK esetében a "},{"_type":"span","marks":["em"],"text":"\"kevesebb több\""},{"_type":"span","marks":[],"text":" hozzáállás a kulcs."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az SSO-tól eltekintve (amiről későbbiekben még írunk majd), sikerült egy klasszikus modell keretei közé visszaszorítani az alkalmazást."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Belsőségek"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A belső felépítés már régen sem volt túl bonyolult, a klasszikus három rétegű architektúrát követi, csak az arányok tolódtak el rossz irányba. Az üzleti réteg meglepően karcsú, már-már belecsúszik az adatelérési rétegbe. A webréteg túlságosan felduzzadt, rengeteg üzleti logika került bele. Ez nagyban megnehezíti az átláthatóságot és az automatikus tesztelhetőséget is alapjaiban gáncsolja el."}]},{"_type":"block","markDefs":[{"_key":"331bd7efee93","_type":"link","href":"http://hibernate.org/"},{"_key":"35f6a1df9f17","_type":"link","href":"https://wicket.apache.org/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az alkalmazás egésze a JavaEE stackre támaszkodik. Így JPA-t ("},{"_type":"span","marks":["331bd7efee93"],"text":"Hibernate"},{"_type":"span","marks":[],"text":") használunk az adatbázis eléréséhez, EJB-ket az üzleti rétegben és "},{"_type":"span","marks":["35f6a1df9f17"],"text":"Wicketet"},{"_type":"span","marks":[],"text":" webes keretrendszerként."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Lassan, 6-7 év távlatából a JavaEE egy vitatható döntés, de tanulás szempontjából (ami esetünkben kiváltképp fontos) mindenképpen hasznos. Ugyan a tanulási görbe egy picit meredek, és az előítéletek is riasztóak mind magával a Javaval, mind a JavaEE-vel szemben. Ha valaki túl tudja tenni magát ezeken, a JavaEE egy kifejezetten jó technológia. Megvannak a saját butaságai, de ez alól egyik platform sem kivétel. A JavaEE erősségei a backend oldalon mutatkoznak meg a leginkább (tranzakciók, aszinkron üzenet feldolgozás, deklaratív autorizáció)."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A PÉK esetében ez nem érzékelhető egyértelműen, mert a rendszer bonyolultsága nem éri el azt a pontot, ahol ennek az összetett technológiának igazán kijönnének az előnyei. Sőt, valószínűleg sosem fog akkorára nőni, hogy ez megtörténjen."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A problémáink legnagyobb része nem a backend oldalon mutatkozik, hanem régóta látható, hogy a frontend a szűk keresztmetszet. A Wicket a java világban a webes keretrendszerek közül az egyik leghasználhatóbb, de még így is alulmarad a többi nyelven elérhetőekhez képest."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A javas webes fejlesztés egyik legnagyobb fájdalma a folyamatos és sokszor időigényes "},{"_type":"span","marks":["em"],"text":"deploy"},{"_type":"span","marks":[],"text":" (telepítés), ez alól a Wicket sem kivétel. A komponens-orientált dizájn pedig valami '90-es évekbeli maradvány érthetetlen túlélése. Manapság már ritka, hogy a klasszikus formokkal és jelentősebb ajax használat nélkül is elboldoguljunk. Így a Wicket az utóbbi időben inkább csak hátráltatott minket - egy utat erőltet, amitől eltérni "},{"_type":"span","marks":["em"],"text":"nem"},{"_type":"span","marks":[],"text":" lehet."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Meg merem kockáztatni, hogy jelenleg a Wicket az egyik legnagyobb akadály, amit a rendszer fejlesztésébe bekapcsolódni vágyóknak át kell ugrania. Sokszor feleslegesen bonyolult és olyan koncepciókat hoz be, amiket egyszerűbb felépítéssel könnyen kikerülhettek volna. Pont ezek miatt fogunk megszabadulni ettől a keretrendszertől az elkövetkeződő hónapok alatt."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Összegezzünk!"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ahogy láttuk az alkalmazás önmagában nincs túlbonyolítva, inkább az egyes technológiák nyűgjeivel küzd és sajnos nem csak technológiai értelemben. A Java és a JavaEE nem vonzó, így új embereket rávenni a fejlesztésre évről-évre nehezebb. A PÉK legnagyobb problémája ebben mutatkozik meg."}]},{"_type":"block","markDefs":[{"_key":"a1ec5ed74e1b","_type":"link","href":"http://en.wikipedia.org/wiki/Source_lines_of_code"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A kódbázis is ijesztő méretű lehet egy átlagos egyetemi beadandóhoz képest, most nagyjából 22 "},{"_type":"span","marks":["a1ec5ed74e1b"],"text":"KLOC"},{"_type":"span","marks":[],"text":"-ra rúg."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A népszerűségi gondokon segíteni nem nagyon tudunk, így inkább megpróbáljuk megtalálni azt a pár embert, aki magától is érdeklődik a téma iránt. Ez az utóbbi években nem vezetett egyértelmű sikerre, de az egész rendszert egy vonzóbb nyelven nem írhatjuk újra. Arra, hogy miért nem, a következő bejegyzésben fogok kitérni. Lassan a sorozat végére érünk, mert a következő cikkben már a PÉK jövője kerül elő."}]}]}
{"_type":"post","_createdAt":"2014-01-28T13:20:00.000+01:00","publishedAt":"2014-01-28T13:20:00.000+01:00","title":"Hypermedia API","body":[{"_type":"block","markDefs":[{"_key":"06b0db843851","_type":"link","href":"http://en.wikipedia.org/wiki/Service-oriented_architecture"},{"_key":"e9cf7f10481c","_type":"link","href":"http://en.wikipedia.org/wiki/Resource-oriented_architecture"},{"_key":"e71932159c3b","_type":"link","href":"http://en.wikipedia.org/wiki/Representational_state_transfer"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az informatikai rendszerek architektúrájában egy evolúciós lépés a szolgáltatás-orientált programozás ("},{"_type":"span","marks":["06b0db843851"],"text":"SOA"},{"_type":"span","marks":[],"text":"), melyet gyakran webszolgáltatások formájában implementálnak. A SOA architektúra azonban önmagában nem a webre született, így kialakult az erőforrás-orientált architektúra ("},{"_type":"span","marks":["e9cf7f10481c"],"text":"ROA"},{"_type":"span","marks":[],"text":"), mely inkább programozási paradigmának, vagy megvalósítási stílusnak nevezhető. A ROA lényege, hogy a szoftvert erőforrások formájában tervezzük meg és az alkalmazást alkotó szolgáltatások "},{"_type":"span","marks":["e71932159c3b"],"text":"REST"},{"_type":"span","marks":[],"text":" interfészen keresztül kommunikálnak."}]},{"_type":"block","markDefs":[{"_key":"4a44f0feab3a","_type":"link","href":"http://en.wikipedia.org/wiki/SOAP"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Két gép kommunikációjához valamilyen protokollra és adatformátumra van szükség. Az erőforrás-orientált programozás során használt REST a HTTP protokoll webes szemantikáját terjeszti ki azzal, hogy az alkalmazás állapotát HTTP kérésekkel lehet lekérdezni, illetve módosítani. Ez webszolgáltatások esetén sokkal könnyebben használható, mint a SOA, ami sokáig egyet jelentett a "},{"_type":"span","marks":["4a44f0feab3a"],"text":"SOAP"},{"_type":"span","marks":[],"text":"-pal. A REST-ben megfogalmazott vezérelvek nem határoznak meg konkrét adatátviteli formátumokat, így webszolgáltatások esetén felhasználástól függően különböző formátumokat használnak, mint például XML vagy JSON."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Hagyományos SOA rendszereknél egy távoli lekérdezés adatokkal tér vissza, ROA esetén viszont az alkalmazás további állapotaiba vezető átmenetek is a visszatérési érték részét képezik. Az alkalmazás állapota részletesen leírható a hypermedia formátumok metaadat leíró képességével, az állapotátmenetek pedig könnyen reprezentálhatóak a hypermedia adatformátumokban meglévő linkekkel: innen ered a technológia elnevezése a "},{"_type":"span","marks":["em"],"text":"Hypermedia API"},{"_type":"span","marks":[],"text":". Használatával a klienseknek csak linkeken keresztül kell kommunikálnia a backend szolgáltatással, így weben rendkívül jól használható. Segítségével valóban vékony kliensek hozhatók létre, amik nagyon keveset tudnak a háttérben dolgozó szolgáltatásról. A szolgáltatás részleteinek változásakor nem kell változtatni a kliensen, ezért a Hypermedia API könnyebben használható programok számára és azokat így könnyebb is karbantartani."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Adatformátumok"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Lényegében bármilyen adatátviteli formátumot használhatunk, de a legelterjedtebbek, melyeket HTTP protokoll felett használnak a HTML, XML és a JSON. Más lehetséges formátumok például a CSV, YAML, Markdown, ATOM, de ezek kevésbé elterjedtek ilyen célból. Koncentráljunk a három legelterjedtebbre, és lássuk melyiknek milyen előnyei vannak."}]},{"_type":"block","markDefs":[],"style":"h3","children":[{"_type":"span","marks":[],"text":"XML"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[]},{"_type":"block","markDefs":[],"style":"normal","level":2,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"Rendkívül kiforrott formátum és nagyon sokféle támogató technológia érhető el hozzá. Például transzformáció (XSLT), lekérdezés (XPath, XQuery), validáció (XSD, DTD)."}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[]},{"_type":"block","markDefs":[],"style":"normal","level":2,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"Szabványos és minden programozási nyelvből elérhető."}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[]},{"_type":"block","markDefs":[],"style":"normal","level":2,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"Kliens oldalon nehezebb használni."}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[]},{"_type":"block","markDefs":[],"style":"normal","level":2,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"Nehézsúlyú: kommunikációs overhead."}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[]},{"_type":"block","markDefs":[],"style":"normal","level":2,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"Nincs natív állapotátmenet reprezentáció kiterjesztés nélkül."}]},{"_type":"block","markDefs":[],"style":"h3","children":[{"_type":"span","marks":[],"text":"JSON"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[]},{"_type":"block","markDefs":[],"style":"normal","level":2,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"Kliens oldalon könnyű használni."}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[]},{"_type":"block","markDefs":[],"style":"normal","level":2,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"Könnyűsúlyú."}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[]},{"_type":"block","markDefs":[],"style":"normal","level":2,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"Nincs szabványos lekérdezés, validálás."}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[]},{"_type":"block","markDefs":[],"style":"normal","level":2,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"Nincs natív állapotátmenet reprezentáció kiterjesztés nélkül."}]},{"_type":"block","markDefs":[],"style":"h3","children":[{"_type":"span","marks":[],"text":"HTML"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[]},{"_type":"block","markDefs":[],"style":"normal","level":2,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"Kiforrott formátum, sok támogató technológia."}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[]},{"_type":"block","markDefs":[],"style":"normal","level":2,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"Kliens oldalon használata triviális."}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[]},{"_type":"block","markDefs":[],"style":"normal","level":2,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"Javascript segítségével módosítható."}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[]},{"_type":"block","markDefs":[],"style":"normal","level":2,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"Natív állapotátmenet reprezentáció."}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[]},{"_type":"block","markDefs":[],"style":"normal","level":2,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"Jól jön, ha olvashatónak kell lennie az API-nak."}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[]},{"_type":"block","markDefs":[],"style":"normal","level":2,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"Nem mindig készíthető egyszerűen el az alkalmazás állapotának reprezentációja."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Néhány példa"}]},{"_type":"block","markDefs":[],"style":"h3","children":[{"_type":"span","marks":[],"text":"Labirintus"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Labirintus játék API XML felhasználásával:"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"Különféle labirintusok közül választhatunk a "},{"_type":"span","marks":["em"],"text":"collection"},{"_type":"span","marks":[],"text":" listából."}]},{"_type":"code","code":"<maze> <collection href=\"...\"> <link href=\"...\" rel=\"maze\" /> <link href=\"...\" rel=\"maze\" /> </collection> </maze> ","language":"html"},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"A kiválasztott labirintusba beléphetünk, vagy visszaléphetünk a labirintus-listához."}]},{"_type":"code","code":"<maze> <item href=\"...\"> <link href=\"...\" rel=\"collection\" /> <link href=\"...\" rel=\"start\" /> </item> </maze> ","language":"html"},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"Járkálhatunk a különböző cellákon ("},{"_type":"span","marks":["em"],"text":"cell"},{"_type":"span","marks":[],"text":"), újrakezdhetjük a labirintust, vagy választhatunk másik labirintust. Megjegyzés: természetesen nem mindig lehet minden irányban lépkedni, itt az összes lehetőséget felsoroltam."}]},{"_type":"code","code":"<maze> <cell href=\"...\"> <link href=\"...\" rel=\"north\" /> <link href=\"...\" rel=\"south\" /> <link href=\"...\" rel=\"east\" /> <link href=\"...\" rel=\"west\" /> <link href=\"...\" rel=\"exit\" /> <link href=\"...\" rel=\"maze\" /> <link href=\"...\" rel=\"collection\" /> </cell> </maze> ","language":"html"},{"_type":"block","markDefs":[],"style":"h3","children":[{"_type":"span","marks":[],"text":"Todo app"}]},{"_type":"block","markDefs":[{"_key":"19f61251166e","_type":"link","href":"http://amundsen.com/media-types/collection/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Todo alkalmazás API-ja "},{"_type":"span","marks":["19f61251166e"],"text":"JSON+Collection"},{"_type":"span","marks":[],"text":" adatformátumot használva (itt az "},{"_type":"span","marks":["em"],"text":"items"},{"_type":"span","marks":[],"text":" tömbben vannak az adatok eltárolva és "},{"_type":"span","marks":["em"],"text":"queries"},{"_type":"span","marks":[],"text":"-ben a lehetséges műveletek):"}]},{"_type":"code","code":"{ \"list\" : { \"link\" : { \"href\": \"{collection-uri}\", \"rel\": \"list\" }, \"items\" : [ { \"link\" : { \"href\": \"{item-uri}\", \"rel\": \"item\" }, \"title\" : \"First task\", \"description\" : \"start JSON implementation of the list\", \"date-due\" : \"2010-05-01\", \"completed\" : false }, ... ], \"queries\" : [ { \"link\" : { \"href\": \"{query-link}\", \"rel\": \"today\" } }, { \"link\" : { \"href\": \"{query-link}\", \"rel\": \"open\" } }, ... ] } } ","language":"js"},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Tervezés"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A Hypermedia API-k tervezésének lépései:"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"number","children":[{"_type":"span","marks":[],"text":"Üzleti logika vizsgálata"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"number","children":[{"_type":"span","marks":[],"text":"Állapotgép készítése"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"number","children":[{"_type":"span","marks":[],"text":"Adatreprezentáció készítése"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az ábrázolás részletei a választott adatformátumtól függnek, de sok közös vonás van, amik megegyeznek az egyes formátumok között, közös elnevezésük angolul "},{"_type":"span","marks":["em"],"text":"H-Factors"},{"_type":"span","marks":[],"text":". Ezek a tényezők alapvetően két részre bonthatók: vannak a "},{"_type":"span","marks":["em"],"text":"link factor"},{"_type":"span","marks":[],"text":"-ok, melyek a kliens-szerver kommunikáció létrehozásáért felelősek; és vannak a "},{"_type":"span","marks":["em"],"text":"control factor"},{"_type":"span","marks":[],"text":"-ok, melyek a metaadatok részleteit módosítják. Lássuk hogyan épül fel belőlük egy API, mely HTML-t használ adatformátumként:"}]},{"_type":"block","markDefs":[],"style":"h3","children":[{"_type":"span","marks":[],"text":"Link factors"}]},{"_type":"block","markDefs":[],"style":"h4","children":[{"_type":"span","marks":[],"text":"LE (Embedding links)"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Egy adott URL-en lévő tartalmat be kell olvasni és az adott helyen megjeleníteni, más néven beillesztés."}]},{"_type":"code","code":"<img alt=\"...\" src=\"...\" /> ","language":"html"},{"_type":"block","markDefs":[],"style":"h4","children":[{"_type":"span","marks":[],"text":"LO (Outbound links)"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Egy adott URL-en lévő tartalmat ki kell olvasni és egy új nézetben megjeleníteni, más néven navigáció."}]},{"_type":"code","code":"<a href=\"...\">...</a> ","language":"html"},{"_type":"block","markDefs":[],"style":"h4","children":[{"_type":"span","marks":[],"text":"LT (Templated links)"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Egy adott URL-en lévő tartalmat valamilyen klienstől származó információkkal paraméterezve kell kiolvasni."}]},{"_type":"code","code":"<form method=\"get\" action=\"http://www.example.org/\"> <input type=\"text\" name=\"search\" /> <input type=\"submit\" /> </form> ","language":"html"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"vagy"}]},{"_type":"code","code":"<a href=\"http://www.example.org/?search={searchParam}\"></a> ","language":"html"},{"_type":"block","markDefs":[],"style":"h4","children":[{"_type":"span","marks":[],"text":"LI (Idempotent links)"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Idempotens metódusok, melyek többszöri végrehajtása ugyanazt az eredményt adja, mint az egyszeri végrehajtás. HTTP protokoll esetén ezek a "},{"_type":"span","marks":["em"],"text":"PUT"},{"_type":"span","marks":[],"text":" és "},{"_type":"span","marks":["em"],"text":"DELETE"},{"_type":"span","marks":[],"text":" verb-ekkel végrehajtott kérések. HTML-ben csak Javascript segítségével megvalósítható."}]},{"_type":"block","markDefs":[],"style":"h4","children":[{"_type":"span","marks":[],"text":"LN (Non-idempotent links)"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Nem idempotens metódusok, ilyenek a HTTP protokoll esetén a "},{"_type":"span","marks":["em"],"text":"POST"},{"_type":"span","marks":[],"text":" verb-ekkel végrehajtott kérések."}]},{"_type":"code","code":"<form method=\"post\" action=\"http://example.org/comments/\"> <textarea name=\"comment\"></textarea> <input type=\"submit\" /> </form> ","language":"html"},{"_type":"block","markDefs":[],"style":"h3","children":[{"_type":"span","marks":[],"text":"Control factors"}]},{"_type":"block","markDefs":[],"style":"h4","children":[{"_type":"span","marks":[],"text":"CR (Read controls)"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az adatok olvasását befolyásoló tényezők. Ilyenek HTTP protokoll esetén a fejléc (header) változók, mint például a "},{"_type":"span","marks":["em"],"text":"Content-Type"},{"_type":"span","marks":[],"text":"."}]},{"_type":"block","markDefs":[],"style":"h4","children":[{"_type":"span","marks":[],"text":"CU (Update controls)"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az adatok olvasásának befolyásolását segíti ez a tényező. Ilyen HTML esetén a formokban található "},{"_type":"span","marks":["em"],"text":"enctype"},{"_type":"span","marks":[],"text":" attribútum, mely a kéréshez tartozó "},{"_type":"span","marks":["em"],"text":"Content-Type"},{"_type":"span","marks":[],"text":" fejlécet tudja módosítani."}]},{"_type":"code","code":"<form method=\"post\" action=\"http://example.org/comments/\" enctype=\"text/plain\"> <textarea name=\"comment\"></textarea> <input type=\"submit\" /> </form> ","language":"html"},{"_type":"block","markDefs":[],"style":"h4","children":[{"_type":"span","marks":[],"text":"CM (Method controls)"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az adatkezelés módjának megváltoztatását segíti ez a tényező. HTML esetén a "},{"_type":"span","marks":["em"],"text":"method"},{"_type":"span","marks":[],"text":" attribútum erre szolgál."}]},{"_type":"code","code":"<!-- frissítés --> <form method=\"post\" action=\"...\" /> ... </form> <!-- olvasás --> <form method=\"get\" action=\"...\" /> ... </form> ","language":"html"},{"_type":"block","markDefs":[],"style":"h4","children":[{"_type":"span","marks":[],"text":"CL (Link annotation controls)"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Egy node annotációjával is módosíthatjuk egy URL-en található tartalom értelmezését. Ilyen HTML esetén a link tag "},{"_type":"span","marks":["em"],"text":"rel"},{"_type":"span","marks":[],"text":" attribútuma."}]},{"_type":"code","code":"<link rel=\"stylesheet\" href=\"...\" /> ","language":"html"},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Konklúzió"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Egy rövid bevezető után láthattuk hogyan épül fel a Hypermedia API, megismertük a főbb jellemzőket. Láthattuk hogy:"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"hogyan csökkenti a csatolást a kliens és a szerver oldali kód között a paradigma a belső megvalósítás függetlensége miatt (nincs konkrét url-től, paraméterektől való függőség)"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"hogyan lesz könnyebben használható kliensek számára"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"hogyan lesz olvashatóbb felhasználók számára"}]},{"_type":"block","markDefs":[{"_key":"0b329223e013","_type":"link","href":"https://api.github.com/"},{"_key":"e284c30776e2","_type":"link","href":"https://github.com/mamund/Building-Hypermedia-APIs"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Egy szóval linkek használata az API-ban egy jó dolog, próbáljátok ki a "},{"_type":"span","marks":["0b329223e013"],"text":"GitHub API-ját"},{"_type":"span","marks":[],"text":"! Akit továbbiakban is érdekel a téma "},{"_type":"span","marks":["e284c30776e2"],"text":"itt találhat"},{"_type":"span","marks":[],"text":" 3 teljes implementációt XML, JSON és HTML nyelven, valamint teszt klienseket is hozzájuk."}]}]}
{"_type":"post","_createdAt":"2014-01-29T22:45:00.000+01:00","publishedAt":"2014-01-29T22:45:00.000+01:00","title":"PÉK jelene és jövője, IV. rész","body":[{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Előzmények:"}]},{"_type":"block","markDefs":[{"_key":"a9d02e8f4d5f","_type":"link","href":"/post/2014-01-23-pek-jelen-es-jovo-i"}],"style":"normal","level":1,"listItem":"number","children":[{"_type":"span","marks":["a9d02e8f4d5f"],"text":"PÉK jelene és jövője, I. rész"}]},{"_type":"block","markDefs":[{"_key":"db2a35f4fbda","_type":"link","href":"/post/2014-01-25-pek-jelen-es-jovo-ii"}],"style":"normal","level":1,"listItem":"number","children":[{"_type":"span","marks":["db2a35f4fbda"],"text":"PÉK jelene és jövője, II. rész"}]},{"_type":"block","markDefs":[{"_key":"d6dd508b14c9","_type":"link","href":"/post/2014-01-27-pek-jelen-es-jovo-iii"}],"style":"normal","level":1,"listItem":"number","children":[{"_type":"span","marks":["d6dd508b14c9"],"text":"PÉK jelene és jövője, III. rész"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A negyedik résszel elérkeztünk a sorozat végére. Ebben a részben áttekintjük, hogy mire jutottunk az utóbbi 1-2 hónapban. Rengeteget beszéltünk arról, hogy merre vigyük a PÉK-et, mert több ötlet is felmerült. Megrágtunk jó néhány variációt, de végül győzött a józan ész."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A PÉK technológiai hiányosságai mellett sokkal nagyobb problémát jelent a megfelelő fejlesztői utánpótlás biztosítása. Ez nagyon csúnyán hangzik, de valójában arról van szó, hogy a java és a vele járó technológiák iránt egyre kisebb az érdeklődés. Ennek a megoldása jelenleg fontosabb, mint a technológiai hiányosságok javítása."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Egy esetleges PÉK vérfrissítésről (felhasználói felület és dizájn vonalon) már évek óta beszélgetünk. Most, hogy összeértek a problémák, gyorsan össze is vontuk őket, annak a reményében, hogy egy csapásra kettőt is meg tudunk oldani."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A PÉK felületét és annak hiányosságait nem kell bemutatni: azok, akik sűrűbben (de legalábbis minden félév végén) találkoznak vele, nyilván érzékelték már, hogy az amúgy is ad-hoc felület több helyen is "},{"_type":"span","marks":["em"],"text":"döcög"},{"_type":"span","marks":[],"text":". Az alkalmazás eddigi fejlesztőinek mentségére legyen szólva, hogy többnyire backend oldalon szeretnek dolgozni."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A fentiek fényében az elkövetkezendő pár hónapban lecseréljük és modernizáljuk a PÉK frontendjét. A jelenlegi felület hiányosságairól és legnagyobb problémáiról a ti véleményeteket is szeretnénk majd kikérni, ennek az első lépcsője a következő napokban fog hozzátok eljutni. Figyeljétek a blogot és az email fiókotokat!"}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Oszd meg és uralkodj!"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A jelenlegi alkalmazást egy könnyed vágással ketté fogjuk osztani: a frontendet teljesen leválasztjuk a backendről. A backend oldalon marad a JavaEE EJB-kkel és XML hegyekkel. Az üzleti logika fölött egy vékony REST API lesz, amit JSON üzeneteken keresztül lehet majd megszólítani."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az API az első időkben valószínűleg zárt lesz, mert arra számítunk, hogy az elején nem fogunk tudni egy stabil API-t biztosítani. Idővel viszont szeretnénk majd megnyitni, mert a PÉK alatt lévő adatbázis kincseket rejteget, csak meg kell őket találni. Valami hasonlóra már volt próbálkozás, de valójában sosem valósult meg belőle semmi. Ebben az esetben viszont a saját API-nk első felhasználói mi leszünk, így kénytelenek leszünk ezúttal tényleg befejezni a projektet."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A nyílt API-tól azt reméljük, hogy a karon más (nem Kir-Devhez tartozó) hallgatók is kedvet kapnak majd olyan fejlesztésekhez, amik a közösségnek is jól jönnek. Sőt, talán ezekkel a külső fejlesztéssekkel együtt új igények is jelentkeznek majd, amik tovább lendíthetik a PÉK-et a következő szintre."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Node all the way"}]},{"_type":"block","markDefs":[{"_key":"259f371cd547","_type":"link","href":"http://en.wikipedia.org/wiki/Continuous_delivery"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A frontenddel az a nagy szerencsénk, hogy lényegében bármilyen technológiát választhatunk, mert a feladat mérete megengedi ezt. A backendtől elválasztva, külön alkalmazásként futhat majd a frontend, saját életciklussal és akár azonnali új verzióval ("},{"_type":"span","marks":["259f371cd547"],"text":"continuous delivery"},{"_type":"span","marks":[],"text":"). Ezzel szeretnénk felgyorsítani a fejlesztést, az ötlettől a release-ig tartó utat lerövidíteni. Ez mindenkinek jó: a fejlesztőnek azért, mert szinte azonnal látja a munkája eredményét, a terméknek pedig azért, mert az új ötleteket gyorsan lehet kipróbálni."}]},{"_type":"block","markDefs":[{"_key":"c13e426f6707","_type":"link","href":"http://nodejs.org/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A technológia választása esetünkben nem azért volt fontos, hogy megtaláljuk a problémához legjobban illőt, hanem inkább egy olyat kerestünk, amit majd az utánunk jövők is szívesen használnak majd. A választásunk végül a "},{"_type":"span","marks":["c13e426f6707"],"text":"Node.js"},{"_type":"span","marks":[],"text":"-re esett."}]},{"_type":"block","markDefs":[{"_key":"1ade47716c0b","_type":"link","href":"https://www.paypal-engineering.com/2013/11/22/node-js-at-paypal/"},{"_key":"9a85ce1af933","_type":"link","href":"http://venturebeat.com/2012/01/24/why-walmart-is-using-node-js/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A Node.js az utóbbi egy-két évben szinte a semmiből bukkant elő, és napjainkra meglepő népszerűségre tette szert. Több nagy cég is letette mellette a voksát, a két legnagyobb talán a "},{"_type":"span","marks":["1ade47716c0b"],"text":"PayPal"},{"_type":"span","marks":[],"text":" és a "},{"_type":"span","marks":["9a85ce1af933"],"text":"Walmart"},{"_type":"span","marks":[],"text":"."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Számunkra a Node.js elsősorban népszerűsége és - ezen keresztül - a vonzereje miatt lehet igazán előnyös. Az már csak hab a tortán, hogy valószínűleg érdekes kihívások elé fog állítani minket a fejlesztés során. Nem titkolt cél, hogy ezzel vonjunk be új embereket a fejlesztésbe és a kör életébe. Ebbe beletartoznak a potenciális új körtagok és körben lézengő emberek is. :) Ha esetleg érdekelne a téma és szívesen beszállnál a fejlesztésbe, akkor keress meg minket!"}]}]}
{"_type":"post","_createdAt":"2014-02-03T14:50:00.000+01:00","publishedAt":"2014-02-03T14:50:00.000+01:00","title":"PÉK kérdőív","body":[{"_type":"block","markDefs":[{"_key":"4f6e9a7ac7d1","_type":"link","href":"/post/2014-01-29-pek-jelen-es-jovo-iv"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Múltkor "},{"_type":"span","marks":["4f6e9a7ac7d1"],"text":"említettem"},{"_type":"span","marks":[],"text":", hogy a kíváncsiak vagyunk a véleményetekre a PÉK jelenlegi állapotát illetően. Elsősorban azt szeretnénk tudni ti hogyan használjátok a PÉK-et, milyen nehézségekbe ütköztök és mi hiányzik a legjobban. Ennek a felmérésére készítettünk egy rövid kérdőívet."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A kérdőív kitöltésével nagyban segíted a PÉK fejlesztésének következő iterációját, amiben a mostani felületet fogjuk újragondolni és lecserélni."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Előre is köszönjük, ha rá tudsz szánni pár percet és kitöltöd a kérdőívet."}]},{"_type":"block","markDefs":[{"_key":"54623843df7a","_type":"link","href":"https://docs.google.com/forms/d/1Ym90EyaZhHOTLm50V0zA4iNPzB_mHoi29vKDg5IRoTE/viewform"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A kérdőív kitöltéséhez "},{"_type":"span","marks":["54623843df7a"],"text":"kattints ide"},{"_type":"span","marks":[],"text":"."}]}]}
{"_type":"post","_createdAt":"2014-02-12T22:15:00.000+01:00","publishedAt":"2014-02-12T22:15:00.000+01:00","title":"Web alapozó tanfolyam","body":[{"_type":"block","markDefs":[{"_key":"2fe88f465a92","_type":"link","href":"http://kir-dev.github.io/tanfolyam/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az előző évekhez hasonlóan idén is szervezünk tanfolyamot. Az idei tanfolyam - szakítva a hagyományokkal - a JavaScript, HTML és CSS hármasa köré fog épülni. További információkat a "},{"_type":"span","marks":["2fe88f465a92"],"text":"tanfolyamunk honlapján"},{"_type":"span","marks":[],"text":" találsz, ahol "},{"_type":"span","marks":["strong"],"text":"jelentkezni"},{"_type":"span","marks":[],"text":" is tudsz. Minden érdeklődőt szeretettel várunk."}]},{"_type":"block","markDefs":[{"_key":"151d6cab66a2","_type":"link","href":"http://kir-dev.sch.bme.hu/pek/2014/01/29/pek-jelen-es-jovo-iv/"},{"_key":"24897438aea0","_type":"link","href":"https://www.facebook.com/kirdevteam"},{"_key":"4aada30baaec","_type":"link","href":"https://twitter.com/KirDev"},{"_key":"2acc7abed9c5","_type":"link","href":"http://webchat.freenode.net/?channels=kir-dev"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ha úgy érzed, hogy az alapok már megvannak és szeretnél tovább fejlődni, akkor nálunk a helyed. A "},{"_type":"span","marks":["151d6cab66a2"],"text":"PÉK felületének újraírása"},{"_type":"span","marks":[],"text":" sok kihívást tartogat. Új technológiákat ismerhetsz meg (például Node.js), részt vehetsz a PÉK API-jának megtervezésében és formálhatod az új felületet. Ha felkeltettük az érdeklődésed, akkor keress minket emailben (kir-dev [kukac] sch.bme.hu), "},{"_type":"span","marks":["24897438aea0"],"text":"facebookon"},{"_type":"span","marks":[],"text":", "},{"_type":"span","marks":["4aada30baaec"],"text":"twitteren"},{"_type":"span","marks":[],"text":" vagy a "},{"_type":"span","marks":["2acc7abed9c5"],"text":"#kir-dev"},{"_type":"span","marks":[],"text":" irc csatornán a Freenode-on."}]}]}
{"_type":"post","_createdAt":"2014-02-14T21:45:00.000+01:00","publishedAt":"2014-02-14T21:45:00.000+01:00","title":"mloc.js konferencia I. nap","body":[{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://dl.dropboxusercontent.com/u/31443466/2014-02-13%2013.10.06.jpg","alt":"mloc.js badges"}}]},{"_type":"block","markDefs":[{"_key":"9cd6550532a2","_type":"link","href":"http://mloc-js.com/2014/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ha követitek a magyarországi konferenciákat, akkor láthattátok, hogy február 13-14-én a Prezi a \"House of Ideas\"-ban rendezi az "},{"_type":"span","marks":["9cd6550532a2"],"text":"mloc.js"},{"_type":"span","marks":[],"text":" JavaScript konferenciát. Ebben a cikkben az első nap eseményeiről szeretnénk megosztani az élményeinket."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Mielőtt belekezdenék, köszönetet szeretnék mondani a szervezőknek, hogy ilyen remek konferenciát hoztak össze. Valamint az előadóknak is, hogy eljöttek és bepillantást engedtek a munkájukba, igazán színvonalas előadásokat láthattunk."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"PayPal - Release The Kraken"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://dl.dropboxusercontent.com/u/31443466/2014-02-13%2010.31.11.jpg","alt":"Release the Kraken"}}]},{"_type":"block","markDefs":[{"_key":"54703cb866ff","_type":"link","href":"https://twitter.com/juxtajeff"},{"_key":"47bfcbfd9ea8","_type":"link","href":"https://github.com/paypal/kraken-js"},{"_key":"8c88e4175e40","_type":"link","href":"http://expressjs.com/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A PayPal az egyik legnépszerűbb online fizetési megoldás és nemrégiben kezdték meg az átállást Node.js-re a szerver oldalon is. Erről lehet vitatkozni, hogy jó döntés volt-e vagy sem, de ők azzal érveltek, hogy sokkal produktívabb így a fejlesztés. Természetesen az előadás végén rengeteg kérdést kapott "},{"_type":"span","marks":["54703cb866ff"],"text":"Jeff Harrell"},{"_type":"span","marks":[],"text":". Főként az általuk használt technológiáról beszélt, amely most már JavaScripten alapul. Ez a "},{"_type":"span","marks":["47bfcbfd9ea8"],"text":"Kraken"},{"_type":"span","marks":[],"text":", amely az "},{"_type":"span","marks":["8c88e4175e40"],"text":"express.js"},{"_type":"span","marks":[],"text":" (amit mi is használni fogunk valószínűleg a "},{"_type":"span","marks":[],"text":"PÉK frontend"},{"_type":"span","marks":[],"text":" újraírásakor) egy kiegészítése, amivel struktúrát és konvenciókat lehet a rendszerbe vinni."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Google - New Optimizations of Google Chrome's V8"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://dl.dropboxusercontent.com/u/31443466/2014-02-13%2011.53.22.jpg","alt":"V8 optimizations"}}]},{"_type":"block","markDefs":[{"_key":"8e78d5f7bb74","_type":"link","href":"http://www.cubrid.org/blog/dev-platform/understanding-java-garbage-collection/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ben L. Titzer az előadásában bevezetett a heap optimalizálásába és a Garbage Collector működésébe (eléggé hasonló a JVM GC működéséhez: "},{"_type":"span","marks":["8e78d5f7bb74"],"text":"Old & Young generations"},{"_type":"span","marks":[],"text":"). Szintén rengeteg kérdést kapott és elárulta, hogy azon túl, hogy a Chrome-ban remekül fut a JavaScript, a Google-nél egyéb dolgokra is szeretnék használni a nyelvet. Ha már itt volt érdeklődtek a szomszédban lévő magyar cégek arról is, hogy hogyan érdemes optimális, gyors kódot írni. :)"}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Ebédszünet"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ehhez sok kommentet nem fűznénk. A kaja nagyon finom volt és közben lehetett csevegni a többi résztvevővel."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://dl.dropboxusercontent.com/u/31443466/2014-02-13%2013.51.37.jpg","alt":"lunch at mloc.js"}}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"JavaScript as an Intermediate Language"}]},{"_type":"block","markDefs":[{"_key":"9b7e5858dfee","_type":"link","href":"https://twitter.com/ShriramKMurthi"}],"style":"normal","children":[{"_type":"span","marks":["9b7e5858dfee"],"text":"Shriram Krishnamurthi"},{"_type":"span","marks":[],"text":" a Brown University-ről érkezett. Egy remek témát hozott arról, hogy hogyan lehetne a JavaScriptet köztes nyelvként használni. Akadémiai vonalról jött, de számomra ez az előadás volt a nap legjobbja. Magával ragadott a felvezetés, ahogy elmondta, hogy a JavaScriptet funkcionális nyelvként próbálták használni a matematika oktatására. A tanulókat nem érdekli a stack és az alacsony szintű dolgok, ők egyszerűen csak programozni akarnak és alkotni úgy, hogy a részletekről nem akarnak tudni."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Természetesen az oktatás problémáiról is beszélt, de mikor már a közepénél jártunk azért párszor kifagyasztotta a Chrome-ot "},{"_type":"span","marks":["code"],"text":"while(true){print \"loop\";}"},{"_type":"span","marks":[],"text":" illetve néha stackoverflow-t is tudott produkálni. A többi böngészővel meg sem próbálkozott."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://dl.dropboxusercontent.com/u/31443466/2014-02-13%2015.14.51.jpg","alt":"JavaScript as an Intermediate Language"}}]},{"_type":"block","markDefs":[{"_key":"8c699eb556d8","_type":"link","href":"http://www.pyret.org/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Valljuk be egy végtelen ciklus nem szép dolog és szétfagyasztja az egész UI-t. Aztán jött a csavar és bemutatta, hogy mikre képes az "},{"_type":"span","marks":["8c699eb556d8"],"text":"általuk fejlesztett rendszer"},{"_type":"span","marks":[],"text":". A felhasználói felület végig reszponzív maradt, még végtelen ciklus esetén is. Képes volt megállítani a futást, sőt pause-t nyomni, majd pedig ugyanonnan folytatni a program futását. Ezek után pedig részletezte, hogy mi mindenre lehetne használni ezt a projektet. Innentől a ti fantáziátokra bíznánk és ha van kedvetek tippelni, akkor szóljatok hozzá a cikk alatt!"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://dl.dropboxusercontent.com/u/31443466/2014-02-13%2015.16.04.jpg","alt":"JavaScript as an Intermediate Language"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A nap végén az emberek elégedetten távoztak és rengetegen dicsérték a konferencia első napját. Mi is nagyon élveztük az előadásokat, de a végére nagyon elfáradtunk. Ideje volt már elindulni haza pihenni, hogy másnap újult erővel figyelhessünk többek között a Facebooktól jött előadó szavaira. Hamarosan folytatjuk..."}]}]}
{"_type":"post","_createdAt":"2014-02-15T22:33:00.000+01:00","publishedAt":"2014-02-15T22:33:00.000+01:00","title":"mloc.js konferencia II. nap","body":[{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A fantasztikus első nap után örömmel keltem fel reggel fél hétkor, hogy berohanjak a Prezibe a konferencia második napjára. Sajnos az első nap után lévő partit ki kellett hagynom, de a srácok, akik ott maradtak biztos tudnának mesélni róla. Kicsit fáradt volt a csapat, mert segítőként voltunk jelen és hosszú volt az előző nap. Miután felkészültünk az emberek fogadására kezdődhetett a második nap."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Streams for the web"}]},{"_type":"block","markDefs":[{"_key":"83983f832f04","_type":"link","href":"https://twitter.com/domenic"}],"style":"normal","children":[{"_type":"span","marks":["83983f832f04"],"text":"Domenic Denicola"},{"_type":"span","marks":[],"text":" a streamek fontosságáról beszélt és arról, hogy ezek miket tesznek számunkra lehetővége. Egy olyan API-t hozott létre, amely segítséget nyújt streamek kezelésére JavaScriptből. Az előadás alatt kicsit mélyebb betekintést adott a streamek működésébe. A prezentációja király volt, csak nézzétek meg az alábbi képet! :)"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://dl.dropboxusercontent.com/u/31443466/2014-02-14%2009.59.59.jpg","alt":"streams"}}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Introduction to React"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://dl.dropboxusercontent.com/u/31443466/2014-02-14%2010.37.52.jpg","alt":"react"}}]},{"_type":"block","markDefs":[{"_key":"d043b3a6c19a","_type":"link","href":"https://twitter.com/stoyanstefanov"},{"_key":"d293c948918f","_type":"link","href":"http://facebook.github.io/react/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A Facebook előadója "},{"_type":"span","marks":["d043b3a6c19a"],"text":"Stoyan Stefanov"},{"_type":"span","marks":[],"text":" volt, aki a "},{"_type":"span","marks":["d293c948918f"],"text":"Reactról"},{"_type":"span","marks":[],"text":" beszélt. A Facebooknál a social pluginok teljesítményével foglalkozik (például mikor egy másik weboldalon lájkolsz valamit). A React a Facebook és az Instagram közös library-je, amivel dinamikus web interfészeket tudunk építeni úgy, hogy azok gyorsak legyenek. Egyszerűen kifejezve a Facebook ettől tűnik gyorsabbnak az utóbbi időben."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Szünetekben"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Két előadásos blokkok voltak. Ilyenkor alkalmunk nyílt kicsit beszélgetni az emberekkel és körbenézni, hogy miket lehet elfogyasztani."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://dl.dropboxusercontent.com/u/31443466/2014-02-14%2011.08.31.jpg","alt":"breaks"}}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Enterpise JavaScript Architectures - With some vanilla topping"}]},{"_type":"block","markDefs":[{"_key":"ccbc38bb39d4","_type":"link","href":"https://twitter.com/adam_rocska"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A konferencia utolsó előadását "},{"_type":"span","marks":["ccbc38bb39d4"],"text":"Rocska Ádám"},{"_type":"span","marks":[],"text":" tartotta aki az EPAM-nál senior front-end fejlesztő. Az előadás nagyon izgalmas volt, mert arról beszélt, hogy hogyan érdemes JavaScriptben front-end architektúrákat fejleszteni."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://dl.dropboxusercontent.com/u/31443466/2014-02-14%2016.16.36.jpg","alt":"speaker"}}]},{"_type":"block","markDefs":[{"_key":"560da8d2c562","_type":"link","href":"http://en.wikipedia.org/wiki/Vanilla_software"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Beszélt a projektek életciklusa során felmerülő döntésekről és azok meghozásáról. Szó volt arról is, hogy nem feltétlenül jó dolog már a projekt kezdetén egy keretrendszer mellett elköteleződni. Használjunk "},{"_type":"span","marks":["560da8d2c562","em"],"text":"vanilla"},{"_type":"span","marks":[],"text":" JavaScriptet addig amíg tudunk, mert az előnyére válik a kód minőségének."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://dl.dropboxusercontent.com/u/31443466/2014-02-14%2016.33.07.jpg","alt":"blueprint"}}]},{"_type":"block","markDefs":[{"_key":"f3e5921515f3","_type":"link","href":"http://steigerwald.cz/"},{"_key":"4976c80b829e","_type":"link","href":"https://developers.google.com/experts/members/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Fontosak, hogy a tesztek és a dokumentáció meglegyenek, mivel mindig jobb egy nem használt dokumentáció, mint egy olyan dokumentáció, amit használni szeretnénk, de nem létezik. Az előadás végére a kétkedők és a támogatók között egy jó kis vita alakult ki, amit nagyon érdekes volt hallgatni. Ebbe a vitába beszállt az előző nap egyik előadója "},{"_type":"span","marks":["f3e5921515f3"],"text":"Daniel Steigerwald"},{"_type":"span","marks":[],"text":", aki többek között a "},{"_type":"span","marks":["4976c80b829e"],"text":"Google Developer Expert"},{"_type":"span","marks":[],"text":" program tagja és próbálta meggyőzni az embereket, hogy mennyire igazak az elhangzottak."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Vége"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Mi nagyon jól éreztük magunkat ezen a konferencián, ahogy mindenki aki részt vett rajta. Reméljük, hogy jövőre ugyanitt találkozunk és újabb hasznos tapasztalatokkal és barátokkal gazdagodunk majd. Ja, és nagy taps a Prezinek és a Ustreamnek, hogy tető alá hozták ezt az egészet!"}]}]}
{"_type":"post","_createdAt":"2014-02-16T22:15:00.000+01:00","publishedAt":"2014-02-16T22:15:00.000+01:00","title":"Jelszavak kezelése szkriptekben","body":[{"_type":"block","markDefs":[{"_key":"f7c7e9644981","_type":"link","href":"http://xkcd.com/1205/"}],"style":"normal","children":[{"_type":"span","marks":["f7c7e9644981"],"text":"Sokszor készítünk"},{"_type":"span","marks":[],"text":" szkripteket azért, hogy a gyakran végzendő feladatokat automatizáljuk, ezekben néha különféle jelszavak bekérésére is szükség van. Lehetne, hogy egy konstansban elmentjük az érzékeny információt a szkriptben, de ez ugye amellett, hogy nem szép a verziókezelést is nehezíti. Ha a hívott alkalmazás támogatja a jelszófájlokat, akkor érdemes azt használni és a fájlt megfelelően titkosítani."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ha az alkalmazás vagy erőforrás nem támogatja a jelszófájlokat (pl. jarsigner), akkor valamilyen módon be kell kérni és beadni parancssori paraméterben."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Példa egy konkrét utasításra, amikor a jelszó parancssori paraméterben szerepel:"}]},{"_type":"code","code":"$ jarsigner -keystore mystore.ks -storepass MySecretPass awesome.jar mycert ","language":"sh"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A fenti példa azért is nagyon rossz gyakorlat, mert a jelszó könnyen kiszivároghat a bash history-n vagy processzlistázó eszközökön (ps, top) keresztül."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A kulcsot érdemes úgy bekérni, hogy az ne írodjon ki a standard outputra gépeléskor ( "},{"_type":"span","marks":["em"],"text":"echo"},{"_type":"span","marks":[],"text":" ), erre mutatok megoldást bash-ben, Pythonban és Rubyban."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":["strong"],"text":"Bash"}]},{"_type":"block","markDefs":[{"_key":"eb6e2d9f08a5","_type":"link","href":"http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_08_02.html"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Használjuk a bash "},{"_type":"span","marks":["eb6e2d9f08a5"],"text":"read"},{"_type":"span","marks":[],"text":" parancsát a "},{"_type":"span","marks":["code"],"text":"silent mode"},{"_type":"span","marks":[],"text":" és "},{"_type":"span","marks":["code"],"text":"prompt"},{"_type":"span","marks":[],"text":" kapcsolókkal."}]},{"_type":"code","code":"#!/bin/bash read -s -p \"Store Password: \" storepw jarsigner -keystore mystore.ks -storepass \"$storepw\" awesome.jar mycert ","language":"sh"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":["strong"],"text":"Python"}]},{"_type":"code","code":"from getpass import getpass pw = getpass(\"Password: \") print \"Your password is\", len(pw), \"characters long\" ","language":"python"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":["strong"],"text":"Ruby"}]},{"_type":"code","code":"require \"io/console\" print \"Password: \" pw = STDIN.noecho(&:gets).chomp print \"Your password is #{pw.length} characters long\" ","language":"ruby"},{"_type":"block","markDefs":[{"_key":"d9e276d97c76","_type":"link","href":"http://www.ruby-doc.org/stdlib-2.1.0/libdoc/io/console/rdoc/IO.html#method-i-noecho"},{"_key":"ed93379dab75","_type":"link","href":"http://www.ruby-doc.org/core-2.1.0/IO.html#method-i-gets"},{"_key":"596b52a16b29","_type":"link","href":"http://ruby-doc.org/core-2.1.0/String.html#method-i-chomp"},{"_key":"8462ebfc1a98","_type":"link","href":"https://github.com/JEG2/highline/blob/master/examples/password.rb"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Kicsit mágikusnak tűnhet, de a 3. sor nem csinál mást, mint "},{"_type":"span","marks":["d9e276d97c76"],"text":"kikapcsolja"},{"_type":"span","marks":[],"text":" az "},{"_type":"span","marks":["em"],"text":"echo"},{"_type":"span","marks":[],"text":" funkciót és "},{"_type":"span","marks":["ed93379dab75"],"text":"beolvas egy sort"},{"_type":"span","marks":[],"text":", aminek a végéről "},{"_type":"span","marks":["596b52a16b29"],"text":"levágja"},{"_type":"span","marks":[],"text":" a sorvége karaktert. Csak ezért a funkcióért nem biztos, hogy megéri behúzni, de a "},{"_type":"span","marks":["em"],"text":"highline gem"},{"_type":"span","marks":[],"text":" is tudja ezt kicsit "},{"_type":"span","marks":["8462ebfc1a98"],"text":"olvashatóbban"},{"_type":"span","marks":[],"text":"."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ha a szkriptünk egy integrált rendszer részeként fut (pl. cron), a linux terminál eszközeivel a fenti megközelítést bash-ban továbbra is használhatjuk. Egyszerűen mentsük el a jelszót egy védett fájlba és irányítsuk a szkriptünkbe."}]},{"_type":"code","code":"$ myscript.sh < mypassw.txt ","language":"sh"},{"_type":"block","markDefs":[{"_key":"f2552b356ac0","_type":"link","href":"http://ruby-doc.org/core-2.1.0/ARGF.html"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ez a trükk az előzőekben ismertetett Python és Ruby kódokkal nem működik, de ilyen követelmény esetén találhatunk mindkét környezethez többféle megoldást (Tipp: "},{"_type":"span","marks":["f2552b356ac0"],"text":"Ruby ARGF"},{"_type":"span","marks":[],"text":")"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":["strong"],"text":"Környezeti változók"}]},{"_type":"block","markDefs":[{"_key":"6963798536b1","_type":"link","href":"http://en.wikipedia.org/wiki/Platform_as_a_service"},{"_key":"a5d1629c1a13","_type":"link","href":"https://devcenter.heroku.com/articles/config-vars"},{"_key":"1c9d24158131","_type":"link","href":"http://blog.vbalazs.me/2013/12/how-not-to-commit-passwords-to-openshift.html"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Egy másik lehetőség a jelszavak kezelésére a környezeti változók használata, ezt a megközelítést használják az elterjedt "},{"_type":"span","marks":["6963798536b1"],"text":"PaaS"},{"_type":"span","marks":[],"text":" felhőkben is ("},{"_type":"span","marks":["a5d1629c1a13"],"text":"Heroku"},{"_type":"span","marks":[],"text":", "},{"_type":"span","marks":["1c9d24158131"],"text":"OpenShift"},{"_type":"span","marks":[],"text":"). A rendszer a jelszavakat és az olyan erőforrásokat, mint az adatbázis connection string, ebben a formában teszi elérhetővé, a kódban elég a változót megadni, így nem szükséges azt külön módosítani a fejlesztői és éles környezetben."}]},{"_type":"code","code":"$ export MY_SECRET=myPassWord ","language":"sh"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":["strong"],"text":"Bash"}]},{"_type":"code","code":"#!/bin/bash jarsigner -keystore mystore.ks -storepass $MY_SECRET awesome.jar mycert ","language":"sh"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":["strong"],"text":"Python"}]},{"_type":"code","code":"import os pw = os.environ['MY_SECRET'] print \"Your password is\", len(pw), \"characters long\" ","language":"python"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":["strong"],"text":"Ruby"}]},{"_type":"code","code":"pw = ENV['MY_SECRET'] print \"Your password is #{pw.length} characters long\" ","language":"ruby"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A bash history miatt az "},{"_type":"span","marks":["code"],"text":"export"},{"_type":"span","marks":[],"text":" még mindig aggályos, ezt áthidalhatjuk úgy, hogy a jelenlegi munkafolyamatban deaktiváljuk a történet mentését az "},{"_type":"span","marks":["code"],"text":"unset HISTFILE"},{"_type":"span","marks":[],"text":" utasítással vagy egyszerűen elmentjük a változókat egy fájlba és futtatjuk."}]},{"_type":"code","code":"$ cat myvars.sh #!/bin/bash export MY_KEY1=mysecret1 export MY_KEY2=mysecret2 $ source myvars.sh ","language":"sh"},{"_type":"block","markDefs":[{"_key":"4903797721bc","_type":"link","href":"https://korok.sch.bme.hu/profile/show/uid/nightw"}],"style":"normal","children":[{"_type":"span","marks":["em"],"text":"A cikk szakmai felülvizsgálatáért és a javaslatokért köszönet "},{"_type":"span","marks":["em","4903797721bc"],"text":"night[w]"},{"_type":"span","marks":["em"],"text":"-nak!"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Happy scripting! "},{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBOUT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--84d177924506f649932f80336fc3051b890b60d5/automation.png","alt":"null"}}]}]}
{"_type":"post","_createdAt":"2014-02-18T19:00:00.000+01:00","publishedAt":"2014-02-18T19:00:00.000+01:00","title":"Tanfolyam plakát","body":[{"_type":"block","markDefs":[{"_key":"de7aaf8020b7","_type":"link","href":"https://profile.sch.bme.hu/profile/show/uid/kresshy"},{"_key":"dc38b29e7106","_type":"link","href":"http://kir-dev.github.io/tanfolyam/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Köszönjük "},{"_type":"span","marks":["de7aaf8020b7"],"text":"kresshy"},{"_type":"span","marks":[],"text":"-nek, hogy összerakta a plakátot a tanfolyamhoz. Minden fontos információt megtaláltok rajta. Ha többre lennél kíváncsi, akkor a "},{"_type":"span","marks":["dc38b29e7106"],"text":"tanfolyamunk weboldalán"},{"_type":"span","marks":[],"text":" további részleteket is találsz."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Találkozunk jövőhét kedden!"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBPUT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--f53ba1ac0da36be25fe0be9347c80ac5eaaba35a/tanf_plakat_2014.jpg","alt":"tanfolyam plakát"}}]}]}
{"_type":"post","_createdAt":"2014-02-22T01:00:00.000+01:00","publishedAt":"2014-02-22T01:00:00.000+01:00","title":"Front-end tooling Yeoman segítségével","body":[{"_type":"block","markDefs":[{"_key":"f6214dd68729","_type":"link","href":"http://yeoman.io/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Minden fejlesztőnek megvan a maga kedvenc eszközkészlete, melyet szívesen használ valamilyen fejlesztéshez, jelentsen ez egy IDE-t, egy szövegszerkesztőt, verziókezelőt, build rendszert vagy bármi hasonlót. A következőkben a "},{"_type":"span","marks":["em","f6214dd68729"],"text":"Yeoman"},{"_type":"span","marks":[],"text":" eszközkészletet, vagyis még inkább egy munkafolyamatot fogok bemutatni, melyet front-end fejlesztéshez lehet használni."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBMQT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--50d3242d2b291308b0fe3128f813b91a4cff9c17/2014-02-22-yeoman.jpg","alt":"yeoman"}}]},{"_type":"block","markDefs":[{"_key":"07537b2743ea","_type":"link","href":"http://en.wikipedia.org/wiki/Yeoman"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A "},{"_type":"span","marks":["07537b2743ea"],"text":"Yeoman"},{"_type":"span","marks":[],"text":" nevű programcsomag rendkívül megkönnyíti a front-end fejlesztők életét. Köszönhető ez a nagyon gazdag funkcionalitásának, mely könnyen kiegészíthető, konfigurálható, így tényleg a segédünkként tud szolgálni az eszköz. Alapvetően három, különállóan fejlesztett, de együttműködő NodeJS-ben írt alkalmazásról van szó, melyek különbözőképpen segíthetik munkánkat:"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":["strong"],"text":"Yo"},{"_type":"span","marks":[],"text":": scaffolding eszköz"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":["strong"],"text":"Bower"},{"_type":"span","marks":[],"text":": függőségkezelő eszköz"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":["strong"],"text":"Grunt"},{"_type":"span","marks":[],"text":": feladatfuttató eszköz"}]},{"_type":"block","markDefs":[{"_key":"be379a9363ea","_type":"link","href":"http://angularjs.org/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Egyesével bemutatom mire képesek és hogyan kell őket használni. A könnyebb érthetőség érdekében egy komplett példán keresztül fogom bemutatni a Yeoman-t: egy "},{"_type":"span","marks":["be379a9363ea"],"text":"AngularJS"},{"_type":"span","marks":[],"text":" alapú kezdő alkalmazást fogunk készíteni."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Előkövetelmények és telepítés"}]},{"_type":"block","markDefs":[{"_key":"53be29b7bb77","_type":"link","href":"https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager"},{"_key":"4db5d546c68b","_type":"link","href":"https://github.com/joyent/node/wiki/installation#wiki-building-on-gnulinux-and-other-unix"},{"_key":"4b569693a3e4","_type":"link","href":"https://github.com/joyent/node/wiki/installation#wiki-building-on-windows"},{"_key":"8bb36db49390","_type":"link","href":"https://github.com/joyent/node/wiki/installation#wiki-mac-osx"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Először is szükség lesz egy NodeJS telepítésére, ugyanis ez fogja futtatni a fenti programokat. Linuxon lehet "},{"_type":"span","marks":["53be29b7bb77"],"text":"csomagkezelőből"},{"_type":"span","marks":[],"text":", vagy "},{"_type":"span","marks":["4db5d546c68b"],"text":"forrásból telepíteni"},{"_type":"span","marks":[],"text":". "},{"_type":"span","marks":["4b569693a3e4"],"text":"Windows-hoz"},{"_type":"span","marks":[],"text":" és "},{"_type":"span","marks":["8bb36db49390"],"text":"Mac OSX rendszerre"},{"_type":"span","marks":[],"text":" elérhetőek bináris formátumban is."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ha ez megvan, következhet a konkrét eszközök telepítése:"}]},{"_type":"code","code":"# npm install -g yo bower grunt ","language":"sh"},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Yo"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Mit is jelent a "},{"_type":"span","marks":["em"],"text":"scaffolding"},{"_type":"span","marks":[],"text":"? Alapvetően ezzel a fejlesztés sebességét tudjuk növelni. Sablonokat generálhatunk, melyekből kiindulva állhatunk neki egy program elkészítésének. Ezek a sablonok sokfélék lehetnek, az egyszerű konfigurációs fájloktól kezdve, melyeket más programok használnak, egészen a saját elkészítendő programunk vázáig. Lehetnek ezek fejlesztést segítő szkriptek, komplett szoftverstack vagy más boilerplate kódok, melyeket előre generálhatunk az alkalmazásunkhoz."}]},{"_type":"block","markDefs":[{"_key":"d118db883877","_type":"link","href":"http://yeoman.io/official-generators.html"},{"_key":"fcbbc34aedfd","_type":"link","href":"http://yeoman.io/community-generators.html"},{"_key":"1f6b979adcd0","_type":"link","href":"http://lab.hakim.se/reveal-js/#/"},{"_key":"105d79424c7f","_type":"link","href":"http://expressjs.com/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ahhoz, hogy sablonokat tudjunk készíteni a Yo-val generátorokra lesz szükség. Egyrészt vannak "},{"_type":"span","marks":["d118db883877"],"text":"hivatalos"},{"_type":"span","marks":[],"text":" és még több a "},{"_type":"span","marks":["fcbbc34aedfd"],"text":"közösség által készített"},{"_type":"span","marks":[],"text":" generátorok, melyekkel teljes alkalmazás vázakat és hozzájuk tartozó környezetet tudunk generálni. Például készíthetünk teljes AngularJS környezetet (ami integrálja a Bower és Grunt eszközöket is), mobil first weboldalt, Wordpress alapkörnyezetet, "},{"_type":"span","marks":["1f6b979adcd0"],"text":"RevealJS"},{"_type":"span","marks":[],"text":" vázakat, de készíthetünk szerver oldali alkalmazás szkeletonokat is, például "},{"_type":"span","marks":["105d79424c7f"],"text":"ExpressJS"},{"_type":"span","marks":[],"text":"-hez. Kezdjük el tehát az AngularJS kiinduló programunkat:"}]},{"_type":"code","code":"# npm install -g generator-angular $ mkdir angularapp && cd angularapp $ yo angular example ","language":"sh"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Elsőként telepítettük az AngularJS-hez szükséges generátort, majd egy mappában legeneráltuk a teljes kiinduló alkalmazás sablont. Az AngularJS egy MVVM keretrendszer, így tudunk olyan sablonokat generálni, mint az MVC-ből is ismert Controller, vagy a View elemeket valósítják meg."}]},{"_type":"code","code":"$ yo angular:controller myController $ yo angular:view myView ","language":"sh"},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Bower"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Senki nem szereti az alkalmazásának a függőségeit kézzel letölteni és azok minden újabb verziójánál újra eljátszani ezt a folyamatot. Az egyszerű megoldás valamilyen függőségkezelő eszköz ( "},{"_type":"span","marks":["em"],"text":"dependency management tool"},{"_type":"span","marks":[],"text":" ) használata, mellyel mindezt megtehetjük. A program intelligensen feloldja és telepíti a kívánt CSS, vagy JavaScript könyvtár saját függőségeit is. Például így kereshetünk a jQuery projektek között és telepíthetjük, a jQuery UI-t, majd frissítjük az összes telepített függőségünket:"}]},{"_type":"code","code":"$ bower search jquery $ bower install jquery-ui $ bower update ","language":"sh"},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Grunt"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az utolsó eszköz amit bemutatok a Grunt, mely egy parancssoros feladat futtató ( "},{"_type":"span","marks":["em"],"text":"task runner tool"},{"_type":"span","marks":[],"text":" ). Ez sokat nem mond el magáról, de egy elég általános célú eszköz, ezért konkrétabban nem is lehet definiálni. Legjobban JavaScript alapú fejlesztéseink során alkalmazhatjuk, és temérdek feladatot végeztethetünk el vele nagyon egyszerűen. Néhány példa a sokrétű használhatóságára:"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"JavaScript fájlok minimalizálása, kódtömörítés ( "},{"_type":"span","marks":["em"],"text":"minify"},{"_type":"span","marks":[],"text":" )"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"JavaScript kód obfuszkálása ( "},{"_type":"span","marks":["em"],"text":"uglify"},{"_type":"span","marks":[],"text":" )"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"képek tömörítése a webre"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"JavaScript és CSS fájlok összefűzése"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"livereload Web szerver indítása teszteléshez, melyben az alkalmazásunk fut"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"szintaktikai ellenőrzések futtatása"}]},{"_type":"block","markDefs":[{"_key":"4e077b72a07f","_type":"link","href":"http://en.wikipedia.org/wiki/Continuous_integration"}],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"egység és integrációs tesztek futtatása (előzővel együtt használva "},{"_type":"span","marks":["em","4e077b72a07f"],"text":"continuous integration"},{"_type":"span","marks":[],"text":"-re is használható)"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ezek csak a beépített és gyakran használt funkciók, az eszköz ennél sokkal többre képes és egyszerűen kiegészíthető a közösség által készített újabb taszkokkal. Példa a használatára:"}]},{"_type":"code","code":"## livereload webszerver indítása $ grunt serve ## tesztek futtatása $ grunt test ## alkalmazás buildelése (kódtömörítés, obfuszkálás, stb.) $ grunt build ","language":"sh"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ezzel a Yeoman bemutatásának végére értünk, remélem hasznosnak találtátok, és sikerült bemutatni, mivel tudják kiegészíteni a front-end fejlesztők eszközparkját ezek a programok."}]}]}
{"_type":"post","_createdAt":"2014-02-23T11:35:00.000+01:00","publishedAt":"2014-02-23T11:35:00.000+01:00","title":"Single Sign-on","body":[{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Már többször ígértem, hogy írok a Single Sign-on-ról (SSO). Az utóbbi években ez a technológia határozta meg a kör egyik fő irányvonalát. Valójában nem csak a kör életében volt ez meghatározó, hanem (kis túlzással) a schönherzes közéletben is."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ebben a bejegyzésben megpróbálom felvázolni, hogy mi is az az SSO pontosan, hol találkozhattatok vele, milyen problémákba ütköztünk és mire számíthattok a következő félévekben."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Mi az az SSO?"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A SSO inkább egy koncepció, mint egy konkrét technológia. Röviden a lényege annyi lenne, hogy a felhasználókezelés egy központi helyen van megvalósítva. Ez a felhasználók számára azt jelenti, hogy egyetlen felhasználónév-jelszó párost kell megjegyezniük, valamint ha valahol bejelentkeztek, akkor mindenhol bejelentkeztek egyszerre (erre utal a név is). A látszólag független rendszerek felismerik, hogy a felhasználó már belépett egyszer és rögtön hozzáférést engednek a védett tartalomhoz."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Talán a legismertebb SSO rendszer éppen a Google-nél található. Ha megfigyeljük, akkor a Gmail, a Drive, a Youtube és még sok másik Google szolgáltatás is jól elkülönül, de ugyanazzal a felhasználónévvel és jelszóval tudunk belépni mindenhol. Sőt, belépni is csak egyszer kell és ezt bármelyik szolgáltatásban megtehetjük."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"A VIR lelke az SSO"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A VIR központi része az SSO. Jelenleg a legtöbb körös holnapra a már jól ismert kék bejelentkező felületen tudtok belépni."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBMUT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--0fcca74443f7fc3427e775f291cb4a750c242388/2014-02-23-sso-vir-login.jpg","alt":"VIR SSO login oldal"}}]},{"_type":"block","markDefs":[{"_key":"c8603ecc0fcc","_type":"link","href":"/post/2014-01-23-pek-jelen-es-jovo-i"},{"_key":"f175095bff96","_type":"link","href":"https://profil.sch.bme.hu"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az "},{"_type":"span","marks":["c8603ecc0fcc"],"text":"eredeti VIR koncepció"},{"_type":"span","marks":[],"text":" központi gondolata a lazán összekapcsolt rendszerek voltak. Ez a laza kapcsolat a felhasználókezelésben öltött testet: minden társrendszer ugyanazokkal a felhasználókkal dolgozik, amit egyetlen helyen tartunk nyilván (ez lenne a "},{"_type":"span","marks":["f175095bff96"],"text":"PÉK"},{"_type":"span","marks":[],"text":")."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ezzel mindenki életét megkönnyítettük. A felhasználókét azért, mert egyetlen felhasználói fiókkal hozzáférhetnek az összes Schönherzhez köthető szolgáltatáshoz. Beléphetnek a PÉK-be vagy a wikire, de akár a saját körük holnapjára is. Az üzemeltetők dolgát pedig azért, mert a felhasználókezelés és tárolás terhét veszi le a vállukról."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A marketing szövegünk valahogy így nézhetett volna ki:"}]},{"_type":"block","style":"blockquote","markDefs":[],"children":[{"_type":"span","marks":[],"text":"Egy új projektet szeretnél útjára indítani a Schönherzen belül? Írd meg, szólj nekünk és a felhasználókat mi adjuk. Az új alkalmazás rögtön átugorhatja a felhasználók regisztrációra csábítását, mert a karon a VIR-ben mindenki (értsd "},{"_type":"span","marks":["em"],"text":"mindenki"},{"_type":"span","marks":[],"text":") benne van."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"OpenAM"}]},{"_type":"block","markDefs":[{"_key":"681855491326","_type":"link","href":"http://openam.forgerock.org/"},{"_key":"8820c7fc7cd1","_type":"link","href":"http://forgerock.com/products/open-identity-stack/openam/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az SSO funkcionalitást használni nagyon kényelmes, de a megvalósítása nem triviális. Mi erre egy kész szoftvert, az "},{"_type":"span","marks":["681855491326"],"text":"OpenAM"},{"_type":"span","marks":[],"text":"-et (korábbi nevén OpenSSO) használtuk, amit a Sun, majd a ForgeRock fejlesztett. Ez a megoldás felelt a felhasználók azonosításáért, a felhasználó profiljának kiolvasásáért az adatbázisból és a munkamenetek kezeléséért. Emellett természetesen számtalan olyan funkciója volt, amit (sajnos) mi nem használtunk, érdemes "},{"_type":"span","marks":["8820c7fc7cd1"],"text":"utánaolvasni"},{"_type":"span","marks":[],"text":"."}]},{"_type":"block","markDefs":[{"_key":"e0c8a5c1284c","_type":"link","href":"http://shibboleth.net/products/service-provider.html"},{"_key":"02f4f518b26b","_type":"link","href":"https://wiki.niif.hu/index.php?title=F%C3%B6der%C3%A1ci%C3%B3"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Mivel a körös oldalak shared hosting megoldású szervereken vannak (wadon, lothlorien), ezért - és mert az SSO apache agenttel sem voltak jó tapasztalatok - telepítésre került egy "},{"_type":"span","marks":["e0c8a5c1284c"],"text":"Shibboleth Service Provider"},{"_type":"span","marks":[],"text":". Ennek segítségével a társrendszerek (körök oldalai) egyszerűbben felvehetőek voltak a "},{"_type":"span","marks":["02f4f518b26b"],"text":"föderációba"},{"_type":"span","marks":[],"text":" és tudták használni az SSO nyújtotta előnyöket. Szerver üzemeltetés szempontjából sajnos továbbra sem volt tökéletes a megoldás: az Apache webszerverbe épülő Shibboleth modul gyakran okozott random leállást (és ezzel nem kis fejfájást a KSZK-s kollégáknak)."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Problémák"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ha mindez eddig túl szépnek tűnt, akkor nem jársz rossz nyomon. Az OpenAM és Shibboleth bonyolult technológiák, amiket üzemeltetni nem éppen egyszerű feladat. Személy szerint én viszonylagos biztonságból figyelem az eseményeket, de egy-egy Shibboleth konfiguráció mindig véres harcot jelent."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Egy új rendszer integrálása mindig kihívásokat tartogat. Nehéz általánosítani, könnyű előre nem látott problémákba futni, de ami a Kir-Dev szempontjából a legrosszabb, hogy a részünkről is aktív és néha időigényes elfoglaltság egy új rendszert behozni a VIR SSO alá."}]},{"_type":"block","markDefs":[{"_key":"2e01719c6da1","_type":"link","href":"https://login.bme.hu/admin/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A technológiai problémákon túl megint beleütközünk az állandósult emberi erőforrás hiányába. A körön belül az OpenAM nem örvend túlzott népszerűségnek - konkrétan senkit sem érdekel. Hónapokon belül ott fogunk tartani, hogy az utolsó körtag, aki még értett hozzá, elérhetetlen messzeségbe kerül. Ha pedig senki nem ért hozzá, akkor értelemszerűen üzemeltetni sem fogjuk tudni. Ezzel egy időben a "},{"_type":"span","marks":["2e01719c6da1"],"text":"BME címtárral"},{"_type":"span","marks":[],"text":" való integráció is egyre sürgetőbbé válik. OpenAM-en keresztül valószínűleg megoldható lenne, de érdeklődés hiányában ez sajnos nem opció."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Mi lesz ezután?"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A SSO végső célja az lenne, hogy az összes schönherzes rendszert egy tető alá hozza. Ez a mai napig még nem sikerült, mert bizonyos (KSZK által üzemeltetett) szolgáltatásokat nem érhetsz el a VIR fiókoddal. A házon belüli teljesen egységes autentikáció gondolata már régóta foglalkoztat minket, és ötletelések is fel-felbukkannak, de eddig még nem sikerült érdemben közelebb hoznunk az SchAcc-ot a VIR fiókhoz (vagy éppen fordítva)."}]},{"_type":"block","markDefs":[{"_key":"b0b1c84967f8","_type":"link","href":"https://git.sch.bme.hu/kszk/authsch/blob/master/README.md"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A KSZK berkein belül már nagy erőkkel dolgoznak az "},{"_type":"span","marks":["b0b1c84967f8"],"text":"auth.sch"},{"_type":"span","marks":[],"text":"-n, ami koncepciójában hasonló megoldás lesz, mint a jelenlegi VIR SSO, csak a mögötte lévő technológia teljesen más."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A jövőben azt tervezzük, hogy a jelenlegi SSO megoldásunkat nyugdíjazzuk és mi is felsorakozunk az auth.sch mögé. Ebben az esetben a határidők adottak, mert a következő őszi félévben a gólyáknak már az új, auth.sch-t használó rendszeren keresztül kellene regisztrálni a PÉK-be."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A jelenlegi SSO is megmarad még egy ideig, amíg mindenkinek sikerül áttérnie az új auth.sch-ra, utána pedig leállítjuk a rendszert és könnyes búcsút veszünk egy korszaktól."}]},{"_type":"block","markDefs":[{"_key":"451eadb7cdf4","_type":"link","href":"https://profile.sch.bme.hu/profile/show/uid/balo"},{"_key":"cb9c2b2c664a","_type":"link","href":"https://profile.sch.bme.hu/profile/show/uid/aldaris"}],"style":"normal","children":[{"_type":"span","marks":["em"],"text":"A cikk szakmai felülvizsgálatáért és az OpenAM-es részekért köszönet "},{"_type":"span","marks":["em","451eadb7cdf4"],"text":"balonak"},{"_type":"span","marks":["em"],"text":" és "},{"_type":"span","marks":["em","cb9c2b2c664a"],"text":"aldarisnak"},{"_type":"span","marks":["em"],"text":"!"}]}]}
{"_type":"post","_createdAt":"2014-02-24T23:12:00.000+01:00","publishedAt":"2014-02-24T23:12:00.000+01:00","title":"Android app patch (forráskód nélkül ;)...)","body":[{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Bizony! Jól látjátok, az eddig már bejáratott webfeljesztős témáktól most ugrunk egy szép nagyot. A következő pár percben részese lehettek egy androidos alkalmazás patchelésének. A dolog érdekessége pedig ott kezdődik, hogy a forráskód nem áll a rendelkezésünkre. Az úgy túl könnyű feladat lenne. Megkeresni a hibás kódrészletet, kijavítani a hibát és újrafordítani az alkalmazást, majd feltölteni a telefonra. A cél persze ugyanaz, és nagyjából a folyamat is, egyedül a módszerek különböznek. Ebben a cikkben megismerkedhettek a Reverse engineeringgel, a különböző toolokkal és magával a folyamattal. A sikerélményről pedig majd a végén, mert ez vagy sikerül vagy nem."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Let the game begin!"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Fut egy alkalmazás (nem a sajátod) ami nem várt hibát produkál. A program bluetoothon kommunikál egy mikrokontrollerrel és az adatátvitel megszakad. Kapunk egy hibaüzenetet miszerint timeout volt. A dolog érdekessége, hogy csak akkor kapunk timeoutot, hogyha 29000 byte-nál több adatot akarunk lekérni az eszközről, ami ez esetben egy altimeter."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBOQT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--8aae98b96bf34d37528f3eefe34eff64b870020f/app.png","alt":"the_application"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A működéséről csak annyit tudunk amit látunk. Ha valaki jártas az Android fejlesztésben akkor viszont tudja, hogy mi történik a rendszer mélyében, és talán kicsi motivációt érez arra, hogy a hibát kikalapálja a szoftverből. Egy nagyon egyszerű dolgot fogunk megcsinálni, mégpedig átírjuk, hogy a timeout sokkal később következzen be. Ez nem biztos, hogy megoldja a problémát, de jó lehetőség arra, hogy a program működésébe beleássuk magunkat, és az esetleges hiba nyomára is rábukkanjunk eközben."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"I need the installer..."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Kell a telepítő fájl, ami nélkül esélyünk sincs belefogni a munkába. Ezt mindenféle backup programmal le lehet szedni a telefonról rootolás nélkül, de mivel ez egy olyan eszközhöz járt, amihez a gyártó a honlapjára feltöltötte a telepítő *.apk fájlt, így nem kell ezzel foglalkozni. A következő programok kellenek ahhoz, hogy el tudjuk végezni a feladatot: apktool, dex2jar, jd-gui, apk-signer. Mindegyiknek megvan a maga feladata, ahogy azt majd folyamat közben látni is fogjátok."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Tear it apart 4 fun"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Fogjuk meg az apktoolt és szedjük szét a telepítőt. Ehhez parancssorban adjuk ki a következő parancsot:"}]},{"_type":"code","code":"apktool decode FD-A(V2.0).apk I: Baksmaling... I: Loading resource table... I: Loaded. I: Decoding AndroidManifest.xml with resources... I: Loading resource table from file: C:\\Users\\Kresshy\\apktool\\framework\\1.apk I: Loaded. I: Regular manifest package... I: Decoding file-resources... I: Decoding values */* XMLs... I: Done. I: Copying assets and libs... ","language":"sh"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Láthatjuk, ahogy elkezdi szétszedni az alkalmazást. Az apktool smali kódot állít elő, ami egyfajta reprezentációja a Dalvik bytecodenak. A sorok között megbújik a bytecode, de sokkal olvashatóbb. Megvan a soroknak a számozása, jelölve van, hogy az adott kódrészlet egy függvény, egy változó, stb. A Dalvik bytecode kicsit különbözik a Java bytecodetól, mégpedig abban, hogy regiszter alapú, míg a Java bytecode stack alapú. Sokkal tömörebb, így kisebb méretet foglal a mobil eszközön és eléggé jól ki van optimalizálva a gyors futás érdekében (azért tudjuk, hogy az android képes akadozni még így is). A Java itt csak mint nyelv jelenik meg a fejlesztés során, minden kicsit másképp működik mint az asztali környezetben. Itt kitérnék rá, hogy a Google nemsokára lecseréli a Dalvik VM-et az ART-ra. A változással gyorsulni fog a rendszer mivel a JIT (Just-In-Time) compilertől megszabadulnak és helyette AOT (Ahead-Of-Time) compiler lesz. Akit érdekel a runtime-ok világa az olvasson utána a megadott linkeken, továbbiakban itt nem lesz róla szó."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBPZz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--d228a0ba14a8715c283463ea15d1ef13997e8d1e/unzip.png","alt":"unzip_this_stuff"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Nézzük tovább a telepítő szétszedését. Nem elég az apktoollal szétszedni az alkalmazást, mivel a smali kódból elég nehéz megérteni a működését. Lehetőségünk van visszaállítani a Java kódot is a telepítőből. Abban ne reménykedjünk, hogy egy az egyben azt a kódot fogjuk visszakapni amit az alkalmazás fejlesztője megírt, de elég közel áll majd hozzá, és sokkal könnyebb belőle kiszedni, hogy hogyan működik a program. Az "},{"_type":"span","marks":["em"],"text":".apk többé-kevésbé egy tömörített állomány, így bármilyen tömörító programmal meg tudjuk nyitni és ki tudjuk csomagolni. Ez a folyamat visszafele nem működik ott majd trükközni kell egy kicsit. Találni fogunk egy classes.dex fájt. Ezt a fájlt nevezzük Dalvik Executablenek és lényegében az ebben található kód fut a telefonon. Most jön képbe a következő hasznos tool, mégpedig a dex2jar. Ezzel a Dalvik futattható állományból egy "},{"_type":"span","marks":[],"text":".jar fájlt tudunk csinálni. Jelenleg itt visszafele haladunk egy alkalmazás telepítő létrehozásának a folyamatában. Ha Eclipseben rákattintasz a fordításra akkor elsőként egy "},{"_type":"span","marks":["em"],"text":".jar fájl jön létre, majd abból készül a "},{"_type":"span","marks":[],"text":".dex fájl, végül pedig az "},{"_type":"span","marks":["em"],"text":".apk, amit fel tudsz telepíteni a telefonodra (itt több minden történik persze de most erre se térünk ki). Mostanra eljutottunk odáig, hogy megvannak a smali fájlok, amikben el tudjuk végezni a szükséges patcheléseket, és megvan a "},{"_type":"span","marks":[],"text":".jar fájl, amiből vissza tudjuk állítani a java kódot."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Reverse engineer the code :)"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Kezdjük el feltérképezni az alkalmazás működését. Az első fájl amit megnyitunk az AndroidManifest.xml amit az apktool visszaállított nekünk olvashatóra. Ebben kikeressük az alkalmazásunk belépési pontját, ami jelen esetben egy activity lesz, mégpedig az, amelyik legelsőnek elindul."}]},{"_type":"code","code":"<activity android:label=\"@string/AppTitle\" android:icon=\"@drawable/logo\" android:name=\".frmMain\" android:screenOrientation=\"portrait\"> <intent-filter> <action android:name=\"android.intent.action.MAIN\" /> <category android:name=\"android.intent.category.LAUNCHER\" /> </intent-filter> </activity> ","language":"xml"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ezt a részt keressük, és ha megvan el is indíthatjuk a következő eszközünket a jd-gui-t és betölthetjük bele a már korábban elkészített "},{"_type":"span","marks":["em"],"text":".jar fájlt. A Jd-gui egy grafikus felületű szoftver ami képes arra, hogy a "},{"_type":"span","marks":[],"text":".jar fájlból visszaállítsa a Java kódot. Olyan mintha egy IDE lenne csak nem fogod benne szerkeszteni a kódot. Most el kell kezdeni megkeresni az említett részt, ahol megkapjuk ezt a hibaüzenetet. Elsőként szedjük össze, hogy mit tudunk a programról. Valószínű, hogy egy activityt keresünk amiben van egy TextField, ahova kiírja a már ismert hibaüzenetet."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Androidon érdemes szinte mindent a konfigurációs *.xml fájlokban tárolni, így reméljük, hogy a hibaüzenet amit keresünk szövegként megtalálható lesz a strings.xml fájlban, vagy valami más xml-ben. Jól sejtettük, ott van! Mostmár csak az kell megkeresni, hogy az alkalmazásban, hol használhatja ezt a szöveget. A fő activity két továbbít tud elindítani. Az egyik az frmHardware a másik az frmDraw. Tudjuk, hogy az alkalmazás egy grafikont rajzol ki a mért adatokból, úgyhogy mi most a másik irányba fogunk elindulni. Ez egy nagyon egyszerű alkalmazás, és bejött az elméletünk."}]},{"_type":"code","code":"public static final int ReadDataTimeout = 2131034155; ","language":"java"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Itt lesz az amit keresni fogunk. Egy android alkalmazás lelke az a bizonyos R.class fájl, amihez fejlesztés során nem nyúlhatunk. Ezt magától generálja a fejlesztőkörnyezet és ez tartalmazza a különböző erőforrások összerendelését azokkal a változókal (integer típusuak) amin keresztül elérjük őket. Tehát az R fájlból kikeressük a változónkat, megnézzük az integer értéket, ami hozzá van rendelve, és rákeresünk az frmHardware fájlban erre az értékre."}]},{"_type":"code","code":"String str3 = frmHardware.this.GetString(2131034155); Message localMessage3 = new Message(); localMessage3.obj = str3; localMessage3.what = 4; frmHardware.this.handler.sendMessage(localMessage3); ","language":"java"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Bumm, ott van megtaláltuk! Rengeteg kód, rögtön látjuk, hogy ez egy szálkezelt alkalmazás. Hirtelen rádöbbenünk, hogy a bluetooth kapcsolatot és kommunikációt megvalósító kódok közepén vagyunk. Felmerül a kérdés, hogy innen hova tovább? Nem futamodunk meg, szem előtt tartjuk a célt! Egy számot keresünk, ez lehet konstans lesz de az is előfordulhat, hogy a kódba van beleégetve egy feltételként (ez a valószínűbb). Elkezdjük feltérképezni a program futását. Megjegyezzük, hogy ez a kódrészlet hol volt és mi volt, és elkezdjük feltérképezni ennek az activitynek a működését. Megnézzük a gombok megnyomására milyen függvények hívódnak meg. Megpróbáljuk megérteni a szálak működését és azt, hogy azok a bizonyos handlerek mit csinálnak? Segítek, a szálak közötti kommunikáció megvalósítására használják. Ha ismered az Android SDK-t akkor ez a folyamat elég gyorsan fog menni. Most, hogy már nagyjából átlátjuk remélhetőleg megtaláltuk a feltételünket, ahol a timeout vizsgálat történik."}]},{"_type":"code","code":"if (System.currentTimeMillis() - frmHardware.nTimeStep > 3000L) { ... } ","language":"java"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ez egy long típusú érték. 3000 ms várakozás után terminálni fogja azt a szálat amin a bluetooth kapcsolat fut, auch. Mint már említettem, nem ez a megoldása a problémának, de remek játék más kódjában túrkálni és egyéb működést kikényszeríteni az alkalmazásból. Olyan mintha hackerek lennénk, az igazság az, hogy azok vagyunk! :) W000T ..."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Edit, build and run the stuff"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Oké tudjuk, hogy 3000-ret keresünk de a smali kódban minden szám hexában van. Ha nem akarod kézzel kiszámolni, hogy ez mennyi 16-os számrendszerben, akkor váltsd át az operációs rendszer számológépével. Windowson tud ilyet a ketyere programozó üzemmódban. Ideje megkeresni a smali kódban, hogy hol van ez az érték. A fájlokat az osztályneveknek megfelelően nevezi el az apktool. Az egyedül érdekes dolog a fájl nevében található dollárjel például itt is: frmHardware$1.smali. Ezekben a fájlokban találhatóak azok az osztályok amelyekek megtalálhatóak az frmHardware osztályban. Ezért van itt ennyi frmHardware.smali-tól kezdve frmHardware$13.smali-ig egy csomo fájl, ilyen névvel. Keressünk az egyik fájlban rá az adott hexadecimális értékre ami 3000 esetén 0xbb8-lesz. Ha megtaláltuk akkor bizonyosodjunk meg arról, hogy jó helyen járunk-e. Ez elég nehezen olvasható rész de felfedezhetőek a függvények és ha láttál már assembly-t akkor a parancsok között is megtalálod amiket keresel."}]},{"_type":"code","code":"sget-boolean v5, Lorg/skypup/BT;->lUploadBusy:Z if-eqz v5, :cond_2 .line 136 invoke-static {}, Ljava/lang/System;->currentTimeMillis()J move-result-wide v3 .line 137 .local v3, nTimeNow:J invoke-static {}, Lfdrc/fda/frmHardware;->access$5()J move-result-wide v5 sub-long v5, v3, v5 const-wide/16 v7, 0xbb8 cmp-long v5, v5, v7 if-lez v5, :cond_1 .line 138 iget-object v5, p0, Lfdrc/fda/frmHardware$2;->this$0:Lfdrc/fda/frmHardware; const v6, 0x7f05002b #calls: Lfdrc/fda/frmHardware;->GetString(I)Ljava/lang/String; ","language":"text"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Láthatjuk az UploadBusy függvényt ami egy boolean értékkel tér vissza, majd pedig azt, hogy lekérjük a rendszeridőt currentTimeMillis(). A sub-long nál megtörténik a kivonás, és a cmp-long nál pedig megtörténik az összehasonlítás a 0xbb8 értékkel. Innen már lehet érezni, hogy jó helyen vagyunk. Nincs más dolgunk mint átírni ezt a const-wide sorban levő értéket 10000-re ami 0x2710 és reménykedünk, hogy nem fog összeomlani az alkalmazás."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Lehet csomagolni"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ideje az alkalmazást újra felépíteni. Ezt az apktool segítségével fogjuk megtenni a következő paranccsal:"}]},{"_type":"code","code":"apktool build --force-all FD-A(V2.0) FD-A(V2.0).apk ","language":"sh"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Kaptunk egy *.apk telepítő fájlt! Ohh már majdnem megvagyunk, azért még hiányzik egy fontos lépés, de mielőtt még azt megcsinálnánk próbáljuk meg feltelepíteni a telefonra a kapott alkalmazást. Ki gondolta volna, hogy ez nem megy :). Kapunk egy furcsa hibaüzenetet: "},{"_type":"span","marks":["code"],"text":"\"Android package has no certificates at entry ... ignoring\""},{"_type":"span","marks":[],"text":". Lehet vannak még benne egyéb információk, de minket ez érdekel. A telepítő amit csináltunk nincs aláírva :O! Ez így bizony nem fog soha éles rendszerre feltelepülni. A megoldás az, hogy írjuk alá! Erre való az apk-signer amivel tudunk csinálni egy saját keystore-t és ennek a segítségével aláírni a már kész telepítőt. Miután ezt megtettük fel tudjuk telepíteni a megpatchelt alkalmazásunkat ami remélhetőleg megjavul."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Mit tanultunk mi ebből?"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Jelen esetben sajnos ez nem segített a probléma megoldásában, de remek példa volt arra, hogy hogyan álljunk neki egy ilyen összetett feladatnak. Érdemes rászánni egy-két órát mire sikerül felépíteni a fejedben azt az absztrakt magas szintű struktúrát, ami egy idegen program működésének a megértéséhez kell. Megismerkedtünk rengeteg új és hasznos eszközzel, illetve ez a módszer alkalmas arra is, hogy ha kell szétszedjünk egy programot, megnézzük az implementációt és ötletet merítsünk belőle a saját programunkhoz. Mindig azt mondják, hogy más kódjából sokat lehet tanulni és ez igaz is. Ugyanakkor hozzá kell tennem, hogy nem etikus csak így turkálni más szoftverében. Gondolom ti se örülnétek neki, ha az engedélyetek nélkül elkezdenék lemásolni a programotoknak a belsejét. A végére még tartogatok egy meglepetést! Lehetőség van arra, hogy megnehezítsük az emberek dolgát, ha szétszedik az alkalmazásunkat. A natív kódot nehéz olvasni, sok mindent érdemes c++-ban implementálni. Az assembly-ben lévő kódot sokkal nehezebb visszafejteni és így a program működését is megérteni. A Java részéhez pedig használjunk obfuszkátort, erre van beépített tool az Android SDK-ban! Remélem tetszett nektek ez a cikk, a kérdéseket nyugodtan tegyétek fel kommentben!"}]}]}
{"_type":"post","_createdAt":"2014-03-06T17:20:00.000+01:00","publishedAt":"2014-03-06T17:20:00.000+01:00","title":"Boundaries","body":[{"_type":"block","markDefs":[{"_key":"f0995327af1a","_type":"link","href":"https://twitter.com/garybernhardt"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ma egy érdekes előadással jelentkezünk. "},{"_type":"span","marks":["f0995327af1a"],"text":"Gary Bernhardt"},{"_type":"span","marks":[],"text":" beszél a szoftverek lelki világáról. Ebben a picit több, mint fél órában elsősorban a szoftverkomponensek közötti határvonalakról beszél, de érinti többek között a tesztelés témakörét is. Külön érdekes, hogy hogyan mossa össze az OO és a funkcionális programozás határait."}]},{"_type":"block","markDefs":[{"_key":"43866e8651ef","_type":"link","href":"https://www.destroyallsoftware.com/talks/boundaries"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A videó "},{"_type":"span","marks":["43866e8651ef"],"text":"Destroy All Software oldalán"},{"_type":"span","marks":[],"text":" érhető el."}]}]}
{"_type":"post","_createdAt":"2014-03-13T21:30:00.000+01:00","publishedAt":"2014-03-13T21:30:00.000+01:00","title":"Function.prototype.call, apply és bind","body":[{"_type":"block","markDefs":[{"_key":"d936c090b10b","_type":"link","href":"http://kir-dev.github.io/tanfolyam/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A "},{"_type":"span","marks":["d936c090b10b"],"text":"web alapozó tanfolyamunk"},{"_type":"span","marks":[],"text":" JavaScript alapozó előadásán belefutottunk két olyan témába, amelyek bőven túlmutatnak egy bevezető keretein. Sőt, egy átlag weboldal fejlesztésénél sem igazán futunk bele ezekbe a dolgokba."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ebben a bejegyzésben a "},{"_type":"span","marks":["code"],"text":"Function.prototype"},{"_type":"span","marks":["code"],"text":"call"},{"_type":"span","marks":[],"text":", "},{"_type":"span","marks":["code"],"text":"apply"},{"_type":"span","marks":[],"text":" és "},{"_type":"span","marks":["code"],"text":"bind"},{"_type":"span","marks":[],"text":" metódusairól fogok picit részletesebben írni. A minisorozat második részében pedig a "},{"_type":"span","marks":["code"],"text":"new"},{"_type":"span","marks":[],"text":" operátor rejtélyeibe fogunk belemászni."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Metódusok"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Érdemes egy pillanatra elidőzni a metódusokon. Minden nap használjuk őket, de fel sem merül bennünk, hogy valami különleges dologról lenne szó. Szerencsére nincs is, csupán az objektum-orientált programozással együtt a függvény fogalma is átalakult némileg."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Míg a függvény egy olyan képződmény, ami a külvilággal mit sem törődve végzi dolgát, addig a metódusnak (vagy más néven tagfüggvénynek) mindig van kontextusa. A metódus önmagában nem értelmezhető, mindig van egy fogadó objektuma. Ezt a fogadó objektumot sok programozási nyelven a "},{"_type":"span","marks":["code"],"text":"this"},{"_type":"span","marks":[],"text":" kulcsszóval érhetjük el. Ez adja kontextust, ahol elérhető az objektum belső állapota."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Metódusok JavaScriptben"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"JavaScriptes világban a "},{"_type":"span","marks":["code"],"text":"function"},{"_type":"span","marks":[],"text":" kulcsszó szolgál a függvények definiálására. Ez kicsit csalóka, mert a függvények lehetnek metódusok is. Sőt, ha nagyon ragaszkodom az előbbiekben leírt definícióhoz, akkor minden függvény egyben metódus is, mert JavaScriptben minden függvényben elérhető a "},{"_type":"span","marks":["code"],"text":"this"},{"_type":"span","marks":[],"text":" kulcsszó."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az már egy sokkal érdekesebb kérdés, hogy egy adott pillanatban a "},{"_type":"span","marks":["code"],"text":"this"},{"_type":"span","marks":[],"text":" mire is mutat. Általánosságban elmondható, hogy arra mutat, amire számítanánk, de néha érhetnek meglepetések."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A klasszikus esetben tényleg a fogadó objektumra mutat."}]},{"_type":"code","code":"var obj = { myMethod: function () { console.log(this) } } obj.myMethod() // => Object {myMethod: function} ","language":"javascript"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Itt egyértelmű, hogy az "},{"_type":"span","marks":["code"],"text":"obj"},{"_type":"span","marks":[],"text":" változóban tárolt objektumra mutat a "},{"_type":"span","marks":["code"],"text":"this"},{"_type":"span","marks":[],"text":", végülis a "},{"_type":"span","marks":["code"],"text":"myMethod"},{"_type":"span","marks":[],"text":" az "},{"_type":"span","marks":["code"],"text":"obj"},{"_type":"span","marks":[],"text":" metódusa."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A másik sokat használt eset, amikor a nagyvilágban van egy függvényem és azt hívom meg."}]},{"_type":"code","code":"var f = function () { console.log(this) } f() // => Window {...} ","language":"javascript"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ebben az esetben nincs explicit fogadó objektum. Viszont a "},{"_type":"span","marks":["code"],"text":"window"},{"_type":"span","marks":[],"text":" ott ül mindennek a tetején és a legvégén nála futnak össze a dolgok."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ebből látszik, hogy amennyiben van explicit fogadó objektum, akkor a "},{"_type":"span","marks":["code"],"text":"this"},{"_type":"span","marks":[],"text":" arra állítódik be, ha nincs, akkor pedig a "},{"_type":"span","marks":["code"],"text":"window"},{"_type":"span","marks":[],"text":"-ra. Látni fogjuk, hogy akkor is ez a helyzet, ha a "},{"_type":"span","marks":["code"],"text":"this"},{"_type":"span","marks":[],"text":" értékének "},{"_type":"span","marks":["code"],"text":"null"},{"_type":"span","marks":[],"text":"-t vagy "},{"_type":"span","marks":["code"],"text":"undefined"},{"_type":"span","marks":[],"text":"-ot állítunk be."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Függvényhívás kicsit másképp"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az alap koncepciót lehet kicsit bonyolítani. Gondoljunk csak a következő esetre:"}]},{"_type":"code","code":"var obj = { method: function (f) { f() }, otherMethod: function () { var f = function () { console.log(this) } f() } } obj.method(function () { console.log(this) }) // => Window {...} obj.otherMethod() // => Window {...} var otherObj = { f: function () { console.log(this) } } obj.method(otherObj.f) // => Window {...} ","language":"javascript"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A fenti példa nagyon sarkított, és itt valójában mindegy, hogy mi a "},{"_type":"span","marks":["code"],"text":"this"},{"_type":"span","marks":[],"text":" értéke. Viszont ha már egy callbackről beszélünk, akkor jó lenne, ha a "},{"_type":"span","marks":["code"],"text":"this"},{"_type":"span","marks":[],"text":" értéke a helyén lenne."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Erre nyújt megoldást a "},{"_type":"span","marks":["code"],"text":"call"},{"_type":"span","marks":[],"text":" és az "},{"_type":"span","marks":["code"],"text":"apply"},{"_type":"span","marks":[],"text":". Ugyanaz a feladatuk, csak a szignatúrájuk más. Mindkét metódussal a "},{"_type":"span","marks":["code"],"text":"this"},{"_type":"span","marks":[],"text":" értékét lehet beállítani egy-egy függvényhívás esetén."}]},{"_type":"code","code":"var f = function (a, b) { console.log(this, a, b) } f.call({ theAnswer: 42 }, 'hello', 'world') // => Object {theAnswer: 42} \"hello\" \"world\" f.call(null, 'hello', 'world') // => Window {...} \"hello\" \"world\" f.call(undefined, 'hello', 'world') // => Window {...} \"hello\" \"world\" f.apply({ theAswer: 42 }, ['hello', 'world']) // => Object {theAnswer: 42} \"hello\" \"world\" ","language":"javascript"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A különbség csak annyi, hogy a "},{"_type":"span","marks":["code"],"text":"call"},{"_type":"span","marks":[],"text":"-nak felsorolásszerűen kell átadni a paramétereket, míg az "},{"_type":"span","marks":["code"],"text":"apply"},{"_type":"span","marks":[],"text":"-nak tömbként."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"bind"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A "},{"_type":"span","marks":["code"],"text":"bind"},{"_type":"span","marks":[],"text":" is ugyanazt a célt szolgálja, mint az előző két metódus: előre meghatározhatjuk a "},{"_type":"span","marks":["code"],"text":"this"},{"_type":"span","marks":[],"text":" értékét. Az előnye, hogy nem csak egyetlen függvényhívásra szól. A használata egészen egyszerű:"}]},{"_type":"code","code":"var boundF = f.bind('foo') boundF('hello', 'world') // => String {0: \"f\", 1: \"o\", 2: \"o\", length: 3} \"hello\" \"world\" ","language":"javascript"},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"A bind szimulálása"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A "},{"_type":"span","marks":["code"],"text":"bind"},{"_type":"span","marks":[],"text":" nem alkalmaz fekete mágiát a háttérben. Nagyjából a következő kódrészlettel lehetne is szimulálni:"}]},{"_type":"code","code":"var bind2 = function (f, context) { return function () { f.apply(context, arguments) } } ","language":"javascript"},{"_type":"block","markDefs":[{"_key":"ce8e7b9928b1","_type":"link","href":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions#Using_the_arguments_object"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"(Az "},{"_type":"span","marks":["code"],"text":"arguments"},{"_type":"span","marks":[],"text":" nem a semmiből terem elő: "},{"_type":"span","marks":["ce8e7b9928b1"],"text":"minden függvényben elérhető."},{"_type":"span","marks":[],"text":")"}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Összegzés"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A "},{"_type":"span","marks":["code"],"text":"call"},{"_type":"span","marks":[],"text":", "},{"_type":"span","marks":["code"],"text":"apply"},{"_type":"span","marks":[],"text":" és "},{"_type":"span","marks":["code"],"text":"bind"},{"_type":"span","marks":[],"text":" tehát a "},{"_type":"span","marks":["code"],"text":"this"},{"_type":"span","marks":[],"text":" értékének a manipulálására szolgál. Érdemes ezeket észben tartani, mert egy nagyobb alkalmazás esetén már igencsak jó szolgálatot tehetnek."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A következő részben a "},{"_type":"span","marks":["code"],"text":"new"},{"_type":"span","marks":[],"text":" operátor szépségeiben merülünk el."}]}]}
{"_type":"post","_createdAt":"2014-03-16T13:55:00.000+01:00","publishedAt":"2014-03-16T13:55:00.000+01:00","title":"auth.sch: az új irány","body":[{"_type":"block","markDefs":[{"_key":"e6f027e5b700","_type":"link","href":"/post/2014-02-23-sso"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A "},{"_type":"span","marks":["e6f027e5b700"],"text":"VIR SSO jövőjéről"},{"_type":"span","marks":[],"text":" már írtam egyszer, de akkor még csak elhatározás szintjén jártak a dolgok. Azóta sok minden történt és az SSO leváltásának a körvonalai is kezdenek kibontakozni. Ebben a bejegyzésben egy áttekintést próbálok adni arra, hogy mire lehet majd számítani, ha elkészül az átállás."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"OAuth"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Nem egészen ehhez a bejegyzéshez tartozik az auth.sch által használt technológia taglalása, de központi bejelentkezést használó honlapok szempontjából ez a váltás néhány fontos vonzattal jár. Az auth.sch leegyszerűsítve egy OAuth provider megvalósítás, ami teljesen az ellenkező irányból közelíti meg az SSO koncepcióját."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Eddig egy központi helyen kellett jelezni, hogy ha a saját oldaladhoz a felhasználókezelést VIR SSO-n keresztül szeretted volna intézni. Ez az OAuth-tal teljesen meg fog fordulni. Nem lesz szükség arra, hogy ticketet adj fel, lényegében bárki szabadon dönthet úgy, hogy a központi SSO szolgáltatást használja a saját oldalán."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ez egyszerre jó és rossz. Eddig az integráció az alkalmazások szempontjából a központi SSO-val igen egyszerű volt és extra fejlesztést nem igényelt. Az OAuth esetén ez már nem így lesz. Sőt a jelenlegi SSO-t használó weboldalaknak is ajánljuk, hogy minél hamarabb kezdjék meg az átállást."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"A VIR-fiók átalakulása"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A változások végét nem a technológia váltás jelenti. Az auth.sch egyik legnagyobb előnye az lesz, hogy végre egységesedhet a felhasználókezelés az egész házban - megszűnik az eddigi dualitás (VIR vs schacc). Ez némi áldozattal jár, mert több, már meglévő rendszert kell egy tető alá hozni. Megpróbáltunk olyan megoldást találni, ami a leginkább fájdalommentes mindenkinek, de néhány kényelmetlenséget nem lehet kikerülni."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az auth.sch alatt a VIR fiók nagyrészt "},{"_type":"span","marks":["em"],"text":"megszűnik"},{"_type":"span","marks":[],"text":", helyét az "},{"_type":"span","marks":["em"],"text":"schacc fogja átvenni"},{"_type":"span","marks":[],"text":". Ez azt jelenti, hogy az átállás után ahova eddig a VIR felhasználóddal tudtál bejelentkezni, oda a schaccod lesz jó. Ha esetleg nem lenne még schaccod (mert például VIR-ben külsősként vagy benne), akkor lehetőséged lesz regisztrálni és összekötni a VIR-es fiókoddal."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A legtöbb ember számára az átállás csak annyit fog jelenteni, hogy ezentúl az schacc-cal (vagy az BME id-vel) kell belépniük a VIR felhasználó helyett."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Profil és Körök"}]},{"_type":"block","markDefs":[{"_key":"fe373e65032b","_type":"link","href":"/post/2014-01-29-pek-jelen-es-jovo-iv"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az SSO mellett a kör jelenleg legfontosabb alkalmazása a PÉK. Ezt a "},{"_type":"span","marks":["fe373e65032b"],"text":"nagy átalakulás"},{"_type":"span","marks":[],"text":" mellett ugyanúgy érinteni fogja az auth.sch-s átállás. A következő félévtől már "},{"_type":"span","marks":["em"],"text":"nem lesz lehetőségetek"},{"_type":"span","marks":[],"text":" a PÉK-be belépni a VIR felhasználótokkal. Ebben az esetben is az auth.sch által nyújtott lehetőségeket tudjátok majd használni."}]},{"_type":"block","markDefs":[{"_key":"4c1d2a41c971","_type":"link","href":"http://en.wikipedia.org/wiki/Permalink"},{"_key":"5097a9693589","_type":"link","href":"http://www.facebook.com/help/www/211813265517027"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ez annyiban érdekes, hogy a VIR felhasználónév eltűnésével a profilotokat azonosító felhasználónév is értelmét veszti. Ennek a kiküszöbölésére valószínűleg "},{"_type":"span","marks":["4c1d2a41c971"],"text":"permalinkeket"},{"_type":"span","marks":[],"text":" fogunk bevezetni, ahogy a "},{"_type":"span","marks":["5097a9693589"],"text":"Facebooknál"},{"_type":"span","marks":[],"text":" és a Google-nél is."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Az átállás egy folyamat és nem törés"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A fentebb leírt dolgok rémisztően hathatnak elsőre. Nem arról van szó, hogy a következő félévtől kirántjuk alólatok a már jól megszokott szolgáltatásokat. A VIR SSO-t használó oldalak továbbra is elérhetőek lesznek. Az SSO szolgáltatásunk tovább fog még futni, de csak korlátozott ideig."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az átállást megpróbáljuk megkönnyíteni majd mind a felhasználóknak, mind pedig a weboldalak adminisztrátorainak. Várható több auth.sch-s átállással foglalkozó cikk és segédlet. Lehetséges, hogy nem ennek a blognak a keretein belül, mert az auth.sch-t elsősorban a KSZK-nak köszönhetjük. Viszont lassan közös feladattá válik ez, így a Kir-Dev is aktívabb részt fog vállalni benne."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A lényeg, hogy számíthattok rá, hogy nem a semmiből fog felbukkanni az új rendszer. Mire az élesedik (remélhetőleg) már mindenkinek egyértelmű lesz, hogy mit kell tennie."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Nem kell félnetek, jó lesz"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az indulást a nyár végére tűztük ki. A határidő adott, mert a gólyák már nem tudnak regisztrálni a jelenlegi rendszerbe."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Azt gondoljuk, hogy a némi kényelmetlenség, amit ezzel okozunk kis ár azért, hogy végre egységesedhessen a Schönherzben a felhasználókezelés. Mindenhova ugyanúgy fogsz tudni belépni: a PÉK-be, a wiki-re, a köröd honlapjára és a hálóregedhez se kell a felhasználóneved után kutakodni."}]}]}
{"_type":"post","_createdAt":"2014-03-20T22:00:00.000+01:00","publishedAt":"2014-03-20T22:00:00.000+01:00","title":"Munkakeresés külföldön","body":[{"_type":"block","markDefs":[{"_key":"8829f0e12d21","_type":"link","href":"http://robertheaton.com/2014/03/07/lessons-from-a-silicon-valley-job-search/"}],"style":"normal","children":[{"_type":"span","marks":["8829f0e12d21"],"text":"Lessons from a Silicon Valley job search"}]},{"_type":"block","style":"blockquote","markDefs":[],"children":[{"_type":"span","marks":[],"text":"This post is a fairly exhaustive summary of the things I learned during my recent Silicon Valley job search. It is really quite long, but has been edited aggressively, and I’ve tried to make sure that nearly every point is either actionable, interesting, or both. If you’re currently or may one day be looking for a job as a programmer, either in San Francisco or elsewhere in the world, then there should hopefully be a bunch of useful stuff for you. I’ve tried to give numbers and stats where possible - your mileage will of course vary, but my hope is that they are still helpful for working out which ballpark to start in."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ez a téma nem igazán vág a Kir-Dev profiljába, de kifejezetten hasznos olvasmány. A munkakeresés az egyetem után válik fontos kérdéssé, mikor már vannak elvárásaink, de tapasztalatunk még nem sok. Könnyű elveszni az ajánlatok és az interjúk között."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Informatikusként a sok lehetőség már-már ijesztő és munkakeresés közben a cikkben is megfogalmazott két állapot között könnyű ingadozni:"}]},{"_type":"block","style":"blockquote","markDefs":[],"children":[]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"There are trillions of people who know hundreds of times more stuff about everything than me, and anything I can do could and should be done infinitely quicker and more effectively by these savvy supermen"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"I AM PROGRAMMER, KNEEL BEFORE ME AND BEG ME TO WORK WITH YOU"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Mindenképpen érdemes elolvasni a fentebb linkelt cikket."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ha esetleg már van tapasztalatod munkakeresés terén, szívesen hallanánk róla kommentben."}]}]}
{"_type":"post","_createdAt":"2014-03-25T11:20:00.000+01:00","publishedAt":"2014-03-25T11:20:00.000+01:00","title":"Node.js is a badass rock star tech! - I.rész","body":[{"_type":"block","markDefs":[{"_key":"d9716838674e","_type":"link","href":"http://nodejs.org/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Elérkezett az ideje annak, hogy írjak egy kicsit a "},{"_type":"span","marks":["d9716838674e"],"text":"Node.js"},{"_type":"span","marks":[],"text":"-ről. A szándékainkról már tudtok. Szeretnénk újra írni a PÉK-et és ehhez a Node.js-t használnánk a front-end elkészítéséhez. Ahhoz, hogy tisztán lássunk jó pár dolgot meg kell érteni, és jelen cikk ezeket célozza meg, majd egy következő cikkben pedig bevezetést fogok adni, a Node.js alapjairól. De még mielőtt elkezdenénk belemenni a részletekbe, nézzétek meg ezt a videót, amely a már jól bevált webszervereket állítja szembe az új, még kiforróban lévő Node.js-szel."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Sok ismeretlen fogalom elhangzik a videóban, amelyek egy részére megpróbálok magyarázatot adni. A videó egyik tanulsága, hogy a régi jól bevált dolgoktól nem feltétlenül kell megszabadulni az új technológiák miatt - mindennek megvan a maga helye. Egy Apache webszerver már kiforrott, jól működik és rengeteg fejlesztő megtanulta használni. Jól bevált technológia, folyamatos patchekkel a bugok és biztonsági hibák ellen. Egy olyan szoftver, amely rengeteg igényt kielégít és tökéletes lenne a számunkra is, sőt jelenleg is fut nálunk. Akkor mégis miért szeretnénk mindezt a biztonságot feláldozni és új vizekre evezni? Egy szó a válasz rá: kíváncsiságból."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"A motorháztető alatt"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A Node.js, ha még nem hallottál volna róla, szerver oldali JavaScript futtatásának a lehetőségét kínálja. A bevezető videóban a két maci már az elején dobálózik olyan szavakkal, hogy Non-Blocking I/O, Event-Driven. Ezek nagyon jól hangzanak, de mit is jelentenek igazából? Node.js-ben az I/O műveletek nem blokkolhatnak (később kifejtem, hogy miért). Ez azt jelenti, hogy a HTTP kérések, adatbázis lekérdezések, file I/O és egyéb műveletek nem blokkolják a végrehajtást mindaddig, amíg végbe nem mennek ("},{"_type":"span","marks":["code"],"text":"return"},{"_type":"span","marks":[],"text":")."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ennek megfelelően függetlenül futnak és egy eseményt indítanak, ha az adat a rendelkezésünkre áll. Az Event-Driven gyakorlatilag azt jelenti, hogy valamilyen esemény hatására végrehajtódik egy cselekvés. A böngészőben ez egy kattintás egy gombra, vagy egy billentyű lenyomása. Azonban a Node.js nem a böngészőkben fut a kliens oldalon, hanem a szerveren, ahol nincsenek ilyesféle események. Ez egy nagyon nagy különbség és másféle programozó stílust is követel. Olyan dolgokra van szükség, ami segíti a hatékony szerver oldali futtatást. Ezt a segítséget az event loop (esemény ciklus) biztosítja számunkra."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Event loop"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A legtöbb ember könnyedén megérti azt, hogy milyen az esemény vezérelt programozás. Olyan, mint a mindennapi élet. Főzöl, elkezded melegíteni a vizet a tésztának, és amikor felforr a víz, annak hatására belerakod a tésztát. Az események a víz forrásaval kezdődnek és ennek hatására meghívódik a "},{"_type":"span","marks":["em"],"text":"callback"},{"_type":"span","marks":[],"text":", ami a tészta belerakása a vízbe. Nagyon fontos, hogy egyszerre mindig csak egy dolgot csinálunk. Olyan nincs, hogy egyszerre tesszük bele a tésztát a levesbe, de közben a másik kezünkkel vágjuk a paradicsomot. Ez a JavaScript világából maradt ránk: itt minden egy szálon történik. Ha bármit egyszerre szeretnél csinálni, annak csúnya vége lesz (elvágod a kezed)."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az event loop megértésének egy módja a postás analógiája. Az event-loop a postás, és az event maga a levél. A postás fogja a megkapott levelet és a megfelelő "},{"_type":"span","marks":["em"],"text":"route"},{"_type":"span","marks":[],"text":"-hoz viszi, ami maga lesz a callback, ez lefut, aztán pedig mindez újra és újra megtörténik."}]},{"_type":"code","code":"var http = require('http') http .createServer(function (req, res) { res.writeHead(200, { 'Content-Type': 'text/plain' }) res.end('Hello World\\n') }) .listen(1337, '127.0.0.1') console.log('Server running at http://127.0.0.1:1337/') ","language":"js"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A fenti kódrészlet a Node.js hivatalos weboldaláról van. Ez egy rendkívül egyszerű HTTP szerver kódja, ami nem csinál mást, mint a böngésző kérésére elküldi válaszként a \"Hello World\"-öt. De mi is történik, itt valójában. Beesik egy HTTP kérés hozzánk, ekkor a Node.js a "},{"_type":"span","marks":["em"],"text":"request"},{"_type":"span","marks":[],"text":" eventet bocsájtja ki. Ennek hatására meghívódik a callback-ünk ami jelen esetben egy anonim függvény a "},{"_type":"span","marks":["code"],"text":"createServer"},{"_type":"span","marks":[],"text":"-ben argumentumként átadva. Ez egy nagyon egyszerű callback, ami rendkívül gyorsan fut."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Most tegyük fel, hogy az oldalunk nagyon népszerű lesz és rengeteg kérést kapunk. Tételezzük fel azt is, hogy a callback függvényük egy másodpercig fut és egyszerre két kérés jön be. Mind a két kérést nem tudjuk kiszolgálni és a második további egy másodpercig fog várakozni. Ez egy veszélyes jelenség, mivel blokkoljuk az event-loopot, és a felhasználók látják a kárát."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"E miatt próbáljuk a Node.js-t, amennyire csak lehet esemény vezéreltnek és blokkolás mentesnek meghagyni. Nagyon érdekes technológiáról van szó, amivel érdemes foglalkozni. Azonban megkérdőjelezhető a kód karbantarthatósága. Ha nem vigyázunk olyan szörnyeteget tudunk létrehozni, amit senki nem szeretne piszkálni. Muszáj lesz olyan metodológiákat alkalmazni, amikkel elérhetjük, hogy minőségi kód kerüljön ki a kezünk közül."}]},{"_type":"block","markDefs":[{"_key":"f550c54170a8","_type":"link","href":"http://developer.yahoo.com/blogs/ydn/part-1-understanding-event-loops-writing-great-code-11401.html"},{"_key":"af401017f853","_type":"link","href":"http://www.packtpub.com/node-to-guide-in-the-art-of-asynchronous-server-side-javascript-cookbook/book"},{"_key":"69011568e609","_type":"link","href":"http://nodejs.org/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Források: "},{"_type":"span","marks":["f550c54170a8"],"text":"understanding-event-loops"},{"_type":"span","marks":["af401017f853"],"text":"Node cookbook"},{"_type":"span","marks":["69011568e609"],"text":"nodejs.org"}]}]}
{"_type":"post","_createdAt":"2014-03-26T14:10:00.000+01:00","publishedAt":"2014-03-26T14:10:00.000+01:00","title":"BridgeBudapest konferencia a Prezinél","body":[{"_type":"block","markDefs":[{"_key":"9d8f1b64bdfb","_type":"link","href":"http://bridgebudapest.hu"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Mostanában sok érdekes konferencia volt a Prezinél. A legutóbbi ilyet közösen szervezték a BridgeBudapest csapatával. A "},{"_type":"span","marks":["9d8f1b64bdfb"],"text":"BridgeBudapest"},{"_type":"span","marks":[],"text":" egy speciális ösztöndíj, amit három sikeres magyar startup cég alapított, a Prezi, a Ustream és a LogMeIn. Az a 6-8 szerencsés, aki megnyeri az ösztöndíjat, elmehet ezekhez a cégekhez dolgozni egy hónapra és belepillanthat az életükbe. Kaliforniában a Prezihez és a Ustreamhez, Bostonban a LogMeInhez lehet eljutni. Idén csatlakozott a hármashoz az NNG, akikhez Japánba, vagy Izraelbe lehet kiutazni."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://distilleryimage2.ak.instagram.com/4b8c9378a60e11e380f00afa321cabe2_8.jpg","alt":"BridgeBudapest"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Március 7-én volt a konferencia a Prezi székházban. Rengetegen voltunk, ahogy az a képen is látszik. A magyar Forbes Magazin főszerkesztője volt a beszélgetés moderátora. Ő kérdezte a négy vezetőt: Árvai Pétert és Somlai-Fischer Ádámot a Prezitől, Fehér Gyulát a Ustreamtől és Balogh Pétert az NNG-től. A találkozó eleje a három cég történetéről szólt: melyikük hogyan lett sikeres. Tulajdonképpen egy vállveregetés volt, hogy nyugodtan lehet itthon is csinálni céget, lehet az sikeres is, csak ne a hazai piacra tervezz."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A találkozó második fele az ösztöndíjról szólt. A jelentkezés március 7-én indult és egy egész hónapig, április 7-ig tart. Megszólaltak a tavalyi győztesek, láthattunk néhány kisfilmet az élményeikről. Az érdekes az egészben az volt, hogy ez a program valóban sikeres és működőképes. Két srác már a saját cégét építgeti itthon a kint megszerzett tapasztalatok és tanácsok alapján."}]},{"_type":"block","markDefs":[{"_key":"5381aa15bc16","_type":"link","href":"https://www.facebook.com/bridgebudapest"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az összes kisfilmet, valamint további részleteket a találkozóról és a szövetségről a BridgeBudapest "},{"_type":"span","marks":["5381aa15bc16"],"text":"Facebook"},{"_type":"span","marks":[],"text":" oldalán találhattok."}]}]}
{"_type":"post","_createdAt":"2014-03-28T10:25:00.000+01:00","publishedAt":"2014-03-28T10:25:00.000+01:00","title":"JavaScript new operátor","body":[{"_type":"block","markDefs":[{"_key":"97cb39eecc2c","_type":"link","href":"/post/2014-03-13-call-apply-bind"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Múltkor elkezdtem egy mini-sorozatot azokról a témákról, amik nem fértek bele a web alapozó tanfolyamunkba. Az "},{"_type":"span","marks":["97cb39eecc2c"],"text":"első bejegyzésben"},{"_type":"span","marks":[],"text":" a "},{"_type":"span","marks":["code"],"text":"Function.prototype.call"},{"_type":"span","marks":[],"text":" és társai kerültek elő. Most erre építkezve elmélyedünk a "},{"_type":"span","marks":["code"],"text":"new"},{"_type":"span","marks":[],"text":" operátor szépségeiben."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"A new feladata"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A "},{"_type":"span","marks":["code"],"text":"new"},{"_type":"span","marks":[],"text":" operátor egy előre definiált típust példányosít. Ez persze így nem igaz, mert JavaScriptben nem lehet új típust létrehozni. Valójában a "},{"_type":"span","marks":["code"],"text":"new"},{"_type":"span","marks":[],"text":" operátor által létrehozott új objektum "},{"_type":"span","marks":["code"],"text":"Object"},{"_type":"span","marks":[],"text":" típusú lesz, de egy "},{"_type":"span","marks":["code"],"text":"constructor function"},{"_type":"span","marks":[],"text":" hozza létre, így lényegében egy olyan objektumot kapunk, amit előre felparamétereztünk."}]},{"_type":"code","code":"var Person = function (name) { this.name = name } Person.prototype.greet = function () { return 'Hi, my name is ' + this.name + '!' } var p = new Person('tmichel') console.log(p.name) // => tmichel console.log(p.greet()) // => Hi, my name is tmichel! ","language":"js"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Láthatjuk, hogy a létrehozott objektum úgy viselkedik, mintha "},{"_type":"span","marks":["code"],"text":"Person"},{"_type":"span","marks":[],"text":" típusú lenne, miközben tudjuk, hogy a valós típusa "},{"_type":"span","marks":["code"],"text":"Object"},{"_type":"span","marks":[],"text":". Ez annak köszönhető, hogy az újonnan létrehozott objektum megörökölte a "},{"_type":"span","marks":["code"],"text":"Person"},{"_type":"span","marks":[],"text":" prototípusát."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A "},{"_type":"span","marks":["code"],"text":"new"},{"_type":"span","marks":[],"text":" operátor nagyjából a következő lépésekben hozza létre az új objektumot:"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"number","children":[{"_type":"span","marks":[],"text":"Létrehoz egy új objektumot."}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"number","children":[{"_type":"span","marks":[],"text":"Beállítja a konstruktor függvény (publikus) prototípusát az új objektum (privát) prototípusaként."}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"number","children":[{"_type":"span","marks":[],"text":"Meghívja a konstruktor függvényt, "},{"_type":"span","marks":["code"],"text":"this"},{"_type":"span","marks":[],"text":"-ként az újonnan létrehozott objektumot használja."}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"number","children":[{"_type":"span","marks":[],"text":"Visszatér az új objektummal, vagy a konstruktor függvény visszatérési értékével."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A 2. pont az igazán kritikus. JavaScriptben prototípusokkal lehet imitálni a legtöbb OO koncepciót, bár kérdéses, hogy kell-e. Egy objektum prototípusát csak létrehozási időben lehet beállítani (a szabvány szerint). Tehát csak a "},{"_type":"span","marks":["code"],"text":"new"},{"_type":"span","marks":[],"text":" operátor és az "},{"_type":"span","marks":["code"],"text":"Object.create"},{"_type":"span","marks":[],"text":" függvény segítségével. Újabb böngészőkben elérhető a "},{"_type":"span","marks":["code"],"text":"__proto__"},{"_type":"span","marks":[],"text":" tulajdonság az összes objektumon. Ez tartalmazza a prototípust és ezen keresztül meg is lehet változtatni egy azt. Mondanom sem kell, hogy ez igen veszélyes lehet és nem nem várt következményekkel járhat. Ezen túl a "},{"_type":"span","marks":["code"],"text":"__proto__"},{"_type":"span","marks":[],"text":" nem szabványos, így nincs garancia rá, hogy melyik böngésző támogatja és melyik nem."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Írjunk saját new operátort!"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Nem kell más tennünk, mint a fenti 4 pontot végrehajtani."}]},{"_type":"code","code":"function mynew(ctor) { // létrehozunk egy új objektumot és beállítjuk a prototípusát (1. és 2. pont) var $this = Object.create(ctor.prototype), args = Array.prototype.slice.call(arguments, 1) // meghívjuk a konstruktor függvényt és visszatérünk a függvény visszatérési // értékével, vagy ha undefined, akkor magával az új objektummal. return ctor.apply($this, args) || $this } ","language":"js"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A fentebb definiált "},{"_type":"span","marks":["code"],"text":"Person"},{"_type":"span","marks":[],"text":"-t a következő kódrészlettel lehet példányosítani az új "},{"_type":"span","marks":["code"],"text":"new"},{"_type":"span","marks":[],"text":" operátorunkkal:"}]},{"_type":"code","code":"var me = mynew(Person, 'tmichel') console.log(p.name) // => tmichel console.log(me.greet()) // => Hi, my name is tmichel! ","language":"js"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Látható, hogy ugyanazt az eredményt kaptuk, mintha a beépített nyelvi elemet használtuk volna."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ebből a rövid kis bejegyzésből is kiderül, hogy a JavaScript többet tartogat, mint amit elsőre gondolnánk. Érdemes elmerülni a nyelv részleteiben és picit elmélyedni a JavaScript VM-ek lelki világában. A sorozat következő részében a prototípusokat vizsgáljuk meg közelebbről. Kövessetek minket!"}]}]}
{"_type":"post","_createdAt":"2014-03-28T01:00:00.000+01:00","publishedAt":"2014-03-28T01:00:00.000+01:00","title":"Tanfolyamzáró front-end workshop","body":[{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Nem rég fejeződött be az idei tanfolyamunk, melynek témája a front-end fejlesztés volt. A szükséges tudás megalapozásaként az érdeklődők három előadást hallgathattak meg (hetente egyet), melynek témái a következők voltak:"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"number","children":[{"_type":"span","marks":[],"text":"Webfejlesztés bevezető"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"number","children":[{"_type":"span","marks":[],"text":"JavaScript alapok"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"number","children":[{"_type":"span","marks":[],"text":"HTML+CSS"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ezen általános és nagyrészt elméleti bevezető előadások után, egy workshopot rendeztünk a tanfolyam lezárásaként. A workshopon az eddig megismert technológiák és néhány kiegészítő információ segítségével a gyakorlatban is kipróbálhatták a hallottakat a leendő újoncok és érdeklődők. A délelőtt során először az objektumorientált Javascript programozásról és a prototípusokról, majd a DOM rejtelmeiről és a jQuery-ről lehetett egy-egy előadást meghallgatni. A hétvégi időpont ellenére sokan részt vettek a rendezvényen."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBNZz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--879ea23b82ad1d4a51bd1a80500ba1a47747797b/2014-03-28-ws2.jpg","alt":"workshop1"}}]},{"_type":"block","markDefs":[{"_key":"1f50db432e97","_type":"link","href":"https://github.com/kir-dev/tanfolyam/blob/master/2014-tavasz/workshop/feladatok.md"},{"_key":"d765a2291152","_type":"link","href":"https://github.com/kir-dev/tanfolyam/blob/master/2014-tavasz/workshop/workshop.md#api-le%C3%ADr%C3%A1s"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Egy rövidebb ebédszünet után kihirdetésre kerültek a "},{"_type":"span","marks":["1f50db432e97"],"text":"feladatok"},{"_type":"span","marks":[],"text":". A kapott feladatoknak a résztvevők páronként álltak neki. A feladatok kontextusa egy fórumalkalmazás, melynek back-endjéhez kellett front-end réteget készíteni a tanfolyam során megszerzett tudás segítségével. A fórumalkalmazásban különböző témák vannak, melyekhez felhasználók hozzászólhatnak. Ezen entitásokkal való kapcsolatot az alkalmazás REST API-ja teszi lehetővé, melyhez elérhetővé tettünk "},{"_type":"span","marks":["d765a2291152"],"text":"egy dokumentációt"},{"_type":"span","marks":[],"text":"."}]},{"_type":"block","markDefs":[{"_key":"0f03e1848a7d","_type":"link","href":"http://stewie.sch.bme.hu/workshop/linux/forum"},{"_key":"182721562d90","_type":"link","href":"http://stewie.sch.bme.hu/workshop/forum.exe"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A fenti feladatokat bárki megoldhatja, a back-end alkalmazás letölthető "},{"_type":"span","marks":["0f03e1848a7d"],"text":"Linuxra"},{"_type":"span","marks":[],"text":", és "},{"_type":"span","marks":["182721562d90"],"text":"Windowsra"},{"_type":"span","marks":[],"text":" is. Ha egy kis inspiráció kellene, GitHub-on fent van egy mintamegoldás a kiadott feladatokhoz."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBNUT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--ae5609c56282a131fdbef6f87e2f2ae72d8e3e34/2014-03-28-ws1.jpg","alt":"workshop1"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A workshop alatt minden résztvevő nagyon lelkes volt. Több eltérő megközelítést is láthattunk: voltak akik egy minimalista, single-page fórumalkalmazást készített, amely teljes egészében kihasználja az Ajax technológia előnyeit; mások több lapból álló, könnyen karbantartható szoftvert írtak, gondolván a továbbfejlesztési lehetőségekre is."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Köszönjük a részvételt, reméljük találkozunk még!"}]}]}
{"_type":"post","_createdAt":"2014-03-31T22:22:00.000+02:00","publishedAt":"2014-03-31T22:22:00.000+02:00","title":"JavaScript & QA Meetup a Prezinél","body":[{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Március 27-én volt meetup a House of Ideasban, amely főleg a JavaScript-ről és a tesztelésről szólt. Három előadóhoz volt szerencsénk a magyar startupok világából. Az első Kökény Tamás volt a Brickflow-tól, a második Tóth Barna volt a LogMeIn-től és az este utolsó előadója volt Pengő József (Dzsó) a házigazda Prezitől."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/b42272783dc80d577b835513d131e869b44459b7/700","alt":"Tamas Kokeny"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Kökény Tamás a TDD-ről (Test-Driven Development) beszélt. Az előadás címe a \"TDD in laboratory and in production\" címet kapta. Egy bevezetőt kaphattunk magáról a TDD-ről, illetve azokról az előnyökről és nehézségekről, amik az alkalmazása során előjönnek. Az elején sajnos, ahogy azt várni lehetett nagyon nagy az overheadje. Sokkal lassabban haladsz a fejlesztéssel, de ez hosszú távon megtérül. Minden héten gyorsabb leszel és jobb teszteket fogsz írni. A tanulási folyamat végére pedig eljutsz oda, hogy biztos leszel abban, hogy a kód, amit megírtál, jól fog működni. Mégpedig azért, mert megvannak a tesztjeid, amiket minden egyes alkalommal, mikor változtatsz a kódbázison, akkor futtatsz, és így az elvárt működésről megbizonyosodhatsz."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Tóth Barna a LogMeIn-től volt jelen és az előadása a \"Unit testing and TDD in AngularJS\" nevet viselte. Főként az AngularJS-beli teszt lehetőségekről volt szó, illetve arról, hogy ők miket használnak a LogMeIn-nél. Mutatott pár érdekes kódrészletet, részben tovább vitte az előző előadásban elkezdett gondolatmenetet. Érdekességképpen megjegyezte, hogy náluk körülbelül 5-6000 teszt fut folyamatosan, ami figyelemre méltó szám."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az est utolsó előadója Pengő József volt, aki bevezetett minket a BDD (Behavior-Driver Development) világába. A saját szoftverükön mutatta be, hogy miként tesztelik a funkcionalitást. A Prezinél nagyon sok nyelvet használnak, amik JavaScriptre fordulnak és BDD-t használnak a feladatok specifikálására. A különböző nyelven fejlesztő mérnökök ezt használják, hogy kommunikáljanak egymás között, hogy mit kell implementálni."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A meetupon volt lehetőség kötetlen beszélgetésre is. Ilyenkor lehetett ismerkedni, beszélgetni a technológiákról és arról, hogy ki mire használja az adott teszteket. Természetesen ételből se volt hiány, ahogy a Prezinél ezt már megszokhattuk. A meetup remek volt, és köszönjük ismételten a remek szervezést Kamarás Károlynak!"}]}]}
{"_type":"post","_createdAt":"2014-04-02T23:04:18.000+02:00","publishedAt":"2014-04-02T23:04:18.000+02:00","title":"Node.js is a badass rock star tech - II.rész","body":[{"_type":"block","markDefs":[{"_key":"a0cd13a32da4","_type":"link","href":"http://kir-dev.sch.bme.hu/2014/03/25/nodejs-is-a-badass-rock-star-tech-part-i/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A Node.js cikksorozatunk következő részét olvashatjátok, melyben egy nagyon egyszerű chat programot fogunk elkészíteni. Az "},{"_type":"span","marks":["a0cd13a32da4"],"text":"előző cikkben"},{"_type":"span","marks":[],"text":" megismerkedhettünk egy-két alapvető fogalommal és a belső működéssel, most pedig ideje belevágnunk a programozós részbe. Még mielőtt nagyon belelendülnénk elárulom, hogy a következő cikk az Express.js-ről fog szólni, de ne szaladjunk ennyire előre lássuk azt a chat programot."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://dl.dropboxusercontent.com/u/31443466/Capture.PNG","alt":"chatting with yourself is so much fun"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Nézzünk egy nagyon egyszerű kódrészletet, ami annyiból áll, hogy készítünk egy TCP szervert és várjuk, hogy becsatlakozzanak rá. A kapott adatokat egyszerűen csak kiírjuk a console-ra."}]},{"_type":"code","code":"var net = require('net') var chatServer = net.createServer() chatServer.on('connection', function (client) { client.write('Hi\\n') client.on('data', function (data) { console.log(data) }) }) chatServer.listen(1337) ","language":"js"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Vegyük sorban a fontos részeket. Az első a "},{"_type":"span","marks":["code"],"text":"require(id)"},{"_type":"span","marks":[],"text":" függvény, ahol az id egy "},{"_type":"span","marks":["code"],"text":"String"},{"_type":"span","marks":[],"text":". A require függvény segítségével modulokat tudunk betölteni. Ez ahhoz hasonló, mint Javaban az import vagy c-ben az #include. Jelen esetben a "},{"_type":"span","marks":["code"],"text":"net"},{"_type":"span","marks":[],"text":" modulra van szükségünk. Ennek a segítségével tudunk szerver, illetve kliens oldali streameket is létrehozni."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A "},{"_type":"span","marks":["code"],"text":"chatServer.createServer()"},{"_type":"span","marks":[],"text":" függvénnyel hozzuk létre az új szervert. Ez igazából csak egy wrapper a "},{"_type":"span","marks":["code"],"text":"net.Socket"},{"_type":"span","marks":[],"text":" osztály köré, hogy sokkal könnyebben tudjuk kezelni a socketet."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A következő fontos függvény az "},{"_type":"span","marks":["code"],"text":"on(event, listener)"},{"_type":"span","marks":[],"text":". Ennek segítségével tudunk feliratkozni eseményekre. Jelen esetben a chatServer "},{"_type":"span","marks":["code"],"text":"connection"},{"_type":"span","marks":[],"text":" eseményre iratkozunk fel. Az esemény figyelőnk, vagyis a listener az a függvény lesz, amit megadunk argumentumként "},{"_type":"span","marks":["code"],"text":"function(client)"},{"_type":"span","marks":[],"text":". Fontos, hogy itt a client egy streamet jelent, amin keresztül tudunk olvasni, illetve írni."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A "},{"_type":"span","marks":["code"],"text":"write(string)"},{"_type":"span","marks":[],"text":" függvénnyel tudunk írni a streamre, viszont az olvasáshoz újabb eseményre kell feliratkozni, mégpedig a "},{"_type":"span","marks":["code"],"text":"data"},{"_type":"span","marks":[],"text":" nevű eseményre. Ezt ismételten az "},{"_type":"span","marks":["code"],"text":"on(event, listener)"},{"_type":"span","marks":[],"text":" függvénnyel tudjuk megtenni. Az utolsó fontos dolog pedig a "},{"_type":"span","marks":["code"],"text":"listen(port)"},{"_type":"span","marks":[],"text":" függvény meghívása, amivel megmondhatjuk melyik porton hallgatózzon a szerver."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Eddig nem volt túl bonyolult, de még nem tudnak a felhasználók írni egymásnak. Ehhez el kell tároljuk a csatlakozott streameket és mindegyikre ki kell írni a bejövő adatot, kivéve arra, amelyikről jön az adat. Egészítsük ki a kódunkat, hogy mindez teljesüljön."}]},{"_type":"code","code":"// ebben tároljuk a streameket var clients = [] var chatServer = net.createServer() chatServer.on('connection', function (client) { // nehany adat a bekapcsolodo felhasznalorol client.name = client.remoteAddress + ':' + client.remotePort // eltaroljuk a becsatlakozott streamet clients.push(client) client.on('data', function (data) { broadcastMessage(data, client) }) }) function broadcastMessage(message, client) { for (var i = 0; i < clients.length; i++) { if (client !== clients[i]) { clients[i].write(client.name + 'says' + message) } } } ","language":"js"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A megvalósítás most se túl bonyolult. Eltároljuk a becsatlakozott felhasználót a "},{"_type":"span","marks":["code"],"text":"clients"},{"_type":"span","marks":[],"text":" tömbben, majd ha valaki ír a streamre, akkor mindegyik kapcsolat streamjére kiírjuk az adatot amit kaptunk. Innentől működik a chat programunk. Ha szeretnénk tesztelni, akkor csak simán kapcsolódjunk a megfelelő portra párszor és kezdjünk el irkálni magunknak. A program természetesen tovább finomítható különböző eseményekre történő feliratkozással."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az egyik ilyen az "},{"_type":"span","marks":["code"],"text":"end"},{"_type":"span","marks":[],"text":" esemény amiben ha a kapcsolatot bontják, akkor kapunk egy figyelmeztetést és a callback függvényünkben kezelhetjük a dolgokat. Például ha szeretnénk egy kapcsolatot kivenni a listánkból akkor ki tudjuk szedni a tömbből a "},{"_type":"span","marks":["code"],"text":"splice()"},{"_type":"span","marks":[],"text":" függvénnyel: "},{"_type":"span","marks":["code"],"text":"clients.splice(clients.indexOf(client), 1);"},{"_type":"span","marks":[],"text":"."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A másik hasznos esemény az "},{"_type":"span","marks":["code"],"text":"error"},{"_type":"span","marks":[],"text":". Ha a kapcsolat megszakad és írni szeretnénk a streamre, akkor nem fogunk tudni mert már nem létezik. Egy errort kapunk és fel tudunk készülni erre az eseményre. Ezt megelőzhető, a kapcsolatok vizsgálhatók, hogy írhatók-e. A "},{"_type":"span","marks":["code"],"text":"writeable"},{"_type":"span","marks":[],"text":" tulajdonságot lekérdezve ezt könnyedén ellenőrizhetjük egy feltételként is: "},{"_type":"span","marks":["code"],"text":"if (clients[i].writeable) ..."},{"_type":"span","marks":[],"text":"."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Remélem tetszett ez a kis tutorial. A sorozat következő részében már egy webes keretrendszert fogunk megnézni, amit a PÉK front-end újraírásakor is használni fogunk. Ha érdekel, akkor a továbbiakban is tartsatok velünk!"}]},{"_type":"block","markDefs":[{"_key":"dd501362c411","_type":"link","href":"http://shop.oreilly.com/product/0636920015956.do"},{"_key":"c5e48070ca53","_type":"link","href":"http://nodejs.org/api/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Források: "},{"_type":"span","marks":["dd501362c411"],"text":"Node - Up and Running"},{"_type":"span","marks":["c5e48070ca53"],"text":"Node.js Manual & Documentation"}]}]}
{"_type":"post","_createdAt":"2014-04-06T20:18:40.000+02:00","publishedAt":"2014-04-06T20:18:40.000+02:00","title":"A kliens oldali teljesítmény számít","body":[{"_type":"block","markDefs":[{"_key":"8ef97242c675","_type":"link","href":"http://highscalability.com/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Sokan hallhattatok már a backend oldali skálázásról, a különböző cluster és sharding megoldásról (a témában érdemes követni a "},{"_type":"span","marks":["8ef97242c675"],"text":"HighScalability"},{"_type":"span","marks":[],"text":" oldalt), de valójában erre az esetek nagy részében nincs szükség egy új alkalmazás bevezetésekor a piacra. Ekkor sokkal nagyobb hangsúlyt érdemes fektetni a felhasználói elégedettségre, amit inkább az alkalmazásunk kliens oldali teljesítménye határoz meg. A határok persze nem ilyen élesek, olvass tovább!"}]},{"_type":"block","markDefs":[{"_key":"721e31865f15","_type":"link","href":"http://alistapart.com/article/improving-ux-through-front-end-performance"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A felhasználók számára elsőrendű kérdés, hogy mennyit kell várniuk egy oldal betöltődésére. A Google felmérései szerint 500 ms késleltetés a keresési eredmények megjelenítésében 20%-os reklámbevétel kiesést jelent, az Amazon mérései szerint minden 100 ms késleltetés 1%-al csökkenti az eladott áruk mennyiségét a webes kereskedő portálon. 2 másodperc várakozás után a felhasználók már türelmetlenek kezdenek lenni, 3 másodperc után 40%-uk "},{"_type":"span","marks":["721e31865f15"],"text":"egyszerűen elhagyja"},{"_type":"span","marks":[],"text":" az oldalt."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Két számot érdemes megjegyezni a front-end optimalizációval kapcsolatban:"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":["strong"],"text":"1000 ms"},{"_type":"span","marks":[],"text":": ennyi idő alatt feltétlen valamilyen használható tartalmat kell mutatni a felhasználónak"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":["strong"],"text":"16,6 ms"},{"_type":"span","marks":[],"text":": ennyi időnként elő kell állítani egy frame-et a jó minőségű, 60 FPS sebesség eléréséhez"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A bevezetőben sugalltuk, hogy a kliens oldali teljesítménynél nem csak a felhasználóhoz megérkezett adatoktól számított feldolgozási és renderelési időt vesszük figyelembe, hanem azt is, hogy a bitek milyen formában közlekednek a böngésző és a szerver(ek) között. Mielőtt elkezdenénk megvizsgálni a különböző optimalizálási lehetőségeket, nagy vonalakban áttekintjük a HTTP lekérdezések felépítését."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBMZz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--0a39ffef0821b92eba2b0f136da2a5e1c0c9fdd3/2014-03-06-httprequest.png","alt":"httprequest"}}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"number","children":[{"_type":"span","marks":[],"text":"DNS lekérdezés: A kliens megpróbálja feloldani a domain nevet, a DNS szerver válaszol egy IP címmel."}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"number","children":[{"_type":"span","marks":[],"text":"Kapcsolódás: Megtörténik a háromfázisú TCP handshake, a kliens SYN csomagot küld a szervernek, a szerver SYN-ACK csomaggal válaszol, végül a kliens ACK csomagot küld és ezzel létrejött a TCP kapcsolat."}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"number","children":[{"_type":"span","marks":[],"text":"Küldés: A kliens HTTP üzeneteket küld a web szervernek."}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"number","children":[{"_type":"span","marks":[],"text":"Várakozás: A szerver feldolgozza a kérést, elkészíti a választ, majd elküldi a kliensnek."}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"number","children":[{"_type":"span","marks":[],"text":"Betöltés: A kliens feldolgozza szerver válaszát."}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"number","children":[{"_type":"span","marks":[],"text":"Lezárás: A kliens lezárja a kapcsolatot."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"1. fázis: DNS lekérdezés"}]},{"_type":"block","markDefs":[{"_key":"7b031992db7d","_type":"link","href":"http://www.chromium.org/developers/design-documents/dns-prefetching"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A DNS lekérdezés folyamatának ideje elég széles skálán mozog. DNS cache találatkor 1 ms-től kezdődően, a teljes lekérdezés esetén akár több másodperces idejéig változhat a művelet ideje. Az egyik lehetőség DNS lekérdezés gyorsítására a "},{"_type":"span","marks":["7b031992db7d"],"text":"DNS prefetch"},{"_type":"span","marks":[],"text":", ahol az oldalon található linkek domainjei már betöltődés közben párhuzamosan fel lesznek oldva. Ezt a böngésző egy külön szálon végzi el. Hasznos lehet ez a funkció, ha gyakran hivatkozott más domainekre vannak linkjeink, ilyen például egy hírportál, vagy egy keresőprogram. A domain nevek előzetes feloldását manuálisan elősegíthetjük a következőképpen:"}]},{"_type":"code","code":"<link rel=\"dns-prefetch\" href=\"//<prefetch-elni kívánt oldal címe>\" /> ","language":"html"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A prefetchelést ki és bekapcsolhatjuk a következő meta tag "},{"_type":"span","marks":["em"],"text":"content"},{"_type":"span","marks":[],"text":" attribútumának "},{"_type":"span","marks":["em"],"text":"off"},{"_type":"span","marks":[],"text":" vagy "},{"_type":"span","marks":["em"],"text":"on"},{"_type":"span","marks":[],"text":" értékével:"}]},{"_type":"code","code":"<meta http-equiv=\"x-dns-prefetch-control\" content=\"off\" /> ","language":"html"},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"2. - 3. fázis: Kapcsolódás és küldés"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Láthatjuk, hogy az idő jelentős részében a kliens csak hálózati kommunikációt folytat, így a DNS lekérdezések és TCP kapcsolatok létrehozása jelentős overhead-del jár. Ezen akkor tudunk spórolni, hogy ha minél inkább kötegelten, egyszerre végzünk el műveleteket, ugyanis a hálózati kommunikációt nem igazán tudjuk gyorsítani (2.-3. fázis). Ehhez kapcsolódó módszereket a kliens oldali optimalizáció részénél mutatom be."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"4. fázis: Várakozás a szerver válaszára"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ez a lépés főleg a szerver oldali alkalmazás gyorsítását jelenti: a minél gyorsabb válaszidő elérését. Ennek elég terjedelmes szakirodalma van és nem is tartozik nagyon a kliensoldali optimalizációhoz, így most nem fogok bővebben írni róla. Statikus fájlok kiszolgálásakor érdemes a cachelést finomhangolni, illetve beállítani a gzip tömörítést a webszervernél."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"5. fázis: Betöltés"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A kliens oldali teljesítményt legnagyobb részben ez a tényező határozza meg. Itt dolgozza fel a kliens a szerver válaszát, betölti az oldalhoz szükséges erőforrásokat, előállítja a megjelenítendő oldalt, másnéven rendereli azt. Két művelet van a megjelenítés során, amelyeket meg kell érteni:"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"repaint: Egy elem kinézete megváltozott, de az oldal elrendezése nem változott. Például ilyen, ha "},{"_type":"span","marks":["em"],"text":"outline"},{"_type":"span","marks":[],"text":", background-color CSS osztályok lettek hozzáadva egy elemhez."}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"reflow: Az elem megváltozása miatt újra kell számolni az oldal elrendezését. Ez a művelet mindig egy repaint-et is vonz maga után, így különösen drága művelet, ezért spórolni kell a használatával."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ezek után az a kérdés, hogy mi okoz reflow-t? A rossz hír az, hogy szinte minden: például DOM műveletek, lekérdezések; stílusok hozzáadása, elvétele; görgetés, átméretezés. A rengeteg DOM műveletet végző alkalmazásoknál spórolni kell a nagy számításigényű műveletekkel, mert csak így lehet nagyobb teljesítményt elérni."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A következőkben bemutatok pár jól használható technikát, amelyekkel csökkenthetjük a fenti erőforrásigényes műveletek számát. A legfontosabb, hogy a DOM-fa minél kisebb részfáját módosítsuk. Az egyik leghasznosabb trükk, ha semmiképpen sem tudjuk elkerülni a nagyszámú DOM műveletet, ha azokat a fáról leválasztva végezzük el. CSS segítségével "},{"_type":"span","marks":["em"],"text":"display:none;"},{"_type":"span","marks":[],"text":" stílust adhatunk egy részfának, így a különböző műveletek esetén nem okoznak reflow-t a módosítások. Javascript esetén a részfákat kell előállítanunk memóriában, majd később hozzá lehet adni a DOM fához. A részfa lemásolásához használható a "},{"_type":"span","marks":["em"],"text":"cloneNode()"},{"_type":"span","marks":[],"text":" metódus. Hasznos lehet tudni, hogy a DOM műveleteket a böngészőmotor csoportosítva, kötegelten végzi el, így az olvasás illetve írás jellegű műveleteket minél inkább egyszerre érdemes végrehajtani. Erre példa lehet, amikor CSS osztályokkal alkalmazunk egy stílust egyszerre több elemre, vagy Javascriptnél próbáljuk a lekérdezés, módosítás jellegű műveleteket csoportosítani."}]},{"_type":"block","markDefs":[],"style":"h3","children":[{"_type":"span","marks":[],"text":"Erőforrások betöltése"}]},{"_type":"block","markDefs":[{"_key":"738aa616d94a","_type":"link","href":"http://http2.github.io/"},{"_key":"051bd6fd849a","_type":"link","href":"http://hu.wikipedia.org/wiki/SPDY"},{"_key":"0892860bc38b","_type":"link","href":"https://developers.google.com/speed/spdy/mod_spdy/"},{"_key":"284c3a5e56ee","_type":"link","href":"http://nginx.org/en/docs/http/ngx_http_spdy_module.html"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az egyik első dolog, amit optimalizálni érdemes az az oldal betöltődéséhez szükséges kapcsolatok számának minimalizálása. Alapesetben minden erőforrást egy külön kapcsolaton keresztül kell megszerezni, így ez rengeteg overhead-et jelent. Ennek megoldásában segíthetnek a HTTP2 / SPDY protokollok használata. A "},{"_type":"span","marks":["738aa616d94a"],"text":"HTTP2"},{"_type":"span","marks":[],"text":" a "},{"_type":"span","marks":["051bd6fd849a"],"text":"SPDY"},{"_type":"span","marks":[],"text":" protokollon alapszik, mely képes multiplexelni a kapcsolatokat, illetve tömöríti a fejléceket. "},{"_type":"span","marks":["0892860bc38b"],"text":"Apache HTTPD modulként"},{"_type":"span","marks":[],"text":" és "},{"_type":"span","marks":["284c3a5e56ee"],"text":"NGINX modulként"},{"_type":"span","marks":[],"text":" is szerezhető támogatás hozzá. A kapcsolatok multiplexelésével az oldalhoz szükséges erőforrások egyszerre letöltődnek, így azok nem jelentenek külön overhead-et. Azonban, ha nem a saját webszerünkön futtatjuk az alkalmazást és nem tudjuk kihasználni a fenti protokollok előnyeit, akkor más módszerek használatára is szükség van."}]},{"_type":"block","markDefs":[{"_key":"e7e05a5792f3","_type":"link","href":"http://kir-dev.sch.bme.hu/2014/02/22/yeoman/"},{"_key":"91a011c06ee7","_type":"link","href":"http://gruntjs.com/sample-gruntfile"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Egyrészt a SPDY protokoll nyújtotta előnyök egy részét mi is előállíthatjuk magunknak, ha tömörítjük és összefűzzük az erőforrásokat. CSS és JS fájloknál a tömörítés a whitespace-ek eltávolítását jelenti, illetve JS esetén az obfuszkálással (kódösszezavarással) is kisebb lesz a fájl mérete. Ezen feladatokat a "},{"_type":"span","marks":["e7e05a5792f3"],"text":"múltkori cikkben"},{"_type":"span","marks":[],"text":" is bemutatott "},{"_type":"span","marks":["91a011c06ee7"],"text":"Grunt"},{"_type":"span","marks":[],"text":" segítségével könnyen végrehajthatjuk a "},{"_type":"span","marks":["em"],"text":"concat"},{"_type":"span","marks":[],"text":" és "},{"_type":"span","marks":["em"],"text":"uglify"},{"_type":"span","marks":[],"text":" taskok segítségével."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A nélkülözhetetlen funkciókat tartalmazó kritikus JS és CSS fájlok kiválasztása rendkívül fontos: a "},{"_type":"span","marks":["em"],"text":"critical rendering path"},{"_type":"span","marks":[],"text":" minimalizálásával a legnagyobb, sok erőforrást használó oldalt is gyorsabbá tehetjük, mint akár egy egyszerűbb weboldalt. Milyen funkciókat tartunk kritikusnak? Azokat amelyek az oldal kezdeti betöltődésekor görgetés nélkül látszódnak és alapvető funkciókat nyújtanak az oldal használatában. A görgetés nélkül látszódó tartalmat okosan kell megválasztani, ehhez úgy kell átstruktúrálni az oldal HTML kódját, hogy a fő tartalom ott helyezkedjen el és a másodlagos dolgok csak később kerüljenek betöltésre. Például egy navigációs sávot hiába feljebb helyezkedik el az oldalon a tartalom után kell elhelyezni a HTML-ben és csak ezután CSS segítségével pozícionálni. Ezzel a trükkel a felhasználóknak gyorsan tudunk tartalmat kiszolgálni."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A lehető leggyorsabb alkalmazás betöltődéshez és a minél hamarabbi használhatósághoz a kritikus funkciókat tartalmazó rövidebb JS és CSS részeket tehát érdemes inline az oldal "},{"_type":"span","marks":["em"],"text":"head"},{"_type":"span","marks":[],"text":" részében megírni, mivel azon kódrészletek futnak le a leghamarabb a HTML fájl letöltődése után. A hosszabb kritikus JS és CSS fájlokat azonban érdemesebb már külső erőforrásként betölteni, mivel azokat a böngésző cacheli. A többi fájl betöltése történhet "},{"_type":"span","marks":["em"],"text":"lazy loading"},{"_type":"span","marks":[],"text":" segítségével (azaz JavaScript-ből adjuk hozzá a script tag-et a HTML-hez), vagy használhatjuk a késleltetett betöltés technikáját."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBNQT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--27c5d690cb3a2dca77a6245357f213adb84d22f8/2014-03-06-scriptexecution.jpg","alt":"scriptexecution"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Alapvetően háromféle módon tölthetünk be külső JavaScript-et:"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"alapértelmezett: Ebben az esetben, ha a HTML fájl parse-olása a script tag-hez ér, akkor megszakad a parse-olás, betölti a JS fájlt, lefuttatja, majd folytatja a script tag utáni HTML beolvasását."}]},{"_type":"code","code":"<script type=\"text/javascript\" src=\"<JS fájl elérési útvonala>\"></script> ","language":"html"},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"késleltetett: Amikor a HTML fájl parse-olása a script tag-hez ér, párhuzamosan letöltődik a JS fájl, majd csak a HTML fájl parse-olásának végén kerül futtatásra."}]},{"_type":"code","code":"<script defer type=\"text/javascript\" src=\"<JS fájl elérési útvonala>\"></script> ","language":"html"},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"aszinkron: Amikor a HTML fájl parse-olása a script tag-hez ér, párhuzamosan letöltődik a JS fájl, majd a parse-olás megszakad és csak akkor folytatódik, ha lefutott a JavaScript kód."}]},{"_type":"code","code":"<script async type=\"text/javascript\" src=\"<JS fájl elérési útvonala>\"></script> ","language":"html"},{"_type":"block","markDefs":[{"_key":"7125d74f6182","_type":"link","href":"http://www.feedthebot.com/pagespeed/defer-loading-javascript.html"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A tapasztalatok alapján azonban nem minden böngészőben működik jól az erőforrás betöltődés késleltetése (defer) így, ha a critical rendering path-ról teljesen el akarjuk tüntetni a betöltődést, használhatjuk a Google által is "},{"_type":"span","marks":["7125d74f6182"],"text":"javasolt megoldást"},{"_type":"span","marks":[],"text":":"}]},{"_type":"code","code":"<script type=\"text/javascript\"> function downloadJSAtOnload() { var element = document.createElement(\"script\"); element.src = \"<JS fájl elérési útvonala>\"; document.body.appendChild(element); } if (window.addEventListener) window.addEventListener(\"load\", downloadJSAtOnload, false); else if (window.attachEvent) window.attachEvent(\"onload\", downloadJSAtOnload); else window.onload = downloadJSAtOnload; </script> ","language":"js"},{"_type":"block","markDefs":[{"_key":"c318863b7ce0","_type":"link","href":"https://developers.google.com/speed/libraries/devguide?csw=1"},{"_key":"bb4c6f3622f0","_type":"link","href":"http://cdnjs.com/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ha külső domainről töltünk be erőforrást, akkor pedig mindenképp érdemes valamilyen CDN-t ( "},{"_type":"span","marks":["em"],"text":"content delivery network"},{"_type":"span","marks":[],"text":" ) használni, mely egy olyan szolgáltatás, amivel a felhasználóhoz földrajzilag legközelebb eső szerverről szerezheti meg a kívánt erőforrást. Ilyen CDN-t a "},{"_type":"span","marks":["c318863b7ce0"],"text":"Google is üzemeltet"},{"_type":"span","marks":[],"text":", de itt inkább csak a legismertebb library-ket találhatjuk meg, így célravezető "},{"_type":"span","marks":["bb4c6f3622f0"],"text":"máshol is körbenézni"},{"_type":"span","marks":[],"text":"."}]},{"_type":"block","markDefs":[],"style":"h3","children":[{"_type":"span","marks":[],"text":"Képek"}]},{"_type":"block","markDefs":[{"_key":"ec4a84fc0d68","_type":"link","href":"http://www.smushit.com/ysmush.it/"},{"_key":"7b1f614f7768","_type":"link","href":"http://punypng.com/"},{"_key":"8221768d1e25","_type":"link","href":"http://webcodertools.com/imagetobase64converter"},{"_key":"819b2e6ace8d","_type":"link","href":"http://snapsvg.io/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A következő nagyobb optimalizálható rész egy honlapon a képek kezelése. A critical render path-ra eső képeket a HTML-lel együtt töltsük be, az egyéb kevésbé fontos, vagy nem látszódó képeket lazy loading segítségével Javascript kódból. A megjelenítendő képeket minden esetben optimalizáljuk a webes megjelenítésre. Böngészőkből a képeket átméretezni sok számítással jár és minden esetben reflow-t okoz, így azokat minél inkább kerüljük. Minőségüket a szemmel nem látható mértékig csökkentsük, és tömörítsük őket. A tömörítésben segíthetnek a különböző fejlettebb képszerkesztő programok, vagy olyan webes eszközök, mint a "},{"_type":"span","marks":["ec4a84fc0d68"],"text":"Yahoo Smush.it"},{"_type":"span","marks":[],"text":" és a "},{"_type":"span","marks":["7b1f614f7768"],"text":"PunyPNG"},{"_type":"span","marks":[],"text":". Egyes esetekben a képméretet más fájlok méretének rovására csökkenthetjük, például megadhatjuk a képünket "},{"_type":"span","marks":["8221768d1e25"],"text":"base64 kódolással"},{"_type":"span","marks":[],"text":" a CSS méretének megnövelésével, vagy ha a képeket SVG formátumban használjuk, elkészíthetjük őket akár "},{"_type":"span","marks":["819b2e6ace8d"],"text":"Javascript segítségével"},{"_type":"span","marks":[],"text":" is."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Spórolhatunk a különböző képek betöltéséhez szükséges kapcsolatokon is, ha azokat egyszerre, kötegelten végezzük el. Ebben segíthet a korábban már említett SPDY protokoll, vagy választhatjuk a korábbi módszert, a spriteokat. Sprite-ok esetén egy nagyobb képre összemásoljuk az összes szükséges képet, így azok egyetlen fájlként töltődnek le, majd CSS segítségével jelenítjük meg belőlük a szükséges részeket kivágással."}]},{"_type":"block","markDefs":[{"_key":"5b099cb6a307","_type":"link","href":"https://developers.google.com/speed/webp/"},{"_key":"e0505f3d3baf","_type":"link","href":"http://caniuse.com/webp"},{"_key":"c964f6fa3dae","_type":"link","href":"http://blog.chromium.org/2014/03/webp-improves-while-rolling-out-across.html"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Érdekességként említeném meg a külön webre optimalizált formátumokat, mint a "},{"_type":"span","marks":["5b099cb6a307"],"text":"WebP"},{"_type":"span","marks":[],"text":", mely 25-34%-al kisebb mint az egyéb képformátumok. Sajnos nem mindenhol "},{"_type":"span","marks":["e0505f3d3baf"],"text":"támogatott"},{"_type":"span","marks":[],"text":" a technológia (például Firefox-ban nem használható még), így nem ajánlott az éles bevetése, de mindenképp érdemes figyelemmel "},{"_type":"span","marks":["c964f6fa3dae"],"text":"kísérni fejlődésüket"},{"_type":"span","marks":[],"text":"."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Összefoglalás, további olvasnivalók"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Először is gratulálok mindenkinek, aki eljutott az olvasással idáig. Hosszú út volt, amely során láthattuk, hogy a HTTP lekérdezések egyes fázisait milyen módszerekkel lehet optimalizálni. A rengeteg lehetőség közül, amiket a leginkább kiemelnék és a Google ajánlások közül is a legfontosabbak:"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"oldal tartalmának priorizálása (critical rendering path)"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"erőforrások okos betöltése"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"képek optimalizálása"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBMdz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--de47ca18d6557f48c1df9e41c614b3f75d0a8aef/2014-03-06-pagespeedinsights.png","alt":"pagespeedinsights"}}]},{"_type":"block","markDefs":[{"_key":"5dd7b03c2b95","_type":"link","href":"https://developers.google.com/speed/pagespeed/insights/"},{"_key":"4c65b0a80903","_type":"link","href":"http://www.webpagetest.org/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Természetesen a fenti műveletek végrehajtása után is érdemes méréseket végezni, ehhez ajánlom a "},{"_type":"span","marks":["5dd7b03c2b95"],"text":"Google PageSpeed Insights"},{"_type":"span","marks":[],"text":" és "},{"_type":"span","marks":["4c65b0a80903"],"text":"Webpagetest"},{"_type":"span","marks":[],"text":" elemzőprogramokat, melyek értékelési szempontjai alapján ezen cikk is készült. További olvasnivalónak pedig ajánlom az alábbi linkeket:"}]},{"_type":"block","markDefs":[{"_key":"f7e1587d3a52","_type":"link","href":"http://www.feedthebot.com/pagespeed/"}],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":["f7e1587d3a52"],"text":"Google PageSpeed Insights optimalizáció"}]},{"_type":"block","markDefs":[{"_key":"f7e79479d6d4","_type":"link","href":"http://www.slideshare.net/matenadasdi1/optimizing-browser-experience-hwsw-app-conf"}],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":["f7e79479d6d4"],"text":"Teljesítményoptimalizálás mobilon"}]}]}
{"_type":"post","_createdAt":"2014-04-19T10:00:00.000+02:00","publishedAt":"2014-04-19T10:00:00.000+02:00","title":"Az express.js és az npm, Node is still a badass tech - III. rész","body":[{"_type":"block","markDefs":[{"_key":"4c07fe786af3","_type":"link","href":"http://www.npmjs.com/"},{"_key":"39792d27aec1","_type":"link","href":"http://expressjs.com/"},{"_key":"975992f34855","_type":"link","href":"http://www.sinatrarb.com/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Egy kisebb kihagyás után folytatjuk az előre haladást a Node.js világában. A mai témánk az npm ("},{"_type":"span","marks":["4c07fe786af3"],"text":"Node Package Manager"},{"_type":"span","marks":[],"text":") illetve az "},{"_type":"span","marks":["39792d27aec1"],"text":"Express.js"},{"_type":"span","marks":[],"text":" web application framework. Előbbi a csomagok menedzselésére, utóbbi pedig webalkalmazások készítésére szolgál. Az express.js egy "},{"_type":"span","marks":["975992f34855"],"text":"Sinatra"},{"_type":"span","marks":[],"text":" szerű framework, amelyet igen egyszerű használni. Ebben a cikkben az alapokról lesz szó, és megpróbálom bemutatni, hogyan tudtok elindulni egy ilyen webalkalmazás fejlesztésekor."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/08e5024461b554fc0a43611ffab1a8fe3c0eb5c1","alt":"express-cover"}}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Node package manager"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az npm egy package manager (csomagkezelő) a Node.js-hez. A nevéből következően arra használhatjuk, hogy Node programokat és csomagokat telepítsünk. Ha fejlesztéshez használod, akkor az megkönnyíti a függőségek letöltését és menedzselését az alkalmazáshoz. Segítséghez az "},{"_type":"span","marks":["code"],"text":"npm help"},{"_type":"span","marks":[],"text":" parancsot futtassuk. A csomagokat az "},{"_type":"span","marks":["code"],"text":"nmp install blerg"},{"_type":"span","marks":[],"text":" paranccsal tudjuk telepíteni. Jelen esetben a blerg csomag legfrissebb verzióját fogja telepíteni. Az "},{"_type":"span","marks":["code"],"text":"npm ls"},{"_type":"span","marks":[],"text":" paranccsal lehet listázni a telepített vagy létező csomagokat például: "},{"_type":"span","marks":["code"],"text":"npm ls installed"},{"_type":"span","marks":[],"text":". Az "},{"_type":"span","marks":["code"],"text":"npm update"},{"_type":"span","marks":[],"text":" paranccsal frissíthetjük a már telepített csomagokat. Az npm az úgynevezett "},{"_type":"span","marks":["em"],"text":"registryből"},{"_type":"span","marks":[],"text":" dolgozik, ahol az összes létező csomagról megtalálhatóak az információk."}]},{"_type":"block","markDefs":[],"style":"h3","children":[{"_type":"span","marks":[],"text":"A package.json fájl"}]},{"_type":"block","markDefs":[{"_key":"f9e5093f8554","_type":"link","href":"http://www.w3schools.com/json/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ez a fájl az alkalmazásod könyvtárának a gyökerébe kell kerüljön. Információkat hordoz az npm számára, hogy hogyan épül fel a csomagod, és mit kell csinálni, amikor telepíted. A legtöbb esetben a \"name\", \"version\" mezőket kell kitölteni. A formátuma, ahogy a kiterjesztése is mutatja json, így ha nem tudod, hogy ez hogy kell felépüljön, akkor ideje megtanulni "},{"_type":"span","marks":["f9e5093f8554"],"text":"innen"},{"_type":"span","marks":[],"text":"."}]},{"_type":"code","code":"{ \"name\": \"application-name\", \"version\": \"0.0.1\", \"private\": true, \"scripts\": { \"start\": \"node app.js\" }, \"dependencies\": { \"express\": \"3.5.0\", \"jade\": \"*\", \"less-middleware\": \"*\", \"connect\": \"*\" } } ","language":"json"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az itt látható json egy egyszerű Node.js alkalmazásnak a package.json fájlja. Egyértelmű, hogy melyik mező mire szolgál. A nagyon fontos rész a "},{"_type":"span","marks":["code"],"text":"dependencies"},{"_type":"span","marks":[],"text":". Itt tudod megmondani az alkalmazás függőségeit, amelyeket telepíteni kell, hogy működjön a csomagod, vagy az alkalmazásod. Ha ez a fájl létezik elég kiadnod egy "},{"_type":"span","marks":["code"],"text":"node install"},{"_type":"span","marks":[],"text":" parancsot az aktuális könyvtárban, és automatikusan telepíteni fogja ezeket a csomagokat."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Az express.js framework"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Annak ellenére, hogy a Node HTTP modulja kiváló, nagyon sok dologról kéne gondoskodnunk, ha mindent mi szeretnénk megvalósítani. Az express keretrendszer alapvető funkcionalitásokat valósít meg számunkra, hogy ne azzal menjen az idő el, hogy routingot vagy statikus fájlok kiszolgálását valósítjuk meg, hanem ténylegesen csak az alkalmazással kelljen törődnünk, és minden mást szolgáltat nekünk."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az express telepítéséhez a már előbb bemutatott npm-et fogjuk használni. Adjuk ki a következő parancsot: "},{"_type":"span","marks":["code"],"text":"npm -g install express"},{"_type":"span","marks":[],"text":". Ekkor az npm telepíteni fogja az express csomagot. A "},{"_type":"span","marks":["code"],"text":"-g"},{"_type":"span","marks":[],"text":" kapcsoló azt jelenti, hogy globálisan telepíti a csomagkezelő. Az express innentől parancssoros alkalmazásként is működik. Egy új webalkalmazás létrehozásához adjuk ki az "},{"_type":"span","marks":["code"],"text":"express test"},{"_type":"span","marks":[],"text":" parancsot. Ennek hatására létrejön egy új könyvtár "},{"_type":"span","marks":["em"],"text":"test"},{"_type":"span","marks":[],"text":" néven és minden szükséges függőséget telepíteni fog, illetve legenerál nekünk a parancssoros eszköz. A test/package.json fájl is létrejön amiben a következők lesznek megtalálhatóak:"}]},{"_type":"code","code":"{ \"name\": \"application-name\", \"version\": \"0.0.1\", \"private\": true, \"scripts\": { \"start\": \"node app.js\" }, \"dependencies\": { \"express\": \"3.5.0\", \"jade\": \"*\" } } ","language":"json"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Láthatjuk, hogy ennek az alkalmazásnak két függősége van. Az egyik maga az express keretrendszer, annak is a 3.5.0-ás verziója, a másik pedig a Jade, ami nem más mint egy template engine, amelyről a sorozat következő cikkében lesz szó."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Található még egy app.js fájl, ami az alkalmazásunk fő JavaScript fájlja lesz. Láthatjuk a fentebbi json-ban, hogy a node mindig ezt a fájlt fogja futtatni, és létrejön jópár könyvtár alapvető fájlokkal, amik gyakorlatilag az alkalmazás vázát adják."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ha a könyvtárba belépünk és kiadjuk az "},{"_type":"span","marks":["code"],"text":"npm install"},{"_type":"span","marks":[],"text":" parancsot, akkor megtörténik a függőségek telepítése. Ilyenkor létrejön egy "},{"_type":"span","marks":["code"],"text":"test/node_modules/"},{"_type":"span","marks":[],"text":" könyvtár amin belül megtalálhatóak az alkalmazásunk függőségei. Amennyiben most szeretnénk a következő paranccsal ki is tudjuk próbálni, hogy működik-e az alkalmazásunk"}]},{"_type":"code","code":"$ node app.js Express server listening on port 3000 ","language":"sh"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ha minden rendben kiírja, hogy a 3000-res porton hallgat az alkalmazás, amit egy böngészőben meg is nézhetünk. Annyi a dolgunk, hogy írjuk be a következő címet: "},{"_type":"span","marks":["code"],"text":"localhost:3000"},{"_type":"span","marks":[],"text":". Láthatjuk a paranccsorban, hogy befut egy HTTP GET kérés és az oldal a böngészőben meg is jelenik."}]},{"_type":"code","code":"GET / 200 500ms - 170b GET /stylesheets/style.css 200 10ms - 117b Error: ENOENT, open '...\\workspace\\test\\node_modules\\expres s\\node_modules\\connect\\node_modules\\public\\favicon.ico' ","language":"sh"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Látható a kimeneten, hogy az express is használ csomagokat, amik szintén az "},{"_type":"span","marks":["code"],"text":"express/node_modules"},{"_type":"span","marks":[],"text":" könyvtárában vannak telepítve. Ilyen például a "},{"_type":"span","marks":["code"],"text":"connect"},{"_type":"span","marks":[],"text":" csomag, ami jelenleg annyira nem érdekel minket, de a segítségével sokkal könyebb a HTTP GET illetve POST kéréseket feldolgozni és az express erőteljesen épít a szolgáltatásaira."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Gyorsan vizsgáljuk meg a létrehozott könyvtárakat is. Három fontos könyvtár van, a "},{"_type":"span","marks":["code"],"text":"public"},{"_type":"span","marks":[],"text":", a "},{"_type":"span","marks":["code"],"text":"routes"},{"_type":"span","marks":[],"text":", illetve a "},{"_type":"span","marks":["code"],"text":"views"},{"_type":"span","marks":[],"text":". Az elsőben tároljuk az összes statikusan kiszolgálható fájlt pl.: képek, javascript fájlok, css fájlok stb. Természetesen ezek is a megfelelő mappákba vannak rendezve."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ami viszont sokkal érdekesebb az a "},{"_type":"span","marks":["code"],"text":"routes"},{"_type":"span","marks":[],"text":" könyvtár, ahol kapásból találhatunk egy index.js fájlt. Ez a mappa tartalmazza, az egyes url-ekhez tartozó JavaScript fájlokat, amik kezelik a különböző kéréseket. Az index.js fájl tartalma most még nagyon egyszerű, egy függvényt van benne, amit az exports objektumon be is állítunk. Ez az egész a route-ok megvalósításához kell, mert az app.js-ben ezekre az exportált függvényekre hivatkozunk, amikor egy url-en befut egy kérés."}]},{"_type":"code","code":"/* * GET home page. */ exports.index = function (req, res) { res.render('index', { title: 'Express' }) } ","language":"js"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az utolsó könyvtár pedig a "},{"_type":"span","marks":["code"],"text":"views"},{"_type":"span","marks":[],"text":", ahol a HTML template fájlokat tároljuk. A template engine alapértelmezett esetben a jade, de ez természetesen bármikor lecserélhető."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Miket rejteget az app.js fájl?!"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Nézzük meg szinte soronként a fájl tartalmát. Az első rész a függőségek betöltése."}]},{"_type":"code","code":"/* * Module dependencies. */ var express = require('express') var routes = require('./routes') var user = require('./routes/user') var http = require('http') var path = require('path') var app = express() ","language":"js"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az app objektumunk lesz az alkalmazásunk lelke. Ebben az objektumban tudjuk beállítani a szükséges dolgokat, hogy az express működjön. Az alább olvasható részben látható, hogy kezdjük a portszámmal, amin futni fog az alkalmazás, a különböző könyvtárak megadásával, ahol a templateket tároljuk illetve a statikus fájlokat. Láthatjuk, hogy az alkalmazásunk különböző modulokat használ az expressből."}]},{"_type":"code","code":"// all environments app.set('port', process.env.PORT || 3000) app.set('views', path.join(__dirname, 'views')) app.set('view engine', 'jade') app.use(express.favicon()) app.use(express.logger('dev')) app.use(express.json()) app.use(express.urlencoded()) app.use(express.methodOverride()) app.use(app.router) app.use(express.static(path.join(__dirname, 'public'))) ","language":"js"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A legutolsó legfontosabb rész pedig a route-ok megadása, ezeket a böngészőbe beírva, biztosan lesz egy kezelő függvény, ami megvalósítja a kívánt működést. Az utolsó fontos rész pedig a szerver elindítása és a megadott porton történő figyelés a kérések kiszolgálása érdekében."}]},{"_type":"code","code":"app.get('/', routes.index) app.get('/users', user.list) http.createServer(app).listen(app.get('port'), function () { console.log('Express server listening on port ' + app.get('port')) }) ","language":"js"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ma két dolgot néztünk át. Az egyik az npm és annak használata, a másik pedig egy ismerkedés volt, az express.js keretrendszerrel. A következő részben viszont már egy egyszerű weboldalt fogunk készíteni az express.js-t használva."}]}]}
{"_type":"post","_createdAt":"2014-05-07T23:38:16.000+02:00","publishedAt":"2014-05-07T23:38:16.000+02:00","title":"PÉK 2.7.0 release","body":[{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Lassan, de eljött ez is. A nagy megújulás előtti utolsó nagyobb release. A felszínen nem sok minden változott, inkább a motorháztető alatt takarítottunk megint. Még mindig az egyszerűség és karbantarthatóság a vesszőparipánk. A mostani változtatások is ebbe az irányba vitték a kódbázist."}]},{"_type":"block","markDefs":[{"_key":"7de9443e7f4f","_type":"link","href":"https://github.com/kir-dev/korok/compare/60e0dfa66e7c12722188108159c1c50402ee0e90...sch-pek-2.7.0"},{"_key":"4b6ec15ad63b","_type":"link","href":"https://github.com/kir-dev/korok/pull/92"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A legutolsó kiadás óta beküldött összes commit megtekinthető a "},{"_type":"span","marks":["7de9443e7f4f"],"text":"githubon"},{"_type":"span","marks":[],"text":", valamint a mostani a releváns "},{"_type":"span","marks":["4b6ec15ad63b"],"text":"pull request"},{"_type":"span","marks":[],"text":" is."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A mostani kiadás elsődleges célja az adatbázisban lévő üzleti logika (tárolt eljárások) felszámolása volt. A tárolt eljárások nagyon hasznosak, de esetünkben nagyban nehezítik a kód megértését és tesztelhetőségét."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A legnagyobb változás, hogy a közösségi pontok már nem "},{"_type":"span","marks":["em"],"text":"on-thy-fly"},{"_type":"span","marks":[],"text":" generálódnak, amikor egy felhasználó "},{"_type":"span","marks":["em"],"text":"Közösségi történet"},{"_type":"span","marks":[],"text":"ét nézzük, hanem az értékelési időszak lezárásával generáljuk őket, onnantól pedig a tárolt érték kerül megjelenítésre."}]}]}
{"_type":"post","_createdAt":"2014-06-05T00:56:00.000+02:00","publishedAt":"2014-06-05T00:56:00.000+02:00","title":"auth.sch tesztrepülés","body":[{"_type":"block","markDefs":[{"_key":"bd7479bdfdcd","_type":"link","href":"/post/2014-03-16-auth-sch"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Már többször volt szó arról (legutóbb az "},{"_type":"span","marks":["bd7479bdfdcd"],"text":"auth.sch koncepciójának felvázolásakor"},{"_type":"span","marks":[],"text":"), hogy a Schönherzben megújítjuk és egyben le is cseréljük a jelenlegi SSO megoldásunkat. Ez lényegében azt jelenti, hogy a következő félévtől a jól megszokott VIR-es bejelentkező felületet nyugdíjazzuk és helyette egy rugalmasabb megoldást adunk. Felhasználói szemszögből nem sok minden változik. A következő félévtől már nem tudsz[^1] majd belépni a VIR felhasználóddal, helyette a "},{"_type":"span","marks":["em"],"text":"schaccodat"},{"_type":"span","marks":[],"text":" vagy a "},{"_type":"span","marks":["em"],"text":"BME címtár azonosítódat"},{"_type":"span","marks":[],"text":" tudod majd használni."}]},{"_type":"block","markDefs":[{"_key":"48029930153f","_type":"link","href":"https://auth.sch.bme.hu/"},{"_key":"3a9c592ac631","_type":"link","href":"https://twitter.com/vbalazs"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A fejlesztések már nagyban folynak - mind a KSZK, mind pedig a Kir-Dev oldalán. Ennek előszelét láthatjátok most a megváltozott bejelentkező képernyőn. Az "},{"_type":"span","marks":["48029930153f"],"text":"auth.sch"},{"_type":"span","marks":[],"text":" már készen áll egy nyílt tesztre, valamint "},{"_type":"span","marks":["3a9c592ac631"],"text":"Balo"},{"_type":"span","marks":[],"text":" meghegesztette az OpenAM-et, hogy be lehessen jelentkezni VIR-be auth.sch-n keresztül is."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Tehát röviden összefoglalva, mostantól lehetőség van a VIR-be bejelentkezni az ősztől élesedő rendszeren keresztül is. Minden bejelentkezésnél választhatsz, hogy az auth.sch-n keresztül jelentkezel be, vagy maradsz a régi jól bevált formnál."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Bátorítanék mindenkit, hogy próbálja ki az új bejelentkezési módszert. Ezzel nagyban segíted a munkánkat. Az a jó, ha minél előbb kijönnek a bajok és mindenféle bugok a rendszerből, és ősszel már egy stabil és jól használható szoftvert tudnánk átadni."}]},{"_type":"block","markDefs":[{"_key":"259017b23eba","_type":"link","href":"http://webchat.freenode.net/?channels=kir-dev"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Előre is köszönjük a segítségedet. Még egyszer hangsúlyoznám, hogy fejlesztés alatt lévő szoftverről van szó, így ha nem megy valami, akkor mielőtt melegebb éghajlatra kívánsz minket, inkább írj nekünk. Leggyorsabban a "},{"_type":"span","marks":["259017b23eba"],"text":"#kir-dev"},{"_type":"span","marks":[],"text":" irc csatornán érsz el bennünket."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Fejlesztőknek"}]},{"_type":"block","markDefs":[{"_key":"decac7ec6f39","_type":"link","href":"https://twitter.com/zolij"},{"_key":"23f6ed50fa3c","_type":"link","href":"https://git.sch.bme.hu/kszk/authsch/wikis/oauth_client"},{"_key":"56299231a5f6","_type":"link","href":"https://git.sch.bme.hu/kszk/authsch/wikis/api"},{"_key":"d9b5f7ebe4c8","_type":"link","href":"http://webchat.freenode.net/?channels=kir-dev"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A körös és egyéb VIR bejelentkezést használó oldalak fejlesztőit és karbantartóit arra szeretnénk kérni, hogy minél előbb kezdjék meg az átállást az auth.sch-ra. "},{"_type":"span","marks":["strong"],"text":"Erre már most is van lehetőség"},{"_type":"span","marks":[],"text":". Az auth.sch-hoz "},{"_type":"span","marks":["decac7ec6f39"],"text":"zolij"},{"_type":"span","marks":[],"text":" készített egy jó leírást, amit a projekt wiki oldalain találtok meg a git.sch.bme.hu-n: "},{"_type":"span","marks":["23f6ed50fa3c"],"text":"itt"},{"_type":"span","marks":[],"text":" és "},{"_type":"span","marks":["56299231a5f6"],"text":"itt"},{"_type":"span","marks":[],"text":". Ha bármilyen kérdés van, akkor újfent a "},{"_type":"span","marks":["d9b5f7ebe4c8"],"text":"#kir-dev"},{"_type":"span","marks":[],"text":" irc csatornán tudtok kérdezni."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"[^1]: Ez nem teljesen igaz, mert a következő félév folyamán, míg a teljes átállás"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"meg nem történik, a régi VIR is használható lesz, de csak korlátozottan."}]}]}
{"_type":"post","_createdAt":"2014-06-09T23:56:00.000+02:00","publishedAt":"2014-06-09T23:56:00.000+02:00","title":"We DOcker","body":[{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"A probléma"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A fejlesztés és üzemeltetés feladata sosem volt élesen elkülöníthető, bármennyire is szeretik a fejlesztők és rendszergazdák kölcsönösen egymásra hárítani a felelősséget."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Minden rendszergazda szembesült már a rémálommal, amikor egy szerveren többféle alkalmazást kellett futtatni. A legtöbb esetben ezek függőségei távolról sincsenek összehangolva, így szinte folyamatos a küzdelem a library verziókkal és mellékhatásokkal."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Másik gyakran előkerülő probléma komplex alkalmazásoknál a fejlesztők lokális környezetének kialakítása. Gondoljunk csak arra, hogy a megfelelő Java "},{"_type":"span","marks":["em"],"text":"(Oracle vs OpenJDK vs IBM)"},{"_type":"span","marks":[],"text":" és annak pontos verziójának beszerzése, különféle adatbázisok és egyéb komponensek telepítése akár egy napos művelet is lehet... Az olyan nagyvállalatok, mint például a Google, saját Ubuntu disztribúcióval oldja meg a problémáit. Ez óriási overhead, amit nem mindenki engedhet meg magának. A fentiekhez szorosan kapcsolódó hiba, amit szerintem már mindenki hallott vagy mondott legalább egyszer: "},{"_type":"span","marks":["em"],"text":"\"Nálam működött\""},{"_type":"span","marks":[],"text":"."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"A megoldás"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az utóbbi néhány évben a fenti problémákat "},{"_type":"span","marks":["em"],"text":"virtualizációval"},{"_type":"span","marks":[],"text":" és ún. microservice-kkel igyekeztek orvosolni, nagyrészt csak az éles futó rendszerekben, ahol az ezeket menedzselő rendszereket beüzemelték. A fejlesztéseknek köszönhetően a virtualizáció overheadje jelentősen csökkent, de még mindig nem elhanyagolható a natívan futó alkalmazásokhoz képest. A másik két problémára is csak félmegoldást nyújt, hiszen ehhez a fejlesztői gépeken is virtuális gépet kellene futtatni, ami kényelmetlen és sok erőforrást használ."}]},{"_type":"block","markDefs":[{"_key":"fd5ea901aa94","_type":"link","href":"http://www.docker.com"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ekkor jött a "},{"_type":"span","marks":["fd5ea901aa94"],"text":"Docker"},{"_type":"span","marks":[],"text":" és kiütéssel győzött. A Docker egy linux konténer technológia, amivel egy operációs rendszeren belül elszeparálhatunk futtatókörnyezeteket, teljes értékű virtualizáció nélkül. A Linux kernelbe került új funkciók tették lehetővé az alkalmazások fejlesztésének, buildelésének és terjesztésének új korszakát (pl. "},{"_type":"span","marks":["em"],"text":"cgroups"},{"_type":"span","marks":[],"text":")."}]},{"_type":"block","markDefs":[{"_key":"bda50b0038b8","_type":"link","href":"http://www.docker.com/whatisdocker/"}],"style":"normal","children":[{"_type":"span","marks":["code"],"text":"Dockerfile"},{"_type":"span","marks":[],"text":"-ok segítségével specifikálhatjuk a konténer környezetét - például az operációs rendszert -, telepíthetünk és konfigurálhatunk alkalmazásokat, meghatározhatjuk a futtató felhasználót és még sok mást. Ezekből image-ket generálhatunk, amikből aztán bármennyi konténer példányt indíthatunk. Nem fogom teljesen bemutatni, mert a hivatalos leírásánál én sem tudnám jobban elmagyarázni. "},{"_type":"span","marks":["bda50b0038b8"],"text":"Tessék elolvasni"},{"_type":"span","marks":[],"text":" :)"}]},{"_type":"block","markDefs":[{"_key":"bb2bec26ddc4","_type":"link","href":"http://blog.docker.com/2014/06/its-here-docker-1-0/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Fun fact, de "},{"_type":"span","marks":["bb2bec26ddc4"],"text":"épp ma adták ki"},{"_type":"span","marks":[],"text":" az 1.0-ás, első stabil verzióját (több ezren már eddig is használták éles környezetekben). Érdemes elolvasni, hogy 15 hónap alatt honnan hová jutott el ez a nyílt forráskodú projekt."}]},{"_type":"block","style":"blockquote","markDefs":[],"children":[{"_type":"span","marks":[],"text":"On March 20, 2013, we released the first version of Docker. After 15 months, 8,741 commits from more than 460 contributors, 2.75 million downloads, over 14,000 “Dockerized” apps, and feedback from 10s of 1000s of users about their experience with Docker, from a single container on a laptop to 1000s in production in the cloud"}]},{"_type":"block","markDefs":[{"_key":"e65f0ae21f93","_type":"link","href":"https://www.openshift.com/blogs/containers-certifications-docker-openshift-and-why-it-all-matters"},{"_key":"7f0a1da1f86a","_type":"link","href":"https://www.openshift.com/blogs/how-docker-changed-the-way-we-develop-and-release-openshift-online"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A fenti statisztikából látszik, hogy jelenleg is sokan használják, de az is, hogy messze még a lehetőségek vége. A RedHat épp most dolgozik azon, hogy az OpenShift PaaS (Platform as a service) rendszerébe "},{"_type":"span","marks":["e65f0ae21f93"],"text":"integrálva"},{"_type":"span","marks":[],"text":" a felhasználók még könnyebben futtathassák az alkalmazásaikat. Érdemes elolvasni azt is, hogy a fejlesztőcsapat "},{"_type":"span","marks":["7f0a1da1f86a"],"text":"hogyan használja"},{"_type":"span","marks":[],"text":" a Dockert fejlesztéséhez."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Hogyan használjuk mi?"}]},{"_type":"block","markDefs":[{"_key":"62d74f16e163","_type":"link","href":"http://wildfly.org"},{"_key":"237744576cf6","_type":"link","href":"/post/2014-01-29-pek-jelen-es-jovo-iv"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A Profil és Körök egy komplex üzleti alkalmazás fájlokkal, adatbázissal, JavaEE alkalmazással és "},{"_type":"span","marks":["62d74f16e163"],"text":"Wildfly"},{"_type":"span","marks":[],"text":" szerverrel, illetve "},{"_type":"span","marks":["237744576cf6"],"text":"hamarosan"},{"_type":"span","marks":[],"text":" egy Node.js frontenddel. A fejlesztéshez a belépési küszöböt az elmúlt évben jelentősen csökkentettük (tavaly volt még egy LDAP storage is!), de az újoncok még így sem boldogultak a környezettel."}]},{"_type":"block","markDefs":[{"_key":"56ebb2ab0ddd","_type":"link","href":"https://github.com/kir-dev/korok/tree/docker/docker"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Bármennyire hirdetik, hogy a Docker egyszerű, tapasztalatból tudhatjuk, hogy semmi sem az :) Pár napot eltöltöttem a szoftver szoros társaságában, de végül összeállt a Profil és Körök alkalmazásunk fejlesztői környezete 3 Docker image formájában. Egy "},{"_type":"span","marks":["em"],"text":"shared data volume"},{"_type":"span","marks":[],"text":" a perzisztens adatoknak, egy PostgreSQL szerver és a Wildfly alkalmazásszerver. Az eredmény megtekinthető a "},{"_type":"span","marks":["56ebb2ab0ddd"],"text":"repóban"},{"_type":"span","marks":[],"text":", némi dokumentáció társaságában."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Biztos vagyok benne, hogy még lehetne javítani, alakítani rajtuk, de egy bíztató kezdet. Ha valaki készít egy seeds.sql fájlt, némi minimális adattal, akkor nem csak a körtagok, hanem "},{"_type":"span","marks":["strong"],"text":"bárki"},{"_type":"span","marks":[],"text":" könnyedén be tud kapcsolódni a fejlesztésbe. :)"}]},{"_type":"block","markDefs":[{"_key":"b26be526bb56","_type":"link","href":"http://webchat.freenode.net/?channels=kir-dev"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Egy potenciális jövőképben a körtagok kialakítják a continuous integration, continuous delivery környezeteket és talán élesben is használják majd a technológiát. A lehetőségek száma végtelen. Ha tetszik, amit csinálunk és megjött hozzá a kedved, akkor megtalálsz minket "},{"_type":"span","marks":["b26be526bb56"],"text":"IRC"},{"_type":"span","marks":[],"text":"-n."}]}]}
{"_type":"post","_createdAt":"2014-07-18T11:08:00.000+02:00","publishedAt":"2014-07-18T11:08:00.000+02:00","title":"WIP PéK Front-end","body":[{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Nagyon sokat írtunk már a PéK-ről, de eddig nem nagyon osztottunk meg információkat róla, hogy miként fog kinézni az alkalmazás. Az elmúlt napokban viszonylag jól haladtunk a fejlesztéssel, így kaphattok egy kis betekintést a front-end jelenlegi állapotáról. Szó lesz a használt technológiákról, illetve a folytatásról is."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Egy kis UX és UI"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A folyamat úgy kezdődött, hogy kukáztuk a jelenlegi felületet és az alapjaitól átgondolva kezdtük el fejleszteni az újat. A célunk, hogy teljesen eltüntessük a nyomait, hogy korábban ez két különálló alkalmazás volt, így elég sokat ötleteltünk a megfelelő irányról. Szeretnénk egy modern és felhasználóbarát felületet készíteni a számotokra és ezzel megkönnyíteni az alkalmazás használatát."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az alkalmazást logikailag két külön részre különítjük el. Van egy publikus része, amit mindenki lát és használ: ez a profil, körök, profil szerkesztés, közösségi pontjaid, tagságaid, stb. A zárt részét pedig a körvezetők és adminisztrátorok érik csak el, ilyen például: a közösségi pontozás leadása, illetve jóváhagyása, új kör létrehozása, pék admin felület, svie admin felület, stb. Ezekkel az oldalakkal az emberek többsége nem találkozik, de a nagyobbik részét ezek teszik ki az alkalmazásnak. Most a publikus részéről láthattok egy kis betekintést."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"The UI flow"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/ad342c8a557d49268e40fd229540b11fbfd5618f/800","alt":"ui-flow"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A designon hamarabb kezdtünk el dolgozni, de mikor úgy éreztük, hogy megtaláltuk a megfelelő utat el kellett gondolkozni arról, hogy ez az egész miként fog összeállni egy nagy webalkalmazássá. Egy délután összeültünk közösen és átbeszéltük, hogy milyen elemek kellenek még a front-endre, és milyen legyen a navigáció az oldalon. A korábbi felmérésünkből, amit szép számmal kitöltöttetek kiderült, hogy a legtöbben keresésre használjátok az alkalmazást ezért úgy döntöttünk, hogy az oldal fő funkcionalitása a keresés lesz. Mindenhol tudtok majd keresni, a főoldaltól kezdve, a profilon át, a körös oldalakon keresztül mindenhol lesz egy kereső mező, ahonnan bármit könnyedén el tudtok érni."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"A kezdőoldal"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/0c06143f10dc155436a8c39d38998ec703ab6b84/800","alt":"landing"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A kezdőoldalt ennek megfelelően egy nagy kereső felületté alakítottuk át, ahol a keresési találatok kis kártyákként fognak megjelenni. Az oldal tetején állandó jelleggel találhattok majd egy navbart, aminek a jobb oldalán elérhetitek a profilotokat, illetve egy menüt, ahonnan elnavigálhattok az alkalmazás további oldalaihoz. Természetesen a keresési találatokra kattintáskor is megtörténik a navigáció a profilra vagy a kör profiljára. A menüben egy új feature lesz, az értesítések megjelenítése. Ez főleg a fontos időszakokat fogja mutatni a körvezetők számára, de később egyre több eseményre fogja majd a figyelmeteket felhívni."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"A profil"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/dfbda73d50cce96e19119536d938603a062e514e/800","alt":"profile"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A profil is átalakul, sokkal modernebb lesz a megjelenése a felületnek. Ezen a képen a lenyíló menüt is láthatjátok. A profilon tabok lesznek, amin az információkat csoportokba szervezve megjelenítjük. Az alkalmazás többi oldala is ilyen stílusban lesz elkészítve, és amikor kész vagyunk vele, akkor reményeink szerint lesz mobilra optimalizált verzió is, de ez még nagyon a jövő zenéje."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Stuffs 4 geeks"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Fizikailag három részre lehet elkülöníteni jelenleg az alkalmazást, A back-end JavaEE-ben van írva, amit rendesen megdolgozott tmichel és balo azért, hogy kevesebb bug legyen benne, és a későbbiekben sokkal egyszerűbb legyen karbantartani. A front-end Node.js-ben készül, ami kommunikálni fog a back-enddel. A kliens oldalon, ami a böngésződben fut, természetesen JavaScriptben készülnek a dolgok a HTML és CSS mellett, de hogy a saját életünket is kicsit megkönnyítsük az Angular.js keretrendszert használjuk. Erősen Ajaxos lesz az alkalmazás és reményeink szerint ezzel remek felhasználói élményt fog nyújtani számotokra. Az egyes elemeknek meglesznek a saját controllereik, illetve különböző direktívákat is alkalmazunk a komplex funkcionalitással rendelkező elemekhez. Ilyen például a tabokat megvalósító "},{"_type":"span","marks":["code"],"text":"tabset"},{"_type":"span","marks":[],"text":" direktíva, amelynél a ui.bootstrap-et hívtuk segítségül. Ebben nagyon sok előre definiált direktíva van, így kevesebb sajátot kell írni, csak CSS-ből megfelelően felül kell definiálni a bootstrapes kinézetet. A kliens oldalról történő erőforrás eléréseket pedig angular-serviceként implementáljuk."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Remélem élveztétek az elcsepegtetett információ morzsákat, netán ha túl sok a szabadidőtök így a nyáron, és kedvet kaptatok a fejlesztéshez keressetek minket irc-en, githubon, vagy emailben!"}]}]}
{"_type":"post","_createdAt":"2014-07-28T23:59:00.000+02:00","publishedAt":"2014-07-28T23:59:00.000+02:00","title":"PÉK 2.8.0 release","body":[{"_type":"block","markDefs":[{"_key":"fe8f64736347","_type":"link","href":"http://en.wikipedia.org/wiki/Security_Assertion_Markup_Language"},{"_key":"897fe179a2a3","_type":"link","href":"/post/2014-03-16-auth-sch"},{"_key":"a821b904e3de","_type":"link","href":"/post/2014-06-05-auth-sch-tesztrepules"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A PÉK 2.8.0-ás verziójának nagy újítása, hogy az OpenAM-et, a klasszikus "},{"_type":"span","marks":["fe8f64736347"],"text":"SAML alapú SSO"},{"_type":"span","marks":[],"text":" szolgáltatást magunk mögött hagyjuk és teljesen átállunk az auth.sch-ra. Erről az átállásról már "},{"_type":"span","marks":["897fe179a2a3"],"text":"többször"},{"_type":"span","marks":["a821b904e3de"],"text":"írtunk"},{"_type":"span","marks":[],"text":", de most tényleg eljött. A bejelentkezés módjának változása melett pár fontos módosítást is bevezetünk ezzel a verzióval. Ebben a bejegyzésben ezeket fogom részletesebben megnézni."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Bejelentkezés és regisztráció"}]},{"_type":"block","markDefs":[{"_key":"22733d7e965f","_type":"link","href":"https://korok.sch.bme.hu"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ha ellátogattok a "},{"_type":"span","marks":["22733d7e965f"],"text":"korok.sch.bme.hu"},{"_type":"span","marks":[],"text":" címre, akkor egy új képernyő fogad, ahonnan be lehet jelentkezni az alkalmazásba. Autentikáció után már a megszokott felületeket láthatjátok."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A csavar akkor jön, ha az auth.sch és a PÉK nem tudja automatikusan összekapcsolni a két felhasználói fiókot. Ha van VIR fiókod, akkor egyszerűen csak a felhasználónév és jelszó megadásával linkelheted a fiókjaid. A következő bejelentkezésnél már nem lesz gond. Ha nincs még VIR felhasználód, akkor könnyedén létrehozhatsz egy újat. Már nem szükséges a supporton keresztül új felhasználót igényelni."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A külsősök számára (gondolok itt a külsős MMMK tagokra) a VIR fiók igénylés átalakul "},{"_type":"span","marks":["em"],"text":"schacc"},{"_type":"span","marks":[],"text":" igényléssé, amit supporton keresztül tehetnek meg. Ezügyben a KSZK-hoz kell fordulni."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Fontos, hogy aki eddig auth.sch-n próbált meg bejelentkezni a PÉK-be és folyton hibaüzenetet kapott, az azért volt, mert a két rendszer között az egyeztetés még nem volt teljesen megoldott."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Közösségi pontszámítás"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Több panasz is érkezett a pontszámítással kapcsolatban. Némi vizsgálódás után kiderítettük, hogy a rendszer "},{"_type":"span","marks":["strong"],"text":"helyesen"},{"_type":"span","marks":[],"text":" számítja a pontokat. Egyetlen apró hiba volt ezzel kapcsolatban: az egyes köröknél kapott pontok és belépők akkor is megjelentek a felületen, ha a státuszuk nem "},{"_type":"span","marks":["em"],"text":"elfogadott"},{"_type":"span","marks":[],"text":" volt. Ezt most javítottuk, ezután már csak az elfogadott pontozások láthatóak."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A 2.7.0-ás verzióval változott a pontok előállítása is. Csak egyszer generáljuk a pontokat és utána csak megjelenítjük őket. 2.7-es verzió előtt "},{"_type":"span","marks":["em"],"text":"on-the-fly"},{"_type":"span","marks":[],"text":" generálódtak a pontok, amikor lekérdeztük őket. A 2.8-as verzióban a pontok generálása minden alkalommal megtörténik amikor elbírálnak egy pontozási kérelmet. Így tehát "},{"_type":"span","marks":["strong"],"text":"mindig"},{"_type":"span","marks":[],"text":" a helyes pontszámokat fogjátok látni a "},{"_type":"span","marks":["em"],"text":"közösségi történet"},{"_type":"span","marks":[],"text":" oldalon."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Profil adatok láthatósága"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Egy tavaly őszi frissítés alapértelmezetten elrejtett minden profil adatot így a rendszerünk egyik legfontosabb funkciója, a keresés, szinte használhatatlanná vált. Ezt a problémát most úgy próbáljuk orvosolni, hogy "},{"_type":"span","marks":["strong"],"text":"mindenkinek"},{"_type":"span","marks":[],"text":" láthatóvá tesszük a fontos elérhetőségeit (már ha egyáltalán kitöltötte.) Mostantól a következő attribútumok láthatóak alapértelmezetten: mobil, email és szobaszám. Az újonnan regisztrált felhasználóknál ezek az attribútumok ugyanúgy láthatóak alapértelmezetten. Arra kérnénk mindenkit, hogy ezeket az adatokat tartsátok naprakészen, hogy elérhetőek legyetek a társaitok számára."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Amennyiben valaki úgy érzi, hogy nem szeretné kiadni ezeket az információkat, a profil szerkesztése oldalon (ahogy eddig is) szabályozhatja, hogy mely adatok jelenjenek meg a profil oldalon."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Szobaszámok"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Apró változás, de az auth.sch-s szinkronizáció jóvoltából mostantól KFR-ből megkapjuk az adott félévre vonatkozó szobaszámokat. Ezt minden bejelentkezés után frissítjük."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Jelszavak"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A PÉK-en belül a jelszavak értelmüket vesztették, ezért elkezdtük a kivezetésüket. Jelenleg egyetlen funkciójuk a fentebb is említett fiók összekapcsolás. A jelszókezeléssel kapcsolatos oldalakat töröljük. A jelszó megváltoztatására szolgáló oldal már el is tűnt. Idővel a jelszó emlékeztető oldalt is kivonjuk a forgalomból."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A régi VIR bejelentkező oldalról is eltűnt a jelszavas bejelentkeztető form. Már ott is csak auth.sch-n keresztül lehet bejelentkezni. Ha esetleg hibát dobna az oldal bejelentkezés után, akkor előfordulhat, hogy nem kapcsoltad össze a VIR és auth.sch fiókodat."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Api"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az auth.sch számára a PÉK is szolgáltat adatokat. Az új verzióban pár új dolgot is átadunk az auth.sch számára, így ezeket ti is elérhetitek. Ilyenek például az "},{"_type":"span","marks":["em"],"text":"öregtag"},{"_type":"span","marks":[],"text":" státuszú körtagságok, valamint a körtagságok kezdete és vége is."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Kód"}]},{"_type":"block","markDefs":[{"_key":"23f78fffaf95","_type":"link","href":"https://github.com/kir-dev/korok/compare/sch-pek-2.7.0...v2.8.0"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A végén menjünk bele picit a csúnya részletek be is. A release-hez tartozó összes commit "},{"_type":"span","marks":["23f78fffaf95"],"text":"megtekinthető githubon"},{"_type":"span","marks":[],"text":". Jó néhány pull-request is született menet közben. Ezeken keresztül betekinthettek a munkamódszerünkbe. Jó böngészést kívánok."}]}]}
{"_type":"post","_createdAt":"2014-07-28T14:30:00.000+02:00","publishedAt":"2014-07-28T14:30:00.000+02:00","title":"PÉK fejlesztés várhatóan csúszik némileg","body":[{"_type":"block","markDefs":[{"_key":"eacde6080b33","_type":"link","href":"/post/2014-07-18-pek-front-end"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A "},{"_type":"span","marks":["eacde6080b33"],"text":"legutolsó bejegyzésünkben"},{"_type":"span","marks":[],"text":" arról számoltunk be, hogy szépen halad a munka. Nagyon sok szoftverprojekt életében elérkezik a pillanat, amikor be kell ismerni az elkerülhetetlen csúszás tényét. Mi most megérkeztünk ehhez a pillanathoz. Az új PÉK az átgondolt felületével és vállalható felhasználói élményével egyelőre a jövő homályába veszik."}]},{"_type":"block","markDefs":[{"_key":"d04ccd7b096d","_type":"link","href":"https://lists.sch.bme.hu/wws"},{"_key":"a3a0aae5f650","_type":"link","href":"https://wiki.sch.bme.hu"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Januárban, amikor indult az átalakítási projekt, nagyon optimistán egy július végi időpontot tűztünk ki az éles indulásra. Pontosabban a gólyák érkezésével együtt akartuk indítani az új rendszert. Ahogy közeledett ez a dátum egyre valószínűtlenebbé vált, hogy ezt nem sikerül majd tartani. Ekkor kitoltuk augusztus végére az indulást. Ennél tovább már nem lehet halogatni, mert a gólyák már nem tudnak regisztrálni a mostani (2.7.0-ás) PÉK-be, így például a "},{"_type":"span","marks":["d04ccd7b096d"],"text":"lists.sch"},{"_type":"span","marks":[],"text":" szolgáltatásait nem tudnák igénybe venni, ahogy a "},{"_type":"span","marks":["a3a0aae5f650"],"text":"wiki"},{"_type":"span","marks":[],"text":"-t sem tudnák szerkeszteni."}]},{"_type":"block","markDefs":[{"_key":"5eb43c1902bb","_type":"link","href":"/post/2014-06-05-auth-sch-tesztrepules"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A szomorú tény az, hogy az augusztus végi határidőt sem tudjuk tartani. Ez nekünk fáj a legjobban. Kényszermegoldásként a jelenlegi rendszert alakítottuk át, hogy együtt tudjon működni az "},{"_type":"span","marks":["5eb43c1902bb"],"text":"auth.sch"},{"_type":"span","marks":[],"text":"-val. Ez 2.8.0-ás verziószámmal fog kikerülni hamarosan. Már most is tesztelhető, ha valakit érdekel a dolog. Keressetek minket ircen!"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ezzel a kényszermegoldással a rendszer továbbra is használható marad, mi pedig nyerünk némi időt az új verzió befejezésére. A pontos roadmap egyelőre még nem tisztázott."}]},{"_type":"block","markDefs":[{"_key":"f9b01ccbc906","_type":"link","href":"https://github.com/kir-dev/korok"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A PÉKben az a szép, hogy open source. A kód kint van "},{"_type":"span","marks":["f9b01ccbc906"],"text":"githubon"},{"_type":"span","marks":[],"text":", és pull- requesteket szívesen fogadunk. Aki kedvet kapott hozzá, hogy alakítsa a Schönherz közéletének egyik fontos pillérét, az ne habozzon. Csak egy "},{"_type":"span","marks":["code"],"text":"git clone"},{"_type":"span","marks":[],"text":"-nyi távolságra vagyunk."}]}]}
{"_type":"post","_createdAt":"2017-11-02T22:30:00.000+01:00","publishedAt":"2017-11-02T22:30:00.000+01:00","title":"Még életben","body":[{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ezzel a poszttal egy sorozatot indítok útjára infrastruktúránk egy kisebb, de annál fontosabb részének frissítéséről."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Szóval kezdeném azzal miről is van szó. Kir-Dev-es szerverállományunk két fizikai vasból és egy cloud vm-ből áll. Most az előbbiekre koncentrálnék, azok közül is Meg-re, a development szerverünkre. A korábbi években eléggé el lett hanyagolva, majd évekig ki lett vonva a forgalomból. A rajta levő 12.04-es Ubuntu verzió felett már eljárt az idő, upgrade pedig elmaradt, melynek egyszerű oka, a hardveres RAID vezérlő támogatása... vagyis annak hiánya. Mivel nem tartom túl hasznosnak az erőforrás elpazarolását, úgy döntöttem változtatok a kialakult helyzeten."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Nyár folyamán, egy workshop alkalmával sikerült elindítani magát a szervert. Fellélegeztünk, fél siker. A tükrözött tömb egyik lemezével tökéletesen ment, viszont a másik lemez minden parancs futtatására I/O error-t dobott. Ezután került hozzám a gép, azonnal neki is láttam a lemezek tesztelésének. Szerencsére sok-sok óra után kiderült, nincsen semmi bajuk, így következett a telepítés - mármint csak következett volna. A gép nem akarta semmilyen módon bebootolni az USB-s telepítőt, mindegy volt, milyen külső eszközről volt szó. Ezek után a KSZK-s PXE-vel próbálkoztam, de ott sem akarta az igazságot. Végső megoldásként majdnem optikai tárolók fele fordultam, viszont nem volt kéznél semmi ehhez szükséges eszköz."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"## Telepítés"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ezután jött a gondolat, mi lenne, ha saját PXE szervert készítenék. Nos elsőre jobb ötletnek tűnt, mint megvalósítása volt. Először is az egyszerűség kedvéért hanyagoltam a MacOs-t. Szerencsére volt kéznél egy üres HDD, melyen landolt egy friss Ubuntu. Mélyebben beleásva magamat, láttam, hogy az alábbi három dolog szükséges a művelethez:"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"DHCP server"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"TFTP"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"webkiszolgáló"}]},{"_type":"block","markDefs":[{"_key":"44277837da1a","_type":"link","href":"https://www.ostechnix.com/how-to-install-pxe-server-on-ubuntu-16-04/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Akit érdekel a folyamat "},{"_type":"span","marks":["44277837da1a"],"text":"itt"},{"_type":"span","marks":[],"text":" részletesen le van írva. Amit érdemes megfogadni minden egyes konfigurációs fájl szerkesztés után:"}]},{"_type":"block","style":"blockquote","markDefs":[],"children":[{"_type":"span","marks":[],"text":"Check if ... service is running or not with command:"},{"_type":"span","marks":[],"text":"\n\n"},{"_type":"span","marks":[],"text":"\n\n"},{"_type":"span","marks":[],"text":"\"sudo systemctl status ...\""}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Igen, enélkül nehéz észrevenni az esetleges typo-kat. Ezek után az Ubuntu Server telepítés már gyerekjáték, majdnem a next-next elvet követi, az egyetlen fontosabb mozzanat a RAID tömb beállítása. A dedikált RAID vezérlő használatának ötletét elvetettük, mivel nem támogatott, illetve számunkra csak nyűg lenne és nem igazán profitálnánk belőle. Maradt a szoftveres RAID. Szerencsére a telepítő lehetőséget nyújt ilyen egyszerűen megoldani a kérdést:"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBNdz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--1956b164ff2a029d2847624fc33635c721d5fab5/2017-11-02-raid.png","alt":"RAID beállítása"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Halkan megjegyzem, hogy telepítés során engedélyeztem a csomagok automatikus frissítését is. Kövezzen meg bárki, de korábbi tapasztalatok alapján a karbantartás el szokott maradni és az egyes biztonsági rések nagyobb veszélyt jelentenek, mint az esetleges kiesések."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Következő részben a szerver konfigurálásáról mesélek..."}]}]}
{"_type":"post","_createdAt":"2017-12-31T22:18:57.000+01:00","publishedAt":"2017-12-31T22:18:57.000+01:00","title":"Tanuló","body":[{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A project alapötletét a kollégiumi tanulószobák ihlették. Szinteken keresztül mászkálni, keresni üres helyet, hogy hangzavartól mentesen lehessen készülni egy-egy számonkérésre, befejezni a kiadott házi feladatot stb. Mennyivel kényelmesebb lenne, ha előre látnánk, melyik szinten találunk nyugalomra? Vigyük tovább az ötletet. Mennyivel kényelmesebb lenne látni, hogy éppen melyik szinten készülnek egy aktuális ZH-ra, vagy írják éppen a grafika házijukat? Mennyivel kényelmesebb lenne célzottan segítséget kérni vagy adni másoknak?"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ezen problémák szülték a tanuló projektet, mely arra hívatott, hogy a kollégium tanulószobáit felosztva, célzottan tudjunk tájékozódni közöttük, tanuló csoportokat alkothassunk, konzultációkat szervezhessünk, segítsük a közös együttélést és a közös tanulást."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A KBPR-ral való egyeztetés után jött a hibabejelentés funkció ötlete, mellyel a tanulószobák hibáit lehet bejelenteni."}]},{"_type":"block","markDefs":[{"_key":"66d6f138acc7","_type":"link","href":"https://tanulo.kir-dev.sch.bme.hu/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A következő félévben már ennek segítségével tervezhetitek a közös tanulást. Addig is a "},{"_type":"span","marks":["66d6f138acc7"],"text":"https://tanulo.kir-dev.sch.bme.hu/"},{"_type":"span","marks":[],"text":" címen tudjátok tesztelni az alkalmazást. Hibákat, észrevételeket küldjétek a [email protected]."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A technikai részleteket egy későbbi bejegyzésben fogjuk tárgyalni."}]}]}
{"_type":"post","_createdAt":"2019-11-11T21:41:05.000+01:00","publishedAt":"2019-11-11T21:41:05.000+01:00","title":"Költözünk","body":[{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"A múlt"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Egy szomorú hírrel kell kezdenem ezt a blogbejegyzést. Történt ugyanis, hogy hőn szeretett Brian szerverünk, aki sokáig kitartóan szolgált és látta el webszerveri kötelességét, mára annyira instabil állapotba került, hogy kénytelenek voltunk kényszernyugdíjazni az öreg harcost."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"A jelen"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Szerencsére a sors keze nem volt teljesen kegyetlen velünk, és szert tettünk "},{"_type":"span","marks":["strike-through"],"text":"két"},{"_type":"span","marks":[],"text":" egy, bár szintén veterán, de még egészen jól működő utódra. Sajnos az együkükbe egyelőre nem tudtunk életet lehelni (táphiba a gyanú), de pótalkatrésznek még tökéletes lehet."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az új szerver neve, megtartva a Kir-Dev hagyományos nomenklatúráját, szintén a Family Guy sorozat szereplői közül került ki. Ezúttal Lois-ra esett a választás, és szerencsénkre hardware-es felszereltségében nem kelt csalódást: 2U-s belsejében 24 processzmag mellett 64GB RAM teljesít szolgálatot. Ahogy az alábbi képen is látszik, számítási teljesítményből nem lesz hiány."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBOZz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--88c907db1188597e2435cdd81dae97c9264b1df0/lois_htop.png","alt":"Lois htop"}}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"A jövő"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Bár az új szerverünkre az átállás még folyamatban van, nem árthat máris a jövőbe tekinteni. Felmerült ugyanis, hogy lehetőség lenne a KSZK Kubernetes rendszerén is hosztolni az általunk készített weboldalakat. Ez amiatt nagyon csábító, hogy így a saját hardware esetleges hibáitól függetleníteni tudnánk magunkat, és egy jól skálázódó rendszeren tudnánk kiszolgálni az oldalakat. Mivel a jelenlegi rendszeren is mindent Dockerben futtatunk, az átállás vélhetően elég simán menne. A jelenlegi szervereinket pedig használhatnánk development environmentnek, CI szervernek, etc."}]}]}
{"_type":"post","_createdAt":"2019-12-21T14:45:22.000+01:00","publishedAt":"2019-12-21T14:45:22.000+01:00","title":"Blog 2.0","body":[{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Bár még éppen csak leporoltuk a blogunkat egy nagy Jekyll verziófrissítéssel, máris új vizekre evezünk. Még korábban felmerült az ötlet bennem és Kircsiben, hogy a Jekyll nem tud feltétlen minden feature-t, amire szükségünk lenne (vagy legalábbis nem olyan egyszerű megvalósítani). Mi lenne tehát, ha választanánk egy alkalmasabb frameworköt, és újraírnánk abban?"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Szét is néztünk a static site generátorok piacán megoldást keresve. Több lehetőséget végignéztünk, végül a következő három jelölt maradt a ringben:"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"Hugo: Go nyelvre épít, ami miatt gyors (bár ez egy ekkor projektnél annyira nem szempont), egyedi templatinget használ. A három közül ezt ismerjük a legkevésbé."}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"Jekyll: A mostani blog ezt használja, a szervermigrálás miatt már a legújabb verzióval. Ez Ruby nyelvet használ liquid template-tel. Egyszerű használni és van hozzá néhány hasznos plugin viszont a GitHub Pages még nem támogatja, emiatt a deploy jelenleg saját szerveren, dockerrel van megoldva, ami kissé körülményes."}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"Gatsby: Ez egy Reactra épülő framework, ami támogatja a TypeScriptet is. Messze ez a legfejlettebb framework, rengeteg plugin készült hozzá, és mivel Reactra épül, végtelen npm package is használható. Out-of-the-box támogatott a GitHub Pages, így a deploy is egyszerű, mint az 1x1. A Netlify integrációnak köszönhetően pedig a Pull Requestek is könnyedén kirakhatóak egy saját environmentbe."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A fentiek alapján végül a Gatsbyre esett a választás. Mivel jelenleg mindketten TypeScript-ben fejlesztünk (Angular illetve React), evidens volt, hogy ezt a projektet is ebben szeretnénk megírni. Egy kis kutakodás után találtunk egy megfelelő starter projektet, és kezdődhetett is a kódolás."}]},{"_type":"block","markDefs":[{"_key":"fb7928345b32","_type":"link","href":"https://chakra-ui.com/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A UI kialakításához úgy döntöttünk, hogy a "},{"_type":"span","marks":["fb7928345b32"],"text":"Chakra"},{"_type":"span","marks":[],"text":"-t vesszük igénybe. Ez egy Reacthoz készített UI library, előre definiált, de könnyen testreszabható komponensekkel, könnyen témázható, és default támogatja dark mode-ot (és mellesleg a Simonyi Web is ezt használja)."}]},{"_type":"block","markDefs":[{"_key":"3e783bd19559","_type":"link","href":"https://github.com/kir-dev/blog-next"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Maga a projekt még erősen fejlesztési szakaszban van, de már most érezni, hogy könnyű lesz a frameworkkel dolgozni. A kód a szokásos módon nyílt forráskódú és elérhető a "},{"_type":"span","marks":["3e783bd19559"],"text":"GitHub"},{"_type":"span","marks":[],"text":"-on."}]}]}
{"_type":"post","_createdAt":"2020-06-09T15:33:54.000+02:00","publishedAt":"2020-06-09T15:33:54.000+02:00","title":"Fejlesztés Docker konténerekben","body":[{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Tartalomjegyzék"}]},{"_type":"code","code":"# There comes the toc ","language":"toc"},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Bevezetés"}]},{"_type":"block","markDefs":[{"_key":"1f813803db2f","_type":"link","href":"https://rubyonrails.org/"},{"_key":"f2aab7cd782e","_type":"link","href":"https://www.jetbrains.com/ruby/"},{"_key":"6e770c44420c","_type":"link","href":"https://code.visualstudio.com/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A Docker és egyéb virtualizációs technológiák az üzemeltetésben már jelentősen elterjedtek, viszont a fejlesztésnél még csak szűkebb körben használtak. Egy egyszerű "},{"_type":"span","marks":["1f813803db2f"],"text":"Ruby on Rails"},{"_type":"span","marks":[],"text":" framework alapú projekten keresztül vizsgáljuk meg, hogy milyen szinten lehet hasznosítani a konténereket már a fejlesztés folyamatában is. Az alkalmazásnak szüksége van egy Ruby nyelvet támogató környezetre és egy PostgreSQL adatbázisra. Ezek a gazdagépre nem lesznek telepítve, kizárólag konténereken keresztül lesznek használva. A "},{"_type":"span","marks":["f2aab7cd782e"],"text":"RubyMine"},{"_type":"span","marks":[],"text":" és "},{"_type":"span","marks":["6e770c44420c"],"text":"Visual Studio Code"},{"_type":"span","marks":[],"text":" IDE-ket fogjuk beállítani és használni. Ez a két eszköz eltérő módon közelíti meg a konténerek használatát, ezért érdemes mindkettőt megismerni."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Miért érdemes ezzel foglalkozni?"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"Gyorsan és egyszerűen el lehet kezdeni egy adott alkalmazáson dolgozni, ha van hozzá Docker konfiguráció. Nincs szükség a függőségek letöltésére, konfigurálására."}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"A fejlesztői és üzemeltetési környezetek közötti eltérések jelentős problémákat okzozhatnak egy alkamazás életciklusa közben. A konténerek által biztositott egységes környezetek csökkentik ezen problémák valószínűségét."}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"Több alkalmazás párhuzamos fejlesztése adott függőség (pl.: adatbáziskezelő alakalmazás) eltérő verzióinak használatával könnyen megoldható, mivel egyszerűen lehet párhuzamosan használni több konténerhálózatot."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Konténerek elkészítése"}]},{"_type":"block","markDefs":[{"_key":"fd4627d0d247","_type":"link","href":"https://github.com/JetBrains/sample_rails_app"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A JetBrains csapata elkészitett egy "},{"_type":"span","marks":["fd4627d0d247"],"text":"példa projektet"},{"_type":"span","marks":[],"text":", a konténerek elkészítéséhez azt vesszük alapul. Elösször szükségünk van egy konténerre, amiben a Rails keretrendszert tudjuk futtatni. Docker Hub-on nem találtam megfelelő image-et ehez, ezért az alábbi "},{"_type":"span","marks":["strong"],"text":"Dockerfile"},{"_type":"span","marks":[],"text":"-ban érdemes leirni az image-et:"}]},{"_type":"code","code":"FROM ruby:2.6.3 RUN curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - RUN echo \"deb https://dl.yarnpkg.com/debian/ stable main\" | tee /etc/apt/sources.list.d/yarn.list RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs postgresql-client yarn RUN mkdir /test_app WORKDIR /test_app # A projekt létrehozásánál kommentezzük ki a --- közötti sorokat. #--------------------- COPY Gemfile /test_app/Gemfile COPY Gemfile.lock /test_app/Gemfile.lock COPY package.json /test_app/package.json COPY yarn.lock /test_app/yarn.lock RUN gem install bundler -v '2.0.2' RUN bundle install RUN yarn install --check-files #-------------------- COPY . /test_app EXPOSE 3000 ","language":"Dockerfile"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A fenti image a Ruby 2.6.3-as verzióját tartalmazza, egy Debian rendszeren. Telepítjük még a Yarn és NodeJS csomagokat, amik kezelik a projektben lévő JavaScript fájlokat. Ezután létrehozzuk a test_app mappát és beállítjuk a konténer munkamappájának. Az ezt követő rész felelős az alkalmazás függőségeit képező Ruby és JavaScript könyvtárak letöltéséért. Az utolsó két sor bemásolja a projekt mappáját a konténerbe, majd a konténer 3000-es portját elérhetővé teszi a gazdagép számára."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A Dockerfile elkészítése után elkészíthetjük a "},{"_type":"span","marks":["strong"],"text":"docker-compose.yml"},{"_type":"span","marks":[],"text":" fájl-t, ami a több konténerből álló alkalmazásunkat írja le."}]},{"_type":"code","code":"version: '3' services: db: image: postgres volumes: - ./tmp/db:/var/lib/postgresql/data environment: POSTGRES_HOST_AUTH_METHOD: trust ports: - '5432:5432' web: build: . # command: bundle exec rails s -p 3000 -b '0.0.0.0' command: tail -f /dev/null volumes: - .:/test_app - /test_app/node_modules ports: - '3000:3000' # Ports required for debugging - '1234:1234' - '26166:26168' depends_on: - db ","language":"yaml"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A fájl első részében létrehozzuk a "},{"_type":"span","marks":["strong"],"text":"db"},{"_type":"span","marks":[],"text":" szolgáltást, ami a postgres image alapú konténer lesz. Az adatbázisban tárolt adatok mappáját összekötjük a host egyik mappájával, ezzel perzisztensé téve az adatbázis adatait. Az egyszerűség kedvéért jelszót nem állítunk be. Majd a host 5432-es portját és a konténer 5432-es portját összekötjük."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A második szolgáltatásban fog futni a rails web szerver, ezért ezt "},{"_type":"span","marks":["strong"],"text":"web"},{"_type":"span","marks":[],"text":" néven fogjuk létrehozni. Két lehetséges parancsot is felvettem. Az első elindítja a szervert. A második csak futó állapotban tartja a konténert, hogy fejlesztés közben csatlakozni lehessen hozzá."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az alap Rails projekt elkészítéséhez kommentezzük ki a "},{"_type":"span","marks":["code"],"text":"---"},{"_type":"span","marks":[],"text":"-t tartalmazó sorok közötti részeket a Dockerfile-ban. Ezek a sorok majd az elkészült alkalmazás függőségeinek telepítéséért lesznek felelősek. Ezután létre kell hoznunk a konténereket és a web szolgáltatásban telepítenünk kell a rails könyvtárat, valamint létrehozni egy új alkalmazást, ami a PostgreSQL adatbázist fogja használni. Ha létrejött az alkalamazás, akkor a hozzá tartozó adatbázist is létre kell hozni. Az alábbi parancsok kiadásával tehetjük ezt meg."}]},{"_type":"code","code":"docker-compose run web bash gem install rails rails new test_app --database=postgresql rails db:create ","language":"sh"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A gazdagépen észrevehetjük, hogy a létrehozott fájlokat nem tudjuk szerkeszteni, mivel a tulajdonosuk a root felhasználó. Egy kézenfekvő megoldás a problémára, hogy megváltoztatjuk a fájlok tulajdonosát:"}]},{"_type":"code","code":" sudo chown -R $USER . ","language":"sh"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ez a megoldás hosszútávon nem ideális, mivel mindig meg kell változtatnunk a fájlok tulajdonosát, amikor a konténerből hozzuk létre őket. A Docker lehetőséget biztosít a felhasználói névtér map-elésére. Ezáltal elérhetjük, hogy a konténeren belüli root felhasználóhoz a konténeren kívül a saját felhasználónk tartozzon. Így a konténeren belül létrehozott fájloknak is a saját felhasználónk lesz a tulajdonosa. Ennek a beállításához az alábbi lépéseket kell követni."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Állítsuk be a felhasználó által használható UID-ket. Ehhez nézzük meg felhasználónevünket "},{"_type":"span","marks":["code"],"text":"$USER"},{"_type":"span","marks":[],"text":" váltózóban, valamint a UID-t az "},{"_type":"span","marks":["code"],"text":"id -u"},{"_type":"span","marks":[],"text":" paranccsal. Az alábbi fájlhoz hozzáadunk egy új bejegyzést, ami tartalmazza a felhasználónevünket (user), a UID-t(1000), és a kiosztható ID-k számát(1), kettősponttal elválasztva."}]},{"_type":"code","code":"#/etc/subuid user:1000:1 ","language":"text"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Végezzük el a fenti műveletet a GID-kre. Annyi különbséggel, hogy itt a saját csoportunk ID-jét használjuk. Ezt az "},{"_type":"span","marks":["code"],"text":"id -g"},{"_type":"span","marks":[],"text":" paranccsal kérhetjük le."}]},{"_type":"code","code":"#/etc/subgid user:127:1 ","language":"text"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A fenti beállítások elvégzése után, userns-remap tulajdonságot kell beállítani a felhasználónevünkre. Ez megtehetjük kapcsolóként."}]},{"_type":"code","code":"dockerd --userns-remap=user ","language":"sh"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Vagy daemon.json fájlban."}]},{"_type":"code","code":"#/etc/docker/daemon.json { \"userns-remap\": \"user\" } ","language":"json"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ezután már a konténerből létrehozott fájlok tulajdonosa a gazdagépen a saját felhasználónk lesz. Az alábbi paranccsal elindíhatjuk a konténereinket."}]},{"_type":"code","code":"docker-compose up ","language":"sh"},{"_type":"block","markDefs":[{"_key":"4cb51cf34874","_type":"link","href":"http://localhost:3000/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A "},{"_type":"span","marks":["4cb51cf34874"],"text":"localhost:3000"},{"_type":"span","marks":[],"text":" megtekinthetjük a Rails szerver kezdőoldalát."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBDdz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--27eaddfb7a3d78c6cfdb73d085bbbe92772fc38e/5DGpHV2.png","alt":"Imgur"}}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"RubyMine konfigurálása"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Először gyorsan áttekintjük, miként állithatjuk be, hogy a RubyMine a konténerünet használja fejlesztés során. Megnyitjuk az IDE-t a projektünk mappájában. A "},{"_type":"span","marks":["strong"],"text":"Settings/Preferences/Languages & Frameworks/Ruby SDK and Gems"},{"_type":"span","marks":[],"text":" oldalra navigálunk. Itt a "},{"_type":"span","marks":["strong"],"text":"New remote"},{"_type":"span","marks":[],"text":" gombra kattintva felugrik egy dialógus ablak. Ezen beállítjuk a "},{"_type":"span","marks":["strong"],"text":"Docker Compose"},{"_type":"span","marks":[],"text":" használatát. A lehetséges szolgáltatások közül kiválasztjuk a "},{"_type":"span","marks":["strong"],"text":"web"},{"_type":"span","marks":[],"text":"-et. Az oké gombra kattintás után kiválasztjuk a most létrehozott remote-ot."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ahhoz, hogy el tudjuk indítani az IDE-ből a webszervert, létre kell hoznunk a megfelelő konfigurációs fájlt. Ezt a "},{"_type":"span","marks":["strong"],"text":"Edit configurations"},{"_type":"span","marks":[],"text":" menüpont használatával tehetjük meg. Ezene belül a "},{"_type":"span","marks":["strong"],"text":"template"},{"_type":"span","marks":[],"text":"-ek közül válasszuk ki a "},{"_type":"span","marks":["strong"],"text":"Rails"},{"_type":"span","marks":[],"text":" konfigurációt. Állitsuk át a használt docker-compose parancsot "},{"_type":"span","marks":["strong"],"text":"docker-compose exec"},{"_type":"span","marks":[],"text":"-re. Ezután már elindítható lesz a webszerver."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A debugolás használatához még szükségünk lesz 2 gem-re. Ezek felvételéhez először írjuk be az alábbi sorokat a Gemfile-ba."}]},{"_type":"code","code":"#Gemfile gem 'debase' gem 'ruby-debug-ide' ","language":"rb"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az IDE Alt+Enter lenyomása után felkínálja, hogy újra build-eli az image-et. Használjuk ezt a lehetősége, hogy a gem-ek belekerüljenek az image-be. Ha később további gem-ek telepítésére lenne szükségünk, a fentihez hasonló módon tehetjük meg."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"RubyMine használata"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A Rails keretrendszer lehetőséget biztosít generátorok használatára, amik segítségével egy CRUD-ot megvalósító, tesztekkel ellátott weboldalt hozhatunk létre. Ennek használatával fogjuk kipróbálni a fejlesztőkörnyezet funkcióit. Ahhoz, hogy parancsokat tudjunk futtatni a konténerben, először csatlakoznunk kell hozzá. Ezt az alábbi paranccsal tehetjük meg."}]},{"_type":"code","code":"docker-compose exec web bash ","language":"sh"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Alapvetően a RubyMine terminálja nem kapcsolódik a konténerekhez. Több mód is van, hogy a fejlesztőkörnyezet integrált terminálját automatikusan hozzákapcsoljuk az általunk választott konténerhez. Például a Services oldalon az attach menüpont használatával vagy a Shell Path átállításával. Az egyszerűség kedvéért most manuálisan, a fenti paranccsal csatlakozunk a konténerhez, mivel nem lesz erre gyakran szükség."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ezután a konténerben navigáljunk el a projektünk mappájába (/test_app) és már, ki is adhatjuk a parancsot, amivel hozzáadunk alapvető funkcionalitásokat az alkalmazásunkhoz."}]},{"_type":"code","code":"rails g scaffold ruby_mine name:string points:integer ","language":"sh"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ha mindent jól csináltunk, akkor az alábbi sorok jelennek meg a konzolon:"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBFdz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--872fc944eb0973f81d94c712172e587eccf45ab9/wDxKCEh.png","alt":"Imgur"}}]},{"_type":"block","markDefs":[{"_key":"6656ce6e9cfc","_type":"link","href":"http://localhost:3000/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Láthajuk, hogy létrejöttek oldalak, tesztek, valamint egy kontroller is. Főként ezeket fogjuk használni az IDE tesztelés során. A "},{"_type":"span","marks":["strong"],"text":"zöld háromszög"},{"_type":"span","marks":[],"text":" gomb lenyomásával elindítható a webszerver, ami a "},{"_type":"span","marks":["6656ce6e9cfc"],"text":"localhost:3000"},{"_type":"span","marks":[],"text":"-es címen elérhető."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBFQT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--18354d5dc8bdcfc7b68608ff5f79279b5fa88230/IJgL6cZ.png","alt":"Imgur"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ezután próbáljuk ki a többi fontosabb eszköz működését az IDE-ben. A debug, miután beállítottuk, hogy docker exec-kel legyen használva, egyből használható."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBEUT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--c4432e0d12b637d090fc87eb7400b42d5e6574e9/Dgln72k.png","alt":"Imgur"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Teszteket is könnyedén futthatunk az IDE GUI-ján keresztül. Ehhez navigáljunk egy teszteket tartalmazó fájl-hoz, mondjuk "},{"_type":"span","marks":["strong"],"text":"test/controllers/ruby_mines_controller_test.rb"},{"_type":"span","marks":[],"text":"-hez, itt a "},{"_type":"span","marks":["strong"],"text":"jobb egérgomb"},{"_type":"span","marks":[],"text":" lenyomásával megjelennek a kontextusfüggő lehetőségek. Ezek közül válasszuk a "},{"_type":"span","marks":["strong"],"text":"Run Minitest:"},{"_type":"span","marks":[],"text":"-lehetőséget. A tesztek futásának eredményét is megjeleníti a fejlesztőkörnyezet. Emellett lehetőség van a tesztek közül csak egyet futtani, valamint debug módban is elindíthatjuk a teszteket."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBFUT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--30e75bb65e909367e78a48617bf2c77c476eae7d/IrfSvfK.png","alt":"Imgur"}}]},{"_type":"block","markDefs":[{"_key":"7fcdb482387e","_type":"link","href":"https://youtrack.jetbrains.com/issue/RUBY-12337"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A code-completion és az intelligens navigáció is működik, bár ezekhez nem szükséges a nyelvi környezet, az IDE önállóan nyújtja ezeket a szolgáltatásokat. Szinte minden lehetőség elérhető a konténerből, amit a natívan használt verzió támogat. Egy kivételt találtam: a natív ruby-t használó IDE-ben van lehetőség egyes tesztek futtatása után kilistázni a tesztfedettséget. Valamint az érintett sorokat is színezi a környezet annak függvényében, hogy érintette-e őket az adott futás. Ez a lehetőség még konténeres használat során nem elérhető, de a fejlesztők már tudnak a "},{"_type":"span","marks":["7fcdb482387e"],"text":"problémáról"},{"_type":"span","marks":[],"text":".(A PyCharm alkalmazásban már megoldották, hogy elérhető legyen remote használatával ez a funkcionalitás.)"}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Visual Studio Code konfigurálása"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Nyissuk meg a projektet VSCode-ban. Első lépésként a "},{"_type":"span","marks":["strong"],"text":"telepítsük a szükséges bővítményeket-öket"},{"_type":"span","marks":[],"text":". Ezek az alábbiak:"}]},{"_type":"block","markDefs":[{"_key":"6aeb3c0ce80d","_type":"link","href":"https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers"}],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":["6aeb3c0ce80d"],"text":"Remote - Containers"}]},{"_type":"block","markDefs":[{"_key":"82d2f1ec5cda","_type":"link","href":"https://marketplace.visualstudio.com/items?itemName=rebornix.Ruby"}],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":["82d2f1ec5cda"],"text":"Ruby"}]},{"_type":"block","markDefs":[{"_key":"530af54b156b","_type":"link","href":"https://marketplace.visualstudio.com/items?itemName=castwide.solargraph"}],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":["530af54b156b"],"text":"Ruby Solargraph"}]},{"_type":"block","markDefs":[{"_key":"5db735a21539","_type":"link","href":"https://solargraph.org/guides/rails"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Miután ezeket telepítettük "},{"_type":"span","marks":["strong"],"text":"inditsuk újra az IDE-t"},{"_type":"span","marks":[],"text":" és indítsuk el a "},{"_type":"span","marks":["strong"],"text":"docker-compose up"},{"_type":"span","marks":[],"text":" parancs kiadásával a konténereket. Ezután a bal oldalon lévő "},{"_type":"span","marks":["strong"],"text":"Docker logóra"},{"_type":"span","marks":[],"text":" kattinva válasszuk ki "},{"_type":"span","marks":["strong"],"text":"rails_developmet_in_containers_web"},{"_type":"span","marks":[],"text":" konténert, és válasszuk az "},{"_type":"span","marks":["strong"],"text":"Attach Visual Studio Code"},{"_type":"span","marks":[],"text":" lehetőséget. Ezután telepítsük a konténerbe is a megfelelő bővítményeket. Ezt a "},{"_type":"span","marks":["strong"],"text":"felhő gombra"},{"_type":"span","marks":[],"text":" kattinva egyszerűen megtehetjük. Ezután az "},{"_type":"span","marks":["strong"],"text":"Open Folder"},{"_type":"span","marks":[],"text":" gomb használatával nyissuk meg "},{"_type":"span","marks":["strong"],"text":"/test_app"},{"_type":"span","marks":[],"text":" mappát. A Solargraph működéséhez extra beállításokat kell elvégeznünk, a források között található "},{"_type":"span","marks":["5db735a21539"],"text":"linken"},{"_type":"span","marks":[],"text":" ez is megtekinthető,de ezt itt nem írnám le részletesen. Már csak egy lépés van, hogy elkezdhessük használni a fejlesztő környezetet. A "},{"_type":"span","marks":["strong"],"text":"launch.json"},{"_type":"span","marks":[],"text":" fájl-ban vegyük fel a "},{"_type":"span","marks":["strong"],"text":"Rails server, Listen for rdebug-ide, Rails test"},{"_type":"span","marks":[],"text":" konfigurációkat. A VSCode által javasolt előre definiált lehetőségek teljesen megfelelők. Ezek után már használhatjuk az okos navigálást, code-completion-t, valamit debugolhatjuk és tesztelhetjük az alkalmazásunkat."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Visual Studio Code használata"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az egyik legnagyobb különbség a VSCode és a RubyMine használata között, hogy a VSCode integrált terminálja autómatikusan kapcsolódik a konténerhez, igy egyéb beállítások / parancsok nélkül is elérhetjük a konténer parancssorát. Ezt használva itt is létrehozhatjuk, a fenti példához hasonlóan, a teszteléshez szükséges fájl-okat."}]},{"_type":"code","code":"rails g scaffold vs_code name:string points:integer ","language":"sh"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A fenti parancs kimenetén a létrehozott fájlok nevére kattintva gyorsan megnyithatjuk az adott fájlt."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBEdz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--da81d0c31ca2cfdeb9a9d36e295513b17a105729/HGVdaEL.png","alt":"Imgur"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ha sikeresen felvettük a szükséges konfigurációkat a launch.json fájlba, akkor a "},{"_type":"span","marks":["strong"],"text":"Run"},{"_type":"span","marks":[],"text":" tabon kiválaszthatjuk a "},{"_type":"span","marks":["strong"],"text":"Rails server"},{"_type":"span","marks":[],"text":" konfigurációt és a zöld háromszöggel elindíthatjuk a szervert."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBEZz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--53b6d15702f300d9185afb976cb69ae8ce2dfd24/Ewk3Aua.png","alt":"Imgur"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A debuggoláshoz "},{"_type":"span","marks":["strong"],"text":"Run"},{"_type":"span","marks":[],"text":" tabon, válasszuk ki a "},{"_type":"span","marks":["strong"],"text":"Listen for rdebug-ide"},{"_type":"span","marks":[],"text":" konfigurációt, majd indítsuk el. Felvehetünk breakpontokat, megnézhetjük a stack trace-t, valamint megfigyelhetjük a változók értékeit."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBFZz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--dcd0215d42b2bef992e015847ba6ea4c81933790/NcIQcFv.png","alt":"Imgur"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A teszteket a "},{"_type":"span","marks":["strong"],"text":"Run"},{"_type":"span","marks":[],"text":" tabon a "},{"_type":"span","marks":["strong"],"text":"Rails test"},{"_type":"span","marks":[],"text":" konfiguráció elindításával tudjuk futtatni. A VSCode tesztfuttatás terén kevesebb lehetőséget biztosít, mint a RubyMine. Külön konfiguráció nélkül csak egyszerre tudjuk futtatni a teszteket, egy kiválasztott tesztet önállóan nem indíthatunk el. Valamint a tesztek debug-olásaház is új konfigurációt kell hozzáadni a launch.json fájlhoz."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBEQT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--6437fa5153989fa763ee4893cba7ee6eddf34f01/c2vV8WC.png","alt":"Imgur"}}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Összefoglalás"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Amikor mérlegeljük, hogy megéri-e konténeres környezetben fejleszteni, több szempontot is érdemes figyelembe venni. Az első, hogy a nekünk szükséges környezet konfigurálása mennyire összetett / időigényes. Ha van megfelelő Dockerfile, docker-compose.yml, valamint már használtunk olyan IDE-t, ami támogatja a konténerek használatát, akkor a konfiguráció jelentősen egyszerűbb. Valamint érdemes utánanézni, hogy vannak-e olyan funkcionalitások a választott IDE-ben, amik konténeres környezetben nem használhatóak, valamint ezek mennyire szükségesek a munkánkhoz. Talán a legfontosabb tényező, hogy mennyi időt takaríthatunk meg, ha virtualizált környezetben fejlesztünk. Ha többen dolgozunk egy projekten, akkor hatékony lehet, hogy nem kell mindenkinek a telepítést és konfigurálást elvégezni, valamint egységes működésre lehet számítani minden eszköznél, tehát ilyenkor jelentős időt takaríthatunk meg."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Kész projekt"}]},{"_type":"block","markDefs":[{"_key":"329e7f2711dc","_type":"link","href":"https://github.com/SepsiLaszlo/rails_development_in_containers"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az befejezett projekt elérhető GitHub-on, az alábbi linken: "},{"_type":"span","marks":["329e7f2711dc"],"text":"https://github.com/SepsiLaszlo/rails_development_in_containers"}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Források"}]},{"_type":"block","markDefs":[{"_key":"3fa0c73bae98","_type":"link","href":"https://www.jetbrains.com/help/ruby/using-docker-compose-as-a-remote-interpreter.html"}],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"rubymine setup: "},{"_type":"span","marks":["3fa0c73bae98"],"text":"https://www.jetbrains.com/help/ruby/using-docker-compose-as-a-remote-interpreter.html"}]},{"_type":"block","markDefs":[{"_key":"edcfb513b636","_type":"link","href":"https://github.com/JetBrains/sample_rails_app"}],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"alap image: "},{"_type":"span","marks":["edcfb513b636"],"text":"https://github.com/JetBrains/sample_rails_app"}]},{"_type":"block","markDefs":[{"_key":"b39ecad0cd94","_type":"link","href":"https://jtreminio.com/blog/running-docker-containers-as-current-host-user/"}],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"konténeren belül létrehozott fájlok jogosultsága problémaleírás: "},{"_type":"span","marks":["b39ecad0cd94"],"text":"https://jtreminio.com/blog/running-docker-containers-as-current-host-user/"}]},{"_type":"block","markDefs":[{"_key":"4ccbf7400ee0","_type":"link","href":"https://www.jujens.eu/posts/en/2017/Jul/02/docker-userns-remap/"}],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"megoldás: "},{"_type":"span","marks":["4ccbf7400ee0"],"text":"https://www.jujens.eu/posts/en/2017/Jul/02/docker-userns-remap/"}]},{"_type":"block","markDefs":[{"_key":"dd636d1b0003","_type":"link","href":"https://success.docker.com/article/introduction-to-user-namespaces-in-docker-engine"}],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"docker user namespace dokumentáció: "},{"_type":"span","marks":["dd636d1b0003"],"text":"https://success.docker.com/article/introduction-to-user-namespaces-in-docker-engine"}]},{"_type":"block","markDefs":[{"_key":"f3b69e4801ed","_type":"link","href":"https://share.atelie.software/using-visual-studio-code-to-debug-a-rails-application-running-inside-a-docker-container-3416918d8cc8"}],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"vscode debug setup: "},{"_type":"span","marks":["f3b69e4801ed"],"text":"https://share.atelie.software/using-visual-studio-code-to-debug-a-rails-application-running-inside-a-docker-container-3416918d8cc8"}]},{"_type":"block","markDefs":[{"_key":"16ec495d7d62","_type":"link","href":"https://solargraph.org/guides/rails"}],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"vscode Solargraph (language server) setup: "},{"_type":"span","marks":["16ec495d7d62"],"text":"https://solargraph.org/guides/rails"}]},{"_type":"block","markDefs":[{"_key":"f4800af2c8c0","_type":"link","href":"https://youtrack.jetbrains.com/issue/RUBY-12337"}],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"tesztlefedettség vizualizáció issue: "},{"_type":"span","marks":["f4800af2c8c0"],"text":"https://youtrack.jetbrains.com/issue/RUBY-12337"}]},{"_type":"block","markDefs":[{"_key":"dcdf01788790","_type":"link","href":"https://www.jetbrains.com/ruby"}],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"Ruby Mine: "},{"_type":"span","marks":["dcdf01788790"],"text":"https://www.jetbrains.com/ruby"}]},{"_type":"block","markDefs":[{"_key":"7a3102c23e3a","_type":"link","href":"https://code.visualstudio.com/"}],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"Visual Studio Code: "},{"_type":"span","marks":["7a3102c23e3a"],"text":"https://code.visualstudio.com/"}]},{"_type":"block","markDefs":[{"_key":"626dd0bee165","_type":"link","href":"https://github.com/JetBrains/sample_rails_app"}],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"alap projekt: "},{"_type":"span","marks":["626dd0bee165"],"text":"https://github.com/JetBrains/sample_rails_app"}]},{"_type":"block","markDefs":[{"_key":"40f235810763","_type":"link","href":"https://unsplash.com/photos/HjBOmBPbi9k"}],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"featured image in the post by Ian Taylor on Unsplash: "},{"_type":"span","marks":["40f235810763"],"text":"https://unsplash.com/photos/HjBOmBPbi9k"}]}]}
{"_type":"post","_createdAt":"2021-08-22T23:55:13.000+02:00","publishedAt":"2021-08-22T23:55:13.000+02:00","title":"Mi történt velünk mostanában?","body":[{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A nyáron sem állt meg a munka a körünkben, ebből szeretnénk egy kis ízelítőt mutatni nektek..."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Új projektek"}]},{"_type":"block","markDefs":[],"style":"h3","children":[{"_type":"span","marks":[],"text":"Új blog"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Korábban a blogunk csupán egy rövid bemutatkozóval és a blogposztokkal rendelkezett. Azonban már régebb óta tervben volt egy új blog és portfolió oldal összerakása, hiszen jól jön az, ha meg tudjuk mutatni egy csinos weboldalon, mivel foglalkozunk a körnél, kik vagyunk mi. Éppen ezért foglalnak helyet ezen az új weboldalon a projektek bemutatásai, a tagok portfoliója, a tanfolyamok rendje és a részletes "},{"_type":"span","marks":["em"],"text":"Rólunk"},{"_type":"span","marks":[],"text":" oldal is."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Sikeresen lefutott a projekt a félév során, Vercel felhőszolgáltatónál került élesítésre a weboldal. A blog már készen áll arra, hogy feltölthessük tartalommal: technológiai posztokkal, Kir-Deves hírekkel és izgalmas projektbemutatókkal."}]},{"_type":"block","markDefs":[{"_key":"692d0659ab24","_type":"link","href":"/project/blog-next"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Bővebb betekintést olvashattok a projekt "},{"_type":"span","marks":["692d0659ab24"],"text":"bemutató oldalán"},{"_type":"span","marks":[],"text":"."}]},{"_type":"block","markDefs":[],"style":"h3","children":[{"_type":"span","marks":[],"text":"Warp drive"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A blog előbbi verziójánál is felmerült, hogy jól jönne egy kép hosztolási szolgáltatás a kör életében, hogy ne kelljen külső szolgáltatókra bízni a képeinket, így egy helyen lehetnének a mi kezelésünkben azok. Ezért jött létre a Warp drive először még Go alapokon, aztán most pedig újraindult Ruby on Rails alapokon az Active Storage használatával."}]},{"_type":"block","markDefs":[{"_key":"8577849e0e02","_type":"link","href":"/project/warp-next"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Bővebb betekintést olvashattok a projekt "},{"_type":"span","marks":["8577849e0e02"],"text":"bemutató oldalán"},{"_type":"span","marks":[],"text":"."}]},{"_type":"block","markDefs":[],"style":"h3","children":[{"_type":"span","marks":[],"text":"Ftsrg Next"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az ftsrg, azaz a Kritikus Rendszerek Kutatócsoport megkeresett minket azzal a céllal, hogy segítsünk nekik átdolgozni a weboldalukat, hogy kétféle nyelven is elérhetővé válhasson blog és portfolió weboldaluk, és hogy ezt a rendszert könnyedén lehessen bővíteni."}]},{"_type":"block","markDefs":[{"_key":"eede3a0158ae","_type":"link","href":"/project/ftsrg-next"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ehhez a Gatsby és React keretrendszereket hívtuk segítségül, és már a kódbázis átadására készülünk. Bővebb betekintést olvashattok a projekt "},{"_type":"span","marks":["eede3a0158ae"],"text":"bemutató oldalán"},{"_type":"span","marks":[],"text":"."}]},{"_type":"block","markDefs":[],"style":"h3","children":[{"_type":"span","marks":[],"text":"AirsoftSCH"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A Schönherz Airsoft Team bízott meg minket azzal, hogy egy olyan weboldalt készítsünk számukra, amellyel könnyedén tudnak játékokat szervezni és híreket közölni, játékjelentkezéseket adminisztrálni és felszereléseket kölcsönadni. Ezzel a projekttel februárban indultunk el, és hamarosan átadásra készülünk."}]},{"_type":"block","markDefs":[{"_key":"a9388b89d638","_type":"link","href":"/project/airsoft"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Bővebb betekintést olvashattok a projekt "},{"_type":"span","marks":["a9388b89d638"],"text":"bemutató oldalán"},{"_type":"span","marks":[],"text":"."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Új megjelenés"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A tavaszi félév elején elkezdtük egyeztetni, hogy tudnánk feldobni a Kir-Dev PR-ját. Arra jutottunk, érdemes volna egy új pólódesignt kialakíttatni, és abban villogni legközelebb GólyaKörTén és egyéb standolásokon."}]},{"_type":"block","markDefs":[{"_key":"bcdd863f8fba","_type":"link","href":"schdesign.hu"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A design elkészítésére az "},{"_type":"span","marks":["bcdd863f8fba"],"text":"schdesign"},{"_type":"span","marks":[],"text":"-t kerestük meg, és a félév végére össze is jött a végső design. Mostanában indult el a rendelés, hamarosan a nyomtatás is el tud kezdődni. Lentebb az általuk kialakított látványtervet láthatjátok."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBDZz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--ddf987fccff2f62b8f00b24e1c52d7b743489f98/kirdev_mockup.png","alt":"poloterv"}}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Sikeres bemutatkozó"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Augusztusban a VIK Gólyatáborában nagy sikerrel mutatkoztunk be a gólyáknak. Bemutattuk, mivel foglalkozunk, a leendő elsőévesek élvezték a kiállítás játékait, a projektek bemutatóit, roppant jó kérdéseik voltak, sokukkal tudtunk kellemes szakmai társalgást folytatni."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Örülünk neki, hogy ilyen nagyszerű motivációval készülnek a gólyák nekifutni az egyetemi életnek. Reméljük, a következő tanfolyamidőszakban sokukkal találkozunk majd!"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBDUT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--278668d7c14e082c2921e599742295eb0292f74f/20210814_145833_vince.jpg","alt":"standolas"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Sok projekt indult, zárult és futott tovább ebben a félévben is sikeresen, lelkes újoncok is bekapcsolódtak a kör életébe. A Simonyi Nyári Táborban készült képünkkel búcsúzom Tőletek ebben a posztban:"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBDQT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--219692dc85b16c4d08e17aef4d357312b8c14aa8/20210718_095824_talli.jpg","alt":"snyt"}}]},{"_type":"block","markDefs":[{"_key":"098199e897bc","_type":"link","href":"https://spot.sch.bme.hu/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Köszönet a fotókért a "},{"_type":"span","marks":["098199e897bc"],"text":"SPOT"},{"_type":"span","marks":[],"text":" csapatának."}]}]}
{"_type":"post","_createdAt":"2021-11-25T18:03:48.000+01:00","publishedAt":"2021-11-25T18:03:48.000+01:00","title":"Szakmai Hét 2021","body":[{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Nagyon vártuk a Simonyi Szakmai Hetet. Rengeteg izgalmas program és előadás volt a menetrendben. Az előadások közül több is kapcsolódott a kör profiljához, a webfejlesztéshez."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBSZz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--d967304f2860d66d4eb052ad4ac2fb7d350c8ddf/szakmai-het-cover.jpg","alt":"szakmai-het"}}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Szakmai Est"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A hét első napja a Szakmai Est volt, ahol a Simonyi aktív tagjai mutatták be, hogy mivel foglalkoztak az utóbbi időben. Több szakkollégiumi körből is jöttek előadók. Mi is készültünk előadással, aminek a címe PéK: Webfejlesztés hosszútávon lett. Itt meséltünk egy kicsit a projekt történelméről valamint arról, hogy milyen szakmai kihívásokkal kell megbirkóznia a fejlesztőknek, ha több mint 20 éven át szeretnének egy webes szolgáltatást biztosítani. Az előadást a kör PéK Adminja, Sepsi László tartotta meg."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBSdz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--8bdd736197e9e504ed6acac49303e6856472c548/minikonf-pek-eloadas.jpg","alt":"szakmai-est-pek"}}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Minikonferencia"}]},{"_type":"block","markDefs":[{"_key":"d5e144eafc6d","_type":"link","href":"https://uxstudioteam.com/"},{"_key":"0a2d14e81464","_type":"link","href":"https://uxfol.io/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A hét további részében is feltűntek ismerős arcok az előadók között. A Minikonferencia második napján Vass Bence, körünk egyik tagja, mutatta be, hogy milyen technológiákkal dolgoznak a "},{"_type":"span","marks":["d5e144eafc6d"],"text":"UX studio"},{"_type":"span","marks":[],"text":"-nál, a "},{"_type":"span","marks":["0a2d14e81464"],"text":"uxfolio"},{"_type":"span","marks":[],"text":" fejlesztése során."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBTQT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--8d8d74ee3b22b71c610951204f9bf75495bfbb12/minikonf-masodik-nap.jpg","alt":"minikonferencia-masodik-nap"}}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Szülinap"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az elsők között érkeztünk meg a Szülinap helyszínére, így még volt asztal, ahova mindannyian le tudtunk ülni. Az utóbbi hetek nagyon mozgalmasan teltek mindenki számára, ezért kifejezetten jó volt kicsit összeülni és sztorizgatni. A sajtófalat is meglátogattuk, néhány kép erejéig. A Szülinap további része is nagyon jól telt, a táncolás és a bulizás mellett néhány sörpöng mérkőzés lejátszására is volt időnk. Sajnos csak olyan képet találtunk, ahol a Kir-Dev-es csapat nem teljesen látszik, de az asztal másik végén tényleg mi vagyunk. :wink:"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBSQT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--8cec0c76ed80e7d138a6236a13ef1eccd7ba724a/kir-dev-at-simonyi-szulinap-table.jpg","alt":"beszelgetes"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBRZz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--8c0201879b26e0649ca7ca7c6728c8a9cea28529/kir-dev-simonyi-szulinap.jpg","alt":"foto-sajtofalnal"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBSUT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--55c184c47101981a6b4c414370fea574f2a2d24e/kir-dev-at-simonyi-szulinap-pong.jpg.jpg","alt":"pong"}}]},{"_type":"block","markDefs":[{"_key":"10c4763bd157","_type":"link","href":"https://spot.sch.bme.hu/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Köszönjük a képeket a "},{"_type":"span","marks":["10c4763bd157"],"text":"SPOT fotókörnek"},{"_type":"span","marks":[],"text":"!"}]}]}
{"_type":"post","_createdAt":"2022-02-02T21:31:32.000+01:00","publishedAt":"2022-02-02T21:31:32.000+01:00","title":"Ruby on Rails telepítési útmutató","body":[{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Tartalomjegyzék"}]},{"_type":"code","code":"# There comes the toc ","language":"toc"},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Bevezetés"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ez a kis útmutató legfőképpen a tavaszi tanfolyamon résztvevőknek szól, de bárki más is olvassa nyugodt szívvel."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A Ruby on Rails egy nagyon népszerű webes keretrendszer, amivel érdemes megismerkednie akár annak is, aki nem feltétlen a webes világban akar elhelyezkedni. Sajnos a legelső akadály sokszor elég nagy szokott lenni, ami nem más mint a keretrendszer beüzemelése. Az olyan runtimeokkal ellentétben, mint például a NodeJS, ahol az LTS verzió feltepítéséve után már neki is lehet állni, itt elég sok buktatóba bele lehet futni, főleg ha valaki Windows rendszeren szeretne fejleszteni. Mivel a tanfolyamunk szerves része, hogy közös kódolások alkalmával mindenki kipróbálja a fejlesztés élményét, ezért ebben a kis cikkben leírom, hogyan lehet megugrani ezt az első akadályt. A telepítés menetét megmutatom "},{"_type":"span","marks":["strong"],"text":"Windows 10"},{"_type":"span","marks":[],"text":" és "},{"_type":"span","marks":["strong"],"text":"Ubuntu 20.04"},{"_type":"span","marks":[],"text":" operációs rendszereken is."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Ruby telepítése"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Első lépésként a Ruby-t kell felraknunk, ami Windows és Linux rendszereken kicsit máshogy néz ki."}]},{"_type":"block","markDefs":[],"style":"h3","children":[{"_type":"span","marks":[],"text":"Windows"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Bár van néhány dolog, ami Windows rendszereken nem igen, vagy csak nehézkesen működik, amikor Ruby-val dolgozunk, a tanfolyam alkalmakon csak olyan részeket fogunk érinteni, amiknek mindenképpen működniük kell."}]},{"_type":"block","markDefs":[],"style":"h4","children":[{"_type":"span","marks":[],"text":"Szükséges szoftverek"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A Rails helyes működéséhez szükséged lesz néhány dologra."}]},{"_type":"block","markDefs":[{"_key":"c45f6fe87eb1","_type":"link","href":"https://git-scm.com/download/win"}],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"git: "},{"_type":"span","marks":["c45f6fe87eb1"],"text":"git-scm.com"}]},{"_type":"block","markDefs":[{"_key":"d311a49e0740","_type":"link","href":"https://nodejs.org/en/"}],"style":"normal","level":1,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"nodeJs (LTS verzió megfelelő): "},{"_type":"span","marks":["d311a49e0740"],"text":"nodejs.org"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ezeknek a telepítésénél maradhatunk az alapértelmezett beállításoknál."}]},{"_type":"block","markDefs":[],"style":"h4","children":[{"_type":"span","marks":[],"text":"Ruby telepítése Windowsra"}]},{"_type":"block","markDefs":[{"_key":"b03d2ba9c93f","_type":"link","href":"https://rubyinstaller.org/downloads/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A telepítőt a "},{"_type":"span","marks":["b03d2ba9c93f"],"text":"rubyinstaller.org"},{"_type":"span","marks":[],"text":" oldalról tudjuk letölteni. A ("},{"_type":"span","marks":["em"],"text":"2022 tavaszi"},{"_type":"span","marks":[],"text":") tanfolyamhoz a "},{"_type":"span","marks":["strong"],"text":"Ruby+Devkit3.0.3-(x64)"},{"_type":"span","marks":[],"text":" verziót töltsük le, majd futtassuk."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A telepítő varázslóban mindent hagyhatunk az alapértelmezett értéken. "},{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBidz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--2be162588d0e615761c1e5b77a2d2b676dcd05ae/Screenshot%202022-02-02%20195239.png","alt":"installler"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A telepítés után előjön az MSYS2 és MINGW telepítője, amit szintén hagyhatunk alapértelmezett beállításokkal -> "},{"_type":"span","marks":["em"],"text":"nyomjunk entert"},{"_type":"span","marks":[],"text":". "},{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBjQT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--4c5b0d303b5c72fa47c4031c01441630137e3f81/Screenshot%202022-02-02%20195550.png","alt":"MSYS2 & MINGW"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Nem kell megijedni, ha warningok és látszólagos hibák jönnek elő, ha a végén van egy zöld success felirat. "},{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBjUT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--80fec14e803267d5be072f2c62dba92f587fdc04/Screenshot%202022-02-02%20195759.png","alt":"install done"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ha minden jól megy, a "},{"_type":"span","marks":["code"],"text":"ruby -v"},{"_type":"span","marks":[],"text":" parancs kiadása után valami ilyesminek kell megjelenni:"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBjZz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--2a6cb235744dd725d670a6129180682c624310ad/Screenshot%202022-02-02%20200617.png","alt":"ruby version"}}]},{"_type":"block","markDefs":[],"style":"h4","children":[{"_type":"span","marks":[],"text":"Tipikus hiba: invalid byte sequence in UTF-8"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ha a Windows-on használt felhasználó nevünkben space vagy ékezetes betűk szerepelnek, akkor van esély, hogy a Rails alkalmazás létrehozásakor, elindításakor az alábbi hibaüzenetet kapjuk:"}]},{"_type":"code","code":"C:/Ruby30-x64/lib/ruby/3.0.0/pathname.rb:50:in `match?': invalid byte sequence in UTF-8 (ArgumentError) ","language":"bash"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ezt többféle képpen megoldhatjuk. A legegyszerűbb, ha létrehozunk egy új felhasználót, amit a Rails fejlesztéshez fogunk használni. Ezt a "},{"_type":"span","marks":["strong"],"text":"Gépház/Fiókok/Családtagok és más felhasználók/Más új felhasználó felvétele"},{"_type":"span","marks":[],"text":" menüpont alatt tudjuk megtenni. Adjuk egy olyan nevet, amiben csak az "},{"_type":"span","marks":["strong"],"text":"angol ábécé kisbetűi"},{"_type":"span","marks":[],"text":" találhatóak meg. Ezután még elérhetővé kell tennünk az új a felhasználónak is a a Ruby elérési útvonalát. Ehhez nyissuk meg a "},{"_type":"span","marks":["strong"],"text":"Gépház/Rendszer/Névjegy/Speciális rendszerbeállítások/ Környezeti változók"},{"_type":"span","marks":[],"text":" ablakot. Itt válasszuk ki az eredeti felhasználónk alatt a "},{"_type":"span","marks":["strong"],"text":"PATH változót és kattintsunk a Szerkesztés"},{"_type":"span","marks":[],"text":" gombra. Itt másoljuk ki a Ruby binárishoz tartozó útvonalat. Valami ilyesmi lesz:"}]},{"_type":"code","code":"C:\\Ruby30-x64\\bin ","language":"bash"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ezután nyissuk meg "},{"_type":"span","marks":["strong"],"text":"Rendszerváltozók alatt szerkesztésre a Path"},{"_type":"span","marks":[],"text":" változót. Itt az új gomb megnyomásával másoljuk be a Ruby elérési útvonalát. Ha végeztünk mentsük el a módosításokat. Lépjünk át az új felhasználó fiókba és már elkezdhetjük használni a Ruby környezetet."}]},{"_type":"block","markDefs":[],"style":"h4","children":[{"_type":"span","marks":[],"text":"Megjegyzés a WSL-ről"}]},{"_type":"block","markDefs":[{"_key":"933e966b4235","_type":"link","href":"https://docs.microsoft.com/en-us/windows/wsl/"},{"_key":"5dda0be8829e","_type":"link","href":"https://ubuntu.com/tutorials/how-to-run-ubuntu-desktop-on-a-virtual-machine-using-virtualbox#1-overview"},{"_key":"1d6761350cf3","_type":"link","href":"https://itsfoss.com/install-ubuntu-1404-dual-boot-mode-windows-8-81-uefi/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az interneten sok útmutatót találhat az ember, ahol a "},{"_type":"span","marks":["933e966b4235"],"text":"WSL"},{"_type":"span","marks":[],"text":" ("},{"_type":"span","marks":["em"],"text":"Windows Subsystem for Linux"},{"_type":"span","marks":[],"text":") segítségével telepítik fel a keretrendszert. Bár működőképes, de sok olyan mellékhatása van, amit ezen cikk keretében nem tudok mind felsorolni. Ezért aki komolyabban szeretne foglalkozni a Ruby fejlesztéssel, annak ajánlanék inkább egy "},{"_type":"span","marks":["5dda0be8829e"],"text":"Linux virtuális gépet"},{"_type":"span","marks":[],"text":", vagy második operációs rendszerként ("},{"_type":"span","marks":["1d6761350cf3"],"text":"Dual BOOT"},{"_type":"span","marks":[],"text":") egy Linux disztribúciót felrakni."}]},{"_type":"block","markDefs":[],"style":"h3","children":[{"_type":"span","marks":[],"text":"Ubuntu"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Aki rendszeresen használ Linux alapú rendszereket, annak biztos ismerős lesz a feltelepítés módja, de azok kedvéért, akik esetleg most ismerkednek vele, megmutatom, hogy egy frissen telepített rendszerre hogyan érdemes felvarázsolni a Railst."}]},{"_type":"block","markDefs":[],"style":"h4","children":[{"_type":"span","marks":[],"text":"Szükséges szoftverek"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":["strong"],"text":"Figyelem! A Linuxon való telepítéshez sudo jogosultsággal kell rendelkezned."},{"_type":"span","marks":[],"text":" A telepítéshez (és amúgy a szoftverfejlesztéshez általában) szükséged lesz git kliensre. És a Ruby futtatókörnyezet lefordításához (amit majd automatikusan a verziókezelő tesz meg) néhány fejlesztői könyvtárra. Ezeket a következő parancsok kiadásával tudod telepíteni."}]},{"_type":"code","code":"sudo apt update sudo apt install -y libssl-dev zlib1g-dev sqlite3 libsqlite3-dev git-all ","language":"bash"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ezen felül szükséged lesz még NodeJS-re és Yarn-ra. A következő parancsokkal lehet feltelepíteni őket:"}]},{"_type":"code","code":"curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - echo \"deb https://dl.yarnpkg.com/debian/ stable main\" | sudo tee /etc/apt/sources.list.d/yarn.list sudo apt update sudo apt install -y yarn ","language":"bash"},{"_type":"block","markDefs":[],"style":"h4","children":[{"_type":"span","marks":[],"text":"Rbenv telepítése"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Linux rendszereken a normális telepítési mód helyett érdemes inkább egy verziókezelőt telepíteni, ami minden egyes projekthez a szükséges verziójú Ruby-t fogja betölteni, mindezt ✨ "},{"_type":"span","marks":["em"],"text":"automágikusan"},{"_type":"span","marks":[],"text":" ✨ a háttérben."}]},{"_type":"block","markDefs":[{"_key":"755a03e9f2f3","_type":"link","href":"https://github.com/rbenv/rbenv"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A szoftver telepítése sok féle képpen megtörténhet, érdemes elolvasni az rbenv "},{"_type":"span","marks":["755a03e9f2f3"],"text":"github oldalát"},{"_type":"span","marks":[],"text":", de a készítők szolgáltatnak egy scriptet, ami megoldja számunkra a telepítés összes lépését. Ezt a következő parancsal futtathatjuk."}]},{"_type":"code","code":"curl -fsSL https://github.com/rbenv/rbenv-installer/raw/HEAD/bin/rbenv-installer | bash ","language":"bash"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":["em"],"text":"Megjegyzés: Nem egészséges ismeretlen internetről letöltött scripteket csak úgy futtatni, így mindig érdemes átnézni pontosan mit csinál, mielőtt elindítod."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Azért, hogy minden esetben működjön a program még manuálisan be kell állítani pár dolgot. Ahogy azt a telepítő végén írja is, hozzá kell adnunk a PATH változóhoz az rbenv helyét. Futtassuk a következő parancsokat:"}]},{"_type":"code","code":"echo 'export PATH=\"$HOME/.rbenv/bin:$PATH\"' >> ~/.bashrc echo 'eval \"$(rbenv init - bash)\"' >> ~/.bashrc ","language":"bash"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Zárjuk be, majd nyissuk meg újra a terminált, hogy a módosításaink érvényességet nyerjenek. Hogy minden rendben van, azt ellenőrizhetjük a következő script futtatásával:"}]},{"_type":"code","code":"curl -fsSL https://github.com/rbenv/rbenv-installer/raw/main/bin/rbenv-doctor | bash ","language":"bash"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Valahogy így kell kinéznie:"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBkQT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--f49ccd11ac9ef79d6330804d49c1d7122652af87/Screenshot%202022-02-03%20133723.png","alt":"succesfull install"}}]},{"_type":"block","markDefs":[],"style":"h4","children":[{"_type":"span","marks":[],"text":"Megfelelő Ruby verzió telepítése"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Most már, hogy van egy verziókezelőnk, már csak meg kell adni, hogy mi legyen a verzió amivel dolgozni akarunk. Adjuk ki a következő parancsot:"}]},{"_type":"code","code":"rbenv install 3.0.3 && rbenv global 3.0.3 ","language":"bash"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ez letölti, majd feltelepíti a kívánt verziót, majd beállítja globálisan, hogy ez legyen használva. Ha minden jól megy, a "},{"_type":"span","marks":["code"],"text":"ruby -v"},{"_type":"span","marks":[],"text":" parancs kiadása után a kiválasztott Ruby verziónak kell megjelennie:"}]},{"_type":"code","code":"ruby 3.0.3p157 (2021-11-24 revision 3fb7d2cadc) [x86_64-linux] ","language":"bash"},{"_type":"block","markDefs":[],"style":"h3","children":[{"_type":"span","marks":[],"text":"macOS"}]},{"_type":"block","markDefs":[{"_key":"5031302ae9d2","_type":"link","href":"https://gorails.com/setup/osx/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Amennyiben macOS-re szeretnéd telepíteni a Railst, ajánlom ezt a "},{"_type":"span","marks":["5031302ae9d2"],"text":"weblapot"},{"_type":"span","marks":[],"text":" olvasgatásra."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Rails telepítése"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ezután a Rails keretrendszer telepítése pofon egyszerű, csak ki kell adni parancssorban a megfelelő parancsokat:"}]},{"_type":"code","code":"gem install bundler gem install rails ","language":"bash"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ez jónéhány csomagot, úgynevezet "},{"_type":"span","marks":["em"],"text":"gem"},{"_type":"span","marks":[],"text":"-et fog feltelepíteni, és ez eltarthat némi időbe."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Hello World applikáció"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Most eljött az ideje, hogy kipróbáljuk, hogy minden működik-e. Parancssorban / terminálban navigálj egy olyan mappába, ahol a projekteket tárolni szeretnéd, majd add ki a következő parancsot:"}]},{"_type":"code","code":"rails new hello_world ","language":"bash"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Legelső alkalommal ez is eltarthat sokáig, mert szintén fog egy két gem-et installálni."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Miután lefutott a parancs, navigálj be az elkészített mappába"}]},{"_type":"code","code":"cd hello_world ","language":"bash"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"és add ki a következő parancsokat."}]},{"_type":"code","code":"bundle install rails db:create rails s ","language":"powershell"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A konzolon valami hasonlónak kell megjelenni"}]},{"_type":"code","code":"=> Booting Puma => Rails 7.0.1 application starting in development => Run `bin/rails server --help` for more startup options *** SIGUSR2 not implemented, signal based restart unavailable! *** SIGUSR1 not implemented, signal based restart unavailable! *** SIGHUP not implemented, signal based logs reopening unavailable! Puma starting in single mode... * Puma version: 5.6.1 (ruby 3.0.3-p157) (\"Birdie's Version\") * Min threads: 5 * Max threads: 5 * Environment: development * PID: 12360 * Listening on http://[::1]:3000 * Listening on http://127.0.0.1:3000 Use Ctrl-C to stop ","language":"powershell"},{"_type":"block","markDefs":[{"_key":"82973f33d9e2","_type":"link","href":"http://127.0.0.1:3000"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"és a "},{"_type":"span","marks":["82973f33d9e2"],"text":"http://127.0.0.1:3000"},{"_type":"span","marks":[],"text":" címre ellátogatva a következőt kell látni:"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBjdz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--b03cce34ab2bf5bb5f01a6258a2c77bce8436955/Screenshot%202022-02-02%20205507.png","alt":"welcome screen"}}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Végszó"}]},{"_type":"block","markDefs":[{"_key":"442d78ae8dd3","_type":"link","href":"https://www.redhat.com/en/topics/middleware/what-is-ide"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Miután fel van telepítve a keretrendszer, már mehet is a fejlesztés. A következő cikkemben bemutatok néhány fejlesztést segítő programot, és két "},{"_type":"span","marks":["442d78ae8dd3"],"text":"IDE"},{"_type":"span","marks":[],"text":"-t, amivel még kényelmesebbé teheted a Ruby on Rails élményt."}]}]}
{"_type":"post","_createdAt":"2022-05-19T21:02:53.000+02:00","publishedAt":"2022-05-19T21:02:53.000+02:00","title":"Kir-Dev 20+!","body":[{"_type":"code","code":"# There comes the toc ","language":"toc"},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Megrendezésre kerül a Kir-Dev 20+!"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBbElCIiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--37cb6341ad70d92d1a0dc938363cd278911931fa/kir-dev3.jpg","alt":"kir-dev-at-konf"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A Kir-Dev 2021-ben elérte működésének 20-adik évfordulóját. Ennek a kiemelkedő mérföldkőnek a megünneplését nem szeretnénk tovább húzni. Így idén nyáron, a Kir-Dev 20+ rendezvény formájában szeretnénk megünnepelni ezt, a kör valamennyi tagjával és öregtagjával együtt!"}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Jelentkezés"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBbEVCIiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--9dd76b2443b2dc393898c58c6550fb7c29c857ea/kir-dev2.jpg","alt":"kir-dev-join-us"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A rendezvény a Schönherz Kollégiumban kerül megrendezésre, 2022-es nyár folyamán. A pontos időpontot szeretnék úgy megválasztani, hogy minél több öregtagunk el tudjon jönni. Ha körünk öregtagja vagy, akkor az alábbi form-on tudod jelezni, hogy mely időpontok alkalmasak számodra."}]},{"_type":"block","markDefs":[{"_key":"5dae888bf65e","_type":"link","href":"https://forms.gle/XjYcb3UKZ6RzQkR86"}],"style":"normal","children":[{"_type":"span","marks":["5dae888bf65e"],"text":"https://forms.gle/XjYcb3UKZ6RzQkR86"}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Programok"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/img/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBbEFCIiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--0fe8ebf5b16ee4799510b8c6b2a7e1c4442ae80c/kir-dev1.jpg","alt":"kir-dev-program"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A rendezvényre több programmal is készülünk a résztvevők számára:"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Megnyitó"}]},{"_type":"block","markDefs":[],"style":"normal","level":2,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"Résztvevők köszöntése, valamint egy tömör összefoglaló a Kir-Dev utóbbi néhány évéről, aktuális projektjeiről."}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Tagok bemutatkozása"}]},{"_type":"block","markDefs":[],"style":"normal","level":2,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"A program ezen a részén felkérjük a megjelent tagokat és öregtagokat, hogy mutatkozzanak be és néhány mondatban foglalják össze, körön belüli és körön túli tevékenységeiket."}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Vacsora - 🍲"}]},{"_type":"block","markDefs":[],"style":"normal","level":1,"listItem":"bullet","children":[]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Kötetlen program"}]},{"_type":"block","markDefs":[],"style":"normal","level":2,"listItem":"bullet","children":[{"_type":"span","marks":[],"text":"Lesz lehetőség folytatni a beszélgetést néhány ital mellett. Valamint lesz lehetőség részt venni egy mini sörpong bajnokságon is. Társasjátékokkal is játszhatnak a klasszikus játékok kedvelői."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Várunk!"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":["strong"],"text":"Köszönjük, hogy végigolvastad! Reméljük, hogy a rendezvényen találkozunk!"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Bármilyen kérdéssel keressetek minket bizalommal, a körös levelezőlistákon, vagy a Slack csoportban!"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Üdv: A Kir-Dev Csapata"}]}]}
{"_type":"post","_createdAt":"2022-09-17T18:18:55.000+02:00","publishedAt":"2022-09-17T18:18:55.000+02:00","title":"Kir-Dev Nyár 2022","body":[{"_type":"code","code":"# There comes the toc ","language":"toc"},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Kir-Dev Nyár 2022"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A tanév igazán mozgalmasan telt a Kir-Dev számára, emiatt már nagyon vártuk a nyarat, hogy legyen időnk egy kis kikapcsolódásra."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"SNYT"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az első program, amin részt vettünk a nyár folyamán a körrel, a Simonyi Nyári Tábor volt. Ennek keretein belül Patcára látogattunk el, ahol a Szakkollégium többi körével együtt, feledhetetlen három napot töltöttünk el."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Első lépésként, közösen meghódítottuk a Katica Tanyát. A tanyán kipróbáltuk a lábbal hajtós gokartokat, csúszdákat, labirintusokat és az ugrálóvárat is. De a kedvenc játékunk a komp volt, amit sikerült két alkalommal majdnem elsüllyesztenünk."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/kir-dev-boat-cropped","alt":"kir-dev-on-ship"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A kör a szórakozás mellett, itt sem volt tétlen. Az SNYT-re is készítettünk weboldalt, amivel QR kódokat és ötletes feladatokat tudtak beadni a táborozók."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Emellett a Kir-Dev volt az a kör a táborban, aki a tagjaik arányához képest, a legnagyobb létszámban volt jelen. Ezért járó díjat büszkén vettük át a szervezőktől."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/20220709_175453_spot","alt":"snyt-group-pic"}}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Kir-Dev Tábor"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A nyár a Kir-Dev Táborral folytatódott, itt Szokolya festői tájai közé vonultunk vissza. Az első este a szállás birtokbavételével és társasozással kezdődött. A buli sajnos elmaradt, mert a gazdasági felelősünk otthon hagyta JBL-t. Ehelyett egy izgalmas éjszakai turán vettünk részt, ahol jobban megismertük a helyi állatvilágot. "},{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/img_0391","alt":"szokolya-sunset"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Fontos a kör számára, hogy aktív kikapcsolódásban is részt vehessenek a tagok, ezért a tábor második napján kenuzni mentünk. Nagymarostól leeveztünk első körben Verőcére, ahol megvizsgáltuk a helyi vendéglátóipari egységeket. Majd folytattuk utunkat Vácig, ahol a főteret jártuk körbe. Ezután visszatértünk a táborhelyre, ahol csaptunk egy jó esti sütögetést. "},{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/img_0389","alt":"kir-dev-on-shore"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A hazaindulás előtt beírtuk magunkat a vendégkönyvbe, hogy az utókor számára is megmaradjon valami. "},{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/img_0399","alt":"guest-book"}}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Kir-Dev 20+"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A nyáron megtartásra került a régóta várt Kir-Dev 20+ redezvény. Itt lehetőség nyílt arra, hogy a kör jelenlegi aktív tagjai, találkozzanak a kör öregtagjaival és együtt megünnepeljék a kör késői huszadik születésnapját. "},{"_type":"img","asset":{"src":"https://spot.sch.bme.hu/photos/2022/20220828_kir_dev/2048/20220828_204609_ppeti.jpg","alt":"kir-dev-20-group-pic"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A rendezvényt a körvezető nyitotta meg egy izgalmas prezentációval. Beni ismertette a kör jelenlegi helyzetét, bemutatta az aktuális projekteket és elért célokat. A körös áttekintés után időrendi sorrendben, a legpatinásabb öregtagoktól kezdve, mindenki megosztotta a legkedvesebb körös élményeit és történeteit. Ezután a körtagok minőségi whiskyvel koccintottak a kör huszadik születésnapjára. "},{"_type":"img","asset":{"src":"https://spot.sch.bme.hu/photos/2022/20220828_kir_dev/2048/20220828_210005_ppeti.jpg","alt":"kir-dev-20-cheers"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az este további részében helyet kapott egy vacsora és italozás is. Az est maradék idejében egy eposzi történetekbe illő sörpong bajnokságra is sor került, ahol különböző generációk képviselői csaptak össze, hogy bizonyítsák rátermettségüket. "},{"_type":"img","asset":{"src":"https://spot.sch.bme.hu/photos/2022/20220828_kir_dev/2048/20220828_210923_ppeti.jpg","alt":"kir-dev-20-pong"}}]},{"_type":"block","markDefs":[{"_key":"d9baa8d81b99","_type":"link","href":"https://spot.sch.bme.hu/photo/2022/20220828_kir_dev/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az eseményről készült összes képet itt találjátok meg: "},{"_type":"span","marks":["d9baa8d81b99"],"text":"https://spot.sch.bme.hu/photo/2022/20220828_kir_dev/"}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Végszó"}]},{"_type":"block","markDefs":[{"_key":"292b2af0617d","_type":"link","href":"https://spot.sch.bme.hu/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Köszönjük, hogy végigolvastad a posztot! Reméljük, izgalmas volt számodra! Emellett szeretnénk megköszönni a "},{"_type":"span","marks":["292b2af0617d"],"text":"SPOT Fotókörnek"},{"_type":"span","marks":[],"text":" is, hogy remek képeket készítettek az eseményekről!"}]}]}
{"_type":"post","_createdAt":"2022-09-30T16:01:28.000+02:00","publishedAt":"2022-09-30T16:01:28.000+02:00","title":"Szintfestés","body":[{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Mi az a szintfestés?"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A szintfestés a Schönherz közéletének egy nagyon fontos része: ez egy olyan alkalom, ahol a kollégium lakói mindannyian festhetnek a szintjük falára logókat vagy bármilyen vicces, funky ábrákat. (Bizonyos határokon belül.)"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ezek az alkotások generációkon át díszítik a Schönherz belsejét, amíg újra nem festik az egész szintet, helyet adva újabb lehetőségeknek."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"2022 őszi szintfestés"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"../images/posts/kirdev_szintfestes.png","alt":"szintfestes-group-pic"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Idén a szintfestés alól a Schönherz 13. emelete, a Simonyi Károly Szakkollégium szintje se maradhatott ki. Még egészen sok üres hely volt a falakon, így már igazán itt volt az ideje, hogy színesebbé tegyük a folyosókat."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A Kir-Dev csapata is részt vett ebben. Még a szintfestés napja előtt megterveztünk és felrajzoltuk a kör logójának körvonalát, majd a várva várt napon egy kellemes délutánt töltöttek tagjaink a festegetéssel. Ugyan nem a festés az erősségünk, mégis sikerült egy csodálatos logót alkotnunk, ráadásul jövőre is vannak már elképzeléseink, hogy a logó köré miket szeretnénk festeni. Eddig még soha nem volt Kir-Dev logó festve a szakkoli szintjén, úgyhogy már nagyon itt volt az ideje."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/kirdev-logo-phases","alt":"kirdev-logo-phases"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Viszont a tagjaink tevékenysége a logónk befejeztével se maradt abba, ugyanis egy másik logó is nagyon hiányzott már a szintről, mégpedig a szakkollégium logója. A Simonyi sok köréből érkeztek lelkes emberek, és közös erővel megalkottuk a gyönyörű Simonyi logót is. Ha valaki a 13. szintre érkezik, most már egyből tudni fogja, hogy jó helyen jár."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/festett-simonyi-logo","alt":"festett-simonyi-logo"}}]}]}
{"_type":"post","_createdAt":"2022-11-08T10:26:14.000+01:00","publishedAt":"2022-11-08T10:26:14.000+01:00","title":"Félévnyitó és Felvételi Vacsora - 2022","body":[{"_type":"code","code":"# There comes the toc ","language":"toc"},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Félévnyitó és Felvételi Vacsora - 2022"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/f-f-2021-cover","alt":"f&f-2021-cover"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ez a félév sem indulhatott el egy remek simonyis Félévnyitó és Felvételi Vacsora nélkül. A nyár után már nagyon vártuk, hogy találkozhassunk a többi szakkollégiumi kör tagjaival. A rendezvény elején elfoglaltuk a szokásos asztalunkat, hogy legyen egy stabil kiindulópontja az estének."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/f-f-2021-table","alt":"f&f-2021-table"}}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Új tagokkal bővültünk"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az est középpontjában természetesen a felvételizők álltak. Idén 3 felvételizőnk vágott bele a felvételi folyamatba. Nagyon meggyőző teljesítményeket nyújtottak ebben az évben a felvételizőink, mindannyian sikeresen vették az akadályokat. A körvezetőnk büszkén adta át nekik a körös és szakkollégiumi tagságot jelképező oklevelet."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/f-f-2021-okelvel","alt":"f&f-2021-table"}}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Főztünk"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A mostani F&F kifejezetten izgalmas volt a körünk számára, hiszen mi kaptuk a lehetőséget, hogy főzzünk a résztvevők számára. Az egyik specialitásunkat készítettük el, lecsót virslipolippal. Az étel áttörő sikert aratott."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/c77f0dac-e028-48d9-803c-209634d5205e_1_105_c","alt":"f&f-2021-table"}}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Együtt a csapat!"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A rendezvény nagyon pörgős volt, de egy pillanatra azért megálltunk közben, hogy készülhessen rólunk egy szép csoportkép."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/f-f-2021-kir-dev-group","alt":"f&f-2021-group"}}]}]}
{"_type":"post","_createdAt":"2022-12-03T19:43:05.000+01:00","publishedAt":"2022-12-03T19:43:05.000+01:00","title":"Simonyi Szakmai Hét 2022","body":[{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Simonyi Szakmai Hét"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/20221107_212238_vilmazsuzsi","alt":"kep"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A Szakmai Hét lényege, hogy előadások és közös beszélgetések keretein belül osszunk meg hasznos dolgokat a szakkolisokkal. 2 vendégelőadónk is volt, a Brahman Technologies-tól és a Shapr3D-től."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/20221109_211755_mszrsblnt","alt":"kep"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Idén a körvezetőnk, Berente Bálint is előadott. Témája a körünk működéséről szólt, ugyanis az évben többször is sikerült olyan odaadással és módszerekkel dolgoznunk, mint ahogy azt a rendes cégeknél is csinálják."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/20221107_235117_vilmazsuzsi","alt":"kep"}}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"XIX. Simonyi Szülinap"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/20221111_202635_ppeti","alt":"simony-szulinap"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A Szakmai Hét zárásául idén is megrendezésre került a Simonyi Szülinap. Körünk számos tagja is megjelent és egy felejthetetlen estét töltöttünk el a szakkoli többi tagjával együtt."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/20221111_220636_nmsd","alt":"kirdev-group-pic"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A rendezvényt pedig egy nagy zenés-táncos bulival zártuk."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/20221112_014049_endre","alt":"simonyi-szulinap-party"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Boldog szülinapot Simonyi Szakkoli!"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/20221111_234311_mszrsblnt","alt":"cake"}}]}]}
{"_type":"post","_createdAt":"2022-12-20T22:07:14.000+01:00","publishedAt":"2022-12-20T22:07:14.000+01:00","title":"Karácsony 2022","body":[{"_type":"code","code":"# There comes the toc ","language":"toc"},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Boldog Karácsonyt!"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":["strong"],"text":"Kellemes Ünnepeket és Boldog Karácsonyt kíván mindenkinek a Kir-Dev Csapata!"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"../images/posts/karacsony-2022.jpg","alt":"solid"}}]},{"_type":"block","markDefs":[{"_key":"14cd3dbbd259","_type":"link","href":"https://spot.sch.bme.hu/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az ünnepi időszak közeledtével minket is utolért a Karácsony szelleme. Így nagy lelkesedéssel vettünk részt a "},{"_type":"span","marks":["14cd3dbbd259"],"text":"SPOT Fotókör"},{"_type":"span","marks":[],"text":" karácsonyi fotózásán, ahol számos remek kép született. Ezek közül néhánnyal szeretnénk nektek kellemes ünnepeket kívánni!"}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Ajándékok"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Idén a fa alatt nem találtuk az ajándékokat, ezért kénytelenek voltunk debug-olni ezt a problémát és szokatlanabb helyeken is körül kellett néznünk."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/20221214_194858_geresbergo","alt":"search"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Nagy erőfeszítések árán sikerült rájönnük, hogy a csomagok mérete túl nagy volt, ezért beragadtak a kandallóba. De szerencsére ügyes mérnökeink kiszabadították őket."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/20221214_194718_geresbergo","alt":"loot-1"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az ajándékok végső kiszállítását a legjobb manókra bíztuk."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/20221214_194735_geresbergo","alt":"loot-2"}}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Mindennapok"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A félév vége felé elcsendesednek a projektek, mindenki bekuckózik az ünnepeket és persze, a viszagaidőszakot, várva. Ilyenkor kifejezetten fontos a törődés és az, hogy minden medvéről gondoskodjunk."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/20221214_195354_geresbergo","alt":"daily-1"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Egy ilyen idilli környezetet kevés dolog zavarhat meg. Egy ilyen dolog lehet egy nagyon fontos, tegnapra kéne projekt. A képen éppen most juttatja el ezt az ajándékot a körvezető a gyanútlan körtagok számára."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/20221214_195002_geresbergo","alt":"daily-2"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ilyenkor az boldogság nem mindig felhőtlen és egész drasztikus lépések is bekövetkezhetnek."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/20221214_195123_geresbergo","alt":"daily-3"}}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Mézeskalács sütés"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A fotózás után beköltöztünk a 13. szint konyhájába. Itt kellemes karácsonyi dalok hallgatása mellett, jelentős mennyiségű mézeskalácsot sütöttünk meg."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A munkálatok a tészta begyúrásával kezdődtek. Ez egy időigényes folyamat volt, mivel a tészta a kezdetekben nem akart rendesen összeállni. Miután elérte a megfelelő konzisztenciát, elkezdett a tészta kovalens kötést kialakítani a körvezetőnkkel. Szerencsére sikerült kiszabadítani."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/bb-and-dough","alt":"dough"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A tészta begyúrása után a nyújtás következett. Itt a szokásos nagyvállalati munkamegosztást alkalmaztuk. Egy fejlesztő és n+1 nem operatív segítő."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/20221215_201001","alt":"group"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ezután már csak a tészta formára vágása és megsütése volt hátra. A szokásos karácsonyi formák mellett megpróbáltuk a kör logóját is megformázni mézeskalácsból."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/kir-dev-bread-2","alt":"bread"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A logó megformázása sikeres volt, ezután egy próbakóstolást követően, közösen elfogyasztottuk az alkotást."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/20221215_205653","alt":"taste"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Köszönjük, hogy végigolvastad és mégegyszer "},{"_type":"span","marks":["strong"],"text":"Kellemes Ünnepeket kívánunk!"}]}]}
{"_type":"post","_createdAt":"2022-12-30T12:34:34.000+01:00","publishedAt":"2022-12-30T12:34:34.000+01:00","title":"Félévzáró + B.Ú.É.K. - 2022","body":[{"_type":"code","code":"# There comes the toc ","language":"toc"},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Boldog Új Évet Kívánunk!"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Egy igazán eseményteli félévet és évet tudhatunk magunk mögött. Számos felejthetetlen élménnyel gazdagodtunk az év során, valamint rengeteg mérföldkövet is sikerült átlépnünk. Reméljük, hogy számodra is ilyen jól telt a 2022-es év és 2023 is legalább ennyire remek lesz!"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az év utolsó eseményének, a Simonyi Félévzáró, Ami Amúgy Szakestélynek az élménybeszámolójával zárjuk az évet és kívánunk "},{"_type":"span","marks":["strong"],"text":"boldog új évet Mindenkinek!"}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Simonyi Félévzáró, Ami Amúgy Szakestély"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Már hagyománnyá vált Szakestély megszervezésével zárta le a Simonyi Károly Szakkollégium az évet. Ennek kifejezetten örültünk, mert a korábbi Szakestélyeket nagyon élveztük mindannyian."}]},{"_type":"block","markDefs":[{"_key":"8c4f92edaf10","_type":"link","href":"https://pek.sch.bme.hu/profiles/kiraly96"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A rendezvény a Szakest elnökválasztásával kezdődött, amit a tisztviselők kinevezése követett. Több tagunk is a tisztviselők sorát erősítette. Volt körvezetőnk, "},{"_type":"span","marks":["8c4f92edaf10"],"text":"Kircsi (Király Bálint)"},{"_type":"span","marks":[],"text":" a Kontrapunkt-ban kapott helyet."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/felevzaro-2","alt":"szakest"}}]},{"_type":"block","markDefs":[{"_key":"2835fbac9efc","_type":"link","href":"https://pek.sch.bme.hu/profiles/triszt4n"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Emellett "},{"_type":"span","marks":["2835fbac9efc"],"text":"Trisz (Piller Trisztán)"},{"_type":"span","marks":[],"text":" a Szakkollégium Elnöke címe mellé megkapta az etalon részeg tisztséget is, nyilván az utóbbit csak ezen este időtartamára. Feladatát a tőle megszokott lelkesedéssel és szakmai minőségben látta el, igazán büszke volt rá a kör!"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/trisz","alt":"trisz"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ezután meghallgatásra kerültek az alkohol impotenciában szenvedők és a késők, akik kreatívabbnál kreatívabb indokokkal próbálták megmagyarázni a hiányosságaikat. Ezután a kontrák műsora következett, ami hatalmas sikert aratott."}]},{"_type":"block","markDefs":[{"_key":"181b605e4cd2","_type":"link","href":"https://pek.sch.bme.hu/profiles/berenteb"},{"_key":"8fb21c662247","_type":"link","href":"https://pek.sch.bme.hu/profiles/beni99"},{"_key":"d2b47cd9c034","_type":"link","href":"https://pek.sch.bme.hu/profiles/sepsilaci"},{"_key":"2c155b258d54","_type":"link","href":"https://pek.sch.bme.hu/profiles/yeti"},{"_key":"c3a4d807641c","_type":"link","href":"https://pek.sch.bme.hu/profiles/kiraly96"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az est teli volt meglepetésekkel. A műsor egy pontján a kontrák kihívták a Kir-Dev jelenlegi és összes jelenlévő ex-körvezetőjét, hogy egy sörpárbajban bizonyítsák a rátermettségüket. A résztvevők időrendi sorrendben, legfiatalabbtól a legtapasztaltabbig: "},{"_type":"span","marks":["181b605e4cd2"],"text":"Berente Bálint"},{"_type":"span","marks":[],"text":", "},{"_type":"span","marks":["8fb21c662247"],"text":"Bucsy Benjámin"},{"_type":"span","marks":[],"text":", "},{"_type":"span","marks":["d2b47cd9c034"],"text":"Sepsi László"},{"_type":"span","marks":[],"text":", "},{"_type":"span","marks":["2c155b258d54"],"text":"Fehér János"},{"_type":"span","marks":[],"text":", "},{"_type":"span","marks":["c3a4d807641c"],"text":"Király Bálint"},{"_type":"span","marks":[],"text":". Kircsi rutinos győzelmet aratott."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/beerduel","alt":"parbaj"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A programot a Krampampuli meggyújtása, majd elfogyasztása zárta."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/20221217_003356_simi-2","alt":"krampampuli"}}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Félév Csapata"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Minden félév végén a Szakkollégium Vezetősége megszavazza egy csapatnak a lehengerlően elismerő Félév Csapata címet, akikről úgy vélik, hogy az időszakban valamilyen tekintetben kiemelkedtek. "},{"_type":"span","marks":["strong"],"text":"Ebben a félévben a megtisztelő Félév Csapata címet a Kir-Dev kapta,"},{"_type":"span","marks":[],"text":" ennek nagyon örültünk és köszönjük a bizalmat!"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/csapat-2","alt":"csapat"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":["strong"],"text":"Ezekkel a gondolatokkal zárjuk az évet, Boldog Új Évet Kívánunk Mindenkinek!"}]}]}
{"_type":"post","_createdAt":"2023-03-05T14:21:16.000+01:00","publishedAt":"2023-03-05T14:21:16.000+01:00","title":"Az új Konzisite fejlesztése","body":[{"_type":"code","code":"","language":"toc"},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/konzisite_email_header","alt":"konzisite header"}}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Mi is a Konzisite?"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A BME VIK hallgatói találkozhattak már a régi Konzisite-tal, melyet Hallgatói Képviselet készített valamikor a 2010-es évek elején. Az oldal fő feladata, hogy egy felületet adjon a kar hallgatóinak, ahol konzultációkat kérhetnek, illetve ha konzultációt tartanak, meghirdethessék azt az egész karnak. Ezen kívül a résztvevők értékelhetik is a konzikat, amely alapján a HK ösztöndíjban tudja részesíteni a konzi tartóit. Sajnos ez az oldal már sok szempontból elavulttá vált, fejlesztése, javítása pedig nagyon nehézkes volt. Ezért kért meg minket a HK, hogy fejlesszünk egy új verziót. Az eddig létező funkciók mellett volt pár új ötletük is. Valamint természetesen az is cél volt, hogy a jövőben is könnyen bővíthető legyen az oldal. Mi a Kir-Dev-nél fontosnak tartjuk, hogy az új tagjaiknak átadjuk azt a tudást, amit mi a körben szereztünk, így tudás nem veszik el, a projektjeink pedig éveken keresztül üzemelhetnek, hiszen mindig lesz, aki tud javítani vagy új funkciót fejleszteni."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/kepernyokep-2022-12-04-031952","alt":"oreg_konzisite"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A Konzisite korábbi nyitólapja"}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Külsős projektek a Kir-Dev-nél"}]},{"_type":"block","markDefs":[{"_key":"dce8688f3c54","_type":"link","href":"https://pek.sch.bme.hu/profiles/feketesamu"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Mint sok más projektünk a Kir-Dev-nél, a Konzisite is egy külsős projekt, azaz nem mi találtuk ki, hanem egy másik kör vagy szervezet (ez esetben a HK) keresett meg minket. Ilyenkor tipikusan egy minél pontosabb specifikációt kérünk a megrendelőtől, ami alapján mi meg tudjuk kezdeni a tervezést. Emellett kinevezünk egy projektfelelőst, aki a szívén viseli a projektet a jövőben. Az ő felelőssége lesz a kapcsolattartás a megrendelővel, a feladatok felosztása a körön belül, valamint a projekt haladásának felügyelete. Ennél a projektnél ezt a feladatot "},{"_type":"span","marks":["dce8688f3c54"],"text":"Fekete Sámuel"},{"_type":"span","marks":[],"text":" kapta meg, ami számára is új volt, hiszen akkor még csak fél éve volt tagja a körnek."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Tervezés"}]},{"_type":"block","markDefs":[{"_key":"a9749a64089b","_type":"link","href":"https://www.postgresql.org/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A specifikáció alapján egyértelmű volt számunkra, hogy ez a bonyolultabb projektjeink közé fog tartozni. A tavaszi félév közepén, a NodeJS és React tanfolyamok végezetével sok érdeklődő újoncunk volt, akik szerették volna hasznosítani újonnan szerzett tudásukat, viszont nem volt futó projektünk ezekben a technológiákban. Így döntöttünk a Node-React stack mellett, adatbázisnak pedig az általunk sokat használt "},{"_type":"span","marks":["a9749a64089b"],"text":"PostgreSQL"},{"_type":"span","marks":[],"text":" relációs adatbázist választottuk, ami ideális nagy, bonyolult adatbázis sémájú projektekhez."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az első és legfontosabb tervezési lépés egy adatvezérelt rendszer fejlesztése előtt az adatbázis sémájának megtervezése. Erre épül minden, később aránylag nehéz változtatni, de ha nem ideális, nagyban meg tudja nehezíteni a fejlesztést. Ezt az újoncokkal közösen terveztük meg, akik így a tanfolyam elvégzése után rögtön részt vehettek egy valódi projektben, ráadásul már a legelső fázistól. Az eredmény: "},{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/konzisite_diagram","alt":"adatbázis séma egyszerűsített ábrája"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az adatbázis séma egyszerűsített ábrája"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ezután az oldal alapvető felépítését terveztük meg. A HK csak funkcionalitást specifikált számunkra, így szabad kezet kaptunk az oldal felépítésének megtervezésében. Megbeszéltük, milyen oldalakra bontsuk fel az alkalmazást és hogy az egyes oldalon milyen funkciók, gombok és linkek kapjanak helyet. Ezt is fontos viszonylag korán eldönteni, hiszen az alkalmazás backendjét, vagyis a szerveroldali kódot ez alapján lehet elkészíteni."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Választott technológiák"}]},{"_type":"block","markDefs":[],"style":"h3","children":[{"_type":"span","marks":[],"text":"Node.js"}]},{"_type":"block","markDefs":[{"_key":"9c40d031467b","_type":"link","href":"https://nodejs.org/en/"},{"_key":"10a5e367ee2e","_type":"link","href":"https://www.typescriptlang.org/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A "},{"_type":"span","marks":["9c40d031467b"],"text":"NodeJS"},{"_type":"span","marks":[],"text":"-t választottuk backend technológiának. A NodeJS egy JavaScript futtatókörnyezet, ami lehetővé teszi, hogy böngészőn kívül futtassunk JS-t. Manapság egyre gyakrabban használt ez webalkalmazások backendjeként, hiszen könnyen tanulható. JavaScript-tel minden webfejlesztőnek van tapasztalata, hiszen frontenden kikerülhetetlen. Továbbá nagyon sok könyvtár elérhető az ökoszisztémában, amiknek köszönhetően nem kell mindent a nulláról lekódolnunk. Azonban nagy projektben a JavaScript-tel nehéz fejleszteni, hiszen gyengén típusos, azaz a változók futás közben típust változtathatnak. Ilyen kódbázist nehéz konzisztensen tartani sok fejlesztővel, ezért a NodeJS-t "},{"_type":"span","marks":["10a5e367ee2e"],"text":"TypeScript"},{"_type":"span","marks":[],"text":"-tel használtuk (és használjuk is minden más projektünkben is). Ez a nyelv a JS-nek egy kiterjesztése, ami egy jobb típusrendszert biztosít, de végül JS-re fordul."}]},{"_type":"block","markDefs":[],"style":"h3","children":[{"_type":"span","marks":[],"text":"NestJS"}]},{"_type":"block","markDefs":[{"_key":"3d8dffb77d0f","_type":"link","href":"https://nestjs.com/"},{"_key":"36a260004665","_type":"link","href":"https://api.konzisite-staging.kir-dev.hu/api"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A NodeJS magában viszont még nem elég egy komplex webalkalmazás elkészítéséhez. Ehhez a "},{"_type":"span","marks":["3d8dffb77d0f"],"text":"NestJS"},{"_type":"span","marks":[],"text":" nevű keretrendszert használtuk, amivel könnyedén lehet nagyszabású webalkalmazásokat fejleszteni. Korábban nem volt Nest-es projektünk, de a tanfolyamon már ezt tanítottuk, és az itt elkészített projekt számunkra is egy Proof of Concept projekt volt, azaz már korábban kicsiben kipróbáltuk, és megfelelt az igényeinknek. Nagyon hasznos volt még a Nest-nek a könnyen konfigurálható OpenAPI leírója. Ez egy automatikusan generált felület, ahol fel vannak sorolva a REST API végpontjai, és pontosan le van írva, melyik meghívásához milyen paraméterek kellenek, illetve milyen formában adja vissza az adatokat. Ez óriási segítség frontend fejlesztés közben. A tesztverzió OpenAPI leíróját "},{"_type":"span","marks":["36a260004665"],"text":"itt megnézhetitek"},{"_type":"span","marks":[],"text":"."}]},{"_type":"block","markDefs":[],"style":"h3","children":[{"_type":"span","marks":[],"text":"Prisma"}]},{"_type":"block","markDefs":[{"_key":"76be35384528","_type":"link","href":"https://www.prisma.io/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Mint már említettem, az alkalmazás adatbázisa meglehetősen összetett lett. Egy ilyen sémához SQL lekérdezéseket írni igen nehéz lenne, de szerencsére erre nem is volt szükség. Szintén ebben a projektben próbáltuk ki először a "},{"_type":"span","marks":["76be35384528"],"text":"Prisma"},{"_type":"span","marks":[],"text":" ORM-et (Object Relational Mapping). Ez egy olyan JavaScript könyvtár, ami kezeli a kapcsolatot a kódunk és az adatbázis között. Az adatbázisból kinyert rekordokat TypeScript objektumokká alakítja, valamint a lekérdezések egy nagyon kényelmes JS szintaxissal adhatóak meg. Talán elsőre megérteni nem könnyű, de nagyon tömören meg lehet fogalmazni a komplex lekérdezéseket is. A főoldalon például szükségünk van azokra a konzultációkra, amelyeken a felhasználó részt vett, de még nem értékelte valamelyik előadót. Ez a lekérdezés öt táblát érint, ezeknek a megfelelő join-olása nem embernek való feladat, hanem a Prismának: az alábbi szűrővel megkaphatjuk a megfelelő konzikat, ő majd megoldja a joinokat."}]},{"_type":"code","code":"const results = await this.prisma.consultation.findMany({ where: { presentations: { some: { NOT: { ratings: { some: { ratedBy: { userId: user.id } } } } } }, participants: { some: { userId: user.id } } } }) ","language":"typescript"},{"_type":"block","markDefs":[],"style":"h3","children":[{"_type":"span","marks":[],"text":"React"}]},{"_type":"block","markDefs":[{"_key":"1df7f50c3ab5","_type":"link","href":"https://reactjs.org/"},{"_key":"f119471f7e9c","_type":"link","href":"https://chakra-ui.com/"},{"_key":"4cfc045d95ca","_type":"link","href":"https://react-query-v3.tanstack.com/"},{"_key":"7acd0eb7bbae","_type":"link","href":"https://react-hook-form.com/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A frontenden a "},{"_type":"span","marks":["1df7f50c3ab5"],"text":"React"},{"_type":"span","marks":[],"text":" nevű könyvtárat használtuk, mely jelenleg messze a legelterjedtebb. Számos projektben dolgoztunk már vele, így van tapasztalatunk bőven. Könnyen tanítható az újoncoknak is, szintaxisa nagyban hasonlít a HTML-hez, de rengeteg mindennel kiegészíti azt, és gyorsan lehet vele egy jól használható felhasználói felületet készíteni. Nagy előnye még, hogy rengeteg kisebb könyvtárat készítettek hozzá, melyekkel gyakori problémákat lehet egyszerűen megoldani. Csak a legfontosabbakat szeretném kiemelni azok közül, amiket használtunk ebben a projektben. A "},{"_type":"span","marks":["f119471f7e9c"],"text":"Chakra UI"},{"_type":"span","marks":[],"text":" az egységes, de mégis stílusos megjelenést segíti, a "},{"_type":"span","marks":["4cfc045d95ca"],"text":"ReactQuery"},{"_type":"span","marks":[],"text":" a hálózati kéréseket, a "},{"_type":"span","marks":["7acd0eb7bbae"],"text":"ReactHookForm"},{"_type":"span","marks":[],"text":" pedig az űrlapok kezelését egyszerűsíti."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Végeredmény"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"https://warp.sch.bme.hu/images/konzisite_16_10","alt":"konzisite landing page"}}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az új Konzisite nyitólapja"}]},{"_type":"block","markDefs":[{"_key":"e051add37a5e","_type":"link","href":"https://konzi.kir-dev.hu"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"A tavaszi félév kezdetére készültünk el az első olyan verzióval, mely már kikerülhetett élesbe. Az új verziót a "},{"_type":"span","marks":["e051add37a5e"],"text":"konzi.kir-dev.hu"},{"_type":"span","marks":[],"text":" címen éritek el, a megszokott címen pedig a régi verzió is fennmaradt, hiszen az előző félévben tartott konzultációk adaitaira még szüksége lesz az ösztöndíjakra pályázóknak. A régi konzisite-hoz képest szerintem egy sokkal könnyebben használható UI-t raktunk össze. Van lehetősége bárkinek csoportokat létrehoznia, nem kell ehhez a HK-nak emailt írni. Egy konzinak több előadója is lehet, mindegyiküket külön lehet értékelni. Egy felhasználóra érkezett értékelések megjelennek a profilján. Van egy külön felhasználó böngésző oldal, ahol publikus a konzitartók átlagos értékelése és egyéb statisztikák is. A konzi tartóknak van lehetősége jegyzet feltöltésére egy konzihoz, amit a résztvevők az alkalom után tölthetnek le, ha értékelték az előadókat."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Az oldal még nincs kész, vannak funkciók, amik tervben vannak, sőt némelyik már készül is. Lesznek még például email értesítések és exportálható naptár fájlok. Ha van még ötleted, mit lehetne belerakni, keress meg minket!"}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Tapasztalatok"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"\"Projektvezetőként nagyon élveztem ezen a projekten dolgozni, hiszen nekem is ez volt az első fullstack projektem, ahol a legelső fázistól kezdve részt vettem a munkában. A tech-stack választást nagyon jól eltaláltuk, bár ez nem az én érdemem, hanem a kör tapasztaltabb tagjaié. Büszke vagyok a projektre amit összeraktunk a körrel, remélem sokáig tudják használni a hallgatók.\" - "},{"_type":"span","marks":["em"],"text":"Samu"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"\"Tavaly tavasszal csatlakoztam a körhöz és ez volt az első ilyen projektem, nem csak körön belül, hanem összességében. Habár gyakorlatilag minden új volt - és még most is vannak meglepetések -, de rengetek segítséget kaptam a kör tagjaitól, hogy ne veszítsem el a fejem. A projekten dolgozni olyan érzés volt, mintha profi közegben lennék, mind szervezésileg, mind szakmailag.\" - "},{"_type":"span","marks":["em"],"text":"Smuky"}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Kitekintés"}]},{"_type":"block","markDefs":[{"_key":"fc4b8395d82c","_type":"link","href":"https://kir-dev.hu/courses/"},{"_key":"8155f331e83c","_type":"link","href":"https://kir-dev.hu/about/"}],"style":"normal","children":[{"_type":"span","marks":[],"text":"Ha ez a poszt felkeltette az érdeklődésedet és szeretnél becsatlakozni egy hasonló projektbe, akkor mindenképpen vedd fel velünk a kapcsolatot! A tavaszi félév elején indulnak a tanfolyamaink, ahol a nulláról megtanítjuk a legfontosabb dolgokat az itt említett technológiákról. Ezekről többet a "},{"_type":"span","marks":["fc4b8395d82c"],"text":"Tanfolyamok"},{"_type":"span","marks":[],"text":" oldalon tudhatsz meg. Ha ezekről lemaradtál volna, a "},{"_type":"span","marks":["8155f331e83c"],"text":"Kapcsolat"},{"_type":"span","marks":[],"text":" oldalon megtalálod a kontaktjainkat!"}]}]}
{"_type":"post","_createdAt":"2023-09-01T17:00:00.000+02:00","publishedAt":"2023-09-01T17:00:00.000+02:00","title":"2023 nyár","body":[{"_type":"code","code":"","language":"toc"},{"_type":"block","markDefs":[],"style":"h1","children":[{"_type":"span","marks":[],"text":"Kir-Dev Tábor"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Nyári táboraink mindig különlegesek és emlékezetesek szoktak lenni. Idén sem volt ez másként, amikor a Kir-Dev csapat 10 tagja júliusban összegyűlt Pannonhalmán egy fantasztikus hétvégét eltölteni."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Érkezés"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A szállás, amit választottunk, a Pannonhalmi Főapátság Szent Jakab Vendégháza volt, egy teljesen új komplexum, ami minden szempontból megfelelt az igényeinknek. A kényelmes szobák és a barátságos légkör hamar otthonossá tette az egész helyet."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"A Gasztronómiai Élmények"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Már az első este elkezdtük a kulináris utazást, amikor a tábor kuktái (mindenki) felajánlották, hogy elkészítik a vacsorát. A menüben szerepelt a híres tejszínes csirkés tészta, amit mindenki imádott. Így már az étkezések is összekovácsoltak minket, és együtt tölthettünk el kellemes estéket a kertben. A reggeli is pompás volt, a szállás terasz szerűségén gyűltek össze a táborozók és egy kiadós lakomát tartottak a túra előtt."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"../images/posts/2023-nyar/2023-fozes.jpg","alt":"fozes"}},{"_type":"img","asset":{"src":"../images/posts/2023-nyar/2023-reggeli.jpeg","alt":"reggeli"}}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"Ride 'n' Wine"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Közös kirándulásunk az apátságba különleges élmény volt. A Pannonhalmi Bencés Főapátság impozáns épületegyüttese gyönyörű környezetben található, és a történelme is lenyűgöző. Az apátság környékének minden szegletét bejárva a csapat lelkiekben már a délutáni borkostolóra készült. A helyi borászatok kiváló borai mellett a társaság is remek volt, így a borok mellett a hangulat is fokozódott. A nap végén a vacsorát megejtve folytatódott a szeszkultúra egy kis társasjátékkal fűszerezve."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"../images/posts/2023-nyar/2023-borkostolo.jpeg","alt":"apatsag"}}]},{"_type":"block","markDefs":[],"style":"h1","children":[{"_type":"span","marks":[],"text":"Simonyi Nyári Tábor"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A szakkollégium életében kiemelt fontosságú az SNYT, azaz a Simonyi Nyári Tábor. Körünk idén is nagy kedvvel vett részt a rendezvényen, ahol a szakkollégiumi élet minden aspektusával megismerkedhettünk. A szervezőknek ezúton is köszönjük a lehetőséget! "},{"_type":"img","asset":{"src":"../images/posts/2023-nyar/2023-snyt.jpg","alt":"snyt"}}]},{"_type":"block","markDefs":[],"style":"h1","children":[{"_type":"span","marks":[],"text":"Nyári Munka"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"Körünk szokásos nyári tevékenységei vették kezdetüket. A Gólyatábor, Gólyahét és Qpa közeledte már éreztette hatását."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"CMSch"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A CMSch projekt az említett rendezvények közeledtével ismét erőre kapott. A kör tagjai a nyári hónapokban is folyamatosan dolgoztak a rendszeren, hogy a felhasználók számára a lehető legjobb élményt nyújtsa a későbbiekben. A rendezvények azóta lementek sikeresen, sok tapasztalattal és egy még stabilabb rendszerrel gazdagodtunk."}]},{"_type":"block","markDefs":[],"style":"h2","children":[{"_type":"span","marks":[],"text":"B(e)acon - CMSch Tracker mobilapp"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A nyáron egy új irányzatot is elővettünk a fiókból: a mobilapp fejlesztést. A cél az volt, hogy a Gólyahéten a gólyák követni tudják a tankörseniorjaikat, ezáltal a tankörüket, valamint, hogy a rendezők is követni tudják a tankörök mozgását. A fejlesztés során a React Native keretrendszert használtuk, amelynek köszönhetően a kódunkat Androidra és iOS-re ki tudtuk adni TestFlight és PlayStore béta segítségével. Több száz felhasználóhoz jutott el az alkalmazás."}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"img","asset":{"src":"../images/posts/2023-nyar/2023-app.png","alt":"beacon"}}]},{"_type":"block","markDefs":[],"style":"h1","children":[{"_type":"span","marks":[],"text":"Valami véget ér, valami csak most kezdődik"}]},{"_type":"block","markDefs":[],"style":"normal","children":[{"_type":"span","marks":[],"text":"A nyár végére a csapat már teljes erőbedobással készült a következő félévre, amikor ismét együtt dolgozhatunk a kör fejlődésén. Izgalmas félév lesz, hiszen rengeteg új tag áll a felvételi előtt!"}]}]}