Match an approaching date In Lua - string

I'm looking for a little help on a Lua script. Essentially I'm looking to match an approaching date X number of minutes prior to today. In the example below I've used 9000 minutes.
alarm.get ()
message = "Certificate Expiry Warning - Do something"
SUPPKEY = "Certificate Expiry"
SUBSYS = "1.1"
SOURCE = "SERVERNAME"
--local pattern = "(%d-%m-%Y)"
local t = os.date('*t'); -- get current date and time
print(os.date("%d-%m-%Y")); --Prints todays date
t.min = t.min - 9000; -- subtract 9000 minutes
--print(os.date("%Y-%m-%d %H:%m:%S", os.time(t))); --Original Script
print(os.date("%d-%m-%Y", os.time(t))); --Prints alerting date
if string.match ~=t.min --Match string
--if string.match(a.message, pattern)
--then print (al.message)
then print ("We have a match")
--then nimbus.alarm (1, message , SUPPKEY , SUBSYS , SOURCE) --Sends alert
else print ("Everything is fine") --Postive, no alert
--else print (al.message)
end
The alarm.get grabs a line of text that looks like this:
DOMAIN\USERNAME,Web Server (WebServer),13/01/2017 09:13,13/01/2019,COMPANY_NAME,HOSTNAME_FQDN,SITE
So the line shown above is passed as an a.message variable and I'm looking to match the date highlighted in bold to today's date with 9000 minutes taken off it.
The commented out parts are just me testing different things.

I'm not sure if I understood the question well, but from my perspective it seems you are trying to do two things:
Retrieve current time minus 9000 minutes in format DD/MM/YYYY.
Compare this time to the one your program reads from file and do something, when the two dates are equal.
Here goes my sample code:
-- Settings
local ALLOWED_AGE = 9000 -- In minutes
-- Input line (for testing only)
local inputstr = "DOMAIN\\USERNAME,Web Server (WebServer),13/01/2017 09:13,13/01/2019,COMPANY_NAME,HOSTNAME_FQDN,SITE"
-- Separate line into 7 variables by token ","
local path, server, time, date, company_name, hostname, site = string.match(inputstr, "([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+)")
-- Check, if the line is ok (not necessary, but should be here to handle possible errors)
-- Also note, some additional checks should be here (eg. regex to match DD/MM/YYYY format)
if date == nil then
print("Error reading line: "..inputstr)
end
-- Get current time minus 9000 minutes (in format DD/MM/YYYY)
local target_date = os.date("%d/%m/%Y", os.time() - ALLOWED_AGE * 60)
-- Printing what we got (for testing purposes)
print("Target date: "..target_date..", Input date: "..date)
-- Testing the match
if target_date == date then
print("Dates are matched!")
else
print("Dates are not matched!")
end
Although I'm not sure, whether you shouldn't be instead checking for "one date is bigger/smaller then the other" in your case.
Then the code above should be modified to something like this:
-- Extract day, month and year from date in format DD/MM/YYYY
local d, m, y = string.match(date, "([^/]+)/([^/]+)/([^/]+)")
-- Note I'm adding one day, so the certificate will actually expire day after it's "valid until" date.
local valid_until = os.time({year = y, month = m, day = d + 1})
local expire_time = os.time() - ALLOWED_AGE * 60 -- All certificates older than this should expire.
-- Printing what we got (for testing purposes)
print("Expire time: "..expire_time..", Cert valid until: "..valid_until)
-- Is expired?
if valid_until <= expire_time then
print("Oops! Certificate expired.")
else
print("Certificate date is valid.")
end

Related

Why does the code only return the last date to OBS "text"?

