Book reviews for August 2017

Empire Games (Empire Games #1) by Charles Stross

Empire Games (Empire Games #1) by Charles Stross

4/5

 

The Delirium Brief (Laundry Files, #8) by Charles Stross

The Delirium Brief (Laundry Files, #8) by Charles Stross

4/5

 

The Thirst (Harry Hole #11) by Jo Nesbø

The Thirst (Harry Hole #11) by Jo Nesbø

4/5

 

The Revolution Trade (The Merchant Princes, #5-6) by Charles Stross

The Revolution Trade (The Merchant Princes, #5-6) by Charles Stross

4/5

 

The Traders' War (The Merchant Princes, #3-4) by Charles Stross

The Traders' War (The Merchant Princes, #3-4) by Charles Stross

4/5

 

Influx by Daniel Suarez

Influx by Daniel Suarez

4/5

 

The Bloodline Feud (The Merchant Princes, #1-2) by Charles Stross

The Bloodline Feud (The Merchant Princes, #1-2) by Charles Stross

4/5

 

Add your comment...

Related Posts

(All Reviews)

Recent Wildlife

By Robert Ellison. Updated on Monday, January 20, 2025.

Recent Wildlife

Recent Wildlife

Recent Wildlife

Recent Wildlife

Recent Wildlife

Recent Wildlife

Recent Wildlife

Black bear cub, red legged frog, deer, lizard #10, young salmon, elk and a random crab.

In this photograph, we find ourselves observing a tranquil scene that unfolds across the expanse of a serene water body. A dense forest borders the far side of the water, its foliage merging into an array of deep greens and earthy browns, evoking a sense of untouched wilderness. Near the water’s edge, a lone dark figure, possibly a bear, can be glimpsed against the lush backdrop, adding an element of intrigue and life to the landscape. The rippling water reflects the overcast sky, lending an emotional ambiance of calmness intertwined with a hint of mystery. The photograph aspires to capture the essence of wildlife in its indigenous setting, where nature remains the prominent storyteller.

The style of the photograph could be described as documentary with a focus on capturing wildlife in its natural habitat. The composition is expansive, allowing the viewer's eye to wander from the foreground to the distant treeline, providing context and setting. However, the clarity of the central subject is somewhat compromised; the photograph lacks sharpness, particularly around the wildlife, which diminishes the impact of this central motif. Despite this, the image succeeds in depicting a peaceful, natural tableau. The use of horizontal lines in the form of the water and shore helps anchor the image, yet the viewer may find the lack of focus a bit distracting. Overall, while the image effectively conveys a serene natural environment, enhancing the focus on the wildlife subject would add greater visual impact.

Add your comment...

Related Posts

(Recent Photos)

(Published to the Fediverse as: Recent Wildlife #photo #bear #frog #deer #lizard #fish #elk #crab Photos of a bear, a red legged frog, a deer, a lizard, a young salmon, an elk and a random crab. )

2017 Total Solar Eclipse from Madras, OR

By Robert Ellison. Updated on Saturday, January 18, 2025.

Total solar eclipse composite shot from Madras, Oregon for the 2017 eclipse.

Edited highlights from the 2017 total solar eclipse shot from Madras, Oregon.

360 spherical video of totality. This is best in a virtual reality headset.



The three timelapse videos edited into the version at the top of the page. The first one was shot on a GoPro. The second is from a Sony RX100V with an ND5 filter and the third is the Sony timelapse processed to keep the sun at the center of the frame.

(Previously)

This captivating photograph captures the ethereal dance of the 2017 Total Solar Eclipse from Madras, Oregon. A series of crescents, slightly curved and luminescent, cascade diagonally across the black canvas of the sky. Gradually moving from left to right, each of the crescents represents a stage in the eclipse, illustrating the moon’s graceful passage across the sun's fiery gaze. The serene background of deep blackness enhances the sense of cosmic wonder, suggesting an embrace between celestial giants. Each crescent edges closer to perfect obscuration, narrating the celestial event's story through a sequence of breathtaking transformations captured in perfect symmetry.

The photograph employs a time-lapse composition that masterfully conveys the eclipse's temporal progression. The strong diagonal line formed by the crescents adds dynamism and guides the viewer's eye instinctively across the frame, creating a sense of movement and continuity. This composition is highly effective in representing the eclipse’s journey. Technically, the balance between light and darkness is impeccably managed, with the black sky providing a stark contrast that highlights the sun's varying crescents. What stands out is the precision in spacing each stage evenly, enhancing the visual narrative. However, one could argue that a slightly wider frame might have offered more context, perhaps embracing the horizon or subtle atmospheric hues. Overall, this photograph succeeds in conveying the awe-inspiring phenomenon with grace and clarity.

Add your comment...

Related Posts

(Recent Photos)

(Published to the Fediverse as: 2017 Total Solar Eclipse from Madras, OR #photo #timelapse #spherical #eclipse #solar #360 #video Timelapse video, composite photo and spherical 360 video of totality from the 2017 total solar eclipse in Madras, Oregon. )

Stars from Pine Mountain Lake

By Robert Ellison. Updated on Saturday, February 19, 2022.

Stars from Pine Mountain Lake

Timelapse of sunset and then stars shot over several nights at Pine Mountain Lake in Groveland, CA.

Add your comment...

Related Posts

(More Timelapses)

(Published to the Fediverse as: Stars from Pine Mountain Lake #timelapse #4k #stars #california #video Timelapse of sunset and stars from Pine Mountain Lake in Groveland, California (4K) )

Why Microsoft is Likely Doomed Based on one Email Folder

By Robert Ellison. Updated on Thursday, August 5, 2021.

Close up of the useless Junk folder in Microsoft Outlook

When you get a piece of spam in Outlook you move it to Junk or block the sender. And then, even if that junk mail is marked as read, the Junk folder has a BOLD MESSAGE COUNT. It's the only folder that does this. I cannot do any other work while I have a bold message count and so I have to switch to the Junk folder and delete the message to get rid of it.

Regular email: read, file, done.

Junk email: recognize as spam, click block sender, confirm that I really want to block the sender, switch to Junk folder, mark as read, delete.

Something is really wrong with this workflow. It's a lens through which you can view the ultimate demise of the company. Sure, Office isn't going away soon and Azure is growing like crazy and SQL Server runs on Linux. But somewhere in Redmond 5,000 people designed a Junk email folder that is the MOST IMPORTANT folder in Outlook. The rest were presumably too busy making Windows Update worse to stop this.

My Google experience is that I really don't get much spam. The spam that I do get is hidden from me unless I actually need to rifle through it for some reason. On the occasion I actually get legitimate junk I just flag it as such and never have to touch it or it's ilk again.

Add your comment...

Related Posts

(All Etc Posts)

(Published to the Fediverse as: Why Microsoft is Likely Doomed Based on one Email Folder #etc #outlook #microsoft The Junk folder in Microsoft Outlook is a lens through which you can view the ultimate demise of the company. )

Bay Snaps

By Robert Ellison. Updated on Saturday, January 18, 2025.

Golden Gate Bridge

Alcatraz through Spray

Photos of the Golden Gate Bridge and Alcatraz in the San Francisco Bay.

The photograph titled "Bay Snaps" captures a majestic view of the iconic Golden Gate Bridge, shrouded in a blanket of ethereal fog. The imposing architectural marvel stretches diagonally across the frame, its massive steel beams painting a vibrant streak of red against the muted grays of the misty sky. The fog clings to the upper sections of the bridge, obscuring its towering form and adding a sense of mystery and grandeur. Below, the calm waters of the bay mirror the muted tones of the cloudy atmosphere, while the rugged coastline provides a sturdy foundation in the background, grounding the scene with its textured rocks.

The composition adopts a dramatic angle, positioning the viewer beneath the bridge, which enhances the sense of scale and amplifies its grandeur. This perspective leads the eye along the bridge’s span, creating a dynamic tension between the man-made and natural elements. The use of color is striking, with the vivid red of the bridge standing out starkly against the monochrome fog, creating a powerful focal point. The technical execution is impressive, capturing the subtle nuances of the fog and the strong lines of the bridge with clarity. However, some may find the heavy use of negative space in the upper part slightly overwhelming, perhaps wishing for more detail in the sky or surroundings. Nonetheless, the overall mood and drama conveyed through the interplay of light, color, and perspective make this photograph a captivating snapshot of architectural magnificence.

Add your comment...

Related Posts

(Recent Photos)

(Published to the Fediverse as: Bay Snaps #photo #ggb #alcatraz Pictures of the Golden Gate Bridge and Alcatraz )

Stars over Lake Tahoe

By Robert Ellison. Updated on Saturday, February 19, 2022.

Timelapse of stars over Lake Tahoe, California

4K timelapse of stars and the Milky Way over Lake Tahoe, California.

Add your comment...

Related Posts

(More Timelapses)

(Published to the Fediverse as: Stars over Lake Tahoe #timelapse #video #4k #laketahoe #california 4K timelapse of stars and the Milky Way over Lake Tahoe, California. )

Email Alerts for new Referers in Google Analytics using Apps Script

By Robert Ellison. Updated on Monday, February 13, 2023.

Referral Traffic in Google Analytics

It's useful to know when you have a new website referrer. Google Analytics is plagued with spam referral and you want to filter this out of reporting as quickly as possible to stop it from skewing your data. It's also helpful to be able to respond quickly to new referral traffic - maybe leave a comment or promote the new link on social media.

The script below will send you a daily email with links to any new referrers (this is GA3, there is a GA4 version later in this post).

var TableId = 'ga:your-view-id';
var SendEmailTo = 'your-email-address';
function main() {
var scriptProperties = PropertiesService.getScriptProperties();
var currentProps = scriptProperties.getProperties();
var anythingNew = false;
var newText = '';
var yesterday = Utilities.formatDate(new Date(new Date().getTime() - 24 * 60 * 60 * 1000), Session.getTimeZone(), 'yyyy-MM-dd');
var options = {
'dimensions': 'ga:fullReferrer',
'filters': 'ga:medium==referral',
'max-results': 20000
};
var report = Analytics.Data.Ga.get(TableId, yesterday, yesterday, 'ga:sessions', options);
if (report.rows) {
for (var i = 0; i < report.totalResults; i++) {
if (!(report.rows[i][0] in currentProps)) {
Logger.log('Found new referrer: ' + report.rows[i][0]);
scriptProperties.setProperty(report.rows[i][0], report.rows[i][1]);
anythingNew = true;
newText += 'New referrer: ' + report.rows[i][0] + '\r\n';
}
}
} else {
Logger.log('GA report is empty');
}
if (anythingNew) {
MailApp.sendEmail(SendEmailTo, 'Found new referrers for ' + TableId + ' on ' + new Date(), newText);
}
}
view raw NewReferers.gs hosted with ❤ by GitHub

Start a new apps script project in Google Drive and paste in the code. At the top enter the view ID that you want to monitor and the email address that should receive reports.

Choose Advanced Google Services from the Resources menu and switch on the Google Analytics API. Then click the Google API Console link and enable the Google Analytics API there as well.

Finally pick Current project's triggers from the Edit menu and trigger the main function daily at a convenient time.

This script saves known referrers in script properties. For a site with lots of traffic this may run out of space in which case you might need to switch this out and write known referrers to a sheet instead.

For Google Analytics 4 properties use the version of the script below. The setup process is the same, but you need the Google Analytics Data API instead of the Google Analytics API.

var PropertyId = '';
var PropertyName = ''
var SendEmailTo = '';
function main() {
var scriptProperties = PropertiesService.getScriptProperties();
var currentProps = scriptProperties.getProperties();
var anythingNew = false;
var newText = '';
const metric = AnalyticsData.newMetric();
metric.name = 'totalUsers';
const dimension = AnalyticsData.newDimension();
dimension.name = 'pageReferrer';
const dateRange = AnalyticsData.newDateRange();
dateRange.startDate = 'yesterday';
dateRange.endDate = 'yesterday';
const dimensionfilter = AnalyticsData.newFilterExpression()
dimensionfilter.filter = AnalyticsData.newFilter()
dimensionfilter.filter.fieldName = 'sessionMedium'
dimensionfilter.filter.stringFilter = AnalyticsData.newStringFilter()
dimensionfilter.filter.stringFilter.value = 'referral'
const request = AnalyticsData.newRunReportRequest();
request.dimensions = [dimension];
request.metrics = [metric];
request.dateRanges = dateRange;
request.dimensionFilter = dimensionfilter;
const report = AnalyticsData.Properties.runReport(request,
'properties/' + PropertyId);
if (!report.rows) {
Logger.log('GA returned no data.');
return;
}
for (var i = 0; i < report.rowCount; i++){
var referrer = report.rows[i].dimensionValues[0].value;
if ((referrer) && (referrer.length > 0)) {
if (!(referrer in currentProps)){
Logger.log('Found new referrer: ' + referrer);
scriptProperties.setProperty(referrer, report.rows[i].metricValues[0].value);
anythingNew = true;
newText += 'New referrer: ' + referrer + '\r\n';
}
}
}
if (anythingNew) {
MailApp.sendEmail(SendEmailTo, 'Found new referrers for ' + PropertyName + ' on ' + new Date(), newText);
}
}
view raw Code.gs hosted with ❤ by GitHub

Add your comment...

More Google Apps Script Projects

(All Code Posts)

(Published to the Fediverse as: Email Alerts for new Referers in Google Analytics using Apps Script #code #googleanalytics #appsscript #gas #ga4 Apps script that will email you any new referral traffic from Google Analytics. Useful for responding to new links and referrer spam. GA3 and GA4 versions. )

Reading and Writing Office 365 Excel from a Console app using the Microsoft.Graph C# Client API

By Robert Ellison. Updated on Sunday, September 18, 2022.

Read and Write Excel from Microsoft Graph

I needed a console app that reads some inputs from an online Excel workbook, does some processing and then writes back the results to a different worksheet. Because I enjoy pain I decided to use the thinly documented new Microsoft.Graph client library. The sample code below assumes that you have a work or education Office 365 subscription.

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Microsoft.Graph;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Newtonsoft.Json.Linq;
namespace Excel365Test
{
/// <summary>
/// 1) Install Microsoft.Graph NuGet Package
/// 2) Install Microsoft.IdentityModel.Clients.ActiveDirectory NuGet Package
/// 3) Register app at https://portal.azure.com/ - need app ID and redirct URL below
/// </summary>
class Program
{
static void Main(string[] args)
{
TokenCache tokenCache = new TokenCache();
// load tokens from file
string tokenPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Excel365Test");
if (!Directory.Exists(tokenPath)) { Directory.CreateDirectory(tokenPath); }
tokenPath = Path.Combine(tokenPath, "tokens.dat");
if (System.IO.File.Exists(tokenPath))
{
tokenCache.Deserialize(System.IO.File.ReadAllBytes(tokenPath));
}
// this is the OAUTH 2.0 TOKEN ENDPOINT from https://portal.azure.com/ -> Azure Active Directory -> App Registratuons -> End Points
var authenticationContext = new AuthenticationContext("https://login.windows.net/your-url-here/", tokenCache);
// only prompt when needed, you'll get a UI the first time you run
var platformParametes = new PlatformParameters(PromptBehavior.Auto);
var authenticationResult = authenticationContext.AcquireTokenAsync("https://graph.microsoft.com/",
"your-app-id", // Application ID from https://portal.azure.com/
new Uri("http://some.redirect.thing/"), // Made up redirect URL, also from https://portal.azure.com/
platformParametes).Result;
string token = authenticationResult.AccessToken;
// save token so we don't need to re-authorize
System.IO.File.WriteAllBytes(tokenPath, tokenCache.Serialize());
// use the token with Microsoft.Graph calls
GraphServiceClient client = new GraphServiceClient(new DelegateAuthenticationProvider(
(requestMessage) =>
{
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", token);
return Task.FromResult(0);
}));
// test reading from a sheet - in this case I have a test worksheet with a two column table for name/value pairs
var readSheet = client.Me.Drive.Items["your-workbook-id"].Workbook.Worksheets["test"];
var readTables = readSheet.Tables.Request().GetAsync().Result;
string readTableId = readTables[0].Name;
var table = readSheet.Tables[readTableId].Rows.Request().GetAsync().Result;
// convert page to a dictionary... this doesn't handle pagination
Dictionary<string, decimal> tableValues = table.CurrentPage.ToDictionary(r => r.Values.First.First.ToString(),
r => Convert.ToDecimal(r.Values.First.Last, CultureInfo.InvariantCulture));
// test adding a row to a table with four columns
// sadly it seems you need this exact format, a regular JArray or JObject fails
WorkbookTableRow newRow = new WorkbookTableRow
{
Values = JArray.Parse("[[\"1\",\"2\",\"3\",\"4\"]]")
};
var outputSheet = client.Me.Drive.Items["your-workbook-id"].Workbook.Worksheets["data"];
var outputTables = outputSheet.Tables.Request().GetAsync().Result;
string outputTableId = outputTables[0].Name;
var outputResult = outputSheet.Tables[outputTableId].Rows.Request().AddAsync(newRow).Result;
// the excel unit tests seem to be the most useful documentation right now:
// https://github.com/microsoftgraph/msgraph-sdk-dotnet/blob/dev/tests/Microsoft.Graph.Test/Requests/Functional/ExcelTests.cs
}
}
}
view raw Program.cs hosted with ❤ by GitHub

Paste the code into a new console project and then follow the instructions at the top to add the necessary NuGet packages. You'll also need to register an application at https://portal.azure.com/. You want a Native application and you'll need the Application ID and the redirect URL (just make up some non-routable URL for this). Under Required Permissions for the app you should add read and write files delegated permissions for the Microsoft Graph API.

Hope this saves you a few hours. Comment below if you need a more detailed explanation for any of the above.

Add your comment...

Related Posts

(All Code Posts)

(Published to the Fediverse as: Reading and Writing Office 365 Excel from a Console app using the Microsoft.Graph C# Client API #code #microsoft #excel #graph #office365 How to read and write data to an Office 365 Excel workbook using the Microsoft.Graph client library from a C# console application. )

Point Reyes Deer

By Robert Ellison. Updated on Saturday, January 18, 2025.

A deer at Point Reyes

A deer on a treacherous cliff-top path at Point Reyes.

The photograph titled "Point Reyes Deer" captures a breathtaking scene of nature's majesty and subtlety. The image is painted with the vast blues of the ocean, stretching seemingly infinitely under the clear sky, engendering a deep sense of calm and infinite possibility. To the left, the rugged cliffs stand resolutely, their earthy tones contrasting with the vibrant blue of the sea, marked by sheer edges and weathered surfaces that tell endless tales of time and tide. A lush carpet of green and purple foliage rolls over the hill in the foreground, lending life and texture to the landscape. Amidst this scene, almost hidden, a solitary deer stands on the cliff's edge, its gentle presence a reminder of the harmonious coexistence of life with its environment.

The composition of this photo employs both leading lines and the rule of thirds to draw the viewer's eye naturally across the frame. The cliffs rise diagonally, guiding attention towards the deer, which is subtly positioned to catch the light and subtly poised against the vast ocean. This compositional choice adds depth, inviting a contemplation of scale between the small, delicate deer and the expansive view. The balance of color and light is aesthetically pleasing, with the contrasting textures of rock, foliage, and sea. However, the deer is somewhat hidden, and a closer crop or different angle might have highlighted its presence more prominently. This subtle approach can be seen as both a strength in maintaining the scene's natural flow and a limitation for viewers seeking a more pronounced focal point. Overall, the photograph beautifully encapsulates a moment of serene wilderness.

Add your comment...

Related Posts

(Recent Photos)

(Published to the Fediverse as: Point Reyes Deer #photo #deer Photo of a deer on a cliff-top path at Point Reyes. )