Skip to content

Instantly share code, notes, and snippets.

@lars-erik
Last active May 3, 2022 06:41
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save lars-erik/f1d1e0226f5a552dc278 to your computer and use it in GitHub Desktop.
Save lars-erik/f1d1e0226f5a552dc278 to your computer and use it in GitHub Desktop.
Rebuild Umbraco indexes if gone bad. NB! Update SMTP settings. Params are URL, user name, password and threshold (count of items in index to be below for reindex to start)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Mail;
using System.ServiceModel.Channels;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
namespace LuceneWatchdog
{
class Program
{
private static HttpClient client;
private static Dictionary<string, int> indexers;
private static string baseUrl;
private static StringBuilder outputBuilder;
private static bool rebuiltAny;
private static string username;
private static string password;
private static int threshold;
private static bool view;
static void Main(string[] args)
{
if (!ParseArguments(args))
return;
using (var handler = new HttpClientHandler())
{
handler.UseCookies = true;
//handler.UseProxy = true;
client = new HttpClient(handler);
var loginTask = client.PostAsync(
string.Format("http://{0}/umbraco/backoffice/umbracoapi/authentication/postlogin", baseUrl),
new StringContent(
JsonConvert.SerializeObject(new {username = username, password = password}),
Encoding.UTF8,
"application/json"
)
);
loginTask.Wait();
if (!loginTask.Result.IsSuccessStatusCode)
{
Console.WriteLine("Invalid username or password");
return;
}
var token = handler.CookieContainer.GetCookies(new Uri("http://" + baseUrl))["XSRF-TOKEN"].Value;
client.DefaultRequestHeaders.Add("X-XSRF-TOKEN", token);
var statusTask = client
.GetStringAsync(string.Format("http://{0}/umbraco/BackOffice/Api/ExamineManagementApi/GetIndexerDetails", baseUrl));
statusTask.Wait();
var json = statusTask.Result;
var settings = new JsonSerializerSettings {ContractResolver = new CamelCasePropertyNamesContractResolver()};
indexers = JsonConvert.DeserializeObject<Indexer[]>(json, settings).ToDictionary(ix => ix.Name, ix => ix.DocumentCount);
outputBuilder = new StringBuilder();
foreach (var indexer in indexers)
outputBuilder.AppendFormat("{0}: {1}\r\n", indexer.Key, indexer.Value);
rebuiltAny = false;
if (!view)
{
foreach (var indexer in indexers.Where(ix => ix.Key != "InternalMemberIndexer"))
{
RebuildIfEmpty(indexer.Key);
}
}
if (rebuiltAny)
{
using (var smtp = new SmtpClient("your-smtp-server-here"))
{
smtp.Send(
"noreply@your-domain-here.no",
"your-email-here",
"INDEXES REBUILT ON " + baseUrl,
outputBuilder.ToString());
}
}
Console.WriteLine(outputBuilder.ToString());
}
}
private static bool ParseArguments(string[] args)
{
try
{
baseUrl = args[0];
username = args[1];
password = args[2];
threshold = Convert.ToInt32(args[3]);
view = args.Length > 4 && args[4] == "view";
return true;
}
catch
{
Console.WriteLine("Usage: UmbWatch <baseurl> <username> <password> <threshold> [view]");
return false;
}
}
private static void RebuildIfEmpty(string indexerName)
{
if (indexers[indexerName] <= threshold)
{
rebuiltAny = true;
outputBuilder.AppendFormat("Indexer {0} is empty. Rebuilding...\r\n", indexerName);
var rebuildTask = client.PostAsync(
string.Format(
"http://{0}/umbraco/BackOffice/Api/ExamineManagementApi/PostRebuildIndex?indexerName=" +
indexerName,
baseUrl), new StringContent(""));
rebuildTask.Wait();
}
else
{
outputBuilder.AppendFormat("Indexer {0} has content. No worries! :)\r\n", indexerName);
}
}
public class Indexer
{
public string Name { get; set; }
public int DocumentCount { get; set; }
}
}
}
@ismailmayat
Copy link

This is awesome i am having this lol

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment