linux/ubuntu/gnome: wallpaper-wechsler

Code-Stücke können hier veröffentlicht werden.
Antworten
Benutzeravatar
HorstJENS
User
Beiträge: 123
Registriert: Donnerstag 9. Februar 2006, 21:41
Wohnort: Wien, Österreich
Kontaktdaten:

Dieses Skript ändert den Desktop-Hintergrund für gnome (getestet nur mit ubuntu). Trägt man das "wallpaperchanger.py" unter dem Gnome-Menüpunkt "System->Präferenzen->Sitzungen->Startprogramme" ein so wird bei jedem Neustart von Gnome ein neuer Desktop-Hintergrund angezeigt.
Das besondere an dem Skript: Im Gegensatz zu anderen Hintergrund-wechsel-Programmen wird hier nicht verlangt daß alle erwünschten Hintergrundbilder in einem bestimmten Verzeichnis liegen. Stattdessen wird ein neues Verzeichnis namens ".wallpaperchanger" erstellt und dort eine Datei namens "wallpaperchangerconfig.py" erzeugt. Diese Datei ist per Texteditor veränderbar und enthält:
  • Liste von Bilder-Verzeichnissen, welche rekursiv durchsucht werden (inkl. Unterverzeichnisse)
    Liste von Schlüsselwörtern, bei deren Vorkommen ein Bild NICHT verwendet werden soll (zB "Thumbnail"
    Liste von Schlüsselwörtern, bei deren Vorkommen ein Bild gekachelt (gestreckt, gezoomt, skaliert) werden soll.
Vielleicht raffe ich mich noch dazu auf das Skript plattformunabhängig zu machen (KDE, XFC, Apple, Windows...)

Python Skript und fertiges .deb-Paket für Ubuntu stehen hier zum download bereit: http://members.chello.at/horst.jens/files.htm

Python-Skript Quellcode:

Code: Alles auswählen

#!/usr/bin/python
#
# wallpaperchanger.py
#
# A script to change your gnome wallpaper to a random background image
#
# (c) 2004, Davyd Madeley <davyd@madeley.id.au>
# edited 8/2006 by Horst JENS <Horst.Jens@gmx.at>
#
#   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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#


import gconf
import os
import sys
import random
import mimetypes

if os.name != 'posix':
    raise SystemExit, "no-linux Operations System detected. Yuk !"
sys.path.append(os.environ["HOME"])
sys.path.append(os.path.join(os.environ["HOME"], '.wallpaperchanger'))
configdir = os.path.join(os.environ["HOME"], '.wallpaperchanger')
try:
    from wallpaperchangerconfig import * # try to import config file 
    #print "config file imported."
except:
    print 'could not import configfile, so fresh configfile will be created in ~/.wallpaperchanger'
    os.chdir(os.environ["HOME"])
    try:
        os.mkdir('.wallpaperchanger')
    except:
        pass # if you can not create a directory, it may already exist...
    os.chdir('.wallpaperchanger')
    try:
        c = file('wallpaperchangerconfig.py','w')
        c.write('#config file for wallpaperchanger \n')
        c.write('#must be located in ~/.wallpaperchanger \n')
        c.write('#and must be named wallpaperchangerconfig.py \n')
        c.write('#all text behind a # is a comment \n')
        c.write('#you can edit this file as you like \n')
        c.write('#all directorys listed here will be searched recursive (INCLUDING their sub-directorys). Example: \n')
        c.write('# picturedirs = ["/home", "/media/win_c/pictures", "/media/win_d/personal/mycat/"] \n')
        c.write('picturedirs = ["/home"] \n')
        c.write('#all keywords listed here will make the wallpaper tiled if keyword is found in pathname or filename. \n')
        c.write('keywords_tiled = ["tiled", "pattern"] \n')
        c.write('#all keywords listed here will make the wallpaper centered if keyword is found in pathname or filename. \n')
        c.write('keywords_centered = ["centered"] \n')
        c.write('#all keywords listed here will make the wallpaper zoomed if keyword is found in pathname or filename. \n')
        c.write('keywords_zoomed = ["zoomed"] \n')
        c.write('#all keywords listed here will make the wallpaper streched if keyword is found in pathname or filename. \n')
        c.write('keywords_stretched = ["stretched"] \n')
        c.write('# per default, all wallpapers will be "scaled" if no other keyword is found. \n')
        c.write('#if any of the keywords listed here is found in  filename or pathname, file will NOT be used as wallpaper.. \n')
        c.write('keywords_exclude = ["privat", "secret", "bad", "ugly", "temp", "thumb"] \n')
        c.close()
    except:
        raise SystemExit, "could not write configfile to ~/.wallpaperchanger . Please check write permissions."
    from wallpaperchangerconfig import * # try to import config file 
    #print "config file written to ~/.wallpaperchanger and imported."


class GConfClient:
        def __init__(self):
                self.__client__ = gconf.client_get_default ()
        def get_background(self):
                return self.__client__.get_string("/desktop/gnome/background/picture_filename")
        def set_background(self, background):
                self.__client__.set_string("/desktop/gnome/background/picture_filename", background)
        def set_option (self, option):
                self.__client__.set_string("/desktop/gnome/background/picture_options", option)
client = GConfClient()


imageitems = []
for picturedir in picturedirs:
    for rootdir, dirlist, filelist in os.walk(picturedir): # recursive scan for filenames
        for file in filelist:
            mimetype = mimetypes.guess_type(file)[0]
            if mimetype and mimetype.split('/')[0] == "image":
                clean = True
                for keyword in keywords_exclude:
                    if keyword in rootdir or keyword in file:
                        clean = False
                if clean == True:
                    imageitems.append(os.path.join(rootdir,file))
if len(imageitems) < 1:
    raise SystemExit, "no pictures found"
item = random.randint(0, len (imageitems) - 1)
current_bg = client.get_background()

while (imageitems[item] == current_bg):
        item = random.randint(0, len(imageitems) - 1)
client.set_background(imageitems[item])

option = "scaled" # default
for keyword in keywords_tiled:
    if keyword in imageitems[item]:
        option = "wallpaper"
for keyword in keywords_centered:
    if keyword in imageitems[item]:
        option = "centered"
for keyword in keywords_zoomed:
    if keyword in imageitems[item]:
        option = "zoom"
for keyword in keywords_stretched:
    if keyword in imageitems[item]:
        option = "stretched"
client.set_option(option)
#print "setting wallpaper" , imageitems[item], "with the option", option
#options = ["scaled","wallpaper", "zoom", "centered", "streched"]
[/url]

Kommentare ? :oops:
http://spielend-programmieren.at
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

HorstJENS hat geschrieben:Kommentare ? :oops:
Kann KDE von selbst - nein, ein Witz muss sein. 8) Im Ernst: es ist schon ganz in Ordnung, aber ich glaub es wäre eleganter das schreiben so zu lösen:

