mirror of
https://github.com/IgorTimofeev/MineOS.git
synced 2025-12-20 11:09:21 +01:00
304 lines
11 KiB
Lua
Executable File
304 lines
11 KiB
Lua
Executable File
|
||
---------------------------------------------------- Библиотеки ----------------------------------------------------------------
|
||
|
||
require("advancedLua")
|
||
local json = require("json")
|
||
local serialization = require("serialization")
|
||
local event = require("event")
|
||
local ecs = require("ECSAPI")
|
||
local fs = require("filesystem")
|
||
local bigLetters = require("bigLetters")
|
||
local buffer = require("doubleBuffering")
|
||
local image = require("image")
|
||
local unicode = require("unicode")
|
||
local component = require("component")
|
||
local GUI = require("GUI")
|
||
local MineOSCore = require("MineOSCore")
|
||
local MineOSPaths = require("MineOSPaths")
|
||
|
||
---------------------------------------------------- Константы ----------------------------------------------------------------
|
||
|
||
local weather = {}
|
||
local changeCityButton = {}
|
||
local exitButton = {}
|
||
|
||
local resources = MineOSCore.getCurrentApplicationResourcesDirectory()
|
||
local pathToWeatherFile = MineOSPaths.applicationData .. "Weather/Forecast.cfg"
|
||
|
||
local pathsToWeatherTypes = {
|
||
sunny = resources .. "Sunny.pic",
|
||
sunnyWithClouds = resources .. "SunnyWithClouds.pic",
|
||
snowy = resources .. "Snowy.pic",
|
||
rainy = resources .. "Rainy.pic",
|
||
cloudy = resources .. "Cloudy.pic",
|
||
stormy = resources .. "Stormy.pic",
|
||
}
|
||
|
||
local weatherIcons = {
|
||
[0] = pathsToWeatherTypes.stormy,
|
||
[1] = pathsToWeatherTypes.stormy,
|
||
[2] = pathsToWeatherTypes.stormy,
|
||
[3] = pathsToWeatherTypes.stormy,
|
||
[4] = pathsToWeatherTypes.stormy,
|
||
[5] = pathsToWeatherTypes.rainy,
|
||
[6] = pathsToWeatherTypes.rainy,
|
||
[7] = pathsToWeatherTypes.rainy,
|
||
[8] = pathsToWeatherTypes.rainy,
|
||
[9] = pathsToWeatherTypes.rainy,
|
||
[10] = pathsToWeatherTypes.rainy,
|
||
[11] = pathsToWeatherTypes.rainy,
|
||
[12] = pathsToWeatherTypes.rainy,
|
||
[13] = pathsToWeatherTypes.snowy,
|
||
[14] = pathsToWeatherTypes.snowy,
|
||
[15] = pathsToWeatherTypes.snowy,
|
||
[16] = pathsToWeatherTypes.snowy,
|
||
[17] = pathsToWeatherTypes.snowy,
|
||
[18] = pathsToWeatherTypes.rainy,
|
||
[19] = pathsToWeatherTypes.cloudy,
|
||
[20] = pathsToWeatherTypes.cloudy,
|
||
[21] = pathsToWeatherTypes.cloudy,
|
||
[22] = pathsToWeatherTypes.cloudy,
|
||
[23] = pathsToWeatherTypes.cloudy,
|
||
[24] = pathsToWeatherTypes.cloudy,
|
||
[25] = pathsToWeatherTypes.cloudy,
|
||
[26] = pathsToWeatherTypes.cloudy,
|
||
[27] = pathsToWeatherTypes.cloudy,
|
||
[28] = pathsToWeatherTypes.cloudy,
|
||
[29] = pathsToWeatherTypes.sunnyWithClouds,
|
||
[30] = pathsToWeatherTypes.sunnyWithClouds,
|
||
[31] = pathsToWeatherTypes.sunny,
|
||
[32] = pathsToWeatherTypes.sunny,
|
||
[33] = pathsToWeatherTypes.sunny,
|
||
[34] = pathsToWeatherTypes.sunny,
|
||
[35] = pathsToWeatherTypes.rainy,
|
||
[36] = pathsToWeatherTypes.sunny,
|
||
[37] = pathsToWeatherTypes.stormy,
|
||
[38] = pathsToWeatherTypes.stormy,
|
||
[39] = pathsToWeatherTypes.stormy,
|
||
[40] = pathsToWeatherTypes.rainy,
|
||
[41] = pathsToWeatherTypes.snowy,
|
||
[42] = pathsToWeatherTypes.snowy,
|
||
[43] = pathsToWeatherTypes.snowy,
|
||
[44] = pathsToWeatherTypes.sunnyWithClouds,
|
||
[45] = pathsToWeatherTypes.stormy,
|
||
[46] = pathsToWeatherTypes.snowy,
|
||
[47] = pathsToWeatherTypes.stormy,
|
||
}
|
||
|
||
|
||
--Запрос на получение погоды
|
||
local function weatherRequest(city)
|
||
local url = "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22" .. city .. "%2C%20ak%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys"
|
||
local success, response = ecs.internetRequest(url)
|
||
|
||
if success then
|
||
response = json:decode(response)
|
||
if response.query and response.query.results and response.query.results.channel and response.query.results.channel.item and response.query.results.channel.item.condition and response.query.results.channel.item.condition.temp then
|
||
return true, response
|
||
else
|
||
return false, "Ответ от Yahoo.com содержит неполную информацию, измените город или подождите некоторое время"
|
||
end
|
||
else
|
||
return false, "Запрос погоды к Yahoo.com не удался. Повторите попытку."
|
||
end
|
||
end
|
||
|
||
--Конвертим ПЕНДОССКИЕ мили в километры
|
||
local function convertMilesToKilometers(miles)
|
||
return miles / 1.609344
|
||
end
|
||
|
||
--Конвертируем МИЛИ В ЧАС, блядь, в МЕТРЫ В СЕКУНДУ
|
||
local function convertMPHtoMS(mph)
|
||
local kmph = convertMilesToKilometers(mph)
|
||
local metersPerHour = 1000 * kmph
|
||
local metersPerSecond = metersPerHour / 3600
|
||
return metersPerSecond
|
||
end
|
||
|
||
--Конвертируем давление в паскалях в царские ММ РТ СТОЛБА,Е ПТА
|
||
local function converPascalsToMMHG(pascals)
|
||
return pascals * 0.75006375541921
|
||
end
|
||
|
||
--Ну, а тут фаренгейт точеный в цельсий дроченый
|
||
local function convertFtoC(tempF)
|
||
return ecs.adaptiveRound((tempF - 32) / 1.8)
|
||
end
|
||
|
||
--А тут ебашим пиздатую иконку состояния погоды для прогноза (не охуевшую)
|
||
local function drawCorrectWeatherIcon(x, y, weatherCode)
|
||
buffer.image(x, y, image.load(weatherIcons[weatherCode] or pathsToWeatherTypes.sunny))
|
||
end
|
||
|
||
--Конвертирует направление ветра в градусах от 0 до 360 в словесную интерпретацию ХУЙНИ
|
||
local function getWindDirection(windAngle)
|
||
local directions = {
|
||
"северный",
|
||
"северо-восточный",
|
||
"восточный",
|
||
"юго-восточный",
|
||
"южный",
|
||
"юго-западный",
|
||
"западный",
|
||
"северо-западный",
|
||
}
|
||
|
||
local step = 360 / #directions * 2
|
||
local currentDirection = 1
|
||
|
||
local windDirection = "N/A"
|
||
|
||
for i = 0, 360, step do
|
||
if windAngle >= i and windAngle <= (i + step) then
|
||
windDirection = directions[currentDirection]
|
||
break
|
||
end
|
||
currentDirection = currentDirection + 1
|
||
end
|
||
|
||
return windDirection
|
||
end
|
||
|
||
--Делаем массив погоды пиздатым, а не ебливо-пиндосским
|
||
--Ну, там фаренгейты в цельсий, залупу в пизду и т.п.
|
||
local function prepareJsonWeatherResponseFromDrawing(jsonWeatherResponse)
|
||
weather.temperature = convertFtoC(jsonWeatherResponse.query.results.channel.item.condition.temp) .. "°"
|
||
weather.pressure = "Давление: " .. ecs.adaptiveRound(converPascalsToMMHG(jsonWeatherResponse.query.results.channel.atmosphere.pressure)) .. " мм"
|
||
weather.city = jsonWeatherResponse.query.results.channel.location.city .. ", " .. jsonWeatherResponse.query.results.channel.location.country
|
||
weather.wind = "Ветер: " .. getWindDirection(tonumber(jsonWeatherResponse.query.results.channel.wind.direction)) .. ", " .. ecs.adaptiveRound(convertMPHtoMS(tonumber(jsonWeatherResponse.query.results.channel.wind.speed))) .. " м/с"
|
||
weather.humidity = "Влажность: " .. jsonWeatherResponse.query.results.channel.atmosphere.humidity .. "%"
|
||
|
||
weather.forecast = {}
|
||
for i = 1, #jsonWeatherResponse.query.results.channel.item.forecast do
|
||
weather.forecast[i] = {}
|
||
weather.forecast[i].day = jsonWeatherResponse.query.results.channel.item.forecast[i].day
|
||
weather.forecast[i].code = tonumber(jsonWeatherResponse.query.results.channel.item.forecast[i].code)
|
||
weather.forecast[i].temperature = convertFtoC(tonumber(jsonWeatherResponse.query.results.channel.item.forecast[i].high)) .. " / " .. convertFtoC(tonumber(jsonWeatherResponse.query.results.channel.item.forecast[i].low)).. "°"
|
||
end
|
||
end
|
||
|
||
local function drawWeather()
|
||
--Рисуем обоинку или просто говнофон ССАНЫЙ
|
||
if fs.exists(MineOSCore.properties.wallpaper or "---aefaefaefaefae") then
|
||
buffer.image(1, 1, image.load(MineOSCore.properties.wallpaper))
|
||
buffer.square(1, 1, buffer.getWidth(), buffer.getHeight(), 0x0, 0x0, " ", 0.6)
|
||
else
|
||
buffer.clear(0x262626)
|
||
end
|
||
|
||
--Рисуем текущую температуру
|
||
local x, y = 10, buffer.getHeight() - 25
|
||
bigLetters.drawText(x, y, 0xFFFFFF, weather.temperature, drawWithSymbol)
|
||
y = y + 6
|
||
--Рисуем название города
|
||
buffer.text(x, y, 0xFFFFFF, weather.city)
|
||
--Рисуем ветер
|
||
y = y + 2
|
||
buffer.text(x, y, 0xFFFFFF, weather.wind)
|
||
y = y + 1
|
||
buffer.text(x, y, 0xFFFFFF, weather.pressure)
|
||
y = y + 1
|
||
buffer.text(x, y, 0xFFFFFF, weather.humidity)
|
||
--Рисуем КНОПАЧКИ
|
||
y = y + 2
|
||
changeCityButton = {buffer.button(x, y, 22, 1, 0xEEEEEE, 0x262626, "Другой город")}
|
||
exitButton = {buffer.button(buffer.getWidth() - 4, 2, 3, 1, 0xEEEEEE, 0x262626, "X")}
|
||
|
||
--Рисуем долгосрочный прогноз
|
||
y = y + 3
|
||
for i = 1, #weather.forecast do
|
||
--Рисуем дату
|
||
buffer.text(x + 2, y, 0xFFFFFF, weather.forecast[i].day)
|
||
--Рисуем КОРТИНАЧКУ
|
||
drawCorrectWeatherIcon(x, y + 2, weather.forecast[i].code)
|
||
--Рисуем температуру
|
||
buffer.text(x, y + 7, 0xFFFFFF, weather.forecast[i].temperature)
|
||
x = x + 11
|
||
end
|
||
end
|
||
|
||
local function loadWeatherData()
|
||
if fs.exists(pathToWeatherFile) then
|
||
weather = table.fromFile(pathToWeatherFile)
|
||
else
|
||
weather = {
|
||
myCity = "saint-petersburg",
|
||
temperature = "0°",
|
||
pressure = " ",
|
||
city = "Получение информации о погоде...",
|
||
wind = " ",
|
||
humidity = " ",
|
||
forecast = {},
|
||
}
|
||
end
|
||
end
|
||
|
||
local function saveWeatherData()
|
||
table.toFile(pathToWeatherFile, weather)
|
||
end
|
||
|
||
local function tryToGetAndDrawWeather()
|
||
local success, jsonWeatherResponse = weatherRequest(weather.myCity)
|
||
if success then
|
||
--Подготавливаем данные под РУССКОЕ отображение ГОВНА
|
||
prepareJsonWeatherResponseFromDrawing(jsonWeatherResponse)
|
||
--РЕСУЕМ ПАГОДУ
|
||
drawWeather()
|
||
buffer.draw()
|
||
--Сейвим погодку
|
||
saveWeatherData()
|
||
else
|
||
GUI.error(jsonWeatherResponse)
|
||
end
|
||
end
|
||
|
||
local function clicked(x, y, object)
|
||
if x >= object[1] and y >= object[2] and x <= object[3] and y <= object[4] then return true end
|
||
return false
|
||
end
|
||
|
||
--------------------------------------------------------------------------------------------------------------------
|
||
|
||
loadWeatherData()
|
||
drawWeather()
|
||
buffer.draw(true)
|
||
|
||
tryToGetAndDrawWeather()
|
||
|
||
while true do
|
||
local e = {event.pull()}
|
||
if e[1] == "touch" then
|
||
if clicked(e[3], e[4], changeCityButton) then
|
||
local data = ecs.universalWindow("auto", "auto", 36, 0x262626, true,
|
||
{"EmptyLine"},
|
||
{"CenterText", ecs.colors.orange, "Изменить город"},
|
||
{"CenterText", ecs.colors.white, "(допускаются только названия по-английски)"},
|
||
{"EmptyLine"},
|
||
{"Input", 0xFFFFFF, ecs.colors.orange, weather.myCity},
|
||
{"EmptyLine"},
|
||
{"Button", {ecs.colors.orange, 0xffffff, "OK"}, {0x999999, 0xffffff, "Отмена"}}
|
||
)
|
||
|
||
if data[2] == "OK" then
|
||
weather.myCity = data[1]
|
||
tryToGetAndDrawWeather()
|
||
end
|
||
elseif clicked(e[3], e[4], exitButton) then
|
||
-- buffer.clear(0x262626)
|
||
-- ecs.prepareToExit()
|
||
return
|
||
end
|
||
end
|
||
end
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|