Like you see in this code, I want to get all the information about friends in twitter, people I follow.
But doing this :
PagableResponseList<User> users = twitter.getFriendsList(USER_ID, CURSOR);
... only gives me the first 20 recent friends... What can I do?
Complete code about it :
PagableResponseList<User> users = twitter.getFriendsList(USER_ID, CURSOR);
User user = null;
max = users.size();
System.out.println("Following: "+max);
for (int i = 0 ; i < users.size() ; i++){
user = users.get(i);
System.out.print("\nID: "+user.getId()+" / User: "+user.getName()+" /");
System.out.print("\nFollowers: "+user.getFollowersCount()+"\n");
tid.add(Long.parseLong(String.valueOf(user.getId())));
tusername.add(user.getName());
tfollowers.add(Long.parseLong(String.valueOf(user.getFollowersCount())));
tname.add(user.getScreenName());
}
Thanks..
you can try this code to get the list of people you follow.
long cursor = -1;
PagableResponseList<User> users;
while ((cursor = followers.getNextCursor()) != 0);
{
users = twitter.getFriendsList(userId, cursor);
}
I've taken a peek at the documentation at Twitter4J and Twitter themselves and it's all about that cursor.
To prevent you're getting loaded with a whole bunch of friends at once, Twitter only returns the first 20 results. It doesn't return just the first 20 results, but it also returns a cursor. That cursor is just a random number that's managed by Twitter. When you make a call again and pass this cursor, the next 20 entries (friends) will be returned, again with a cursor that's different now. You can repeat this until the cursor returned is zero. That means there are no more entries available.
In case you want to know more, check these two links: Twitter DEV and Twitter4J documentation.
Concerning your Java, you just need to find a way to get the current cursor, and pass that cursor to your method again, making the app load the next 20 entries. According to this piece of information, that should do the trick.
List<User> allUsers = new ArrayList<User>();
PagableResponseList<User> users;
long cursor = -1;
while (cursor != 0) {
users = twitter.getFriendsList(USER_ID, cursor);
cursor = users.getNextCursor();
allUsers.add(users);
}
You should be able to request up to 200 results at a time:
final PagableResponseList<User> users = twitter.getFriendsList(USER_ID, cursor, 200);
cursor = users.getNextCursor();
If you need to start from where you left off between invocations of your program then you need to store the value of cursor somewhere.
Improvements to Sander's answer!
You can set a count value to the getFriendsList method as in Jonathan's Answer. The maximum value allowed for count is 200. The loop construct will help to collect more than 200 friends now. 200 friends per page or per iteration!
Yet, there are rate limits for any request you make. The getFriendsList method will use this api endpoint: GET friends/list which has a rate limit of 15 hits per 15 minutes. Each hit can fetch a maximum of 200 friends which equates to a total of 3000 friends (15 x 200 = 3000) per 15 minutes. So, there will be no problem if you have only 3000 friends. If you have more than 3000 friends, an exception will be thrown. You can use the RateLimitStatus class to avoid that exception. The following code is an example implementation to achieve this.
Method 1: fetchFriends(long userId)
public List<User> fetchFriends(long userId) {
List<User> friends = new ArrayList<User>();
PagableResponseList<User> page;
long cursor = -1;
try {
while (cursor != 0) {
page = twitter.getFriendsList(userId, cursor, 200);
friends.addAll(page);
System.out.println("Total number of friends fetched so far: " + friends.size());
cursor = page.getNextCursor();
this.handleRateLimit(page.getRateLimitStatus());
}
} catch (TwitterException e) {
e.printStackTrace();
}
return friends;
}
Method 2: handleRateLimit(RateLimitStatus rls)
private void handleRateLimit(RateLimitStatus rls) {
int remaining = rls.getRemaining();
System.out.println("Rate Limit Remaining: " + remaining);
if (remaining == 0) {
int resetTime = rls.getSecondsUntilReset() + 5;
int sleep = (resetTime * 1000);
try {
if(sleep > 0) {
System.out.println("Rate Limit Exceeded. Sleep for " + (sleep / 1000) + " seconds..");
Thread.sleep(sleep);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
By doing so, your program will sleep for some time period based on the rate limiting threshold. It will continue to run from where it left after the sleep. This way we can avoid our program stopping in the midway of collecting friends counting more than 3000.
I have the solution to my post... thanks to Sander, give me some ideas...
The thing was change the for to while ((CURSOR = ids.getNextCursor()) != 0);.
And... user = twitter.showUser(id);
Playing with showUser makes it possible to get, with a slowly time, all the info about all my friends...
That's all. Don't use user.get(i);
Related
So i'm keeping a count on some pictures a user can visit, i want to make sure though that if they click refresh it does not increase the number of counts for that picture. The below code is causing my server to crash, and respond back with an error code 500.
HttpSession session = request.getSession() ;
Integer counter = (Integer) session.getAttribute("counter");
String accCount = (String) session.getAttribute("attributeKey") ;
if (accCount == null) { // New session?
response.sendRedirect("/techfore/WelcomePage");
}
if(counter == 0){
counter = new Integer(counter.intValue() + 1);
session.setAttribute("counter", counter);
}
I want to find items in a folder which are older than xx days and Delete all the items found in one shot.
I was able to find the items matching my criteria. here is my code.
import org.joda.time.DateTime;
int purgeDays = 14;
try {
ItemView view = new ItemView(Integer.MAX_VALUE);
Folder purgeFolder = Folder.bind(service, folderId);
// need to convert to get Mon Sep 12 16:31:27 CDT 2016
SearchFilter searchFilter = new SearchFilter.IsLessThanOrEqualTo(ItemSchema.DateTimeReceived, (DateTime.now().minusDays(purgeDays).toDate()));
FindItemsResults<Item> emailsToPurge = service.findItems(purgeFolder.getId(), searchFilter, view);
if (emailsToPurge != null && emailsToPurge.getItems() != null && emailsToPurge.getTotalCount() > 0 ) {
// want something to delete all items at once
emailsToPurge.deleteAll();
} else {
log.info("Found no emails to purge for Mailbox-"+ userName);
}
} catch (Exception e) {
log.error("Exception "+ e.getMessage());
}
Have a look at the deleteItems method on the ExchangeService class https://msdn.microsoft.com/en-us/library/microsoft.exchange.webservices.data.exchangeservice.deleteitems(v=exchg.80).aspx this allows you to send a batch DeleteItem request. I would suggest you page your deletes though at no more than 1000 items at a time else you may have issue with throttling and/or the requests timing out.
I'm trying to get a specific user's tweets into Processing and then have them spoken out using the TTS Library, but only have them spoken when a specific value is detected from Arduino over Serial = 491310
I've got the tweets coming into Processing and can have them printed and spoken, and the value 491310 is picked up by Processing, BUT it's the placement of the if Statement ( 'if (sensor == 491310) {') that I'm struggling with, as it currently has no effect - Can anyone solve this one?
Absolute novice here, any help would be great. Thanks.
import twitter4j.util.*;
import twitter4j.*;
import twitter4j.management.*;
import twitter4j.api.*;
import twitter4j.conf.*;
import twitter4j.json.*;
import twitter4j.auth.*;
import guru.ttslib.*;
import processing.serial.*;
TTS tts;
Serial myPort;
int sensor = 0;
void setup() {
tts = new TTS();
myPort = new Serial(this, Serial.list()[0], 9600);
}
void draw() {
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setOAuthConsumerKey("XXXX");
cb.setOAuthConsumerSecret("XXXX");
cb.setOAuthAccessToken("XXXX");
cb.setOAuthAccessTokenSecret("XXXX");
java.util.List statuses = null;
Twitter twitter = new TwitterFactory(cb.build()).getInstance();
String userName ="TWITTER HANDLE";
int numTweets = 19;
String[] twArray = new String[numTweets];
try {
statuses = twitter.getUserTimeline(userName);
}
catch(TwitterException e) {
}
if( statuses != null) {
for (int i=0; i<statuses.size(); i++) {
Status status = (Status)statuses.get(i);
if (sensor == 491310) {
println(status.getUser().getName() + ": " + status.getText());
tts.speak(status.getUser().getName() + ": " + status.getText());
}
}
}
}
void serialEvent (Serial myPort) {
int inByte = myPort.read();
sensor = inByte;
print(sensor);
}
Reading from a serial port returns a byte( 8 bit) not a 16 bit integer. The value of 'sensor" cannot be above 255 so never matches 491310. You'll have to do 2 reads to form the 16 bit int.
My guess is that you're hitting twitter's rate limit. Twitter only allows a certain amount of API calls in a given 15 minute window. And since you're calling getUserTimeline() in the draw() function (which happens 60 times per second), you're going to hit that limit pretty fast.
So you're probably getting a TwitterException, but you're just ignoring it. Never use an empty catch block! At least put a call to e.printStackTrace() in there:
catch(TwitterException e) {
e.printStackTrace();
}
To fix the problem, you're going to have to modify your code to only check for tweets once at the beginning of the program. Move all of your logic for fetching the tweets into the setup() function, and then move the logic for printing them out into the serialEvent() function.
If you still can't get it working, then you're going to have to do some debugging: what is the value of every single variable in your sketch? Use the println() function to help figure that out. Is statuses == null? What is the value of statuses.size()? What is the value of sensor? Once you know that, you'll be able to figure out exactly what's going wrong with your code. But my bet would be it's the twitter rate limit, so check that first.
I have issue keep throw error of unable to find the xpath , as i set the loop for opening this xpath to insert data . Although i set the time wait for existance to 60secound but it still couldn't find it. I been trying alot method calling this by using title or status hence it still not working . Kindly advise
HTML :
91.14
CODE :
public void clickOnItemTax () {
By xPath = By.xpath("//a[contains(#href,'edit_total_amt')]");
this.sleep(3);
if (this.waitForExistence(xPath,60)) {
WebElement domLink = linkGet(xPath);
domLink.click();
} else {
JLog.fail("Unable to find a writable item taxdialog!");
}
}
-waitforExistence
public boolean waitForExistence(By by, int timeoutSeconds){
boolean exists = false;
Long polling_interval = (long) 250;
Long timeout = (long) timeoutSeconds * 1000; // in seconds
Long elapsed = (long) 0;
while (elapsed <= (timeout)) {
if (exists(by)) {
exists = true;
break;
}
try {
Thread.sleep(polling_interval);
} catch (InterruptedException e) {
JLog.warning(JLog.getStackTraceAsString(e));
break;
}
elapsed += polling_interval;
}
if (elapsed >= timeout) {
JLog.warning("waitForExistence waited for " + timeout/1000 + " seconds, but unable to find: " + by.toString());
}
return exists;
}
Thanks you
If it's an internal company webpage could I suggest that you give the an 'id' to make your life easier. If not you can do this. I'm always surprised by people writing their own wait method when you could use either the implicit or explicit wait time in Selenium.
The former is as follows, the only thing to be aware using this method is that when looking for an element it will always wait this long. It is however a much safer way to write your scripts looking for elements and doesn't bloat your code:
driver.manage().timeouts().implicitlyWait(6, TimeUnit.SECONDS);
if (driver.findElements(By.cssSelector("//*[#title=\"Override total tax amount\"]")).size()!=0)
{
driver.findElement(By.cssSelector("//*[#title=\"Override total tax amount\"]")).click();
}
else
{
JLog.fail("Unable to find a writable item taxdialog!");
}
The explicit way to do it would be as follows where 10 is your seconds:
WebElement myDynamicElement = (new WebDriverWait(driver, 10))
.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("//*[#title=\"Override total tax amount\"]")));
See the following link for more on this.
http://docs.seleniumhq.org/docs/04_webdriver_advanced.jsp
I am reading UDP packets and i wanna display that info on UI as table in android app.
Here is my code,
try {
byte buffer[] = new byte[10000];<br/>
InetAddress address = InetAddress.getByName("192.168.xx.xx");<br/>
int port = xxx;<br/>
Log.d("..........","What will Happen ?? ");<br/>
for(int k=0;k<50;k++) { // 50 rows are added , This i wanna make it 5000+ rows so it takes plenty of time to load that table <br/>
DatagramPacket p = new DatagramPacket(buffer, buffer.length, address, port);<br/>
DatagramSocket ds = new DatagramSocket(port);<br/>
Log.d("..........","Perfect Binding .... Waiting for Data");<br/>
ds.receive(p);<br/>
Log.d("..........","Packet Received");<br/>
byte[] data = p.getData();<br/>
String result = "";<br/>
int b[] = new int[data.length];</br>
for (int i=0; i < 150; i++) {<br/>
result += Integer.toString( ( data[i] & 0xff ) + 0x100, 16).substring( 1 );<br/>
result += "_";<br/>
}<br/>
Log.d("Result => ",result); <br/>
TableLayout tl=(TableLayout)findViewById(R.id.TableLayout01);<br/>
TableRow tr=new TableRow(this);
TextView tv= new TextView(this);
TextView tv2 = new TextView(this);
tv.setPadding(5, 0, 5, 0);
tv2.setPadding(5,0,5,0);
String k1 = Integer.toString(k);
tv.setText(k1);
tv2.setText(it_version);
tr.addView(tv);
tr.addView(tv2);
tl.addView(tr,1);
ds.close();
}
} catch (Exception e) {
Log.e("UDP", "Client error", e);
}
If i keep 50 rows am able to display it properly without any time delay, if i put 3000 rows its taking too long time and sometimes app is hanging... I wanna add 50 entries to a table and load the table and again read 50 entries and append to the table without touching any button or anything so i have a table in UI and it will update automatically by reading UDP packets ... how i can achieve that ?? Any clue appreciated.
or once i read the UDP packet i wanna display it on UI[appending to the table],How i can do this ??[Scrolling and all i will take care] please let me know
I already tried using threads but no use
Basically, you need to implement an infinite listview. There are a couple strategies to do this:
You can get all the data and store it in a database and only show the user 50 at a time.
You can fetch only 50 at first and then fetch the next 50 when the user scrolls past them.
You can fetch 100, show 50 and then show next 50 when the user scrolls past the first 50. Pre-fetch the next 100 to show next and so on.
Once you figured out your fetching strategy, you need to implement the actual adapter and listview. Here's a good technique to do this. I would recommend that you don't re-invent the wheel and use this great library called EndlessAdapter unless you want to implement it for learning purposes.
Something like this is what you might use in order to get a infinite list effect when you don't have a cursor.
Please note this is a very rough draft since I deleted the code only relevant to my app, to help for you clarity, and for my privacy and the apps privacy. Also it may not be the best way of doing everything, but it worked the first time I wrote it (which took like 10 minutes) and worked beautifully for a very complex list, so I haven't bothered coming back to it.
class AsyncGetUpdates extends AsyncTask<Void, Void, List<UpdateDTO>>
{
#Override
protected void onPreExecute()
{
showDialog();
super.onPreExecute();
}
#Override
protected List<UpdateDTO> doInBackground(Void... params)
{
return APIHelper.getUpdates(count);
}
#Override
protected void onPostExecute(List<UpdateDTO> result)
{
killDialog();
isCurrentlyUpdating = false;
setAdapterData(result);
super.onPostExecute(result);
}
}
public void setAdapterData(List<UpdateDTO> result)
{
killDialog();
if (this != null && this.getActivity() != null)
{
Log.d(TAG, "setAdapterData");
if (lvUpdatesList.getAdapter() != null)
{
// save index and top position
int index = lvUpdatesList.getFirstVisiblePosition();
View v = lvUpdatesList.getChildAt(0);
int top = (v == null) ? 0 : v.getTop();
updateListAdapter = new UpdateListAdapter(this.getActivity().getLayoutInflater(), result, this);
lvUpdatesList.setAdapter(updateListAdapter);
lvUpdatesList.refreshDrawableState();
lvUpdatesList.setSelectionFromTop(index, top);
}
else
{
updateListAdapter = new UpdateListAdapter(this.getActivity().getLayoutInflater(), result, this);
lvUpdatesList.setAdapter(updateListAdapter);
lvUpdatesList.refreshDrawableState();
}
}
// add in a listener to know when we get to the bottom
lvUpdatesList.setOnScrollListener(new OnScrollListener()
{
#Override
public void onScrollStateChanged(AbsListView view, int scrollState)
{
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
{
// we do not want to update if we already are
if (isCurrentlyUpdating == false)
{
if (lvUpdatesList.getAdapter() != null && lvUpdatesList.getAdapter().getCount() == count)
{
final int lastItem = firstVisibleItem + visibleItemCount;
if (lastItem == totalItemCount)
{
isCurrentlyUpdating = true;
// add to the count of views we want loaded
count += 20;
// start a update task
new AsyncGetUpdates().execute();
}
}
}
}
});
}
Finally I would like to say that copy pasting might get you the results you want, but it will hinder you future ability. I would say study, read, learn, try, fail, and try again.