Google Drive API watch channel is only 24h - c#

I am using the v3 api drive file watch api. I just want to subscribe to the changes made in specific folders. I was able to establish the watch channel. However, the expiration date I receive is only 24h even when I set it manually to 7 days.
var expirationWatchTime = DateTimeOffset.UtcNow.AddDays(7);
var channel = DriveService.Files.Watch(
new Channel
{
Address = _googleConfiguration.Value.WebHookUrl,
Type = "web_hook",
Id = projectDocumentFolderId.ToString(),
Expiration = expirationWatchTime.ToUnixTimeMilliseconds()
},
missingFolder.Id).Execute();

I'm checking the official documentation and it seems that subscribing to file resources changes will have a maximum expiration date of 24 hours. I'll quote the specific note:
Note: For the Drive API, the maximum expiration time is 86400 seconds (1 day) after the current time for File resources and 604800 seconds (1 week) for Changes. If you don’t set the expiration property in your request, the expiration time defaults to 3600 seconds after the current time.
There is this thread that it as well provides the same answer.

Related

AWSSDK not generating new PreSigned URLs (always expired)

I have a private bucket that generates pre-signed URLs that expires in 300 seconds (5 minutes), in total there are 10 images stored, but 1 image always generates an expired URL (it never updates the expire time). I have tried with different browsers and devices in different computers, it isn't a caché or temp problem.
I'm using AWSSDK 1.5.2.2, my code to generate the URLs is the next:
public string GetPreSignedURL(string bucketName, string keyName, System.DateTime expiration)
{
GetPreSignedUrlRequest urlRequest = new GetPreSignedUrlRequest();
urlRequest.BucketName = bucketName;
urlRequest.Key = keyName;
urlRequest.Expires = expiration;
urlRequest.Protocol = this.AwsProtocol;
return this.S3.GetPreSignedURL(urlRequest);
}
And I call it like this:
this.image = this.AWSManager.GetPreSignedURL(bucketName, keyName, this.GetExpireTime());
The GetExpireTime() method is this:
private DateTime GetExpireTime()
{
int expireTime;
try
{
expireTime = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["expireTime"].ToString());
}
catch
{
expireTime = defaultExpireTime;
}
return DateTime.Now.AddSeconds(expireTime);
}
Of the 10 images that are stored in AWS, there is always one, and the same image that returns the same URL everytime it is generated (only happens in production, so I have no way to debug). I connected the develop environment to the production bucket, and replicated the DB register to see if I can replicate the problem, but in my local machine the URL gets generated just fine.
Here is a URL that was generated at 9:34 AM:
https://gtidev-masorden.s3.amazonaws.com/P4285735_thumbnail.png?AWSAccessKeyId=AKIAJTCJB4KPHVI4HTXQ&Expires=1550177695&Signature=f0Llq2syEvDvgdhxYHeedHCpD8s%3D
And here is one generated at 10:00 AM:
https://gtidev-masorden.s3.amazonaws.com/P4285735_thumbnail.png?AWSAccessKeyId=AKIAJTCJB4KPHVI4HTXQ&Expires=1550177695&Signature=f0Llq2syEvDvgdhxYHeedHCpD8s%3D
I compare every generated URL here:
https://text-compare.com/
And it's always the same URL, no changes in Expires param or Signature param. When I reupload the picture, it starts to generate valid urls again but a few minutes later, another picture starts to fail.
EDIT:I have been requesting the same image for about 4 days and the expiration date is the same. When I open the URL in a new tab, this is what it says:
<Error>
<Code>AccessDenied</Code>
<Message>Request has expired</Message>
<Expires>2019-02-14T20:54:55Z</Expires>
<ServerTime>2019-02-18T17:09:27Z</ServerTime>
<RequestId>C78E43335EE8E845</RequestId>
<HostId>
PPHXhK6Oj7PEKOqb8io1IcVY6mfqNM5zc89ttLylzH/DKPldIo0v8pukdW4SZmqACAVn8WSyIu0=
</HostId>
</Error>
Perhaps I'm missing somethig, and I don't want to update the AWSSDK because others projects depend on it. Any ideas?