I am trying to change the code in a phyton script for OBS studio to show the dates of coming events from a google calendar. But the output to OBS Studio only shows the same (last) date on every event. The script log shows it as it should be thou...
After struggling to find a way to convert the dictionary items to print in a way that I wanted to show it, I finally thought I had made it work the way I wanted.
I am new to python and have basically just searched for answers to how to solve what I needed to change in the code.
It took me days to find out about datetime.datetime and how strftime could work together, and that I needed to upgrade Dateutil to a more recent version to not get some of the errors I got.
Anyway, since I am new to coding and most of this script has been written by someone else it is somewhat hard for me to see where this problem lies.
it works as it should in the script log but the date in "stime" becomes the same for every event when I send it to "text" in OBS Studio.
If anyone could help me with a solution to this, I would be very happy.
# Time objects using datetime
dt_now = dt.utcnow()
now = dt.utcnow().isoformat() + 'Z' # 'Z' indicates UTC time
#Timeformat
locale.setlocale(locale.LC_TIME, "sv_SE") # swedish
tmfmt = '%d %B, %H:%M '
# Gets events currently happending by setting bounds to events happening within a second of current datetime
events = service.events().list(calendarId=cal_url, timeMin=now, timeMax=(dt_now+datetime.timedelta(7,1)).isoformat() +'Z',
maxResults=max_events, singleEvents=True, orderBy='startTime').execute()
# Logs the events to console
for event in events['items']:
mystart = (event['start']['dateTime'])
stime = dt.strftime(dtparse(mystart), format=tmfmt)
print(stime)
#print(datetime.datetime.utcnow().date())
#print (event['start']['dateTime'])
print(event['summary'])
#print(dt_now("%d %b, %Y"))
# Updates the text for each event
count = 0
stream_event_happening = False
record_event_happening = False
for event in events['items']:
if(count >= max_events):
break
text = stime + "\n" + event['summary']
settings = obs.obs_data_create()
obs.obs_data_set_string(settings, "text", text)
source = obs.obs_get_source_by_name(source_names[count])
obs.obs_source_update(source, settings)
obs.obs_data_release(settings)
obs.obs_source_release(source)
settings2 = obs.obs_data_create()
obs.obs_data_set_string(settings2, "file", "{}/{}.jpg".format(images_path, text))
source2 = obs.obs_get_source_by_name(image_sources[count])
obs.obs_source_update(source2, settings2)
obs.obs_data_release(settings2)
obs.obs_source_release(source2)
count += 1
text = stime + "\n" + event['summary']
shows only the same date but different events...
Wow, just a few minutes later I found a solution on my own... I added:
mystart = (event['start']['dateTime'])
stime = dt.strftime(dtparse(mystart), format=tmfmt)
just before:
text = stime + "\n" + event['summary']
and now it works as it should :)

search string format in current or next line until match

ics file generated by evolution:
BEGIN:VCALENDAR
CALSCALE:GREGORIAN
PRODID:-//Ximian//NONSGML Evolution Calendar//EN
VERSION:2.0
X-EVOLUTION-DATA-REVISION:2017-10-28T04:50:31.240215Z(0)
BEGIN:VTIMEZONE
TZID:/freeassociation.sourceforge.net/Asia/Kolkata
X-LIC-LOCATION:Asia/Kolkata
BEGIN:STANDARD
TZNAME:IST
DTSTART:19701014T230000
TZOFFSETFROM:+0530
TZOFFSETTO:+0530
END:STANDARD
END:VTIMEZONE
BEGIN:VTODO
UID:f13168013f7c8b9abc36c31e43028c34a3f40823
DTSTAMP:20171019T025556Z
SUMMARY:Trial
DTSTART;TZID=/freeassociation.sourceforge.net/Asia/Kolkata:
20171019T000000
DUE;TZID=/freeassociation.sourceforge.net/Asia/Kolkata:20171030T000000
PERCENT-COMPLETE:0
CLASS:PUBLIC
DESCRIPTION:Hello
SEQUENCE:2
CREATED:20171019T031330Z
LAST-MODIFIED:20171028T045031Z
CATEGORIES:Work
END:VTODO
END:VCALENDAR
The problem is in the line 20-23 where:
DTSTART;TZID=/freeassociation.sourceforge.net/Asia/Kolkata:
20171019T000000
DUE;TZID=/freeassociation.sourceforge.net/Asia/Kolkata:20171030T000000
So, the DTSTART's time is in the next line while the DUE's timestamp is in the same line. Hence, a simple python function like:
if line.startswith("DTSTART;TZID"):
line = next(finp)
dt = line.strip()[0:8]
wont work for both. This one won't works for DUE, and I have to make another function without next for that purpose.
How can I handle any such date/time etc irrespective of the linebreak?
Maybe using regex would be useful in your case,
try this:
import re
if line.startswith("DTSTART;TZID"):
line = next(finp)
dt = re.search('(.*)T.*', line).groups(1)
if line.startswith("DTSTART;TZID"):
dt = re.search('.*\:(.*)T.*', line).groups(1)
The first group that's wrapped in () is in both cases the datestamp.
To decipher the regex; .* matches anything until the explictly named character occurs, which is in the first scenario 'T' because of the newline and the "plain" string given to us. In the second the stamp is between ':' and 'T' which enclose the date.
Using String-Slicing could become difficult when you are not sure if the city is always Kolkata etc.

