// OpenTween - Client of Twitter
// Copyright (c) 2012 kim_upsilon (@kim_upsilon)
// All rights reserved.
//
// This file is part of OpenTween.
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 3 of the License, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program. If not, see , or write to
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using OpenTween.Thumbnail.Services;
namespace OpenTween.Thumbnail
{
class ThumbnailGenerator
{
public static List Services { get; protected set; }
internal static ImgAzyobuziNet ImgAzyobuziNetInstance { get; private set; }
static ThumbnailGenerator()
{
ThumbnailGenerator.Services = new List();
}
public static void InitializeGenerator(HttpClient http)
{
ImgAzyobuziNetInstance = new ImgAzyobuziNet(http, autoupdate: true);
ThumbnailGenerator.Services = new List()
{
// ton.twitter.com
new TonTwitterCom(),
// DirectLink
new SimpleThumbnailService(@"^https?://.*(\.jpg|\.jpeg|\.gif|\.png|\.bmp)$", "${0}"),
// img.azyobuzi.net
ImgAzyobuziNetInstance,
// ImgUr
new SimpleThumbnailService(
@"^http://(?:i\.)?imgur\.com/(\w+)(?:\..{3})?$",
"http://img.imgur.com/${1}l.jpg",
"http://img.imgur.com/${1}.jpg"),
// Twitpic
new SimpleThumbnailService(
@"^http://(www\.)?twitpic\.com/(?\w+)(/full/?)?$",
"http://twitpic.com/show/thumb/${photoId}",
"http://twitpic.com/show/large/${photoId}"),
// yfrog
new SimpleThumbnailService(
@"^http://yfrog\.com/(\w+)$",
"${0}:small",
"${0}"),
// Lockerz
new SimpleThumbnailService(
@"^http://(tweetphoto\.com/[0-9]+|pic\.gd/[a-z0-9]+|(lockerz|plixi)\.com/[ps]/[0-9]+)$",
"http://api.plixi.com/api/tpapi.svc/imagefromurl?size=thumbnail&url=${0}",
"http://api.plixi.com/api/tpapi.svc/imagefromurl?size=big&url=${0}"),
// MobyPicture
new SimpleThumbnailService(
@"^http://moby\.to/(\w+)$",
"http://mobypicture.com/?${1}:small",
"http://mobypicture.com/?${1}:full"),
// 携帯百景
new SimpleThumbnailService(
@"^http://movapic\.com/pic/(\w+)$",
"http://image.movapic.com/pic/s_${1}.jpeg",
"http://image.movapic.com/pic/m_${1}.jpeg"),
// はてなフォトライフ
new SimpleThumbnailService(
@"^http://f\.hatena\.ne\.jp/(([a-z])[a-z0-9_-]{1,30}[a-z0-9])/((\d{8})\d+)$",
"http://img.f.hatena.ne.jp/images/fotolife/${2}/${1}/${4}/${3}_120.jpg",
"http://img.f.hatena.ne.jp/images/fotolife/${2}/${1}/${4}/${3}.jpg"),
// PhotoShare
new SimpleThumbnailService(@"^http://(?:www\.)?bcphotoshare\.com/photos/\d+/(\d+)$", "http://images.bcphotoshare.com/storages/${1}/thumb180.jpg"),
// img.ly
new SimpleThumbnailService(@"^http://img\.ly/(\w+)$",
"http://img.ly/show/thumb/${1}",
"http://img.ly/show/full/${1}"),
// Twitgoo
new SimpleThumbnailService(@"^http://twitgoo\.com/(\w+)$",
"http://twitgoo.com/${1}/mini",
"http://twitgoo.com/${1}/img"),
// youtube
new Youtube(),
// ニコニコ動画
new Nicovideo(),
// ニコニコ静画
new SimpleThumbnailService(
@"^http://(?:seiga\.nicovideo\.jp/seiga/|nico\.ms/)im(?\d+)",
"http://lohas.nicoseiga.jp/thumb/${id}q?",
"http://lohas.nicoseiga.jp/thumb/${id}l?"),
// pixiv
new Pixiv(http),
// flickr
new MetaThumbnailService(http, @"^https?://www\.flickr\.com/.+$"),
// フォト蔵
new SimpleThumbnailService(
@"^http://photozou\.jp/photo/show/(?[0-9]+)/(?[0-9]+)",
"http://photozou.jp/p/thumb/${photoId}",
"http://photozou.jp/p/img/${photoId}"),
// Piapro
new MetaThumbnailService(http, @"^http://piapro\.jp/(?:content/[0-9a-z]+|t/[0-9a-zA-Z_\-]+)$"),
// Tumblr
new Tumblr(),
// ついっぷるフォト
new SimpleThumbnailService(@"^http://p\.twipple\.jp/(?[0-9a-z]+)", "http://p.twipple.jp/show/large/${contentId}"),
// mypix/shamoji
new SimpleThumbnailService(@"^http://www\.(mypix\.jp|shamoji\.info)/app\.php/picture/(?[0-9a-z]+)", "${0}/thumb.jpg"),
// ow.ly
new SimpleThumbnailService(@"^http://ow\.ly/i/(\w+)$", "http://static.ow.ly/photos/thumb/${1}.jpg"),
// vimeo
new Vimeo(http),
// cloudfiles
new SimpleThumbnailService(@"^http://c[0-9]+\.cdn[0-9]+\.cloudfiles\.rackspacecloud\.com/[a-z_0-9]+", "${0}"),
// Instagram
new SimpleThumbnailService(
@"^http://(?:instagram.com|instagr\.am)/p/.+/",
"${0}media/?size=m",
"${0}media/?size=l"),
// pikubo
new SimpleThumbnailService(
@"^http://pikubo\.me/([a-z0-9-_]+)",
"http://pikubo.me/q/${1}",
"http://pikubo.me/l/${1}"),
// Foursquare
new FoursquareCheckin(http),
// TINAMI
new Tinami(http),
// pic.twitter.com
new SimpleThumbnailService(
@"^https?://p\.twimg\.com/.*$",
"${0}:thumb",
"${0}"),
// TwitrPix
new SimpleThumbnailService(
@"^http://twitrpix\.com/(\w+)$",
"http://img.twitrpix.com/thumb/${1}",
"http://img.twitrpix.com/${1}"),
// Pckles
new SimpleThumbnailService(
@"^https?://pckles\.com/\w+/\w+$",
"${0}.resize.jpg",
"${0}.jpg"),
// via.me
new ViaMe(http),
// tuna.be
new SimpleThumbnailService(@"^http://tuna\.be/t/(?[a-zA-Z0-9\.\-_]+)$", "http://tuna.be/show/thumb/${entryId}"),
// Path (path.com)
new MetaThumbnailService(http, @"^https?://path.com/p/\w+$"),
// GIFMAGAZINE
new MetaThumbnailService(http, @"^http?://gifmagazine\.net/post_images/\d+$"),
};
}
public static async Task> GetThumbnailsAsync(PostClass post, CancellationToken token)
{
var thumbnails = new List();
if (post.Media != null)
{
foreach (var media in post.Media)
{
var thumbInfo = await ThumbnailGenerator.GetThumbnailInfoAsync(media, post, token)
.ConfigureAwait(false);
if (thumbInfo != null)
thumbnails.Add(thumbInfo);
token.ThrowIfCancellationRequested();
}
}
if (post.PostGeo != null && !(post.PostGeo.Lat == 0 && post.PostGeo.Lng == 0))
{
var map = MapThumb.GetDefaultInstance();
thumbnails.Add(new ThumbnailInfo()
{
ImageUrl = map.CreateMapLinkUrl(post.PostGeo.Lat, post.PostGeo.Lng),
ThumbnailUrl = map.CreateStaticMapUrl(post.PostGeo.Lat, post.PostGeo.Lng),
TooltipText = null,
});
}
return thumbnails;
}
public static async Task GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
{
foreach (var generator in ThumbnailGenerator.Services)
{
var result = await generator.GetThumbnailInfoAsync(url, post, token)
.ConfigureAwait(false);
if (result != null)
return result;
token.ThrowIfCancellationRequested();
}
return null;
}
}
}