Skip to content

Commit

Permalink
Added refractory period for running script
Browse files Browse the repository at this point in the history
  • Loading branch information
k1o0 committed Sep 3, 2020
1 parent 1aade8d commit e94e024
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 16 deletions.
1 change: 1 addition & 0 deletions +ww/Params.m
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ function save(obj)
... Preferences ...
'Mode', 2, ...
'nDaysInFuture', 2, ...
'minLastSent', 2, ...
'Email_format', 'html', ...
'Email_admins', {''}, ...
'Email_recipients', {''});
Expand Down
6 changes: 5 additions & 1 deletion +ww/formatTable.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
% format (char): Formats include 'png', 'tsv', 'html'. If no format is
% specified, a tab separated string is returned. If
% 'tsv' a file is also saved to disk.
%
% TODO Improve debugging mode

if nargin == 1; format = ''; end
dataInCells = table2cell(data);
Expand Down Expand Up @@ -56,7 +58,9 @@
end
out = [out, '</table>'];
%%% FOR DEBUGGING %%%
save printWeekendWaterVars.mat
if ww.Params().get('Mode') > 0
save(fullfile(userpath, 'printWeekendWaterVars.mat'))
end
%%%
otherwise
columnHeaders = cellfun(@strtrim,columnHeaders,'uni',0);
Expand Down
30 changes: 18 additions & 12 deletions +ww/generate.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@ function generate()
if isempty(fieldnames(excl)), excl = struct; end

% Path to email file which will be sent
mail = fullfile(iff(ispc, getenv('APPDATA'), getenv('HOME')), 'mail.txt');
% mod = file.modDate(mail);
% Check if email was generated in the past 2 days
% if ~isempty(mod) && (now - file.modDate(which('dat.paths')) < 2)
% return
% end
filename = sprintf('mail%s.txt', iff(test, '-test', ''));
mail = fullfile(iff(ispc, getenv('APPDATA'), getenv('HOME')), filename);

% Check when email was last generated and potentially return if too soon
mod = file.modDate(mail);
minLastSent = params.get('minLastSent'); % min number of days before next
if ~test && ~isempty(mod) && (now - mod < minLastSent)
fprintf('Email already sent in last %.2g days\n', minLastSent)
return
end

% Set email prefs for sending the email
% TODO These may no longer be required as we use curl
Expand All @@ -35,7 +39,7 @@ function generate()
end

