Get system installation date programmatically - macos

I am trying to get the system installation date by running a console app.
The only way I know how to do this is by parsing the /var/log/install.log file for the latest string containing OSInstaller & Install Complete items.
Is there a handy system API I am missing?

As a suggestion for exploration only:
You could try looking at the files /System/Library/Receipts.
You will probably see a com.apple.pkg.BaseSystemResources.plist file, its modification date may tell you when the OS was installed.
There are also com.apple.pkg.update.os.*.plist files for updates, again look at the modification dates and maybe parse the wildcard (*) bit if you can determined a naming convention.
HTH, Happy Hunting!

So in case, someone finds this useful.
Swift 3.0
SOLUTION 1
Initially I parsed /var/log/install.log file to get date string:
// To get OS installation date we'll need to check system log file and find entry which contains installation date
var systemDates : String? = nil
do {
let fullSystemLog = try NSString(contentsOf: URL(fileURLWithPath: "/var/log/install.log"), encoding: String.Encoding.utf8.rawValue)
let entries = fullSystemLog.components(separatedBy: "\n")
//Filter to get only entries about OS installation
let filtered = entries.filter{ entry in
return entry.contains("OSInstaller") && entry.contains("Install Complete") //Markers telling that OS was installed
}
var latestMention = ""
if filtered.count > 0 {
//If 1 or more entries found we'll pick last one
latestMention = filtered.last!
}
else if entries.count > 0 {
//If there are 0 mentions of OS installation - we'll use first entry in logs
latestMention = entries.first!
}
//parse picked entry for date
do {
let regex = try NSRegularExpression(pattern: ".+:[0-9]{2}", options: [])
let nsString = latestMention as NSString
let results = regex.matches(in: latestMention,
options: [], range: NSMakeRange(0, nsString.length))
let actualDateSubstrings = results.map { nsString.substring(with: $0.range)}
if let dateStringFromMention = actualDateSubstrings.first {
systemDates = dateStringFromMention
}
else {
systemDates = "<Error: no date results>"
}
} catch let error as NSError {
systemDates = "<Error: invalid regex: \(error.localizedDescription)>"
}
}
catch {
systemDates = "<Error: system log file not found>"
}
print("\tSYSTEM INSTALLED: \(systemDates)")
SOLUTION 2
The second solution appears much simpler. Look into the InstallDate field of /System/Library/Receipts/com.apple.pkg.BaseSystemResources.plist:
let systemDates = NSDictionary(contentsOfFile: "/System/Library/Receipts/com.apple.pkg.BaseSystemResources.plist")
print("\tSYSTEM INSTALLED: \(systemDates?["InstallDate"])")

Related

reading data from multiple tabs in excel

