## netglance2.py
## for Python3. Python2 version at https://pastebin.com/uxiK6Z99
## November 2019 by Marco Nassenstein https://nassenstein.com
import gi
gi.require_version(\'Gtk\', \'3.0\')
from gi.repository import Gtk, Gio, GdkPixbuf
from threading import Timer,Thread,Event
import urllib.request
#import urllib2 # Python2
import argparse
from datetime import datetime
## Kommandozeilenparameter
parser = argparse.ArgumentParser()
parser.add_argument("-u", "--url", help="URL to an online JPG or PNG file", default="http://www.haemmern.de/live/bild.jpg")
parser.add_argument("-iw", "--width", help="Image width", default="640")
parser.add_argument("-ih", "--height", help="Image height, 0 to keep aspect ratio", default="0")
parser.add_argument("-x", "--posx", help="Horizontal position of the image on desktop in pixel", default="20")
parser.add_argument("-y", "--posy", help="Vertical position of the image on desktop in pixel", default="20")
parser.add_argument("-t", "--time", help="Refresh duration in seconds, 0 for no refresh", default="60")
args = parser.parse_args()
url = args.url
dimx = int(args.width)
dimy = int(args.height)
if dimy == 0:
# Aspect Ratio soll eingehalten werden
ratio = True
dimy = dimx
else:
ratio = False
posx = int(args.posx)
posy = int(args.posy)
seconds = int(args.time)
# URL Host als Titel des Fensters
titel = url.split("//")[-1].split("/")[0]
titel = titel.replace("www.","")
savefile = titel
# Refresh dahinter angeben
if seconds != 0:
titel = titel+" ("+str(seconds)+"s)"
##### THREADING Subroutinen
class perpetualTimer():
def __init__(self,t,hFunction):
self.t=t
self.hFunction = hFunction
self.thread = Timer(self.t,self.handle_function)
def handle_function(self):
self.hFunction()
self.thread = Timer(self.t,self.handle_function)
self.thread.start()
def start(self):
self.thread.start()
def cancel(self):
self.thread.cancel()
##### THREADING
class Handler:
def on_Fenster_destroy(self, *args):
if seconds != 0:
t.cancel()
Gtk.main_quit()
def on_Eventbox_button_press_event(self,widget,event):
if event.button == 3: ## Rechte Maustaste, Datei-Speichern-Dialog
print ("Save Image...")
dialog = Gtk.FileChooserDialog("Save Image",
None,
Gtk.FileChooserAction.SAVE,
(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
Gtk.STOCK_SAVE, Gtk.ResponseType.OK))
dialog.set_default_size(-1,-1)
#dialog.resize(500,400)
dialog.set_transient_for(x.builder.get_object("Fenster"))
zeit = datetime.now().strftime(\'%Y-%m-%d %H:%M\')
savfile = savefile + " " + zeit
dialog.set_current_name(savfile+".jpg")
response = dialog.run()
if response == Gtk.ResponseType.OK:
bilddatei = dialog.get_filename()
if not bilddatei.endswith(".jpg") and not bilddatei.endswith(".png"):
bilddatei += ".jpg"
bild = x.builder.get_object("Bild").get_pixbuf()
if bilddatei.endswith(".jpg"):
bild.savev(bilddatei, "jpeg", ["quality"], ["100"])
elif bilddatei.endswith(".png"):
bild.savev(bilddatei, "png", "", "")
print("...saved to "+bilddatei)
elif response == Gtk.ResponseType.CANCEL:
print("...cancel")
dialog.destroy()
else: ## Irgend eine andere Taste: Manueller Refresh!
print("Manual"),
lauf()
class Netglance:
def __init__(self):
self.builder=Gtk.Builder()
#self.builder.add_from_file("/home/nassenstein/Python/Netglance2.glade")
self.builder.add_from_string("<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?>\\n<!-- Generated with glade 3.22.1 -->\\n<interface>\\n <requires lib=\\"gtk+\\" version=\\"3.20\\"/>\\n <object class=\\"GtkWindow\\" id=\\"Fenster\\">\\n <property name=\\"can_focus\\">False</property>\\n <property name=\\"title\\" translatable=\\"yes\\">Netglance</property>\\n <property name=\\"resizable\\">False</property>\\n <property name=\\"icon_name\\">image-x-generic</property>\\n <signal name=\\"destroy\\" handler=\\"on_Fenster_destroy\\" swapped=\\"no\\"/>\\n <child type=\\"titlebar\\">\\n <placeholder/>\\n </child>\\n <child>\\n <object class=\\"GtkBox\\" id=\\"Kiste\\">\\n <property name=\\"visible\\">True</property>\\n <property name=\\"can_focus\\">False</property>\\n <property name=\\"orientation\\">vertical</property>\\n <child>\\n <object class=\\"GtkEventBox\\" id=\\"Eventbox\\">\\n <property name=\\"visible\\">True</property>\\n <property name=\\"can_focus\\">False</property>\\n <signal name=\\"button-press-event\\" handler=\\"on_Eventbox_button_press_event\\" swapped=\\"no\\"/>\\n <child>\\n <object class=\\"GtkImage\\" id=\\"Bild\\">\\n <property name=\\"visible\\">True</property>\\n <property name=\\"can_focus\\">False</property>\\n <property name=\\"stock\\">gtk-missing-image</property>\\n </object>\\n </child>\\n </object>\\n <packing>\\n <property name=\\"expand\\">True</property>\\n <property name=\\"fill\\">True</property>\\n <property name=\\"position\\">0</property>\\n </packing>\\n </child>\\n </object>\\n </child>\\n </object>\\n</interface>\\n")
self.builder.connect_signals(Handler())
window=self.builder.get_object("Fenster")
# Fenster positionieren
window.move(posx,posy)
window.set_title(titel)
window.show_all()
print("Startup "+url+" Refresh after "+str(seconds)+" seconds")
#response = urllib2.urlopen(url) # Python2
response = urllib.request.urlopen(url)
input_stream = Gio.MemoryInputStream.new_from_data(response.read(), None)
pixbuf = GdkPixbuf.Pixbuf.new_from_stream_at_scale(input_stream, dimx, dimy, ratio, None)
self.builder.get_object("Bild").set_from_pixbuf(pixbuf)
def main(self):
Gtk.main()
x=Netglance()
def lauf():
print("Refresh")
response = urllib.request.urlopen(url)
#response = urllib2.urlopen(url) # Python2
input_stream = Gio.MemoryInputStream.new_from_data(response.read(), None)
pixbuf = GdkPixbuf.Pixbuf.new_from_stream_at_scale(input_stream, dimx, dimy, ratio, None)
x.builder.get_object("Bild").set_from_pixbuf(pixbuf)
if seconds != 0:
t=perpetualTimer(seconds,lauf)
t.start()
x.main()