Using Sardines report method to query events from CalDAV server - caldav

I'm trying to fetch events from a CalDAV server using Sardine (and biweekly). Fetching an entire calendar is working for me:
Sardine sardine = SardineFactory.begin();
InputStream is = sardine.get(CALDAV_URL_STRING);
ICalendar iCalendar = Biweekly.parse(is).first();
Now I would like to fetch events for specific time range. Based on this "Building a CalDAV client" article, I assume you should use Sardines report method to do so, right?
If so, how should you use that method? It's not documented in the wiki, and the Javadoc is also not very clear.
Should I write my own SardineReport? I looks like I should end up with something like:
Sardine sardine = SardineFactory.begin();
SardineReport<List<VEvent>> report = new MyRangeReport(FROM_DATE, END_DATE);
List<VEvent> result = sardine.report(CALDAV_URL_STRING, 1, report);
Am I on the right track? Does anyone have any pointers to how to write your own Sardine report?

You are correct, to run a time range query you need to issue an HTTP REPORT request containing a calendar-query. You can find a sample in RFC 4719 Section 7.8.1. I don't know Sardine, but yes, report sounds right ;-)
Simplified even further:
REPORT /bernard/work/ HTTP/1.1
Host: cal.example.com
Depth: 1
Content-Type: application/xml; charset="utf-8"
Content-Length: xxxx
<?xml version="1.0" encoding="utf-8" ?>
<calendar-query xmlns:D="DAV:" xmlns="urn:ietf:params:xml:ns:caldav">
<D:prop>
<D:getetag/>
<calendar-data />
</D:prop>
<filter>
<comp-filter name="VCALENDAR">
<comp-filter name="VEVENT">
<time-range start="20060104T000000Z" end="20060105T000000Z"/>
</comp-filter>
</comp-filter>
</filter>
</calendar-query>
Should I write my own SardineReport?
Looks like, scanning over the GitHub of Sardine it doesn't seem to include CalDAV queries. You can probably base yours on their
SyncCollectionReport.java.
Note that the response to the calendar-query REPORT is just a regular WebDAV 207 multi-status response. Nothing extra required. (the Result object would be the same like in their SyncCollectionReport but w/o the extra syncToken).

I've implemented a report class which works, however, the result returned by Radicale seem to be incorrect. It looks like Radicale does not support the time-range filter.
For what it's worth, here are the relevant bits of the report:
public class VEventsTimeRangeSardineReport extends SardineReport<List<VEvent>>
{
...
#Override
public String toXml() throws IOException
{
// Hardcode for now
String xml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" +
"<c:calendar-query xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\n" +
" <d:prop>\n" +
" <c:calendar-data/>\n" +
" <d:getetag/>\n" +
" </d:prop>\n" +
" <c:filter>\n" +
" <c:comp-filter name=\"VCALENDAR\">\n" +
" <c:comp-filter name=\"VEVENT\">\n" +
" <c:time-range start=\"%s\" end=\"%s\"/>\n" +
" </c:comp-filter>\n" +
" </c:comp-filter>\n" +
" </c:filter>\n" +
"</c:calendar-query>";
return String.format(xml, SDF.format(fromDate), SDF.format(toDate));
}
#Override
public List<VEvent> fromMultistatus(Multistatus multistatus)
{
List<VEvent> events = new ArrayList<>(multistatus.getResponse().size());
for (Response response : multistatus.getResponse()) {
// Here response.getPropstat().get(0).getProp().getAny().get(0).getFirstChild().getTextContent() is parsed
events.addAll(ICalendarSardineReport.getICalendar(response).getEvents());
}
return events;
}
#Override
public Object toJaxb()
{
return null;
}
}

Related

Alfresco audit query: fromTime/toTime seem to have no effect

I want to get all audit entries from an Alfresco audit application.
Following the Alfresco Audit REST API documentation, I wrote this query:
curl -u admin:admin "http://localhost:8080/alfresco/service/api/audit/query/audit-custom?fromId=1&toId=100000&fromTime=2017-02-19T18:46:09.212+09:00&toTime=2017-02-20T18:46:09.212+09:00&user=admin&forward=true&limit=0&verbose=true"
(Note the fromTime={2017-02-19T18:46:09.212+09:00}&toTime={2017-02-20T18:46:09.212+09:00} part)
PROBLEM: This returns the exact same 90 results as the request without the fromTime and toTime parameters. By the way, I installed Alfresco on 2017-02-21 so the query above should actually return zero results.
Same problem with { and } characters around the dates
Same problem with simpler dates like fromTime={2017-02-19}&toTime={2017-02-20}
Same problem without the extra parameters
How to use correctly the fromTime and toTime parameters?
It is not obvious in the documentation, but fromTime and longTime must be entered as long values.
Here is the relevant Alfresco source code:
public static final String PARAM_FROM_TIME = "fromTime";
protected Long getParamFromTime(WebScriptRequest req)
{
String paramStr = req.getParameter(PARAM_FROM_TIME);
try
{
return Long.parseLong(paramStr);
}
catch (NumberFormatException e)
{
return DEFAULT_TO_TIME;
}
}
As you can see, format problems are quietly dropped, and default values used instead, which is what is happening with the requests included in the question above.
With long values, a valid request could be:
curl -u admin:admin "http://localhost:8080/alfresco/service/api/audit/query/audit-custom?fromTime=1485152993728&toTime=1485239393728&verbose=true"
(Note the fromTime=1485152993728&toTime=1485239393728 part)
Here is a convenient Java snippet to convert dates to long values when performing tests:
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
long now = System.currentTimeMillis();
long lastMonth = now - TimeUnit.DAYS.toMillis(30);
long lastMonthPlusOne = now - TimeUnit.DAYS.toMillis(29);
System.out.println("Now:" + now);
System.out.println("Last month:" + lastMonth);
System.out.println("Last month plus one day:" + lastMonthPlusOne);
}
}

