I'm trying to write a program that uses Imgur's API to download images based on an account name.
private volatile int threadCount;
private volatile double totalFileSize;
private volatile List<String> albums = new ArrayList<>();
private volatile Map<JSONObject, String> images = new HashMap<>();
private final ExecutorService executorService = Executors.newFixedThreadPool(100, (Runnable r) -> {
Thread t = Executors.defaultThreadFactory().newThread(r);
t.setDaemon(true);
return t;
});
private void downloadAlbums(List<String> albums) {
threadCount = 0;
albums.forEach((albumHash) -> {
if (hasRemainingRequests()) {
incThreadCount();
executorService.execute(() -> {
try {
String responseString;
String dirTitle;
String albumUrl = URL_ALBUM + albumHash;
String query = String.format("client_id=%s", URLEncoder.encode(CLIENT_ID, CHARSET));
URLConnection connection = new URL(albumUrl + "?" + query).openConnection();
connection.setRequestProperty("Accept-Charset", CHARSET);
InputStream response = connection.getInputStream();
try (Scanner scanner = new Scanner(response)) {
responseString = scanner.useDelimiter("\\A").next();
JSONObject obj = new JSONObject(responseString).getJSONObject("data");
dirTitle = obj.getString("title");
String temp = "";
// Get save path from a TextField somewhere else on the GUI
ObservableList<Node> nodes = primaryStage.getScene().getRoot().getChildrenUnmodifiable();
for (Node node : nodes) {
if (node instanceof VBox) {
ObservableList<Node> vNodes = ((VBox) node).getChildrenUnmodifiable();
for (Node vNode : vNodes) {
if (vNode instanceof DestinationBrowser) {
temp = ((DestinationBrowser) vNode).getDestination().trim();
}
}
}
}
final String path = temp + "\\" + formatPath(accountName) + "\\" + formatPath(dirTitle);
JSONArray arr = obj.getJSONArray("images");
arr.forEach((jsonObject) -> {
totalFileSize += ((JSONObject) jsonObject).getDouble("size");
images.put((JSONObject) jsonObject, path);
});
}
} catch (IOException ex) {
//
} catch (Exception ex) {
//
} finally {
decThreadCount();
if (threadCount == 0) {
Platform.runLater(() -> {
DecimalFormat df = new DecimalFormat("#.#");
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);// 714833218
alert.setHeaderText("Found " + images.size() + " images (" + (totalFileSize < 1000000000 ? df.format(totalFileSize / 1000000) + " MB)" : df.format(totalFileSize / 1000000000) + " GB)"));
alert.setContentText("Proceed with download and save images?");
Optional<ButtonType> alertResponse = alert.showAndWait();
if (alertResponse.get() == ButtonType.OK) {
progressBar.setTotalWork(images.size());
executorService.execute(() -> {
for (JSONObject obj : images.keySet()) {
(new File(images.get(obj))).mkdirs();
downloadImage(obj, images.get(obj));
}
});
}
});
}
}
});
}
});
}
albums is a List of codes that are required to send a GET request to Imgur in order to receive that album's images. The data returned is then used in another method which downloads the images themselves.
Now, all of this works fine, but when the program is making all the GET requests the JavaFX thread hangs (GUI becomes unresponsive). And after all the GET requests have been executed, the JavaFX thread stops hanging and the alert shows up with the correct information.
I just don't understand why the GUI becomes unresponsive when I'm not (I believe I'm not) blocking it's thread and I'm using an ExecutorService to do all the network requests.
Related
I am trying to fetch campaign,ad level information from Facebook Using Graph API.
Campaign level information is getting with zero error for all accounts.
But for the Ad Level info, I am not getting the entire data. The API returns only 50. Remaining ads are getting with an exception called "Internal Server Error".
I've been getting this problem all day for one particular account. Every other Account works fine.
Below is the HTTP response:
response = (okhttp3.Response) Response{protocol=http/1.1, code=500, message=Internal Server Error,
url=https://graph.facebook.com/v3.3/act_fbAccountId/ads?access_token=myAccessToken&fields=%5B%22account_id%22%2C%22campaign_id%22%2C%22adset_id%22%2C%22id%22%2C%22bid_amount%22%2C%22name%22%2C%22status%22%2C%22preview_shareable_link%22%5D&limit=25&after=QVFIUkFzZAVdONXEwMXc5NjlOWURwczRQN0V3QW12NndRa0I4ZAUxsSjNkZA0FTRHR1U1dnaTQ5MTh2QnJ3bzNwWkNPd21jbC1tbjRmZAF81WVBsc0txaERCMHVn}
Below is the code
public List facebookAdsSynchThroughJson(String accessTokens, Long advertAccId, Properties googleStructureProperties, byte isOnScheduler, String appSecret) {
this.access_tokens = accessTokens;
this.appSecret = appSecret;
APIContext context = new APIContext(accessTokens, appSecret).enableDebug(true);
List<FacebookAdsStructure> adsList = new ArrayList<>();
String ads = "";
JSONObject advertIdObj = null;
JSONArray dataList = null;
ObjectMapper mapper = null;
boolean cond = true;
boolean success = false;
int limitValue = 100;
try {
while (cond) {
try {
AdAccount adAccount = new AdAccount(advertAccId, context).get().execute();
List adsFields = new ArrayList();
adsFields.add("account_id");
adsFields.add("campaign_id");
adsFields.add("adset_id");
adsFields.add("id");
adsFields.add("bid_amount");
adsFields.add("name");
adsFields.add("status");
adsFields.add("preview_shareable_link");
Map<String, Object> adsmap = new HashMap<>();
adsmap.put("fields", adsFields);
adsmap.put("limit", limitValue);
ads = adAccount.getAds().setParams(adsmap).execute().getRawResponseAsJsonObject().toString();
} catch (APIException ex) {
LOGGER.info("Exception thrown when fetching ads for Account Id: " + advertAccId + " with limit value: " + limitValue);
LOGGER.error(ex);
if (limitValue > 6) {
cond = true;
limitValue = limitValue / 2;
} else {
cond = false;
success = false;
break;
}
}
if (!ads.isEmpty()) {
cond = false;
success = true;
}
}
if (success) {
advertIdObj = new JSONObject(ads);
dataList = advertIdObj.getJSONArray("data");
mapper = new ObjectMapper();
adsList = mapper.readValue(dataList.toString(), new TypeReference<List<FacebookAdsStructure>>() {
});
JsonObject obj;
JsonParser parser = new JsonParser();
JsonElement result = parser.parse(ads);
obj = result.getAsJsonObject();
int maxTries = 1;
if (obj.has("data") && maxTries <= 5) {
while (obj.has("paging") && maxTries <= 5) {
JsonObject paging = obj.get("paging").getAsJsonObject();
if (paging.has("cursors")) {
JsonObject cursors = paging.get("cursors").getAsJsonObject();
String before = cursors.has("before") ? cursors.get("before").getAsString() : null;
String after = cursors.has("after") ? cursors.get("after").getAsString() : null;
}
String previous = paging.has("previous") ? paging.get("previous").getAsString() : null;
String next = paging.has("next") ? paging.get("next").getAsString() : "empty";
if (!next.equalsIgnoreCase("empty")) {
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(5, TimeUnit.MINUTES)
.writeTimeout(5, TimeUnit.MINUTES)
.readTimeout(5, TimeUnit.MINUTES)
.build();
Request request1 = new Request.Builder().url(next).get().build();
Response response = client.newCall(request1).execute();
if (response.isSuccessful()) {
maxTries = 1;
ads = response.body().string();
advertIdObj = new JSONObject(ads);
dataList = advertIdObj.getJSONArray("data");
mapper = new ObjectMapper();
List<FacebookAdsStructure> adsLists = new ArrayList<>();
adsLists = mapper.readValue(dataList.toString(), new TypeReference<List<FacebookAdsStructure>>() {
});
adsList.addAll(adsLists);
LOGGER.info("Fetched the Ad Structure.." + adsList.size());
parser = new JsonParser();
result = parser.parse(ads);
obj = result.getAsJsonObject();
} else {
LOGGER.info("Exception in response when fetching ads for Account Id: " + advertAccId + " , error response message: " + response.message() + " and with limit value: " + limitValue);
maxTries++;
if (maxTries >= 6) {
break;
}
try {
LOGGER.info("Thread Sleeping For 2 Minutes - Started for fb se_account_id " + advertAccId + " and maxTries = " + maxTries);
Thread.sleep(120000);
LOGGER.info("Thread Sleeping For 2 Minutes - Completed for fb se_account_id " + advertAccId + " and maxTries = " + maxTries);
} catch (InterruptedException ex) {
Logger.getLogger(FacebookAccountStructureSyncThroughJson.class.getName()).log(Level.SEVERE, null, ex);
}
}
} else {
obj = new JsonObject();
}
}
}
}
} catch (JsonSyntaxException | IOException | JSONException ex) {
LOGGER.error(ex);
}
return adsList;
}
If anybody knows anything about this issue, please help me.
Recently, I review the kafka code and test. I found a strange case:
I print the bytebuffer on the entry of SocketServer processCompletedReceives, as well as print the value on the point of Log sotre as follows:
the entry of SocketServer
private def processCompletedReceives() {
selector.completedReceives.asScala.foreach { receive =>
try {
openOrClosingChannel(receive.source) match {
case Some(channel) =>
val header = RequestHeader.parse(receive.payload)
val connectionId = receive.source
val context = new RequestContext(header, connectionId, channel.socketAddress,
channel.principal, listenerName, securityProtocol)
val req = new RequestChannel.Request(processor = id, context = context,
startTimeNanos = time.nanoseconds, memoryPool, receive.payload, requestChannel.metrics)
if(header.apiKey() == ApiKeys.PRODUCE){
LogHelper.log("produce request: %v" + java.util.Arrays.toString(receive.payload.array()))
}
...
the point of Log
validRecords.records().asScala.foreach { record =>
LogHelper.log("buffer info: value " + java.util.Arrays.toString(record.value().array()))
}
but, the result of print is different. and record.value() is not what I passed in client value like this:
public void run() {
int messageNo = 1;
while (true) {
String messageStr = "Message_" + messageNo;
long startTime = System.currentTimeMillis();
if (isAsync) { // Send asynchronously
producer.send(new ProducerRecord<>(topic,
messageNo,
messageStr), new DemoCallBack(startTime, messageNo, messageStr));
} else { // Send synchronously
try {
producer.send(new ProducerRecord<>(topic,
messageNo,
messageStr)).get();
System.out.println("Sent message: (" + messageNo + ", " + messageStr + ")");
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
++messageNo;
}
}
the print result is not the not String messageStr = "Message_" + messageNo;
so what happend in the case.
done. I write the code as follows:
public class KVExtractor {
private static final Logger logger = LoggerFactory.getLogger(KVExtractor.class);
public static Map.Entry<byte[], byte[]> extract(Record record) {
if (record.hasKey() && record.hasValue()) {
byte[] key = new byte[record.key().limit()];
record.key().get(key);
byte[] value = new byte[record.value().limit()];
record.value().get(value);
System.out.println("key : " + new String(key) + " value: " + new String(value));
return new AbstractMap.SimpleEntry<byte[], byte[]>(key, value);
}else if(record.hasValue()){
// illegal impl
byte[] data = new byte[record.value().limit()];
record.value().get(data);
System.out.println("no key but with value : " + new String(data));
}
return null;
}
}
I am trying to build a plugin on cordova that can find the Bluetooth, USB and Network printer and print text, images, QR code, bar-codes... I have an issue in the network printer scanning, need some help with that. I have this code below that can search for the network printer connected to wifi. It works well with android 7 and 6 but in case of android 5, it is unable to return callback.This probably might be cause of the thread limit or something on android 5
scanWifi(ips, new OnIPScanningCallback() {
#Override
public void onScanningComplete(List<String> results) {
Log.d("TAG", "onScanningComplete: " + results.size()+" : "+results.toString());
Printers printerList =null;
for(String printerIps:results) {
String mac = getHardwareAddress(printerIps);
printerList = new Printers(printerIps, mac);
printers.put(printerIps);
list.add(printerList);
}
Log.d(TAGS,"The List of all wifi Printers : "+list);
}
});
isStart = false;
}
private static void scanWifi(final List<String> ips, final
OnIPScanningCallback callback) {
final Vector<String> results = new Vector<String>();
final int totalSize = ips.size();
final int splitSize = 10;
final int[] index = {0};
final long start = System.currentTimeMillis();
for (int i = 0; i < totalSize; i += splitSize) {
final List<String> child = new ArrayList<String>(ips.subList(i, Math.min(totalSize, i + splitSize)));
new Thread() {
#Override
public void run() {
for (String ip : child) {
Log.d("TAG", " scanning : " + index[0] + ", ip: " + ip);
boolean isPrinter = connect(ip);
if (isPrinter) {
results.add(ip);
}
if (index[0] == ips.size() - 1) {
long end = System.currentTimeMillis();
Log.d("TAG", "scanning time: " + (end - start) / 1000);
callback.onScanningComplete(results);
} else {
index[0]++;
}
}
}
}.start();
}
}
public interface OnIPScanningCallback {
void onScanningComplete(List<String> results);
}
I have also tried the async task and it works on all the versions of android but the problem is the process takes 170 to 193 secs which is way too long as in the above code it was able to do the same in 20 secs
scanWifi(ips, new PrintingPlugin.OnIPScanningCallback() {
#Override
public void onScanningComplete(List<String> results) {
Log.d(TAGS, "onScanningComplete: " + results.size() + " : " + results.toString());
Printers printerList;
for (String printerIps : results) {
String mac = getHardwareAddress(printerIps);
printerList = new Printers(printerIps, mac);
printers.put(printerIps);
list.add(printerList);
}
Log.d(TAGS, "The List of all wifi Printers : " + list);
}
});
isStart = false;
} catch (Exception e) {
Log.e(TAGS, "Error while scanning for wifi"+e.getMessage());
}
return printers;
}
private Integer index = 0;
void resetIndex() {
index = 0;
}
private void scanWifi(final List<String> ips, final PrintingPlugin.OnIPScanningCallback callback) {
Log.d(TAGS, " scanWifi" );
final Vector<String> results = new Vector<String>();
final int totalSize = ips.size();
final int splitSize = 10;
resetIndex();
final long start = System.currentTimeMillis();
for (int i = 0; i < totalSize; i += splitSize) {
final List<String> child = new ArrayList<String>(ips.subList(i, Math.min(totalSize, i + splitSize)));
executeTask(new AsyncTask() {
#Override
protected Object doInBackground(Object[] objects) {
synchronized (index) {
for (String ip : child) {
Log.d(TAGS, " scanning : " + index + ", ip: " + ip);
boolean isPrinter = connect(ip);
if (isPrinter) {
results.add(ip);
}
if (index == ips.size() - 1) {
long end = System.currentTimeMillis();
Log.d(TAGS, "scanning time: " + (end - start) / 1000);
callback.onScanningComplete(results);
} else {
index++;
}
}
}
return null;
}
});
}
public void executeTask(AsyncTask asyncTask) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
asyncTask.execute();
}
}
This is the message that I get when I run on android 5.
D/ConnectivityManager.CallbackHandler: CM callback handler got msg 524290
Any help to make this thing work in any way (the first code to work on android 5 or the second code to work faster and in an efficient way ) will be deeply appreciated. I have looked on the issues related to this but I don't want to use print services.
As the index value was the reason why the callback was not sent, so to solve it just sending the callback as soon as you discover the Network Printer and storing it in a var(JSONArray in my case ) will give you the list of the printers and its effective.
I have a problem if anyone can help,
I'm trying to get tweets done by a specific user, here's my code:
Paging pg = new Paging();
String userName = "Obama";
pg.setCount(200);
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setOAuthConsumerKey("");
cb.setOAuthConsumerSecret("");
cb.setOAuthAccessToken("");
cb.setOAuthAccessTokenSecret("");
Twitter twitter = new TwitterFactory(cb.build()).getInstance();
int numberOfTweets = 1000000;
long lastID = Long.MAX_VALUE;
ArrayList<Status> tweets = new ArrayList<Status>();
while (tweets.size () < numberOfTweets) {
tweets.addAll(twitter.getUserTimeline(userName,pg));
//System.out.println("Gathered " + tweets.size() + " tweets");
for (Status t: tweets) {
System.out.println(t.getUser().getName() + ": " + t.getText()+ " " );
};
pg.setMaxId(lastID-1);
}
System.out.println(tweets.size());
}
The problem is that the result is only the same results, the algorithm takes only the first few tweets from the timeline and makes them X time, and the profile has a million of tweets.
Can someone tell me how can I solve this problem please?
Thanks
Here is a way to do :
ArrayList<Status> statuses = new ArrayList<>();
int pageno = 1;
while(true) {
try {
System.out.println("getting tweets");
int size = statuses.size(); // actual tweets count we got
Paging page = new Paging(pageno, 200);
statuses.addAll(twitter.getUserTimeline(screenName, page));
System.out.println("total got : " + statuses.size());
if (statuses.size() == size) { break; } // we did not get new tweets so we have done the job
pageno++;
sleep(1000); // 900 rqt / 15 mn <=> 1 rqt/s
}
catch (TwitterException e) {
System.out.println(e.getErrorMessage());
}
} // while(true)
And you need a sleep function to respect rate limit :
static void sleep(long ms) {
try { Thread.sleep(ms); }
catch(InterruptedException ex) { Thread.currentThread().interrupt(); }
}
Reference : https://developer.twitter.com/en/docs/tweets/timelines/api-reference/get-statuses-user_timeline.html
I have to pass record to an UDF which calls an API but as we want to do it parallely,we are using spark and thats why UDF is being developed, the problem here is that that UDF needs to take only 100 records at a time not more than that, it can't handle more than 100 records parallely, so how to ensure that only 100 record pass to it in one go please note we don't want to use count() function on whole record.
I am attaching the UDF code here,it's a generic UDF which returns array of struct.moreover if we pass 100 records in batchsize variable each time then,if suppose there are 198 records then if as we dont want to use count() we will not be knowing that its last batchsize is going to be 98.so how to handle that thing.
Guys... I have a generic UDF in which call is made for an API but before calling it creates batch of 100 firstly then only call restapi.. So the argument UDF takes are x1:string, x2:string, batchsize:integer(currently the batchsize is 100)..so in UDF until and unless the batchsize is not 100 the call will not happen.. And for each record it will return null.
So till 99th record it will return. Null but at 100th record the call will happen
[So, now the problem part:as we are taking batchsize 100 and call will take place only at 100th record. So, in condition like if we have suppose 198 record in file then 100 record will get the output but, other 98 will only return null as they will not get processed..
So please help a way around, and UDF take one record at a time, but it keep on collecting till 100th record.. I hope this clears up
public class Standardize_Address extends GenericUDF {
private static final Logger logger = LoggerFactory.getLogger(Standardize_Address.class);
private int counter = 0;
Client client = null;
private Batch batch = new Batch();
public Standardize_Address() {
client = new ClientBuilder().withUrl("https://ss-staging-public.beringmedia.com/street-address").build();
}
// StringObjectInspector streeti;
PrimitiveObjectInspector streeti;
PrimitiveObjectInspector cityi;
PrimitiveObjectInspector zipi;
PrimitiveObjectInspector statei;
PrimitiveObjectInspector batchsizei;
private ArrayList ret;
#Override
public String getDisplayString(String[] argument) {
return "My display string";
}
#Override
public ObjectInspector initialize(ObjectInspector[] args) throws UDFArgumentException {
System.out.println("under initialize");
if (args[0] == null) {
throw new UDFArgumentTypeException(0, "NO Street is mentioned");
}
if (args[1] == null) {
throw new UDFArgumentTypeException(0, "No Zip is mentioned");
}
if (args[2] == null) {
throw new UDFArgumentTypeException(0, "No city is mentioned");
}
if (args[3] == null) {
throw new UDFArgumentTypeException(0, "No State is mentioned");
}
if (args[4] == null) {
throw new UDFArgumentTypeException(0, "No batch size is mentioned");
}
/// streeti =args[0];
streeti = (PrimitiveObjectInspector)args[0];
// this.streetvalue = (StringObjectInspector) streeti;
cityi = (PrimitiveObjectInspector)args[1];
zipi = (PrimitiveObjectInspector)args[2];
statei = (PrimitiveObjectInspector)args[3];
batchsizei = (PrimitiveObjectInspector)args[4];
ret = new ArrayList();
ArrayList structFieldNames = new ArrayList();
ArrayList structFieldObjectInspectors = new ArrayList();
structFieldNames.add("Street");
structFieldNames.add("city");
structFieldNames.add("zip");
structFieldNames.add("state");
structFieldObjectInspectors.add(PrimitiveObjectInspectorFactory.writableStringObjectInspector);
structFieldObjectInspectors.add(PrimitiveObjectInspectorFactory.writableStringObjectInspector);
structFieldObjectInspectors.add(PrimitiveObjectInspectorFactory.writableStringObjectInspector);
structFieldObjectInspectors.add(PrimitiveObjectInspectorFactory.writableStringObjectInspector);
StructObjectInspector si2 = ObjectInspectorFactory.getStandardStructObjectInspector(structFieldNames,
structFieldObjectInspectors);
ListObjectInspector li2;
li2 = ObjectInspectorFactory.getStandardListObjectInspector(si2);
return li2;
}
#Override
public Object evaluate(DeferredObject[] args) throws HiveException {
ret.clear();
System.out.println("under evaluate");
// String street1 = streetvalue.getPrimitiveJavaObject(args[0].get());
Object oin = args[4].get();
System.out.println("under typecasting");
int batchsize = (Integer) batchsizei.getPrimitiveJavaObject(oin);
System.out.println("batchsize");
Object oin1 = args[0].get();
String street1 = (String) streeti.getPrimitiveJavaObject(oin1);
Object oin2 = args[1].get();
String zip1 = (String) zipi.getPrimitiveJavaObject(oin2);
Object oin3 = args[2].get();
String city1 = (String) cityi.getPrimitiveJavaObject(oin3);
Object oin4 = args[3].get();
String state1 = (String) statei.getPrimitiveJavaObject(oin4);
logger.info("address passed, street=" + street1 + ",zip=" + zip1 + ",city=" + city1 + ",state=" + state1);
counter++;
try {
System.out.println("under try");
Lookup lookup = new Lookup();
lookup.setStreet(street1);
lookup.setCity(city1);
lookup.setState(state1);
lookup.setZipCode(zip1);
lookup.setMaxCandidates(1);
batch.add(lookup);
} catch (BatchFullException ex) {
logger.error(ex.getMessage(), ex);
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
/* batch.add(lookup); */
if (counter == batchsize) {
System.out.println("under if");
try {
logger.info("batch input street " + batch.get(0).getStreet());
try {
client.send(batch);
} catch (Exception e) {
logger.error(e.getMessage(), e);
logger.warn("skipping current batch, continuing with the next batch");
batch.clear();
counter = 0;
return null;
}
Vector<Lookup> lookups = batch.getAllLookups();
for (int i = 0; i < batch.size(); i++) {
// ListObjectInspector candidates;
ArrayList<Candidate> candidates = lookups.get(i).getResult();
if (candidates.isEmpty()) {
logger.warn("Address " + i + " is invalid.\n");
continue;
}
logger.info("Address " + i + " is valid. (There is at least one candidate)");
for (Candidate candidate : candidates) {
final Components components = candidate.getComponents();
final Metadata metadata = candidate.getMetadata();
logger.info("\nCandidate " + candidate.getCandidateIndex() + ":");
logger.info("Delivery line 1: " + candidate.getDeliveryLine1());
logger.info("Last line: " + candidate.getLastLine());
logger.info("ZIP Code: " + components.getZipCode() + "-" + components.getPlus4Code());
logger.info("County: " + metadata.getCountyName());
logger.info("Latitude: " + metadata.getLatitude());
logger.info("Longitude: " + metadata.getLongitude());
}
Object[] e;
e = new Object[4];
e[0] = new Text(candidates.get(i).getComponents().getStreetName());
e[1] = new Text(candidates.get(i).getComponents().getCityName());
e[2] = new Text(candidates.get(i).getComponents().getZipCode());
e[3] = new Text(candidates.get(i).getComponents().getState());
ret.add(e);
}
counter = 0;
batch.clear();
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return ret;
} else {
return null;
}
}
}