Leading zero for outbound asterisk call - java

Hy all,
I am a newbie in asterisk so don't know much about it. I am currently tangled in an application which makes an outbound call. Previously it wasn't working due to some provisioning issues and then ANI was showing NULL value. But now it's working fine because I used setCallerID function of java.
The problem is that an outbound call is generated successfully to the users for a number say 123, but a leading zero '0' is attached to it and becomes '0123', I am assuming that '0' is for national number which asterisk attached as per defined in asterisk, and my required number is '123', which I want to change from the java code.
I searched a lot of forums/sites including the leading site of voip-info but didn't get success yet. I want to resolve it through java code if possible. Any help would be greatly appreciated.
Update:
Note:
asterisk version is 1.8 , chain ss7 is 2.1
extensions.conf
[gu]
exten =>007775,1,Answer(); this will answer the call
exten =>007775,2,Wait(1); will wait for 1 second
exten =>007775,3,NoOp(Call from ${CALLERID(all)})
exten =>007775,4,AGI(agi://localhost:4573/com.digitania.ivr.gu.domain.ServiceImplDelegate?uniqueId=${UNIQUEID}&isOutbound=${isOutbound}&msisdn=${MSISDN})
exten =>007775,5,Hangup(); end the call
My java code
private static final String PARAM_MSISDN = "MSISDN";
private static final String PARAM_ISOUTBOUND = "isOutbound";
private static final String EXTENSION = "007775";
private static final String CALLER_ID = "7775";
public static int callCount = 0;
public void call(String msisdn, CallListener listener) {
try {
{
OriginateAction originateAction = new OriginateAction();
originateAction.setChannel((new StringBuilder("SS7/").append(msisdn).toString()));
originateAction.setContext("gu");
originateAction.setPriority(new Integer(1));
originateAction.setExten(EXTENSION);
originateAction.setCallerId(CALLER_ID);
originateAction.setVariable(PARAM_MSISDN, msisdn);
originateAction.setVariable(PARAM_ISOUTBOUND, "true");
ManagerResponse originateResponse = managerConnection
.sendAction(originateAction, 30000L);
System.out.println((new StringBuilder("RESPONSE: \n")).append(
originateResponse.getResponse()).toString());
System.out.println(originateResponse.getMessage());
}
} catch (TimeoutException e) {
listener.callTimeOutException();
} catch (Exception e) {
e.printStackTrace();
}
callCount++;
}

It's been a while for me using libss7, but have you tried looking at these options in chan_dahdi.conf?
ss7_called_nai
ss7_calling_nai
ss7_internationalprefix
ss7_nationalprefix
ss7_subscriberprefix
ss7_unknownprefix
networkindicator
Playing a bit with them (and also talking to your provider) should allow you to send the correct numbers.
Hope it helps.

Related

View all comments on a YouTube video

I am trying to get all the comments on a YouTube video using a Java program. I cannot get them though as it has the "Show More" instead of all the comments. I'm looking for a way to get all the comments or pages of comments that I can go through. I have a video id and things, just need the comments.
I have tried all_comments instead of watch in the URL but it doesn't show all comments still and redirects to watch again.
I have also looked at the YouTube api and can only find how to get comments with their id but I need to get all comments from a video id.
If anyone knows how to do this please tell me.
I have added a 50 rep bounty for whoever can give me a good answer to this.
You need to get comment threads list request for your video and then scroll forward using next page token from the last response:
private static int counter = 0;
private static YouTube youtube;
public static void main(String[] args) throws Exception {
// For Auth details consider:
// https://github.com/youtube/api-samples/blob/master/java/src/main/java/com/google/api/services/samples/youtube/cmdline/Auth.java
// Also don't forget secrets https://github.com/youtube/api-samples/blob/master/java/src/main/resources/client_secrets.json
List<String> scopes = Lists.newArrayList("https://www.googleapis.com/auth/youtube.force-ssl");
Credential credential = Auth.authorize(scopes, "commentthreads");
youtube = new YouTube.Builder(Auth.HTTP_TRANSPORT, Auth.JSON_FACTORY, credential).build();
String videoId = "video_id";
// Get video comments threads
CommentThreadListResponse commentsPage = prepareListRequest(videoId).execute();
while (true) {
handleCommentsThreads(commentsPage.getItems());
String nextPageToken = commentsPage.getNextPageToken();
if (nextPageToken == null)
break;
// Get next page of video comments threads
commentsPage = prepareListRequest(videoId).setPageToken(nextPageToken).execute();
}
System.out.println("Total: " + counter);
}
private static YouTube.CommentThreads.List prepareListRequest(String videoId) throws Exception {
return youtube.commentThreads()
.list("snippet,replies")
.setVideoId(videoId)
.setMaxResults(100L)
.setModerationStatus("published")
.setTextFormat("plainText");
}
private static void handleCommentsThreads(List<CommentThread> commentThreads) {
for (CommentThread commentThread : commentThreads) {
List<Comment> comments = Lists.newArrayList();
comments.add(commentThread.getSnippet().getTopLevelComment());
CommentThreadReplies replies = commentThread.getReplies();
if (replies != null)
comments.addAll(replies.getComments());
System.out.println("Found " + comments.size() + " comments.");
// Do your comments logic here
counter += comments.size();
}
}
Consider api-samples, if you need a sample skeleton project.
Update
The situation when you can't get all the comments can be also caused by the quota limits (at least I faced it):
units/day 50,000,000
units/100seconds/user 300,000
This is not a java, python, js, or whatever language specific rules. If you want to get above the quota, you cant try to apply for higher quota. Though, I would start from controlling your throughput. It's very easy to get above the 100seconds/user quota.
try this it can download all the comments for a given video which i have tested.
https://github.com/egbertbouman/youtube-comment-downloader
python downloader.py --youtubeid YcZkCnPs45s --output OUT
Downloading Youtube comments for video: YcZkCnPs45s
Downloaded 1170 comment(s)
Done!
output is in the JSON format:
{
"text": "+Tony Northrup many thanks for the prompt reply - I'll try that.",
"time": "1 day ago",
"cid": "z13nfbog0ovqyntk322txzjamuensvpch.1455717946638546"
}

Robovm Local notifications not showing up. Scheduling seems successful. Am I missing something?

I am trying to get local/scheduled notifications working. With push messages (using Parse) working fine I though local would be easy, but even though the registration seems to go fine (didRegisterUserNotificationSettings is fired) and the scheduling seems to work too, the notification does not show up. I have tested on iOS 7 (iphone 4) and iOS 9 (iphone simulator). What am I missing?
here is my code:
#Override
public boolean didFinishLaunching(UIApplication application,UIApplicationLaunchOptions launchOptions)
{
boolean retval = super.didFinishLaunching(application, launchOptions);
//some other stuff happens here regarding parse push. But since this works I have cut it out
registerForPush();
return retval;
}
public void registerForPush()
{
if (IOSLauncher.getOSMajorVersion() >= 8)
{
UIUserNotificationType userNotificationTypes = UIUserNotificationType.with(UIUserNotificationType.Alert, UIUserNotificationType.Badge, UIUserNotificationType.Sound);
UIUserNotificationSettings settings = new UIUserNotificationSettings(userNotificationTypes, null);
application.registerUserNotificationSettings(settings);
application.registerForRemoteNotifications();
}
else
{
UIRemoteNotificationType type = UIRemoteNotificationType.with(UIRemoteNotificationType.Alert, UIRemoteNotificationType.Badge, UIRemoteNotificationType.Sound);
application.registerForRemoteNotificationTypes(type);
}
}
public void scheduleNotification(String title, String text, Date date, int ID)
{
UILocalNotification notification = new UILocalNotification();
if(getOSMajorVersion() >= 8 && getOSMinorVersion() >= 2)
notification.setAlertTitle(title);
notification.setAlertBody(text);
notification.setFireDate(new NSDate(date));
NSMutableDictionary<NSObject, NSObject> dict = new NSMutableDictionary<>();
dict.put("id",NSNumber.valueOf(ID));
notification.setUserInfo(dict);
UIApplication.getSharedApplication().scheduleLocalNotification(notification);
}
Edit:
After settting the notification it is present in the array returned by:
UIApplication.getSharedApplication.getScheduledLocalNotifications();
The problem was resolved after Adding:
notification.setTimeZone(NSTimeZone.getLocalTimeZone());
and setting the expire time of my test timer from 1 minute to 5 minutes
I'm not sure which is the actual solution, but the problem is gone, so I'm happy!
EDIT:
UILocalNotification notification = new UILocalNotification();
notification.setAlertTitle("title");
notification.setAlertBody("text");
NSMutableDictionary<NSObject, NSObject> dict = new NSMutableDictionary<>();
//add any customer stuff to your dictionary here
notification.setUserInfo(dict);
notification.setFireDate(new NSDate(date)); //date is some date in the future. Make sure it is in the correct TZ. If it does not work, try to make it at least 5 minutes in the future. I remember this helping my situation
notification.setTimeZone(NSTimeZone.getLocalTimeZone());
UIApplication.getSharedApplication().scheduleLocalNotification(notification);

Strange behaviour with indexOf method

We have deployed our Java EE web application in jboss 4.0.2 (we are using JDK 1.6.0_18).
In our code we are iterating through the Collection and doing string concatenation of userids in collection (refer below code).
On production server, it behaves inconsistently. The userid (2044157) is not found in final string (refer ServerLog line3). If we restart the production jboss server, then it works perfectly fine and it prints all users correctly in final string log. But the problem again reappears after heavy usage (after 5-6 hours). We are not able to replicate the issue on our QA environment.
When problem happens, Looks like the indexOf method incorrectly returns that 2044157 is there in strUsers string (even though 2044157 is not there) and hence it goes into else part and printed it in else part log(refer ServerLog line2 - highlighted in bold font). What could be reason for such inconsistent behavior?
Code:
public class UsersEJB implements SessionBean{
private void processSelectionData{
StringBuilder strUsers = new StringBuilder("");
Collection userVoCollection = dc.retProjectOrgUsers(projectID, strDistributionCompID, porjectDataSource); // This is returning List of 626 UserVO
if(log.isDebugEnabled())
log.debug("UserList Size="+userVoCollection.size()+",B4 strUsers="+strUsers.toString());
Iterator it = userVoCollection.iterator();
while(it.hasNext()) {
UserVO uVO = (UserVO)it.next();
if(!(strUsers.toString().indexOf("," + uVO.userID.toString() + ",") > -1)) {
strUsers.append(uVO.userID.toString()).append(",");
loopCntPos++;
} else {
loopCntNeg++;
if(log.isDebugEnabled())
log.debug("UserId="+uVO.userID.toString()+",strUsers="+loopCnt+"="+strUsers.toString());
}
loopCnt++;
}
if(log.isDebugEnabled())
log.debug("COMPANIES_ID1 strUsers="+strUsers.toString() + ",### loopCnt="+loopCnt + ",loopCntPos="+loopCntPos + ",loopCntNeg="+loopCntNeg);
}
}
ServerLog
UserList Size=626,B4 strUsers=,1732286,2066065,2096854,1952590,1731333,1732065,1734828,1852547,1732020,1733653,1731278,2079012,1733299,1765873,1733431,1960010,1828681,2047672,1731752,1733172,1784314,1989311,1734795,1732658,1731415,1785285,1785185,1738446,1733139,1732526,1733549,1731078,1804055,1732939,1663167,1732768,1732029,1732504,1989185,1882746,1785428,1731213,1732931,1731296,1733503,1753435,1731667,1936166,1747699,2099764,1482144,1747707,1732953,1771653,1731251,1989303,1755297,1731160,1901283,1782751,1733543,1882693,1733354,1974270,2044300,1732082,1907188,1731872,1955156,1732153,1733260,1731096,1604035,1731914,1731169,1732418,1731240,1989180,1731306,1733533,1882684,1821306,1731178,1731389,1733309,1733104,2078768,1989277,1732542,1733513,1733082,1732630,1733289,1733361,2077522,1733252,1732493,1978847,1733071,
UserId=2044157,strUsers=440=,1732286,2066065,2096854,1952590,1731333,1732065,1734828,1852547,1732020,1733653,1731278,2079012,1733299,1765873,1733431,1960010,1828681,2047672,1731752,1733172,1784314,1989311,1734795,1732658,1731415,1785285,1785185,1738446,1733139,1732526,1733549,1731078,1804055,1732939,1663167,1732768,1732029,1732504,1989185,1882746,1785428,1731213,1732931,1731296,1733503,1753435,1731667,1936166,1747699,2099764,1482144,1747707,1732953,1771653,1731251,1989303,1755297,1731160,1901283,1782751,1733543,1882693,1733354,1974270,2044300,1732082,1907188,1731872,1955156,1732153,1733260,1731096,1604035,1731914,1731169,1732418,1731240,1989180,1731306,1733533,1882684,1821306,1731178,1731389,1733309,1733104,2078768,1989277,1732542,1733513,1733082,1732630,1733289,1733361,2077522,1733252,1732493,1978847,1733071,1893797,2137701,2025815,1522850,2027582,1732833,1984513,2037965,1900381,1731514,2044357,2042751,1785407,2118267,2050509,2062445,1934909,1912411,1733673,1731956,1694916,1731951,2048024,1735552,2115155,1732777,2120796,2048007,1845970,1738356,1841988,2101099,2027667,2067876,1734628,1731739,1731893,2051612,1819645,1803654,2037906,1732047,1478544,2073677,2012435,2067977,2073669,1981390,1731124,15916,6766,1978916,1732750,1936298,1891936,1747650,1949484,2101161,1928883,1948164,2013726,1750718,1732164,1733700,1639298,1734968,1732007,1734723,1949403,2137692,1990151,1734617,2101130,1928888,2044163,1732042,1819543,2137672,1735463,1732716,1950975,2025826,1984507,2017645,1372949,1928719,1732684,1952358,1581015,2026878,1731622,1734036,2000528,1734611,2052691,1961286,2107121,1733335,1868846,2000469,1734771,1841953,2118224,2038924,1731609,1735396,2026033,1805573,2107214,1638397,1731502,1731581,2115171,2120903,1892076,2060862,2017603,2002514,1731351,1901274,1760679,1821298,1884485,1777244,1731204,1934917,2000497,1737101,2115043,2121909,2097818,1506144,1953947,1753401,1594875,2135263,1900276,1907168,1851867,1940057,1897000,1765857,2037953,1907085,2037911,2062548,1650062,1801180,1953696,2119602,1605403,1804076,1669286,1844334,1542596,2048001,1938656,1757959,1529666,2070447,1565121,1907065,1944060,2097808,2077490,1843170,1957289,1690800,1823148,1788987,1912477,1738344,1845866,2047996,1962156,1483244,2071932,2127277,1912419,1756748,1999518,1908161,1722312,1548164,1584044,2047896,1856844,1762432,2073439,1861949,1530755,1989292,1852455,2027658,1738380,2067996,1981507,1998543,1958859,1620837,1852555,2012357,1895444,2050380,1789210,1932156,1898948,2046841,2098171,1625335,2138533,2046655,1785464,2105080,2024935,1852446,2073682,1478644,2103660,1751154,1863254,1478332,1849259,1593399,1895334,2075182,2134365,2136657,
COMPANIES_ID1 strUsers=,1732286,2066065,2096854,1952590,1731333,1732065,1734828,1852547,1732020,1733653,1731278,2079012,1733299,1765873,1733431,1960010,1828681,2047672,1731752,1733172,1784314,1989311,1734795,1732658,1731415,1785285,1785185,1738446,1733139,1732526,1733549,1731078,1804055,1732939,1663167,1732768,1732029,1732504,1989185,1882746,1785428,1731213,1732931,1731296,1733503,1753435,1731667,1936166,1747699,2099764,1482144,1747707,1732953,1771653,1731251,1989303,1755297,1731160,1901283,1782751,1733543,1882693,1733354,1974270,2044300,1732082,1907188,1731872,1955156,1732153,1733260,1731096,1604035,1731914,1731169,1732418,1731240,1989180,1731306,1733533,1882684,1821306,1731178,1731389,1733309,1733104,2078768,1989277,1732542,1733513,1733082,1732630,1733289,1733361,2077522,1733252,1732493,1978847,1733071,1893797,2137701,2025815,1522850,2027582,1732833,1984513,2037965,1900381,1731514,2044357,2042751,1785407,2118267,2050509,2062445,1934909,1912411,1733673,1731956,1694916,1731951,2048024,1735552,2115155,1732777,2120796,2048007,1845970,1738356,1841988,2101099,2027667,2067876,1734628,1731739,1731893,2051612,1819645,1803654,2037906,1732047,1478544,2073677,2012435,2067977,2073669,1981390,1731124,15916,6766,1978916,1732750,1936298,1891936,1747650,1949484,2101161,1928883,1948164,2013726,1750718,1732164,1733700,1639298,1734968,1732007,1734723,1949403,2137692,1990151,1734617,2101130,1928888,2044163,1732042,1819543,2137672,1735463,1732716,1950975,2025826,1984507,2017645,1372949,1928719,1732684,1952358,1581015,2026878,1731622,1734036,2000528,1734611,2052691,1961286,2107121,1733335,1868846,2000469,1734771,1841953,2118224,2038924,1731609,1735396,2026033,1805573,2107214,1638397,1731502,1731581,2115171,2120903,1892076,2060862,2017603,2002514,1731351,1901274,1760679,1821298,1884485,1777244,1731204,1934917,2000497,1737101,2115043,2121909,2097818,1506144,1953947,1753401,1594875,2135263,1900276,1907168,1851867,1940057,1897000,1765857,2037953,1907085,2037911,2062548,1650062,1801180,1953696,2119602,1605403,1804076,1669286,1844334,1542596,2048001,1938656,1757959,1529666,2070447,1565121,1907065,1944060,2097808,2077490,1843170,1957289,1690800,1823148,1788987,1912477,1738344,1845866,2047996,1962156,1483244,2071932,2127277,1912419,1756748,1999518,1908161,1722312,1548164,1584044,2047896,1856844,1762432,2073439,1861949,1530755,1989292,1852455,2027658,1738380,2067996,1981507,1998543,1958859,1620837,1852555,2012357,1895444,2050380,1789210,1932156,1898948,2046841,2098171,1625335,2138533,2046655,1785464,2105080,2024935,1852446,2073682,1478644,2103660,1751154,1863254,1478332,1849259,1593399,1895334,2075182,2134365,2136657,2041203,2043944,2040358,2093521,1913544,2082455,2024959,2045812,1973980,1494485,1986446,1525605,2046849,1785194,1822210,2053401,1918823,2001794,1785258,2064339,1986338,1710198,1521244,1822292,1931276,2134370,2075073,2134300,2075068,1521210,2131493,1951008,1914649,1774999,1601557,1485584,2078975,1986330,1612190,2064410,2066054,1985760,1685075,1930273,2032161,1955161,,### loopCnt=626,loopCntPos=274,loopCntNeg=352
As it stands, your search won't pick up the first user as there won't be a preceding comma. However, I would suggest solving the problem in a far simpler manner, by using a set:
public class UsersEJB implements SessionBean
{
private void processSelectionData
{
Collection userVoCollection = dc.retProjectOrgUsers(projectID, strDistributionCompID, porjectDataSource); // This is returning List of 626 UserVO
Set<String> usersSet = new HashSet<String>(userVoCollection.size());
if(log.isDebugEnabled())
log.debug("UserList Size="+userVoCollection.size()+",B4 strUsers="+strUsers.toString());
for (UserVO uVO : userVoCollection)
{
if (usersSet.add(uVO.userID.toString())
loopCntPos++;
else
{
loopCntNeg++;
if(log.isDebugEnabled())
log.debug("UserId="+uVO.userID.toString()+",strUsers="+loopCnt+"="+strUsers.toString());
}
if(log.isDebugEnabled())
log.debug("COMPANIES_ID1 strUsers=" + usersSet + ",### loopCnt="+loopCnt + ",loopCntPos="+loopCntPos + ",loopCntNeg="+loopCntNeg);
}
}

Android-Magento- How to Get the Details of Multiple Products in Android using XML-RPC

How to get the details of Multiple products in a Single Call in Android using XMLRPC from Magento.I am able to get the list of products using the function catalog_product.list using XMLRPC.
Now, i have the SKU id's of all the products.I am able to get the media details of each product using the function product_media.list.
If suppose I have 10 products,i have to call 10 times product_media.list method for each product which takes long time.
So,how can I call the multiCall function of Magento in Android. Many tutorials in php for calling the multiCall function are posted but I am not able to imitate the same in Android.
So please help me if you have similar code snippet that can make me understand multiCall function(for Android) so that I can Advance further using that.
Thanks.
PHP code Example from Josua Marcel C 's Answer:
$session = $client->call('login', array('apiUser', 'apiKey'));
$client->call('call', array($session,'somestuff.method', array('arg1', 'arg2', 'arg3')));
$client->call('call', array($session, 'somestuff.method', 'arg1'));
$client->call('call', array($session, 'somestuff.method'));
$client->call('multiCall',
array($session,
array(
array('somestuff.method', 'arg1'),
array('somestuff.method', array('arg1', 'arg2')),
array('somestuff.method')
)
)
);
I would like to imitate the above php code in Android that calls the multiCall() function of the Magento.
After making long long Research, I got half-way Solution that calls the multiCall() method without any Error,but Still I don't know how to get the response of the Server in a variable and use it.
AnyOne who has knowledge of it can Edit my Answer, I will be thankful to him.
The Code that I have Used is :
Object[] skuid=new Object[product_list.size()];
Object calling[]=new Object[product_list.size()];
for(int m=0;m<product_list.size();m++)
{
skuid[m]=new Object[]{product_list.get(m).getp_Sku()};
calling[m]=new Object[]{"catalog_product_attribute_media.list",skuid[m]};
}
try
{
client.callEx("multiCall",new Object[]{Utils.sessionId,calling});
}
catch (XMLRPCException e)
{
e.printStackTrace();
}
AcknowledgeMents :
I have worked on the Answer posted by Iain.
The Answer
since android is based java application, You can use this.
package org.apache.xmlrpc;
import java.util.Hashtable;
import java.util.Vector;
public class MultiCall
implements ContextXmlRpcHandler
{
public Object execute(String method, Vector params, XmlRpcContext context)
throws Exception
{
if ("multicall".equals(method))
{
return multicall(params, context);
}
throw new NoSuchMethodException("No method '" + method + "' in " + this.getClass().getName());
}
public Vector multicall(Vector requests, XmlRpcContext context)
{
// The array of calls is passed as a single parameter of type array.
requests=(Vector)requests.elementAt(0);
Vector response = new Vector();
XmlRpcServerRequest request;
for (int i = 0; i < requests.size(); i++)
{
try
{
Hashtable call = (Hashtable) requests.elementAt(i);
request = new XmlRpcRequest((String) call.get("methodName"),
(Vector) call.get("params"));
Object handler = context.getHandlerMapping().getHandler(request.getMethodName());
Vector v = new Vector();
v.addElement(XmlRpcWorker.invokeHandler(handler, request, context));
response.addElement(v);
}
catch (Exception x)
{
String message = x.toString();
int code = (x instanceof XmlRpcException ?
((XmlRpcException) x).code : 0);
Hashtable h = new Hashtable();
h.put("faultString", message);
h.put("faultCode", new Integer(code));
response.addElement(h);
}
}
return response;
}
}
Source
Since Magento support SOAP API why didn't you use SOAP API v1? because SOAP is powerful. try to go here What's the difference between XML-RPC and SOAP?
Parsing of Soap messages is not included in Android runtime, so it isn't really straightforward. You should use an external library. I'm using ksoap2.
If you search here on StackOverflow you'll see many examples on how to use it. For instance here
more references: link 1 link 2
MultiCall with PHP
$client = new Zend_XmlRpc_Client('http://magentohost/api/xmlrpc/');
// If somestuff requires api authentification,
// we should get session token
$session = $client->call('login', array('apiUser', 'apiKey'));
$client->call('call', array($session, 'somestuff.method', array('arg1', 'arg2', 'arg3')));
$client->call('call', array($session, 'somestuff.method', 'arg1'));
$client->call('call', array($session, 'somestuff.method'));
$client->call('multiCall', array($session,
array(
array('somestuff.method', 'arg1'),
array('somestuff.method', array('arg1', 'arg2')),
array('somestuff.method')
)
));
// If you don't need the session anymore
$client->call('endSession', array($session));
First login in whatever way works for calling catalog_product.list. Make sure session, client and product_ids have the right values. If you don't need to log in for these operations, set session = null (and if that doesn't work, try not passing session at all :) ). Then:
Object[][] calls = new Object[product_ids.length];
for (int i = 0; i < product_ids.length; i++) {
calls[i] = new Object[] { "product_media.list", product_ids[i] };
}
product_media_ids = client.call("multiCall", new Object[] { session, calls });
product_media_ids should then be an array of arrays of product images - that is, each element of product_media_ids will be a return value from product_media.list.
The code is untested, I'm afraid.

YouTube API too_long error code on short keywords?

I feel really silly to not be able to find this answer anywhere. Could someone please direct me to a place or inform me of what the YouTube limits are with regard to keywords?
I found that the limit was once 120 characters, but then I heard it changed in March 2010 to 500 characters so it shouldn't be a problem for me if that's true. It's possible I have another problem on my hands. Maybe someone could help me with that one...
I'm using the YouTube API for Java using direct upload from a client based application. I have tons of videos I'm trying to upload to several different accounts at once (each in a different language). So I'm using threads to accomplish this. I limit the number of concurrent uploads to 10 just to try and play it safe. None of the descriptions will be much longer than 500 characters and because of this error I'm getting, I had the keywords automatically limit themselves to 120 characters (I even tried to limit it to 70 characters and had the same problem). So, I'm not sure at all why this is happening. The error I get from Google is:
SEVERE: null
com.google.gdata.util.InvalidEntryException: Bad Request
<?xml version='1.0' encoding='UTF-8'?>
<errors>
<error>
<domain>yt:validation</domain>
<code>too_long</code>
<location type='xpath'>media:group/media:keywords/text()</location>
</error>
</errors>
I'm also getting an InvalidEntryException as an error code, but I'll deal with that later (I think it has to do with my authentication timing out or something).
Anyway, I don't get this error on every video. In fact, most videos make it just fine. I haven't yet tested to find out which videos are throwing the error (I will do that when I'm finished with this post), but it's beyond me why I'm getting this error. I'll post my code here, but it's pretty much exactly what's on the api documentation, so I don't know whether it'll be much help. I'm guessing there's something fundamental I'm missing.
uploadToYouTube():
private void uploadToYouTube() throws IOException, ServiceException {
TalkContent talkContent = transfer.getTalkContent();
YouTubeService youTubeService = talkContent.getLanguage().getYouTubeService(); //see code for this below...
String title = talkContent.getTitle();
String category = talkContent.getCategory();
String description = talkContent.getDescription();
List<String> tags = talkContent.getTags();
boolean privateVid = true;
VideoEntry newEntry = new VideoEntry();
YouTubeMediaGroup mg = newEntry.getOrCreateMediaGroup();
//Title
mg.setTitle(new MediaTitle());
mg.getTitle().setPlainTextContent(title);
//Description
mg.setDescription(new MediaDescription());
mg.getDescription().setPlainTextContent(description);
//Categories and developer tags
mg.addCategory(new MediaCategory(YouTubeNamespace.CATEGORY_SCHEME, category));
mg.addCategory(new MediaCategory(YouTubeNamespace.DEVELOPER_TAG_SCHEME, "kentcdodds"));
mg.addCategory(new MediaCategory(YouTubeNamespace.DEVELOPER_TAG_SCHEME, "moregoodfoundation"));
//Keywords
mg.setKeywords(new MediaKeywords());
int tagLimit = 70; // characters
int totalTags = 0; //characters
for (String tag : tags) {
if ((totalTags + tag.length()) < tagLimit) {
mg.getKeywords().addKeyword(tag);
totalTags += tag.length();
}
}
//Visible status
mg.setPrivate(privateVid);
//GEO coordinantes
newEntry.setGeoCoordinates(new GeoRssWhere(40.772555, -111.892480));
MediaFileSource ms = new MediaFileSource(new File(transfer.getOutputFile()), transfer.getYouTubeFileType());
newEntry.setMediaSource(ms);
String uploadUrl = "http://uploads.gdata.youtube.com/feeds/api/users/default/uploads";
VideoEntry createdEntry = youTubeService.insert(new URL(uploadUrl), newEntry);
status = Transfer.FINISHEDUP;
}
getYouTubeService():
public YouTubeService getYouTubeService() {
if (youTubeService == null) {
try {
authenticateYouTube();
} catch (AuthenticationException ex) {
JOptionPane.showMessageDialog(null, "There was an authentication error!" + StaticClass.newline + ex, "Authentication Error", JOptionPane.ERROR_MESSAGE);
Logger.getLogger(Language.class.getName()).log(Level.SEVERE, null, ex);
}
}
return youTubeService;
}
authenticateYouTube():
public void authenticateYouTube() throws AuthenticationException {
if (youTubeService == null) {
System.out.println("Authenticating YouTube Service");
youTubeService = new YouTubeService("THENAMEOFMYPROGRAM", "THEDEVELOPERIDHERE");
youTubeService.setUserCredentials(youTubeUsername, youTubePassword);
System.out.println("Authentication of YouTube Service succeeded");
}
}
Any help on this would be great! Also, before I call the uploadToYouTube() method, I print out that the video's being uploaded to YouTube and after the method call I print out that it finished. Can someone explain why those are printed out within moments of one another? I'm not starting a new thread for the uploadToYouTube() method, I'm guessing that in the insert() method on the youTubeService there's a new thread started for the upload. It's a little annoying though because I'm never quite sure at what point the video finishes uploading and if I stop the program before it's through then the video stops uploading.
Anyway! Thanks for reading all of this! I hope someone can help me out!
The solution was really simple! The problem was even though I'm not over the 500 character limit for total tags, but sometimes I was over the limit of 30 characters per tag! I just changed tag adding lines to the following code:
//Keywords
mg.setKeywords(new MediaKeywords());
int totalTagsLimit = 500; // characters
int singleTagLimit = 30; // characters
int totalTags = 0; //characters
for (String tag : tags) {
if ((totalTags + tag.length()) < totalTagsLimit && tag.length() < singleTagLimit) {
mg.getKeywords().addKeyword(tag);
totalTags += tag.length();
}
}

Categories

Resources