nerdvana-ro / varena-abandoned Goto Github PK
View Code? Open in Web Editor NEWThis project forked from catalinfrancu/mule
Varena is a website program for hosting programming problems.
License: GNU Affero General Public License v3.0
This project forked from catalinfrancu/mule
Varena is a website program for hosting programming problems.
License: GNU Affero General Public License v3.0
În prezent ele pot fi doar încărcate / descărcate, dar nu și șterse. Trebuie ținut cont de permisiuni. Momentan,
Probabil prezentarea ar trebui făcută tabelar, iar atașamentele pe care nu le poți șterge nici să nu aibă link pentru ștergere. Sigur, verificarea dreptului de ștergere se face și în backend, ca utilizatorul să nu compună URL-uri manual.
La click pe linkul de ștergere ar fi util un alert() în Javascript.
Hai să ne tragem și poze. :-)
Mie mi-a plăcut mult jCrop. Îl putem folosi ca să impunem o rezoluție anume, un aspect ratio, ca să-i lăsăm să decupeze / scaleze o porțiune din imaginea încărcată etc.
Îl folosim la dexonline și merge bine, vezi template-ul și codul PHP.
Deocamdată hai să avem o singură poză, de 100x100 sau ceva standard, care să fie afișată în pagina utilizatorului. În timp, vedem ce alte mărimi ne trebuie și cum le implementăm (bine e ca toate thumbnail-urile să fie calculate din poza originală, nu unul din altul).
Pentru stocare, ar trebui să facem un director www/img/user, cu drepturi 777 pe el și cu un .gitignore ca să nu ne bată la cap cu pozele care vor apărea. Acolo pot sta pozele cu numele _<rezoluție>.jpg, de exemplu 1357_300x300.jpg.
Momentan nu este nevoie să stocăm nimic în baza de date. Aflăm dacă un utilizator are avatar direct cu file_exists().
În backend, aș folosi ImageMagick, fie prin biblioteca PHP (dacă există una), fie invocând direct programul extern „convert”.
Enunțul problemei trebuie stocat într-o notație lizibilă: textile, markdown, eventual chiar mediawiki. Trebuie să găsim o bibliotecă PHP care să facă conversia de la această notație la HTML. Biblioteca trebuie să aibă licența GPL sau altceva compatibil cu licența noastră (care este Affero GPL).
Inițial, codul va face această conversie la fiecare afișare.
Avem nevoie de o tabelă nouă, attachment, și evident de o clasă corespunzătoare în _lib/models/Attachment.php. Pentru început, câmpurile care ne interesează sunt:
Tipurile de acces, pentru început, vor fi 1 - public, 2 - author, 3 - admin. Tipul 2 poate fi descărcat doar de către autor sau administratori, tipul 3 doar de către administratori. De asemenea, tipurile 1 și 2 pot fi șterse sau suprascrise doar de către autor sau administratori, iar tipul 3 doar de către administratori.
La încărcarea fișierelor, utilizatorul trebuie să aleagă numele de fișier, dar poate bifa opțiunea „păstrează numele”, care păstrează numele fișierului încărcat. De asemenea, el alege tipul de acces pentru fișierele încărcate (un singur tip pentru toate, în caz că încarcă mai multe fișiere simultan).
Apoi, descărcarea propriu-zisă a fișierelor se va face doar printr-un manager, să zicem în www/attachment.php, care ia ca parametru id-ul din tabela attachment și acceptă sau refuză descărcarea.
În prezent, orice nou mesaj localizat în messages.po întoarce complet pe dos ordinea acelui fișier (vezi de exemplu eab2791). Din cauza asta, este foarte greu să vezi ce s-a adăugat / modificat / șters. Cum toate commit-urile vor introduce câteva mesaje, eroarea asta va polua toate pull requesturile până o reparăm.
Trebuie cumva convins poedit să păstreze ordinea mesajelor. Nu știu dacă se poate. Dacă nu, ne trebuie o unealtă scrisă de noi (sau poate există deja) care să reordoneze fișierul. Atunci localizarea mesajelor ar consta dintr-un pas în plus, invocarea acestei unelte.
Vom avea un script uriaș care să importe întreaga bază de date, dar deschid un tichet separat pentru fiecare categorie. Acest script va lua ca parametru numele bazei de date din care se face importarea, deci
tools/importIA.php --db varena
Un job este rezultatul produs la compilarea și rularea unei surse, cu informații despre timpul de rulare, codul de terminare, punctaj etc.
Va avea sens să ne gândim la acest issue după ce implementăm propriul suport pentru evaluare, ca să știm ce format avem noi înainte de a ne apuca de importare. :-)
Vezi convențiile
În prezent, lib/model/Attachment.php:getDirectoryForId()
hardcodează un ../
, deci directorul de uploads pornește obligatoriu din rădăcina instalării. Este ok, dar aș vrea și suport pentru directoare absolute de genul /tmp
(în development). Deci propun așa:
Poate fi ceva rudimentar, care să primească un fișier și un tip de sursă (C/C++) și să creeze o intrare în tabela source
.
Pentru început, tabela source
va stoca și rezultatele evaluării (punctaj final, data evaluării etc.). Deci nu diferențiem o „sursă” de un „job” pentru evaluator. Dacă, în viitor, vom implementa suport pentru reevaluări de probleme, atunci o sursă poate avea mai multe joburi, unul pentru fiecare evaluare prin care trece.
Ne trebuie câmpuri ca:
Vom avea un script uriaș care să importe întreaga bază de date, dar deschid un tichet separat pentru fiecare categorie. Acest script va lua ca parametru numele bazei de date din care se face importarea, deci
tools/importIA.php --db varena
Nu intru în detalii, dar vor fi multe. Enunțul problemei sper să fie simplu (avem și noi interpretor de textile). Dar după asta vin tag-urile, dificultățile, testele, alte fișiere atașate (imagini), limitele și toate celelalte.
Ar trebui să facem un caz special pentru clasă, care uneori stă în titlul problemei, iar alteori bănuiesc că ar putea sta în „grupa de vârstă”. Scriptul trebuie să știe să unifice astea într-un câmp dedicat.
Trebuie să începem să definim ce este o rundă. În primul rând avem nevoie de tabela round și clasa lib/model/Round.php, cu câmpurile:
De asemenea, ne trebuie o modalitate de a specifica ce probleme conține o rundă. Relația se numește many-to-many, căci o rundă poate avea mai multe probleme, iar o problemă poate fi dată în mai multe runde. Cea mai naturală implementare este cu o tabelă suplimentară, să zicem round_problem:
Pentru acest issue, nu ne ocupăm de editare. Scrieți un patch în patches/ddddd.sql care să insereze manual câteva runde și câteva mapări rundă <-> problemă. Scopul issue-ului este doar să facem prezentarea rundei în www/round.php?id=număr.
La încărcarea unui atașament,
mkdir()
și move_uploaded_file()
s-au terminat cu succes și să dea un mesaj de eroare dacă nu (probabil permisiunile pe directorul upload sunt incorecte).Obiectele importante (în special problem) au nevoie de istorie. Putem face aceasta la nivel de MySQL folosind triggers.
Pentru inspirație, iată cum prezintă dexonline istoria definițiilor.
Pentru început, dorim ceva simplu:
Atașamentele vor sta într-un director definit în fișierul de configurare mule.conf, să zicem:
[upload]
path = /var/varena/uploads
Le punem undeva în afara repository-ului nostru ca să ne asigurăm că nu există nici o modalitate de a păcăli serverul web să servească acele fișiere în mod direct (printr-un URL compus de mână).
Încărcarea de fișiere nu este banală, dar măcar HTML5 permite uploadul de fișiere multiple (în HTML4.1 singura soluție era o bibliotecă javascript).
Permisiuni:
Pe Debian Wheezy sub Virtual Machine, apare urmatoarea eroare la rularea "$ sudo php tools/migration.php":
PHP Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[28000] [1045] Access denied for user 'root'@'localhost' (using password: NO)' in /var/www/varena/lib/idiorn/idiorm.php:254
Stack trace:
#0 /var/www/varena/lib/idiorm/idiorm.php(254): PDO->__construct('mysql:host=loca...', 'root', '', Array)
#1 /var/www/varena/lib/idiorm/idiorm.php(236): ORM::_setup_db('default')
#2 /var/www/varena/lib/Db.php(29): ORM::for_table('variable')
#3 /var/www/varena/tools/migration.php(34): Db::tableExists('variable')
#4 {main}
thrown in /var/www/varena/lib/idiorm/idiorm.php on line 254
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[28000] [1045] Access denied for user 'root'@'localhost' (using password: NO)' in /var/www/varena/lib/idionr/idiorm.php:254
Stack trace:
#0 /var/www/varena/lib/idiorm/idiorm.php (254): PDO->construct('mysql:host=loca...', 'root', '', Array)
#1 /var/www/varena/lib/idiorm/idiorm.php (236): ORM::_setup_db('default')
#2 /var/www/varena/lib/Db.php (29): ORM::for_table('variable')
#3 /var/www/varena/tools/migration.php (34): Db::tableExists('variable')
#4 {main}
thrown in /var/www/varena/lib/idiorm/idiorm.php on line 254
Putem începe să lucrăm la un evaluator rudimentar. Codul Infoarena este software liber, din câte știu, îl putem folosi sau ne putem inspira după el. Pentru început, presupunem că urmăm aceleași convenții de nume pentru fișierele de test.
Depinde de #39. La evaluare, trebuie să actualizeze scorul final al sursei și să creeze câte o intrare într-o tabelă separată pentru fiecare test. Nu știu cum să numim tabela, poate chiar test_result
(cu clasa PHP TestResult.php
).
Conectarea prin OpenID este enervantă în development. Este cam lentă fiindcă face un roundtrip la furnizorul de OpenID. Mai mult, vom vrea mereu să testăm sistemul cu diverse permisiuni și e enervant să tot modifici permisiunile sau să te loghezi în 2-3 conturi.
Pentru comoditate, în dex.conf putem pune o setare development
în secțiunea [general]
. Când development = 1, pe pagina de OpenID trebuie să apară niște linkuri de login direct, local și fără parolă, ca utilizator normal / helper etc.
Când un link este apăsat, sistemul trebuie să creeze un user, dacă nu există deja unul potrivit, cu permisiunile respective. Username-ul poate fi dummyRegular, dummyHelper etc. Apoi sistemul te loghează în acel cont. Procedăm așa, pentru că nu vrem ca, din greșeală, chiar să creăm acele conturi pe serverul din producție.
Vom avea un script uriaș care să importe întreaga bază de date, dar deschid un tichet separat pentru fiecare categorie. Acest script va lua ca parametru numele bazei de date din care se face importarea, deci
tools/importIA.php --db varena
Pentru utilizatori, trebuie să adăugăm sau să modificăm câmpuri ca să putem importa ce ne trebuie. În prezent, această listă este
id
-- importat ca previousId
;username
-- importat ca username
;password
-- NU îl importăm, NU vrem grija parolelor;email
-- importat ca email
;full_name
-- importat ca name
;security_level
-- importat în câmpul admin
, care trebuie extins. Va fi numeric și va căpăta constante în lib/model/User.php
.newsletter
-- e zero pe linie, nu îl importăm;rating_cache
-- important ca previousRating. Pare să fie 3 * numărul afișat pe site.Accesul inițial al utilizatorilor la aceste conturi va fi puțin complicat, căci nu vor avea OpenID-uri asociate (în tabela identity
). Sistemul suportă deja autentificare prin e-mail, prin care utilizatorul primește un cod unic prin email. Trebuie doar să reformulăm textul de pe pagina de login ca să includă și „...sau dacă contul tău a fost migrat” etc.
Există câteva conturi, posibil zeci, care și-au tastat adresa greșit: yahooo.com, yhoo.com, gamil.com, gmai.com etc. Putem face un minim de efort să le scriem la adresele presupuse corecte ca să vedem dacă vor să-și păstreze acest cont, sau putem să le scriem pe listele existente să-i rugăm să-și verifice corectitudintea acestei adrese de email. Nu închide acest tichet până nu facem ceva în această privință sau până nu deschidem un tichet special pentru această cerință.
La www/user.php și în templates/user.tpl trebuie construit scheletul paginii utilizatorului.
Aici se va vedea, pentru început:
Pe măsură ce adăugăm alte posibilități, le vom lista și aici (poză de profil, rating, lista de probleme încercate, lista de concursuri la care a participat...)
Pagina user.php trebuie să primească ca parametru id-ul utilizatorului SAU numele de utilizator (username). Dacă cei doi parametri se bat cap în cap sau dacă nu există un utilizator cu parametrii dați, pagina va raporta o eroare (folosind FlashMessage).
Vezi una dintre http://openid.net/developers/libraries/
Motivul este că Google retrage suportul pentru OpenID 2.0, deci ar fi o idee bună să ne aliniem. https://developers.google.com/accounts/docs/OpenID
Vom avea un script uriaș care să importe întreaga bază de date, dar deschid un tichet separat pentru fiecare categorie. Acest script va lua ca parametru numele bazei de date din care se face importarea, deci
tools/importIA.php --db varena
Va avea sens să ne gândim la acest issue după ce implementăm propriul suport pentru runde, ca să știm ce format avem noi înainte de a ne apuca de importare. :-)
Merge perfect cu modificatorul date_format din Smarty. Singura problemă acolo e că trebuie specificat de fiecare dată formatul -- %e %b %Y
sau ce-o fi. Asta generează redundanță și, posibil, formate diferite.
Ar fi bine să avem modificatori personalizați pentru dată, respectiv dată+oră. Se poate face în Smarty, trebuie citit. Iar formatele dorite trebuie să stea în mule.conf.sample / mule.conf, ca să poată fi ușor convertite în caz că se schimbă limba.
Depinde de #8. Editarea numelui, a orei de start și a duratei este relativ ușoară.
Editarea listei de probleme este un pic mai grea. Cred că cea mai elegantă variantă este cu select2.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.