Skip to content

Instantly share code, notes, and snippets.

@iseebi
Last active August 29, 2015 13:57
Show Gist options
  • Save iseebi/9694613 to your computer and use it in GitHub Desktop.
Save iseebi/9694613 to your computer and use it in GitHub Desktop.
Twitter 片思い抽出
> KataomoiList.exe [Twitter ID] > results.html
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="AsyncOAuth" version="0.8.4" targetFramework="net45" />
<package id="Microsoft.Bcl" version="1.0.19" targetFramework="net45" />
<package id="Microsoft.Bcl.Async" version="1.0.165" targetFramework="net45" />
<package id="Microsoft.Bcl.Build" version="1.0.13" targetFramework="net45" />
<package id="Newtonsoft.Json" version="6.0.1" targetFramework="net45" />
</packages>
using System;
using AsyncOAuth;
using System.Security.Cryptography;
using Newtonsoft.Json.Linq;
using System.Linq;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace KataomoiList
{
class MainClass
{
private static string ConsumerKey = "<<CONSUMER KEY>>";
private static string ConsumerSecret = "<<CONSUMER SECRET>>";
private static AccessToken AccessToken = new AccessToken("<<ACCESS TOKEN>>", "<<ACCESS TOKEN SECRET>>");
public static void Main(string[] args)
{
OAuthUtility.ComputeHash = (key, buffer) =>
{
using (var hmac = new HMACSHA1(key))
{
return hmac.ComputeHash(buffer);
}
};
var t = DoProcess(AccessToken, args[0]);
t.Wait();
if (System.Diagnostics.Debugger.IsAttached)
{
Console.Read();
}
}
static async Task DoProcess(AccessToken accessToken, string screenName)
{
var client = OAuthUtility.CreateOAuthClient(ConsumerKey, ConsumerSecret, accessToken);
var followings = JObject.Parse(await client.GetStringAsync("https://api.twitter.com/1.1/friends/ids.json?cursor=-1&count=5000&screen_name=" + screenName))["ids"].Values<uint>();
var follwers = JObject.Parse(await client.GetStringAsync("https://api.twitter.com/1.1/followers/ids.json?cursor=-1&count=5000&screen_name=" + screenName))["ids"].Values<uint>();
var excepts = followings.Except(follwers);
var results = await excepts.Chunk(100).Select(async ids =>
JArray.Parse(await client.GetStringAsync("https://api.twitter.com/1.1/users/lookup.json?user_id="
+ string.Join(",", ids.Select(i => i.ToString()))))
.Select(j => new
{
ScreenName = j["screen_name"].Value<string>(),
ProfileImage = j["profile_image_url"].Value<string>()
})
)
.WhenAll();
Console.WriteLine("<html><body><ul>");
foreach (var item in results.SelectMany(i => i).OrderBy(i => i.ScreenName))
{
Console.WriteLine("<li><a href=\"https://twitter.com/{1}\"><img src=\"{0}\" />{1}</a></li>", item.ProfileImage, item.ScreenName);
}
Console.WriteLine("</ul></body></html>");
Console.Error.WriteLine("Output {0} items", results.SelectMany(i => i).Count());
}
}
// http://devlights.hatenablog.com/entry/20121130/p2
public static class LinqSamples59_Extensions
{
/// <summary>
/// シーケンスを指定されたサイズのチャンクに分割します.
/// </summary>
public static IEnumerable<IEnumerable<T>> Chunk<T>(this IEnumerable<T> self, int chunkSize)
{
if (chunkSize <= 0)
{
throw new ArgumentException("Chunk size must be greater than 0.", "chunkSize");
}
while (self.Any())
{
yield return self.Take(chunkSize);
self = self.Skip(chunkSize);
}
}
}
// http://neue.cc/2013/12/04_435.html
public static class TaskEnumerableExtensions
{
public static Task WhenAll(this IEnumerable<Task> tasks)
{
return Task.WhenAll(tasks);
}
public static Task<T[]> WhenAll<T>(this IEnumerable<Task<T>> tasks)
{
return Task.WhenAll(tasks);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment