Skip to content

Instantly share code, notes, and snippets.

@myesn
Last active July 31, 2024 16:07
Show Gist options
  • Save myesn/99e2f48e05b9724044b30d45abdcdf0c to your computer and use it in GitHub Desktop.
Save myesn/99e2f48e05b9724044b30d45abdcdf0c to your computer and use it in GitHub Desktop.
使用自定义条件批量取消我对仓库的 Star
#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