% use 2 for usual weekends, 3 for long weekends etc.
[nDays, fail] = getNumDays();
[nDays, fail] = ww.getNumDays();
if fail && ~test
sendmail(admins, 'Action required: Days may be incorrect',...
['Weekend water script failed to determine whether there are any upcoming ',...
Expand All @@ -54,7 +58,7 @@ function generate()
users = ai.getData('users');

% Extract the data from alyx and give water to whomever needs it
[data, skipped] = getWeekendWater(ai, nDays, excl);
[data, skipped] = ww.getWeekendWater(ai, nDays, excl);
if height(data) == 0, return, end % Return if there are no restricted mice

if ~isempty(skipped) && ~test
Expand All @@ -68,12 +72,12 @@ function generate()
end

% print nicely, 'water.png' will be saved in the current folder
data = formatTable(data, params.get('Email_format'));
data = ww.formatTable(data, params.get('Email_format'));

% Get list of email recipients
recipients = strip(lower(params.get('Email_recipients')));
% In test mode only send to admin, otherwise send to all recipients and admins
to = iff(test, admins{1}, union(recipients, admins));
to = iff(test, admins(1), union(recipients, admins));

%% 'Weekend water',...
% Write email to file
Expand Down Expand Up @@ -105,9 +109,11 @@ function generate()
gitExe = getOr(dat.paths, 'gitExe');
bashPath = fullfile(gitExe(1:end-11), 'git-bash.exe');
bash = @(cmd)['"',bashPath,'" -c "',cmd,'"'];
system(bash(cmd), '-echo'); % Send email
failed = system(bash(cmd), '-echo'); % Send email

assert(~failed, 'failed to send email')

% Restore previous preferences
for prop = string(fieldnames(internetPrefs))'
setpref('Internet', prop, s.(prop))
setpref('Internet', prop, internetPrefs.(prop))
end
5 changes: 4 additions & 1 deletion +ww/getWeekendWater.m
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
function [data, skipped] = getWeekendWater(ai, nDaysInFuture, exclude)
% WW.GETWEEKENDWATER Builds a table of water amounts and posts to Alyx
% TODO Create log instead of dumping vars to file in debug mode
if nargin<2
nDaysInFuture = 2;
end
Expand Down Expand Up @@ -72,7 +73,9 @@
end
end
%%% FOR DEBUGGING %%%
save getWeekendWaterVars.mat
if ww.Params().get('Mode') > 0
save(fullfile(userpath, 'getWeekendWaterVars.mat'))
end
%%%
% collect the data for the table
data = table(animalName, prcWeightToday, giveWater);
12 changes: 11 additions & 1 deletion +ww/setup.m
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
% Performs some simple requirements checks then prompts the user to
% provide settings and preferences.

% Check for requirements % FIXME Move checks
% Check for requirements
assert(~verLessThan('matlab', '9.5'), 'Requires MATLAB 2018b or later')
assert(~isempty(which('dat.paths')), ...
'Requires <a href="matlab:web(''%s'',''-browser'')">Rigbox</a>', ...
Expand All @@ -18,6 +18,7 @@
'https://gitforwindows.org/')

params = ww.Params;

% ----STMP-SERVER-----
disp('Setting up email STMP server settings...')
disp('...Press return to keep unchanged...')
Expand All @@ -38,6 +39,7 @@
fprintf('Account password: \n');
reply = passwordUI();
if ~isempty(reply), params.set('SMTP_Password', reply); end

% --------ALYX--------
disp('Alyx user account to use...')
prompt = sprintf('Alyx username: (%s) ', params.get('ALYX_Login'));
Expand All @@ -46,6 +48,7 @@
fprintf('Alyx password: \n');
reply = passwordUI();
if ~isempty(reply), params.set('ALYX_Password', reply); end

% ------CALENDAR------
disp('Setting up calandar API settings (for determining bank holidays)...')
prompt = sprintf('API URL: (%s) ', params.get('CAL_API_URL'));
Expand All @@ -60,6 +63,7 @@
prompt = sprintf('Region: (%s) ', params.get('CAL_Region'));
reply = input(prompt,'s');
if ~isempty(reply), params.set('CAL_Region', reply); end

% -----PREFERENCES-----
disp('Setting up script preferences...')
prompt = sprintf('Mode (0 = normal, 1 = debug, test = 2): (%i) ',...
Expand All @@ -76,6 +80,12 @@
assert(reply > 0)
params.set('nDaysInFuture', int8(reply));
end
prompt = sprintf(...
'Minimum number of days before script can be re-run: (%.2g) ',...
params.get('minLastSent'));
reply = input(prompt);
if ~isempty(reply), params.set('minLastSent', reply); end

% -----EMAILS------
disp('Setting up email recipients...')
disp('Please enter a single email in quotes, or a cell array of emails')
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ This is designed to work with Rigbox and Alyx.
2. In MATLAB, add the WeekendWater repository to your paths (e.g. `addpath('WeekendWater')`)
3. Follow [these instructions](http://cortex-lab.github.io/Rigbox/paths_config.html) on how to set up your Rigbox paths file. You will need to ensure that the `gitExe` field points to your installed Git Bash executable, and the `mainRepository` is where your parameterProfiles.mat file will be saved (where subjects marked for weekend training are stored).
4. In MATLAB, run `ww.setup` and follow the steps to set the required parameters.
5. To run the script, say, every Friday, create a task on [Windows Scheduler](https://windowsreport.com/schedule-tasks-windows-10/). Add an action to start a program. The program should be MATLAB (i.e. `"C:\Program Files\MATLAB\R2018b\bin\matlab.exe"`) and the arguments should be `-r "ww.generate;exit"`.
5. To run the script, say, every Friday, create a task on [Windows Scheduler](https://windowsreport.com/schedule-tasks-windows-10/). Add an action to start a program. The program should be MATLAB (i.e. `"C:\Program Files\MATLAB\R2018b\bin\matlab.exe"`) and the arguments should be `-r "ww.generate;exit"`*.

*To ensure that MATLAB returns, even after errors, use `-r "exit(run_safe)"`

## Updating parameters
Parameters can be updated using the `ww.Params` class, or by simply re-running `ww.setup`. Below shows how to change the number of future weekend days to 3:
Expand Down
7 changes: 7 additions & 0 deletions run_safe.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
function status = run_safe
try
ww.generate;
status = 0;
catch
status = 1;
end

0 comments on commit e94e024

Please sign in to comment.