Advertisement
peachyontop

hthththth

Apr 4th, 2025
10
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.64 KB | None | 0 0
  1. import requests
  2. from kivy.metrics import dp
  3. from kivy.clock import Clock
  4. from kivy.lang import Builder
  5. from kivy.utils import platform
  6. from kivymd.app import MDApp
  7. from kivymd.uix.screen import MDScreen
  8. from kivymd.uix.boxlayout import MDBoxLayout
  9. from kivymd.uix.label import MDLabel
  10. from kivymd.uix.toolbar import MDTopAppBar
  11. from kivymd.uix.card import MDCard
  12. from threading import Thread
  13. from datetime import datetime
  14. from dateutil import parser
  15.  
  16. Builder.load_string('''
  17. <WeatherScreen>:
  18. MDBoxLayout:
  19. orientation: 'vertical'
  20.  
  21. MDTopAppBar:
  22. title: "Weather App"
  23. elevation: 4
  24. left_action_items: [['arrow-left', lambda x: app.go_back()]]
  25. right_action_items: [['refresh', lambda x: root.refresh()]]
  26.  
  27. ScrollView:
  28. MDBoxLayout:
  29. orientation: 'vertical'
  30. spacing: dp(20)
  31. padding: dp(20)
  32. size_hint_y: None
  33. height: self.minimum_height
  34.  
  35. MDCard:
  36. id: main_card
  37. orientation: 'vertical'
  38. size_hint_y: None
  39. height: dp(200)
  40. padding: dp(20)
  41. spacing: dp(10)
  42. elevation: 2
  43.  
  44. MDBoxLayout:
  45. spacing: dp(20)
  46. size_hint_y: None
  47. height: dp(80)
  48. pos_hint: {'center_y': 0.5}
  49.  
  50. MDLabel:
  51. id: weather_icon
  52. text: "⛅"
  53. font_size: dp(48)
  54. halign: 'center'
  55. size_hint_x: None
  56. width: dp(80)
  57.  
  58. MDLabel:
  59. id: temp_label
  60. text: "--°C"
  61. font_style: 'H2'
  62. bold: True
  63. halign: 'center'
  64.  
  65. MDLabel:
  66. id: location_label
  67. text: "Locating..."
  68. halign: 'center'
  69. font_style: 'Subtitle1'
  70.  
  71. MDLabel:
  72. id: update_label
  73. text: "Last update: --"
  74. halign: 'center'
  75. font_style: 'Caption'
  76.  
  77. MDCard:
  78. id: details_card
  79. size_hint_y: None
  80. height: dp(120)
  81. padding: dp(20)
  82. elevation: 2
  83.  
  84. MDGridLayout:
  85. cols: 3
  86. spacing: dp(20)
  87.  
  88. DetailItem:
  89. icon: "💨"
  90. value: "-- km/h"
  91. label: "Wind"
  92.  
  93. DetailItem:
  94. icon: "💧"
  95. value: "--%"
  96. label: "Humidity"
  97.  
  98. DetailItem:
  99. icon: "đŸŒ§ī¸"
  100. value: "-- mm"
  101. label: "Rain"
  102.  
  103. MDCard:
  104. id: forecast_card
  105. size_hint_y: None
  106. height: dp(150)
  107. padding: dp(20)
  108. elevation: 2
  109.  
  110. MDLabel:
  111. text: "Hourly Forecast"
  112. font_style: 'H6'
  113. bold: True
  114.  
  115. ScrollView:
  116. MDBoxLayout:
  117. id: forecast_container
  118. orientation: 'horizontal'
  119. spacing: dp(15)
  120. size_hint_x: None
  121. width: self.minimum_width
  122.  
  123. <DetailItem@MDBoxLayout>:
  124. orientation: 'vertical'
  125. spacing: dp(5)
  126. size_hint_x: None
  127. width: dp(100)
  128.  
  129. MDLabel:
  130. text: root.icon
  131. font_size: dp(24)
  132. halign: 'center'
  133.  
  134. MDLabel:
  135. text: root.value
  136. font_style: 'H6'
  137. halign: 'center'
  138. bold: True
  139.  
  140. MDLabel:
  141. text: root.label
  142. font_style: 'Caption'
  143. halign: 'center'
  144. ''')
  145.  
  146. class WeatherScreen(MDScreen):
  147. def on_enter(self):
  148. self.refresh()
  149.  
  150. def refresh(self):
  151. self.ids.temp_label.text = "--°C"
  152. self.ids.location_label.text = "Locating..."
  153. self.ids.update_label.text = "Updating..."
  154. Thread(target=self.fetch_weather, daemon=True).start()
  155.  
  156. def fetch_weather(self):
  157. try:
  158. # Get sample data
  159. lat, lon = 48.1351, 11.5820 # Munich coordinates
  160. response = requests.get(
  161. f"https://api.open-meteo.com/v1/forecast?latitude={lat}&longitude={lon}"
  162. "&current_weather=true&hourly=temperature_2m,precipitation_probability"
  163. )
  164. data = response.json()
  165.  
  166. current = data.get('current_weather', {})
  167. hourly = data.get('hourly', {}).get('temperature_2m', [])[:12]
  168.  
  169. Clock.schedule_once(lambda dt: self.update_ui(
  170. temp=current.get('temperature', '--'),
  171. wind=current.get('windspeed', '--'),
  172. time=current.get('time', ''),
  173. forecast=hourly
  174. ))
  175. except Exception as e:
  176. Clock.schedule_once(lambda dt: self.show_error(str(e)))
  177.  
  178. def update_ui(self, temp, wind, time, forecast):
  179. # Main card
  180. self.ids.temp_label.text = f"{temp}°C"
  181. self.ids.weather_icon.text = self.get_weather_icon()
  182.  
  183. # Location and time
  184. self.ids.location_label.text = "Munich, DE"
  185. try:
  186. dt = parser.isoparse(time).strftime("%H:%M")
  187. self.ids.update_label.text = f"Updated: {dt}"
  188. except:
  189. self.ids.update_label.text = "Updated: Now"
  190.  
  191. # Details
  192. details = self.ids.details_card.children[0].children
  193. details[0].value = f"{wind} km/h"
  194. details[1].value = "65%"
  195. details[2].value = "0 mm"
  196.  
  197. # Forecast
  198. container = self.ids.forecast_container
  199. container.clear_widgets()
  200. for temp in forecast[:6]: # Show 6 items for mobile
  201. container.add_widget(ForecastItem(temp=temp))
  202.  
  203. def get_weather_icon(self):
  204. icons = ["â˜€ī¸", "⛅", "đŸŒ§ī¸", "â„ī¸", "đŸŒŠī¸"]
  205. return icons[datetime.now().hour % 5]
  206.  
  207. def show_error(self, message):
  208. self.ids.temp_label.text = "Error"
  209. self.ids.location_label.text = "Check connection"
  210. self.ids.update_label.text = message[:30]
  211.  
  212. class ForecastItem(MDBoxLayout):
  213. def __init__(self, temp, **kwargs):
  214. super().__init__(**kwargs)
  215. self.orientation = 'vertical'
  216. self.spacing = dp(5)
  217. self.size_hint_x = None
  218. self.width = dp(80)
  219.  
  220. self.add_widget(MDLabel(
  221. text=f"{temp}°",
  222. font_style='H6',
  223. halign='center'
  224. ))
  225. self.add_widget(MDLabel(
  226. text=f"{datetime.now().hour % 24:02d}:00",
  227. font_style='Caption',
  228. halign='center'
  229. ))
  230.  
  231. class WeatherApp(MDApp):
  232. def build(self):
  233. self.theme_cls.theme_style = "Dark"
  234. self.theme_cls.primary_palette = "Blue"
  235. return WeatherScreen()
  236.  
  237. def go_back(self):
  238. self.stop()
  239.  
  240. if __name__ == '__main__':
  241. WeatherApp().run()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement