Last active
August 29, 2015 13:57
-
-
Save iseebi/9694613 to your computer and use it in GitHub Desktop.
Twitter 片思い抽出
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
> KataomoiList.exe [Twitter ID] > results.html |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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