image thumbnail
from Mat Nanny v1.0 - RSS and html progress reports by Nick Clark
Check computation progress from anywhere with internet

MatNanny(webStruct,dataStruct)
%% MatNanny v1.0 - 4th Sept 2008
function MatNanny(webStruct,dataStruct)

% MatNanny is a simple function which publishes a data structure as
% html and an RSS feed when called. This allows for convenient remote
% checking on the progress of models or other computations which have been
% left running while away from the office. I recommend using free webspace
% on xthost.info as there is no sign up required and the no-fuss ftp update
% process works very fast. The username and password in the demo provided
% are real and are free for your use while evaluating this software. This
% may not work correctly if more than one person is trying this out
% simultaneously as xthost doesn't like simultaneous ftp connections from
% the same username, but it only takes 2 seconds to make your own account.
% 
% The function takes 2 input structures. The webStruct structure must
% contain all of the fields provided in the demo below. This structure is
% used to hold data about the hosting service which you are using. The
% second structure, dataStruct, can contain anything which you want to
% appear online for your own checking.
% 
% Example:
% webStruct.process = 'Dinosaur_Marmot_Reconstruction_Model';
% webStruct.description = 'Foo procees for demo only';
% webStruct.timeZone = 'GMT';
% webStruct.webAddy = 'http://one.xthost.info/matlabprocess/';
% webStruct.hostAddy = 'one.xthost.info';
% webStruct.uName = 'matlabprocess';
% webStruct.pwd = 'rRHbTX';
%  
% dataStruct.percentComplete = 54;
% dataStruct.bigData = 1:100;
% dataStruct.genetic = 12.45346;
% dataStruct.probabilityOfMarmot = rand;
% dataStruct.ghosting = 'OK';
% dataStruct.thing = 'RaRaRa';
%  
% MatNanny(webStruct,dataStruct);
% 
% The script above will recreate the webpage shown in the screenshot
% Enjoy!

t = clock;
%% Make local directory for html and rss feed
if isfield(webStruct,'process')
    procName = webStruct.process;
else
    procName = 'WARNING_no_field_named_process';
end

if isempty(dir(fullfile('www',procName)))
    mkdir(fullfile('www',procName))
end

%% Make RSS 2.0 feed
stampRFC822 = [datestr(weekday(now),'ddd') ',' datestr(now,' dd mmm yyyy HH:MM:SS ') webStruct.timeZone]; %date stamp in RFC 822 format
rssFID  = fopen(fullfile('www',procName,[procName '.xml']),  'w');

% RSS channel
fprintf(rssFID,'<?xml version="1.0" encoding="utf-8"?>\n');

% Feed information
fprintf(rssFID,'<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">\n');
fprintf(rssFID,'<channel>\n<title>%s</title>\n',procName);
fprintf(rssFID,'<description>%s</description>\n',webStruct.description);
fprintf(rssFID,'<image><title>Nick Clark</title><url>http://www.mathworks.com/images/membrane_icon.gif</url></image>');
fprintf(rssFID,'<link>http://www.mathworks.com/matlabcentral/fileexchange/</link>\n');
fprintf(rssFID,'<lastBuildDate>%s</lastBuildDate>\n',stampRFC822);
fprintf(rssFID,'<language>en-us</language>\n\n');

% RSS item(s)
fields = fieldnames(dataStruct);
for n = 1:length(fields)
    fprintf(rssFID,'<item>\n');
    if ischar(dataStruct.(fields{n}))
        fprintf(rssFID,'<title>%s = %s</title>\n',fields{n},dataStruct.(fields{n}));
    elseif length(dataStruct.(fields{n}))>1
        fprintf(rssFID,'<title>%s = %s</title>\n',fields{n},num2str(dataStruct.(fields{n})));
    else
        fprintf(rssFID,'<title>%s = %g\n</title>',fields{n},dataStruct.(fields{n}));
    end
    fprintf(rssFID,'<link>%s</link>\n',[webStruct.webAddy procName '.html']);
    fprintf(rssFID,'<guid>%s</guid>\n',[webStruct.webAddy procName '.html']);
    fprintf(rssFID,'<pubDate>%s</pubDate>\n',stampRFC822);
    fprintf(rssFID,'<description>Selected data for inclusion in RSS feed.</description>\n');
    fprintf(rssFID,'</item>\n\n');
end

%close channel and file
fprintf(rssFID,'</channel>\n</rss>\n');
fclose(rssFID);

%% Make HTML page
htmlFile = fullfile('www',procName,[procName '.html']);
htmlFID = fopen(htmlFile, 'w');
fprintf(htmlFID,'<style type="text/css"> h1 {border-style: solid; border-width: 5px; border-left-width: 10px; border-right-width: 10px; border-color: red;}</style>');
fprintf(htmlFID,'<html>\n<head>\n<title>%s</title>\n</head>\n<body bgcolor="#C8FFF0">\n<h1>%s ',procName,procName);
fprintf(htmlFID,'<a href="%s"><img border="0" src="http://www.rssboard.org/images/rss-icon.png"></a></h1>\n',[procName '.xml']);
fprintf(htmlFID,'</ul>\n<h3>%s</h3>\n',webStruct.description);
fprintf(htmlFID,'<style type="text/css" media="all">td {border: 1px solid #999;	padding: 0.1em 1em;}</style><table>');
for n = 1:length(fields)
    fprintf(htmlFID,'<tr>');
    if ischar(dataStruct.(fields{n}))
        fprintf(htmlFID,'<td>%s</td>  <td>%s</td>\n',fields{n},dataStruct.(fields{n}));
    elseif length(dataStruct.(fields{n}))>1
        fprintf(htmlFID,'<td>%s</td>  <td>%s</td>\n',fields{n},num2str(dataStruct.(fields{n})));
    else
        fprintf(htmlFID,'<td>%s</td>  <td>%g</td>\n',fields{n},dataStruct.(fields{n}));
    end
    fprintf(htmlFID,'</tr>');
end
fprintf(htmlFID,'<table>');
fprintf(htmlFID,'<br /><br /><br /><p><a href="http://www.mathworks.com/matlabcentral/fileexchange/loadAuthor.do?objectType=author&objectId=1097407">More submissions by Nick Clark</a></p>');
fprintf(htmlFID,'%.3f Seconds elapsed generating web page and rss feed</body></html>',etime(clock, t));
fclose(htmlFID);

%% Upload files to server via ftp and close connection when done
try
    ftpObj = ftp(webStruct.hostAddy,webStruct.uName,webStruct.pwd);
    mput(ftpObj,fullfile('www',procName,[procName '.html']));
    mput(ftpObj,fullfile('www',procName,[procName '.xml']));
    close(ftpObj)
catch ME
    fprintf(1,'No luck connecting to server this time because I %s :(\n',ME.message)
end

Contact us at files@mathworks.com