Custom output cache mvc4

I am trying to utilise caching on an MVC4 project and I have the following attribute set on my homepage:
[OutputCache(Location=OutputCacheLocation.ServerAndClient,Duration=14400)]
This works fine, however the duration is causing me an issue. What I need is for the cache to expire on the start of a new day (midnight each day). I could set the duration to be 24 hours however this does not solve my problem with my page having new content on the start of each day. I have explored the vary by param method and I understand that I can append the date to the URL but this is very messy. Does anyone know an alternative?
Thanks in advance
A solution will be to extend the OutputCacheAttribute and to create a new one that works for midnight because you can set Duration in constructor.
public class OutputCacheMidnightAttribute : OutputCacheAttribute
{
public OutputCacheMidnightAttribute()
{
// remaining time to midnight
Duration = (int)((new TimeSpan(24, 0, 0)) - DateTime.Now.TimeOfDay).TotalSeconds;
}
}
And you use it like this
[OutputCacheMidnight(Location=OutputCacheLocation.ServerAndClient)]

Get PC TimeZone on C#

Im currently developing on asp - c# as a backend code. I want to get the current timezone that was set on the PC.
The below code are still identifying what is the correct timezone of my current area (+8GMT) even though I already changed my PC timezone settings into another timezone.
What I want is to get the timezone offset specified on the PC date settings. Can anyone help me on this. Below is my code so far.
public TimeSpan currentOffset;
public DateTime utc;
public DateTime local;
this.utc = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTime.Now, TimeZoneInfo.Utc.Id);
this.local = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTime.Now, TimeZoneInfo.Local.Id);
this.currentOffset = this.local.Subtract(this.utc);
In addition to David Haney's answer.
TimeZoneInfo is caching data after first call so any changes in PC settings will not affect your application if it is already running.
You should call method:
TimeZoneInfo.ClearCachedData();
to refresh this cache.
So this one will work in your case:
TimeZoneInfo.ClearCachedData();
var offsetTimespan = DateTimeOffset.Now.Offset;
var offsetInHours = offsetTimespan.TotalHours;
You're making your life harder than it needs to be. :)
Use DateTimeOffset: http://msdn.microsoft.com/en-us/library/system.datetimeoffset.now%28v=vs.110%29.aspx
var now = DateTimeOffset.Now;
This will include the time zone offset information as well.

Inconsistencies in DateTime between local machine and Azure

I have an app hosted in an Azure Website. When using the hosted application, the DateTimes are displayed and saved properly. When I run the application locally, and pull the data from the Azure SQL database, I get very weird results. Every datetime seems to be 6 hours off.
If I'm on my local box and I pull data from the server, all datetimes are displayed as actual+6 hours.
If I then, from local box, post something to Azure SQL, the time gets saved as actual-6hrs.
An example of the reads/writes I'm talking about:
Write:
var chatMessage = new ChatMessage() {
DatePosted = DateTime.Now
};
db.ChatMessages.Add(chatMessage);
Read:
// get chatMessage from db
messageVm.DateIndicator = DateUtilities.GetFriendlyDate(chatMessage.DatePosted);
// GetFriendlyDate is:
public static string GetFriendlyDate(DateTime? postDate) {
if (postDate == null) {
return null;
}
string stringy = string.Empty;
TimeSpan diff = DateTime.Now.Subtract((DateTime) postDate);
double days = diff.Days;
double hours = diff.Hours + days * 24;
double minutes = diff.Minutes + hours * 60;
if (minutes <= 1) {
return "Just Now";
}
// etc
}
So in the above Read - if I'm running the app locally and accessing Azure SQL, content posted 5 hours ago is being displayed as posted "Just Now", and if I save a new message, the hosted application displays the time as 6 hours ago (when it should be "just now").
Splitting the logic (local) from the db (azure) is obviously the cause of this - but is this an indication that I'm not handling DateTimes properly? If so, what am I doing wrong?
You're in a different time zone. Use DateTime in UTC, or better yet avoid all the oddities of that and use DateTimeOffset.
Unlike .NET's DateTime type, databases don't have a "Kind" that indicates if they're a local or UTC date. This makes them really easy to use inconsistently and not even realize it. DateTimeOffset stores an offset from UTC, so it does not have the same problem.
Try using DateTime.UtcNow rather than DateTime.Now

File creation time in C#

I need to get when a file was created - I have tried using:
FileInfo fi = new FileInfo(FilePath);
var creationTime = fi.CreationTimeUtc;
and
var creationTime = File.GetCreationTimeUtc(FilePath);
Both methods generally return the wrong creation time - I guess it is being cached somewhere.
The file is deleted and re-created with the same name and I need to know when/if it has been re-created (by checking if the created date/time has changed) - I had planned to do this by seeing it the file creation time had changed but I have found this to be inaccurate.
I'm working on Win 7 and if I check File Explorer it shows the new file creation time correctly.
I have also tried using the FileSystemWatcher but it doesn't entirely work for my use case. E.g. if my program is not running, the FileSystemWatcher is not running, so when my program starts up again I don't know if the file has been deleted and recreated or not.
I've seen MSDN http://msdn.microsoft.com/en-us/library/system.io.file.getcreationtime.aspx where it says:
This method may return an inaccurate value, because it uses native functions whose values may not be continuously updated by the operating system.
But I have also tried using their alternative suggestion and setting the SetCreationDate after creating a new file but I also find that this doesn't work. See test below:
[Test]
public void FileDateTimeCreatedTest()
{
var binPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
var fullFilePath = Path.Combine(binPath, "Resources", "FileCreatedDatetimeTest.txt");
var fullFilePathUri = new Uri(fullFilePath);
var dateFormatted = "2013-08-17T15:31:29.0000000Z"; // this is a UTC string
DateTime expectedResult = DateTime.MinValue;
if (DateTime.TryParseExact(dateFormatted, "o", CultureInfo.InvariantCulture,
DateTimeStyles.AssumeUniversal, out expectedResult)) // we expect the saved datetime to be in UTC.
{
}
File.Create(fullFilePathUri.LocalPath);
Thread.Sleep(1000); // give the file creation a chance to release any lock
File.SetCreationTimeUtc(fullFilePathUri.LocalPath, expectedResult); // physically check what time this puts on the file. It should get the local time 16:31:29 local
Thread.Sleep(2000);
var actualUtcTimeFromFile = File.GetCreationTimeUtc(fullFilePathUri.LocalPath);
Assert.AreEqual(expectedResult.ToUniversalTime(), actualUtcTimeFromFile.ToUniversalTime());
// clean up
if (File.Exists(fullFilePathUri.LocalPath))
File.Delete(fullFilePathUri.LocalPath);
}
Any help much appreciated.
You need to use Refresh:
FileSystemInfo.Refresh takes a snapshot of the file from the current
file system. Refresh cannot correct the underlying file system even if
the file system returns incorrect or outdated information. This can
happen on platforms such as Windows 98.
Calls must be made to Refresh before attempting to get the attribute
information, or the information will be outdated.
The key bits from MSDN indicate that it takes a snapshot and attribute information..will be outdated.
Try using FileInfo and Refresh method of it
fileInfo.Refresh();
var created = fileInfo.CreationTime;
this should work
File.Create(fullFilePathUri.LocalPath);
Thread.Sleep(1000); // give the file creation a chance to release any lock
That is not how you do it. File.Create creates stream writer which should be closed to release the lock without any waiting. If you find yourself using Thread.Sleep, you will often find that you are doing something wrong.
If the file described in the path parameter does not exist, this method returns 12:00 midnight, January 1, 1601 A.D. (C.E.) Coordinated Universal Time (UTC), adjusted to local time.
https://learn.microsoft.com/en-us/dotnet/api/system.io.file.getcreationtime?view=netframework-4.8

Categories