#!/usr/bin/env python # -*- coding: utf-8 -*- # Copyright 2008 Gary C. Martin # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # Activity web site: http://wiki.laptop.org/go/Moon # Created: Febuary 2008 # Author: gary@garycmartin.com # Home page: http://www.garycmartin.com/ import os import sys import time import math import gi from gi.repository import Gtk from gi.repository import Gdk from gi.repository import GdkPixbuf from gi.repository import GObject from sugar3.activity import activity from sugar3.graphics.toolbarbox import ToolbarBox from sugar3.activity.widgets import StopButton from sugar3.activity.widgets import ActivityToolbarButton from gettext import gettext as _ import MoonGlobals as MG from Moonwidgets import * IMAGE_SIZE = 726 HALF_SIZE = IMAGE_SIZE / 2 SECONDS_PER_DAY = 86400.0 format = "%Y-%m-%d %H:%M" try: import json json.dumps except (ImportError, AttributeError): import simplejson as json class MoonActivity(activity.Activity): def __init__(self, handle): activity.Activity.__init__(self, handle, True) self.set_title(_("Luna")) self.modify_bg(Gtk.StateType.NORMAL, MG.BACKGROUND) self.main_view = None self.mooncalendar = None self.info_panel = None self.info = None self.luna_hoy = None self.label_emisferio = None self.aspectframe = None self.bufferinfo = None self.activity_state = {} self.max_participants = 1 self.set_layout() self.show_all() self.realize() self.maximize() self.connect("delete_event", self.delete_event) self.luna_hoy.connect("draw", self.repaint) self.actualizador = GObject.timeout_add(1000, self.handle) def set_layout(self): anio, mes, fecha, hora = MG.get_date_time_now() self.luna_hoy = CalendarButton(anio, mes, fecha, hora) self.mooncalendar = MoonCalendar() self.aspectframe = Gtk.AspectFrame() self.aspectframe.modify_bg(Gtk.StateType.NORMAL, MG.BACKGROUND) self.aspectframe.add(self.luna_hoy) cajabase = Gtk.VBox() self.main_view = Gtk.HBox() cajabase.pack_end(self.main_view, True, True, 5) toolbox = ToolbarBox() activity_button = ActivityToolbarButton(self) activity_button.show() toolbox.toolbar.insert(activity_button, 0) boton = Gtk.ToggleToolButton() pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size( os.path.join(MG.ICONOS,'grid-ico.svg'), 32, 32) imagen = Gtk.Image() imagen.set_from_pixbuf(pixbuf) boton.set_icon_widget(imagen) imagen.show() boton.show() toolbox.toolbar.insert(boton, -1) boton.connect("clicked", self.toggle_grid_clicked) boton.modify_bg(Gtk.StateType.NORMAL, MG.BACKGROUND) boton = Gtk.ToggleToolButton() pixbuf= GdkPixbuf.Pixbuf.new_from_file_at_size( os.path.join(MG.ICONOS,'hemi-ico.svg'), 32, 32) imagen = Gtk.Image() imagen.set_from_pixbuf(pixbuf) boton.set_icon_widget(imagen) imagen.show() boton.show() toolbox.toolbar.insert(boton, -1) boton.connect("clicked", self.toggle_hemisphere_clicked) boton.modify_bg(Gtk.StateType.NORMAL, MG.BACKGROUND) boton = Gtk.ToggleToolButton() pixbuf= GdkPixbuf.Pixbuf.new_from_file_at_size( os.path.join(MG.ICONOS,'calendario-ico.svg'), 32, 32) imagen = Gtk.Image() imagen.set_from_pixbuf(pixbuf) boton.set_icon_widget(imagen) imagen.show() boton.show() toolbox.toolbar.insert(boton, -1) boton.connect("clicked", self.switch_calendar_luna) boton.modify_bg(Gtk.StateType.NORMAL, MG.BACKGROUND) self.label_emisferio = Gtk.Label() item = Gtk.ToolItem() item.add(self.label_emisferio) toolbox.toolbar.insert(item, -1) self.label_emisferio.modify_bg(Gtk.StateType.NORMAL, MG.BACKGROUND) self.label_emisferio.modify_fg(Gtk.StateType.NORMAL, MG.FOREGROUND) self.label_emisferio.show() separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_size_request(0, -1) separator.set_expand(True) toolbox.toolbar.insert(separator, -1) toolbox.toolbar.insert(StopButton(self), -1) self.set_toolbar_box(toolbox) toolbox.show_all() info_scroll = Gtk.ScrolledWindow() info_scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) self.info_panel = Gtk.VBox() self.info = Gtk.TextView() self.info.set_property("sensitive", False) self.info.set_border_window_size(Gtk.TextWindowType.TOP, 10) self.info.set_border_window_size(Gtk.TextWindowType.LEFT, 10) self.info.set_border_window_size(Gtk.TextWindowType.RIGHT, 10) self.info.set_border_window_size(Gtk.TextWindowType.BOTTOM, 10) self.info_panel.pack_start(self.info, False, False, 0) info_scroll.add_with_viewport(self.info_panel) event = Gtk.EventBox() event.modify_bg(Gtk.StateType.NORMAL, MG.BACKGROUND) event.add(self.aspectframe) self.main_view.pack_start(info_scroll, False, False, 5) self.main_view.pack_end(event, True, True, 5) self.set_canvas(cajabase) self.bufferinfo = Gtk.TextBuffer() self.info.set_buffer(self.bufferinfo) self.mooncalendar.set_mes(anio, mes, fecha, hora) self.update_text_information_view() self.activity_state['hemisphereView'] = self.luna_hoy.hemisphere_view self.activity_state['showGrid'] = self.luna_hoy.show_grid self.read_and_parse_prefs(os.environ['SUGAR_ACTIVITY_ROOT'] + '/data/defaults') def toggle_grid_clicked(self, widget= None): self.luna_hoy.toggle_grid_clicked() self.mooncalendar.toggle_grid_clicked( widget = None, actualizar = self.mooncalendar in self.aspectframe.get_children()) def toggle_hemisphere_clicked(self, widget= None): self.luna_hoy.toggle_hemisphere_clicked() self.mooncalendar.toggle_hemisphere_clicked( widget = None, actualizar = self.mooncalendar in self.aspectframe.get_children()) def switch_calendar_luna(self, widget): if self.mooncalendar in self.aspectframe.get_children(): self.aspectframe.remove(self.mooncalendar) self.aspectframe.add(self.luna_hoy) self.luna_hoy.show_all() elif self.luna_hoy in self.aspectframe.get_children(): self.aspectframe.remove(self.luna_hoy) self.aspectframe.add(self.mooncalendar) self.mooncalendar.show_all() self.show_all() self.realize() def handle(self): self.update_text_information_view() if self.luna_hoy in self.aspectframe.get_children(): self.luna_hoy.actualizar() return True def repaint(self, widget= None, event= None): rect = self.luna_hoy.get_allocation() self.luna_hoy.repaint(min( [rect.width, rect.height] )) def delete_event(self, widget, event, data=None): sys.exit(0) return False def update_text_information_view(self): anio, mes, fecha, hora = MG.get_date_time_now() hoy = "%s-%s-%s %s" % (anio, mes, fecha, hora) ahora = time.mktime(time.strptime(hoy, MG.format)) self.luna_hoy.data_model.update_moon_calculations(ahora) information = "" information += "%s:\n\n" % (_("Today's Moon Information")) information += "%s\n\n" % (MG.get_date_time()) information += "%s:\n%s\n\n" % (_("Phase"), self.luna_hoy.data_model.moon_phase_name( self.luna_hoy.data_model.phase_of_moon)) information += "%s:\n%.2f (%s)\n\n" % (_("Julian Date"), self.luna_hoy.data_model.julian_date, _("astronomical")) information += "%s:\n" % (_("Age")) dias = self.luna_hoy.data_model.days_old horas = self.luna_hoy.data_model.hours_old minutos = self.luna_hoy.data_model.minutes_old information += "%i %s, %i %s, %i %s.\n\n" % ( dias, _("days"), horas, _("hours"), minutos, _("minutes")) phase = self.luna_hoy.data_model.phase_of_moon * 100 lunation = self.luna_hoy.data_model.lunation information += "%s:\n" % (_("Lunation")) information += "%.2f%s %s %d.\n\n" % ( phase, "%", _("through lunation"), lunation) information += "%s:\n" % (_("Surface Visibility")) information += "%.0f%s (%s)\n\n" % ( self.luna_hoy.data_model.percent_of_full_moon * 100, "%", _("estimated")) #information += _("Surface Visibility:\n%.0f%% (estimated)\n\n") % #(self.luna_hoy.data_model.percent_of_full_moon * 100) selen = {'deg':self.luna_hoy.data_model.selenographic_deg, 'westOrEast':self.luna_hoy.data_model.west_or_east, 'riseOrSet':self.luna_hoy.data_model.rise_or_set} information += _(u"Selenographic Terminator Longitude:\n%(deg).1f\u00b0%(westOrEast)s (%(riseOrSet)s)\n\n") % selen full = {'date':time.strftime(MG.LOCALE_DATE_FORMAT, time.localtime(self.luna_hoy.data_model.next_full_moon_date)), 'days':self.luna_hoy.data_model.days_until_full_moon} information += _("Next Full Moon:\n%(date)s in %(days).0f days\n\n") % full new = {'date':time.strftime(MG.LOCALE_DATE_FORMAT, time.localtime(self.luna_hoy.data_model.next_new_moon_date)), 'days':self.luna_hoy.data_model.days_until_new_moon} information += _("Next New Moon:\n%(date)s in %(days).0f days\n\n") % new lunare = {'date':time.strftime(MG.LOCALE_DATE_FORMAT, time.localtime(self.luna_hoy.data_model.next_lunar_eclipse_date)), 'days':self.luna_hoy.data_model.days_until_lunar_eclipse} information += _("Next Lunar eclipse:\n%(date)s in %(days).0f days\n\n") % lunare solare = {'date':time.strftime(MG.LOCALE_DATE_FORMAT, time.localtime(self.luna_hoy.data_model.next_solar_eclipse_date)), 'days':self.luna_hoy.data_model.days_until_solar_eclipse} information += _("Next Solar eclipse:\n%(date)s in %(days).0f days") % solare self.bufferinfo.set_text(information) self.label_emisferio.set_text( " %s: %s" % ( _("Vista Hemisferio"),_(self.luna_hoy.hemisphere_view)) ) def read_and_parse_prefs(self, file_path): try: read_file = open(file_path, 'r') self.activity_state = json.loads(read_file.read()) if self.activity_state.has_key('hemisphereView'): self.luna_hoy.hemisphere_view = self.activity_state['hemisphereView'] if self.activity_state.has_key('showGrid'): self.luna_hoy.show_grid = self.activity_state['showGrid'] read_file.close() except: pass def read_file(self, file_path): self.read_and_parse_prefs(file_path) def write_file(self, file_path): self.activity_state['hemisphereView'] = self.luna_hoy.hemisphere_view self.activity_state['showGrid'] = self.luna_hoy.show_grid serialised_data = json.dumps(self.activity_state) to_journal = file(file_path, 'w') try: to_journal.write(serialised_data) finally: to_journal.close() to_persistent_fs = file(os.environ['SUGAR_ACTIVITY_ROOT'] + '/data/defaults', 'w') try: to_persistent_fs.write(serialised_data) finally: to_persistent_fs.close()