I have some data in multiple tabs in excel and those need to be read using cypress. Is there a way to do it? The only suggested way to read data from excel is to convert to JSON file. So, I referred and wrote this in ./cypress/support/command.js file with an intention that each tab will be stored as JSON file.
Cypress.Commands.add('dataFile', (excelFile) => {
let XLSX = require('xlsx');
let fs = require('fs');
let XLBook = XLSX.readFile('cypress/fixtures/' + excelFile);
let XLTabs = XLBook.SheetName;
for(let i = 0; i < XLTabs.length; i++)
{
let XLTabName = XLTabs[i].toString();
let XLData = XLSX.utils.sheet_to_json(XLBook.Sheets[XLTabs[i]);
fs.writeFile('./cypress/fixtures/jSONData.json', JSON.stringify(XLData , null, 2), (e: string) => {
if(e) {
console.log(e);
}
});
}
});
I used the below command in my test to use it.
cy.dataFile('File1.xlsx');
But, the test was highlighting this error:
Property 'dataFile' does not exist on type 'cy & EventEmitter'.ts(2339)
Please read Types for custom commands to resolve the error
Property 'dataFile' does not exist on type 'cy & EventEmitter'.ts(2339)
But you cannot use a custom command, because both let XLSX = require('xlsx') and let fs = require('fs') must be used in a task.
Please see this answer Read excel files in Cypress for the broad strokes.

InDesign Server Crashing on Data Merge

I'm trying to do a very basic data merge with InDesign Server and keep getting a crash.
I begin the server with ./InDesignServer -port 18383 starts with no problems.
I call the script with ./sampleclient ./scripts/test.jsx
The .jsx looks like this:
var source = File("/Users/me/Desktop/InDesign Server/example/example.indd")
var destination = File("/Users/me/Desktop/InDesign Server/example/example.pdf")
var sourceData = File("/Users/me/Desktop/InDesign Server/example/example.csv")
var doc = app.open(source);
doc.dataMergeProperties.selectDataSource(sourceData);
doc.dataMergeProperties.dataMergePreferences.recordNumber = 1;
doc.dataMergeProperties.mergeRecords(); // <-- Crashes here
var myPDFExportPreset = app.pdfExportPresets.item(0);
app.documents.item(0).exportFile(ExportFormat.pdfType, destination, false, myPDFExportPreset);
app.documents.item(0).close(SaveOptions.no);
doc.close(SaveOptions.no);
InDesign Server responds with:
Tue Sep 18 09:48:21 2018 INFO [javascript] Executing Script
./InDesignServer: line 13: 30363 Segmentation fault: 11 "$installed_name" "$#"
And crashes. This script runs perfectly fine in InDesign CC Desktop. Server appears to crash on the .mergeRecords() call. Any ideas why?
Edit: I've modified the code to 1) Have no spaces in the file path 2) check that my objects all exist before performing the merge.
var source = File("/Users/me/Desktop/example/example.indd");
var destination = File("/Users/me/Desktop/example/example.pdf");
var sourceData = File("/Users/me/Desktop/example/example.csv");
var doc = app.open(source);
doc.dataMergeProperties.selectDataSource(sourceData);
if (source.exists && destination.exists && sourceData.exists) {
try {
app.consoleout("Performing merge...");
doc.dataMergeProperties.mergeRecords(); // <-- Crashes here
} catch (err) {
app.consoleout(err);
}
} else {
app.consoleout("Something doesn't exist...");
}
It logs "Performing merge..." so my file paths do in fact point to files that exist. What's more, it full on crashes, and does not report any errors.
Edit 2:
It should be noted, this is the error the Terminal window which launched sampleclient gets from IDS: Error -1 fault: SOAP-ENV:Client [no subcode]
"End of file or no input: Operation interrupted or timed out"
Detail: [no detail]
The folks at Adobe took notice, and fixed this issue for the 2019 release of InDesign Server. The same script, with a similar merging document, no longer produces the error.
So, for a solution, update to 2019.
More information:
Adobe Forums Post
Found a solution, if others find themselves in my situation.
Still a mystery why mergeRecords() seems broken in Server.
doc.dataMergeProperties.exportFile()
Props to Colecandoo: https://forums.adobe.com/thread/2478708
My code is now:
var source = File("/Users/me/Desktop/example/example.indd");
var destination = File("/Users/me/Desktop/example/example.pdf");
var sourceData = File("Macintosh HD:Users:me:Desktop:example:example.csv");
var doc = app.open(source);
var myExport = File(doc.filePath + "/" + doc.name.split(".indd")[0] + ".pdf");
doc.dataMergeProperties.dataMergePreferences.recordNumber = 3;
with (doc.dataMergeProperties.dataMergePreferences) {
recordSelection = RecordSelection.ONE_RECORD;
}
app.dataMergeOptions.removeBlankLines = true;
doc.dataMergeProperties.exportFile(myExport, "[High Quality Print]", );
Still takes some tweaking, but it's performing the merge - this is what I needed.

Use swift and macOS to set file attributes

macOS, swift3
Apple has an API Foundation > FileManager > setAttributes(_:ofItemAtPath:)
The declaration is
func setAttributes(_ attributes: [FileAttributeKey : Any], ofItemAtPath path: String) throws
It is for setting the creation date etc for a file.
I can handle the >ofItem path:String) throws< but the first part has me stumped.
The API says it can return 'true' but swift returns void. There is an attribute named 'creationDate'. What is the significance of the underscore '_'.
I think 'attributes' is a mutable dictionary
var myAttributesDictionary = [FileAttributeKey : Date]()
myAttributesDictionary[FileAttributeKey.creationDate] = myDateObject
let fm = FileManger()
let xxx = fm.setAttributes(myAttributesDictionary:[FileAttributeKey : creationDate], ofItemAtPath myPath)
I have tried many variations and now I am stumped and I do not know what is required. I cannot get the setAttributes line to compile
I spent some time looking for an answer before posting the question.
When I went looking for my questionI found an answer.
let mypath = "/path/to/file"
let myDateObject = NSDate() // NSDate() is todays date
let attributes = [FileAttributeKey.creationDate: myDateObject]
do {
try FileManager.default.setAttributes(attributes, ofItemAtPath: myPath)
}
catch
{
print(error)
}

Is it possible to sync just ONE file with lsyncd?

