Skip to content

Instantly share code, notes, and snippets.

@gousiosg
Last active December 15, 2015 16:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gousiosg/5290793 to your computer and use it in GitHub Desktop.
Save gousiosg/5290793 to your computer and use it in GitHub Desktop.
Find Github pull requests that are then tweeted. Implemented with Rx.Net in C#.
/*
* Github commits that are then tweeted.
* by @gousiosg, @headinthebox
*/
void Main()
{
var q = from ghinfo in PullRequestersInfo()
from u in ghinfo
from t in Tweets(u).TakeUntil(Observable.Timer(TimeSpan.FromMinutes(5)))
select new {User = u, Tweet = t};
q.DumpLive();
}
public static IObservable<IEnumerable<String>> PullRequesters()
{
return PullRequesters(TimeSpan.FromSeconds(6));
}
public static IObservable<IEnumerable<String>> PullRequesters(TimeSpan interval)
{
return Observable.Timer(TimeSpan.Zero, interval).SelectMany( _ =>
ReadGithubAsync("foo", "bar")
).DistinctUntilChanged();
}
public static IObservable<IGroupedObservable<String, String>> PullRequestersInfo()
{
var u = from users in PullRequesters()
from user in users select user;
var groups = from user in u
group user by user;
return groups;
}
public static async Task<IEnumerable<string>> ReadGithubAsync(string user, string password) {
var header = new AuthenticationHeaderValue(
"Basic",
Convert.ToBase64String(System.Text.UTF8Encoding.UTF8.GetBytes(string.Format("{0}:{1}", user, password)))
);
var client = new HttpClient{
BaseAddress = new Uri("https://api.github.com/"),
DefaultRequestHeaders = {Authorization = header}
};
client.DefaultRequestHeaders.Add("user-agent", "rx-example");
var response = await client.GetAsync("/events");
var json = await response.Content.ReadAsStringAsync();
return (from e in JArray.Parse(json).Children()
where (string)e["type"] == "PullRequestEvent" && (string)e["payload"]["action"] == "opened"
select (string)e["actor"]["login"]);
}
public static IObservable<string> Tweets(string user)
{
return Observable.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(10))
.SelectMany(_ => ReadTwitterAsync(user))
.Scan(new string[]{}, (a,v) =>
{
var diff = v.Except(a).ToArray();
if(diff.Length == 0) return a;
return diff;
})
.DistinctUntilChanged()
.SelectMany(ts => ts);
}
public static async Task<IEnumerable<string>> ReadTwitterAsync(string user)
{
var client = new HttpClient{ BaseAddress = new Uri("http://search.twitter.com/search.json")};
var response = await client.GetAsync(String.Format("?q={0}", user));
var json = await response.Content.ReadAsStringAsync();
var tweets = from e in JValue.Parse(json)["results"]
where (string)e["from_user"] == user &&
Regex.Match((string)e["text"], "github.com/.*/pulls/").Success
select new{ Text = (string)e["text"], From = (string)e["from_user"] };
return tweets.Select(x => x.Text);
}

Meant to be run in LinqPad. To setup, install the newest version of .Net and using NuGet install the following packages:

  • Newtonsoft.Json
  • Rx-Main

Linqpad requires the following namespace imports to run this example

  • Newtonsoft.Json
  • Newtonsoft.Json.Bson
  • Newtonsoft.Json.Converters
  • Newtonsoft.Json.Linq
  • Newtonsoft.Json.Schema
  • Newtonsoft.Json.Serialization
  • System.Net
  • System.Net.Http
  • System.Reactive
  • System.Reactive.Linq
  • System.Runtime.Serialization
  • System.Runtime.Serialization.Json
  • System.Threading.Tasks
  • System.Net.Http.Headers
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment