0

Q1に必要な画像

こんにちは、

私はこれに初心者です(私のためにそのように答えてください)。私の(2番目の)質問を修正した後、すべてのコードは簡単に実行できるはずです。実際、私のマシンでは問題なく動作しますが、おそらくあなたのマシンではまだそうではありません. 誰かが読みやすくするために、どこにでもコメントしようとしました。これは Ubuntu 12.10 マシンで実行されますが、私の問題を解決するために Linux を実行する必要はありません!

解決済み 1. コード レビュー: コードを確認する際に、より適切で適切な方法で物事を要約または実行する方法についての意見をいただければ幸いです。私の残りの質問は、私がすでに取り組んでおくべきだとわかっていることです。しかし、私のコーディングスタイルなどで何か他に見つけたことがあれば、率直に言ってください。すべての良いコメントに賛成票を投じます。

解決済み: 2. 相対アイコン パス: 次の場所:

/home/mh00h/workspace/issindicator/src/International_Space_Station_clip_art.svg

これは、このスクリプトと同じフォルダーへの絶対パスです。私はそれを望んでいません、このスクリプトを誰のマシンでも動作させたいのです。私はこれらを試しました:

$HOME/workspace...
(nothing in front) International_Space_Station_clip_art.svg
./International_Space_Station_clip_art.svg

しかし、それらはうまくいきませんでした。上の画像は私が使用しようとしているものです (はい、リストされている png の代わりに SVG があることは知っています、imgur の制限)。これがドキュメントです。それは「アイコンテーマパス」について語っています...多分それは何とかそれを行うでしょうか?または、おそらくすべてのプログラマーがアイコンを保存することが期待される標準ディレクトリがありますか?

3. 日時関数の集中: 本当に、これを機能させることができて幸運でした。私のやり方は回り道ですが、私が知る限り、うまくいきます。でも、その混乱を修正するためのより良い方法があると確信しています!! スクリプトの下部に、多数の datetime 要素があります。

解決済み: 4. Appindicator3 フック: 毎秒実行するのではなく、メニューが呼び出されたときにのみ GTK を更新したいと考えています。これはここで部分的に回答されましたが、「実現」の実装方法がよくわかりません。(うまくいけば、これはこれを尋ねるのに適切な場所ですか?)

ありがとうございました!

#!/usr/bin/env python
import json, urllib2, time, math, datetime, os, webbrowser
from dateutil import tz

#indicator
from gi.repository import Gtk, GObject
from gi.repository import AppIndicator3 as appindicator

