Coder Social home page Coder Social logo

nerdvana-ro / varena-abandoned Goto Github PK

View Code? Open in Web Editor NEW

This project forked from catalinfrancu/mule

6.0 6.0 5.0 2.37 MB

Varena is a website program for hosting programming problems.

License: GNU Affero General Public License v3.0

PHP 97.83% CSS 0.38% JavaScript 1.79%

varena-abandoned's People

Contributors

catalinfrancu avatar sddddgjd avatar stelarcf avatar znickq avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

varena-abandoned's Issues

suport pentru ștergerea de fișiere atașate

În prezent ele pot fi doar încărcate / descărcate, dar nu și șterse. Trebuie ținut cont de permisiuni. Momentan,

  • doar autorul problemei sau adminii pot șterge atașamente;
  • autorul problemei nu poate șterge un atașament deținut de un admin.

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.

avataruri utilizator

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”.

unealtă pentru conversia enunțului problemei la HTML

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.

controlul accesului la fișierele atașate

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:

  • id (ca de obicei, int not null auto_increment)
  • userId (persoana care încarcă acel fișier)
  • problemId (problema de care este legat fișierul)
  • fileName (numele fișierului, fără cale)
  • access (tipul de acces)
  • created și modified (ca de obicei, int not null)

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.

messages.po trebuie să-și păstreze ordinea

Î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.

importul joburilor din baza de date varena.ro

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. :-)

suport pentru directoare absolute pentru upload

Î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:

  • dacă opțiunea de configurare upload.path începe cu /, ea este o cale absolută;
  • altfel ea este o cale relativă la rădăcina instalării (ca până acum).

trimiterea de surse

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:

  • userId
  • problemId
  • extension (text cu valorile c sau cpp)
  • evalStatus (1 = neevaluat, 2 = evaluat, posibil 3 = eroare de evaluator, constante definite în Source.php)
  • score

importul problemelor din baza de date varena.ro

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.

conceptul de „rundă”

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:

  • id, created, modified -- la fel ca toate celelalte tabele
  • name - numele rundei, cum ar fi „Tema 5 clasa a 8-a”
  • userId - creatorul rundei
  • startDate - data de început, stocată ca timestamp
  • duration - durata întreagă în minute (nu în ore, cu virgulă)

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:

  • id, created, modified -- ca mai sus
  • roundId - id-ul (numeric al) rundei
  • problemId - id-ul problemei.

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.

problemele au nevoie de autor

  • Trebuie adăugat câmpul problem.userId (să zicem după name în ordinea câmpurilor).
  • Câmpul va fi de tipul int not null;
  • Adăugarea trebuie făcută prin-un fișier ddddd.sql în patches/.
  • La afișarea problemei (în problem.tpl) trebuie afișat un mesaj de genul „adăugată de ...”
  • Mesajul respectiv trebuie localizat.

buguri la încărcarea de attachments

La încărcarea unui atașament,

  • sistemul trebuie să verifice că directorul de upload există și să dea un mesaj de eroare dacă nu;
  • sistemul trebuie să verifice că funcțiile 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).

istoricul modificărilor

Obiectele importante (în special problem) au nevoie de istorie. Putem face aceasta la nivel de MySQL folosind triggers.

  • creăm o tabelă nouă, să zicem history_problem, cel puțin cu câmpurile userId și statement (utilizatorul care face modificarea și noul enunț).
  • creăm un trigger MySQL care, la fiecare modificare a problemei, inserează o înregistrare în history_problem;
  • ne trebuie și o pagină unde să putem vedea modificările aduse unei probleme de-a lungul timpului.
  • ideal ar fi să vedem nu doar un cârnat cu versiunile, ci diff-ul între fiecare două versiuni.

Pentru inspirație, iată cum prezintă dexonline istoria definițiilor.

suport pentru atașamente

Pentru început, dorim ceva simplu:

  • autorul problemei și administratorii să poată adăuga atașamente la orice problemă
  • oricine să poată vedea lista de atașamente

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).

editarea problemelor

  • câmpurile name și statement trebuie să fie editabile

Permisiuni:

  • doar administratorii pot edita câmpul name și doar dacă nu există deja o altă problemă cu numele dorit;
  • doar autorul problemei sau administratorii pot edita câmpul statement;

tools/migration.php error

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

evaluator

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).

utilizatori dummy

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.

importul utilizatorilor din baza de date varena.ro

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ță.

pagina utilizatorului

La www/user.php și în templates/user.tpl trebuie construit scheletul paginii utilizatorului.

Aici se va vedea, pentru început:

  • numele de utilizator
  • numele complet
  • adresa de e-mail, dacă utilizatorul și-a dat-o
  • privilegiile de administrare (normal / admin, deocamdată)
  • lista de probleme propuse

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).

importul rundelor din baza de date varena.ro

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. :-)

metodă uniformă de a formata data/ora în Smarty

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.

editarea rundei

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.

  • Descărcați fișierele JS și CSS și salvați-le în www/js și www/css. Dacă este mai mult de un fișier, creați subdirectoare, de exemplu www/css/select2/.
  • Adăugați apelurile acestor fișiere în SmartyWrap.php, în rutinele addCss() și addJs().
  • Codul php care gestionează editarea rundelor (posibil tot round.php) va apela SmartyWrap::addCss('select2'); și similar pentru Js.
  • Pentru găsirea ușoară a problemelor, pagina HTML va trebui să comunice, prin Ajax, cu o pagină din backend care știe doar să raporteze lista de probleme, în format JSON. Creați directorul www/ajax și în el fișierul problems.php, să zicem.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.