mirror of
https://github.com/chylex/TweetDuck.git
synced 2025-05-28 17:34:06 +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.Controls;
|
||||||
using TweetDuck.Core.Notification;
|
using TweetDuck.Core.Notification;
|
||||||
using TweetDuck.Core.Other;
|
using TweetDuck.Core.Other;
|
||||||
using TweetDuck.Core.Utils;
|
|
||||||
using TweetDuck.Data;
|
using TweetDuck.Data;
|
||||||
using TweetLib.Core.Features.Configuration;
|
using TweetLib.Core.Features.Configuration;
|
||||||
|
using TweetLib.Core.Features.Twitter;
|
||||||
|
|
||||||
namespace TweetDuck.Configuration{
|
namespace TweetDuck.Configuration{
|
||||||
sealed class UserConfig : BaseConfig{
|
sealed class UserConfig : BaseConfig{
|
||||||
@ -80,7 +80,7 @@ sealed class UserConfig : BaseConfig{
|
|||||||
public bool IsCustomNotificationSizeSet => CustomNotificationSize != Size.Empty;
|
public bool IsCustomNotificationSizeSet => CustomNotificationSize != Size.Empty;
|
||||||
public bool IsCustomSoundNotificationSet => NotificationSoundPath != string.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{
|
public string NotificationSoundPath{
|
||||||
get => _notificationSoundPath ?? string.Empty;
|
get => _notificationSoundPath ?? string.Empty;
|
||||||
|
@ -12,13 +12,14 @@
|
|||||||
using TweetDuck.Core.Other;
|
using TweetDuck.Core.Other;
|
||||||
using TweetDuck.Core.Other.Analytics;
|
using TweetDuck.Core.Other.Analytics;
|
||||||
using TweetDuck.Resources;
|
using TweetDuck.Resources;
|
||||||
|
using TweetLib.Core.Features.Twitter;
|
||||||
using TweetLib.Core.Utils;
|
using TweetLib.Core.Utils;
|
||||||
|
|
||||||
namespace TweetDuck.Core.Handling{
|
namespace TweetDuck.Core.Handling{
|
||||||
abstract class ContextMenuBase : IContextMenuHandler{
|
abstract class ContextMenuBase : IContextMenuHandler{
|
||||||
protected static UserConfig Config => Program.Config.User;
|
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 MenuOpenLinkUrl = (CefMenuCommand)26500;
|
||||||
private const CefMenuCommand MenuCopyLinkUrl = (CefMenuCommand)26501;
|
private const CefMenuCommand MenuCopyLinkUrl = (CefMenuCommand)26501;
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using TweetLib.Core.Features.Twitter;
|
||||||
using TweetLib.Core.Utils;
|
using TweetLib.Core.Utils;
|
||||||
using Cookie = CefSharp.Cookie;
|
using Cookie = CefSharp.Cookie;
|
||||||
|
|
||||||
@ -29,14 +30,6 @@ static class TwitterUtils{
|
|||||||
"tweetdeck", "TweetDeck", "tweetduck", "TweetDuck", "TD"
|
"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){
|
public static bool IsTweetDeckWebsite(IFrame frame){
|
||||||
return frame.Url.Contains("//tweetdeck.twitter.com/");
|
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");
|
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){
|
public static string GetMediaLink(string url, ImageQuality quality){
|
||||||
if (quality == ImageQuality.Orig){
|
return ImageUrl.TryParse(url, out var obj) ? obj.WithQuality(quality) : url;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetImageFileName(string 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){
|
public static void ViewImage(string url, ImageQuality quality){
|
||||||
void ViewImageInternal(string path){
|
void ViewImageInternal(string path){
|
||||||
string ext = Path.GetExtension(path);
|
string ext = Path.GetExtension(path);
|
||||||
|
|
||||||
if (ValidImageExtensions.Contains(ext)){
|
if (ImageUrl.ValidExtensions.Contains(ext)){
|
||||||
WindowsUtils.OpenAssociatedProgram(path);
|
WindowsUtils.OpenAssociatedProgram(path);
|
||||||
}
|
}
|
||||||
else{
|
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 Xunit
|
||||||
open TweetDuck.Core.Utils
|
open TweetDuck.Core.Utils
|
||||||
|
open TweetLib.Core.Features.Twitter
|
||||||
|
|
||||||
|
|
||||||
[<Collection("RegexAccount")>]
|
[<Collection("RegexAccount")>]
|
||||||
@ -60,7 +61,7 @@ module RegexAccount_Match =
|
|||||||
|
|
||||||
|
|
||||||
module GetMediaLink_Default =
|
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"
|
let domain = "https://pbs.twimg.com"
|
||||||
|
|
||||||
[<Fact>]
|
[<Fact>]
|
||||||
@ -77,7 +78,7 @@ module GetMediaLink_Default =
|
|||||||
|
|
||||||
|
|
||||||
module GetMediaLink_Orig =
|
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"
|
let domain = "https://pbs.twimg.com"
|
||||||
|
|
||||||
[<Fact>]
|
[<Fact>]
|
||||||
|
Loading…
Reference in New Issue
Block a user