I want to search for all users on twitter wit a particular account creation date. So does Twitter api allows that? And if yes, how do I do so using twitter4j?
I am not sure whether it is possible or not. However you might use following things.
For example, assume that you are searching users who has been created in 2010-03-05 (yyyy-MM-dd)
You can create a query like below by giving since and until date points like 1 day before to since point and 1 day later to until point. Because there is no explicit field to set exact date, I came up with this idea. Then, you should call SearchUsers() method with paging mechanism. You can explore how to implement pagination in this, I don't remember how it was, but you can easily find a sample on the Internet. Try the following codes, I hope it will work:
try
{
Query query = new Query();
query.setSince("2010-03-04");
query.setUntil("2010-03-06");
ResponseList<User> userList = twitterObj.searchUsers(query.toString(), -1);
for (User userItem : userList)
{
// Then here you can do whatever you want by using userItem object
}
}
catch (TwitterException ex)
{
// Do necessary error handling mechanism here
}
public void tweetSearch(String queryRequest) throws IOException, TwitterException{
// Create configuration builder and set key, token etc
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDebugEnabled(true);
cb.setOAuthConsumerKey("xxxxx");
// type your provided Consumer key and consumer secret key from twitter
//and leave access token access secret token as blank
cb.setOAuthConsumerSecret("xxxx");
cb.setOAuthAccessToken("xxxx");
cb.setOAuthAccessTokenSecret("xxxx");
// Create Twitter instance
Twitter Twitter = new TwitterFactory(cb.build()).getInstance();
// Create file writer and buffer writer
FileWriter fstream = new FileWriter("Twitterstream.txt",true);
BufferedWriter out = new BufferedWriter(fstream);
// Create Query object and set search string
Query query = new Query("");
//change the date as u wish...
query.setSince("2014-06-12");
query.setUntil("2014-06-14");
query.setQuery(queryRequest);
// Get query result
QueryResult qr = Twitter.search(query);
// Get tweets and write in the file
while(qr.hasNext()){
qr.nextQuery();
List<Status> tweets = qr.getTweets();
for (Status t: tweets){
System.out.println(t.getId() + " - " + t.getCreatedAt() + ": " + t.getText());
out.write("\n"+t.getId()+",");
out.write("\t"+t.getText()+",");
out.write("\t"+t.getUser()+",");
}
}
System.out.println("Generated Twitter Stream");
}
Related
I am trying to fetch a user from a tenant by email. It works when getting some users, but doesn't work when getting a particular user who happens to have a '+' in the email address. I am not sure if that character is the problem or if it's something else. The query below always returns null for that user. My question, is how do I figure out why it's returning null when the user is obviously there for that particular user? I checked Audit Logs in AD B2C tenant, but they only show logins or deletions. Where can I check what happened with the graph API call? Second question, why would it do this? The user is obviously there!
public static GraphServiceClient GetGraphServiceClient()
{
var clientapp = ConfidentialClientApplicationBuilder
.Create(Globals.ClientId)
.WithTenantId(Globals.TenantId)
.WithClientSecret(Globals.ClientSecret)
.Build();
ClientCredentialProvider authProvider = new ClientCredentialProvider(clientapp);
return new GraphServiceClient(authProvider);
}
public static async Task<User> GetADUserAsyncByEmail(string email)
{
var graphClient = GetGraphServiceClient();
try
{
Logger.Log(LogLevel.Trace, $"Contacting AD tenant {Globals.Tenant} for user {email}.");
var users = await graphClient.Users
.Request()
.Filter($"identities/any(c:c/issuerAssignedId eq '{email}' and c/issuer eq '{Globals.Tenant}')")
.Select("displayName,id,userPrincipalName")
.GetAsync();
Logger.Log(LogLevel.Trace, $"Finished contacting AD tenant {Globals.Tenant} for user {email}.");
var foundUser = users.FirstOrDefault();
return foundUser;
}
catch (ServiceException ex)
{
Logger.Log(LogLevel.Error, ex, $"Error Alert:Encountered an exception when trying to get AD User {email}.");
return null;
}
catch (Exception ex)
{
Logger.Log(LogLevel.Error, ex, $"Error Alert:Encountered an exception when trying to get AD User {email}.");
return null;
}
}
It seems that Microsoft graph's handling of issuerAssignedId is not perfect.
It will encode the request url to URL-encoded format with the content of {email} being ignored.
Nevertheless, it can still return the correct result for most symbols that have not been encoded. For example, "*".
"+" seems a bit special, and Microsoft graph does not handle it well.
As a workaround, you can use Uri.EscapeDataString to encode the email and put it into filter.
var encodedEmail = Uri.EscapeDataString(email);
AND
.Filter($"identities/any(c:c/issuerAssignedId eq '{encodedEmail}' and c/issuer eq '{Globals.Tenant}')")
I have an ODataController with a Get method as such:
public IHttpActionResult Get(ODataQueryOptions<MyModel> queryOptions) {
IQueryable<MyModel> models = _Models.AsQueryable(); // _Models Defined in Controller as List<MyModel> and is already populated with nested data for both .LevelOne and .LevelOne.LevelTwo which are two other Lists.
Uri fullrequest = Request.GetRequestContext().Url.Request.RequestUri; // http://localhost:8080/odata/Root?$expand=LevelOne($expand=LevelTwo)
Uri serviceroot = new Uri(controller.GetLeftPart(UriPartial.Path).Replace("/Root", "")); // http://localhost:8080/odata
String metadata = service + "/$metadata"; // http://localhost:8080/odata/$metadata
IEdmModel model = EdmxReader.Parse(XmlTextReader.Create(metadata));
ODataUriParser parser = new ODataUriParser(model, serviceroot, fullrequest);
SelectExpandClause selectAndExpand = parser.ParseSelectAndExpand();
//Only one of the two below lines is ever commented in...
Request.ODataProperties().SelectExpandClause = queryOptions.SelectExpand.SelectExpandClause; // This line will work
Request.ODataProperties().SelectExpandClause = selectAndExpand; // This line will not work
return Ok(models);
}
using my manually parsed selectAndExpand does not expand the dataset, but using the predefined queryOptions one does. Any ideas why? Both objects appear to contain the same information while viewed in the debugger, but I must be missing something. I want to be able to parse the URI myself, without the need for the ODataQueryOptions at all.
What I ended up doing, was building a new ODataQueryOptions object based off the original request, and then pulling just the SelectExpandClause from that. It doesn't answer my initial question, but it is a somewhat working solution for not having to pass in a ODataQueryOptions parameter. See my Code below:
public IHttpActionResult Get() {
//Get Queryable Item (in this case just a list made queryable)
IQueryable<MyModel> models = _Models.AsQueryable();
//Create new ODataQueryContext based off initial request (required to create ODataQueryOptions)
ODataQueryContext selectAndExpandContext = new ODataQueryContext(Request.ODataProperties().Model, typeof(MyModel), Request.ODataProperties().Path);
//Create new ODataQueryOptions based off new context and original request
ODataQueryOptions<Employee> selectAndExpandOptions = new ODataQueryOptions<Employee>(selectAndExpandContext, Request);
//Attach Select + Expand options to be processed
if (selectAndExpandOptions.SelectExpand != null) {
Request.ODataProperties().SelectExpandClause = selectAndExpandOptions.SelectExpand.SelectExpandClause;
}
return Ok(models);
}
Iam trying to apply Pagination to my MVC application. Iam using Azure table storage
Here is what I have tried:-
public List<T> GetPagination(string partitionKey, int start, int take)
{
List<T> entities = new List<T>();
TableQuery<T> query = new TableQuery<T>().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, partitionKey.ToLower()));
entities = Table.ExecuteQuery(query).Skip(start).Take(take).ToList();
return entities;
}
Controller:-
public ActionResult Index()
{
key= System.Web.HttpContext.Current.Request[Constants.Key];
if (String.IsNullOrEmpty(key))
return RedirectToAction("NoContext", "Error");
var items= _StorageHelper.GetPagination(key,0,3);
ItemCollection itemCollection = new ItemCollection();
itemCollection .Items= Mapper.Map<List<ItemChart>, List<ItemModel>>(items);
itemCollection .Items.ForEach(g => g.Object = g.Object.Replace(key, ""));
return View(itemCollection);
}
This currently gives me the first 3 entries from my data. Now how can I show and implement the "Previous" and "Next" to show the rest of the entries on next page? How do I implement the rest of the controller and HTML page?
Any help is appreciated.
When it comes to pagination, there are a few things to consider:
Not all LINQ operators (and in turn OData query options) are supported for Table Service. For example Skip is not supported. For a list of supported operators, please see this link: https://msdn.microsoft.com/en-us/library/azure/dd135725.aspx.
The way pagination works with Table Service is that when you query your table to fetch some data, maximum number of entities that can be returned by table service is 1000. There's no guarantee that always 1000 entities will be returned. It may be less than 1000 or even 0 depending on how you're querying. However if there are more results available, Table Service returns something called a Continuation Token. You must use this token to fetch next set of results from table service. Please see this link for more information on query timeout and pagination: https://msdn.microsoft.com/en-us/library/azure/dd135718.aspx.
Taking these two factors into consideration, you can't really implement a paging solution where a user can directly jump to a particular page (for example, user is sitting on page 1 and then the user can't go to page 4). At the most you can implement next page, previous page and first page kind of functionality.
To implement next page kind of functionality, store the continuation token returned by table service and use that in your query.
To implement previous page kind of functionality, you must store all the continuation tokens returned in an array or something and keep track of which page a user is on currently (that would be the current page index). When a user wants to go to previous page, you just get the continuation token for the previous index (i.e. current page index - 1) and use that in your query.
To implement first page kind of functionality, just issue your query without continuation token.
Do take a look at ExecuteQuerySegmented method in Storage Client Library if you want to implement pagination.
UPDATE
Please see the sample code below. For the sake of simplicity, I have only kept first page and next page functionality:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.WindowsAzure.Storage.Auth;
using Microsoft.WindowsAzure.Storage.Blob;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Queue;
using Microsoft.WindowsAzure.Storage.Table;
namespace TablePaginationSample
{
class Program
{
static string accountName = "";
static string accountKey = "";
static string tableName = "";
static int maxEntitiesToFetch = 10;
static TableContinuationToken token = null;
static void Main(string[] args)
{
var cloudStorageAccount = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true);
var cloudTableClient = cloudStorageAccount.CreateCloudTableClient();
var table = cloudTableClient.GetTableReference(tableName);
Console.WriteLine("Press \"N\" to go to next page\nPress \"F\" to go first page\nPress any other key to exit program");
var query = new TableQuery().Take(maxEntitiesToFetch);
var continueLoop = true;
do
{
Console.WriteLine("Fetching entities. Please wait....");
Console.WriteLine("-------------------------------------------------------------");
var queryResult = table.ExecuteQuerySegmented(query, token);
token = queryResult.ContinuationToken;
var entities = queryResult.Results;
foreach (var entity in entities)
{
Console.WriteLine(string.Format("PartitionKey = {0}; RowKey = {1}", entity.PartitionKey, entity.RowKey));
}
Console.WriteLine("-------------------------------------------------------------");
if (token == null)//No more token available. We've reached end of table
{
Console.WriteLine("All entities have been fetched. The program will now terminate.");
break;
}
else
{
Console.WriteLine("More entities available. Press \"N\" to go to next page or Press \"F\" to go first page or Press any other key to exit program.");
Console.WriteLine("-------------------------------------------------------------");
var key = Console.ReadKey();
switch(key.KeyChar)
{
case 'N':
case 'n':
continue;
case 'F':
case 'f':
token = null;
continue;
default:
continueLoop = false;
break;
}
}
} while (continueLoop);
Console.WriteLine("Press any key to terminate the application.");
Console.ReadLine();
}
}
}
I am developing application related to jira. I want count of issues return by the jql query.
i got searchCount method in this link but i am not getting how to use this method using instance.
The setup should look like this:
String jqlQuery = "project=ABC"; // insert your JQL query here
SearchService.ParseResult parseResult = searchService.parseQuery(currentUser, jqlQuery);
if (!parseResult.isValid())
{
// errors in parseResult.getErrors().getErrorMessages()
throw new MyException();
}
com.atlassian.query.Query query = parseResult.getQuery();
com.atlassian.jira.util.MessageSet validateResults = searchService.validateQuery(currentUser, query);
if (validateResults.hasAnyErrors())
{
// errors in validateResults.getErrorMessages()
throw new MyException();
}
With the resulting validated query object, you can then call searchService.searchCount(currentUser, query) to get your issue count.
This is a follow-up to this post: New at MVC 4 Web API Confused about HTTPRequestMessage
Here is a summary of what I am trying to do: There is a web site that I want to interface with via MVC 4 Web API. At the site, users can log in with a user name and password, then go to a link called ‘Raw Data’ to query data from the site.
On the ‘Raw Data’ page, there is a dropdown list for ‘Device’, a text box for ‘From’ date, and a text box for ‘To’ date. Given these three parameters, the user can click the ‘Get Data’ button, and return a table of data to the page. What I have to do, is host a service on Azure that will programmatically provide values for these three parameters to the site, and return a CSV file from the site to Azure storage.
The company that hosts the site has provided documentation to programmatically interface with the site to retrieve this raw data. The document describes how requests are to be made against their cloud service. Requests must be authenticated using a custom HTTP authentication scheme. Here is how the authentication scheme works:
Calculate an MD5 hash from the user password.
Append the request line to the end of the value from step one.
Append the date header to the end of the value in step two.
Append the message body (if any) to the end of the value in step 3.
Calculate MD5 hash over the resulting value from step 4.
Append the value from step 5 to the user email using the “:” character as a delimiter.
Calculate Base64 over the value from step 6.
The code that I am going to list was done in Visual Studio 2012, C#, .NET Framework 4.5. All of the code in this post is in my 'FileDownloadController.cs' Controller class. The ‘getMd5Hash’ function takes a string, and returns an MD5 hash:
//Create MD5 Hash: Hash an input string and return the hash as a 32 character hexadecimal string.
static string getMd5Hash(string input)
{
// Create a new instance of the MD5CryptoServiceProvider object.
MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider();
// Convert the input string to a byte array and compute the hash.
byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));
// Create a new Stringbuilder to collect the bytes
// and create a string.
StringBuilder sBuilder = new StringBuilder();
// Loop through each byte of the hashed data
// and format each one as a hexadecimal string.
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
// Return the hexadecimal string.
return sBuilder.ToString();
}
This function takes a string, and returns BASE64:
//Convert to Base64
static string EncodeTo64(string input)
{
byte[] str1Byte = System.Text.Encoding.ASCII.GetBytes(input);
String plaintext = Convert.ToBase64String(str1Byte);
return plaintext;
}
The next function creates an HTTPClient, makes an HTTPRequestMessage, and returns the authorization. Note: The following is the URI that was returned from Fiddler when data was returned from the ‘Raw Data’ page: GET /rawdata/exportRawDataFromAPI/?devid=3188&fromDate=01-24-2013&toDate=01-25-2013 HTTP/1.1
Let me first walk through what is happening with this function:
The ‘WebSiteAuthorization’ function takes a ‘deviceID’, a ‘fromDate’, a ‘toDate’ and a ‘password’.
Next, I have three variables declared. I’m not clear on whether or not I need a ‘message body’, but I have a generic version of this set up. The other two variables hold the beginning and end of the URI.
I have a variable named ‘dateHeader’, which holds the data header.
Next, I attempt to create an HTTPClient, assign the URI with parameters to it, and then assign ‘application/json’ as the media type. I’m still not very clear on how this should be structured.
In the next step, the authorization is created, per the requirements of the API documentation, and then the result is returned.
public static string WebSiteAuthorization(Int32 deviceid, string fromDate, string toDate, string email, string password)
{
var messagebody = "messagebody"; // TODO: ??????????? Message body
var uriAddress = "GET/rawdata/exportRawDataFromAPI/?devid=";
var uriAddressSuffix = "HTTP/1.1";
//create a date header
DateTime dateHeader = DateTime.Today;
dateHeader.ToUniversalTime();
//create the HttpClient, and its BaseAddress
HttpClient ServiceHttpClient = new HttpClient();
ServiceHttpClient.BaseAddress = new Uri(uriAddress + deviceid.ToString() + " fromDate" + fromDate.ToString() + " toDate" + toDate.ToString() + uriAddressSuffix);
ServiceHttpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//create the authorization string
string authorizationString = getMd5Hash(password);
authorizationString = authorizationString + ServiceHttpClient + dateHeader + messagebody;
authorizationString = email + getMd5Hash(authorizationString);
authorizationString = EncodeTo64(authorizationString);
return authorizationString;
}
I haven’t tested this on Azure yet. I haven't completed the code that gets the file. One thing I know I need to do is to determine the correct way to create an HttpRequestMessage and use HttpClient to send it. In the documentation that I've read, and the examples that I've looked at, the following code fragments appear to be possible approaches to this:
Var serverAddress = http://my.website.com/;
//Create the http client, and give it the ‘serverAddress’:
Using(var httpClient = new HttpClient()
{BaseAddress = new Uri(serverAddress)))
Var requestMessage = new HttpRequestMessage();
Var objectcontent = requestMessage.CreateContent(base64Message, MediaTypeHeaderValue.Parse (“application/json”)
or----
var formatters = new MediaTypeFormatter[] { new jsonMediaTypeFormatter() };
HttpRequestMessage<string> request = new HttpRequestMessage<string>
("something", HttpMethod.Post, new Uri("http://my.website.com/"), formatters);
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var httpClient = new HttpClient();
var response = httpClient.SendAsync(request);
or------
Client = new HttpClient();
var request = new HttpRequestMessage
{
RequestUri = "http://my.website.com/",
Method = HttpMethod.Post,
Content = new StringContent("ur message")
};
I'm not sure which approach to take with this part of the code.
Thank you for your help.
Read this step by step tutorial to understand the basic.