How do I show a REST call response in Test Results with Serenity?

I am using a framework with Serenity BDD (Thucydides), Cucumber and RestAssured. I want to be able to show the Response that I get after performing a request in my Test results HTML page.
Is there any way for doing that?
Thanks!
You can pass valid HTML text as a parameter to #Step methods in the step library. This will show up as formatted text in the reports on the step details page.
This can be achieved by creating a dummy #Step method called description that takes a String parameter. At runtime, the tests supply this method with formatted html text as parameter.
#Step
public void description(String html) {
//do nothing
}
public void about(String description, String...remarks) {
String html =
"<h2 style=\"font-style:italic;color:black\">" + description + "</h2>" +
"<div><p>Remarks:</p>" +
"<ul style=\"margin-left:5%; font-weight:200; color:#434343; font-size:10px;\">";
for (String li : remarks) html += "<li>" + li + "</li>";
html += "<ul></div>";
description(html);
}
This approach is described more fully here.

Swift 2 parse HTML and find particular nodes

Using the Kanna import I am currently parsing html using the following code:
if let doc = Kanna.HTML(url: NSURL(string: "https://en.wikipedia.org/wiki/Data")!, encoding: NSUTF8StringEncoding) {
// Search for nodes by XPath
for link in doc.xpath("/html/head...") {
primaryDisplay.text!=link.text!
print(link.text)
}
}
}
I was wondering how to identify specific "nodes"(not sure if that is the correct term) in/on a html page to parse the specific data I want...
Here is a image that shows what it is I wanted to know... I think...
A simple way to do what are you finding is using SwiftSoup
Try this:
do{
let html = "<!DOCTYPE html>" +
"<html>" +
"<head>" +
"<title>Some webpage</title>" +
"</head>" +
"<body>" +
"<p class='normal'>This is the first paragraph.</p>" +
"<p class='special'><b>this is in bold</b></p>" +
"</body>" +
"</html>";
let doc: Document = try SwiftSoup.parse(html)
let els: Elements = try doc.getElementsByClass("special")
let special: Element? = els.first()//get first element
print(try special?.text())//"this is in bold"
print(special?.tagName())//"p"
print(special?.child(0).tag().getName())//"b"
}catch Exception.Error(let type, let message)
{
print("")
}catch{
print("")
}
You should also take a look at xpath/xquery - it is a language specifically intended to traverse and query XML, which makes it applicable to XHTML and well HTML. XHTML is basically well formed HTML.
Assuming you had an xpath/xquery parser installed on your machine, you could...
get a list of all the p elements in the document: //p
get a list of all the p elements having class "special": //p[#class = 'special']
XQuery adds the ability to query documents using a SQL like syntax called FLWOR.
The difficulty in using this or any other parser for html is that often, the HTML is not well formed. That means that every opening tag does not have a closing tag. This makes any kind of parsing somewhat sketchy as the parser may not be able to figure out the hierarchy implied by the HTML.

Is there a way to get Bing's photo of the day?