Code: Alles auswählen

c.write("""#config file for wallpaperchanger
#must be located in ~/.wallpaperchanger
#and must be named wallpaperchangerconfig.py
#all text behind a # is a comment
#you can edit this file as you like
#all directorys listed here will be searched recursive (INCLUDING their sub-directorys). Example:
# picturedirs = ["/home", "/media/win_c/pictures", "/media/win_d/personal/mycat/"]
picturedirs = ["/home"]
#all keywords listed here will make the wallpaper tiled if keyword is found in pathname or filename.
keywords_tiled = ["tiled", "pattern"]
#all keywords listed here will make the wallpaper centered if keyword is found in pathname or filename.
keywords_centered = ["centered"]
#all keywords listed here will make the wallpaper zoomed if keyword is found in pathname or filename.
keywords_zoomed = ["zoomed"]
'#all keywords listed here will make the wallpaper streched if keyword is found in pathname or filename.
keywords_stretched = ["stretched"]
# per default, all wallpapers will be "scaled" if no other keyword is found.
#if any of the keywords listed here is found in  filename or pathname, file will NOT be used as wallpaper.. 
keywords_exclude = ["privat", "secret", "bad", "ugly", "temp", "thumb"]
""")
Wobei das auch nicht ganz astrein ist, da die einrückund der Datei dann nicht stimmt. Vielleicht kann man den Text auch einfach in eine Modulglobale Variable auslagern, das wäre wohl am besten.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
HorstJENS
User
Beiträge: 123
Registriert: Donnerstag 9. Februar 2006, 21:41
Wohnort: Wien, Österreich
Kontaktdaten:

so etwa ?

Code: Alles auswählen

#!/usr/bin/python
#
# wallpaperchanger.py
#
# A script to change your gnome wallpaper to a random background image
#
# (c) 2004, Davyd Madeley <davyd@madeley.id.au>
# edited 8/2006 by Horst JENS <Horst.Jens@gmx.at>
#
#   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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#


import gconf
import os
import sys
import random
import mimetypes