comparing strings - Lua

I have a file (termino.txt) that is all filled in the following format :
pay the bill
2015-08-30T13:22:53.108Z
Go to the doctor
2015-09-30T13:22:53.108Z
....
All the even lines are of the form RFC 3339 timestamp. What I need is to compare today's date with these dates the file to see if they are the same. I'm trying this:
local function verifica(evt)
local nome= ''
local dia = ''
local turn = 1
local data = os.date("%x")
local file = io.open("termino.txt", "r")
while true do
nome = dia
line = file:read()
dia = line
if (turn %2 == 0) then
> Here I need to compare "data" with "dia" that will receive string with RFC 3339 timestamp format.
end
turn ++
end
end
I need help to make this comparison! Thanks
local dia = '2015-10-6T13:22:53.108Z'
-- parse date info from the RFC 3339 timestamp
local year, month, day = dia:match('(%d+)-(%d+)-(%d+)')
-- get today's date from Lua, in table format
local today = os.date('*t')
-- compare
if tonumber(year) == today.year
and tonumber(month) == today.month
and tonumber(day) == today.day then
-- the dates match
end

Insert rows into Excel with MATLAB

The data in my Excel files is supposed to be contentious (index in the first column). But some data is missing in the file. For example, # 5, and 6 are missing between $ 4 and 7. My purpose are (1) identify the file with missing data and (2) if data is missing insert rows to make it continuous. Can anyone tell me how to add in rows in the existing data? Using xlswrite I can only add in rows at the end of the file or replace some rows.
EDIT 1:
I have another set of file in which the index is not so direct. The first 3 columns are described below (as shown in the Excel file):
Column 1:Year: 2003 (read as number in matlab)
Column 2:Date: 1-Sep (read as text in matlab)
Column 3:Time: 1:00 (1:00 read as number 0.04167 and 2:00 read as 0.0833, not sure how it works)
Then the way to tell if it is continuous will be quite complicate since there will be different years, months, and days. Could you give some hint on this?
Basically you need to read the entire data, preferably in raw(cell) format, add the missing rows(with respect to the indices) and write back.
Based on your question, this code might work -
% NOTE: We are assuming that the indexing starts with 1
% Read data from input excel file with missing indices
[num,txt,raw] = xlsread('input.xls');
% Error-checking
if (size(num,1)-num(end,1)~=0)
disp('At least one index is missing!');
end
% Expand data such that all indices are covered.
data1=NaN(num(end,1),size(raw,2));
data1(:,1) = 1:num(end,1);
data1=num2cell(data1);
k1=1;
for k = 1:num(end,1)
if(num(k1,1)==k)
data1(k,:)= raw(k1,:);
k1 = k1+1;
end
end
% Write data
xlswrite('output.xls',data1);
EDIT 1:
In view of your new requirements, additional code is added next.
Please note few things about this code -
The code adds data for every year and not from a specific month, date and time to another specific month, date and time. If you wish to achieve that, please edit the associated
function - 'create_comp_sheet'.
It saves an intermediate file named - 'proper_base_data.xls', which maybe deleted at the end of the code.
%% MAIN CODE - CODE1.M
INPUT_FILENAME = 'input.xls'; % Excel file that has some missing year,date and time info
OUTPUT_FILENAME = 'output.xls'; % Excel file that has data from the input file along with all the missing year,date and time info
%% Base data
start_year=2003;
end_year=2005;
proper_base_data = create_comp_sheet(start_year,end_year);
xlswrite('proper_base_data.xls',proper_base_data);
[num,txt,raw] = xlsread('proper_base_data.xls');
base_data=cell(size(num,1),1);
for row_ID = 1:size(num,1)
base_data(row_ID) = {strcat(num2str(cell2mat(raw(row_ID,1))),'-', cell2mat(raw(row_ID,2)),'-',num2str(round(24*cell2mat(raw(row_ID,3)))))};
end
%% Input data
[num,txt,raw] = xlsread(INPUT_FILENAME);
input_data=cell(size(num,1),1);
for row_ID = 1:size(num,1)
input_data(row_ID) = {strcat(num2str(cell2mat(raw(row_ID,1))),'-', cell2mat(raw(row_ID,2)),'-',num2str(round(24*cell2mat(raw(row_ID,3)))))};
end
%% Setup final data
final_data = num2cell(NaN(size(proper_base_data,1),size(raw,2)));
final_data(:,1:3) = proper_base_data;
for k1=1:size(input_data,1)
for k2=1:size(base_data,1)
if strcmp(cell2mat(base_data(k2)),cell2mat(input_data(k1)))
final_data(k2,4:end) = raw(k1,4:end);
end
end
end
%% Write final data to excel
xlswrite(OUTPUT_FILENAME,final_data);
Associated function -
function data1 = create_comp_sheet(start_year,end_year)
months_string = {'Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'};
date_count = [31 28 31 30 31 30 31 31 30 31 30 31];
num_hours = 24;
data1=[];
for year_ID = start_year:end_year
for month_ID = 1:numel(months_string)
days_per_month = date_count(month_ID);
if rem(year_ID,4)==0 && month_ID ==2
days_per_month = days_per_month+1;
end
for date_ID = 1:days_per_month
year = repmat({num2str(year_ID)},[num_hours 1]);
date = repmat({strcat(num2str(date_ID),'-',char(months_string(month_ID)))},[num_hours 1]);
time=cell(num_hours,1);
for k = 1:num_hours
time(k) = {strcat(num2str(k),':00')};
end
data1 = [data1 ; [year date time]];
end
end
end
return;
Hope this saves all your troubles!