I really am stumped - I've spent almost two hours searching for an answer to a ridiculously simple question: how can I continually keep two local files in sync on my mac? I investigated various tricks involving rsync, then settled on using lsyncd.
But for the life of me, I can't figure out how I can get lsyncd to sync two specific files. Is this even supported in the API? It was not clear in the documentation whether or not I could use rsync in this manner; I assume that lsyncd is passing CLI options which are preventing this. My configuration is as follows:
sync = {
default.rsync,
source = "/Users/username/Downloads/test1.txt",
target = "/Users/username/Downloads/test2.txt",
rsync = {
binary = "/usr/local/bin/rsync",
archive = "true"
}
}
It just says 'nothing to sync'. Help?
This had worked for me:
sync {
default.rsync,
source = "/Users/username/Downloads/",
target = "/Users/username/Downloads/",
rsync = {
binary = "/usr/bin/rsync",
archive = "true",
_extra = {
"--include=test1.txt",
"--exclude=*"
}
}
}
You have to use the include/exclude feature of lsyncd, which did not come out of the box. You have to use _extra field to set them.
In lsynd you can do like this
settings {
logfile = "/var/log/lsyncd.log",
statusFile = "/var/log/lsyncd-status.log",
statusInterval = 20,
nodaemon = true
}
sync {
default.rsync,
source="/srcdir/",
target="/dstdir/",
rsync = {
archive = true,
compress = true,
whole_file = false,
_extra = { "--include=asterisk", "--exclude=*" },
verbose = true
},
delay=5,
log=all,
}
After start lsyncd i have next
root#localhost:/srcdir# ls
12 aster asterisk
root#localhost:/dstdir# ls
asterisk

Save all files in Visual Studio project as UTF-8

