1
0
mirror of https://github.com/wulkanowy/wulkanowy.git synced 2025-01-19 00:16:48 -06:00

Add notes api (#8)

* Add notes api with tests
* Get county for snp direct from database
This commit is contained in:
Mikołaj Pich 2017-08-02 12:04:49 +02:00 committed by GitHub
parent 3271065263
commit 89d235dd8a
20 changed files with 514 additions and 89 deletions

View File

@ -41,4 +41,6 @@ dependencies {
compile 'org.apache.commons:commons-lang3:3.6'
testCompile 'junit:junit:4.12'
testCompile 'org.powermock:powermock-api-mockito:1.6.1'
testCompile group: 'org.unitils', name: 'unitils-core', version: '3.3'
}

View File

@ -19,10 +19,13 @@ import java.util.Map;
import io.github.wulkanowy.R;
import io.github.wulkanowy.api.Cookies;
import io.github.wulkanowy.api.StudentAndParent;
import io.github.wulkanowy.api.grades.Grade;
import io.github.wulkanowy.api.grades.GradesList;
import io.github.wulkanowy.api.grades.Subject;
import io.github.wulkanowy.api.grades.SubjectsList;
import io.github.wulkanowy.database.accounts.AccountData;
import io.github.wulkanowy.database.accounts.DatabaseAccount;
public class MarksFragment extends Fragment {
@ -83,13 +86,18 @@ public class MarksFragment extends Fragment {
try {
Cookies cookies = new Cookies();
cookies.setItems(loginCookies);
SubjectsList subjectsList = new SubjectsList(cookies, "powiatjaroslawski");
DatabaseAccount databaseAccount = new DatabaseAccount(mContext);
databaseAccount.open();
AccountData accountData = databaseAccount.getAccount(1);
databaseAccount.close();
StudentAndParent snp = new StudentAndParent(cookies, accountData.getCounty()).setUp();
SubjectsList subjectsList = new SubjectsList(snp.getCookiesObject(), snp);
List<Subject> subjects = subjectsList.getAll();
for (Subject item : subjects) {
subject.add(item.getName());
}
GradesList gradesList = new GradesList(cookies, "powiatjaroslawski");
GradesList gradesList = new GradesList(snp.getCookiesObject(), snp);
List<Grade> grades = gradesList.getAll();
for (Grade item : grades) {
Log.d("MarksFragment", item.getSubject() + ": " + item.getValue());

View File

@ -14,12 +14,14 @@ import java.io.ObjectOutputStream;
import io.github.wulkanowy.R;
import io.github.wulkanowy.activity.dashboard.DashboardActivity;
import io.github.wulkanowy.api.Cookies;
import io.github.wulkanowy.api.StudentAndParent;
import io.github.wulkanowy.api.login.AccountPermissionException;
import io.github.wulkanowy.api.login.BadCredentialsException;
import io.github.wulkanowy.api.login.Login;
import io.github.wulkanowy.api.login.LoginErrorException;
import io.github.wulkanowy.api.user.BasicInformation;
import io.github.wulkanowy.api.user.PersonalData;
import io.github.wulkanowy.api.user.User;
import io.github.wulkanowy.database.accounts.AccountData;
import io.github.wulkanowy.database.accounts.DatabaseAccount;
import io.github.wulkanowy.security.CryptoException;
@ -64,12 +66,11 @@ public class LoginTask extends AsyncTask<String, Integer, Integer> {
} catch (LoginErrorException e) {
return R.string.login_denied;
}
try {
String cookiesPath = activity.getFilesDir().getPath() + "/cookies.txt";
FileOutputStream out = new FileOutputStream(cookiesPath);
ObjectOutputStream outputStream = new ObjectOutputStream(out);
outputStream.writeObject(login.getJar());
outputStream.writeObject(login.getCookies());
outputStream.flush();
} catch (IOException e) {
return R.string.login_cookies_save_failed;
@ -77,8 +78,10 @@ public class LoginTask extends AsyncTask<String, Integer, Integer> {
if (save) {
try {
BasicInformation userInfo = new BasicInformation(login.getCookies(),
credentials[2]);
StudentAndParent snp = new StudentAndParent(login.getCookiesObject(),
credentials[2]).setUp();
User user = new User(snp.getCookiesObject(), snp);
BasicInformation userInfo = new BasicInformation(user, snp);
PersonalData personalData = userInfo.getPersonalData();
String firstAndLastName = personalData.getFirstAndLastName();
@ -117,7 +120,8 @@ public class LoginTask extends AsyncTask<String, Integer, Integer> {
Toast.makeText(activity, activity.getString(messageID), Toast.LENGTH_LONG).show();
if (messageID == R.string.login_accepted || messageID == R.string.root_failed || messageID == R.string.encrypt_failed) {
if (messageID == R.string.login_accepted || messageID == R.string.root_failed
|| messageID == R.string.encrypt_failed) {
Intent intent = new Intent(activity, DashboardActivity.class);
activity.startActivity(intent);
}

View File

@ -6,15 +6,17 @@ public class Cookies {
private Map<String, String> cookies;
public void setItems(Map<String, String> items) {
cookies = items;
}
public void addItems(Map<String, String> items) {
cookies.putAll(items);
}
public Map<String, String> getAll() {
public Map<String, String> getItems() {
return cookies;
}
public Cookies setItems(Map<String, String> items) {
this.cookies = items;
return this;
}
public Cookies addItems(Map<String, String> items) {
this.cookies.putAll(items);
return this;
}
}

View File

@ -20,20 +20,17 @@ public class StudentAndParent extends Vulcan {
private String uonetPlusOpiekunUrl;
public StudentAndParent(Cookies cookies, String locID) throws IOException {
super(cookies);
this.cookies = cookies;
this.locationID = locID;
setUp();
}
private void setUp() throws IOException {
public StudentAndParent setUp() throws IOException {
startPageUrl = startPageUrl.replace("{locationID}", locationID);
// get link to uonetplus-opiekun.vulcan.net.pl module
Document startPage = Jsoup.connect(startPageUrl)
.followRedirects(true)
.cookies(getJar())
.cookies(getCookies())
.get();
Element studentTileLink = startPage.select(".panel.linkownia.pracownik.klient > a").first();
uonetPlusOpiekunUrl = studentTileLink.attr("href");
@ -41,13 +38,15 @@ public class StudentAndParent extends Vulcan {
//get context module cookie
Connection.Response res = Jsoup.connect(uonetPlusOpiekunUrl)
.followRedirects(true)
.cookies(getJar())
.cookies(getCookies())
.execute();
addCookies(res.cookies());
cookies.addItems(res.cookies());
return this;
}
protected String getLocationID() {
public String getLocationID() {
return locationID;
}
@ -64,4 +63,8 @@ public class StudentAndParent extends Vulcan {
return match;
}
public String getRowDataChildValue(Element e, int index) {
return e.select(".daneWiersz .wartosc").get(index - 1).text();
}
}

View File

@ -4,25 +4,23 @@ import java.util.Map;
public abstract class Vulcan {
private Cookies cookies;
protected Cookies cookies;
public Vulcan(Cookies cookies) {
this.cookies = cookies;
}
public Map<String, String> getJar() {
return cookies.getAll();
}
public Cookies getCookies() {
public Cookies getCookiesObject() {
return cookies;
}
public void setCookies(Map<String, String> items) {
cookies.setItems(items);
public Map<String, String> getCookies() {
return cookies.getItems();
}
public void addCookies(Map<String, String> items) {
cookies.addItems(items);
public Cookies setCookies(Map<String, String> cookies) {
this.cookies.setItems(cookies);
return this.cookies;
}
public Cookies addCookies(Map<String, String> cookies) {
this.cookies.addItems(cookies);
return this.cookies;
}
}

View File

@ -13,25 +13,29 @@ import java.util.regex.Pattern;
import io.github.wulkanowy.api.Cookies;
import io.github.wulkanowy.api.StudentAndParent;
import io.github.wulkanowy.api.Vulcan;
import io.github.wulkanowy.api.login.LoginErrorException;
public class GradesList extends StudentAndParent {
public class GradesList extends Vulcan {
private StudentAndParent snp = null;
private String gradesPageUrl =
"https://uonetplus-opiekun.vulcan.net.pl/{locationID}/{ID}/Oceny/Wszystkie?details=2";
private List<Grade> grades = new ArrayList<>();
public GradesList(Cookies cookies, String locationID) throws IOException {
super(cookies, locationID);
public GradesList(Cookies cookies, StudentAndParent snp) {
this.cookies = cookies;
this.snp = snp;
}
public List<Grade> getAll() throws IOException, LoginErrorException {
gradesPageUrl = gradesPageUrl.replace("{locationID}", getLocationID());
gradesPageUrl = gradesPageUrl.replace("{ID}", getID());
gradesPageUrl = gradesPageUrl.replace("{locationID}", snp.getLocationID());
gradesPageUrl = gradesPageUrl.replace("{ID}", snp.getID());
Document marksPage = Jsoup.connect(gradesPageUrl)
.cookies(getJar())
.cookies(getCookies())
.get();
Elements marksRows = marksPage.select(".ocenySzczegoly-table > tbody > tr");

View File

@ -11,25 +11,29 @@ import java.util.List;
import io.github.wulkanowy.api.Cookies;
import io.github.wulkanowy.api.StudentAndParent;
import io.github.wulkanowy.api.Vulcan;
import io.github.wulkanowy.api.login.LoginErrorException;
public class SubjectsList extends StudentAndParent {
public class SubjectsList extends Vulcan {
private StudentAndParent snp = null;
private String subjectsPageUrl =
"https://uonetplus-opiekun.vulcan.net.pl/{locationID}/{ID}/Oceny/Wszystkie?details=1";
private List<Subject> subjects = new ArrayList<>();
public SubjectsList(Cookies cookies, String locationID) throws IOException {
super(cookies, locationID);
public SubjectsList(Cookies cookies, StudentAndParent snp) {
this.cookies = cookies;
this.snp = snp;
}
public List<Subject> getAll() throws IOException, LoginErrorException {
subjectsPageUrl = subjectsPageUrl.replace("{locationID}", getLocationID());
subjectsPageUrl = subjectsPageUrl.replace("{ID}", getID());
subjectsPageUrl = subjectsPageUrl.replace("{locationID}", snp.getLocationID());
subjectsPageUrl = subjectsPageUrl.replace("{ID}", snp.getID());
Document subjectPage = Jsoup.connect(subjectsPageUrl)
.cookies(getJar())
.cookies(getCookies())
.get();
Elements rows = subjectPage.select(".ocenyZwykle-table > tbody > tr");

View File

@ -23,7 +23,7 @@ public class Login extends Vulcan {
"https://uonetplus.vulcan.net.pl/{locationID}/LoginEndpoint.aspx";
public Login(Cookies cookies) {
super(cookies);
this.cookies = cookies;
}
public boolean login(String email, String password, String county)
@ -61,7 +61,7 @@ public class Login extends Vulcan {
certificatePageUrl = certificatePageUrl.replace("{locationID}", county);
Document certificatePage = Jsoup.connect(certificatePageUrl)
.cookies(getJar())
.cookies(getCookies())
.get();
return new String[]{
@ -77,12 +77,12 @@ public class Login extends Vulcan {
Connection.Response response = Jsoup.connect(loginEndpointPageUrl)
.data("wa", protocolVersion)
.data("wresult", certificate)
.cookies(getJar())
.cookies(getCookies())
.followRedirects(true)
.method(Connection.Method.POST)
.execute();
setCookies(response.cookies());
addCookies(response.cookies());
Document html = response.parse();
if (html.getElementsByTag("title").text().equals("Logowanie")) {

View File

@ -0,0 +1,32 @@
package io.github.wulkanowy.api.notes;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import io.github.wulkanowy.api.login.LoginErrorException;
public class AchievementsList {
private Notes notes = null;
private List<String> achievementsList = new ArrayList<>();
public AchievementsList(Notes notes) {
this.notes = notes;
}
public List<String> getAllAchievements() throws LoginErrorException, IOException {
Element pageFragment = notes.getNotesPageDocument().select(".mainContainer > div").get(1);
Elements items = pageFragment.select("article");
for (Element item : items) {
achievementsList.add(item.text());
}
return achievementsList;
}
}

View File

@ -0,0 +1,48 @@
package io.github.wulkanowy.api.notes;
public class Note {
private String date;
private String teacher;
private String category;
private String content;
public String getDate() {
return date;
}
public Note setDate(String date) {
this.date = date;
return this;
}
public String getTeacher() {
return teacher;
}
public Note setTeacher(String teacher) {
this.teacher = teacher;
return this;
}
public String getCategory() {
return category;
}
public Note setCategory(String category) {
this.category = category;
return this;
}
public String getContent() {
return content;
}
public Note setContent(String content) {
this.content = content;
return this;
}
}

View File

@ -0,0 +1,33 @@
package io.github.wulkanowy.api.notes;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.IOException;
import io.github.wulkanowy.api.Cookies;
import io.github.wulkanowy.api.StudentAndParent;
import io.github.wulkanowy.api.Vulcan;
import io.github.wulkanowy.api.login.LoginErrorException;
public class Notes extends Vulcan {
private StudentAndParent snp = null;
private String notesPageUrl =
"https://uonetplus-opiekun.vulcan.net.pl/{locationID}/{ID}/UwagiOsiagniecia.mvc/Wszystkie";
public Notes(Cookies cookies, StudentAndParent snp) {
this.cookies = cookies;
this.snp = snp;
}
public Document getNotesPageDocument() throws IOException, LoginErrorException {
notesPageUrl = notesPageUrl.replace("{locationID}", snp.getLocationID());
notesPageUrl = notesPageUrl.replace("{ID}", snp.getID());
return Jsoup.connect(notesPageUrl)
.cookies(getCookies())
.get();
}
}

View File

@ -0,0 +1,42 @@
package io.github.wulkanowy.api.notes;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import io.github.wulkanowy.api.StudentAndParent;
import io.github.wulkanowy.api.login.LoginErrorException;
public class NotesList {
private Notes notes = null;
private StudentAndParent snp = null;
private List<Note> notesList = new ArrayList<>();
public NotesList(Notes notes, StudentAndParent snp) {
this.notes = notes;
this.snp = snp;
}
public List<Note> getAllNotes() throws LoginErrorException, IOException {
Element pageFragment = notes.getNotesPageDocument().select(".mainContainer > div").get(0);
Elements items = pageFragment.select("article");
Elements dates = pageFragment.select("h2");
int index = 0;
for (Element item : items) {
notesList.add(new Note()
.setDate(dates.get(index++).text())
.setTeacher(snp.getRowDataChildValue(item, 1))
.setCategory(snp.getRowDataChildValue(item, 2))
.setContent(snp.getRowDataChildValue(item, 3))
);
}
return notesList;
}
}

View File

@ -1,62 +1,46 @@
package io.github.wulkanowy.api.user;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import java.io.IOException;
import io.github.wulkanowy.api.Cookies;
import io.github.wulkanowy.api.StudentAndParent;
import io.github.wulkanowy.api.login.LoginErrorException;
public class BasicInformation extends StudentAndParent {
public class BasicInformation {
private String studentDataPageUrl =
"https://uonetplus-opiekun.vulcan.net.pl/{locationID}/{ID}/Uczen.mvc/DanePodstawowe";
private StudentAndParent snp = null;
private Document studentDataPageDocument;
public BasicInformation(Cookies cookies, String locationID)
public BasicInformation(User user, StudentAndParent snp)
throws IOException, LoginErrorException {
super(cookies, locationID);
this.snp = snp;
studentDataPageDocument = getPage();
}
private Document getPage() throws IOException, LoginErrorException {
studentDataPageUrl = studentDataPageUrl.replace("{locationID}", getLocationID());
studentDataPageUrl = studentDataPageUrl.replace("{ID}", getID());
return Jsoup.connect(studentDataPageUrl)
.cookies(getJar())
.get();
}
private String getRowDataChildValue(Element e, int index) {
return e.select(".daneWiersz .wartosc").get(index - 1).text();
studentDataPageDocument = user.getPage();
}
public PersonalData getPersonalData() {
Element e = studentDataPageDocument.select(".mainContainer > article").get(0);
return new PersonalData()
.setNames(getRowDataChildValue(e, 1))
.setDateAndBirthPlace(getRowDataChildValue(e, 2))
.setPesel(getRowDataChildValue(e, 3))
.setGender(getRowDataChildValue(e, 4))
.setPolishCitizenship(getRowDataChildValue(e, 5))
.setFamilyName(getRowDataChildValue(e, 6))
.setParentsNames(getRowDataChildValue(e, 7));
.setNames(snp.getRowDataChildValue(e, 1))
.setDateAndBirthPlace(snp.getRowDataChildValue(e, 2))
.setPesel(snp.getRowDataChildValue(e, 3))
.setGender(snp.getRowDataChildValue(e, 4))
.setPolishCitizenship(snp.getRowDataChildValue(e, 5))
.setFamilyName(snp.getRowDataChildValue(e, 6))
.setParentsNames(snp.getRowDataChildValue(e, 7));
}
public AddressData getAddresData() {
Element e = studentDataPageDocument.select(".mainContainer > article").get(1);
return new AddressData()
.setAddress(getRowDataChildValue(e, 1))
.setRegisteredAddress(getRowDataChildValue(e, 2))
.setCorrespondenceAddress(getRowDataChildValue(e, 3));
.setAddress(snp.getRowDataChildValue(e, 1))
.setRegisteredAddress(snp.getRowDataChildValue(e, 2))
.setCorrespondenceAddress(snp.getRowDataChildValue(e, 3));
}
@ -64,8 +48,8 @@ public class BasicInformation extends StudentAndParent {
Element e = studentDataPageDocument.select(".mainContainer > article").get(2);
return new ContactDetails()
.setPhoneNumber(getRowDataChildValue(e, 1))
.setCellPhoneNumber(getRowDataChildValue(e, 2))
.setEmail(getRowDataChildValue(e, 3));
.setPhoneNumber(snp.getRowDataChildValue(e, 1))
.setCellPhoneNumber(snp.getRowDataChildValue(e, 2))
.setEmail(snp.getRowDataChildValue(e, 3));
}
}

View File

@ -0,0 +1,33 @@
package io.github.wulkanowy.api.user;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.IOException;
import io.github.wulkanowy.api.Cookies;
import io.github.wulkanowy.api.StudentAndParent;
import io.github.wulkanowy.api.Vulcan;
import io.github.wulkanowy.api.login.LoginErrorException;
public class User extends Vulcan {
private StudentAndParent snp = null;
private String studentDataPageUrl =
"https://uonetplus-opiekun.vulcan.net.pl/{locationID}/{ID}/Uczen.mvc/DanePodstawowe";
public User(Cookies cookies, StudentAndParent snp) {
this.cookies = cookies;
this.snp = snp;
}
public Document getPage() throws IOException, LoginErrorException {
studentDataPageUrl = studentDataPageUrl.replace("{locationID}", snp.getLocationID());
studentDataPageUrl = studentDataPageUrl.replace("{ID}", snp.getID());
return Jsoup.connect(studentDataPageUrl)
.cookies(getCookies())
.get();
}
}

View File

@ -0,0 +1,14 @@
package io.github.wulkanowy.api;
import java.io.InputStream;
import java.util.Scanner;
public class FixtureHelper {
public static String getAsString(InputStream inputStream) {
Scanner s = new Scanner(inputStream).useDelimiter("\\A");
String input = s.hasNext() ? s.next() : "";
return input;
}
}

View File

@ -0,0 +1,55 @@
package io.github.wulkanowy.api.notes;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito;
import org.unitils.reflectionassert.ReflectionAssert;
import java.util.ArrayList;
import java.util.List;
import io.github.wulkanowy.api.FixtureHelper;
public class AchievementsListTest {
private String fixtureFilledFileName = "UwagiOsiagniecia-filled.html";
private String fixtureEmptyFileName = "UwagiOsiagniecia-empty.html";
private AchievementsList getSetUpAchievementsList(String fixtureFileName) throws Exception {
String input = FixtureHelper.getAsString(getClass().getResourceAsStream(fixtureFileName));
Document notesPageDocument = Jsoup.parse(input);
Notes notes = Mockito.mock(Notes.class);
Mockito.when(notes.getNotesPageDocument()).thenReturn(notesPageDocument);
return new AchievementsList(notes);
}
@Test
public void getAllAchievementsFilledTest() throws Exception {
List<String> expectedList = new ArrayList<>();
expectedList.add("I miejsce w ogólnopolskim konkursie ortograficznym");
expectedList.add("III miejsce w ogólnopolskim konkursie plastycznym");
List<String> actualList = getSetUpAchievementsList(
fixtureFilledFileName).getAllAchievements();
Assert.assertEquals(2, actualList.size());
ReflectionAssert.assertReflectionEquals(expectedList, actualList);
}
@Test
public void getAllAchievementsEmptyTest() throws Exception {
List<String> expectedList = new ArrayList<>();
List<String> actualList = getSetUpAchievementsList(
fixtureEmptyFileName).getAllAchievements();
Assert.assertEquals(0, actualList.size());
ReflectionAssert.assertReflectionEquals(expectedList, actualList);
}
}

View File

@ -0,0 +1,74 @@
package io.github.wulkanowy.api.notes;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito;
import org.unitils.reflectionassert.ReflectionAssert;
import java.util.ArrayList;
import java.util.List;
import io.github.wulkanowy.api.FixtureHelper;
import io.github.wulkanowy.api.StudentAndParent;
public class NotesListTest {
private String fixtureFilledFileName = "UwagiOsiagniecia-filled.html";
private String fixtureEmptyFileName = "UwagiOsiagniecia-empty.html";
private NotesList getSetUpNotesList(String fixtureFileName) throws Exception {
String input = FixtureHelper.getAsString(getClass().getResourceAsStream(fixtureFileName));
Document notesPageDocument = Jsoup.parse(input);
Notes notes = Mockito.mock(Notes.class);
Mockito.when(notes.getNotesPageDocument()).thenReturn(notesPageDocument);
StudentAndParent snp = Mockito.mock(StudentAndParent.class);
Mockito.when(snp.getRowDataChildValue(Mockito.any(Element.class),
Mockito.anyInt())).thenCallRealMethod();
return new NotesList(notes, snp);
}
@Test
public void getAllNotesFilledTest() throws Exception {
List<Note> expectedList = new ArrayList<>();
expectedList.add(new Note()
.setDate("06.06.2017")
.setTeacher("Jan Kowalski [JK]")
.setCategory("Zaangażowanie społeczne")
.setContent("Pomoc przy pikniku charytatywnym")
);
expectedList.add(new Note()
.setDate("01.12.2016")
.setTeacher("Ochocka Zofia [PZ]")
.setCategory("Reprezentowanie szkoły")
.setContent("Udział w przygotowaniu spektaklu")
);
expectedList.add(new Note()
.setDate("01.10.2016")
.setTeacher("Kochański Leszek [KL]")
.setCategory("Zachowanie na lekcji")
.setContent("Przeszkadzanie w prowadzeniu lekcji")
);
List<Note> actualList = getSetUpNotesList(fixtureFilledFileName).getAllNotes();
Assert.assertEquals(3, actualList.size());
ReflectionAssert.assertReflectionEquals(expectedList, actualList);
}
@Test
public void getAllNotesWhenEmpty() throws Exception {
List<Note> actualList = getSetUpNotesList(fixtureEmptyFileName).getAllNotes();
List<Note> expectedList = new ArrayList<>();
Assert.assertEquals(0, actualList.size());
ReflectionAssert.assertReflectionEquals(expectedList, actualList);
}
}

View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="utf-8">
<title>Witryna ucznia i rodzica Uwagi i osiągnięcia</title>
</head>
<body>
<main class="mainContainer">
<div>
<h1>Uwagi</h1>
<h2>Brak informacji do wyświetlenia</h2>
</div>
<div>
<h1>Osiągnięcia</h1>
<h2>Brak informacji do wyświetlenia</h2>
</div>
</main>
<footer>wersja: 17.05.0000.24042</footer>
</body>
</html>

View File

@ -0,0 +1,65 @@
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="utf-8">
<title>Witryna ucznia i rodzica Uwagi i osiągnięcia</title>
</head>
<body>
<main class="mainContainer">
<div>
<h1>Uwagi</h1>
<h2>06.06.2017</h2>
<article>
<div class="daneWiersz">
<div class="tytul">Nauczyciel:</div>
<div class="wartosc">Jan Kowalski [JK]</div>
</div>
<div class="daneWiersz">
<div class="tytul">Kategoria:</div>
<div class="wartosc">Zaangażowanie społeczne</div>
</div>
<div class="daneWiersz">
<div class="tytul">Treść:</div>
<div class="wartosc">Pomoc przy pikniku charytatywnym</div>
</div>
</article>
<h2>01.12.2016</h2>
<article>
<div class="daneWiersz">
<div class="tytul">Nauczyciel:</div>
<div class="wartosc">Ochocka Zofia [PZ]</div>
</div>
<div class="daneWiersz">
<div class="tytul">Kategoria:</div>
<div class="wartosc">Reprezentowanie szkoły</div>
</div>
<div class="daneWiersz">
<div class="tytul">Treść:</div>
<div class="wartosc">Udział w przygotowaniu spektaklu</div>
</div>
</article>
<h2>01.10.2016</h2>
<article>
<div class="daneWiersz">
<div class="tytul">Nauczyciel:</div>
<div class="wartosc">Kochański Leszek [KL]</div>
</div>
<div class="daneWiersz">
<div class="tytul">Kategoria:</div>
<div class="wartosc">Zachowanie na lekcji</div>
</div>
<div class="daneWiersz">
<div class="tytul">Treść:</div>
<div class="wartosc">Przeszkadzanie w prowadzeniu lekcji</div>
</div>
</article>
</div>
<div>
<h1>Osiągnięcia</h1>
<article>I miejsce w ogólnopolskim konkursie ortograficznym</article>
<article>III miejsce w ogólnopolskim konkursie plastycznym</article>
</div>
</main>
<footer>wersja: 17.05.0000.24042</footer>
</body>
</html>