· 4 years ago · Feb 21, 2021, 03:36 PM
1import datetime
2import json
3import sqlite3 as sql
4import time
5
6from kivy.clock import Clock
7from kivy.lang import Builder
8from kivy.properties import StringProperty
9from kivy.uix.boxlayout import BoxLayout
10from kivy.uix.screenmanager import Screen
11from kivymd.app import MDApp
12from kivymd.uix.boxlayout import MDBoxLayout
13from kivymd.uix.button import MDFlatButton
14from kivymd.uix.dialog import MDDialog
15from kivymd.uix.expansionpanel import MDExpansionPanel, MDExpansionPanelTwoLine
16from kivymd.uix.list import IRightBodyTouch, MDList
17
18
19from news import News
20
21
22class NewsLayout(BoxLayout):
23 title = StringProperty()
24 picture = StringProperty(allownone=True)
25 description = StringProperty(allownone=True)
26
27
28
29class Content(MDList):
30 pass
31
32
33class RecordLine(MDBoxLayout):
34 text = StringProperty()
35
36
37class InformationDialog(MDDialog):
38 pass
39
40
41class MainMenuScreen(Screen):
42 pass
43
44
45class InputScreen(Screen):
46 pass
47
48
49class RestingHeartRateScreen(Screen):
50 pass
51
52
53class ResultObeseScreen(Screen):
54 pass
55
56
57class ResultNormalScreen(Screen):
58 pass
59
60
61class ResultOverweightScreen(Screen):
62 pass
63
64
65class ResultUnderweightScreen(Screen):
66 pass
67
68
69class LocationSearchScreen(Screen):
70 pass
71
72
73class LocationResultScreen(Screen):
74 pass
75
76
77class HistoryScreen(Screen):
78 pass
79
80
81class DemoApp(MDApp):
82 conn = sql.connect('USERINFO.db')
83 cur = conn.cursor()
84 cur.execute(""" CREATE TABLE IF NOT EXISTS results (
85 UID INTEGER PRIMARY KEY AUTOINCREMENT,
86 RESULT INT,
87 DATE_TIME TEXT DEFAULT CURRENT_TIMESTAMP)
88 """)
89 cur.execute(""" CREATE TABLE IF NOT EXISTS information (
90 id INTEGER PRIMARY KEY AUTOINCREMENT,
91 fname VARCHAR(50),
92 height INT,
93 weight INT,
94 age INT,
95 heartrate INT)
96 """)
97 conn.commit()
98 conn.close()
99
100 def __init__(self, **kwargs):
101 super().__init__(**kwargs)
102 self.news = News() # create the Class instance
103 self.news.get_news() # pull a list of stories from the web
104 self.i = 0 # index for moving through the
105 self.list_items = [] # Dictionary where the items is stored
106 self.counter = 0
107 self.counting = {'Item counter': self.counter}
108 self.dialog = None
109 self.selected_category = None
110 self.selected_rec = None
111 self.card_file = \
112 [{'Category': 'Barangay ALABANG',
113 'Record': [
114 {'title': 'Alabang Medical Clinic ( MAIN )',
115 'Details': [
116 ' ADDRESS: \n 297 Montillano St, Alabang, Muntinlupa \n TELEPHONE NUMBER: \n (02) 8842 0680']},
117 {'title': 'Alabang Medical Center, Alabang Zapote road',
118 'Details': [
119 ' ADDRESS: \n Ayala Life-FGU Center, Zapote Road Corner Acacia Avenue Madrigal Business Park, Ayala Alabang, Muntinlupa \n TELEPHONE NUMBER: \n 0998 855 9221']},
120 {'title': 'Asian Hospital and Medical Center',
121 'Details': [
122 ' ADDRESS: \n 2205 Civic Dr, Alabang, Muntinlupa \n TELEPHONE NUMBER: \n (02) 8771 9000']},
123 {'title': 'Aventus Medical Care, Inc. - Alabang Clinic',
124 'Details': [
125 ' ADDRESS: \n 2/F Sycamore ARCS 1 Building Buencamino Street corner Alabang - Zapote Road Madrigal Business Park, Alabang, Muntinlupa \n TELEPHONE NUMBER: \n (02) 8556 3598']},
126 {'title': 'Healthway Medical Festival Mall',
127 'Details': [
128 ' ADDRESS: \n 2nd Floor, Pixie Forest Entrance, Filinvest Ave, Filinvest City, Muntinlupa \n TELEPHONE NUMBER: \n (02) 751 4929']},
129 {'title': 'Healthfirst clinic ALABANG',
130 'Details': [
131 ' ADDRESS: \n G/F, South Supermarket, Filinvest Ave., Filinvest Corporate City \n TELEPHONE NUMBER: \n (+632) 8 821 1423 | 0917 842 8214']},
132 {'title': 'Ospital ng Muntinlupa ( OSMUN )',
133 'Details': [
134 ' ADDRESS: \n Civic Dr, Alabang, Muntinlupa \n TELEPHONE NUMBER: \n (02) 8771 0457']},
135 {'title': 'St. Michaels Medical Center',
136 'Details': [
137 ' ADDRESS: \n Starmall Alabang, South Super Hwy, Alabang, Muntinlupa\n TELEPHONE NUMBER: \n 0921 624 4418']},
138 {'title': 'San Roque Medical Clinic',
139 'Details': [' ADDRESS: \n Alabang, Muntinlupa \n TELEPHONE NUMBER: \n (02) 8842 2950']},
140 {'title': 'Megason Diagnostic Clinic',
141 'Details': [' ADDRESS: \nAlabang, Muntinlupa \n TELEPHONE NUMBER: \n (02) 8809 9044']},
142 {'title': 'Tokyo Healthlink 東京ヘルスリンク - Alabang',
143 'Details': [
144 ' ADDRESS: \n Molito Complex, Madrigal Ave, Ayala Alabang, Muntinlupa \n TELEPHONE NUMBER: \n (02) 8772 2678']},
145 {'title': 'Research Institute for Tropical Medicine',
146 'Details': [
147 ' ADDRESS: \n Filinvest Corporate City, 9002 Research Dr, Alabang, Muntinlupa \n TELEPHONE NUMBER: \n (02) 8807 2631']},
148 ]},
149 {'Category': 'Barangay BAYANAN',
150 'Record': [
151 {'title': 'Silverio Medical Clinic',
152 'Details': [
153 ' ADDRESS: \n 233g National Road, Muntinlupa \n TELEPHONE NUMBER: \n (02) 8862 0223']},
154 {'title': 'Bayanan Health Center (Annex)',
155 'Details': [
156 ' ADDRESS: \n Block 2, Purok 1, 292 M Dolleton St, Muntinlupa \n TELEPHONE NUMBER: \n (02) 8862 0124']},
157 {'title': 'Bayanan Medical Clinic, X-Ray and Laboratory Services',
158 'Details': [
159 ' ADDRESS: \n 231 National Road, Bayanan, Muntinlupa \n TELEPHONE NUMBER: \n (02) 8861 5861']},
160 {'title': 'El Natividad Medical And Maternity Clinic',
161 'Details': [
162 ' ADDRESS: \n 214 National Road, Muntinlupa \n TELEPHONE NUMBER: \n 0923 701 5164']},
163 ]},
164 {'Category': 'Barangay CUPANG',
165 'Record': [
166 {'title': 'Hillside General Hospital',
167 'Details': [
168 ' ADDRESS: \n Km. 23, West Service Road, Cupang, Muntinlupa \n TELEPHONE NUMBER: \n (02) 8842 3958']},
169 {'title': 'Alabang Medical Center',
170 'Details': [
171 ' ADDRESS: \n 8 Corregidor, Cupang, Muntinlupa \n TELEPHONE NUMBER: \n (02) 8850 8719']},
172 {'title': 'Cupang Health Center',
173 'Details': [
174 ' ADDRESS: \n Barangay Hall, Beside Cupang, Manuel L. Quezon, Cupang, Muntinlupa \n TELEPHONE NUMBER: \n --']},
175 ]},
176 {'Category': 'Barangay POBLACION',
177 'Record': [
178 {'title': 'Albia Medical & Diagnostic Clinic',
179 'Details': [
180 ' ADDRESS: \n 93 Rizal St, Poblacion, Muntinlupa \n TELEPHONE NUMBER: \n (02)8461204']},
181 {'title': 'Babaran Echavez Medical And Psychiatric Clinic',
182 'Details': [
183 ' ADDRESS: \n 1125 Amparo Corner Sto Nino Street, Poblacion, Muntinlupa \n TELEPHONE NUMBER: \n (02) 8861 3066']},
184 {'title': 'MCC De La Merced Maternity And Childrens Clinic',
185 'Details': [
186 ' ADDRESS: \n 92 Rizal St, Poblacion, Muntinlupa \n TELEPHONE NUMBER: \n (02) 8861 3944']},
187 {'title': 'Mauricestela Medical Clinic',
188 'Details': [
189 ' ADDRESS: \n 212 Pedro Diaz St, Poblacion, Muntinlupa, 1776 Metro Manila \n TELEPHONE NUMBER: \n (02) 8862 2117']},
190 {'title': 'Poblacion Health Center Main',
191 'Details': [
192 ' ADDRESS: \n Poblacion, Muntinlupa \n TELEPHONE NUMBER: \n NONE']},
193 ]},
194 {'Category': 'Barangay PUTATAN',
195 'Record': [
196 {'title': 'Alabang Medical Clinic - Muntinlupa Branch',
197 'Details': [
198 ' ADDRESS: \n 1 National Highway, Putatan, Muntinlupa \n TELEPHONE NUMBER: \n (02) 8861 1779']},
199 {'title': 'IMS Wellth Care, Inc.',
200 'Details': [
201 ' ADDRESS: \n 49 National Road, Putatan, Muntinlupa \n TELEPHONE NUMBER: \n (02) 8861 1592']},
202 {'title': 'Medical Center Muntinlupa',
203 'Details': [
204 ' ADDRESS: \n National Road, Putatan, Muntinlupa \n TELEPHONE NUMBER: \n 8620162']},
205 {'title': 'Muntinlupa Doctors Clinic',
206 'Details': [
207 ' ADDRESS: \n 1 National Road, Putatan, Muntinlupa \n TELEPHONE NUMBER: \n (02) 8842 2718']},
208 {'title': 'Medcare Multi Specialty',
209 'Details': [
210 ' ADDRESS: \n 84-I, National Road, Barangay Putatan, Muntinlupa \n TELEPHONE NUMBER: \n 0922 857 4180']},
211 ]},
212 {'Category': 'Barangay SUCAT',
213 'Record': [
214 {'title': 'Sucat Health Center',
215 'Details': [
216 ' ADDRESS: \n 624 Dir. A. Bunye, Sucat, Muntinlupa \n TELEPHONE NUMBER: \n NONE']},
217 ]},
218 {'Category': 'Barangay TUNASAN',
219 'Record': [
220 {'title': 'Beato-Cauilan Hospital',
221 'Details': [
222 ' ADDRESS: \n Manila S Rd, Tunasan, Muntinlupa \n TELEPHONE NUMBER: \n +632 861-5284']},
223 ]}]
224
225 def on_start(self):
226 Clock.schedule_interval(self.update_news, 5) # every 5 seconds, show the next story
227 for category in self.card_file:
228 panel = MDExpansionPanel(icon="scr2.png", content=Content(),
229 panel_cls=MDExpansionPanelTwoLine(text=category['Category'],
230 secondary_text="Tap to view Hospitals"))
231 self.root.ids.scr_mngr.get_screen('locsearch').ids.rlist.add_widget(panel)
232 for rec in category['Record']:
233 rw = RecordLine(text=rec['title'])
234 print(rec['title'])
235 self.root.ids.scr_mngr.get_screen('locsearch').ids.rlist.children[0].content.add_widget(rw)
236
237 def showinfo(self, cat, r):
238 close_button = MDFlatButton(text="Done", on_release=self.close_dialog)
239 ingredients = self.hlist(cat, r)
240 ingredients_text = ''
241 for ingredient in ingredients:
242 ingredients_text += ingredient
243 self.dialog = InformationDialog(size_hint=(0.8, 0.8), text=ingredients_text, auto_dismiss=True,
244 buttons=[close_button])
245 self.dialog.open()
246
247 def hlist(self, selected_cat, selected_r):
248 self.selected_rec = selected_r
249 self.selected_category = selected_cat
250 for category in self.card_file:
251 if category['Category'] == selected_cat:
252 for rec in category['Record']:
253 if rec['title'] == selected_r:
254 return rec['Details']
255
256 def on_stop(self): # Event handler that triggers when the application has finished running
257 # Creates a json file to saved the all the items in dictionary when closing the app
258 with open('saved_list.txt', 'w') as f:
259 json.dump(self.list_items, f)
260
261 class Container(IRightBodyTouch, MDBoxLayout): # This line position widget to the right.
262 adaptive_width = True
263
264 def update_news(self, dt):
265 # this is moving through the list of stories pulled, it does not go back to the web for more content
266 # to get refresed content call self.news.get_news()
267 # Skip stories that don't have a picture and a description
268 if not self.news.headlines[self.i][1] or not self.news.headlines[self.i][2]:
269 self.i = (self.i + 1) % len(self.news.headlines)
270 self.update_news(None) # junk parameter...
271 else:
272 p = self.root.ids.scr_mngr.get_screen('menu').ids.nl # a sort cut to avoid writing self.root.ids.dl 3x
273 p.title = self.news.headlines[self.i][0] # The title
274 p.picture = self.news.headlines[self.i][1] # url to the picture
275 p.description = self.news.headlines[self.i][2]
276 self.i = (self.i + 1) % len(self.news.headlines)
277
278 def save_data(self):
279 conn = sql.connect('USERINFO.db')
280 cur = conn.cursor()
281 cur.execute(""" INSERT INTO information (fname,height,weight,age,heartrate) VALUES (?,?,?,?,?)""",
282 (self.root.ids.scr_mngr.get_screen('input').ids.fname.text,
283 self.root.ids.scr_mngr.get_screen('input').ids.height.text,
284 self.root.ids.scr_mngr.get_screen('input').ids.weight.text,
285 self.root.ids.scr_mngr.get_screen('input').ids.age.text,
286 self.root.ids.scr_mngr.get_screen('input').ids.heartrate.text))
287 conn.commit()
288 conn.close()
289
290 def result_condition(self):
291 n = int(10000)
292 h = int(self.root.ids.scr_mngr.get_screen('input').ids.height.text)
293 w = int(self.root.ids.scr_mngr.get_screen('input').ids.weight.text)
294 unix = time.time()
295 date = str(datetime.datetime.fromtimestamp(unix).strftime('%Y-%m-%d %H:%M:%S'))
296 answer = (w / h / h) * n
297 print(round(answer,2))
298
299 conn = sql.connect('USERINFO.db')
300 cur = conn.cursor()
301 cur.execute(""" INSERT INTO results (RESULT,DATE_TIME) VALUES (?,?)""",
302 (
303 (round(answer,2)),
304 date
305 ))
306 conn.commit()
307 conn.close()
308 if answer <= 18.5:
309 self.root.ids.scr_mngr.current = 'underweight'
310 elif 18.6 <= answer <= 24.9:
311 self.root.ids.scr_mngr.current = 'normal'
312 elif 25.0 <= answer <= 29.9:
313 self.root.ids.scr_mngr.current = 'overweight'
314 else:
315 self.root.ids.scr_mngr.current = 'obese'
316
317 def clear_inputs(self): # set each of the inputs to an empty string
318 self.root.ids.scr_mngr.get_screen('input').ids.fname.text = ""
319 self.root.ids.scr_mngr.get_screen('input').ids.heartrate.text = ""
320 self.root.ids.scr_mngr.get_screen('input').ids.age.text = ""
321 self.root.ids.scr_mngr.get_screen('input').ids.height.text = ""
322 self.root.ids.scr_mngr.get_screen('input').ids.weight.text = ""
323
324 def info1_dialog(self):
325 close_button = MDFlatButton(text="Okay", on_release=self.close_dialog)
326 self.dialog = MDDialog(title="Details",
327 text="Hospitals listed are still operating up-to-date",
328 size_hint=(1, 1),
329 buttons=[close_button])
330 self.dialog.open()
331
332 def show_database(self):
333 conn = sql.connect('USERINFO.db')
334 cur = conn.cursor()
335 cur.execute("""
336 SELECT fname, height, weight, heartrate, RESULT, DATE_TIME
337 FROM information INNER JOIN results
338 ON information.id = results.UID
339 """)
340 output = cur.fetchall()
341 for data in output:
342 print(data)
343
344 def build(self):
345 self.theme_cls.primary_palette = "Lime"
346 self.theme_cls.theme_style = "Light"
347 screen = Builder.load_file("main.kv")
348 return screen
349
350 def show_alert_dialog(self):
351 close_button = MDFlatButton(text="Okay",
352 on_release=self.okay)
353 more_button = MDFlatButton(text="Cancel", on_press=self.close_dialog)
354
355 self.dialog = MDDialog(title="Confirmation", text="Confirm Details?",
356 size_hint=(1, 1),
357 buttons=[close_button, more_button])
358 self.dialog.open()
359
360 def result_dialog(self):
361 close_button = MDFlatButton(text="Okay", on_release=self.close_dialog)
362 self.dialog = MDDialog(title="Where did we get the Results?",
363 text="Results are Determined based on the Details Given by the User",
364 size_hint=(1, 1),
365 buttons=[close_button])
366 self.dialog.open()
367
368 def hrdialog(self):
369 close_button = MDFlatButton(text="Okay", on_release=self.close_dialog)
370 self.dialog = MDDialog(title="Manual BPM Check",
371 text="Age Target BPM Average BPM \n 20 100 to 170 200 \n 30 95 to 162 "
372 " 190 \n 35 93 to 157 185 \n 40 90 to 153 180 \n 45 88 to "
373 "149 175 \n 50 85 to 145 170 \n 55 83 to 140 165 \n 60 80 "
374 "to 136 160 \n 65 78 to 132 155 \n 70 75 to 128 150 \n If "
375 "you feel that your heart is beating out of rhythm, too fast, or too slow, "
376 "speak to a doctor about your symptoms.",
377 size_hint=(1, 1),
378 buttons=[close_button])
379 self.dialog.open()
380
381 def info2dialog(self):
382 close_button = MDFlatButton(text="Okay", on_release=self.close_dialog)
383 self.dialog = MDDialog(title="Instructions",
384 text="Manual Heartbeat check can be used to determine if you have a normal heart rate "
385 "for your age. \n "
386 "If height = feet/inches, Convert to Centimeter (FEET× 30.48 +INCHES× 2.54) ",
387 size_hint=(1, 1),
388 buttons=[close_button])
389 self.dialog.open()
390
391 def show_data(self, *args):
392 if self.root.ids.scr_mngr.get_screen('input').ids.fname.text == "" \
393 or self.root.ids.scr_mngr.get_screen('input').ids.height.text == "" \
394 or self.root.ids.scr_mngr.get_screen('input').ids.weight.text == "" \
395 or self.root.ids.scr_mngr.get_screen('input').ids.heartrate.text == "" \
396 or self.root.ids.scr_mngr.get_screen('input').ids.age.text == "" \
397 or self.root.ids.scr_mngr.get_screen('input').ids.heartrate.text == "":
398 close_button = MDFlatButton(text="Okay", on_release=self.close_dialog)
399 self.dialog = MDDialog(title="Invalid", text="No data added",
400 size_hint=(1, 1), buttons=[close_button])
401 self.dialog.open()
402 else:
403 self.show_alert_dialog()
404
405 def okay(self, *args):
406 print(self.root.ids.scr_mngr.get_screen('input').ids.fname.text),
407 print(self.root.ids.scr_mngr.get_screen('input').ids.height.text),
408 print(self.root.ids.scr_mngr.get_screen('input').ids.weight.text),
409 print(self.root.ids.scr_mngr.get_screen('input').ids.age.text),
410 print(self.root.ids.scr_mngr.get_screen('input').ids.heartrate.text)
411 self.save_data()
412 self.result_condition()
413 self.clear_inputs()
414 self.dialog.dismiss()
415
416 def close_dialog(self, obj):
417 self.dialog.dismiss()
418
419 def history_screen(self, obj):
420 self.root.ids.scr_mngr.current = 'history'
421 self.root.ids.scr_mngr.transition.direction = "right"
422
423 def location_screen(self, obj):
424 self.root.ids.scr_mngr.current = 'locsearch'
425 self.root.ids.scr_mngr.transition.direction = "left"
426
427 def back_screen(self, obj):
428 self.root.ids.scr_mngr.current = 'menu'
429 self.root.ids.scr_mngr.transition.direction = "left"
430
431 # def back2_screen(self, obj):
432 # self.root.ids.scr_mngr.current = 'input'
433 # self.root.ids.scr_mngr.transition.direction = "right"
434
435 def back3_screen(self, obj):
436 self.root.ids.scr_mngr.current = 'menu'
437 self.root.ids.scr_mngr.transition.direction = "right"
438
439 def back4_screen(self, obj):
440 self.root.ids.scr_mngr.current = 'locsearch'
441 self.root.ids.scr_mngr.transition.direction = "right"
442
443 def back_screen6(self, obj):
444 self.root.ids.scr_mngr.current = 'menu'
445 self.root.ids.scr_mngr.transition.direction = "right"
446
447
448DemoApp().run()
449--------------------------------------
450from kivy.event import EventDispatcher
451from kivy.network.urlrequest import UrlRequest
452from kivy.properties import ListProperty
453
454
455class News(EventDispatcher):
456 headlines = ListProperty([('No Internet Connection', 'sad.png', 'No news is good news!')])
457
458 def get_news(self, *args):
459 url = ('http://newsapi.org/v2/top-headlines?'
460 'country=ph&category=health&'
461 'apiKey=0a2a06f5a843426ca8384f89111bfe99')
462 req = UrlRequest(url, self._got_news, on_failure=self.fail, on_error=self.fail)
463
464 def _got_news(self, req, news):
465 print(news)
466 self.headlines.clear()
467 for content in news['articles']:
468 self.headlines.append((content['title'], content['urlToImage'], content['description']))
469
470 def fail(self, instance, value):
471 print('you loose')
472 print(f'Error: {instance}, {value}')
473
474
475if __name__ == '__main__':
476 from kivy.app import App
477 from kivy.clock import Clock
478 from kivy.lang import Builder
479 from kivy.properties import StringProperty
480 from kivy.uix.screenmanager import Screen
481 from kivy.core.window import Window
482
483 import itertools
484 import pprint
485 from textwrap import dedent
486
487 kv = dedent("""
488 <NewsScreen>:
489 BoxLayout:
490 orientation: 'vertical'
491 Label:
492 size_hint_y: .25
493 text: root.headline
494 text_size: self.size
495 valign: 'center'
496 halign: 'center'
497 shorten: True
498 shorten_from: 'right'
499 font_size: 30
500 padding: 20,20
501 theme_text_color:"ContrastParentBackground"
502 bold: True
503 GridLayout:
504 cols: 2
505 padding: 20
506 AsyncImage:
507 source: root.headline_image
508 anim_delay: .03334 # 15fps, for gif videos
509 nocache: True
510 Label:
511 #padding_x: 30
512 text: root.description
513 text_size: self.size
514 font_size: 25
515 valign: 'center'
516
517 BoxLayout: # This is the root widget
518 orientation: 'vertical'
519 ScreenManager:
520 id: sm
521 NewsScreen:
522 name: 'news'
523 next: 'weather'
524 duration: 30
525 """)
526
527
528 class NewsScreen(Screen):
529 headline = StringProperty('')
530 headline_image = StringProperty('')
531 description = StringProperty('')
532
533 def __init__(self, **kwargs):
534 super().__init__(**kwargs)
535 self.app = App.get_running_app()
536 self.story = itertools.cycle(self.app.news.headlines)
537 Clock.schedule_once(self.initial_news, 10)
538 self.refresh = Clock.schedule_interval(self.news_next, 15)
539
540 def initial_news(self, *args):
541 self.headline = self.app.news.headlines[0][0] if self.app.news.headlines[0][0] else 'junk'
542 self.headline_image = self.app.news.headlines[0][1] if self.app.news.headlines[0][1] else 'junk'
543 self.description = self.app.news.headlines[0][2] if self.app.news.headlines[0][2] else 'No Description'
544 print(self.headline)
545
546 def news_next(self, *args):
547 n = next(self.story)
548 self.headline = n[0]
549 self.headline_image = n[1] if n[1] is not None else ''
550 self.description = n[2]
551
552 # def on_pre_enter(self, *args):
553 # self.refresh() # start the news refresh schedule
554 #
555 # def on_leave(self, *args):
556 # self.refresh.cancel() # cancel the schedule when we leave the screen
557
558
559 class TestNewsApp(App):
560 news = News()
561
562 def build(self):
563 Window.size = 1500, 303
564 Window.top = 100
565 Window.left = 10
566 return Builder.load_string(kv)
567
568 def on_start(self):
569 self.news.get_news()
570 Clock.schedule_once(self.print_news, 5) # wait for site..
571 print('waiting 5 seconds...')
572
573 def print_news(self, dt):
574 pp = pprint.PrettyPrinter(width=80, compact=True)
575 pp.pprint(self.news.headlines)
576
577
578 TestNewsApp().run()
579------------------------------
580from kivy.event import EventDispatcher
581from kivy.network.urlrequest import UrlRequest
582from kivy.properties import ListProperty
583
584
585class News(EventDispatcher):
586 headlines = ListProperty([('No Internet Connection', 'sad.png', 'No news is good news!')])
587
588 def get_news(self, *args):
589 url = ('http://newsapi.org/v2/top-headlines?'
590 'country=ph&category=health&'
591 'apiKey=0a2a06f5a843426ca8384f89111bfe99')
592 req = UrlRequest(url, self._got_news, on_failure=self.fail, on_error=self.fail)
593
594 def _got_news(self, req, news):
595 print(news)
596 self.headlines.clear()
597 for content in news['articles']:
598 self.headlines.append((content['title'], content['urlToImage'], content['description']))
599
600 def fail(self, instance, value):
601 print('you loose')
602 print(f'Error: {instance}, {value}')
603
604
605if __name__ == '__main__':
606 from kivy.app import App
607 from kivy.clock import Clock
608 from kivy.lang import Builder
609 from kivy.properties import StringProperty
610 from kivy.uix.screenmanager import Screen
611 from kivy.core.window import Window
612
613 import itertools
614 import pprint
615 from textwrap import dedent
616
617 kv = dedent("""
618 <NewsScreen>:
619 BoxLayout:
620 orientation: 'vertical'
621 Label:
622 size_hint_y: .25
623 text: root.headline
624 text_size: self.size
625 valign: 'center'
626 halign: 'center'
627 shorten: True
628 shorten_from: 'right'
629 font_size: 30
630 padding: 20,20
631 theme_text_color:"ContrastParentBackground"
632 bold: True
633 GridLayout:
634 cols: 2
635 padding: 20
636 AsyncImage:
637 source: root.headline_image
638 anim_delay: .03334 # 15fps, for gif videos
639 nocache: True
640 Label:
641 #padding_x: 30
642 text: root.description
643 text_size: self.size
644 font_size: 25
645 valign: 'center'
646
647 BoxLayout: # This is the root widget
648 orientation: 'vertical'
649 ScreenManager:
650 id: sm
651 NewsScreen:
652 name: 'news'
653 next: 'weather'
654 duration: 30
655 """)
656
657
658 class NewsScreen(Screen):
659 headline = StringProperty('')
660 headline_image = StringProperty('')
661 description = StringProperty('')
662
663 def __init__(self, **kwargs):
664 super().__init__(**kwargs)
665 self.app = App.get_running_app()
666 self.story = itertools.cycle(self.app.news.headlines)
667 Clock.schedule_once(self.initial_news, 10)
668 self.refresh = Clock.schedule_interval(self.news_next, 15)
669
670 def initial_news(self, *args):
671 self.headline = self.app.news.headlines[0][0] if self.app.news.headlines[0][0] else 'junk'
672 self.headline_image = self.app.news.headlines[0][1] if self.app.news.headlines[0][1] else 'junk'
673 self.description = self.app.news.headlines[0][2] if self.app.news.headlines[0][2] else 'No Description'
674 print(self.headline)
675
676 def news_next(self, *args):
677 n = next(self.story)
678 self.headline = n[0]
679 self.headline_image = n[1] if n[1] is not None else ''
680 self.description = n[2]
681
682 # def on_pre_enter(self, *args):
683 # self.refresh() # start the news refresh schedule
684 #
685 # def on_leave(self, *args):
686 # self.refresh.cancel() # cancel the schedule when we leave the screen
687
688
689 class TestNewsApp(App):
690 news = News()
691
692 def build(self):
693 Window.size = 1500, 303
694 Window.top = 100
695 Window.left = 10
696 return Builder.load_string(kv)
697
698 def on_start(self):
699 self.news.get_news()
700 Clock.schedule_once(self.print_news, 5) # wait for site..
701 print('waiting 5 seconds...')
702
703 def print_news(self, dt):
704 pp = pprint.PrettyPrinter(width=80, compact=True)
705 pp.pprint(self.news.headlines)
706
707
708 TestNewsApp().run()
709------------------------------------
710Screen:
711 ScreenManager:
712 id:scr_mngr
713 MainMenuScreen:
714 name:"menu"
715 InputScreen:
716 name:"input"
717 RestingHeartRateScreen:
718 name:"heartrate"
719 ResultObeseScreen:
720 name:"obese"
721 ResultUnderweightScreen:
722 name:"underweight"
723 ResultOverweightScreen:
724 name:"overweight"
725 ResultNormalScreen:
726 name:"normal"
727 LocationSearchScreen:
728 name:"locsearch"
729 LocationResultScreen:
730 name:"locresult"
731 HistoryScreen:
732 name:"history"
733
734<MainMenuScreen>
735# MDBoxLayout:
736# ScreenManager:
737# Screen:
738 MDBoxLayout:
739 orientation:'vertical'
740 # MDToolbar:
741 # title:'MD 24/7'
742 # elevation:10
743
744 NewsLayout:
745 id: nl # and in id to access the instance
746 pos_hint:{'center_y':0.3}
747 orientation:'vertical'
748
749 MDBottomAppBar:
750 MDToolbar:
751 icon: "account"
752 type: "bottom"
753 elevation_normal: 8
754 on_action_button:
755 root.manager.current='input'
756 root.manager.transition.direction = "right"
757 left_action_items:[["history",lambda x: app.history_screen("history")]]
758 right_action_items:[["google-earth",lambda x: app.location_screen("locsearch")]]
759
760<NewsLayout>:
761 orientation: 'vertical'
762 padding: 20
763 Label:
764 text: root.title
765 text_size: self.size
766 halign: 'center'
767 valign: 'center'
768 color : 0,0,0,1
769 size_hint_y: None
770 height: 50
771 bold: True
772 AsyncImage:
773 source: root.picture
774 size_hint_y: .8
775 Label:
776 text_size: self.size
777 halign: 'center'
778 text: root.description
779 color: 0,0,0,1
780 size_hint_y: .2
781
782<InputScreen>
783 on_pre_enter: app.clear_inputs()
784 id:information
785 BoxLayout:
786 orientation: 'vertical'
787 MDToolbar:
788 title:'Input Details'
789 elevation:10
790 left_action_items:[["backspace",lambda x:app.back_screen("menu")]]
791 right_action_items:[["head-question",lambda x:app.info2dialog()]]
792
793 Widget:
794 MDTextField:
795 id:fname
796 hint_text: "Full name"
797 icon_right:"account"
798 pos_hint: {'center_x': 0.5}
799 size_hint_x: None
800 width: '250dp'
801 helper_text:"Please enter your Registered Name"
802 helper_text_mode:"persistent"
803 Widget:
804 height: 35
805
806 MDTextField:
807 id:height
808 input_filter:'int'
809 hint_text: "Height"
810 icon_right:"human-male-height"
811 pos_hint: {'center_x': 0.5}
812 size_hint_x: None
813 width: '250dp'
814 helper_text:"Must be in centimeters"
815 helper_text_mode:"persistent"
816 Widget:
817 height:35
818
819 MDTextField:
820 id:weight
821 hint_text: "Weight"
822 input_filter:'int'
823 icon_right:"weight-kilogram"
824 pos_hint: {'center_x': 0.5}
825 size_hint_x: None
826 width: '250dp'
827 helper_text:"Must be in Kilogram"
828 helper_text_mode:"persistent"
829 Widget:
830 height:35
831
832 MDTextField:
833 id:age
834 hint_text: "Age"
835 input_filter:'int'
836 icon_right:"cake"
837 pos_hint: {'center_x': 0.5}
838 size_hint_x: None
839 width: '250dp'
840 helper_text:"please enter your age"
841 helper_text_mode:"persistent"
842 Widget:
843 height: 35
844
845 MDTextField:
846 id:heartrate
847 hint_text: "Heartrate"
848 input_filter:'int'
849 icon_right:"heart-pulse"
850 pos_hint: {'center_x': 0.5}
851 size_hint_x: None
852 width: '250dp'
853 helper_text:"Count the beat on your palm for 60 seconds"
854 helper_text_mode:"persistent"
855 Widget:
856 size_hint_y: None
857
858 MDScreen:
859 MDRectangleFlatButton:
860 mode: "rectangle"
861 text: '[color=#000000]Confirm'
862 pos_hint: {'center_x':0.5, 'center_y':0.8}
863 on_press :
864 app.show_data()
865
866 Widget:
867 size_hint_x: None
868
869<ResultObeseScreen>
870 BoxLayout:
871 orientation: 'vertical'
872 MDToolbar:
873 title:'Result: OBESE'
874 elevation:10
875 right_action_items:[["head-question",lambda x:app.result_dialog()]]
876 Widget:
877
878 MDLabel:
879 text: " People with obesity have increased risk of cardiovascular disease,type 2 diabetes, high blood pressure, and other health conditions. Waist-to-hip ratio, waist-to-height ratio, and body fat percentage measurements can provide a more complete picture of any health risks. A person should consult with their healthcare provider and consider making lifestyle changes through healthy eating and fitness to improve their health indicators. \n TIPS: \n *Change your diet. \n *Consider adding physical activity \n *Medication \n *Consume less “bad” fat and more “good” fat. \n *Consume less processed and sugary foods. \n *Eat more servings of vegetables and fruits \n *Eat plenty of dietary fiber. \n *limit your vices (drinking,smoking,etc)"
880 halign: "left"
881
882 Widget:
883
884 MDScreen:
885 MDRectangleFlatButton:
886 mode: "rectangle"
887 text: '[color=#000000]Main Menu'
888 pos_hint: {'center_x':0.3, 'center_y':0.8}
889 on_press : root.manager.current='menu'
890 MDRectangleFlatButton:
891 mode: "rectangle"
892 text: '[color=#000000]Check Heartbeat Results'
893 pos_hint: {'center_x':0.7, 'center_y':0.8}
894 on_press : app.hrdialog()
895
896
897<ResultNormalScreen>
898 BoxLayout:
899 orientation: 'vertical'
900 MDToolbar:
901 title:'Result: NORMAL WEIGHT'
902 elevation:10
903 right_action_items:[["head-question",lambda x:app.result_dialog()]]
904 Widget:
905
906 MDLabel:
907 text :" Maintaining a healthy weight may lower the risk of developing certain health conditions, including cardiovascular disease and type 2 diabetes. Waist-to-hip ratio, waist-to-height ratio, and body fat percentage measurements can provide a more complete picture of any health risks. \n TIPS: \n *Limit what you eat \n *exercise \n *sleep 7-8 hours a day \n *maintain a consistent sleeping routine \n *consider eating more healthy foods \n *limit your vices (drinking,smoking,etc)"
908 halign: "left"
909
910 Widget:
911
912 MDScreen:
913 MDRectangleFlatButton:
914 mode: "rectangle"
915 text: '[color=#000000]Main Menu'
916 pos_hint: {'center_x':0.3, 'center_y':0.8}
917 on_press : root.manager.current='menu'
918 MDRectangleFlatButton:
919 mode: "rectangle"
920 text: '[color=#000000]Check Heartbeat Results'
921 pos_hint: {'center_x':0.7, 'center_y':0.8}
922 on_press : app.hrdialog()
923
924<ResultOverweightScreen>
925 BoxLayout:
926 orientation: 'vertical'
927 MDToolbar:
928 title:'Result: OVERWEIGHT'
929 elevation:10
930 right_action_items:[["head-question",lambda x:app.result_dialog()]]
931 Widget:
932
933 MDLabel:
934 text: " Being overweight may increase the risk of certain health conditions, including cardiovascular disease, high blood pressure, and type 2 diabetes. Waist-to-hip ratio, waist-to-height ratio, and body fat percentage measurements can provide a more complete picture of any health risks. A person should consult with their healthcare provider and consider making lifestyle changes through healthy eating and fitness to improve their health indicators.Being overweight or fat is having more body fat than is optimally healthy \n TIPS: \n *Eat a high protein breakfast. \n *Avoid sugary drinks and fruit juice \n *Drink water before meals. \n *Choose weight-loss-friendly foods. \n *Eat soluble fiber. \n *Drink coffee or tea. \n *Base your diet on whole foods. \n *Eat slowly. \n *limit your vices (drinking,smoking,etc)"
935 halign: "left"
936
937 Widget:
938
939 MDScreen:
940 MDRectangleFlatButton:
941 mode: "rectangle"
942 text: '[color=#000000]Main Menu'
943 pos_hint: {'center_x':0.3, 'center_y':0.8}
944 on_press : root.manager.current='menu'
945 MDRectangleFlatButton:
946 mode: "rectangle"
947 text: '[color=#000000]Check Heartbeat Results'
948 pos_hint: {'center_x':0.7, 'center_y':0.8}
949 on_press : app.hrdialog()
950
951<ResultUnderweightScreen>
952 BoxLayout:
953 orientation: 'vertical'
954 MDToolbar:
955 title:'Result: UNDERWEIGHT'
956 elevation:10
957 right_action_items:[["head-question",lambda x:app.result_dialog()]]
958 Widget:
959
960 MDLabel:
961 text: " Being underweight may pose certain health risks, including nutrient deficiencies and hormonal changes. Waist-to-hip ratio, waist-to-height ratio, and body fat percentage measurements can provide a more complete picture of any health risks. A person should consult with their healthcare provider and consider making lifestyle changes through healthy eating and fitness to improve their health indicators.Being underweight can cause health problems. An underweight person is a person whose body weight is considered too low to be healthy /n TIPS: /n *eat more frequently /n *choose nutrient-rich foods /n *watch what you eat and drink /n *exercise /n *limit your vices (drinking,smoking,etc)"
962 halign: "left"
963
964 Widget:
965
966 MDScreen:
967 MDRectangleFlatButton:
968 mode: "rectangle"
969 text: '[color=#000000]Main Menu'
970 pos_hint: {'center_x':0.3, 'center_y':0.8}
971 on_press : root.manager.current='menu'
972 MDRectangleFlatButton:
973 mode: "rectangle"
974 text: '[color=#000000]Check Heartbeat Results'
975 pos_hint: {'center_x':0.7, 'center_y':0.8}
976 on_press : app.hrdialog()
977
978<LocationSearchScreen>
979 BoxLayout:
980 orientation: 'vertical'
981 MDToolbar:
982 title:'Hospital Searcher'
983 elevation:10
984 left_action_items:[["backspace",lambda x:app.back_screen6("menu")]]
985 right_action_items:[["head-question",lambda x:app.info1_dialog()]]
986
987 ScrollView:
988 MDList:
989 id: rlist
990<RecordLine>:
991 adaptive_height: True
992 OneLineListItem:
993 text: root.text
994 on_release: app.showinfo(root.parent.parent.panel_cls.text, self.text)
995
996<InformationDialog>:
997 title: "Details:"
998
999<OneLineAvatarIconListItem>: # The list widget
1000 id: icnlst
1001 IconLeftWidget:
1002 icon: "clipboard"
1003
1004<HistoryScreen>
1005 MDLabel:
1006 text:'COMING SOON'
1007 halign:'center'
1008
1009 MDToolbar:
1010 id: toolbar
1011 pos_hint: {"top": 1}
1012 elevation: 6
1013 title: "Check History"
1014 left_action_items:[["backspace",lambda x:app.back_screen("menu")]]