How can I modify this query to return all of a users followers as this only returns 20?
var friendship = await twitterCtx.Friendship.Where(f => f.Type == FriendshipType.FollowersList)
.Where(f => f.ScreenName == "JoeBloggs")
.SingleOrDefaultAsync();
if (friendship != null && friendship.Users != null)
friendship.Users.ForEach(friend =>
Console.WriteLine(
"ID: {0} Name: {1}",
friend.UserIDResponse, friend.ScreenNameResponse));
(I can see there is a Cursor property which is a long for paging results but I haven't been able to work out how to use it.)
From searching around and reading the Twitter API documentation about Rate Limits I have the following which is working fine:
public async Task<IEnumerable<ulong>> GetAllFollowers(string userID)
{
var allFollowerIds = new List<ulong>();
Friendship followers;
long cursor = -1;
do
{
try
{
followers =
await
(from follower in twitterCtx.Friendship
where follower.Type == FriendshipType.FollowerIDs &&
follower.UserID == userID &&
follower.Cursor == cursor &&
follower.Count == 5000
select follower)
.SingleOrDefaultAsync();
}
catch (TwitterQueryException tqe)
{
Console.WriteLine(tqe.ToString());
break;
}
if (followers != null &&
followers.IDInfo != null &&
followers.IDInfo.IDs != null)
{
cursor = followers.CursorMovement.Next;
allFollowerIds.AddRange(followers.IDInfo.IDs);
}
} while (cursor != 0);
return allFollowerIds;
}
This will return a maximum of 75,000 followers for a user authorized application. This is because there's a cap of 15 requests for this particular endpoint. You can make another batch of requests after 15 minutes has passed.
I haven't tried myself but if you need to pull down more followers then that for a particular user you should be able to do so by simply calling this method again with the last cursor value being fed in as the starting value.
Related
i am trying to get the records from the database using spring data jpa Speicification API.
here i need to put a condition for "In" clause for status column, for that i am code like below.
public static Specification<UserEntity> userSpecificationsforOperator(String orgName, String groupID,
List<String> status, Date startDate, Date endDate) {
return (root, query, builder) -> {
List<Predicate> predicates = new ArrayList<>();
if (orgName != null) {
Join<UserEntity, OrganizationEntity> organization = root.join("organization");
predicates.add(builder.equal(organization.get("name"), orgName));
}
/*
* if (groupID != null) {
* predicates.add(builder.equal(root.get("refApprovalGroupId"), groupID)); }
*/
if (status != null && status.size()>0) {
predicates.add(root.get("status").in(status));
}
if (startDate != null) {
predicates.add(builder.greaterThanOrEqualTo(root.get("createdDate"), startDate.toInstant()));
}
if (endDate != null) {
predicates.add(builder.lessThanOrEqualTo(root.get("createdDate"), endDate.toInstant()));
}
Predicate[] p = predicates.toArray(new Predicate[predicates.size()]);
return p.length == 0 ? null : p.length == 1 ? p[0] : builder.and(p);
};
}
the above code generating the query in cosole like below
SELECT userentity0_.id AS id1_68_,
userentity0_.created_by AS created_2_68_,
userentity0_.created_date AS created_3_68_,
userentity0_.last_modified_by AS last_mod4_68_,
userentity0_.last_modified_date AS last_mod5_68_,
userentity0_.group_id AS group_id6_68_,
userentity0_.group_name AS group_na7_68_,
userentity0_.is_enrollment_updated AS is_enrol8_68_,
userentity0_.is_federated AS is_feder9_68_,
userentity0_.name AS name10_68_,
userentity0_.organization_id AS organiz17_68_,
userentity0_.ref_approval_group_id AS ref_app11_68_,
userentity0_.reference_name AS referen12_68_,
userentity0_.status AS status13_68_,
userentity0_.uims_id AS uims_id14_68_,
userentity0_.user_status AS user_st15_68_,
userentity0_.version AS version16_68_
FROM user userentity0_
INNER JOIN organization organizati1_
ON userentity0_.organization_id = organizati1_.id
WHERE organizati1_.name ='utopia'
AND ( userentity0_.status =(?,?)
when i take the query into db tool and passing the values i am getting the data.
but while running from the application i am not getting the data.
here i understood that i am able to generate the query properly but my values are not passing correctly.
so could you please suggest how i can get my code return the data.
Maybe the implementation of it causes the issue...
Here, use this and let me know if it works
if (status != null && status.size()>0) {
predicates.add(builder.in(root.get("status")).value(status));
}
private IQueryable<Customer> FilterResult(string search, List<Customer> dtResult, List<string> columnFilters)
{
IQueryable<Customer> results = dtResult.AsQueryable();
results = results.Where(p =>
(
search == null ||
(
p.Name != null && p.Name.ToLower().Contains(search.ToLower())
|| p.City != null && p.City.ToLower().Contains(search.ToLower())
|| p.Postal != null && p.Postal.ToLower().Contains(search.ToLower())
|| p.Email != null && p.Email.ToLower().Contains(search.ToLower())
|| p.Company != null && p.Company.ToLower().Contains(search.ToLower())
|| p.Account != null && p.Account.ToLower().Contains(search.ToLower())
|| p.CreditCard != null && p.CreditCard.ToLower().Contains(search.ToLower())
)
)
&& (columnFilters[0] == null || (p.Name != null && p.Name.ToLower().Contains(columnFilters[0].ToLower())))
&& (columnFilters[1] == null || (p.City != null && p.City.ToLower().Contains(columnFilters[1].ToLower())))
&& (columnFilters[2] == null || (p.Postal != null && p.Postal.ToLower().Contains(columnFilters[2].ToLower())))
&& (columnFilters[3] == null || (p.Email != null && p.Email.ToLower().Contains(columnFilters[3].ToLower())))
&& (columnFilters[4] == null || (p.Company != null && p.Company.ToLower().Contains(columnFilters[4].ToLower())))
&& (columnFilters[5] == null || (p.Account != null && p.Account.ToLower().Contains(columnFilters[5].ToLower())))
&& (columnFilters[6] == null || (p.CreditCard != null && p.CreditCard.ToLower().Contains(columnFilters[6].ToLower())))
);
return results;
}
This is the method which I am using for datatable filter , Here my question is can I make it as generic ? I feel it can be using reflection. But does that affect to performance as well ?
thx in advance..
I have done till it so far :
private IQueryable<T> FilterResult<T>(string search, IQueryable<T> dtResult, List<string> columnFilters)
{
IQueryable<T> results = dtResult;
Type typeParameterType = typeof(T); // this will give me the class detail which I have passed
// 1 How to extract all property of this class to use in where clause
// 2 How I can use it either dynamic linq , foreach or any possible solution.
//1
PropertyInfo[] properties = typeParameterType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (var item in properties)
{
// This will be changed after some validation logic
string predicate = item.Name + " = " + search;
results = results.Where(predicate);
}
return results;
}
I'm not familiar (and don't intend to use) dynamic LINQ. In this case you don't really need such thing. As I said I would not pass in a list of string as column filters, it makes code longer and the order can matter and cause hard-to-debug issues. Here is the code I've just come up with, you can try and I'm not sure it works but if any please let me know:
private IEnumerable<T> FilterResult<T>(string search, IQueryable<T> dtResult, params ColumnFilter<T>[] filters)
{
var propGetters = typeof(T).GetProperties().Where(p => p.PropertyType == typeof(string))
.Select(p => new Func<object,string>((item) => ((p.GetValue(item, null) as string) ?? "").ToLower())).ToList();
if(!string.IsNullOrEmpty(search)) {
Func<T,bool> predicate = e => propGetters.Aggregate(false, (c,o) => c || o(e));
dtResult = dtResult.Where(predicate).AsQueryable();
}
return filters.Aggregate(dtResult.AsEnumerable(), (c,e) => c.Where(o => e.IsOK(o));
}
public class ColumnFilter<T> {
public ColumnFilter(Func<T,string> selector, string term = ""){
PropertySelector = selector;
Term = term;
}
public Func<T,string> PropertySelector {get;set;}
public string Term {get;set;}
public bool IsOK(T item) {
return PropertySelector(item).Contains(Term);
}
}
Usage:
FilterResult(yourSearch, yourDtResult, new ColumnFilter(e=>e.City, "someCitySearch"),
new ColumnFilter(e=>e.Postal, "somePostalSearch"), ...);
If you still want to stick to List for columnFilters, the code can be modified but it will be surely longer.
How can I apply changes to the first record in a table and add one or more additional records to the same table? I am getting the following exception:
An object with the same key already exists in the ObjectStateManager.
The ObjectStateManager cannot track multiple objects with the same key
See sample code below.
var Student = db.Student.Where(d => d.StudentID == studentID);
int count = 0;
if(Student != null)
{
foreach(var student in Student)
{
if (student.Id == id)
{
foreach (var assign in assignment)
{
if (assign != null && count == 0)
{
//How can I save the changes that is made to the first record here
assign.AssignmentId = student.AssignmentID;
db.Assignment.ApplyCurrentValues(assign);
}
if (assign != null && count > 0)
{
//How can I add new records here
assign.AssignmentId = student.AssignmentID;
db.Assignment.AddObject(assign);
}
count++;
}
}
}
}
Try calling save after this line i.e.
db.Assignment.ApplyCurrentValues(assign);
db.SaveChanges();
Then for your new entries:
var assignment = new Assignement() { AssignmentId = student.AssignmentID };
db.Assignments.Add(model);
db.SaveChanges();
I have the following in my Controller
var workshop = registerDB.Workshops.Single(w => w.WorkshopID == id);
ViewBag.Enrollments = registerDB.Carts.Where(x => x.Username.Equals(User.Identity.Name));
and this in my view
#{
//var carts = Model.Carts.Where(x => x.Username.Equals(User.Identity.Name));
var carts = ViewBag.Enrollments;
var timeSlot = Model.TimeSlot;
}
#{
foreach (var item in carts)
{
if (item != null)
{
if (timeSlot == item.Workshop.TimeSlot)
{
<h3>#timeSlot</h3>
}
}
else
{
<h3>Does not Exist</h3>
}
}
}
each time ViewBag.Enrollments = registerDB.Carts.Where(x => x.Username.Equals(User.Identity.Name)); returns no results, I get an error saying System.InvalidOperationException: There is already an open DataReader associated with this Command which must be closed first. and this line is highlighted
if (timeSlot == item.Workshop.TimeSlot)
Try calling .ToList() in the controller to eagerly fetch the results:
ViewBag.Enrollments = registerDB
.Carts
.Where(x => x.Username.Equals(User.Identity.Name))
.ToList();
You are checking that item != null but not that item.Workshop != null before trying to use it. It would appear that is perhaps the error, but why it's raising InvalidOperationException rather than NullReferenceException I don't know.
Try:
if (item != null && item.Workshop != null)
{
if (timeSlot == item.Workshop.TimeSlot)
{
<h3>#timeSlot</h3>
}
}
Could you put the single call in your model:
workshops workshop = registerDB.Workshops.Single(w => w.WorkshopID == id);
And then in your controller set the ViewBag:
try
{
ViewBag.Enrollments = workshop.Carts.Where(x => x.Username.Equals(User.Identity.Name));
}
catch
{
ViewBag.Enrollments = "There are no results";
}
i am building a site with a login page and want to prevent user from login after 5 try fails for 20 min
maybe one way is this
const int maxTryCount = 5;
const int minutesToSuspend = 20;
[HttpPost]
public ActionResult Index(PeopleAccount account, string returnUrl)
{
if (Session["TimeStamp"] == null || ((DateTime)Session["TimeStamp"]).AddMinutes(minutesToSuspend) <= DateTime.Now)
{
PeopleAccountService service = new PeopleAccountService();
DataSet ds = service.Authentication(account.UserName, account.Password, null, null);
if (ds.Tables[1].Rows.Count > 0)
{
FormsAuthentication.SetAuthCookie(account.UserName, false);
Session.Clear();
Session["UserAccressibility"] = ds.Tables[0];
Session["UserFullName"] = ds.Tables[1].Rows[0][0];
if (returnUrl != null && returnUrl.Length > 1 && returnUrl.StartsWith("/") && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
return Redirect(returnUrl);
return RedirectToAction("Index", "Stuff", null);
}
else
{
Session["TryCount"] = (Session["TryCount"] == null
|| (Session["TimeStamp"] != null && ((DateTime)Session["TimeStamp"]).AddMinutes(minutesToSuspend) <= DateTime.Now)) ?
1 : ((int)Session["TryCount"]) + 1;
if ((int)Session["TryCount"] > maxTryCount)
{
Session["TimeStamp"] = DateTime.Now;
return Redirect("~/UnauthorizedAccess/Index");
}
ModelState.AddModelError("", Paymankaran.Content.Messages.InvalidUsernameAndOrPassword);
ModelState.AddModelError("", string.Format(Paymankaran.Content.Messages.TryCountWarning,
Session["TryCount"], maxTryCount, minutesToSuspend));
return View();
}
}
return Redirect("~/UnauthorizedAccess/Index");
}
}
in fact i am using Session["TimeStamp"] and Session["TryCount"] variables to implement this functionality
is there a better or more secure way?
is this a good way to achieve this functionality?
Using Asp.net membership provider would give you this feature (and much more) for free.