---------------------------------------------------- Библиотеки ---------------------------------------------------------------- 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 weather = {} local changeCityButton = {} local exitButton = {} local resources = MineOSCore.getCurrentApplicationResourcesDirectory() local pathToWeatherFile = "/MineOS/System/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.OSSettings.wallpaper or "---aefaefaefaefae") then buffer.image(1, 1, image.load(MineOSCore.OSSettings.wallpaper)) buffer.square(1, 1, buffer.width, buffer.height, 0x0, 0x0, " ", 0.6) else buffer.clear(0x262626) end --Рисуем текущую температуру local x, y = 10, buffer.height - 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.width - 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