Last active
May 26, 2018 02:52
-
-
Save qubbit/23c230e406ddb8553f58fb25b764e48c to your computer and use it in GitHub Desktop.
Periodically download images and set them as wallpaper from Unsplash
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using Microsoft.Win32; | |
| using System; | |
| using System.Drawing; | |
| using System.IO; | |
| using System.Net; | |
| using System.Runtime.InteropServices; | |
| using System.Windows.Forms; | |
| using System.Linq; | |
| // A program that will periodically download an image from Unsplash and | |
| // change your Windows desktop background to the downloaded image | |
| // Compilation: csc /out:unsplash.exe /t:winexe .\Program.cs /nologo /o | |
| // After compilation, drop the executable in a folder and run it with some command line args | |
| // args[0] = minutes (how often to change the background image | |
| // args[1] = search terms to find your desire type of wallpaper | |
| // Example invocation: | |
| // unsplash.exe 60 nature,scenary | |
| // This will change the wallpaper every hour from category of nature and scenary | |
| namespace Unsplash { | |
| // Very simple logger implementation with a lock! | |
| public class FileLogger { | |
| protected readonly object locker = new object(); | |
| const string LOG_FILE_PATH = "application.log"; | |
| const bool ALSO_LOG_TO_STDOUT = true; | |
| public void Log(string message) { | |
| lock (locker) { | |
| using (var streamWriter = new StreamWriter(LOG_FILE_PATH, append: true)) { | |
| var line = string.Format("{0} \t {1}", DateTime.Now.ToString("MM/d/yyyy hh:mm:ss tt zzzz"), message); | |
| streamWriter.WriteLine(line); | |
| if (ALSO_LOG_TO_STDOUT) Console.WriteLine(line); | |
| } | |
| } | |
| } | |
| } | |
| class Program { | |
| const int ONE_HOUR_MS = 60 * 60 * 1000; | |
| const int FIFTEEN_MINUTES_MS = ONE_HOUR_MS / 4; | |
| const string IMAGE_DIR_NAME = "Unsplash"; | |
| const int DEFAULT_SEARCH_INTERVAL_MINUTES = 15; | |
| const string DEFAULT_SEARCH_CATEGORY = "nature,scenary,landmarks"; | |
| // Arg 0 = width, Arg 1 = height, Arg 2 = search terms (comma separated) | |
| const string SEARCH_URL_TEMPLATE = "https://source.unsplash.com/{0}x{1}/?{2}"; | |
| static string url; | |
| static FileLogger logger = new FileLogger(); | |
| static uint timerCallCount = 0; | |
| static void Main(string[] args) { | |
| SetAppBasePath(); | |
| logger.Log("Application started"); | |
| if (args.Length < 2) { | |
| logger.Log(String.Format("Setting default arguments since no arguments were specified. Interval = {0} minutes, search category = {1}", | |
| DEFAULT_SEARCH_INTERVAL_MINUTES, DEFAULT_SEARCH_CATEGORY)); | |
| args = new string[] { DEFAULT_SEARCH_INTERVAL_MINUTES.ToString(), DEFAULT_SEARCH_CATEGORY }; | |
| } | |
| var searchTerms = args[1]; | |
| var screenBounds = Screen.AllScreens.Where(x => x.Primary).First().Bounds; | |
| logger.Log("Primary screen bounds: " + screenBounds.ToString()); | |
| url = string.Format(SEARCH_URL_TEMPLATE, screenBounds.Width, screenBounds.Height, searchTerms); | |
| if (int.TryParse(args[0], out int interval)) { | |
| interval *= 60 * 1000; // convert minutes to milliseconds | |
| if (interval < FIFTEEN_MINUTES_MS) interval = FIFTEEN_MINUTES_MS; | |
| } | |
| else { | |
| interval = ONE_HOUR_MS; | |
| } | |
| new System.Threading.Timer(Tick, null, 0, interval); | |
| while (true) System.Threading.Thread.Sleep(1000); | |
| } | |
| private static void SetAppBasePath() { | |
| string imageDownloadDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, IMAGE_DIR_NAME); | |
| if (!Directory.Exists(imageDownloadDir)) { Directory.CreateDirectory(imageDownloadDir); } | |
| Directory.SetCurrentDirectory(imageDownloadDir); | |
| } | |
| private static void Tick(object state) { | |
| string imageFileName = ImageDownloader.Download(url); | |
| var logMessage = string.Format("Tick count: {0}. Setting wallpaper to {1}", ++timerCallCount, imageFileName); | |
| logger.Log(logMessage); | |
| Wallpaper.Set(imageFileName, Wallpaper.Style.Fill); | |
| } | |
| } | |
| class ImageDownloader { | |
| private static string Extension(string mimeType) { | |
| switch (mimeType) { | |
| case "image/jpeg": | |
| return ".jpg"; | |
| case "image/png": | |
| return ".png"; | |
| default: | |
| return ""; | |
| } | |
| } | |
| public static string Download(string url) { | |
| ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; | |
| var request = (HttpWebRequest)WebRequest.Create(url); | |
| var response = (HttpWebResponse)request.GetResponse(); | |
| var responseUri = response.ResponseUri; | |
| string imageFileName = new FileInfo(response.ResponseUri.LocalPath).Name + Extension(response.ContentType); | |
| using (Stream receiveStream = response.GetResponseStream()) | |
| using (Stream outputStream = File.OpenWrite(imageFileName)) { | |
| byte[] buffer = new byte[4096]; | |
| int bytesRead; | |
| do { | |
| bytesRead = receiveStream.Read(buffer, 0, buffer.Length); | |
| outputStream.Write(buffer, 0, bytesRead); | |
| } while (bytesRead != 0); | |
| } | |
| return imageFileName; | |
| } | |
| } | |
| public sealed class Wallpaper { | |
| const int SPI_SETDESKWALLPAPER = 20; | |
| const int SPIF_UPDATEINIFILE = 0x01; | |
| const int SPIF_SENDWININICHANGE = 0x02; | |
| [DllImport("user32.dll", CharSet = CharSet.Auto)] | |
| static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni); | |
| public enum Style : int { | |
| Fill, | |
| Fit, | |
| Span, | |
| Tile, | |
| Center, | |
| Stretch | |
| } | |
| public static void Set(string filename, Style style) { | |
| Image img = Image.FromFile(filename); | |
| string tempPath = Path.Combine(Path.GetTempPath(), "wallpaper.bmp"); | |
| img.Save(tempPath, System.Drawing.Imaging.ImageFormat.Bmp); | |
| RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Control Panel\Desktop", true); | |
| if (style == Style.Fill) { | |
| key.SetValue(@"WallpaperStyle", "10"); | |
| key.SetValue(@"TileWallpaper", "0"); | |
| } | |
| if (style == Style.Fit) { | |
| key.SetValue(@"WallpaperStyle", "6"); | |
| key.SetValue(@"TileWallpaper", "0"); | |
| } | |
| if (style == Style.Span) // Windows 8 or newer only! | |
| { | |
| key.SetValue(@"WallpaperStyle", "22"); | |
| key.SetValue(@"TileWallpaper", "0"); | |
| } | |
| if (style == Style.Stretch) { | |
| key.SetValue(@"WallpaperStyle", "2"); | |
| key.SetValue(@"TileWallpaper", "0"); | |
| } | |
| if (style == Style.Tile) { | |
| key.SetValue(@"WallpaperStyle", "0"); | |
| key.SetValue(@"TileWallpaper", "1"); | |
| } | |
| if (style == Style.Center) { | |
| key.SetValue(@"WallpaperStyle", "0"); | |
| key.SetValue(@"TileWallpaper", "0"); | |
| } | |
| SystemParametersInfo(SPI_SETDESKWALLPAPER, | |
| 0, | |
| tempPath, | |
| SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment