// (c) 2010-2011 fantasticswallow (@f_swallow) <http://twitter.com/f_swallow>
// (c) 2011 kim_upsilon (@kim_upsilon) <https://upsilo.net/~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.
-//
+// for more details.
+//
// You should have received a copy of the GNU General Public License along
// with this program. If not, see <http://www.gnu.org/licenses/>, or write to
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
#nullable enable
using System;
-using System.Xml.Serialization;
using System.Collections.Generic;
using System.Windows.Forms;
+using System.Xml.Serialization;
+using OpenTween.Connection;
using OpenTween.Thumbnail;
namespace OpenTween
{
+ [XmlSerializerAssembly(null, null)] // OpenTween アセンブリ内の XmlSerializerContract を使用させる
public class SettingCommon : SettingBase<SettingCommon>
{
#region "Settingクラス基本"
- public static SettingCommon Load()
- => LoadSettings();
+ public static SettingCommon Load(string settingsPath)
+ => LoadSettings(settingsPath);
- public void Save()
- => SaveSettings(this);
+ public void Save(string settingsPath)
+ => SaveSettings(this, settingsPath);
#endregion
- public List<UserAccount> UserAccounts = new List<UserAccount>();
+ public List<UserAccount> UserAccounts = new();
+
+ public Guid? SelectedAccountKey { get; set; } = null;
+
+ [XmlIgnore]
+ public UserAccount? SelectedAccount
+ => this.UserAccounts.Find(x => x.UniqueKey == this.SelectedAccountKey);
+
public string UserName = "";
[XmlIgnore]
public string Password = "";
+
public string EncryptPassword
{
- get => Encrypt(Password);
- set => Password = Decrypt(value);
+ get => this.Encrypt(this.Password);
+ set => this.Password = this.Decrypt(value);
}
public string Token = "";
[XmlIgnore]
public string TokenSecret = "";
+
public string EncryptTokenSecret
{
- get => Encrypt(TokenSecret);
- set => TokenSecret = Decrypt(value);
+ get => this.Encrypt(this.TokenSecret);
+ set => this.TokenSecret = this.Decrypt(value);
}
private string Encrypt(string password)
{
- if (string.IsNullOrEmpty(password)) password = "";
+ if (MyCommon.IsNullOrEmpty(password)) password = "";
if (password.Length > 0)
{
try
return "";
}
}
+
private string Decrypt(string password)
{
- if (string.IsNullOrEmpty(password)) password = "";
+ if (MyCommon.IsNullOrEmpty(password)) password = "";
if (password.Length > 0)
{
try
}
public long UserId = 0;
- public List<string> TabList = new List<string>();
+ public List<string> TabList = new();
public int TimelinePeriod = 90;
public int ReplyPeriod = 180;
public int DMPeriod = 600;
public bool ListLock = false;
public MyCommon.IconSizes IconSize = MyCommon.IconSizes.Icon16;
public bool NewAllPop = true;
- public bool EventNotifyEnabled = true;
- public MyCommon.EVENTTYPE EventNotifyFlag = MyCommon.EVENTTYPE.All;
- public MyCommon.EVENTTYPE IsMyEventNotifyFlag = MyCommon.EVENTTYPE.All;
- public bool ForceEventNotify = false;
- public bool FavEventUnread = true;
public string TranslateLanguage = Properties.Resources.TranslateDefaultLanguage;
- public string EventSoundFile = "";
/// <summary>
/// サウンド再生(タブ別設定より優先)
public bool OneWayLove = true;
public MyCommon.NameBalloonEnum NameBalloon = MyCommon.NameBalloonEnum.NickName;
- public bool PostCtrlEnter = false;
+ public bool PostCtrlEnter = true;
public bool PostShiftEnter = false;
public int CountApi = 60;
public int CountApiReply = 40;
public bool TinyUrlResolve = true;
public bool StartupVersion = true;
public bool StartupFollowers = true;
+
+ /// <summary>
+ /// Twitter API v2 の使用を有効にする
+ /// </summary>
+ [XmlIgnore]
+ public bool EnableTwitterV2Api => false;
+
public bool RestrictFavCheck = false;
public bool AlwaysTop = false;
public string CultureCode = "";
public bool ReadOldPosts = false;
public string Language = "OS";
public bool Nicoms = false;
- public List<string> HashTags = new List<string>();
+ public List<string> HashTags = new();
public string HashSelected = "";
public bool HashIsPermanent = false;
public bool HashIsHead = false;
public int FirstCountApi = 100;
public int SearchCountApi = 100;
public int FavoritesCountApi = 40;
- public string TrackWord = "";
- public bool AllAtReply = false;
- public bool UserstreamStartup = true;
- public int UserstreamPeriod = 0;
public int UserTimelineCountApi = 20;
public int UserTimelinePeriod = 600;
public bool OpenUserTimeline = true;
public int ListCountApi = 100;
public int UseImageService = 0;
public string UseImageServiceName = "";
- public int ListDoubleClickAction = 0;
+
+ [XmlIgnore]
+ public MyCommon.ListItemDoubleClickActionType ListDoubleClickAction { get; set; } = MyCommon.ListItemDoubleClickActionType.Reply;
+
+ [XmlElement(ElementName = nameof(ListDoubleClickAction))]
+ public int ListDoubleClickActionNumeric
+ {
+ get => (int)this.ListDoubleClickAction;
+ set => this.ListDoubleClickAction = (MyCommon.ListItemDoubleClickActionType)value;
+ }
+
public string UserAppointUrl = "";
public bool HideDuplicatedRetweets = false;
public bool EnableImgAzyobuziNet = true;
public int MapThumbnailWidth = 200;
public int MapThumbnailZoom = 15;
public MapProvider MapThumbnailProvider = MapProvider.OpenStreetMap;
- public bool IsListsIncludeRts = false;
+
+ /// <summary>Listの発言取得に公式RTを含める</summary>
+ public bool IsListsIncludeRts = true;
+
public bool TabMouseLock = false;
- public bool IsRemoveSameEvent = false;
public bool IsUseNotifyGrowl = false;
public bool ForceIPv4 = false;
public bool ErrorReportAnonymous = true;
[XmlIgnore]
public Version? SkipUpdateVersion
{
- get => string.IsNullOrEmpty(this.SkipUpdateVersionStr) ? null : Version.Parse(this.SkipUpdateVersionStr);
+ get => MyCommon.IsNullOrEmpty(this.SkipUpdateVersionStr) ? null : Version.Parse(this.SkipUpdateVersionStr);
set => this.SkipUpdateVersionStr = value == null ? "" : value.ToString();
}
[XmlElement(ElementName = nameof(SkipUpdateVersion))]
public string SkipUpdateVersionStr { get; set; } = "";
+
+ public void Validate()
+ {
+ if (this.TimelinePeriod < 0)
+ this.TimelinePeriod = 15;
+
+ if (this.ReplyPeriod < 0)
+ this.ReplyPeriod = 15;
+
+ if (this.DMPeriod < 0)
+ this.DMPeriod = 15;
+
+ if (this.PubSearchPeriod < 0)
+ this.PubSearchPeriod = 30;
+
+ if (this.UserTimelinePeriod < 0)
+ this.UserTimelinePeriod = 15;
+
+ if (this.ListsPeriod < 0)
+ this.ListsPeriod = 15;
+
+ if (!Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.Timeline, this.CountApi))
+ this.CountApi = 60;
+
+ if (!Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.Reply, this.CountApiReply))
+ this.CountApiReply = 40;
+
+ if (this.MoreCountApi != 0 && !Twitter.VerifyMoreApiResultCount(this.MoreCountApi))
+ this.MoreCountApi = 200;
+
+ if (this.FirstCountApi != 0 && !Twitter.VerifyFirstApiResultCount(this.FirstCountApi))
+ this.FirstCountApi = 100;
+
+ if (this.FavoritesCountApi != 0 && !Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.Favorites, this.FavoritesCountApi))
+ this.FavoritesCountApi = 40;
+
+ if (this.ListCountApi != 0 && !Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.List, this.ListCountApi))
+ this.ListCountApi = 100;
+
+ if (this.SearchCountApi != 0 && !Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.PublicSearch, this.SearchCountApi))
+ this.SearchCountApi = 100;
+
+ if (this.UserTimelineCountApi != 0 && !Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.UserTimeline, this.UserTimelineCountApi))
+ this.UserTimelineCountApi = 20;
+
+ // 廃止サービスが選択されていた場合ux.nuへ読み替え
+ if (this.AutoShortUrlFirst < 0)
+ this.AutoShortUrlFirst = MyCommon.UrlConverter.Uxnu;
+
+ UserAccount? selectedAccount;
+ if (this.SelectedAccountKey != null)
+ {
+ selectedAccount = this.SelectedAccount;
+ }
+ else
+ {
+ selectedAccount = this.UserAccounts.Find(
+ x => string.Equals(x.Username, this.UserName, StringComparison.InvariantCultureIgnoreCase)
+ );
+ }
+
+ this.SelectedAccountKey = selectedAccount?.UniqueKey;
+
+ if (selectedAccount?.UserId == 0)
+ selectedAccount.UserId = this.UserId;
+
+ if (MyCommon.IsNullOrEmpty(this.Token))
+ this.UserName = "";
+ }
}
public class UserAccount
{
+ public Guid UniqueKey { get; set; } = Guid.NewGuid();
+
public string Username = "";
public long UserId = 0;
+
+ public APIAuthType TwitterAuthType { get; set; } = APIAuthType.OAuth1;
+
+ public string TwitterOAuth1ConsumerKey { get; set; } = "";
+
+ [XmlIgnore]
+ public string TwitterOAuth1ConsumerSecret { get; set; } = "";
+
+ public string TwitterOAuth1ConsumerSecretEncrypted
+ {
+ get => this.Encrypt(this.TwitterOAuth1ConsumerSecret);
+ set => this.TwitterOAuth1ConsumerSecret = this.Decrypt(value);
+ }
+
+ [XmlIgnore]
+ public string TwitterComCookie { get; set; } = "";
+
+ public string TwitterComCookieEncrypted
+ {
+ get => this.Encrypt(this.TwitterComCookie);
+ set => this.TwitterComCookie = this.Decrypt(value);
+ }
+
public string Token = "";
+
[XmlIgnore]
public string TokenSecret = "";
+
public string EncryptTokenSecret
{
- get => Encrypt(TokenSecret);
- set => TokenSecret = Decrypt(value);
+ get => this.Encrypt(this.TokenSecret);
+ set => this.TokenSecret = this.Decrypt(value);
}
+
+ public TwitterAppToken GetTwitterAppToken()
+ {
+ return new()
+ {
+ AuthType = this.TwitterAuthType,
+ OAuth1CustomConsumerKey = MyCommon.IsNullOrEmpty(this.TwitterOAuth1ConsumerKey) ? null : ApiKey.Create(this.TwitterOAuth1ConsumerKey),
+ OAuth1CustomConsumerSecret = MyCommon.IsNullOrEmpty(this.TwitterOAuth1ConsumerSecret) ? null : ApiKey.Create(this.TwitterOAuth1ConsumerSecret),
+ TwitterComCookie = this.TwitterComCookie,
+ };
+ }
+
+ public ITwitterCredential GetTwitterCredential()
+ {
+ var appToken = this.GetTwitterAppToken();
+
+ return appToken.AuthType switch
+ {
+ APIAuthType.OAuth1
+ => new TwitterCredentialOAuth1(appToken, this.Token, this.TokenSecret),
+ APIAuthType.TwitterComCookie
+ => new TwitterCredentialCookie(appToken),
+ _ => new TwitterCredentialNone(),
+ };
+ }
+
private string Encrypt(string password)
{
- if (string.IsNullOrEmpty(password)) password = "";
+ if (MyCommon.IsNullOrEmpty(password)) password = "";
if (password.Length > 0)
{
try
return "";
}
}
+
private string Decrypt(string password)
{
- if (string.IsNullOrEmpty(password)) password = "";
+ if (MyCommon.IsNullOrEmpty(password)) password = "";
if (password.Length > 0)
{
try
public override string ToString()
=> this.Username;
}
+
+ public enum APIAuthType
+ {
+ None,
+ OAuth1,
+ TwitterComCookie,
+ }
}
\ No newline at end of file