How to get Log4perl rotating my logs daily?

I'm reading up on Log4perl and want to try and use it for simple log management of my Perl scripts running on a Linux box. I've also read up on newsyslog and logrotate but want to use Log4perl if at all possible.
I'm trying to configure the /etc/log4perl.conf file so that it:
Defines a widget logger (INFO level) that will write all output to /opt/myapp/logs/myapp-<datetime>.log, where <datetime> is a date/time formatted string like 2012-12-20
This myapp-<datetime>.log file needs to be rotated daily (preferably at midnight), where the old file is deleted, and a new file is created with <datetime> + 1. For instance, myapp-2012-12-20.log would be replaced with myapp-2012-12-21.log, etc.
Here's my best attempt which I believe is close, but is still missing some configuration:
#####/etc/log4perl.conf############################################################
log4perl.logger.widget = INFO, MyAppLogAppender
log4perl.appender.MyAppLogAppender = Log::Log4perl::Appender::File
log4perl.appender.MyAppLogAppender.filename = /opt/myapp/logs/myapp-???.log
log4perl.appender.MyAppLogAppender.layout = Log::Log4perl::Layout::SimpleLayout
###################################################################################
How do I configure log4perl.appender.MyAppLogAppender to rotate once a day, delete the old file, and create a new one with a correct timestamp? Thanks in advance.
Here's an example of a Log::Log4perl configuration file, defining a daily rollover at midnight (date pattern yyyy-MM-dd), keeping a maximum of 5 saved logfiles around, at WARN level, and dumping everything to screen:
log4perl.logger = TRACE, Screen, Logfile
log4perl.appender.Logfile = Log::Dispatch::FileRotate
log4perl.appender.Logfile.Threshold = WARN
log4perl.appender.Logfile.filename    = test.log
log4perl.appender.Logfile.max         = 5
log4perl.appender.Logfile.DatePattern = yyyy-MM-dd
log4perl.appender.Logfile.TZ          = PST
log4perl.appender.Logfile.layout = Log::Log4perl::Layout::PatternLayout
log4perl.appender.Logfile.layout.ConversionPattern = %d %m %n
log4perl.appender.Screen = Log::Log4perl::Appender::Screen
log4perl.appender.Screen.stderr = 0
log4perl.appender.Screen.utf8 = 1
log4perl.appender.Screen.layout = Log::Log4perl::Layout::PatternLayout::Multiline
log4perl.appender.Screen.layout.ConversionPattern = [%p] %m %n
(reference: https://metacpan.org/module/Log::Log4perl::FAQ#How-can-I-roll-over-my-logfiles-automatically-at-midnight-)
There is a gotcha in Log::Dispatch::FileRotate, if your daily job is run later in the day (say 23:00) and takes 2h (so ends at about 01:00), the log rotation will never happens with a "day" pattern like :
log4perl.appender.Logfile.DatePattern = yyyy-MM-dd
A simple workaround is to use an "hourly" pattern like this :
log4perl.appender.Logfile.DatePattern = yyyy-MM-dd-HH
So when the next run starts at 23:00, the log file get rotated as more than one hour has passed.

Resources