Rework config
This commit is contained in:
parent
0845d0df28
commit
19dd251165
2
.gitignore
vendored
2
.gitignore
vendored
@ -2,3 +2,5 @@ downloads/
|
|||||||
.idea/
|
.idea/
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.pyc
|
*.pyc
|
||||||
|
*.pyo
|
||||||
|
config.toml
|
10
README.md
10
README.md
@ -1,2 +1,12 @@
|
|||||||
Useful resources for more providers
|
Useful resources for more providers
|
||||||
- https://github.com/goodtrailer/daily-desktop/tree/main
|
- https://github.com/goodtrailer/daily-desktop/tree/main
|
||||||
|
|
||||||
|
Documentation from third party tools
|
||||||
|
- https://github.com/genzj/pybingwallpaper
|
||||||
|
- https://github.com/goodtrailer/daily-desktop/blob/main/DailyDesktop.Providers.Bing/BingProvider.cs
|
||||||
|
|
||||||
|
Unsplash Applications
|
||||||
|
- https://unsplash.com/oauth/applications
|
||||||
|
|
||||||
|
Wikipedia API Docs
|
||||||
|
- https://api.wikimedia.org/wiki/Getting_featured_content_from_Wikipedia_with_Python#Today's_featured_article
|
@ -1,54 +1,49 @@
|
|||||||
|
import datetime
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
|
||||||
import requests
|
import requests
|
||||||
import importlib
|
import importlib
|
||||||
import logging
|
import logging
|
||||||
|
import slugify
|
||||||
|
import settings
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
|
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
|
||||||
|
|
||||||
|
config = settings.load_settings()
|
||||||
|
logging.debug(f"Config: {config}")
|
||||||
|
|
||||||
session = requests.Session()
|
session = requests.Session()
|
||||||
session.headers.update({
|
session.headers.update({
|
||||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:132.0) Gecko/20100101 Firefox/132.0"
|
"User-Agent": config['general']['user_agent']
|
||||||
})
|
})
|
||||||
|
|
||||||
# Load settings from settings.toml
|
# Convenience variables, could be inlined
|
||||||
settings = tomllib.load(open("settings.toml", mode='b+r'))
|
provider_name = config['general']['provider']
|
||||||
|
provider_settings = config[config['general']['provider']]
|
||||||
general_settings = settings.get("general")
|
download_location = os.path.abspath(os.path.expanduser(config['general']['location']))
|
||||||
|
|
||||||
download_location = general_settings.get("location")
|
|
||||||
logging.debug(f"Download location: {download_location}")
|
|
||||||
|
|
||||||
provider_name = general_settings.get("provider")
|
|
||||||
logging.debug(f"Provider: {provider_name}")
|
|
||||||
|
|
||||||
provider_settings = settings.get(provider_name)
|
|
||||||
|
|
||||||
# Load the provider module
|
# Load the provider module
|
||||||
provider = importlib.import_module(f"providers.{provider_name}")
|
provider = importlib.import_module(f"providers.{config['general']['provider']}")
|
||||||
logging.debug(f"Provider: {provider}")
|
|
||||||
|
|
||||||
# Create an instance of the provider
|
# Create an instance of the provider
|
||||||
provider_obj = getattr(provider, provider_name)(provider_settings, session)
|
provider_obj = getattr(provider, provider_name.title())(provider_settings, session)
|
||||||
|
# Get the image URL and title
|
||||||
# Get the image URL
|
image_url, image_title = provider_obj.get_image_info()
|
||||||
image_url = provider_obj.get_image_url()
|
|
||||||
logging.debug(f"Image URL: {image_url}")
|
logging.debug(f"Image URL: {image_url}")
|
||||||
|
|
||||||
# Download the image
|
# Download the image
|
||||||
image = session.get(image_url).content
|
image = session.get(image_url).content
|
||||||
|
|
||||||
# if its actually text, log it
|
|
||||||
if image.startswith(b"<!DOCTYPE html>"):
|
|
||||||
logging.error("Image is actually HTML")
|
|
||||||
logging.error(image)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
if not os.path.exists(download_location):
|
if not os.path.exists(download_location):
|
||||||
os.mkdir(download_location)
|
os.mkdir(download_location)
|
||||||
with open(f"{download_location}/wallpaper.jpg", "wb") as file:
|
if not os.path.exists(f"{download_location}/{provider_name.title()}"):
|
||||||
|
os.mkdir(f"{download_location}/{provider_name.title()}")
|
||||||
|
|
||||||
|
date = datetime.datetime.now().strftime("%Y-%m-%d")
|
||||||
|
image_title = slugify.slugify(image_title)
|
||||||
|
with open(f"{download_location}/{provider_name.title()}/{date} [{image_title}].jpg", "wb") as file:
|
||||||
file.write(image)
|
file.write(image)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
41
poetry.lock
generated
41
poetry.lock
generated
@ -139,6 +139,23 @@ files = [
|
|||||||
[package.extras]
|
[package.extras]
|
||||||
all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"]
|
all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "python-slugify"
|
||||||
|
version = "8.0.4"
|
||||||
|
description = "A Python slugify application that also handles Unicode"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.7"
|
||||||
|
files = [
|
||||||
|
{file = "python-slugify-8.0.4.tar.gz", hash = "sha256:59202371d1d05b54a9e7720c5e038f928f45daaffe41dd10822f3907b937c856"},
|
||||||
|
{file = "python_slugify-8.0.4-py2.py3-none-any.whl", hash = "sha256:276540b79961052b66b7d116620b36518847f52d5fd9e3a70164fc8c50faa6b8"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
text-unidecode = ">=1.3"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
unidecode = ["Unidecode (>=1.1.1)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "requests"
|
name = "requests"
|
||||||
version = "2.32.3"
|
version = "2.32.3"
|
||||||
@ -160,6 +177,28 @@ urllib3 = ">=1.21.1,<3"
|
|||||||
socks = ["PySocks (>=1.5.6,!=1.5.7)"]
|
socks = ["PySocks (>=1.5.6,!=1.5.7)"]
|
||||||
use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
|
use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "text-unidecode"
|
||||||
|
version = "1.3"
|
||||||
|
description = "The most basic Text::Unidecode port"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
files = [
|
||||||
|
{file = "text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"},
|
||||||
|
{file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tomlkit"
|
||||||
|
version = "0.13.2"
|
||||||
|
description = "Style preserving TOML library"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.8"
|
||||||
|
files = [
|
||||||
|
{file = "tomlkit-0.13.2-py3-none-any.whl", hash = "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde"},
|
||||||
|
{file = "tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "urllib3"
|
name = "urllib3"
|
||||||
version = "1.26.20"
|
version = "1.26.20"
|
||||||
@ -179,4 +218,4 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = "^3.11"
|
python-versions = "^3.11"
|
||||||
content-hash = "5fe821e2ab03f0c4de8c3a81fb06c6dc74655045a0ac2d8c712ce703c8322389"
|
content-hash = "cbcfeef2301c00347932493e38948d8930eb3e2a1cc65f1781d86d50614ac3f6"
|
||||||
|
@ -10,5 +10,5 @@ class Provider(ABC):
|
|||||||
self.session = session
|
self.session = session
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def get_image_url(self):
|
def get_image_info(self):
|
||||||
pass
|
pass
|
@ -1,10 +1,7 @@
|
|||||||
import logging
|
import logging
|
||||||
import requests
|
from providers._provider import Provider
|
||||||
from requests import session
|
|
||||||
|
|
||||||
from providers.provider import Provider
|
class Bing(Provider):
|
||||||
|
|
||||||
class bing(Provider):
|
|
||||||
name = "Bing"
|
name = "Bing"
|
||||||
url = "https://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&mkt=en-US"
|
url = "https://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&mkt=en-US"
|
||||||
idx = 0
|
idx = 0
|
||||||
@ -16,16 +13,17 @@ class bing(Provider):
|
|||||||
self.country = settings.get("country")
|
self.country = settings.get("country")
|
||||||
self.market = settings.get("market")
|
self.market = settings.get("market")
|
||||||
|
|
||||||
def get_image_url(self):
|
def get_image_info(self):
|
||||||
query = f"https://www.bing.com/HPImageArchive.aspx?format=js&idx={self.idx}&n={self.number}&mkt={self.market}"
|
query = f"https://www.bing.com/HPImageArchive.aspx?format=js&idx={self.idx}&n={self.number}&mkt={self.market}"
|
||||||
logging.debug(f"Query: {query}")
|
logging.debug(f"Query: {query}")
|
||||||
|
|
||||||
response = self.session.get(query).json()
|
response = self.session.get(query).json()
|
||||||
logging.debug(f"Response: {response}")
|
# logging.debug(f"Response: {response}")
|
||||||
|
|
||||||
image_url = response["images"][0]["urlbase"]
|
image_url = response["images"][0]["urlbase"]
|
||||||
logging.debug(f"Image URL: {image_url}")
|
logging.debug(f"Image URL: {image_url}")\
|
||||||
|
|
||||||
|
title = response["images"][0]["title"]
|
||||||
|
|
||||||
image_url = f"https://www.bing.com{image_url}_{self.size}.jpg"
|
image_url = f"https://www.bing.com{image_url}_{self.size}.jpg"
|
||||||
return image_url
|
return image_url, title
|
||||||
|
|
||||||
|
@ -1,20 +1,18 @@
|
|||||||
# Using official Unsplash API to get images
|
# Using official Unsplash API to get images
|
||||||
# curl https://api.unsplash.com/collections/1459961/photos
|
# curl https://api.unsplash.com/collections/1459961/photos
|
||||||
# But we will scrape >:)
|
# But we will scrape >:)
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import requests
|
|
||||||
import re
|
import re
|
||||||
from providers.provider import Provider
|
from providers._provider import Provider
|
||||||
|
|
||||||
class unsplash(Provider):
|
class Unsplash(Provider):
|
||||||
name = "Unsplash"
|
name = "Unsplash"
|
||||||
url = "https://unsplash.com/collections/1459961/photo-of-the-day-(archive)"
|
url = "https://unsplash.com/collections/1459961/photo-of-the-day-(archive)"
|
||||||
|
|
||||||
def __init__(self, settings, session):
|
def __init__(self, settings, session):
|
||||||
super().__init__(settings, session)
|
super().__init__(settings, session)
|
||||||
|
|
||||||
def get_image_url(self):
|
def get_image_info(self):
|
||||||
query = "https://unsplash.com/collections/1459961/photo-of-the-day-(archive)"
|
query = "https://unsplash.com/collections/1459961/photo-of-the-day-(archive)"
|
||||||
logging.debug(f"Query: {query}")
|
logging.debug(f"Query: {query}")
|
||||||
|
|
||||||
@ -30,7 +28,8 @@ class unsplash(Provider):
|
|||||||
image_id = image_slug.split("-")[-1]
|
image_id = image_slug.split("-")[-1]
|
||||||
logging.debug(f"Image ID: {image_id}")
|
logging.debug(f"Image ID: {image_id}")
|
||||||
|
|
||||||
|
title = image_slug.replace("-", " ").replace(image_id, "").strip().title()
|
||||||
|
|
||||||
image_url = f"https://unsplash.com/photos/{image_id}/download"
|
image_url = f"https://unsplash.com/photos/{image_id}/download"
|
||||||
logging.debug(f"Image URL: {image_url}")
|
logging.debug(f"Image URL: {image_url}")
|
||||||
return image_url
|
return image_url, title
|
||||||
|
|
||||||
|
@ -1,20 +1,18 @@
|
|||||||
import datetime
|
import datetime
|
||||||
import logging
|
import logging
|
||||||
import requests
|
|
||||||
import re
|
import re
|
||||||
from providers.provider import Provider
|
from providers._provider import Provider
|
||||||
|
|
||||||
# https://api.wikimedia.org/wiki/Feed_API/Reference/Featured_content
|
# https://api.wikimedia.org/wiki/Feed_API/Reference/Featured_content
|
||||||
|
|
||||||
class wikimedia(Provider):
|
class Wikimedia(Provider):
|
||||||
name = "Wikimedia"
|
name = "Wikimedia"
|
||||||
url = "https://api.wikimedia.org/feed/v1/wikipedia/en/featured/"
|
url = "https://api.wikimedia.org/feed/v1/wikipedia/en/featured/"
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, settings, session):
|
def __init__(self, settings, session):
|
||||||
super().__init__(settings, session)
|
super().__init__(settings, session)
|
||||||
|
|
||||||
def get_image_url(self):
|
def get_image_info(self):
|
||||||
today = datetime.datetime.now()
|
today = datetime.datetime.now()
|
||||||
date = today.strftime('%Y/%m/%d')
|
date = today.strftime('%Y/%m/%d')
|
||||||
logging.debug(f"Date: {date}")
|
logging.debug(f"Date: {date}")
|
||||||
@ -22,11 +20,12 @@ class wikimedia(Provider):
|
|||||||
logging.debug(f"URL: {url}")
|
logging.debug(f"URL: {url}")
|
||||||
|
|
||||||
response = self.session.get(url).json()
|
response = self.session.get(url).json()
|
||||||
logging.debug(f"Response: {response}")
|
# logging.debug(f"Response: {response}")
|
||||||
|
|
||||||
image = response['image']['image']['source']
|
image = response['image']['image']['source']
|
||||||
logging.debug(f"Image: {image}")
|
logging.debug(f"Image: {image}")
|
||||||
image_url = image
|
image_url = image
|
||||||
|
|
||||||
return image_url
|
title = response['image']['description']['text']
|
||||||
|
|
||||||
|
return image_url, title
|
||||||
|
@ -9,6 +9,8 @@ readme = "README.md"
|
|||||||
python = "^3.11"
|
python = "^3.11"
|
||||||
requests = "^2.32"
|
requests = "^2.32"
|
||||||
urllib3 = "^1.26"
|
urllib3 = "^1.26"
|
||||||
|
python-slugify = "^8.0"
|
||||||
|
tomlkit = "^0.13.2"
|
||||||
|
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
|
75
settings.py
Normal file
75
settings.py
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
import os.path
|
||||||
|
import tomlkit
|
||||||
|
|
||||||
|
local_path = os.path.abspath("config.toml")
|
||||||
|
user_path = os.path.expanduser("~/.config/daily-wallpaper/config.toml")
|
||||||
|
|
||||||
|
def default_settings():
|
||||||
|
general = tomlkit.table()
|
||||||
|
general.add("interval", 86400)
|
||||||
|
general["interval"].comment("Interval in seconds (24 hours)")
|
||||||
|
general.add("start", 7200)
|
||||||
|
general["start"].comment("Start time in seconds (2:00 AM)")
|
||||||
|
general.add("location", "~/Pictures/Wallpapers")
|
||||||
|
general["location"].comment("Download location")
|
||||||
|
general.add("provider", "bing")
|
||||||
|
general["provider"].comment("Which wallpaper provider to use")
|
||||||
|
general.add("include_title", True)
|
||||||
|
general.value.item("include_title").comment("Include image title in filename")
|
||||||
|
general.add("set_wallpaper", False)
|
||||||
|
general.value.item("set_wallpaper").comment("Set wallpaper after download")
|
||||||
|
general.add("daemon", False)
|
||||||
|
general.value.item("daemon").comment("Run as daemon (continuously in the background)")
|
||||||
|
general.add("log", False)
|
||||||
|
general.value.item("log").comment("Log to file, located in the download location")
|
||||||
|
general.add("log_level", "INFO")
|
||||||
|
general["log_level"].comment("Log level, possible values: DEBUG, INFO, WARNING, ERROR, CRITICAL")
|
||||||
|
general.add("overwrite", False)
|
||||||
|
general.value.item("overwrite").comment("Overwrite existing files")
|
||||||
|
general.add("user_agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:132.0) Gecko/20100101 Firefox/132.0")
|
||||||
|
general["user_agent"].comment("User-Agent to use for requests, change to avoid being blocked or to comply with ToS")
|
||||||
|
general.add(tomlkit.nl())
|
||||||
|
|
||||||
|
bing = tomlkit.table()
|
||||||
|
bing.add("size", "UHD")
|
||||||
|
bing["size"].comment('Image size, possible values: "UHD", "1920x1080"')
|
||||||
|
bing.add("country", "us")
|
||||||
|
bing["country"].comment("Country, currently unused")
|
||||||
|
bing.add("market", "en-US")
|
||||||
|
bing["market"].comment("Market, overrides country")
|
||||||
|
bing.add(tomlkit.nl())
|
||||||
|
|
||||||
|
unsplash = tomlkit.table()
|
||||||
|
unsplash.add("collection", 1459961)
|
||||||
|
unsplash["collection"].comment("Collection ID, which gallery to use")
|
||||||
|
unsplash.add("application_id", "")
|
||||||
|
unsplash["application_id"].comment("Unset, currently not used, as we scrape")
|
||||||
|
unsplash.add("access_key", "")
|
||||||
|
unsplash["access_key"].comment("Unset, currently not used, as we scrape")
|
||||||
|
unsplash.add("secret_key", "")
|
||||||
|
unsplash["secret_key"].comment("Unset, currently not used, as we scrape")
|
||||||
|
unsplash.add(tomlkit.nl())
|
||||||
|
|
||||||
|
wikimedia = tomlkit.table()
|
||||||
|
wikimedia.add("authorization", "")
|
||||||
|
wikimedia["authorization"].comment("Unset, currently not used, as Wikimedia does not require it")
|
||||||
|
|
||||||
|
defaults = tomlkit.document()
|
||||||
|
defaults.add("general", general)
|
||||||
|
defaults.add("bing", bing)
|
||||||
|
defaults.add("unsplash", unsplash)
|
||||||
|
defaults.add("wikimedia", wikimedia)
|
||||||
|
|
||||||
|
return defaults
|
||||||
|
|
||||||
|
def load_settings():
|
||||||
|
if os.path.exists(local_path):
|
||||||
|
settings = tomlkit.parse(open(local_path, mode='r').read())
|
||||||
|
elif os.path.exists(user_path):
|
||||||
|
settings = tomlkit.parse(open(user_path, mode='b+r').read())
|
||||||
|
else:
|
||||||
|
settings = default_settings()
|
||||||
|
os.makedirs(os.path.dirname(user_path), exist_ok=True)
|
||||||
|
with open(user_path, mode='w') as file:
|
||||||
|
tomlkit.dump(settings, file)
|
||||||
|
return settings
|
@ -1,23 +0,0 @@
|
|||||||
[general]
|
|
||||||
provider = "wikimedia" # bing, unsplash, wikimedia
|
|
||||||
location = "downloads"
|
|
||||||
daemon = false
|
|
||||||
|
|
||||||
# Documentation from third party tools
|
|
||||||
# https://github.com/genzj/pybingwallpaper
|
|
||||||
# https://github.com/goodtrailer/daily-desktop/blob/main/DailyDesktop.Providers.Bing/BingProvider.cs
|
|
||||||
[bing]
|
|
||||||
size = "UHD" # UHD, 1920x1080, 1280x720, 640x480
|
|
||||||
country = "us"
|
|
||||||
market = "en-US"
|
|
||||||
|
|
||||||
# https://unsplash.com/oauth/applications
|
|
||||||
[unsplash] # If unset, will scrape
|
|
||||||
application_id = ""
|
|
||||||
access_key = ""
|
|
||||||
secret_key = ""
|
|
||||||
|
|
||||||
# https://api.wikimedia.org/wiki/Getting_featured_content_from_Wikipedia_with_Python#Today's_featured_article
|
|
||||||
[wikimedia]
|
|
||||||
authorization = "" # Not required, but recommended
|
|
||||||
user_agent = "" # Not required, but recommended
|
|
Loading…
Reference in New Issue
Block a user