I wonder if it's possible to save all files in a Visual Studio 2008 project into a specific character encoding. I got a solution with mixed encodings and I want to make them all the same (UTF-8 with signature).
I know how to save single files, but how about all files in a project?
Since you're already in Visual Studio, why not just simply write the code?
foreach (var f in new DirectoryInfo(#"...").GetFiles("*.cs", SearchOption.AllDirectories)) {
string s = File.ReadAllText(f.FullName);
File.WriteAllText (f.FullName, s, Encoding.UTF8);
}
Only three lines of code! I'm sure you can write this in less than a minute :-)
This may be of some help.
link removed due to original reference being defaced by spam site.
Short version: edit one file, select File -> Advanced Save Options. Instead of changing UTF-8 to Ascii, change it to UTF-8. Edit: Make sure you select the option that says no byte-order-marker (BOM)
Set code page & hit ok. It seems to persist just past the current file.
In case you need to do this in PowerShell, here is my little move:
Function Write-Utf8([string] $path, [string] $filter='*.*')
{
[IO.SearchOption] $option = [IO.SearchOption]::AllDirectories;
[String[]] $files = [IO.Directory]::GetFiles((Get-Item $path).FullName, $filter, $option);
foreach($file in $files)
{
"Writing $file...";
[String]$s = [IO.File]::ReadAllText($file);
[IO.File]::WriteAllText($file, $s, [Text.Encoding]::UTF8);
}
}
I would convert the files programmatically (outside VS), e.g. using a Python script:
import glob, codecs
for f in glob.glob("*.py"):
data = open("f", "rb").read()
if data.startswith(codecs.BOM_UTF8):
# Already UTF-8
continue
# else assume ANSI code page
data = data.decode("mbcs")
data = codecs.BOM_UTF8 + data.encode("utf-8")
open("f", "wb").write(data)
This assumes all files not in "UTF-8 with signature" are in the ANSI code page - this is the same what VS 2008 apparently also assumes. If you know that some files have yet different encodings, you would have to specify what these encodings are.
Using C#:
1) Create a new ConsoleApplication, then install Mozilla Universal Charset Detector
2) Run code:
static void Main(string[] args)
{
const string targetEncoding = "utf-8";
foreach (var f in new DirectoryInfo(#"<your project's path>").GetFiles("*.cs", SearchOption.AllDirectories))
{
var fileEnc = GetEncoding(f.FullName);
if (fileEnc != null && !string.Equals(fileEnc, targetEncoding, StringComparison.OrdinalIgnoreCase))
{
var str = File.ReadAllText(f.FullName, Encoding.GetEncoding(fileEnc));
File.WriteAllText(f.FullName, str, Encoding.GetEncoding(targetEncoding));
}
}
Console.WriteLine("Done.");
Console.ReadKey();
}
private static string GetEncoding(string filename)
{
using (var fs = File.OpenRead(filename))
{
var cdet = new Ude.CharsetDetector();
cdet.Feed(fs);
cdet.DataEnd();
if (cdet.Charset != null)
Console.WriteLine("Charset: {0}, confidence: {1} : " + filename, cdet.Charset, cdet.Confidence);
else
Console.WriteLine("Detection failed: " + filename);
return cdet.Charset;
}
}
I have created a function to change encoding files written in asp.net.
I searched a lot. And I also used some ideas and codes from this page. Thank you.
And here is the function.
Function ChangeFileEncoding(pPathFolder As String, pExtension As String, pDirOption As IO.SearchOption) As Integer
Dim Counter As Integer
Dim s As String
Dim reader As IO.StreamReader
Dim gEnc As Text.Encoding
Dim direc As IO.DirectoryInfo = New IO.DirectoryInfo(pPathFolder)
For Each fi As IO.FileInfo In direc.GetFiles(pExtension, pDirOption)
s = ""
reader = New IO.StreamReader(fi.FullName, Text.Encoding.Default, True)
s = reader.ReadToEnd
gEnc = reader.CurrentEncoding
reader.Close()
If (gEnc.EncodingName <> Text.Encoding.UTF8.EncodingName) Then
s = IO.File.ReadAllText(fi.FullName, gEnc)
IO.File.WriteAllText(fi.FullName, s, System.Text.Encoding.UTF8)
Counter += 1
Response.Write("<br>Saved #" & Counter & ": " & fi.FullName & " - <i>Encoding was: " & gEnc.EncodingName & "</i>")
End If
Next
Return Counter
End Function
It can placed in .aspx file and then called like:
ChangeFileEncoding("C:\temp\test", "*.ascx", IO.SearchOption.TopDirectoryOnly)
if you are using TFS with VS :
http://msdn.microsoft.com/en-us/library/1yft8zkw(v=vs.100).aspx
Example :
tf checkout -r -type:utf-8 src/*.aspx
Thanks for your solutions, this code has worked for me :
Dim s As String = ""
Dim direc As DirectoryInfo = New DirectoryInfo("Your Directory path")
For Each fi As FileInfo In direc.GetFiles("*.vb", SearchOption.AllDirectories)
s = File.ReadAllText(fi.FullName, System.Text.Encoding.Default)
File.WriteAllText(fi.FullName, s, System.Text.Encoding.Unicode)
Next
If you want to avoid this type of error :
Use this following code :
foreach (var f in new DirectoryInfo(#"....").GetFiles("*.cs", SearchOption.AllDirectories))
{
string s = File.ReadAllText(f.FullName, Encoding.GetEncoding(1252));
File.WriteAllText(f.FullName, s, Encoding.UTF8);
}
Encoding number 1252 is the default Windows encoding used by Visual Studio to save your files.
Convert from UTF-8-BOM to UTF-8
Building on rasx's answer, here is a PowerShell function that assumes your current files are already encoded in UTF-8 (but maybe with BOM) and converts them to UTF-8 without BOM, therefore preserving existing Unicode characters.
Function Write-Utf8([string] $path, [string] $filter='*')
{
[IO.SearchOption] $option = [IO.SearchOption]::AllDirectories;
[String[]] $files = [IO.Directory]::GetFiles((Get-Item $path).FullName, $filter, $option);
foreach($file in $files)
{
"Writing $file...";
[String]$s = [IO.File]::ReadAllText($file, [Text.Encoding]::UTF8);
[Text.Encoding]$e = New-Object -TypeName Text.UTF8Encoding -ArgumentList ($false);
[IO.File]::WriteAllText($file, $s, $e);
}
}
Experienced encoding problems after converting solution from VS2008 to VS2015. After conversion all project files was encoded in ANSI, but they contained UTF8 content and was recongnized as ANSI files in VS2015. Tried many conversion tactics, but worked only this solution.
Encoding encoding = Encoding.Default;
String original = String.Empty;
foreach (var f in new DirectoryInfo(path).GetFiles("*.cs", SearchOption.AllDirectories))
{
using (StreamReader sr = new StreamReader(f.FullName, Encoding.Default))
{
original = sr.ReadToEnd();
encoding = sr.CurrentEncoding;
sr.Close();
}
if (encoding == Encoding.UTF8)
continue;
byte[] encBytes = encoding.GetBytes(original);
byte[] utf8Bytes = Encoding.Convert(encoding, Encoding.UTF8, encBytes);
var utf8Text = Encoding.UTF8.GetString(utf8Bytes);
File.WriteAllText(f.FullName, utf8Text, Encoding.UTF8);
}
the item is removed from the menu in Visual Studio 2017
You can still access the functionality through File-> Save As -> then clicking the down arrow on the Save button and clicking "Save With Encoding...".
You can also add it back to the File menu through Tools->Customize->Commands if you want to.
I'm only offering this suggestion in case there's no way to automatically do this in Visual Studio (I'm not even sure this would work):
Create a class in your project named 足の不自由なハッキング (or some other unicode text that will force Visual Studio to encode as UTF-8).
Add "using MyProject.足の不自由なハッキング;" to the top of each file. You should be able to do it on everything by doing a global replace of "using System.Text;" with "using System.Text;using MyProject.足の不自由なハッキング;".
Save everything. You may get a long string of "Do you want to save X.cs using UTF-8?" messages or something.

Resources