What is wrong with my Gmail notifier code? - gmail

Do you guys see any issues with this C# code? It gets email notifications from gmail and then prints to CMD how many unread mails are waiting:
Unread Mails: 10
Unread Mails: 10
and then sends how many mails over serial too. But after it says "unread mails:" twice i get:
Operation Timed Out.
Unread Mails: 0
and it repeats.
Iv'e tried this on different computers and ISPs so its definitely something in the code.
The C# program. I also have tried changing the Thread.Sleep value so that it takes longer before it does it again, but still doesn't work.
Thanks!
public static void Main(string[] args)
{
try
{
SerialPort port = new SerialPort( "COM1", 9600, Parity.None, 8, StopBits.One );
port.Open();
string Unreadz = "0";
while ( true )
{
Unreadz = CheckMail();
Console.WriteLine("Unread Mails: " + Unreadz);
if (Convert.ToInt32(Unreadz) < 10) port.Write("0" + Unreadz);
else port.Write("" + Unreadz);
System.Threading.Thread.Sleep( 10000 );
}
} catch ( Exception ee ) { Console.WriteLine( ee.Message ); }
}
public static string TextToBase64( string sAscii )
{
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
byte[] bytes = encoding.GetBytes( sAscii );
return System.Convert.ToBase64String( bytes, 0, bytes.Length );
}
public static string CheckMail()
{
string result = "0";
try
{
var url = #"https://gmail.google.com/gmail/feed/atom";
var USER = "USER";
var PASS = "PASS";
var encoded = TextToBase64( USER + ":" + PASS );
var myWebRequest = HttpWebRequest.Create( url );
myWebRequest.Method = "POST";
myWebRequest.ContentLength = 0;
myWebRequest.Headers.Add( "Authorization", "Basic " + encoded );
var response = myWebRequest.GetResponse();
var stream = response.GetResponseStream();
XmlReader reader = XmlReader.Create( stream );
while ( reader.Read())
if ( reader.NodeType == XmlNodeType.Element )
if ( reader.Name == "fullcount" )
{
result = reader.ReadElementContentAsString();
return result;
}
} catch ( Exception ee ) { Console.WriteLine( ee.Message ); }
return result;
}
}
}

well i seemed to fix it. since i was just looping it every 10 seconds for testing, i put it to 5 minutes. 5 minutes is more realistic for my needs.

Related

Unable to read message from Service bus. it is returning null

I am trying to read the stream that is on Azure Service bus. But I am getting null bytes. File size that is getting created is same as the size of the bytes that are being sent, but it contains all nulls. I have added the code that is used for converting Stream to Byte array with the function name ReadAllBytes(Stream source)
below is the code for reference:
static void Main(string[] args)
{
MemoryStream largeMessageStream = new MemoryStream();
#region ReceiveMessage
var msg = Microsoft.ServiceBus.NamespaceManager.CreateFromConnectionString(ConfigurationSettings.AppSettings["Microsoft.ServiceBus.ConnectionString"].ToString());
var numofmessages = msg.GetQueue(AccountDetails.QueueName).MessageCountDetails.ActiveMessageCount.ToString();
if (msg.GetQueue(AccountDetails.QueueName).RequiresSession)
{
var queueClient1 = QueueClient.CreateFromConnectionString(ConfigurationSettings.AppSettings["Microsoft.ServiceBus.ConnectionString"].ToString(), AccountDetails.QueueName);
var session = queueClient1.AcceptMessageSession();
Console.WriteLine("Message session Id: " + session.SessionId);
Console.Write("Receiving sub messages");
while (true)
{
// Receive a sub message
BrokeredMessage subMessage = session.Receive(TimeSpan.FromSeconds(5));
if (subMessage != null)
{
// Copy the sub message body to the large message stream.
Stream subMessageStream = subMessage.GetBody<Stream>();
subMessageStream.CopyTo(largeMessageStream);
// Mark the message as complete.
subMessage.Complete();
Console.Write(".");
}
else
{
// The last message in the sequence is our completeness criteria.
Console.WriteLine("Done!");
break;
}
}
// Create an aggregated message from the large message stream.
BrokeredMessage largeMessage = new BrokeredMessage(largeMessageStream, true);
Console.WriteLine("Received message");
Console.WriteLine("Message body size: " + largeMessageStream.Length);
string testFile = #"D:\Dev\csvData1.csv";
Console.WriteLine("Saving file: " + testFile);
// Save the message body as a file.
Stream resultStream = largeMessage.GetBody<Stream>();
byte[] x = ReadAllBytes(resultStream);
File.WriteAllBytes(testFile, x);
}
public static byte[] ReadAllBytes(Stream source)
{
long originalPosition = source.Position;
source.Position = 0;
try
{
byte[] readBuffer = new byte[source.Length];
int totalBytesRead = 0;
int bytesRead;
while ((bytesRead = source.Read(readBuffer, totalBytesRead, readBuffer.Length - totalBytesRead)) > 0)
{
totalBytesRead += bytesRead;
if (totalBytesRead == readBuffer.Length)
{
int nextByte = source.ReadByte();
if (nextByte != -1)
{
byte[] temp = new byte[readBuffer.Length * 2];
Buffer.BlockCopy(readBuffer, 0, temp, 0, readBuffer.Length);
Buffer.SetByte(temp, totalBytesRead, (byte)nextByte);
readBuffer = temp;
totalBytesRead++;
}
}
}
byte[] buffer = readBuffer;
if (readBuffer.Length != totalBytesRead)
{
buffer = new byte[totalBytesRead];
Buffer.BlockCopy(readBuffer, 0, buffer, 0, totalBytesRead);
}
return buffer;
}
finally
{
source.Position = originalPosition;
}
}
I send a message with stream body using the following code, and then I receive the message and test your code on my side, the code works for me.
using (MemoryStream stream = new MemoryStream(File.ReadAllBytes(#"C:\Users\xxx\Desktop\source.txt")))
{
client.Send(new BrokeredMessage(stream));
}
My source.txt
"ID", "Age", "Rich", "timestamp"
1, "50", "Y", "2017-06-06 14:19:21.77"
2, "22", "N", "2017-06-06 14:19:21.77"
Byte array
Console app output
csvData1.csv
If possible, you can try to send a new message with stream body and execute your code to check if it can works fine.

I want to send free form native query output to excel using a WebGrid

First I need to explain my problem, I have a native query application where someone types in "Select .... this and that" and the output is currently displayed in a grid that is paginated and I have been asked to add a button that will export the data to excel directly from an untyped datastream. my current code that I've found uses a grid and still doesn't prompt me to download a .xls file for some reason.
[Authorize(Roles = "Portal administrator")]
public void ExportExcel(NativeQueryVM model, int? page, string sort)
{
List<Dictionary<string, object>> result = null;
String vartimedate = DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss");
try
{
var user = Membership.GetUser();
var grid = new System.Web.UI.WebControls.GridView();
if (page == null && sort == null)
{
if (model.QueryText.ToUpper().StartsWith("SELECT"))
{
UserQueryInput queryinput = new UserQueryInput();
queryinput.DatabaseId = model.selectedDatabase;
queryinput.QueryText = model.QueryText;
result = lookupProvider.GetSetNativeQuery((Guid)user.ProviderUserKey, user.UserName, queryinput, "Set");
model.QueryResultData = result;
ViewBag.SubmitType = "Select";
CreateDynamicResult(model.QueryResultData);
if (model == null || model.QueryResultData.Count == 0)
{
ViewBag.ResultMessage = "No Results Found";
}
else
{
WebGrid wd = new WebGrid(source: ViewBag.DynamicResult, canPage: false, canSort: false );
string griddata = wd.GetHtml().ToString();
string attachment = "attachment; filename=NativeQuery" + vartimedate + ".xls";
Response.ClearContent();
Response.AddHeader("content-disposition", attachment);
Response.ContentType = "application/excel";
StringWriter sw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
Response.Write(griddata);
Response.End();
}
}
}
else
{ //This part should come when page or sort is not null for Select. Should not be executed other than SELECT
result = lookupProvider.GetSetNativeQuery((Guid)user.ProviderUserKey, user.UserName, null, "Get");
model.QueryResultData = result;
ViewBag.SubmitType = "Select";
CreateDynamicResult(model.QueryResultData);
if (model == null || model.QueryResultData.Count == 0)
{
ViewBag.ResultMessage = "No Results Found";
}
else
{
}
}
}
catch (Exception ex)
{
logger.Log(new LogMessage()
.ForMethod("SubmitQuery")
.WithContext(Environment.MachineName)
.WithException(ex)
.WithDescription("An error occurred while submiting query to get result"));
}
}
Hi all that answered this problem, and I've found the answer and issues reside outside of the code that I've entered into the question. Jquery was intercepting the output of my file stream and on the other hand, if the button was created with runat=server the model is out of scope and the main part of the solution involved saving the model to a session and pulling it back in.
Thanks for your assistance all...
How are you calling this void function? The return paths include setting a ViewBag property with an error message along with modifying the response. It smells of bad design.
I'd create a hyperlink that links to a #Url.Action for something like this. Note that you'd need to return a FileContentResult with the data UTF8-encoded rather than modifying the Response directly:
public async Task<ActionResult> Test()
{
WebGrid wd = new WebGrid(source: ViewBag.DynamicResult, canPage: false, canSort: false );
string griddata = wd.GetHtml().ToString();
string attachment = "attachment; filename=NativeQuery" + vartimedate + ".xls";
Response.ClearContent();
Response.AddHeader("content-disposition", attachment);
Response.ContentType = "application/excel";
byte[] buffer = System.Text.UTF8Encoding.UTF8.GetBytes(griddata);
return File(buffer, "application/octet-stream");
}

Why is parallel.Invoke not working in this case

I have an array of files like this..
string[] unZippedFiles;
the idea is that I want to parse these files in paralle. As they are parsed a record gets placed on a concurrentbag. As record is getting placed I want to kick of the update function.
Here is what I am doing in my Main():
foreach(var file in unZippedFiles)
{ Parallel.Invoke
(
() => ImportFiles(file),
() => UpdateTest()
);
}
this is what the code of Update loooks like.
static void UpdateTest( )
{
Console.WriteLine("Updating/Inserting merchant information.");
while (!merchCollection.IsEmpty || producingRecords )
{
merchant x;
if (merchCollection.TryTake(out x))
{
UPDATE_MERCHANT(x.m_id, x.mInfo, x.month, x.year);
}
}
}
This is what the import code looks like. It's pretty much a giant string parser.
System.IO.StreamReader SR = new System.IO.StreamReader(fileName);
long COUNTER = 0;
StringBuilder contents = new StringBuilder( );
string M_ID = "";
string BOF_DELIMITER = "%%MS_SKEY_0000_000_PDF:";
string EOF_DELIMITER = "%%EOF";
try
{
record_count = 0;
producingRecords = true;
for (COUNTER = 0; COUNTER <= SR.BaseStream.Length - 1; COUNTER++)
{
if (SR.EndOfStream)
{
break;
}
contents.AppendLine(Strings.Trim(SR.ReadLine()));
contents.AppendLine(System.Environment.NewLine);
//contents += Strings.Trim(SR.ReadLine());
//contents += Strings.Chr(10);
if (contents.ToString().IndexOf((EOF_DELIMITER)) > -1)
{
if (contents.ToString().StartsWith(BOF_DELIMITER) & contents.ToString().IndexOf(EOF_DELIMITER) > -1)
{
string data = contents.ToString();
M_ID = data.Substring(data.IndexOf("_M") + 2, data.Substring(data.IndexOf("_M") + 2).IndexOf("_"));
Console.WriteLine("Merchant: " + M_ID);
merchant newmerch;
newmerch.m_id = M_ID;
newmerch.mInfo = data.Substring(0, (data.IndexOf(EOF_DELIMITER) + 5));
newmerch.month = DateTime.Now.AddMonths(-1).Month;
newmerch.year = DateTime.Now.AddMonths(-1).Year;
//Update(newmerch);
merchCollection.Add(newmerch);
}
contents.Clear();
//GC.Collect();
}
}
SR.Close();
// UpdateTest();
}
catch (Exception ex)
{
producingRecords = false;
}
finally
{
producingRecords = false;
}
}
the problem i am having is that the Update runs once and then the importfile function just takes over and does not yield to the update function. Any ideas on what am I doing wrong would be of great help.
Here's my stab at fixing your thread synchronisation. Note that I haven't changed any of the code from the functional standpoint (with the exception of taking out the catch - it's generally a bad idea; exceptions need to be propagated).
Forgive if something doesn't compile - I'm writing this based on incomplete snippets.
Main
foreach(var file in unZippedFiles)
{
using (var merchCollection = new BlockingCollection<merchant>())
{
Parallel.Invoke
(
() => ImportFiles(file, merchCollection),
() => UpdateTest(merchCollection)
);
}
}
Update
private void UpdateTest(BlockingCollection<merchant> merchCollection)
{
Console.WriteLine("Updating/Inserting merchant information.");
foreach (merchant x in merchCollection.GetConsumingEnumerable())
{
UPDATE_MERCHANT(x.m_id, x.mInfo, x.month, x.year);
}
}
Import
Don't forget to pass in merchCollection as a parameter - it should not be static.
System.IO.StreamReader SR = new System.IO.StreamReader(fileName);
long COUNTER = 0;
StringBuilder contents = new StringBuilder( );
string M_ID = "";
string BOF_DELIMITER = "%%MS_SKEY_0000_000_PDF:";
string EOF_DELIMITER = "%%EOF";
try
{
record_count = 0;
for (COUNTER = 0; COUNTER <= SR.BaseStream.Length - 1; COUNTER++)
{
if (SR.EndOfStream)
{
break;
}
contents.AppendLine(Strings.Trim(SR.ReadLine()));
contents.AppendLine(System.Environment.NewLine);
//contents += Strings.Trim(SR.ReadLine());
//contents += Strings.Chr(10);
if (contents.ToString().IndexOf((EOF_DELIMITER)) > -1)
{
if (contents.ToString().StartsWith(BOF_DELIMITER) & contents.ToString().IndexOf(EOF_DELIMITER) > -1)
{
string data = contents.ToString();
M_ID = data.Substring(data.IndexOf("_M") + 2, data.Substring(data.IndexOf("_M") + 2).IndexOf("_"));
Console.WriteLine("Merchant: " + M_ID);
merchant newmerch;
newmerch.m_id = M_ID;
newmerch.mInfo = data.Substring(0, (data.IndexOf(EOF_DELIMITER) + 5));
newmerch.month = DateTime.Now.AddMonths(-1).Month;
newmerch.year = DateTime.Now.AddMonths(-1).Year;
//Update(newmerch);
merchCollection.Add(newmerch);
}
contents.Clear();
//GC.Collect();
}
}
SR.Close();
// UpdateTest();
}
finally
{
merchCollection.CompleteAdding();
}
}

WebRequest Threads Blocking at Two Requests

I need to test a Data Context and see what behavior it has under multiple simultaneous requests, for that I made a simple console application that [in theory] would send these requests:
private static DateTime startTime = DateTime.Now.AddSeconds(5);
public static Random rand = new Random();
static void Main(string[] args)
{
const byte testThreads = 10;
ThreadStart[] threadStarts = new ThreadStart[testThreads];
Thread[] threads = new Thread[testThreads];
for (byte i = 0; i < testThreads; i++)
{
threadStarts[i] = new ThreadStart(ExecutePOST);
threads[i] = new Thread(threadStarts[i]);
}
for (byte i = 0; i < testThreads; i++){ threads[i].Start(); }
for (byte i = 0; i < testThreads; i++){ threads[i].Join(); }
}
The called function is
private static void ExecutePOST()
{
while (DateTime.Now < startTime) { }
Console.WriteLine("{0} STARTING TEST", DateTime.Now.Millisecond);
WebRequest webRequest = WebRequest.Create(/*URL*/);
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.Method = "POST";
string name = string.Format("Test {0}", Program.rand.Next(1000));
byte[] bytes = Encoding.ASCII.GetBytes(/*PARAMETERS*/);
Stream output = null;
try
{
webRequest.ContentLength = bytes.Length;
output = webRequest.GetRequestStream();
output.Write(bytes, 0, bytes.Length);
Console.WriteLine("{0}:{1}", DateTime.Now.Millisecond, name);
}
catch (WebException ex)
{
Console.WriteLine(ex.Message);
}
finally
{
if (output != null)
{
output.Close();
}
}
}
The output I get is:
Can anyone please explain this behavior? Why is it stopping after two requests?
Thank you
Yes, this is because the number of connections per URL is limited to 2 by default - the connections are pooled.
You're hogging the connection by writing data to the request stream, but then never getting the response. A simple:
using (webRequest.GetResponse()) {}
at the end of the method is likely to sort it out. That will finish the request and release the connection to be used by another request.
Also note that a using statement for the output stream would make your code simpler too.

How to get DateTime from the internet?

How to get current date and time from internet or server using C#? I am trying to get time as follows:
public static DateTime GetNetworkTime (string ntpServer)
{
IPAddress[] address = Dns.GetHostEntry(ntpServer).AddressList;
if (address == null || address.Length == 0)
throw new ArgumentException("Could not resolve ip address from '" + ntpServer + "'.", "ntpServer");
IPEndPoint ep = new IPEndPoint(address[0], 123);
return GetNetworkTime(ep);
}
I am passing server IP address as netServer, but it does not work properly.
Here is code sample that you can use to retrieve time from NIST Internet Time Service
var client = new TcpClient("time.nist.gov", 13);
using (var streamReader = new StreamReader(client.GetStream()))
{
var response = streamReader.ReadToEnd();
var utcDateTimeString = response.Substring(7, 17);
var localDateTime = DateTime.ParseExact(utcDateTimeString, "yy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
}
Here is a quick code to get the time from the header, works without the need of port 13
public static DateTime GetNistTime()
{
var myHttpWebRequest = (HttpWebRequest)WebRequest.Create("http://www.microsoft.com");
var response = myHttpWebRequest.GetResponse();
string todaysDates = response.Headers["date"];
return DateTime.ParseExact(todaysDates,
"ddd, dd MMM yyyy HH:mm:ss 'GMT'",
CultureInfo.InvariantCulture.DateTimeFormat,
DateTimeStyles.AssumeUniversal);
}
Things could go wrong. All implements of the code founded above are prone to errors. Sometimes, it works and sometimes it trows a WebExpection error message.
A better implementation:
try{
using (var response =
WebRequest.Create("http://www.google.com").GetResponse())
//string todaysDates = response.Headers["date"];
return DateTime.ParseExact(response.Headers["date"],
"ddd, dd MMM yyyy HH:mm:ss 'GMT'",
CultureInfo.InvariantCulture.DateTimeFormat,
DateTimeStyles.AssumeUniversal);
}
catch (WebException)
{
return DateTime.Now; //In case something goes wrong.
}
Conclusion:
Having your web app depend on a service that provides accurate date information is critical. I have used one of the code founded here in my app and it really mess things up.
One more version of the same idea:
public static class InternetTime
{
public static DateTimeOffset? GetCurrentTime()
{
using (var client = new HttpClient())
{
try
{
var result = client.GetAsync("https://google.com",
HttpCompletionOption.ResponseHeadersRead).Result;
return result.Headers.Date;
}
catch
{
return null;
}
}
}
}
Here HttpCompletionOption.ResponseHeadersRead is used to prevent loading of the rest of the response, as we need only HTTP headers.
Use InternetTime.GetCurrentTime().Value.ToLocalTime() to get current local time.
Important: first check the avaible servers on
NIST Internet Time Servers.
public static DateTime GetServerTime()
{
var result = DateTime.Now;
// Initialize the list of NIST time servers
// http://tf.nist.gov/tf-cgi/servers.cgi
string[] servers = new string[] {
"time-c.nist.gov",
"time-d.nist.gov",
"nist1-macon.macon.ga.us",
"wolfnisttime.com",
"nist.netservicesgroup.com",
"nisttime.carsoncity.k12.mi.us",
"nist1-lnk.binary.net",
"wwv.nist.gov",
"time.nist.gov",
"utcnist.colorado.edu",
"utcnist2.colorado.edu",
"nist-time-server.eoni.com",
"nist-time-server.eoni.com"
};
Random rnd = new Random();
foreach (string server in servers.OrderBy(x => rnd.NextDouble()).Take(9))
{
try
{
// Connect to the server (at port 13) and get the response. Timeout max 1second
string serverResponse = string.Empty;
var tcpClient = new TcpClient();
if (tcpClient.ConnectAsync(server, 13).Wait(1000))
{
using (var reader = new StreamReader(tcpClient.GetStream()))
{
serverResponse = reader.ReadToEnd();
}
}
// If a response was received
if (!string.IsNullOrEmpty(serverResponse))
{
// Split the response string ("55596 11-02-14 13:54:11 00 0 0 478.1 UTC(NIST) *")
string[] tokens = serverResponse.Split(' ');
// Check the number of tokens
if (tokens.Length >= 6)
{
// Check the health status
string health = tokens[5];
if (health == "0")
{
// Get date and time parts from the server response
string[] dateParts = tokens[1].Split('-');
string[] timeParts = tokens[2].Split(':');
// Create a DateTime instance
DateTime utcDateTime = new DateTime(
Convert.ToInt32(dateParts[0]) + 2000,
Convert.ToInt32(dateParts[1]), Convert.ToInt32(dateParts[2]),
Convert.ToInt32(timeParts[0]), Convert.ToInt32(timeParts[1]),
Convert.ToInt32(timeParts[2]));
// Convert received (UTC) DateTime value to the local timezone
result = utcDateTime.ToLocalTime();
return result;
// Response successfully received; exit the loop
}
}
}
}
catch
{
// Ignore exception and try the next server
}
}
return result;
}
public static Nullable<DateTime> GetDateTime()
{
Nullable<DateTime> dateTime = null;
System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create("http://www.microsoft.com");
request.Method = "GET";
request.Accept = "text/html, application/xhtml+xml, */*";
request.UserAgent = "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)";
request.ContentType = "application/x-www-form-urlencoded";
request.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.NoCacheNoStore);
try
{
System.Net.HttpWebResponse response = (System.Net.HttpWebResponse)request.GetResponse();
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
string todaysDates = response.Headers["date"];
dateTime = DateTime.ParseExact(todaysDates, "ddd, dd MMM yyyy HH:mm:ss 'GMT'",
System.Globalization.CultureInfo.InvariantCulture.DateTimeFormat, System.Globalization.DateTimeStyles.AssumeUniversal);
}
}
catch
{
dateTime = null;
}
return dateTime;
}

Resources