Last active
July 31, 2024 16:07
-
-
Save myesn/99e2f48e05b9724044b30d45abdcdf0c to your computer and use it in GitHub Desktop.
使用自定义条件批量取消我对仓库的 Star
This file contains hidden or 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
#region 必要参数配置 | |
// https://github.com/settings/tokens | |
var accessToken = "ghp_"; | |
/* | |
使用 https://sqlitebrowser.org/ 创建一个 SQLite 数据库文件,并执行以下语句创建表 | |
CREATE TABLE "Stars" ( | |
"Id" INTEGER UNIQUE, | |
"Owner" TEXT NOT NULL, | |
"Name" TEXT NOT NULL, | |
"Archived" INTEGER NOT NULL, | |
"Description" TEXT, | |
"HtmlUrl" TEXT NOT NULL, | |
"StargazersCount" INTEGER, | |
"PushedAt" TEXT, | |
PRIMARY KEY("Id") ON CONFLICT IGNORE | |
) | |
*/ | |
var sqliteDbFilePath = @"D:\dev\db\myesn-github.db"; | |
#endregion | |
var credential = new Credentials(accessToken, AuthenticationType.Bearer); | |
var github = new GitHubClient(new ProductHeaderValue("LINQPad")) { Credentials = credential }; | |
// https://docs.github.com/en/rest/activity/starring?apiVersion=2022-11-28#check-if-a-repository-is-starred-by-the-authenticated-user | |
// https://docs.github.com/en/rest/activity/starring?apiVersion=2022-11-28#unstar-a-repository-for-the-authenticated-user | |
//var iss = await github.Activity.Starring.RemoveStarFromRepo("SonarSource", "sonarqube"); | |
//iss.Dump(); | |
#region 清空表数据 | |
//await DeleteTableDataAsync(); | |
#endregion | |
#region 查询我所有的 Star 并存储到数据库中 | |
//await GetAllForCurrentAndStoreAsync(); | |
#endregion | |
#region 取消对所有已归档仓库的 Star | |
//var archivedStars = await GetAllArchivedsForCurrentAsync(); | |
//Console.WriteLine($"共有 {archivedStars.Count()} 个仓库已归档"); | |
//archivedStars.Dump(); | |
//foreach (var archivedStar in archivedStars)//.Skip(0).Take(100) | |
//{ | |
// // 在浏览器中打开 | |
// //Process.Start(new ProcessStartInfo(archivedStar.HtmlUrl) { UseShellExecute = true }); | |
// | |
// // 直接取消 Star | |
// await UnStarAsync(archivedStar.Owner, archivedStar.Name); | |
//} | |
#endregion | |
#region 查询小于某个日期之前的所有仓库 | |
//var lessThanPushedStars = await GetLessThanPushedAtForCurrentAsync("2024-01-01"); | |
//Console.WriteLine($"共有 {lessThanPushedStars.Count()} 个仓库小于指定日期"); | |
////lessThanPushedStars.Dump(); | |
//foreach (var lessThanPushedStar in lessThanPushedStars)//.Skip(0).Take(100) | |
//{ | |
// // 在浏览器中打开 | |
// //Process.Start(new ProcessStartInfo(lessThanPushedStar.HtmlUrl) { UseShellExecute = true }); | |
// | |
// // 直接取消 Star | |
// await UnStarAsync(lessThanPushedStar.Owner, lessThanPushedStar.Name); | |
//} | |
#endregion | |
#region 取消所有 Stars | |
//var allStars = await GetAllForCurrentAsync(); | |
//Console.WriteLine($"共有 {allStars.Count()} 个仓库"); | |
////lessThanPushedStars.Dump(); | |
//foreach (var allStar in allStars)//.Skip(0).Take(100) | |
//{ | |
// // 在浏览器中打开 | |
// //Process.Start(new ProcessStartInfo(allStar.HtmlUrl) { UseShellExecute = true }); | |
// | |
// // 直接取消 Star | |
// await UnStarAsync(allStar.Owner, allStar.Name); | |
//} | |
#endregion | |
async Task DeleteTableDataAsync() | |
{ | |
using var conn = GetSQLiteConnection(); | |
var sql = "delete from Stars"; | |
await conn.ExecuteAsync(sql); | |
Console.WriteLine("表数据清空完成"); | |
} | |
// 从数据库中获取所有已存档的 Stars | |
async Task<IEnumerable<StarRepositoryDto>> GetLessThanPushedAtForCurrentAsync(string pushedAt) | |
{ | |
using var conn = GetSQLiteConnection(); | |
var sql = "select * from Stars where PushedAt<@PushedAt order by PushedAt asc"; | |
var dtos = await conn.QueryAsync<StarRepositoryDto>(sql, new { PushedAt = pushedAt }); | |
return dtos; | |
} | |
// 取消 Star | |
async Task UnStarAsync(string owner, string name) | |
{ | |
await github.Activity.Starring.RemoveStarFromRepo(owner, name); | |
using var conn = GetSQLiteConnection(); | |
var sql = "delete from Stars where Owner=@Owner and Name=@Name"; | |
await conn.ExecuteAsync(sql, new { Owner = owner, Name = name }); | |
Console.WriteLine($"unstar: {owner}/{name}"); | |
} | |
// 获取 < 指定推送日期的 Stars | |
async Task<IEnumerable<StarRepositoryDto>> GetAllArchivedsForCurrentAsync() | |
{ | |
using var conn = GetSQLiteConnection(); | |
var sql = "select * from Stars where Archived=@Archived order by PushedAt asc"; | |
var dtos = await conn.QueryAsync<StarRepositoryDto>(sql, new { Archived = true }); | |
return dtos; | |
} | |
// 获取所有 Stars | |
async Task<IEnumerable<StarRepositoryDto>> GetAllForCurrentAsync() | |
{ | |
using var conn = GetSQLiteConnection(); | |
var sql = "select * from Stars"; | |
var dtos = await conn.QueryAsync<StarRepositoryDto>(sql); | |
return dtos; | |
} | |
async Task StoreStarsAsync(IEnumerable<StarRepositoryDto> dtos) | |
{ | |
using var conn = GetSQLiteConnection(); | |
var insertSql = @"insert into Stars(Id, Owner,Name,Archived,Description,HtmlUrl,StargazersCount,PushedAt) values (@Id, @Owner,@Name,@Archived,@Description,@HtmlUrl,@StargazersCount,@PushedAt)"; | |
await conn.ExecuteAsync(insertSql, dtos); | |
} | |
// https://stackoverflow.com/a/15292958 | |
SQLiteConnection GetSQLiteConnection() => new SQLiteConnection(@$"Data Source={sqliteDbFilePath};Version=3;"); | |
// 获取我的所有 Star 并存储到 SQLite 数据库 | |
async Task GetAllForCurrentAndStoreAsync() | |
{ | |
// https://docs.github.com/en/rest/activity/starring?apiVersion=2022-11-28#list-repositories-starred-by-the-authenticated-user | |
var startPage = 1; | |
while (true) | |
{ | |
Console.WriteLine($"开始查询第{startPage}页"); | |
var myStars = await GetForCurrentByPageAsync(startPage); | |
if (!myStars.Any()) | |
{ | |
break; | |
} | |
var myStarDtos = Map(myStars); | |
await StoreStarsAsync(myStarDtos); | |
Console.WriteLine($"第{startPage}页已存储"); | |
startPage++; | |
} | |
Console.WriteLine("我的 Star 数据获取并存储完成"); | |
} | |
IEnumerable<StarRepositoryDto> Map(IEnumerable<Repository> repositories) => repositories.Select(x => new StarRepositoryDto( | |
x.Id, | |
x.Owner.Login, | |
x.Name, | |
x.Archived, | |
x.Description, | |
x.HtmlUrl, | |
x.StargazersCount, | |
x.PushedAt?.ToString("yyyy-MM-dd") | |
)); | |
async Task<IEnumerable<Repository>> GetForCurrentByPageAsync(int startPage) | |
{ | |
var myStars = await github.Activity.Starring.GetAllForCurrent( | |
new StarredRequest | |
{ | |
SortProperty = StarredSort.Created, | |
SortDirection = SortDirection.Ascending, | |
}, | |
new ApiOptions | |
{ | |
StartPage = startPage, | |
PageSize = 100, | |
PageCount = 1, | |
} | |
); | |
return myStars; | |
} | |
//record class StarRepositoryDto(long Id, string Owner, string Name, bool Archived, string Description, string HtmlUrl, DateTimeOffset? PushedAt); | |
class StarRepositoryDto | |
{ | |
public long Id { get; set; } | |
public string Owner { get; set; } | |
public string Name { get; set; } | |
public bool Archived { get; set; } | |
public string Description { get; set; } | |
public string HtmlUrl { get; set; } | |
public int StargazersCount { get; set; } | |
public string? PushedAt { get; set; } | |
public StarRepositoryDto() | |
{ | |
} | |
public StarRepositoryDto(long id, string owner, string name, bool archived, string description, string htmlUrl, int stargazersCount, string? pushedAt) | |
{ | |
Id = id; | |
Owner = owner; | |
Name = name; | |
Archived = archived; | |
Description = description; | |
HtmlUrl = htmlUrl; | |
StargazersCount = stargazersCount; | |
PushedAt = pushedAt; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment