I am trying to track some keywords with the LinqToTwitter library. When I look at the buffer, the data format is not correct.
For example, the data should look like:
{"created_at":"Thu Jul 31 04:21:25 +0000 2014","id":494699327386693632,"id_str":"494699327386693632" ...... ,"filter_level":"medium","lang":"tr"}
But the data looks like:
{"created_at":"Thu Jul 31 04:21:25 +0000 2014","id":494699327386693632,"id_str":"494699327386693632" ...... ,"filter_level":"medium","lang":"tr"} JCAAIMhJz.jpg","media_url_https":"https:\/\/pbs.twimg.com\/media\/Bt18rBJCAAIMhJz.jpg"
Sample code like that (little bit different from linqtotwitter default example):
await
(from strm in TwitterCtx.Streaming
where strm.Type == StreamingType.Filter &&
strm.Track == Track
select strm)
.StartAsync(async strm =>
{
if (!String.IsNullOrEmpty(strm.Content))
buffer += strm.Content;
else
{
if (!String.IsNullOrEmpty(buffer))
{
streamContentList.Add(buffer);
buffer = String.Empty;
count++;
}
}
if (count >= QueryBoundary)
{
Task.Factory.StartNew(() => { mongoAnalyzeUpdateQueryMethod(MongoDB, MongoKeyName, (long)count); });
count = 0;
streamContentList = new List<string>();
}
Console.WriteLine(count);
});
I think I broke the data order when I tried to control content.
What should I do resolve that problem?
This problem fixed in the latest version on LINQ to Twitter, v3.0.4. [1]
[1] https://linqtotwitter.codeplex.com/discussions/542281
Related
I am using this script to fetch Chats. I need 100 chats maximum but it may happen that a chat do not have 100 messages. How can I handle that case in this script?
I am using Node Package Microsoft Graph Client.
const { Client, PageIterator } = require('#microsoft/microsoft-graph-client');
async getChatList(GroupChatId) {
let messages = [];
let count = 0;
let pauseAfter = 100; // 100 messages limit
let response = await this.graphClient
.api(`/chats/${GroupChatId}/messages`)
.version('beta')
.get();
let callback = (data) => {
messages.push(data);
count++;
return count < pauseAfter;
}
let pageIterator = new PageIterator(this.graphClient, response, callback);
await pageIterator.iterate();
return messages;
}
As I answered on the GitHub issue you opened, the iterator should stop all by itself if it runs out of items to iterate before hitting your "maximum". However, I think you're hitting a bug in the specific API you're using /chats/id/messages.
The problem is that this API is returning a nextLink value in it's response even if there are no next pages. It shouldn't be, and I'm reporting that to the Teams folks. That's causing the pageIterator to try to get the next set of results, which returns 0 items and a nextLink. You're stuck in an infinite loop.
So because of this, using the pageIterator just won't work for this API. You'll need to do the iteration yourself. Here's some TypeScript code to show it:
let keepGoing: Boolean = true;
do
{
// If there are no items in the page, then stop
// iterating.
keepGoing = currentPage.value.length > 0;
// Loop through the current page
currentPage.value.forEach((message) => {
console.log(JSON.stringify(message.id));
});
// If there's a next link follow it
if (keepGoing && !isNullOrUndefined(currentPage["#odata.nextLink"]))
{
currentPage = await client
.api(currentPage["#odata.nextLink"])
.get();
}
} while (keepGoing);
You need to check with a conditional statement if the message has value or not.
The pseudo code is given below:
let callback = (data) => {
if(data != "" || data != null)
{
messages.push(data);
count++;
return count < pauseAfter;
}
else{
return;
}
}
We're building an Ionic 2 (currently beta 11).
We're using built-in SqlStorage database. From Android our app is able to read and write date just fine, but with iOS we can only write the data. When we attempt to read the data we get the number of rows returned but none of the actual data.
getQueueItems(): Promise<any> {
return new Promise<any>((resolve, reject) => {
this.sql.query('SELECT * FROM queue').then(
(res) => {
console.log(res, 'result');
// resolve(sqlResult.res.rows);
}
);
}).catch(() => {
});
}
The resultset looks like this:
{
"tx": {
"db": {
"openargs": {
"name":"__ionicstorage",
"location":2,
"createFromLocation":0,
"backupFlag":2,
"existingDatabase":false,
"dblocation":"nosync"
},
"dbname":"__ionicstorage"
},
"txlock":true,
"readOnly":false,
"executes":[],
"finalized":true
},
"res": {
"rows": {
"length":3
},
"rowsAffected":0
}
}
Does anyone know how we can read from SqlStorage so that iOS gets the data?
After a lot of searching and reading tons of forum posts we finally found the answer. I'm posting here for future searchers, hopefully it will help you.
The trick is that in order for the query results to be usable by all platforms you have to iterate through the result set yourself adding the appropriate objects as you go.
this.sql.query('SELECT * FROM queue').then(
(sqlResult) => {
let queueItems = [];
for(let i = 0; i < sqlResult.res.rows.length; i++){
queueItems.push(sqlResult.res.rows.item(i));
}
resolve(queueItems);
}
);
On my Kendo Grid I recieve date time from server. On the client end, this time is changed to client's timezone and that is displayed. How can I show the same time from the server to the client.
the following is my kendo code for binding the datetime.
columns.Bound(p => p.CreateDate).Format("{0:dd/MM/yyyy hh:mm:ss}").Sortable(true).Width(180);
Since the dates are created on the client when the response from the server is returned - the dates are always created with an offset according to the timezone of the browser
This will help you:
http://www.kendoui.com/code-library/mvc/grid/using-utc-time-on-both-client-and-server-sides.aspx
For example, your client machine is in Sydney and your code is deployed in India.
Saving datetime to DB:
While passing the date time from client side (JavaScript) to server (.NET), pass it as a string, so that it won't get converted to server's time (UK) while saving to the database.
If your datetime field is non editable, then follow solution 1, otherwise solution 2 would be the right choice.
Retrieving from DB:
Solution 1:
Client side Code:
cols.Bound(c => c.ExamDate)
.ClientTemplate(("#= ExamDateString #"))
.Hidden(false)
.Filterable(x => x
.Cell(cell => cell
.ShowOperators(false)
.Operator(StringOperator.eq.ToString())
)
);
Server Side Code:
Server Model property for format:
public string ExamDateString
{
get
{
return ExamDate.HasValue
? ExamDate.Value.ToString("dd/MM/yyyy hh:mm:ss")
: string.Empty;
}
}
Solution 2:
Retrieving from DB:
Client side code:
$.ajax({
type: "POST",
url: '#Url.Action("Controller action method name", "Controller name")',
data: {
"clientMachineTimeZoneOffsetInMinutes ": (new Date()).getTimezoneOffset()
},
success: function (data) {
}
});
Server side code:
//Server Timezone(India) Offset minutes : 330
//Client Timezone(Sydney) Offset minutes : -600
//Difference between Client and Server timezone offset minutes = -270
var serverTimeZoneOffsetInMinutes = DateTimeOffset.Now.Offset.TotalMinutes;
var serverAndClientMachineTimeZoneDifferenceInMinutes = clientMachineTimeZoneOffsetInMinutes + serverTimeZoneOffsetInMinutes;
//Update your date time field with this offset minutes
ExamDate = ExamDate.Value.AddMinutes(serverAndClientMachineTimeZoneDifferenceInMinutes);
Solution 3:
Solution 2 won't handle daylight saving scenario, this would be the ideal solution to handle all scenarios.
Before you return the DataSource result from the controller action method to kendo grid, do the operation below to stop the conversion:
var response = new ContentResult
{
Content = JsonConvert.SerializeObject(value, new JsonSerializerSettings
{
DateTimeZoneHandling = DateTimeZoneHandling.Local,
DateFormatString = "yyyy-MM-ddTHH:mm:ss"
}),
ContentType = "application/json"
};
return response;
This was my solution.
In the controller I did this:
DateTime time = DateTime.Now();
string x = time.ToString("MM/dd/yyyy hh:mm:ss tt");
And in the View:
columns.Bound(p => p.x);
It is also sortable.
Another option is to use custom JsonResult and convert the date to ISO format.
public class IsoDateJsonResult : JsonResult
{
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
HttpResponseBase response = context.HttpContext.Response;
if (!String.IsNullOrEmpty(ContentType))
{
response.ContentType = ContentType;
}
else
{
response.ContentType = "application/json";
}
if (ContentEncoding != null)
{
response.ContentEncoding = ContentEncoding;
}
if (Data != null)
{
var isoConvert = new IsoDateTimeConverter();
response.Write(JsonConvert.SerializeObject(Data, isoConvert));
}
}
Then change your Controller method to return IsoDateJsonResult instead of ActionResult/JsonResult.
Solution 2 in my above answer, daylight saving hour is getting added if you are not in daylight saving period but you are trying to access the date which falls in daylight saving period, rewriting the solution 2 to support daylight saving period aswell
Client side code to update timezone name:
$.ajax({
type: "POST",
url: '#Url.Action("Controller action method name", "Controller name")',
data: { "timeZoneName": Intl.DateTimeFormat().resolvedOptions().timeZone },
success: function (data) {
}
});
Controller method name to update the timezone in session:
public ActionResult actionMethod(string timeZoneName)
{
Session["timeZoneName"] = Convert.ToString(timeZoneName);
return Json(new { success = true });
}
App config app setting entries:
<add key ="Europe/London" value ="GMT Standard Time" />
Here the key is client time zone name returned by browser and maintained in session here, we have to add entries for all time zone
Place the below code in the controller action method to get the exam date:
var clientMachineTimeZoneName = Convert.ToString(Session["timeZoneName"]);
Get the sever timezone id from config for the corresponding time zone which we got from client side
var timeZoneId = ConfigurationManager.AppSettings[clientMachineTimeZoneName];
TimeZoneInfo clientTimezoneDetails = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
var clientTimeZoneOffsetMinutes = clientTimezoneDetails.GetUtcOffset(x.ExamDate.Value).TotalMinutes * -1;
var serverAndClientMachineTimeZoneDifferenceInMinutes = clientTimeZoneOffsetMinutes + TimeZoneInfo.Local.GetUtcOffset(x.ExamDate.Value).TotalMinutes;
//Update your date time field with this offset minutes
ExamDate = ExamDate.Value.AddMinutes(serverAndClientMachineTimeZoneDifferenceInMinutes);
In my case the server is in CST and I am in MST. I needed to persist my SQL Server data to the browser and was getting 02/08/18 23:57 as 02/08/18 22:57 on my Kendo Grid. So I did this, hope it helps:
Checks User / Browser's timezone offset
Gets difference in hours from server timezone offset
Looks at a column on the Kendo Grid with class .dbDate
Grabs the date in that cell (displayedTime) from data object
Uses Moment.js to Convert (convertedTime) it based on the difference (diff) in hours we pass it.
Formats convertedTime to desired format i.e. 02/08/18 23:57
Add 1 to i so the next date in the object gets adjusted
Passes the Grid back the updated date and time.
Must run last on page/grid load/update.
function getDateOffset() {
var date = new Date();
var offset;
var diff;
offset = date.getTimezoneOffset()
if (offset > 360) { //360 = CST
diff = +(offset - 360) / 60
} else if (offset < 360) {
diff = -(360 - offset) / 60
} else {
diff = 0
}
$(".dbDate").each(function (i) {
var grid = $('#Grid').data('kendoGrid');
var displayedTime = grid.dataSource.data()[i].TicketDateTime
var convertedTime = new moment(displayedTime).add(diff, 'hours').toDate();
var originalTime = moment(convertedTime).format("MM/DD/YY HH:mm");
i + 1
$(this).html(originalTime)
})
}
Outlook rules are putting all Facebook originating mail into a Facebook folder, an external process is running as detailed here to separate the contents of that folder in a way that was not feasible through Outlook rules process, originally I had this process running in VBA in outlook but it was a pig choking outlook resources. So I decided to throw it out externally and as I want to improve my c# skill set, this would be a conversion at the same time. Anyway the mail processing is working as it should items are going to correct sub-folders but for some reason the temporary constraint to exit after i number of iterations is not doing as it should. If there are 800 mails in the Facebook folder ( I am a member of many groups) it only runs through 400 iterations, if there are 30 it only processes 15 etc.
I cant for the life of me see why - can anyone put me right?
Thanks
private void PassFBMail()
{
//do something
// result = MsgBox("Are you sure you wish to run the 'Allocate to FB Recipient' process", vbOKCancel, "Hold up")
//If result = Cancel Then Exit Sub
var result = MessageBox.Show("Are you sure you wish to run the Are you sure you wish to run the 'Allocate to SubFolders' process","Sure?",MessageBoxButtons.OKCancel,MessageBoxIcon.Question,MessageBoxDefaultButton.Button2);
if (result == DialogResult.Cancel)
{
return;
}
try
{
OutLook._Application outlookObj = new OutLook.Application();
OutLook.MAPIFolder inbox = (OutLook.MAPIFolder)
outlookObj.Session.GetDefaultFolder(OutLook.OlDefaultFolders.olFolderInbox);
OutLook.MAPIFolder fdr = inbox.Folders["facebook"];
OutLook.MAPIFolder fdrForDeletion = inbox.Folders["_ForDeletion"];
// foreach (OutLook.MAPIFolder fdr in inbox.Folders)
// {
// if (fdr.Name == "facebook")
// {
// break;
// }
// }
//openFacebookFolder Loop through mail
//LOOPING THROUGH MAIL ITEMS IN THAT FOLDER.
Redemption.SafeMailItem sMailItem = new Redemption.SafeMailItem();
int i = 0;
foreach ( Microsoft.Office.Interop.Outlook._MailItem mailItem in fdr.Items.Restrict("[MessageClass] = 'IPM.Note'"))
{
//temp only process 500 mails
i++;
if (i == 501)
{
break;
}
// eml.Item = em
// If eml.To <> "" And eml.ReceivedByName <> "" Then
// strNewFolder = DeriveMailFolder(eml.To, eml.ReceivedByName)
// End If
sMailItem.Item = mailItem;
string strTgtFdr = null;
if (sMailItem.To != null && sMailItem.ReceivedByName != null)
{
strTgtFdr = GetTargetFolder(sMailItem.To, sMailItem.ReceivedByName );
}
// If fdr.Name <> strNewFolder Then
// If dDebug Then DebugPrint "c", "fdr.Name <> strNewFolder"
// eml.Move myInbox.Folders(strNewFolder)
// If dDebug Then DebugPrint "w", "myInbox.Folders(strNewFolder) = " & myInbox.Folders(strNewFolder)
// Else
// eml.Move myInbox.Folders("_ForDeletion")
// End If
if (fdr.Name != strTgtFdr)
{
OutLook.MAPIFolder destFolder = inbox.Folders[strTgtFdr];
mailItem.Move(destFolder);
}
else
{
mailItem.Move(fdrForDeletion);
}
}
//allocate to subfolders
//Process othersGroups
//Likes Max 3 per day per user, max 20% of group posts
//Comments one per day per user, max 10% of group posts
//Shares one per day per user, max 10% of group posts
}
catch(System.Exception crap)
{
OutCrap(crap);
MessageBox.Show("MailCamp experienced an issues while processing the run request and aborted - please review the error log","Errors during the process",MessageBoxButtons.OK,MessageBoxIcon.Error,MessageBoxDefaultButton.Button1);
}
}
Do not use a foreach loop it you are modifying the number of items in the collection.
Loop from MAPIFolder.Items.Count down to 1.
I am reading Sharepoint list data (>20000 entries) using Odata RESTful service as detailed here -http://blogs.msdn.com/b/ericwhite/archive/2010/12/09/getting-started-using-the-odata-rest-api-to-query-a-sharepoint-list.aspx
I am able to read data but I get only the first 1000 records. I also checked that List View Throttling is set to 5000 on sharepoint server. Kindly advise.
Update:
#Turker: Your answer is spot on!! Thank you very much. I was able to get the first 2000 records in first iteration. However, I am getting the same records in each iteration of while loop. My code is as follows-
...initial code...
int skipCount =0;
while (((QueryOperationResponse)query).GetContinuation() != null)
{
//query for the next partial set of customers
query = dc.Execute<CATrackingItem>(
((QueryOperationResponse)query).GetContinuation().NextLinkUri
);
//Add the next set of customers to the full list
caList.AddRange(query.ToList());
var results = from d in caList.Skip(skipCount)
select new
{
Actionable = Actionable,
}; Created = d.Created,
foreach (var res in results)
{
structListColumns.Actionable = res.Actionable;
structListColumns.Created= res.Created;
}
skipCount = caList.Count;
}//Close of while loop
Do you see a <link rel="next"> element at the end of the feed?
For example, if you look at
http://services.odata.org/Northwind/Northwind.svc/Customers/
you will see
<link rel="next" href="http://services.odata.org/Northwind/Northwind.svc/Customers/?$skiptoken='ERNSH'" />
at the end of the feed which means the service is implementing server side paging and you need to send the
http://services.odata.org/Northwind/Northwind.svc/Customers/?$skiptoken='ERNSH'
query to get the next set of results.
I don't see anything particularly wrong with your code. You can try to dump the URLs beign requested (either from the code, or using something like fiddler) to see if the client really sends the same queries (and thus getting same responses).
In any case, here is a sample code which does work (using the sample service):
DataServiceContext ctx = new DataServiceContext(new Uri("http://services.odata.org/Northwind/Northwind.svc"));
QueryOperationResponse<Customer> response = (QueryOperationResponse<Customer>)ctx.CreateQuery<Customer>("Customers").Execute();
do
{
foreach (Customer c in response)
{
Console.WriteLine(c.CustomerID);
}
DataServiceQueryContinuation<Customer> continuation = response.GetContinuation();
if (continuation != null)
{
response = ctx.Execute(continuation);
}
else
{
response = null;
}
} while (response != null);
I had the same problem, and wanted it to be a generic solution.
So I've extended DataServiceContext with a GetAlltems methode.
public static List<T> GetAlltems<T>(this DataServiceContext context)
{
return context.GetAlltems<T>(null);
}
public static List<T> GetAlltems<T>(this DataServiceContext context, IQueryable<T> queryable)
{
List<T> allItems = new List<T>();
DataServiceQueryContinuation<T> token = null;
EntitySetAttribute attr = (EntitySetAttribute)typeof(T).GetCustomAttributes(typeof(EntitySetAttribute), false).First();
// Execute the query for all customers and get the response object.
DataServiceQuery<T> query = null;
if (queryable == null)
{
query = context.CreateQuery<T>(attr.EntitySet);
}
else
{
query = (DataServiceQuery<T>) queryable;
}
QueryOperationResponse<T> response = query.Execute() as QueryOperationResponse<T>;
// With a paged response from the service, use a do...while loop
// to enumerate the results before getting the next link.
do
{
// If nextLink is not null, then there is a new page to load.
if (token != null)
{
// Load the new page from the next link URI.
response = context.Execute<T>(token);
}
allItems.AddRange(response);
}
// Get the next link, and continue while there is a next link.
while ((token = response.GetContinuation()) != null);
return allItems;
}