- Added Weather 1.0b

git-svn-id: svn://kolibrios.org@8553 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
superturbocat2001 2021-01-27 19:37:12 +00:00
parent d893a4981a
commit 8de8aa7b20
11 changed files with 1774 additions and 0 deletions

View File

@ -0,0 +1,13 @@
{
"files.associations": {
"istream": "c",
"ostream": "c",
"ratio": "c",
"array": "c",
"functional": "c",
"tuple": "c",
"type_traits": "c",
"utility": "c",
"variant": "c"
}
}

16
programs/other/Weather/Makefile Executable file
View File

@ -0,0 +1,16 @@
KTCC_DIR = ../../develop/ktcc/trunk
NAME = weather
KTCC=$(KTCC_DIR)/bin/kos32-tcc
KPACK = kpack
SRC= weather.c
CFLAGS= -I $(KTCC_DIR)/libc/include
LIBS = -ljson -lck -limg -lhttp
all:
$(KTCC) $(CFLAGS) -L json $(SRC) $(LIBS) -o $(NAME)
$(KPACK) $(NAME)
clean:
rm $(NAME)

View File

@ -0,0 +1,21 @@
All contributors arranged by first commit:
James McLaughlin
Alex Gartrell
Peter Scott
Mathias Kaerlev
Emiel Mols
Czarek Tomczak
Nicholas Braden
Ivan Kozub
Árpád Goretity
Igor Gnatenko
Haïkel Guémar
Tobias Waldekranz
Patrick Donnelly
Wilmer van der Gaast
Jin Wei
François Cartegnie
Matthijs Boelstra
Richard Selneck

View File

@ -0,0 +1,26 @@
Copyright (C) 2012, 2013 James McLaughlin et al. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.

View File

@ -0,0 +1,13 @@
KTCC_DIR=../../../develop/ktcc/trunk
KTCC=$(KTCC_DIR)/bin/kos32-tcc
KPACK=kpack
SRC=json.c
CFLAGS=-c -nostdinc -I $(KTCC_DIR)/libc/include -I.
all:
$(KTCC) $(CFLAGS) $(SRC)
ar -crs libjson.a *.o
clean:
rm -f *.o *.a

View File

