mirror of
https://github.com/chylex/TweetDuck.git
synced 2025-05-06 05:34:05 +02:00
Support new image urls & fix missing filename features w/o Best Image Quality
Fixes #270
This commit is contained in:
parent
25680fa980
commit
eac4f30c50
Configuration
Core
lib
@ -3,9 +3,9 @@
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Notification;
|
||||
using TweetDuck.Core.Other;
|
||||
using TweetDuck.Core.Utils;
|
||||
using TweetDuck.Data;
|
||||
using TweetLib.Core.Features.Configuration;
|
||||
using TweetLib.Core.Features.Twitter;
|
||||
|
||||
namespace TweetDuck.Configuration{
|
||||
sealed class UserConfig : BaseConfig{
|
||||
@ -80,7 +80,7 @@ sealed class UserConfig : BaseConfig{
|
||||
public bool IsCustomNotificationSizeSet => CustomNotificationSize != Size.Empty;
|
||||
public bool IsCustomSoundNotificationSet => NotificationSoundPath != string.Empty;
|
||||
|
||||
public TwitterUtils.ImageQuality TwitterImageQuality => BestImageQuality ? TwitterUtils.ImageQuality.Orig : TwitterUtils.ImageQuality.Default;
|
||||
public ImageQuality TwitterImageQuality => BestImageQuality ? ImageQuality.Best : ImageQuality.Default;
|
||||
|
||||
public string NotificationSoundPath{
|
||||
get => _notificationSoundPath ?? string.Empty;
|
||||
|
@ -12,13 +12,14 @@
|
||||
using TweetDuck.Core.Other;
|
||||
using TweetDuck.Core.Other.Analytics;
|
||||
using TweetDuck.Resources;
|
||||
using TweetLib.Core.Features.Twitter;
|
||||
using TweetLib.Core.Utils;
|
||||
|
||||
namespace TweetDuck.Core.Handling{
|
||||
abstract class ContextMenuBase : IContextMenuHandler{
|
||||
protected static UserConfig Config => Program.Config.User;
|
||||
|
||||
private static TwitterUtils.ImageQuality ImageQuality => Config.TwitterImageQuality;
|
||||
private static ImageQuality ImageQuality => Config.TwitterImageQuality;
|
||||
|
||||
private const CefMenuCommand MenuOpenLinkUrl = (CefMenuCommand)26500;
|
||||
private const CefMenuCommand MenuCopyLinkUrl = (CefMenuCommand)26501;
|
||||
|
@ -10,6 +10,7 @@
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using TweetLib.Core.Features.Twitter;
|
||||
using TweetLib.Core.Utils;
|
||||
using Cookie = CefSharp.Cookie;
|
||||
|
||||
@ -29,14 +30,6 @@ static class TwitterUtils{
|
||||
"tweetdeck", "TweetDeck", "tweetduck", "TweetDuck", "TD"
|
||||
};
|
||||
|
||||
public static readonly string[] ValidImageExtensions = {
|
||||
".jpg", ".jpeg", ".png", ".gif"
|
||||
};
|
||||
|
||||
public enum ImageQuality{
|
||||
Default, Orig
|
||||
}
|
||||
|
||||
public static bool IsTweetDeckWebsite(IFrame frame){
|
||||
return frame.Url.Contains("//tweetdeck.twitter.com/");
|
||||
}
|
||||
@ -49,38 +42,19 @@ public static bool IsTwitterLogin2FactorWebsite(IFrame frame){
|
||||
return frame.Url.Contains("//twitter.com/account/login_verification");
|
||||
}
|
||||
|
||||
private static string ExtractMediaBaseLink(string url){
|
||||
int slash = url.LastIndexOf('/');
|
||||
return slash == -1 ? url : StringUtils.ExtractBefore(url, ':', slash);
|
||||
}
|
||||
|
||||
public static string GetMediaLink(string url, ImageQuality quality){
|
||||
if (quality == ImageQuality.Orig){
|
||||
string result = ExtractMediaBaseLink(url);
|
||||
|
||||
if (url.Contains("//ton.twitter.com/") && url.Contains("/ton/data/dm/")){
|
||||
result += ":large";
|
||||
}
|
||||
else if (result != url || url.Contains("//pbs.twimg.com/media/")){
|
||||
result += ":orig";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
else{
|
||||
return url;
|
||||
}
|
||||
return ImageUrl.TryParse(url, out var obj) ? obj.WithQuality(quality) : url;
|
||||
}
|
||||
|
||||
public static string GetImageFileName(string url){
|
||||
return UrlUtils.GetFileNameFromUrl(ExtractMediaBaseLink(url));
|
||||
return UrlUtils.GetFileNameFromUrl(ImageUrl.TryParse(url, out var obj) ? obj.WithNoQuality : url);
|
||||
}
|
||||
|
||||
public static void ViewImage(string url, ImageQuality quality){
|
||||
void ViewImageInternal(string path){
|
||||
string ext = Path.GetExtension(path);
|
||||
|
||||
if (ValidImageExtensions.Contains(ext)){
|
||||
if (ImageUrl.ValidExtensions.Contains(ext)){
|
||||
WindowsUtils.OpenAssociatedProgram(path);
|
||||
}
|
||||
else{
|
||||
|
5
lib/TweetLib.Core/Features/Twitter/ImageQuality.cs
Normal file
5
lib/TweetLib.Core/Features/Twitter/ImageQuality.cs
Normal file
@ -0,0 +1,5 @@
|
||||
namespace TweetLib.Core.Features.Twitter{
|
||||
public enum ImageQuality{
|
||||
Default, Best
|
||||
}
|
||||
}
|
85
lib/TweetLib.Core/Features/Twitter/ImageUrl.cs
Normal file
85
lib/TweetLib.Core/Features/Twitter/ImageUrl.cs
Normal file
@ -0,0 +1,85 @@
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using TweetLib.Core.Utils;
|
||||
|
||||
namespace TweetLib.Core.Features.Twitter{
|
||||
public class ImageUrl{
|
||||
private static readonly Regex RegexImageUrlParams = new Regex(@"(format|name)=(\w+)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
|
||||
public static readonly string[] ValidExtensions = {
|
||||
".jpg", ".jpeg", ".png", ".gif"
|
||||
};
|
||||
|
||||
public static bool TryParse(string url, out ImageUrl obj){
|
||||
obj = default!;
|
||||
|
||||
int slash = url.LastIndexOf('/');
|
||||
|
||||
if (slash == -1){
|
||||
return false;
|
||||
}
|
||||
|
||||
int question = url.IndexOf('?', slash);
|
||||
|
||||
if (question == -1){
|
||||
var oldStyleUrl = StringUtils.SplitInTwo(url, ':', slash);
|
||||
|
||||
if (oldStyleUrl.HasValue){
|
||||
var (baseUrl, quality) = oldStyleUrl.Value;
|
||||
|
||||
obj = new ImageUrl(baseUrl, quality);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
string? imageExtension = null;
|
||||
string? imageQuality = null;
|
||||
|
||||
foreach(Match match in RegexImageUrlParams.Matches(url, question)){
|
||||
string value = match.Groups[2].Value;
|
||||
|
||||
switch(match.Groups[1].Value){
|
||||
case "format":
|
||||
imageExtension = '.' + value;
|
||||
break;
|
||||
|
||||
case "name":
|
||||
imageQuality = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ValidExtensions.Contains(imageExtension) || imageQuality == null){
|
||||
return false;
|
||||
}
|
||||
|
||||
obj = new ImageUrl(url.Substring(0, question) + imageExtension, imageQuality);
|
||||
return true;
|
||||
}
|
||||
|
||||
private readonly string baseUrl;
|
||||
private readonly string quality;
|
||||
|
||||
private ImageUrl(string baseUrl, string quality){
|
||||
this.baseUrl = baseUrl;
|
||||
this.quality = quality;
|
||||
}
|
||||
|
||||
public string WithNoQuality => baseUrl;
|
||||
|
||||
public string WithQuality(ImageQuality newQuality){
|
||||
if (newQuality == ImageQuality.Best){
|
||||
if (baseUrl.Contains("//ton.twitter.com/") && baseUrl.Contains("/ton/data/dm/")){
|
||||
return baseUrl + ":large";
|
||||
}
|
||||
else if (baseUrl.Contains("//pbs.twimg.com/media/")){
|
||||
return baseUrl + ":orig";
|
||||
}
|
||||
}
|
||||
|
||||
return baseUrl + ':' + quality;
|
||||
}
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
|
||||
open Xunit
|
||||
open TweetDuck.Core.Utils
|
||||
open TweetLib.Core.Features.Twitter
|
||||
|
||||
|
||||
[<Collection("RegexAccount")>]
|
||||
@ -60,7 +61,7 @@ module RegexAccount_Match =
|
||||
|
||||
|
||||
module GetMediaLink_Default =
|
||||
let getMediaLinkDefault url = TwitterUtils.GetMediaLink(url, TwitterUtils.ImageQuality.Default)
|
||||
let getMediaLinkDefault url = TwitterUtils.GetMediaLink(url, ImageQuality.Default)
|
||||
let domain = "https://pbs.twimg.com"
|
||||
|
||||
[<Fact>]
|
||||
@ -77,7 +78,7 @@ module GetMediaLink_Default =
|
||||
|
||||
|
||||
module GetMediaLink_Orig =
|
||||
let getMediaLinkOrig url = TwitterUtils.GetMediaLink(url, TwitterUtils.ImageQuality.Orig)
|
||||
let getMediaLinkOrig url = TwitterUtils.GetMediaLink(url, ImageQuality.Best)
|
||||
let domain = "https://pbs.twimg.com"
|
||||
|
||||
[<Fact>]
|
||||
|
Loading…
Reference in New Issue
Block a user