if os.name != 'posix':
    raise SystemExit, "no-linux Operations System detected. Yuk !"
sys.path.append(os.environ["HOME"])
sys.path.append(os.path.join(os.environ["HOME"], '.wallpaperchanger'))
configdir = os.path.join(os.environ["HOME"], '.wallpaperchanger')
inifiletext = """#config file for wallpaperchanger
#must be located in ~/.wallpaperchanger
#and must be named wallpaperchangerconfig.py
#all text behind a # is a comment
#you can edit this file as you like
#all directorys listed here will be searched recursive (INCLUDING their sub-directorys). Example:
# picturedirs = ["/home", "/media/win_c/pictures", "/media/win_d/personal/mycat/"]
picturedirs = ["/home"]
#all keywords listed here will make the wallpaper tiled if keyword is found in pathname or filename.
keywords_tiled = ["tiled", "pattern"]
#all keywords listed here will make the wallpaper centered if keyword is found in pathname or filename.
keywords_centered = ["centered"]
#all keywords listed here will make the wallpaper zoomed if keyword is found in pathname or filename.
keywords_zoomed = ["zoomed"]
#all keywords listed here will make the wallpaper streched if keyword is found in pathname or filename.
keywords_stretched = ["stretched"]
# per default, all wallpapers will be "scaled" if no other keyword is found.
#if any of the keywords listed here is found in  filename or pathname, file will NOT be used as wallpaper..
keywords_exclude = ["privat", "secret", "bad", "ugly", "temp", "thumb"] 
"""
try:
    from wallpaperchangerconfig import * # try to import config file 
    #print "config file imported."
except:
    print 'could not import configfile, so fresh configfile will be created in ~/.wallpaperchanger'
    os.chdir(os.environ["HOME"])
    try:
        os.mkdir('.wallpaperchanger')
    except:
        pass # if you can not create a directory, it may already exist...
    os.chdir('.wallpaperchanger')
    try:
        c = file('wallpaperchangerconfig.py','w')
        c.wirte(inifiletext)
        c.close()
    except:
        raise SystemExit, "could not write configfile to ~/.wallpaperchanger . Please check write permissions."
    from wallpaperchangerconfig import * # try to import config file 
    print "config file written to ~/.wallpaperchanger and imported."


class GConfClient:
        def __init__(self):
                self.__client__ = gconf.client_get_default ()
        def get_background(self):
                return self.__client__.get_string("/desktop/gnome/background/picture_filename")
        def set_background(self, background):
                self.__client__.set_string("/desktop/gnome/background/picture_filename", background)
        def set_option (self, option):
                self.__client__.set_string("/desktop/gnome/background/picture_options", option)
client = GConfClient()


imageitems = []
for picturedir in picturedirs:
    for rootdir, dirlist, filelist in os.walk(picturedir): # recursive scan for filenames
        for file in filelist:
            mimetype = mimetypes.guess_type(file)[0]
            if mimetype and mimetype.split('/')[0] == "image":
                clean = True
                for keyword in keywords_exclude:
                    if keyword in rootdir or keyword in file:
                        clean = False
                if clean == True:
                    imageitems.append(os.path.join(rootdir,file))
if len(imageitems) < 1:
    raise SystemExit, "no pictures found"
item = random.randint(0, len (imageitems) - 1)
current_bg = client.get_background()

while (imageitems[item] == current_bg):
        item = random.randint(0, len(imageitems) - 1)
client.set_background(imageitems[item])

option = "scaled" # default
for keyword in keywords_tiled:
    if keyword in imageitems[item]:
        option = "wallpaper"
for keyword in keywords_centered:
    if keyword in imageitems[item]:
        option = "centered"
for keyword in keywords_zoomed:
    if keyword in imageitems[item]:
        option = "zoom"
for keyword in keywords_stretched:
    if keyword in imageitems[item]:
        option = "stretched"
client.set_option(option)
#print "setting wallpaper" , imageitems[item], "with the option", option
#options = ["scaled","wallpaper", "zoom", "centered", "streched"]
[/code]
http://spielend-programmieren.at
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Ja, so in etwa.

Ich hätte noch was:

Statt sowas, was sich ja recht oft wiederholt

Code: Alles auswählen

for keyword in keywords_tiled: 
    if keyword in imageitems[item]: 
        option = "wallpaper" 
for keyword in keywords_centered: 
    if keyword in imageitems[item]: 
        option = "centered" 
for keyword in keywords_zoomed: 
    if keyword in imageitems[item]: 
        option = "zoom" 
for keyword in keywords_stretched: 
    if keyword in imageitems[item]: 
        option = "stretched"
könntest du sowas schreiben:

Code: Alles auswählen

for keyword in keywords_tiled + keywords_centered + keywords_zoomed + keywords_stretched: 
    if keyword in imageitems[item]: 
        option = "stretched"
Natürlich ungetestet, aber - you catch my drift :)
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
HorstJENS
User
Beiträge: 123
Registriert: Donnerstag 9. Februar 2006, 21:41
Wohnort: Wien, Österreich
Kontaktdaten:

sorry, ich fürchte ich kann Dir da nicht ganz folgen... :shock:

wenn ich all die keywordlisten per + verkette bekomme ich eine riesige liste mit keywörtern... wie soll ich die dann unterscheiden ? (nach "centered", "tiled" etc)

mfg,
-Horst
http://spielend-programmieren.at
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

HorstJENS hat geschrieben:wenn ich all die keywordlisten per + verkette bekomme ich eine riesige liste mit keywörtern... wie soll ich die dann unterscheiden ? (nach "centered", "tiled" etc)
Oh, hast recht - ich hab Blödsinn geschreiben. Aber mit den For-Schleifen kann man sicher etwas machen. Ich poste wenn/falls ich Zeit hab, mir da was funktionsfähiges auszudenken.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BlackJack

Man könnte es so schreiben (ungetestet):

Code: Alles auswählen

option = 'scaled'
for option_name, keyword in (('wallpaper', keywords_tiled),
                             ('centered', keywords_centered),
                             ('zoom', keywords_zoomed),
                             ('stretched', keywords_streched)):
    if keyword in imageitems[item]:
        option = keyword
        break
Das ``break`` kürzt die Sache etwas ab weil bei dem ersten gefundenen Schlüsselwort die Schleife verlassen wird. Um die gleichen Ergebnisse wie ohne ``break`` zu erhalten müsstest Du die Paare in der umgekehrten Reichenfolge abarbeiten. Falls das wichtig ist.
Benutzeravatar
HorstJENS
User
Beiträge: 123
Registriert: Donnerstag 9. Februar 2006, 21:41
Wohnort: Wien, Österreich
Kontaktdaten:

stimmt, spart ein paar Zeilen und schaut besser aus:

Code: Alles auswählen

option = "scaled"  # default 
for option_name, keywordlist in (('wallpaper', keywords_tiled), 
    ('centered', keywords_centered), 
    ('zoom', keywords_zoomed), 
    ('stretched', keywords_stretched)): 
    for keyword in keywordlist:
        #print option_name, keywordlist, keyword
        if keyword in imageitems[item]:
            option = option_name
            break 
:)
http://spielend-programmieren.at
Maduser
User
Beiträge: 1
Registriert: Samstag 30. Dezember 2006, 17:02

Danke für das tolle Script.
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Auch wenn das ganze schon etwas älter ist, möchte ich noch etwas hinzufügen. Folgende zwei Varianten wurden genannt:

Code: Alles auswählen

# erstens
    c.write('blah\n')
    c.write('blub\n')
    c.write('foo\n')
    c.write('bar\n')

# zweitens (etwas abgeändert)
    c.write('''\
blah
blub
foo
bar
''')
Die erste hat den Nachteil, Objekt und Methode (oder alternativ Funktion) immer beim Namen zu nennen, so gehen Übersicht und manuelle Refaktorisierbarkeit durch unnötige Redundanzen verloren.

Die zweite spart Wiederholungen und neben Anführungszeichen und Klammern sogar das Newline ein. Wirkt aber möglicherweise noch verwirrender, da die Einrückung zerstört wird.

Mein Vorschlag lautet daher:

Code: Alles auswählen

# Position des ersten Strings sowie der
# abschließenden Klammer diskutabel.
    c.write(
        'blah\n'
        'blub\n'
        'foo\n'
        'bar\n'
        )

# Oder sogar (spart Newlines), besonders
# bei vielen Strings/Zeilen interessant.
    c.write('\n'.join(
        'blah'
        'blub'
        'foo'
        'bar'
        ))
# Soll am Ende unbedingt ein Newline stehen,
# kann dies (irgendwie unangenehm) durch Hinzufügen
# eines leeren Strings oder durch anschließende
# Konkatenation angefügt werden.
So lassen sich die Nachteile der beiden ersten Varianten umgehen, so dass keine Redundanzen auftreten, aber die Einrückung erhalten bleibt.
Antworten