@ -0,0 +1,97 @@
Very low footprint JSON parser written in portable ANSI C.
* BSD licensed with no dependencies (i.e. just drop the C file into your project)
* Never recurses or allocates more memory than it needs
* Very simple API with operator sugar for C++
[![Build Status](https://secure.travis-ci.org/udp/json-parser.png)](http://travis-ci.org/udp/json-parser)
_Want to serialize? Check out [json-builder](https://github.com/udp/json-builder)!_
Installing
----------
There is now a makefile which will produce a libjsonparser static and dynamic library. However, this
is _not_ required to build json-parser, and the source files (`json.c` and `json.h`) should be happy
in any build system you already have in place.
API
---
json_value * json_parse (const json_char * json,
size_t length);
json_value * json_parse_ex (json_settings * settings,
const json_char * json,
size_t length,
char * error);
void json_value_free (json_value *);
The `type` field of `json_value` is one of:
* `json_object` (see `u.object.length`, `u.object.values[x].name`, `u.object.values[x].value`)
* `json_array` (see `u.array.length`, `u.array.values`)
* `json_integer` (see `u.integer`)
* `json_double` (see `u.dbl`)
* `json_string` (see `u.string.ptr`, `u.string.length`)
* `json_boolean` (see `u.boolean`)
* `json_null`
Compile-Time Options
--------------------
-DJSON_TRACK_SOURCE
Stores the source location (line and column number) inside each `json_value`.
This is useful for application-level error reporting.
Runtime Options
---------------
settings |= json_enable_comments;
Enables C-style `// line` and `/* block */` comments.
size_t value_extra
The amount of space (if any) to allocate at the end of each `json_value`, in
order to give the application space to add metadata.
void * (* mem_alloc) (size_t, int zero, void * user_data);
void (* mem_free) (void *, void * user_data);
Custom allocator routines. If NULL, the default `malloc` and `free` will be used.
The `user_data` pointer will be forwarded from `json_settings` to allow application
context to be passed.
Changes in version 1.1.0
------------------------
* UTF-8 byte order marks are now skipped if present
* Allows cross-compilation by honoring --host if given (@wkz)
* Maximum size for error buffer is now exposed in header (@LB--)
* GCC warning for `static` after `const` fixed (@batrick)
* Optional support for C-style line and block comments added (@Jin-W-FS)
* `name_length` field added to object values
* It is now possible to retrieve the source line/column number of a parsed `json_value` when `JSON_TRACK_SOURCE` is enabled
* The application may now extend `json_value` using the `value_extra` setting
* Un-ambiguate pow call in the case of C++ overloaded pow (@fcartegnie)
* Fix null pointer de-reference when a non-existing array is closed and no root value is present

View File

@ -0,0 +1,14 @@
#include <stdint.h>
#define INT8_MAX 0x7f
#define INT8_MIN (-INT8_MAX - 1)
#define UINT8_MAX (INT8_MAX * 2 + 1)
#define INT16_MAX 0x7fff
#define INT16_MIN (-INT16_MAX - 1)
#define UINT16_MAX (__CONCAT(INT16_MAX, U) * 2U + 1U)
#define INT32_MAX 0x7fffffffL
#define INT32_MIN (-INT32_MAX - 1L)
#define UINT32_MAX (__CONCAT(INT32_MAX, U) * 2UL + 1UL)
#define INT64_MAX 0x7fffffffffffffffLL
#define INT64_MIN (-INT64_MAX - 1LL)
#define UINT64_MAX (__CONCAT(INT64_MAX, U) * 2ULL + 1ULL)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,283 @@
/* vim: set et ts=3 sw=3 sts=3 ft=c:
*
* Copyright (C) 2012, 2013, 2014 James McLaughlin et al. All rights reserved.
* https://github.com/udp/json-parser
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _JSON_H
#define _JSON_H
#ifndef json_char
#define json_char char
#endif
#ifndef json_int_t
#ifndef _MSC_VER
#include "inttypes.h"
#define json_int_t int64_t
#else
#define json_int_t __int64
#endif
#endif
#include <stdlib.h>
#ifdef __cplusplus
#include <string.h>
extern "C"
{
#endif
typedef struct
{
unsigned long max_memory;
int settings;
/* Custom allocator support (leave null to use malloc/free)
*/
void * (* mem_alloc) (size_t, int zero, void * user_data);
void (* mem_free) (void *, void * user_data);
void * user_data; /* will be passed to mem_alloc and mem_free */
size_t value_extra; /* how much extra space to allocate for values? */
} json_settings;
#define json_enable_comments 0x01
typedef enum
{
json_none,
json_object,
json_array,
json_integer,
json_double,
json_string,
json_boolean,
json_null
} json_type;
extern const struct _json_value json_value_none;
typedef struct _json_object_entry
{
json_char * name;
unsigned int name_length;
struct _json_value * value;
} json_object_entry;
typedef struct _json_value
{
struct _json_value * parent;
json_type type;
union
{
int boolean;
json_int_t integer;
double dbl;
struct
{
unsigned int length;
json_char * ptr; /* null terminated */
} string;
struct
{
unsigned int length;
json_object_entry * values;
#if defined(__cplusplus) && __cplusplus >= 201103L
decltype(values) begin () const
{ return values;
}
decltype(values) end () const
{ return values + length;
}
#endif
} object;
struct
{
unsigned int length;
struct _json_value ** values;
#if defined(__cplusplus) && __cplusplus >= 201103L
decltype(values) begin () const
{ return values;
}
decltype(values) end () const
{ return values + length;
}
#endif
} array;
} u;
union
{
struct _json_value * next_alloc;
void * object_mem;
} _reserved;
#ifdef JSON_TRACK_SOURCE
/* Location of the value in the source JSON
*/
unsigned int line, col;
#endif
/* Some C++ operator sugar */
#ifdef __cplusplus
public:
inline _json_value ()
{ memset (this, 0, sizeof (_json_value));
}
inline const struct _json_value &operator [] (int index) const
{
if (type != json_array || index < 0
|| ((unsigned int) index) >= u.array.length)
{
return json_value_none;
}
return *u.array.values [index];
}
inline const struct _json_value &operator [] (const char * index) const
{
if (type != json_object)
return json_value_none;
for (unsigned int i = 0; i < u.object.length; ++ i)
if (!strcmp (u.object.values [i].name, index))
return *u.object.values [i].value;
return json_value_none;
}
inline operator const char * () const
{
switch (type)
{
case json_string:
return u.string.ptr;
default:
return "";
};
}
inline operator json_int_t () const
{
switch (type)
{
case json_integer:
return u.integer;
case json_double:
return (json_int_t) u.dbl;
default:
return 0;
};
}
inline operator bool () const
{
if (type != json_boolean)
return false;
return u.boolean != 0;
}
inline operator double () const
{
switch (type)
{
case json_integer:
return (double) u.integer;
case json_double:
return u.dbl;
default:
return 0;
};
}
#endif
} json_value;
json_value * json_parse (const json_char * json,
size_t length);
#define json_error_max 128
json_value * json_parse_ex (json_settings * settings,
const json_char * json,
size_t length,
char * error);
void json_value_free (json_value *);
/* Not usually necessary, unless you used a custom mem_alloc and now want to
* use a custom mem_free.
*/
void json_value_free_ex (json_settings * settings,
json_value *);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif

View File

@ -0,0 +1,248 @@
/* Copyright (C) 2019-2021 Logaev Maxim (turbocat2001), GPLv2 */
/*
Info: App uses api from openweathermap.org.
The standard configuration uses my token and the city of Moscow.
You can always change it in the weather.json file.
If you use UTF-8 encoding, then city names can be entered in different languages!
*/
#include <stdio.h>
#include <string.h>
#include "json/json.h"
#include <kos32sys1.h>
#include <kolibrisys.h>
#include <clayer/http.h>
#include <clayer/libimg.h>
#define VERSION "Weather 1.0b"
enum BUTTONS{
BTN_QUIT = 1,
BTN_UPDATE = 2
};
#define JSON_OBJ(X) value->u.object.values[X]
#define OK 200
#define API "http://api.openweathermap.org/data/2.5/weather?q=%s&appid=%s&units=metric"
#define IMAGE_URL "http://openweathermap.org/img/w/%s.png"
#define START_YPOS 34
Image *image;
char full_url[256];
char full_url_image[256];
struct kolibri_system_colors sys_color_table;
#pragma pack(push,1)
typedef struct {
char *City;
float wind_speed;
//int wind_deg;
int pressure;
int humidity;
char *weath_main;
char *weath_desc;
int visibility;
int timezone;
char* image_code;
double temp;
}open_weather_data;
#pragma pack(pop)
open_weather_data myw;
void notify_show(char *text)
{
start_app("/sys/@notify", text);
}
void* safe_malloc(size_t size) // Безопасный malloc. Показывает уведомление об ошибке и закрывает программу если память не была выделена
{
void *p=malloc(size);
if(p==NULL){
notify_show("'Memory allocation error!' -E");
exit(0);
}else{
return p;
}
}
static void draw_format_text_sys(int x, int y, color_t color, const char *format_str, ... )
{
char tmp_buff[100];
va_list ap;
va_start (ap, format_str);
vsnprintf(tmp_buff, sizeof tmp_buff ,format_str, ap);
va_end(ap);
draw_text_sys(tmp_buff, x, y , 0, color);
}
void find_and_set(json_value *value, open_weather_data* weather)
{
for(int i=0; i<value->u.object.length; i++){
if(!strcmp(JSON_OBJ(i).name, "main")){
weather->temp = JSON_OBJ(i).value->u.object.values[0].value->u.dbl;
weather->pressure = JSON_OBJ(i).value->u.object.values[4].value->u.integer;
weather->humidity = JSON_OBJ(i).value->u.object.values[5].value->u.integer;
}
if(!strcmp(JSON_OBJ(i).name, "name")){
weather->City = JSON_OBJ(i).value->u.string.ptr;
}
if(!strcmp(JSON_OBJ(i).name, "weather")){
weather->weath_desc = JSON_OBJ(i).value->u.array.values[0]->u.object.values[2].value->u.string.ptr;
weather->image_code = JSON_OBJ(i).value->u.array.values[0]->u.object.values[3].value->u.string.ptr;
}
if(!strcmp(JSON_OBJ(i).name, "wind")){
weather->wind_speed = JSON_OBJ(i).value->u.object.values[0].value->u.dbl;
}
if(!strcmp(JSON_OBJ(i).name, "visibility")){
weather->visibility = JSON_OBJ(i).value->u.integer;
}
if(!strcmp(JSON_OBJ(i).name, "timezone")){
weather->timezone = JSON_OBJ(i).value->u.integer/60/60;
}
if(!strcmp(JSON_OBJ(i).name, "message")){
char *errmsg = safe_malloc(weather->timezone = JSON_OBJ(i).value->u.string.length+6);
sprintf(errmsg,"'%s!' -E", JSON_OBJ(i).value->u.string.ptr);
notify_show(errmsg);
}
}
}
http_msg* get_json(char *City, char *Token)
{
sprintf(full_url, API, City, Token);
http_msg *h = http_get(full_url, 0, HTTP_FLAG_BLOCK, "");
http_long_receive(h);
if (h->status == OK || h->status == 404) {
return h;
} else {
return NULL;
}
}
void get_image(){
sprintf(full_url_image, IMAGE_URL, myw.image_code);
http_msg *h= http_get(full_url_image, 0, HTTP_FLAG_BLOCK, "");
http_long_receive(h);
if (h->status == OK) {
image = img_decode(h->content_ptr, h->content_length, 0); // Decode RAW data to Image data
if (image->Type != IMAGE_BPP32) {
image = img_convert(image, NULL, IMAGE_BPP32, 0, 0); // Convert image to format BPP32
if (!image) {
notify_show("'Convetring image error!' -E");
exit(0);
}
}
//blend = img_create(64, 64, IMAGE_BPP32); // Create an empty layer
//img_fill_color(blend, 64, 64, sys_color_table.work_area); // Fill the layer with one color
image = img_scale(image, 0, 0, 50, 50, NULL, LIBIMG_SCALE_STRETCH , LIBIMG_INTER_BILINEAR, 64, 64);
//img_blend(blend, image, 0, 0, 0, 0, 64, 64); // Blending images to display the alpha channel.
}else{
notify_show("'Image not loaded!!' -W");
}
}
void RedrawGUI() //Рисуем окно
{
char buff[1000];
pos_t win_pos = get_mouse_pos(0); // Получаем координаты курсора
begin_draw(); //Начинаем рисование интерфейса )
sys_create_window(win_pos.x, win_pos.y, 220, START_YPOS+200, VERSION, 0xffffff, 0x14); // Создаём окно.
draw_format_text_sys(10, START_YPOS, 0xB0000000 /*| sys_color_table.work_text*/, "%s (UTC%+d)\0", myw.City, myw.timezone);
draw_format_text_sys(11, START_YPOS, 0xB0000000 /*| sys_color_table.work_text */, "%s (UTC%+d)\0", myw.City, myw.timezone);
img_draw(image, 10, START_YPOS+30, 64,64,0,0);
draw_format_text_sys(10, START_YPOS+20, 0xb0000000 /* | sys_color_table.work_text */, myw.weath_desc);
draw_format_text_sys(11, START_YPOS+20, 0xb0000000 /*| sys_color_table.work_text */, myw.weath_desc);
draw_format_text_sys(90, START_YPOS+45, 0xB1000000 /*| sys_color_table.work_text*/, "%.1f °C", myw.temp);
draw_format_text_sys(91, START_YPOS+46, 0xB1000000 /*| sys_color_table.work_text*/, "%.1f °C", myw.temp);
draw_format_text_sys(10, START_YPOS+80, 0x90000000 /*| sys_color_table.work_text*/, "Pressure: %d hPa",myw.pressure);
draw_format_text_sys(10, START_YPOS+100, 0x90000000 /* | sys_color_table.work_text*/,"Humidity: %d %s", myw.humidity, "%");
draw_format_text_sys(10, START_YPOS+120, 0x90000000 /*| sys_color_table.work_text*/, "Wind speed: %.1f m/s", myw.wind_speed);
draw_format_text_sys(10, START_YPOS+140, 0x90000000 /*| sys_color_table.work_text*/, "Visibility: %d m", myw.visibility);
define_button(X_W(65,80), Y_H(START_YPOS+160,30), BTN_UPDATE, sys_color_table.work_button);
draw_text_sys("Update",80 , START_YPOS+170, 0, 0x90000000 | sys_color_table.work_button_text);
end_draw();
}
void get_config(char **City, char **Token)
{
FILE *config_j = fopen("weather.json", "rb");
if(config_j==NULL){
notify_show("'Configuration file not found!' -E");
exit(0);
}
size_t size = _ksys_get_filesize("weather.json");
char *config_buff = safe_malloc(size+1);
if(size != fread(config_buff, sizeof(char), size, config_j)){
notify_show("'The configuration file was not fully read!' -E");
exit(0);
}
json_value* value =json_parse (config_buff, size);
for(int i=0; i<value->u.object.length; i++){
if(!strcmp(JSON_OBJ(i).name, "Location")){
*City = JSON_OBJ(i).value->u.string.ptr;
}
if(!strcmp(JSON_OBJ(i).name, "Token")){
*Token = JSON_OBJ(i).value->u.string.ptr;
}
}
if(*City==NULL || *Token ==NULL){
notify_show("'Invalid config!!' -E");
exit(0);
}
free(config_buff);
}
void Update(char* city, char* token)
{
memset(&myw, 0, sizeof myw);
myw.City="None";
myw.weath_desc="unknown";
http_msg *json_file = get_json(city, token);
if(json_file != NULL){
json_value* value =json_parse (json_file->content_ptr, json_file->content_length);
find_and_set(value, &myw);
get_image();
}else{
notify_show("'Connection error!' -E");
}
}
int main(){
kolibri_libimg_init();
get_system_colors(&sys_color_table);
char *City = NULL;
char *Token = NULL;
get_config(&City, &Token);
Update(City,Token);
while(1){
switch(get_os_event()){
case KOLIBRI_EVENT_NONE:
break;
case KOLIBRI_EVENT_REDRAW:
RedrawGUI();
break;
case KOLIBRI_EVENT_BUTTON: // Событие обработки кнопок
switch (get_os_button()){
case BTN_UPDATE:
Update(City, Token);
RedrawGUI();
break;
case BTN_QUIT:
exit(0);
break;
}
}
}
return 0;
}

View File

@ -0,0 +1,4 @@
{
"Location": "Москва",
"Token": "19ffa14b3dc0e238175829461d1788b8"
}