class indicator():
    def __init__(self):

        #######Set this to "False" if IssIndicator should hide it's icon during normal runtime (default = True)
        self.isiconhidden = True
        #

        #create indicator
        self.ind = appindicator.Indicator.new (
                        "issindicator",
                        "/home/mh00h/workspace/issindicator/src/International_Space_Station_clip_art.svg",
                        #"indicator-messages",
                        appindicator.IndicatorCategory.APPLICATION_STATUS)
        if self.isiconhidden == True:
            self.ind.set_status (appindicator.IndicatorStatus.PASSIVE)
        else:
            self.ind.set_status (appindicator.IndicatorStatus.ACTIVE)

        #this is used to keep track of the gtk refresh period
        self.refreshvalue = False

        #dropdown menu
        #current pass menu items
        self.menu = Gtk.Menu()
        self.curpass = Gtk.MenuItem("not refreshed")
        self.curpass.connect("activate", self.checkiss)
        self.menu.append(self.curpass)

        self.curpassdur = Gtk.MenuItem(" ")
        self.menu.append(self.curpassdur)

        self.curpassrise = Gtk.MenuItem(" ")
        self.menu.append(self.curpassrise)

        self.curpassset = Gtk.MenuItem(" ")
        self.menu.append(self.curpassset)

        self.sep1 = Gtk.SeparatorMenuItem()
        self.menu.append(self.sep1)

        #future pass items
        self.futpass = Gtk.MenuItem(" ")
        self.futpass.connect("activate", self.onurl)
        self.menu.append(self.futpass)

        self.sep2 = Gtk.SeparatorMenuItem()
        self.menu.append(self.sep2)

        #Options items

        self.aboutmenu = Gtk.MenuItem("About")
        self.aboutmenu.connect("activate", self.onabout)
        self.menu.append(self.aboutmenu)

        self.quit = Gtk.MenuItem("Quit")
        self.quit.connect("activate", self.quitnow)
        self.menu.append(self.quit)

        self.curpass.show()
        self.sep1.show()
        self.futpass.show()
        self.sep2.show()
        self.aboutmenu.show()
        self.quit.show()
        self.ind.set_menu(self.menu)

        #get iss data at first run
        self.updatecache()
        self.checkiss()

        Gtk.main()


    #functions
    def hideicon(self, w=None):
        self.ind.set_status (appindicator.IndicatorStatus.PASSIVE)

    def showicon(self, w=None):
        self.ind.set_status (appindicator.IndicatorStatus.ACTIVE)

    def quitnow(self, w=None):
        Gtk.main_quit()

    #open browser for more tracking info
    def onurl(self, w=None):
        webbrowser.open("http://www.n2yo.com/passes/")

    def onabout(self,widget):
        widget.set_sensitive(False)
        ad=Gtk.AboutDialog()
        ad.set_name("aboutdialog")
        ad.set_version("0.1")
        ad.set_copyright('Copyrignt (c) 2013 mh00h')
        ad.set_comments('Indicating ISS Zarya')
        ad.set_license(''+
        'This program is free software: you can redistribute it and/or modify it\n'+
        'under the terms of the GNU General Public License as published by the\n'+
        'Free Software Foundation, either version 3 of the License, or (at your option)\n'+
        'any later version.\n\n'+
        'This program is distributed in the hope that it will be useful, but\n'+
        'WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n'+
        'or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\n'+
        'more details.\n\n'+
        'You should have received a copy of the GNU General Public License along with\n'+
        'this program.  If not, see <http://www.gnu.org/licenses/>.')
        ad.set_website('https://launchpad.net/~mh00h/+archive/issindicator')
        ad.set_website_label('ISSIndicator Homepage')
        ad.set_authors(['mh00h <abcd@abcd.com'])
        ad.run()
        ad.destroy()
        widget.set_sensitive(True)

    #how often to run checkiss
    def setrefresh(self, r):
        #this clause is required to keep script from hanging
        if r != self.refreshvalue:
            self.refreshvalue = r
            try:
                self.reftime = GObject.source_remove(True)
            except:
                pass        
            try:
                self.reftime = GObject.timeout_add(r, self.checkiss)
            except:
                pass

    #
    def updatecache(self, w=None):
        #this will show in the menu until the update process completes
        self.passingstatus = 'not updated yet'
        #get ISS data from api
        self.ip = urllib2.urlopen("http://api.exip.org/?call=ip").read()
        self.geoip = json.load(urllib2.urlopen("http://freegeoip.net/json/"+self.ip))
        self.data = json.load(urllib2.urlopen("http://api.open-notify.org/iss/?lat="+str(self.geoip["latitude"])+"&lon="+str(self.geoip["longitude"])+"&alt=280&n=47"))
        self.data = {"message": "success", "request": {"latitude": 45.0, "passes": 3, "altitude": 280, "longitude": -81.0, "datetime": 1361502063}, 
                 "response": [{"duration": 542, "risetime": time.time()+10}, {"duration": 642, "risetime": 1361560774}, {"duration": 593, "risetime": 1361566621}]}


    def checkiss(self, w=None):
        #so as to not overload api servers, this runs as a separate process
        #this updates the timers
        self.n = 0
        self.passingstatus = "ISS Zarya is below the horizon"

        #check if we've gone through cached iss passings and update api if needed
        try:
            #ignore errors in case internet is not accessible
            #have a buffer of 5 passes remaining before updating cache
            #at 2 passes left, stop the program to prevent the rest of the program from throwing codes
            if time.time() > self.data['response'][len(self.data['response'])-5]['risetime']:
                self.updatecache
        except:
            if time.time() > self.data['response'][len(self.data['response'])-2]['risetime']:
                os.system("notify-send 'ISS Indicator tried multiple times to update its satellite cache but has run out of its cached track.' 'This may be due to a bad internet connection. The application will now quit.'")
                Gtk.main_quit()

        #get current time
        current_utc = datetime.datetime.utcnow()
        current_utc = current_utc.replace(tzinfo=tz.gettz('UTC'))

        #iterate over all iss passes
        for k in self.data['response']:
            duration = self.data['response'][self.n]['duration']
            risetime = self.data['response'][self.n]['risetime']
            settime = risetime + duration

            #if this iteration matches with the current time, do...
            if risetime <= time.time() <= settime:
                #make the countdown values for the current pass tick
                #rise time calculations and date conversions to string format
                currisetime_utc = datetime.datetime.utcfromtimestamp(self.data['response'][self.n]['risetime'])
                currisetime_utc = currisetime_utc.replace(tzinfo=tz.gettz('UTC'))
                currisetime_tz = currisetime_utc.astimezone(tz.tzlocal())
                currisetime_tzstr = str("%02d" % (currisetime_tz.hour))+':'+str("%02d" % (currisetime_tz.minute))+':'+str("%02d" % (currisetime_tz.second))
                #set time calculations and durations
                cursettime_utc = datetime.datetime.utcfromtimestamp(self.data['response'][self.n]['risetime']+self.data['response'][self.n]['duration'])
                cursettime_utc = cursettime_utc.replace(tzinfo=tz.gettz('UTC'))
                cursettime_tz = cursettime_utc.astimezone(tz.tzlocal())
                curremainingtimeleft = cursettime_utc - current_utc
                curduration = cursettime_utc - currisetime_utc

                z= curremainingtimeleft.seconds
                zhours = z/60/60
                zminutes = z/60-zhours*60
                zseconds = z-zhours*60*60-zminutes*60
                curremainingtimeleftstr = str(zhours)+':'+str("%02d" % (zminutes))+':'+str("%02d" % (zseconds))

                z= curduration.seconds
                zhours = z/60/60
                zminutes = z/60-zhours*60
                zseconds = z-zhours*60*60-zminutes*60
                curdurationstr = str(zhours)+':'+str("%02d" % (zminutes))+':'+str("%02d" % (zseconds))

                cursettime_tzstr = str("%02d" % (cursettime_tz.hour))+':'+str("%02d" % (cursettime_tz.minute))+':'+str("%02d" % (cursettime_tz.second))

                #since the ISS is presently overhead, show the icon and update GTK menuitems to show timers on the ISS pass
                self.showicon()
                self.passingstatus = "ISS Zarya is above the horizon!"
                self.curpass.get_child().set_text(self.passingstatus)
                self.curpassdur.get_child().set_text("Duration: "+curdurationstr+" ("+curremainingtimeleftstr+" remaining)")
                self.curpassdur.show()
                self.curpassrise.get_child().set_text("Rise time: "+currisetime_tzstr)
                self.curpassrise.show()
                self.curpassset.get_child().set_text("Set time: "+cursettime_tzstr)
                self.curpassset.show()
                break
            else:
                #if this iteration of ISS passes does not match with current time, then increase self.n
                self.n += 1

        #regardless of results show the next pass time
        #if the ISS is overhead, use the next dictionary key for data 
        if self.n != len(self.data['response']):
            nextrisetime_utc = datetime.datetime.utcfromtimestamp(self.data['response'][self.n+1]['risetime'])
        else:
            #if the ISS is not overhead, use the first key in the dictionary
            nextrisetime_utc = datetime.datetime.utcfromtimestamp(self.data['response'][0]['risetime'])
        #calculate the next rise time and make timers
        nextrisetime_utc = nextrisetime_utc.replace(tzinfo=tz.gettz('UTC'))
        nextrisetime_tz = nextrisetime_utc.astimezone(tz.tzlocal())
        remainingtimeleft = nextrisetime_utc - current_utc
        z= remainingtimeleft.seconds
        zhours = z/60/60
        zminutes = z/60-zhours*60
        zseconds = z-zhours*60*60-zminutes*60
        remainingtimeleftstr = str(zhours)+':'+str("%02d" % (zminutes))+':'+str("%02d" % (zseconds))
        nextrisetime_tzstr = str("%02d" % (nextrisetime_tz.hour))+':'+str("%02d" % (nextrisetime_tz.minute))+':'+str("%02d" % (nextrisetime_tz.second))

        #update GTK menuitem
        self.futpass.get_child().set_text("Next Pass: "+nextrisetime_tzstr+" ("+remainingtimeleftstr+")")

        #if the ISS is not above the horizon, refresh GTK only once its time for the icon to be visible 
        if self.passingstatus != "ISS Zarya is above the horizon!":
            self.setrefresh(remainingtimeleft.seconds*1000+100)
            #self.setrefresh(1000)
            self.curpass.get_child().set_text(self.passingstatus)
            self.curpassdur.hide()
            self.curpassrise.hide()
            self.curpassset.hide()
            if self.isiconhidden == True:
                self.hideicon()
        else:
            #otherwise, refresh once a second to show the timers ticking in the menu
            #test if the menu is active instead of always running like in this example
            ####MISSING CODE HERE#####  DONT KNOW HOW TO DO IT, SO JUST SETTING TO 1 SEC
            self.setrefresh(1000)

        #for when setrefresh calls this function
        return True

if __name__ == '__main__':
    issindicator = indicator()
4

0 に答える 0