Is there some way I could get the Bing background image programmatically?
Bing's API doesn't seem to provide such functionality, perhaps there's another way?
I think the best way is immitating the way they do it themselves through their AJAX calls.
They call this URL and extract the information through XML deserialization.
XML: http://www.bing.com/HPImageArchive.aspx?format=xml&idx=0&n=1&mkt=en-US
JSON: http://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&mkt=en-US
RSS: http://www.bing.com/HPImageArchive.aspx?format=rss&idx=0&n=1&mkt=en-US
The mkt attribute can obviously be changed to a different region than ´en-US´, but can also be opted out of entirely if you don't care about a specific region.
Note that the _1366x768.jpg suffix that is added to the image names appears to be modifiable into different resolutions (like _1920x1080.jpg for full HD and possibly others).
Here's a dump of the data as of 9/28/2013, in XML format.
<?xml version="1.0" encoding="utf-8"?>
<images>
<image>
<startdate>20130928</startdate>
<fullstartdate>201309280000</fullstartdate>
<enddate>20130929</enddate>
<url>/az/hprichbg/rb/LakeTurkana_EN-US15976511099_1366x768.jpg</url>
<urlBase>/az/hprichbg/rb/LakeTurkana_EN-US15976511099</urlBase>
<copyright>Lava rock pools at the southern end of Lake Turkana, in Kenya (© Nigel Pavitt/Corbis)</copyright>
<copyrightlink>http://www.bing.com/search?q=Lake+Turkana%2C+Kenya&form=hpcapt</copyrightlink>
<drk>1</drk>
<top>1</top>
<bot>1</bot>
<hotspots>
<hotspot>
<desc>These are the southern reaches of a lake...</desc>
<link>http://www.bing.com/maps/?v=2&cp=2.794725~37.335197&lvl=7&dir=0&sty=b&q=Lake%20Turkana%2C%20Kenya&form=hphot1</link>
<query>That stretches for 180 miles, up into another country</query>
<LocX>15</LocX>
<LocY>33</LocY>
</hotspot>
<hotspot>
<desc>This body of water was once called the Jade Sea.</desc>
<link>http://www.bing.com/search?q=green+algae&form=hphot2</link>
<query>What gives the water here its sometimes vibrant hue?</query>
<LocX>37</LocX>
<LocY>42</LocY>
</hotspot>
<hotspot>
<desc>One of the world's most powerful predators lives here.</desc>
<link>http://www.bing.com/videos/search?q=Underwater+Croc+Cams+National+Geographic&FORM=hphot3#view=detail&mid=D25E1909D3514A8732C5D25E1909D3514A8732C5</link>
<query>See some rare underwater footage of the beast</query>
<LocX>66</LocX>
<LocY>33</LocY>
</hotspot>
<hotspot>
<desc>Many fossils of ancient human ancestors have been uncovered in the surrounding area.</desc>
<link>http://www.bing.com/search?q=Turkana+Boy&form=hphot4</link>
<query>One skeleton was so complete, paleoanthropologists gave him a name</query>
<LocX>82</LocX>
<LocY>41</LocY>
</hotspot>
</hotspots>
<messages></messages>
</image>
<tooltips>
<loadMessage>
<message>Indlæser...</message>
</loadMessage>
<previousImage>
<text>Forrige</text>
</previousImage>
<nextImage>
<text>Næste</text>
</nextImage>
<play>
<text>Afspil</text>
</play>
<pause>
<text>Pause</text>
</pause>
</tooltips>
</images>
JSON FORMAT of BING IMAGE
I found a way to fetch the JSON format of the Bing Image of the day
http://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1
Note
n= The no of images u want( u can use Integers) ,
mkt= Your
location (example: en-US)
Here is the JSON output looks like
{
"images": [
{
"startdate": "20141214",
"fullstartdate": "201412141830",
"enddate": "20141215",
"url": "\/az\/hprichbg\/rb\/BlackButte_EN-IN7038391888_1920x1080.jpg",
"urlbase": "\/az\/hprichbg\/rb\/BlackButte_EN-IN7038391888",
"copyright": "Black Butte, seen from the Mount Jefferson Wilderness, Oregon, USA (\u00a9 Marc Adamus\/Aurora Photos)",
"copyrightlink": "http:\/\/www.bing.com\/search?q=Black+Butte&qs=n&form=hpcapt&mkt=en-in&pq=black+butte&sc=8-11&sp=-1&sk=&cvid=228ac7f125f94bbaafd4a4abd4f9a32d",
"wp": true,
"hsh": "94156ae1e2e1be49f9b739d2b7bff65c",
"drk": 1,
"top": 1,
"bot": 1,
"hs": [
],
"msg": [
{
"title": "How does it feel\u2026",
"link": "http:\/\/www.bing.com\/videos\/search?q=Climbing+Black+Butte&FORM=pgbar1&mkt=en-in#view=detail&mid=58BDB2F2B9FCB85D597558BDB2F2B9FCB85D5975",
"text": "To climb 1961.7 m?"
},
{
"title": "On top of the world",
"link": "http:\/\/www.bing.com\/images\/search?q=Pictures+From+the+Top+of+Mount+Everest&FORM=pgbar2&mkt=en-in",
"text": "It's mountaineer's dream view"
}
]
}
],
"tooltips": {
"loading": "Loading...",
"previous": "Previous",
"next": "Next",
"walle": "This image is not available to download as wallpaper.",
"walls": "Download this image. Use of this image is restricted to wallpaper only."
}
}
use the url from the images[]
and add it to 'http://bing.com'
here url is "url": "\/az\/hprichbg\/rb\/DayGecko_EN-US8730336235_1366x768.jpg"
One liner PowerShell (3.0 or higher)
irm is an alias for Invoke-RestMethod
irm "bing.com$((irm "bing.com/HPImageArchive.aspx?format=js&mkt=en-IN&n=1").images[0].url)" -OutFile bing.jpg
Microsoft has recently published a Bing Dynamic Theme for Windows 7, which contains an RSS Feed with links to Bing wallpapers.
There's also a Python script which tries to load the Bing website and guess the correct image URL, but from my experience, it usually results in a lower resolution image than those offered by the RSS feed.
I'm late to the party, but in case someone needs a PHP implementation: I've written a simple class which handles the procedure:
https://github.com/grubersjoe/bing-daily-photo
I like Bing images too but their app is too bloated for the purpose of downloading images. After analyzing connection with fiddler, I wrote this code. The 1920x1200 comes with Bing logo embedded but lower resolutions do not have it.
You can have windows show you random images from the image folder you set, so as you download them daily, it'll show you more random images.
If you do keep the "imageDir", you need to change the permissions on that folder or it will crash, I did not bother with catching errors.
Lastly, un-comment the lines if you want to set your wallpaper to today's image or you can create a task to run the program, say a minute after logon.
using System;
using System.IO;
using System.Net;
//using System.Runtime.InteropServices;
namespace Bing
{
class Program
{
// [DllImport("user32.dll", CharSet = CharSet.Auto)]
// private static extern Int32 SystemParametersInfo(UInt32 uiAction, UInt32 uiParam, String pvParam, UInt32 fWinIni);
private static String imgDir = #"C:\Windows\Web\Wallpaper\Bing\";
static void Main(string[] args)
{
String imageFileName;
if (!Directory.Exists(imgDir))
Directory.CreateDirectory(imgDir);
for (byte i = 6; i >= 0; i--)
{
imageFileName = imgDir + DateTime.Today.AddDays(-i).ToString("yyy-MM-dd") + ".jpg";
if (!File.Exists(imageFileName))
{
string response = null;
Connect(ref response, i);
ProcessXml(ref response);
using (WebClient client = new WebClient())
client.DownloadFile("http://www.bing.com" + response + "_1920x1200.jpg", imageFileName);
}
}
//SystemParametersInfo(20, 0, imageFileName, 0x01 | 0x02);
}
private static void Connect(ref string res, byte i)
{
HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create("http://www.bing.com/hpimagearchive.aspx?format=xml&idx=" + i + "&n=1&mbl=1&mkt=en-ww");
webrequest.KeepAlive = false;
webrequest.Method = "GET";
using (HttpWebResponse webresponse = (HttpWebResponse)webrequest.GetResponse())
using (StreamReader loResponseStream = new StreamReader(webresponse.GetResponseStream()))
res = loResponseStream.ReadToEnd();
}
private static void ProcessXml(ref string xmlString)
{
using (System.Xml.XmlReader reader = System.Xml.XmlReader.Create(new StringReader(xmlString)))
{
reader.ReadToFollowing("urlBase");
xmlString = reader.ReadElementContentAsString();
}
}
}
}
I saw that many people are asking for the new RSS link too, just change the format parameter in the URL to "rss".
RSS: http://www.bing.com/HPImageArchive.aspx?format=rss&idx=0&n=1&mkt=en-US
In case anyone is looking for possible implementations, I wrote a small command-line program in C# to download, save, and set my background as the Bing Image of the Day. Feel free to modify it to your personal needs. https://github.com/josueespinosa/BingBackground
using Microsoft.Win32;
using Newtonsoft.Json;
using System;
using System.Drawing;
using System.IO;
using System.Net;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace BingBackground
{
class BingBackground
{
private static void Main(string[] args)
{
string urlBase = GetBackgroundUrlBase();
Image background = DownloadBackground(urlBase + GetResolutionExtension(urlBase));
SaveBackground(background);
SetBackground(background, PicturePosition.Fill);
}
private static dynamic DownloadJson()
{
using (WebClient webClient = new WebClient())
{
Console.WriteLine("Downloading JSON...");
string jsonString = webClient.DownloadString("https://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&mkt=en-US");
return JsonConvert.DeserializeObject<dynamic>(jsonString);
}
}
private static string GetBackgroundUrlBase()
{
dynamic jsonObject = DownloadJson();
return "https://www.bing.com" + jsonObject.images[0].urlbase;
}
private static string GetBackgroundTitle()
{
dynamic jsonObject = DownloadJson();
string copyrightText = jsonObject.images[0].copyright;
return copyrightText.Substring(0, copyrightText.IndexOf(" ("));
}
private static bool WebsiteExists(string url)
{
try
{
WebRequest request = WebRequest.Create(url);
request.Method = "HEAD";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
return response.StatusCode == HttpStatusCode.OK;
}
catch
{
return false;
}
}
private static string GetResolutionExtension(string url)
{
Rectangle resolution = Screen.PrimaryScreen.Bounds;
string widthByHeight = resolution.Width + "x" + resolution.Height;
string potentialExtension = "_" + widthByHeight + ".jpg";
if (WebsiteExists(url + potentialExtension))
{
Console.WriteLine("Background for " + widthByHeight + " found.");
return potentialExtension;
}
else
{
Console.WriteLine("No background for " + widthByHeight + " was found.");
Console.WriteLine("Using 1920x1080 instead.");
return "_1920x1080.jpg";
}
}
private static Image DownloadBackground(string url)
{
Console.WriteLine("Downloading background...");
WebRequest request = WebRequest.Create(url);
WebResponse reponse = request.GetResponse();
Stream stream = reponse.GetResponseStream();
return Image.FromStream(stream);
}
private static string GetBackgroundImagePath()
{
string directory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), "Bing Backgrounds", DateTime.Now.Year.ToString());
Directory.CreateDirectory(directory);
return Path.Combine(directory, DateTime.Now.ToString("M-d-yyyy") + ".bmp");
}
private static void SaveBackground(Image background)
{
Console.WriteLine("Saving background...");
background.Save(GetBackgroundImagePath(), System.Drawing.Imaging.ImageFormat.Bmp);
}
private enum PicturePosition
{
Tile,
Center,
Stretch,
Fit,
Fill
}
internal sealed class NativeMethods
{
[DllImport("user32.dll", CharSet = CharSet.Auto)]
internal static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni);
}
private static void SetBackground(Image background, PicturePosition style)
{
Console.WriteLine("Setting background...");
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(Path.Combine("Control Panel", "Desktop"), true))
{
switch (style)
{
case PicturePosition.Tile:
key.SetValue("PicturePosition", "0");
key.SetValue("TileWallpaper", "1");
break;
case PicturePosition.Center:
key.SetValue("PicturePosition", "0");
key.SetValue("TileWallpaper", "0");
break;
case PicturePosition.Stretch:
key.SetValue("PicturePosition", "2");
key.SetValue("TileWallpaper", "0");
break;
case PicturePosition.Fit:
key.SetValue("PicturePosition", "6");
key.SetValue("TileWallpaper", "0");
break;
case PicturePosition.Fill:
key.SetValue("PicturePosition", "10");
key.SetValue("TileWallpaper", "0");
break;
}
}
const int SetDesktopBackground = 20;
const int UpdateIniFile = 1;
const int SendWindowsIniChange = 2;
NativeMethods.SystemParametersInfo(SetDesktopBackground, 0, GetBackgroundImagePath(), UpdateIniFile | SendWindowsIniChange);
}
}
}
Bash one liner (needs bash, curl and jq), useful for putting in a cronjob:
BACKGROUND_META=$(curl 'https://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&mkt=en-US'); curl -o $(echo $BACKGROUND_META | jq -r '.images[0].urlbase' | sed s/.*=//).jpg "https://bing.com$(echo $BACKGROUND_META| jq -r '.images[0].url')"
This JavaScript will answer the 'what to do with the api' by changing the background image of a div to the background of the current day's bing image.
function PullBackground() {
var ajaxRequest = new XMLHttpRequest(), background = '';
ajaxRequest.open('POST', "http://www.bing.com/HPImageArchive.aspx?format=xml&idx=0&n=1&mkt=en-US", true);
ajaxRequest.setRequestHeader("Connection", "close");
ajaxRequest.send('');
ajaxRequest.onreadystatechange = function () {
if (ajaxRequest.readyState == 4) {
background = ajaxRequest.responseText;
var res = background.split("<url>");
var res1 = res[1].split("</url>");
background = res1[0];
document.getElementById('NameOfTheDivToChange').style.backgroundImage = "url('http://bing.com" + background + "')"
document.getElementById('NameOfTheDivToChange').style.backgroundSize = "100%";
}
}
}
Have a look at bing-desktop-wallpaper-changer on Github. The script has been written in python and I hope you find your answer there.
#!/usr/bin/python
#-*- coding: utf-8 -*-
import os
import urllib
import urllib2
from bs4 import BeautifulSoup
# Get BingXML file which contains the URL of the Bing Photo of the day
# idx = Number days previous the present day. 0 means current day, 1 means yesterday, etc
# n = Number of images predious the day given by idx
# mkt denotes your location. e.g. en-US means United States. Put in your country code
BingXML_URL = "http://www.bing.com/HPImageArchive.aspx? format=xml&idx=0&n=1&mkt=en-US"
page = urllib2.urlopen(BingXML_URL)
BingXML = BeautifulSoup(page, "lxml")
# For extracting complete URL of the image
Images = BingXML.find_all('image')
ImageURL = "https://www.bing.com" + Images[0].url.text
ImageName = Images[0].startdate.text+".jpg"
urllib.urlretrieve(ImageURL, ImageName)
Have a look at the Github project for detailed code
Simple PowerShell, place into a folder, create a daily task in Windows Task Scheduler, script saves images at its run folder, then in your Desktop Background settings choose that folder as a background.
[xml]$doc = (New-Object System.Net.WebClient).DownloadString("https://www.bing.com/HPImageArchive.aspx?format=xml&idx=0&n=1&mkt=ru-RU")
$url = $doc.images.image.url
$url = "https://www.bing.com/" + $url -replace "_1366x768","_1920x1200"
Write-Output $url
$fileName = Split-Path $url -leaf
$output = "$PSScriptRoot\$fileName"
$start_time = Get-Date
Invoke-WebRequest -Uri $url -OutFile $output
Write-Output "Saved to: $output Time taken: $((Get-Date).Subtract($start_time).Seconds) second(s)"
Here's a simple Python script to fetch the Bing photo of the day using just requests and json:
import requests
import json
BING_URI_BASE = "http://www.bing.com"
BING_WALLPAPER_PATH = "/HPImageArchive.aspx?format=js&idx=0&n=1&mkt=en-US"
# open the Bing HPImageArchive URI and ask for a JSON response
resp = requests.get(BING_URI_BASE + BING_WALLPAPER_PATH)
if resp.status_code == 200:
json_response = json.loads(resp.content)
wallpaper_path = json_response['images'][0]['url']
filename = wallpaper_path.split('/')[-1]
wallpaper_uri = BING_URI_BASE + wallpaper_path
# open the actual wallpaper uri, and write the response as an image on the filesystem
response = requests.get(wallpaper_uri)
if resp.status_code == 200:
with open(filename, 'wb') as f:
f.write(response.content)
else:
raise ValueError("[ERROR] non-200 response from Bing server for '{}'".format(wallpaper_uri))
else:
raise ValueError("[ERROR] non-200 response from Bing server for '{}'".format(BING_URI_BASE + BING_WALLPAPER_PATH))
This will write a file such as TurtleTears_EN-US7942276596_1920x1080.jpg to the same directory where the script is executed. Of course, can tweak a whole bunch of things here, but gets the job done reasonably easily.
I was having trouble getting a proper RSS feed that I could use with John’s Background Switcher until I found this feedburner feed which seems to work quite well: http://feeds.feedburner.com/bingimages
I just finally decided to write a script in Python 3 to get the most images (16) from the xml archive.
So now i can archive the images in no effort. Just run the Python script.
I organize the images into Year / Month folders like this: 2018 > 12 December > 2018-12-06.jpg
This script goes in my Bing Wallpapers folder. (which is in my Pictures folder)
import urllib.request as urllib
import json
from datetime import date
from dateutil import parser
import sys,os
months = "January","Febuary","March","April","May","June","July","August","September","October","November","December"
def downloadBingImages(start):
try: data = urllib.urlopen("https://www.bing.com/hpimagearchive.aspx?format=js&idx=%i&n=8&mkt=en-NZ"%start).read()
except: sys.exit()
e = json.loads(data.decode())
images = e["images"]
for image in images:
d = parser.parse(image["startdate"]) # parse("20181206")
filename = str(d.date())+".jpg" # 2018-12-06.jpg
folder = "%i/%i %s/"%(d.year,d.month,months[d.month-1]) # 2018/12 December/
file = folder+filename # 2018/12 December/2018-12-06.jpg
if not os.path.exists(folder): os.makedirs(folder)
exists = os.path.isfile(file)
url = "https://www.bing.com"+image["urlbase"]+"_1920x1200.jpg"
print(("downloading","exists")[exists],filename,url)
if not exists:
try: urllib.urlretrieve(url,file)
except: sys.exit()
print()
# downloads the 16 latest bing images
downloadBingImages(-1)
downloadBingImages(7)
Optional extra code to update the wallpaper: (put beneath downloadBingImages(7))
import ctypes,win32con
def getWallpaper():
ubuf = ctypes.create_unicode_buffer(512)
ctypes.windll.user32.SystemParametersInfoW(win32con.SPI_GETDESKWALLPAPER,len(ubuf),ubuf,0)
return ubuf.value
def setWallpaper(path):
changed = win32con.SPIF_UPDATEINIFILE | win32con.SPIF_SENDCHANGE
ctypes.windll.user32.SystemParametersInfoW(win32con.SPI_SETDESKWALLPAPER,0,path,changed)
# update wallpaper after a week from current
wallpaper = getWallpaper()
if wallpaper.startswith(os.getcwd()): # has to be in script directory
try: wallpaperDate = parser.parse(os.path.splitext(os.path.basename(wallpaper))[0])
except: sys.exit() # not using an image with a parsable date
t = date.today()
if (t-wallpaperDate.date()).days>=7: # been a week or longer
setWallpaper(os.path.abspath("%i/%i %s/"%(t.year,t.month,months[t.month-1])+str(t)+".jpg")) # .../2018/12 December/2018-12-14.jpg
example output:
exists 2018-12-15.jpg https://www.bing.com/az/hprichbg/rb/YosemiteBridge_ROW11493343707_1920x1200.jpg
exists 2018-12-14.jpg https://www.bing.com/az/hprichbg/rb/CardinalBerries_ROW13321753978_1920x1200.jpg
exists 2018-12-13.jpg https://www.bing.com/az/hprichbg/rb/ReykjavikYuleLads_ROW12406174277_1920x1200.jpg
exists 2018-12-12.jpg https://www.bing.com/az/hprichbg/rb/PoinsettiaBuds_ROW14015106672_1920x1200.jpg
exists 2018-12-11.jpg https://www.bing.com/az/hprichbg/rb/KilimanjaroMawenzi_ROW12001033920_1920x1200.jpg
exists 2018-12-10.jpg https://www.bing.com/az/hprichbg/rb/ChristmasIslandCrab_ROW12174154872_1920x1200.jpg
exists 2018-12-09.jpg https://www.bing.com/az/hprichbg/rb/JohnDaySnow_ROW10922424229_1920x1200.jpg
exists 2018-12-08.jpg https://www.bing.com/az/hprichbg/rb/BanffEvergreens_ROW13248925556_1920x1200.jpg
exists 2018-12-07.jpg https://www.bing.com/az/hprichbg/rb/TaisetsuShirakawago_ROW12053480529_1920x1200.jpg
exists 2018-12-06.jpg https://www.bing.com/az/hprichbg/rb/Huuhkajat_ROW11700922065_1920x1200.jpg
exists 2018-12-05.jpg https://www.bing.com/az/hprichbg/rb/SurfersBronteBeach_ROW9358782018_1920x1200.jpg
exists 2018-12-04.jpg https://www.bing.com/az/hprichbg/rb/SphinxObservatory_ROW9691446114_1920x1200.jpg
exists 2018-12-03.jpg https://www.bing.com/az/hprichbg/rb/HussarPoint_ROW8654856850_1920x1200.jpg
exists 2018-12-02.jpg https://www.bing.com/az/hprichbg/rb/Nuuk_ROW12381573676_1920x1200.jpg
exists 2018-12-01.jpg https://www.bing.com/az/hprichbg/rb/RedAntarctica_ROW12620598839_1920x1200.jpg
exists 2018-11-30.jpg https://www.bing.com/az/hprichbg/rb/KilchurnSky_ROW9474162800_1920x1200.jpg
P.S. the above script is using &mkt=en-NZ for the New Zealand images.
You can check out the market code for other countries here.
You can also see all the images archived since 2009 for different countries here.
(only in 1366x768 though)
Major P.S. add the script to Task Scheduler to run when logging on. (or daily/weekly)
Create Basic Task
Program/script: python (or C:\Python34\python.exe if it's not in your env path)
arguments: "path/to/your/script.py"
start in: "path/to/your"
UPDATE! (March 2019)
The image for 2019-03-10 was given wrong startdate (20190309) in both the xml and rss format.
Using Json format instead. (since it gives accurate date)
https://peapix.com/bing/feed will listing the latest Bing image without Bing logo , maintain by peapix.com. Supported the following country/region: AU,CA,CN,DE,FR,JP,US,GB.
for example, https://peapix.com/bing/feed?country=jp for Japan and https://peapix.com/bing/feed?country=us for the United States.
OP doesn't specify the operating system, so here is one for usage in Linux. I modified from the script offered here.
Basically it fetches the url of the image of the day, downloads the image and save to a fixed file ~/.config/wallpaper.jpg, and uses feh to set the wallpaper. At the same time sends a notification.
#!/bin/sh
WP_FILE=$HOME/.config/wallpaper.jpg
bing="www.bing.com"
# $xmlURL is needed to get the xml data from which
# the relative URL for the Bing pic of the day is extracted
#
# The mkt parameter determines which Bing market you would like to
# obtain your images from.
# Valid values are: en-US, zh-CN, ja-JP, en-AU, en-UK, de-DE, en-NZ, en-CA or opted out.
#
# The idx parameter determines where to start from. 0 is the current day,
# 1 the previous day, etc.
xmlURL="http://www.bing.com/HPImageArchive.aspx?format=xml&idx=0&n=1&mkt=en-US"
# The desired Bing picture resolution to download
# Valid options: "_1024x768" "_1280x720" "_1366x768" "_1920x1200"
desiredPicRes="_1920x1080"
# The file extension for the Bing pic
picExt=".jpg"
# Extract the relative URL of the Bing pic of the day from
# the XML data retrieved from xmlURL, form the fully qualified
# URL for the pic of the day, and store it in $picURL
# Form the URL for the desired pic resolution
desiredPicURL=$bing$(curl -s $xmlURL | grep -oP "(?<=<urlBase>)(.*?)(?=</urlBase>)")$desiredPicRes$picExt
# Form the URL for the default pic resolution
defaultPicURL=$bing$(curl -s $xmlURL | grep -oP "(?<=<url>)(.*?)(?=</url>)")
# $picName contains the filename of the Bing pic of the day
# Attempt to download the desired image resolution. If it doesn't
# exist then download the default image resolution
if wget --quiet --spider "$desiredPicURL"
then
# Download the Bing pic of the day at desired resolution
curl -s -o "$WP_FILE" "$desiredPicURL"
else
# Download the Bing pic of the day at default resolution
curl -s -o "$WP_FILE" "$defaultPicURL"
fi
if [[ -f "${WP_FILE}" ]]; then
feh --bg-scale "$WP_FILE" && \
notify-send -i emblem-photos "Wallpaper" "Wallpaper changed" \
-h int:suppress-sound:1 -h int:transient:1
fi
You might consider getting the file_content of that url and search the file for the image.
Not sure that's the best way, but it is a way.
Using the URL from #Siv, here's an example of JavaScript that updates <div class="bgimg" id="background">
function GetImageURL(ans) {
var suffix = ans.images[0].url
document.getElementById("background").style.backgroundImage = 'url("' +
'http://bing.com/' + suffix + '"'
}
function GetJSON() {
var xmlhttp = new XMLHttpRequest()
var url = "https://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1"
xmlhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
var ans = JSON.parse(this.responseText);
GetImageURL(ans);
}
};
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
window.onload = function () {
GetJSON()
}
The css for this class is:
.bgimg {
height: 100%;
position: relative;
opacity: 0.95;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
You can do that using python and wget on a linux machine:
import os # import the os package
os.system("wget -O index.html http://www.bing.com") # download the bing index
str1 = open('index.html', 'r').read() # extract the file path using split
str2=str1.split("g_img={url: \"")[1]
str3=str2.split(".jpg")[0]
os.system("wget -O daily_im.jpg http://www.bing.com" + str3 + ".jpg") # donwload the daily image
It downloads the daily bing background in the local directory under the name daily_im.jpg. You can put everything on a script.py and launch it programmatically.
EDIT 09/27/2018: http://www.istartedsomething.com/bingimages responds 404 for weeks. It may do not exist anymore. :-(
You can use istartedsomething.com's Bing Image Archive. It is an unofficial Bing Image Archive. It uses an homemade endpoint which is helpful to retrieve images:
GET /bingimages/getimage.php?id=<image_id>
id is a string containing the date when the image was published and the country where it was published. id has to comply with the following format: YYYYMMDD-xx, where:
YYYY is the year, written with four digits.
MM is the month, written with two digits.
DD is the day, written with two digits.
xx is the country indicator. Bing Image Archive currently supports the following countries:
au: Australia.
br: Brazil.
ca: Canada.
cn: China.
de: Deutschland.
fr: France.
gb: Great Britain.
jp: Japan.
nz: New Zealand.
uk: United Kingdom.
us: United States of America.
It returns an useful JSON object if it has some information or false if it hasn't got anything.
Example 1: Retriving the Bing daily image which was published on May, 24th 2014 in New Zealand
The image ID is 20140524-nz because the demanded image was published on 05/24/2014 and it was published in New Zealand, whose country indicator is nz.
http://www.istartedsomething.com/bingimages/getimage.php?id=20140524-nz returns the following piece of JSON:
{
"url":"\/az\/hprichbg\/rb\/LakeMagadiFlamingos_ROW9792683076_1366x768.jpg",
"region":"nz",
"date":"2014-05-24",
"copyright":"Flamingos take flight, Lake Magadi, Kenya (\u00a9 Bobby Haas\/Getty Images)(Bing New Zealand)",
"imageurl":"http:\/\/www.istartedsomething.com\/bingimages\/cache\/LakeMagadiFlamingos_ROW9792683076_1366x768.jpg",
"hotspots":[],
"video":[]
}
You can use the imageurl field or the url (Bing URL path) field to get your image.
Example 2: Retriving the Bing daily image which was published on July, 12th 1998 in France
The image ID is 19980712-fr because the demanded image was published on 07/12/1998 and it was published in France, whose country indicator is fr.
http://www.istartedsomething.com/bingimages/getimage.php?id=19980712-fr returns false because there is no Bing Daily Image for France on 07/12/1998 (Bing did not even exist at this time).

Why is GWT ArrayList of String objects truncating text with an ampersand?

I'm using GWT on the client side. I store String objects in an ArrayList instance, and when I add the value "AT&T", it only seems to be storing "AT". I suspect this is the result of the ArrayList truncating the text due to the ampersand, but I have yet to write a smaller proof-of-concept to be sure. Has anyone else encountered this problem?
GWT 2.1.1
Tomcat 7.0.5
Firefox 5.0.1
So this test succeeds:
ArrayList<String> test = new ArrayList<String>();
test.add( "testing&123");
Window.alert( test.get(0) + " - " + test.get(0).contains("&") );
My code effectively does this:
String test = "AT&T";
MyApp.getInstance().getDataStore().add( test );
Window.alert( test + " - " + MyApp.getInstance().getDataStore().getItems().get(0) );
public void DataStore.add( String item ) {
itemsList.add( item );
}
public ArrayList<String> getItems() {
return itemList;
}
The output is "AT&T - AT". So if the ArrayList is not the problem, is it the method calls?
Well, it turns out it was an interaction between my History Manager and the DataStore class. A very strange situation that no one could have helped me with given the limited amount of information I had provided.