Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Globalization;
- using System.IO;
- using System.Linq;
- using System.Net;
- using System.Text;
- using System.Text.RegularExpressions;
- using System.Threading;
- using System.Threading.Tasks;
- namespace Retel.FactoryLayer.Backend.PLCFileService
- {
- class Panel : HTTPServer
- {
- public Panel(String ip, String username, String password, List<Job> jobs, int timeoutAttempts, bool statistics, double statisticsIntervalInHours, List<String> mailList)
- {
- base.ip = ip;
- base.username = username;
- base.password = password;
- base.jobs = jobs;
- base.timeoutAttempts = timeoutAttempts;
- base.statistics = statistics;
- base.statisticsIntervalInHours = statisticsIntervalInHours;
- base.mailList = mailList;
- }
- public override void Schedule()
- {
- if (statistics && nextStatistic < DateTime.Now)
- {
- SendStatistic();
- nextStatistic = DateTime.Now.AddHours(statisticsIntervalInHours);
- }
- int threadId = Thread.CurrentThread.ManagedThreadId;
- //if the next execution time of a job is before the current time, execute the job
- foreach (Job job in this.jobs)
- {
- if (PLCFileService.watchdog != null)
- {
- PLCFileService.watchdog.NotifyThreadHeartbeat(threadId);
- }
- if (job.GetNextExecutionDate() < DateTime.Now)
- {
- PLCFileService.msgLog.LogMessage("Executing job: " + job.GetName(), Common.MessageLogger.LogLevel.DEBUG);
- job.AddExecute();
- if (this.sessionkey == null)
- {
- this.sessionkey = GetSessionKey();
- if (this.sessionkey == null)
- {
- job.SetNextExecutionDate();
- continue;
- }
- }
- Dictionary<String, DateTime> data;
- try
- {
- data = GetData(arguments: job.GetArguments());
- }
- catch (Exception)
- {
- data = null;
- }
- if (PLCFileService.watchdog != null)
- {
- PLCFileService.watchdog.NotifyThreadHeartbeat(threadId);
- }
- if (data == null)
- {
- PLCFileService.msgLog.LogMessage("Failed to get data for: " + this.ip + ", skipping job.", Common.MessageLogger.LogLevel.WARN);
- job.SetNextExecutionDate();
- continue;
- }
- job.Execute(this.ip, data, this.sessionkey);
- }
- }
- }
- protected override Dictionary<string, DateTime> GetData(int tries = 1, Dictionary<string, string> arguments = null)
- {
- //try as many times at timeout attempts are configured, if it failed send a timeout mail
- if (tries > timeoutAttempts)
- {
- SendTimeoutMail();
- return null;
- }
- int threadId = Thread.CurrentThread.ManagedThreadId;
- if (PLCFileService.watchdog != null)
- {
- PLCFileService.watchdog.NotifyThreadHeartbeat(threadId);
- }
- Dictionary<String, DateTime> result = new Dictionary<String, DateTime>();
- string html = String.Empty;
- try
- {
- //send request to userfiles site to grab the userfiles of the html file
- WebRequest request = WebRequest.Create("http://" + this.ip + "/Browse.html");
- request.Headers.Add("Cookie", "coming_from_login=false; " + this.sessionkey);
- request.Credentials = CredentialCache.DefaultCredentials;
- ((HttpWebRequest)request).UserAgent = ".NET Framework Example Client";
- request.Timeout = 5000;
- request.Method = "GET";
- WebResponse response = request.GetResponse();
- //convert response to html
- Stream data = response.GetResponseStream();
- using (StreamReader sr = new StreamReader(data))
- {
- html = sr.ReadToEnd();
- }
- }
- catch (Exception)
- {
- PLCFileService.msgLog.LogMessage("Timeout while retrieving data. (" + tries + " out of " + timeoutAttempts + ")", Common.MessageLogger.LogLevel.WARN);
- this.sessionkey = GetSessionKey();
- return GetData(tries + 1);
- }
- //get all folders on the webserver
- Dictionary<string, string> folders = ListFolders(html);
- //check which of the folders will be downloaded
- foreach(string folder in arguments["folders"].Split(';'))
- {
- if(folders.Keys.Contains(folder))
- {
- //get all files of that folder
- Dictionary<string, DateTime> files = GetFiles(folders[folder]);
- foreach (string file in files.Keys)
- result.Add(file, files[file]);
- }
- }
- if (result.Count() == 0)
- {
- PLCFileService.msgLog.LogMessage("Timeout while retrieving data, requesting new sessionkey. (" + tries + " out of " + timeoutAttempts + ")", Common.MessageLogger.LogLevel.WARN);
- this.sessionkey = GetSessionKey();
- return GetData(tries + 1);
- }
- return result;
- }
- private Dictionary<string, DateTime> GetFiles(string link)
- {
- //get all files from the link to the folder
- Dictionary<string, DateTime> result = new Dictionary<string, DateTime>();
- String html;
- WebRequest request = WebRequest.Create("http://" + this.ip + link);
- request.Headers.Add("Cookie", "coming_from_login=false; " + this.sessionkey);
- request.Credentials = CredentialCache.DefaultCredentials;
- ((HttpWebRequest)request).UserAgent = ".NET Framework Example Client";
- request.Timeout = 5000;
- request.Method = "GET";
- WebResponse response = request.GetResponse();
- //convert response to html
- Stream data = response.GetResponseStream();
- using (StreamReader sr = new StreamReader(data))
- {
- html = sr.ReadToEnd();
- }
- String pattern = @"<TR>\r\n<TD><IMG(.+?)TR>";
- MatchCollection matches = Regex.Matches(html, pattern, RegexOptions.Singleline);
- foreach(Match m in matches)
- {
- //check if the link is a file, if yes get the date and name and return it
- bool isFile = Regex.IsMatch(m.Value, @"\/Images\/File.gif", RegexOptions.Singleline);
- if (isFile)
- {
- String name = Regex.Match(m.Value, @"<A href='(.+?)\?UP", RegexOptions.Singleline).Groups[1].Value;
- string dateString = Regex.Match(m.Value, "... ... .. ..:..:.. ....", RegexOptions.Singleline).Groups[0].Value;
- DateTime date = DateTime.ParseExact(dateString, "ddd MMM dd HH:mm:ss yyyy", CultureInfo.InvariantCulture);
- result.Add(name, date);
- }
- }
- return result;
- }
- private Dictionary<string, string> ListFolders(string data)
- {
- Dictionary<string, string> result = new Dictionary<string, string>();
- Dictionary<string, string> folderQueue = new Dictionary<string, string>();
- //search the html for hyperlinks directed to the root folders
- string pattern = @"<TR class='Storage'(.*?)TR>";
- MatchCollection matches = Regex.Matches(data, pattern, RegexOptions.Singleline);
- Dictionary<string, string> folders = new Dictionary<string, string>();
- foreach (Match m in matches)
- {
- //Get the Filename and links of the root folders
- String name = Regex.Match(m.Value, @"<font face=""Tahoma"" color=""#000000"" size=""2"">(.+?)</font>").Groups[1].Value;
- String link = Regex.Match(m.Value, "<A HREF=\"(.+?)\"><b>").Groups[1].Value;
- folderQueue.Add(name, link);
- }
- String folderData;
- //search all folders for new folders, if new folders are found they are placed in the folderQueue and after a folder is searched it will move to the result dictionary
- while (folderQueue.Count() > 0)
- {
- KeyValuePair<string, string> folder = folderQueue.First();
- //send request to folder site to grab the folders of the html file
- WebRequest request = WebRequest.Create("http://" + this.ip + folder.Value);
- request.Headers.Add("Cookie", "coming_from_login=false; " + this.sessionkey);
- request.Credentials = CredentialCache.DefaultCredentials;
- ((HttpWebRequest)request).UserAgent = ".NET Framework Example Client";
- request.Timeout = 5000;
- request.Method = "GET";
- WebResponse response;
- try
- {
- response = request.GetResponse();
- }
- catch(Exception)
- {
- folderQueue.Remove(folder.Key);
- continue;
- }
- //convert response to html
- Stream stream = response.GetResponseStream();
- using (StreamReader sr = new StreamReader(stream))
- {
- folderData = sr.ReadToEnd();
- }
- pattern = @"<TR>\r\n<TD><IMG(.+?)TR>";
- matches = Regex.Matches(folderData, pattern, RegexOptions.Singleline);
- //find all links with a folder picture to identify between folders and files
- foreach(Match m in matches)
- {
- bool isFolder = Regex.IsMatch(m.Value, @"\/Images\/Directory.gif", RegexOptions.Singleline);
- if(isFolder)
- {
- //filter name and link on webserver, remove the "go back" folder -> Folder with name ".."
- string name = Regex.Match(m.Value, @"BROWSE'>(.+?)<\/A>", RegexOptions.Singleline).Groups[1].Value;
- string link = Regex.Match(m.Value, @"<A href='(?!\/browse.html)(.+?)'>", RegexOptions.Singleline).Groups[1].Value;
- if(!name.Equals("") && !name.Equals("..") && !link.Equals(""))
- folderQueue.Add(name, link);
- }
- }
- result.Add(folder.Key, folder.Value);
- folderQueue.Remove(folder.Key);
- }
- return result;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement