Compare commits
No commits in common. "master" and "Projekt-1" have entirely different histories.
|
@ -0,0 +1,38 @@
|
|||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea/modules.xml
|
||||
.idea/jarRepositories.xml
|
||||
.idea/compiler.xml
|
||||
.idea/libraries/
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### Eclipse ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
|
||||
### Mac OS ###
|
||||
.DS_Store
|
|
@ -0,0 +1,8 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding">
|
||||
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,67 @@
|
|||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="AutoCloseableResource" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="METHOD_MATCHER_CONFIG" value="java.util.Formatter,format,java.io.Writer,append,com.google.common.base.Preconditions,checkNotNull,org.hibernate.Session,close,java.io.PrintWriter,printf,java.io.PrintStream,printf,org.apache.http.impl.client.HttpClients,createDefault,org.mockito.Mockito,mockStatic" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PyCompatibilityInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="ourVersions">
|
||||
<value>
|
||||
<list size="7">
|
||||
<item index="0" class="java.lang.String" itemvalue="3.7" />
|
||||
<item index="1" class="java.lang.String" itemvalue="3.8" />
|
||||
<item index="2" class="java.lang.String" itemvalue="3.9" />
|
||||
<item index="3" class="java.lang.String" itemvalue="3.10" />
|
||||
<item index="4" class="java.lang.String" itemvalue="3.11" />
|
||||
<item index="5" class="java.lang.String" itemvalue="3.10" />
|
||||
<item index="6" class="java.lang.String" itemvalue="3.11" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="ignoredPackages">
|
||||
<value>
|
||||
<list size="24">
|
||||
<item index="0" class="java.lang.String" itemvalue="httpx" />
|
||||
<item index="1" class="java.lang.String" itemvalue="six" />
|
||||
<item index="2" class="java.lang.String" itemvalue="python-dateutil" />
|
||||
<item index="3" class="java.lang.String" itemvalue="aiofiles" />
|
||||
<item index="4" class="java.lang.String" itemvalue="h11" />
|
||||
<item index="5" class="java.lang.String" itemvalue="MarkupSafe" />
|
||||
<item index="6" class="java.lang.String" itemvalue="numpy" />
|
||||
<item index="7" class="java.lang.String" itemvalue="rfc3986" />
|
||||
<item index="8" class="java.lang.String" itemvalue="click" />
|
||||
<item index="9" class="java.lang.String" itemvalue="Jinja2" />
|
||||
<item index="10" class="java.lang.String" itemvalue="sniffio" />
|
||||
<item index="11" class="java.lang.String" itemvalue="demjson" />
|
||||
<item index="12" class="java.lang.String" itemvalue="addict" />
|
||||
<item index="13" class="java.lang.String" itemvalue="pandas" />
|
||||
<item index="14" class="java.lang.String" itemvalue="starlette" />
|
||||
<item index="15" class="java.lang.String" itemvalue="certifi" />
|
||||
<item index="16" class="java.lang.String" itemvalue="pytz" />
|
||||
<item index="17" class="java.lang.String" itemvalue="uvicorn" />
|
||||
<item index="18" class="java.lang.String" itemvalue="itsdangerous" />
|
||||
<item index="19" class="java.lang.String" itemvalue="justpy" />
|
||||
<item index="20" class="java.lang.String" itemvalue="websockets" />
|
||||
<item index="21" class="java.lang.String" itemvalue="httpcore" />
|
||||
<item index="22" class="java.lang.String" itemvalue="idna" />
|
||||
<item index="23" class="java.lang.String" itemvalue="psycopg2" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PyUnresolvedReferencesInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="ignoredIdentifiers">
|
||||
<list>
|
||||
<option value="blog.models.Post.objects" />
|
||||
<option value="reviews.models.Review.objects" />
|
||||
<option value="django.db.models.fields.related.OneToOneField.email" />
|
||||
<option value="accounts.models.UserProfile.objects" />
|
||||
<option value="accounts.models.User.DoesNotExist" />
|
||||
<option value="vendor.models.Vendor.objects" />
|
||||
</list>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="MavenProjectsManager">
|
||||
<option name="originalFiles">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/pom.xml" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,124 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Palette2">
|
||||
<group name="Swing">
|
||||
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
|
||||
</item>
|
||||
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
|
||||
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
|
||||
<initial-values>
|
||||
<property name="text" value="Button" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="RadioButton" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="CheckBox" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="Label" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
|
||||
<preferred-size width="-1" height="20" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
|
||||
</item>
|
||||
</group>
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
Binary file not shown.
23
README.md
23
README.md
|
@ -1,5 +1,20 @@
|
|||
# Projekty z Pracowni Programowania
|
||||
# Projekt na Pracownię Programowania
|
||||
____
|
||||
## Działanie:
|
||||
1. Po uruchomieniu programu, w konsoli należy podać nazwę miasta, którego pogodę chcemy sprawdzić. Wielkość liter ma znaczenie.
|
||||
2. Lista obsługiwanych miast znajduje się w pliku `cities.json`.
|
||||
3. Aby dodać nowe miasto, należy do `cities.json` dopisać:
|
||||
```
|
||||
"<nazwa_miasta>": {
|
||||
"lat": <szerokość_geograficzna>,
|
||||
"lon": <długość_geograficzna>
|
||||
}
|
||||
```
|
||||
4. Po zakończeniu korzystania z programu, istnieje możliwośc zapisania wyników do pliku *json*, *xml* lub *pdf*.
|
||||
Zapisane wyniki znajdują się w folderze `src/weather-results`.
|
||||
|
||||
## Projekt I - Testowanie + Strumienie + JSON/XML
|
||||
|
||||
## Projekt II - Hibernate
|
||||
## Lista klas i ich działanie:
|
||||
- **Coordinates** - rekord przechowujący dwie dane: szerokość i długość geograficzną
|
||||
- **WeatherEntry** - klasa ułatwiająca przechowywanie danych otrzymanych w odpowiedzi API
|
||||
- **WeatherJsonParser** - klasa pomagająca w serializacji i deserializacji
|
||||
- **WeatherResponse** - klasa odpowiedzialna za wysyłanie zapytań do API i przechowywanie informacji o odpowiedzi
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"Warszawa": {
|
||||
"lat": 52.237049,
|
||||
"lon": 21.017532
|
||||
},
|
||||
"Berlin": {
|
||||
"lat": 52.520008,
|
||||
"lon": 13.404954
|
||||
},
|
||||
"Paryz": {
|
||||
"lat": 48.8566,
|
||||
"lon": 2.3522
|
||||
},
|
||||
"Waszyngton": {
|
||||
"lat": 38.8951,
|
||||
"lon": -77.0364
|
||||
},
|
||||
"Tokio": {
|
||||
"lat": 35.6895,
|
||||
"lon": 139.6917
|
||||
},
|
||||
"Kair": {
|
||||
"lat": 30.0444,
|
||||
"lon": 31.2357
|
||||
},
|
||||
"Nowy Jork": {
|
||||
"lat": 40.7128,
|
||||
"lon": -74.0060
|
||||
},
|
||||
"Test": {
|
||||
"lat": 100.0000,
|
||||
"lon": 190.0000
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.example</groupId>
|
||||
<artifactId>PRA2024</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.16.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-xml -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||
<artifactId>jackson-dataformat-xml</artifactId>
|
||||
<version>2.16.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>4.5.10</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.pdfbox</groupId>
|
||||
<artifactId>pdfbox</artifactId>
|
||||
<version>2.0.29</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.mockito/mockito-core -->
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>5.8.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>5.10.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,3 @@
|
|||
package org.mikgul;
|
||||
|
||||
public record Coordinates(double latitude, double longitude) { }
|
|
@ -0,0 +1,74 @@
|
|||
package org.mikgul;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.InvalidParameterException;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) throws IOException {
|
||||
WeatherJsonParser parser = new WeatherJsonParser();
|
||||
Map<String, Coordinates> cities;
|
||||
try {
|
||||
cities = parser.prepareCities();
|
||||
} catch (IOException e) {
|
||||
System.out.println("Blad przy wczytywaniu danych z `cities.json`: " + e);
|
||||
return;
|
||||
}
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
|
||||
while (true) {
|
||||
System.out.print("Podaj nazwe miasta (q - wyjscie):\n>> ");
|
||||
String cityName = scanner.nextLine();
|
||||
|
||||
// uzytkownik chce wyjsc z programu
|
||||
if ("q".equalsIgnoreCase(cityName)) {
|
||||
if (WeatherEntry.noEntries()) break;
|
||||
|
||||
System.out.print("Podaj format do zapisu - pdf/json/xml (q - wyjscie bez zapisu):\n>> ");
|
||||
String format = scanner.nextLine().toLowerCase();
|
||||
try {
|
||||
switch (format) {
|
||||
case "json":
|
||||
WeatherEntry.saveToJson();
|
||||
System.out.println("Zapisano w JSON.");
|
||||
break;
|
||||
case "xml":
|
||||
WeatherEntry.saveToXml();
|
||||
System.out.println("Zapisano w XML.");
|
||||
break;
|
||||
case "pdf":
|
||||
WeatherEntry.saveToPdf();
|
||||
System.out.println("Zapisano w PDF.");
|
||||
break;
|
||||
case "q":
|
||||
System.out.println("Nie zapisano w zadnym pliku.");
|
||||
break;
|
||||
default:
|
||||
System.out.println("Nieprawidlowy format.");
|
||||
continue;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
System.out.println("Blad podczas zapisu do pliku: " + e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// uzytkownik chce otrzymac dane o podanym miescie
|
||||
Coordinates coordinates = cities.get(cityName);
|
||||
if (coordinates != null) {
|
||||
WeatherResponse res = new WeatherResponse();
|
||||
WeatherEntry entry;
|
||||
try {
|
||||
entry = parser.parseWeatherData(cityName, res.sendWeatherRequest(coordinates));
|
||||
} catch(InvalidParameterException e) {
|
||||
System.out.println("Parsowanie zapytania nie powiodlo sie: " + e + "\n");
|
||||
continue;
|
||||
}
|
||||
System.out.println(entry);
|
||||
} else {
|
||||
System.out.println("Podane miasto nie jest obslugiwane (sprawdz plik `cities.json`).\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
package org.mikgul;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDPage;
|
||||
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||
import org.apache.pdfbox.pdmodel.font.PDFont;
|
||||
import org.apache.pdfbox.pdmodel.font.PDType0Font;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class WeatherEntry {
|
||||
private static final List<WeatherEntry> allEntries = new ArrayList<>();
|
||||
private final String miasto;
|
||||
private final String pogoda;
|
||||
private final double temperatura;
|
||||
private final int cisnienie;
|
||||
private final int wilgotnosc;
|
||||
|
||||
public WeatherEntry(String city, String description, double temperature, int pressure, int humidity) {
|
||||
this.miasto = city;
|
||||
this.pogoda = description;
|
||||
this.temperatura = temperature;
|
||||
this.cisnienie = pressure;
|
||||
this.wilgotnosc = humidity;
|
||||
allEntries.add(this);
|
||||
}
|
||||
|
||||
public static void saveToJson() throws IOException {
|
||||
File jsonFile = new File(generateFileName(".json"));
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.writeValue(jsonFile, allEntries);
|
||||
}
|
||||
|
||||
public static void saveToXml() throws IOException {
|
||||
File xmlFile = new File(generateFileName(".xml"));
|
||||
XmlMapper mapper = new XmlMapper();
|
||||
mapper.writeValue(xmlFile, allEntries);
|
||||
}
|
||||
|
||||
public static void saveToPdf() throws IOException {
|
||||
// zapis do txt
|
||||
String txtFile = "src/weather-results/temp/temp.txt";
|
||||
|
||||
Path parentFolderPath = Paths.get("src/weather-results/temp");
|
||||
File folder = parentFolderPath.toFile();
|
||||
if (!folder.exists()) {
|
||||
try {
|
||||
Files.createDirectories(parentFolderPath);
|
||||
} catch (IOException e) {
|
||||
System.out.println("Brak folderu `src/weather-results/temp`. Tworzenie folderu nie powiodlo sie.");
|
||||
}
|
||||
}
|
||||
|
||||
try (FileWriter writer = new FileWriter(txtFile)) {
|
||||
for (WeatherEntry entry : allEntries) {
|
||||
writer.write(entry.toString() + System.lineSeparator());
|
||||
}
|
||||
}
|
||||
|
||||
// konwersja na pdf
|
||||
PDDocument document = new PDDocument();
|
||||
PDPage page = new PDPage();
|
||||
|
||||
document.addPage(page);
|
||||
|
||||
try (PDPageContentStream contentStream = new PDPageContentStream(document, page)) {
|
||||
List<String> lines = Files.readAllLines(Paths.get(txtFile));
|
||||
|
||||
PDFont font = PDType0Font.load(document, new File("AbhayaLibre-Regular.ttf"));
|
||||
int yPosition = 700;
|
||||
for (String line : lines) {
|
||||
contentStream.beginText();
|
||||
contentStream.setFont(font, 14);
|
||||
contentStream.newLineAtOffset(100, yPosition);
|
||||
contentStream.showText(line);
|
||||
contentStream.endText();
|
||||
yPosition -= 20;
|
||||
}
|
||||
|
||||
}
|
||||
document.save(generateFileName(".pdf"));
|
||||
document.close();
|
||||
}
|
||||
|
||||
private static String generateFileName(String format) {
|
||||
String directoryPath = "src/weather-results/";
|
||||
String baseFileName = "weather-session-";
|
||||
|
||||
File directory = new File(directoryPath);
|
||||
|
||||
int i = 1;
|
||||
while (true) {
|
||||
String newFileName = baseFileName + i + format;
|
||||
|
||||
File newFile = new File(directory, newFileName);
|
||||
if (!newFile.exists()) {
|
||||
return directoryPath + newFileName;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return String.format("Pogoda w %s:\n%s, temperatura: %.2f C; ciśnienie: %d hPa; wilgotność: %d%%\n",
|
||||
miasto, pogoda, temperatura, cisnienie, wilgotnosc);
|
||||
}
|
||||
|
||||
public static boolean noEntries() {
|
||||
return allEntries.isEmpty();
|
||||
}
|
||||
|
||||
public String getMiasto() {
|
||||
return miasto;
|
||||
}
|
||||
|
||||
public String getPogoda() {
|
||||
return pogoda;
|
||||
}
|
||||
|
||||
public double getTemperatura() {
|
||||
return temperatura;
|
||||
}
|
||||
|
||||
public int getCisnienie() {
|
||||
return cisnienie;
|
||||
}
|
||||
|
||||
public int getWilgotnosc() {
|
||||
return wilgotnosc;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package org.mikgul;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.security.InvalidParameterException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Spliterator;
|
||||
import java.util.Spliterators;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
|
||||
public class WeatherJsonParser {
|
||||
public WeatherJsonParser() {}
|
||||
|
||||
public WeatherEntry parseWeatherData(String cityName, WeatherResponse response) throws IOException {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
JsonNode rootNode = objectMapper.readTree(response.getBody());
|
||||
|
||||
if (response.getStatusCode() != 200){
|
||||
throw new InvalidParameterException(
|
||||
rootNode.get("cod").asText()
|
||||
+ " - "
|
||||
+ rootNode.get("message").asText()
|
||||
);
|
||||
}
|
||||
|
||||
String desc = rootNode.get("weather").get(0).get("description").asText();
|
||||
double temp = rootNode.get("main").get("temp").asDouble();
|
||||
int press = rootNode.get("main").get("pressure").asInt();
|
||||
int hum = rootNode.get("main").get("humidity").asInt();
|
||||
|
||||
return new WeatherEntry(cityName, desc, temp, press, hum);
|
||||
}
|
||||
|
||||
public Map<String, Coordinates> prepareCities() throws IOException {
|
||||
File jsonFile = new File("cities.json");
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
JsonNode rootNode = objectMapper.readTree(jsonFile);
|
||||
|
||||
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(rootNode.fields(), Spliterator.ORDERED), false)
|
||||
.collect(Collectors.toMap(
|
||||
Map.Entry::getKey,
|
||||
entry -> new Coordinates(
|
||||
entry.getValue().get("lat").asDouble(),
|
||||
entry.getValue().get("lon").asDouble()
|
||||
),
|
||||
(existing, replacement) -> existing,
|
||||
HashMap::new
|
||||
));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package org.mikgul;
|
||||
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class WeatherResponse {
|
||||
private static final String API_KEY = "c1a110184e10999b88cc360d8580ef57";
|
||||
private static final String API_URL = "https://api.openweathermap.org/data/2.5/weather";
|
||||
|
||||
private int statusCode;
|
||||
private String responseBody;
|
||||
|
||||
public WeatherResponse() {}
|
||||
|
||||
public int getStatusCode() {
|
||||
return statusCode;
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
return responseBody;
|
||||
}
|
||||
|
||||
public void setStatusCode(int statusCode) {
|
||||
this.statusCode = statusCode;
|
||||
}
|
||||
|
||||
public void setResponseBody(String responseBody) {
|
||||
this.responseBody = responseBody;
|
||||
}
|
||||
|
||||
public WeatherResponse sendWeatherRequest(Coordinates coordinates) {
|
||||
String apiUrl = String.format("%s?lat=%s&lon=%s&appid=%s&lang=pl&units=metric",
|
||||
API_URL, coordinates.latitude(), coordinates.longitude(), API_KEY);
|
||||
|
||||
try (CloseableHttpClient httpclient = HttpClients.createDefault()) {
|
||||
HttpGet request = new HttpGet(apiUrl);
|
||||
try (CloseableHttpResponse response = httpclient.execute(request)) {
|
||||
HttpEntity entity = response.getEntity();
|
||||
setStatusCode(response.getStatusLine().getStatusCode());
|
||||
setResponseBody(EntityUtils.toString(entity));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Blad przy wysylaniu zapytania do API: ", e);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
import org.junit.jupiter.api.Test;
|
||||
import org.mikgul.Coordinates;
|
||||
import org.mikgul.WeatherEntry;
|
||||
import org.mikgul.WeatherJsonParser;
|
||||
import org.mikgul.WeatherResponse;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
|
||||
class WeatherAppTest {
|
||||
private boolean checkLongitude(double longitude) {
|
||||
return longitude <= 180.00 && longitude >= -180.00;
|
||||
}
|
||||
|
||||
private boolean checkLatitude(double latitude) {
|
||||
return latitude <= 90.00 && latitude >= -90.00;
|
||||
}
|
||||
|
||||
private WeatherResponse goodResponse(String body) {
|
||||
WeatherResponse res = new WeatherResponse();
|
||||
res.setStatusCode(200);
|
||||
res.setResponseBody(body);
|
||||
return res;
|
||||
}
|
||||
|
||||
private WeatherResponse badResponse(String message) {
|
||||
WeatherResponse res = new WeatherResponse();
|
||||
res.setStatusCode(400);
|
||||
res.setResponseBody(message);
|
||||
return res;
|
||||
}
|
||||
|
||||
// ********** TESTY Z POZYTYWNYM SCENARIUSZEM **********
|
||||
|
||||
@Test
|
||||
void testWeatherRequestWithGoodCoordinates() throws IOException {
|
||||
Coordinates goodCords = new Coordinates(40.7128, -74.0060);
|
||||
|
||||
assertTrue(checkLongitude(goodCords.longitude()));
|
||||
assertTrue(checkLatitude(goodCords.latitude()));
|
||||
|
||||
String sampleBody = "{\"weather\":[{\"description\":\"pochmurnie\"}],\"main\":{\"temp\":25.5,\"feels_like\":25.31,\"temp_min\":19.58,\"temp_max\":28.12,\"pressure\":1015,\"humidity\":50}}";
|
||||
WeatherResponse mockResponse = mock(WeatherResponse.class);
|
||||
when(mockResponse.sendWeatherRequest(any()))
|
||||
.thenReturn(goodResponse(sampleBody));
|
||||
|
||||
WeatherResponse realResponse = mockResponse.sendWeatherRequest(goodCords);
|
||||
|
||||
assertEquals(200, realResponse.getStatusCode());
|
||||
|
||||
WeatherJsonParser parser = new WeatherJsonParser();
|
||||
WeatherEntry result = parser.parseWeatherData("Nowy Jork", realResponse);
|
||||
|
||||
assertEquals("Nowy Jork", result.getMiasto());
|
||||
assertEquals("pochmurnie", result.getPogoda());
|
||||
assertEquals(25.5, result.getTemperatura());
|
||||
assertEquals(1015, result.getCisnienie());
|
||||
assertEquals(50, result.getWilgotnosc());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testWeatherRequestParsing() throws IOException {
|
||||
// zakladamy ze zapytanie bylo poprawne a odpowiedz pozytywna, wiec nie sprawdzamy ich 'assertami'
|
||||
Coordinates cords = new Coordinates(35.6895, 139.6917);
|
||||
|
||||
String sampleBody = "{\"weather\":[{\"description\":\"słonecznie\"}],\"main\":{\"temp\":13.5,\"feels_like\":11.21,\"temp_min\":10.58,\"temp_max\":16.12,\"pressure\":1022,\"humidity\":23}}";
|
||||
WeatherResponse mockResponse = mock(WeatherResponse.class);
|
||||
when(mockResponse.sendWeatherRequest(any()))
|
||||
.thenReturn(goodResponse(sampleBody));
|
||||
|
||||
WeatherJsonParser parser = new WeatherJsonParser();
|
||||
WeatherEntry result = parser.parseWeatherData("Tokio", mockResponse.sendWeatherRequest(cords));
|
||||
|
||||
assertEquals("Tokio", result.getMiasto());
|
||||
assertEquals("słonecznie", result.getPogoda());
|
||||
assertEquals(13.5, result.getTemperatura());
|
||||
assertEquals(1022, result.getCisnienie());
|
||||
assertEquals(23, result.getWilgotnosc());
|
||||
|
||||
assertEquals("Pogoda w Tokio:\nsłonecznie, temperatura: 13,50 C; cisnienie: 1022 hPa; wilgotnosc: 23%\n",
|
||||
result.toString());
|
||||
}
|
||||
|
||||
// ********** TESTY Z NEGATYWNYM SCENARIUSZEM **********
|
||||
|
||||
@Test
|
||||
void testWeatherRequestWithBadLongitude() {
|
||||
Coordinates badCords = new Coordinates(40.7128, -192.0060);
|
||||
|
||||
assertFalse(checkLongitude(badCords.longitude()));
|
||||
assertTrue(checkLatitude(badCords.latitude()));
|
||||
|
||||
String message = "{\"cod\":\"400\",\"message\":\"wrong longitude\"}";
|
||||
WeatherResponse mockResponse = mock(WeatherResponse.class);
|
||||
when(mockResponse.sendWeatherRequest(any()))
|
||||
.thenReturn(badResponse(message));
|
||||
|
||||
WeatherResponse realResponse = mockResponse.sendWeatherRequest(badCords);
|
||||
|
||||
assertEquals(400, realResponse.getStatusCode());
|
||||
assertEquals("{\"cod\":\"400\",\"message\":\"wrong longitude\"}", realResponse.getBody());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testWeatherRequestWithBadLatitude() {
|
||||
Coordinates badCords = new Coordinates(90.7128, -74.0060);
|
||||
|
||||
assertTrue(checkLongitude(badCords.longitude()));
|
||||
assertFalse(checkLatitude(badCords.latitude()));
|
||||
|
||||
String message = "{\"cod\":\"400\",\"message\":\"wrong latitude\"}";
|
||||
WeatherResponse mockResponse = mock(WeatherResponse.class);
|
||||
when(mockResponse.sendWeatherRequest(any()))
|
||||
.thenReturn(badResponse(message));
|
||||
|
||||
WeatherResponse realResponse = mockResponse.sendWeatherRequest(badCords);
|
||||
|
||||
assertEquals(400, realResponse.getStatusCode());
|
||||
assertEquals("{\"cod\":\"400\",\"message\":\"wrong latitude\"}", realResponse.getBody());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue