A python script using Reddit's API to download most upvoted wallpaper and change it

#!/usr/bin/python# -*- coding: utf-8 -*-importargparseimportprawimporturllibimportosimportsubprocessfrombs4importBeautifulSoupimportreimportsys'''
The praw.Reddit connection requires these:
client_id='2ZMSO5JBG4DR5w'
client_secret='B4m8XSe2N2V1dcgRM-EY10YWAJ8'
my_user = 'reddit_user_name'
my_password = 'not.my.password'
user_agent='pc:r_wallpapers_sets_my_wallpaper:0.1 '
1 either provide them here or in a praw.ini file residing in the same directory (or ~/.config/)
reddit = praw.Reddit(client_id=client_id,
client_secret=client_secret,
password=my_password,
user_agent=user_agent,
username=my_user)
2 or read required parameters from praw.ini under [user_data]
[user_data]
client_id=2ZMSO5JBG4DR5w
client_secret=B4m8XSe2N2V1dcgRM-EY10YWAJ8
username=redit_user_name
password=not.my.password
user_agent=pc:r_wallpapers_sets_my_wallpaper:0.1
'''parser=argparse.ArgumentParser()parser.add_argument("--subreddit",required=True,help="name of the subreddit to fetch image from. E.g: 'wallpapers' or 'EarthPorn'")parser.add_argument("--top",required=True,help="subreddit Top time-limit submission: 'day', 'week', 'year'")home_dir=os.path.expanduser('~')wallpapers_dir=os.path.join(home_dir,".wallpapers")defget_submission(subreddit,time,limit):forsubmissioninsubreddit.top(time_filter=time,limit=limit):title=submission.titleurl=submission.urlreturnurl,titledefconfigure_wallpaper_path(title):ifnotos.path.isdir(wallpapers_dir):os.mkdir(wallpapers_dir)wallpaper_path=os.path.join(wallpapers_dir,str(title)+".jpg")returnwallpaper_pathdefget_screen_dimensions():#sys.stdout.isatty() -> True if executed from console, False if executed from cron'''
runs xrandr to get screen dimension from console call.
Can't get it to work when executed from cron (Is it even possible?)
since cron is not tty-based so I can't capture stdout from xrandr call.
Just provide an argument file with screen dimensions when executing from cron?
'''screen_dim=subprocess.Popen("xrandr | grep \* | awk '/x/{print $1}'",shell=True,stdout=subprocess.PIPE).stdout.read().strip("\n")screen_w,screen_h=int(screen_dim.split("x")[0]),int(screen_dim.split("x")[1])return(screen_w,screen_h)defcheck_img_fits_screen(original_title,screen_dimensions):'''
checks the image is more or less rectangular (width/height ratio) to be used as wallpaper
by comparing to local screen dimensions
Uses the original title, bc it's subreddit rules to include image resolution
'''try:screen_w,screen_h=screen_dimensions[0],screen_dimensions[1]original_title=original_title.replace(",",'').replace(".",'')pattern="[\[\(]\d+?[ ]?[*xX][ ]?\d+?[\]\)]"img_dimensions=re.search(pattern,original_title).group(0)w_by_h=re.compile("[*xX]").split(img_dimensions)img_w,img_h=int(w_by_h[0][1:]),int(w_by_h[1][:-1])ratio_img=(img_w+.0)/img_hratio_screen=(screen_w+.0)/screen_hif(screen_w-img_w<200)and(ratio_screen-ratio_img<0.5):returnTrueelse:returnFalseexceptAttributeError:#'NoneType' object has no attribute 'group' when original title doesnt complyreturnFalsedefget_imgur_image_url(url):'''
works either for imgur.com/a/ (album) or just a regular imgur page
with just one picture imgur.com/something
in the first case just grabs url for first picture in the album,
otherwise grabs 'the' image url
'''html=urllib.urlopen(url).read()soup=BeautifulSoup(html,"lxml")matches=soup.find_all('img',attrs={"class":"post-image-placeholder"})#pick first image in album:url=re.search("i.imgur.com/(.+?\")",str(matches[0])).group(0).strip("\"")return"http://"+urldefdownload_wallpaper(url,path):'''
first checks the url respnds OK(200), then check it's not html
'''ifurllib.urlopen(url).getcode()==200:ifnot'html'inurllib.urlopen(url).read():urllib.urlretrieve(url,path)returnurllib.urlopen(url).getcode()defchange_local_wallpaper(wallpaper_path):'''
runs
gsettings set org.gnome.desktop.background picture-uri file://" + wallpaper_path
or dconf write if gsettings gives the dreaded "GLib-GIO-Message:
Using the 'memory' GSettings backend" error message
'''file='file://%s'%wallpaper_pathp=subprocess.Popen(['gsettings','set','org.gnome.desktop.background','picture-uri',file],stderr=subprocess.PIPE)err=p.communicate()[1]if"GLib-GIO-Message: Using the 'memory' GSettings backend"inerr:p=subprocess.Popen(['dconf','write','/org/gnome/desktop/background/picture-uri',"\"%s\""%file],stderr=subprocess.PIPE)out,err=p.communicate()defmain():subreddit_arg=args.subreddit#subreddit_arg = 'EarthPorn'ifsubreddit_arg.lower()notin["wallpapers","earthporn"]:sys.exit('supported subreddits: wallpapers, EarthPorn')time=args.top#time = 'day'reddit=praw.Reddit('user_data')limit=1subreddit=reddit.subreddit(subreddit_arg)url,original_title=get_submission(subreddit,time,limit)screen_dimensions=get_screen_dimensions()img_fits_screen=check_img_fits_screen(original_title,screen_dimensions)whileimg_fits_screen==False:limit+=1url,original_title=get_submission(subreddit,time,limit)img_fits_screen=check_img_fits_screen(original_title,screen_dimensions)short_title=original_title.replace(" ","_").strip(".")[0:30]#replace non-ascii for '?'short_title=''.join([iiford(i)<128else'?'foriinshort_title])wallpaper_path=configure_wallpaper_path(short_title)#i.imgur.com/ and i.redd.it/ are images, not htmlif'imgur.com'inurlandnot'i.imgur.com/'inurl:if'html'inurllib.urlopen(url).read():url=get_imgur_image_url(url)ifdownload_wallpaper(str(url),wallpaper_path):print"\nDownloaded \""+short_title+"\" from "+str(url)change_local_wallpaper(wallpaper_path)print"Set \""+short_title+"\" as wallpaper"if__name__=="__main__":args=parser.parse_args()main()