Move functions to chsrc.h

This commit is contained in:
Aoran Zeng 2023-09-15 12:50:56 +08:00
parent 1d81c02911
commit c8d08fe476
2 changed files with 203 additions and 202 deletions

200
chsrc.c
View File

@ -14,206 +14,6 @@
#include "chsrc.h"
#define Chsrc_Version "v0.1.0-20230915.pre"
/**
*
*
* @param check_cmd `progname` `progname`
* 使 python Windows上
* Microsoft Store
*
* @param progname
*/
bool
does_the_program_exist (char* check_cmd, char* progname)
{
char* which = check_cmd;
int ret = system(which);
// char buf[32] = {0}; sprintf(buf, "错误码: %d", ret);
if (0!=ret) {
// xy_warn (xy_strjoin(4, "× 命令 ", progname, " 不存在,", buf));
xy_warn (xy_strjoin(3, "× 命令 ", progname, " 不存在"));
return false;
} else {
xy_success (xy_strjoin(3, "√ 命令 ", progname, " 存在"));
return true;
}
}
/**
* _setsrc codetarget可用源中
*
* @param target
* @param input default def
*/
#define lets_find_mirror(s, input) does_the_input_mirror_exist(s##_sources, s##_sources_n, (char*)#s+3, input)
int
does_the_input_mirror_exist (source_info* sources, size_t size, char* target, char* input)
{
if (0==size) {
xy_error(xy_strjoin(3, "chsrc: 当前 ", target, " 无任何可用源,请联系维护者"));
exit(1);
}
if (1==size) {
xy_success(xy_strjoin(5, "chsrc: ", sources[0].mirror->name, "", target, " 目前唯一可用镜像站,感谢你们的慷慨支持"));
}
if (xy_streql("default", input) || xy_streql("def", input)) {
xy_info ("chsrc: 默认使用维护团队测速第一的源");
return 0;
}
int idx = 0;
source_info source = sources[0];
bool exist = false;
for (int i=0; i<size; i++)
{
source = sources[i];
if (xy_streql(source.mirror->code, input)) {
idx = i;
exist = true;
break;
}
}
if (!exist) {
xy_error (xy_strjoin(3, "chsrc: 镜像站 ", input, " 不存在"));
xy_error (xy_2strjoin("chsrc: 查看可使用源,请使用 chsrc list ", target));
exit(1);
}
return idx;
}
/**
* oh-my-mirrorz.py(@ccmywish)C语言
*/
char*
to_human_readable_speed (double speed)
{
char* scale[] = {"Byte/s", "KByte/s", "MByte/s", "GByte/s", "TByte/s"};
int i = 0;
while (speed > 1024.0)
{
i += 1;
speed /= 1024.0;
}
char* buf = xy_malloc0(64);
sprintf(buf, "%.2f %s", speed, scale[i]);
char* new = NULL;
if (i <= 1 ) new = xy_str_to_red(buf);
else
{
if (i == 2 && speed < 2.00) new = xy_str_to_yellow(buf);
else new = xy_str_to_green(buf);
}
return new;
}
/**
* https://github.com/mirrorz-org/oh-my-mirrorz/blob/master/oh-my-mirrorz.py
* (@ccmywish)C语言
*
* @return -1
*/
double
test_speed_url (const char* url)
{
char* time_sec = "6";
/* 现在我们切换至跳转后的链接来测速,不再使用下述判断
if (xy_str_start_with(url, "https://registry.npmmirror"))
{
// 这里 npmmirror 跳转非常慢,需要1~3秒,所以我们给它留够至少8秒测速时间,否则非常不准
time_sec = "10";
}
*/
// 我们用 —L,因为Ruby China源会跳转到其他地方
// npmmirror 也会跳转
char* curl_cmd = xy_strjoin(6, "curl -qsL -o ", xy_os_devnull,
" -w \"%{http_code} %{speed_download}\" -m", time_sec ,
" -A chsrc/" Chsrc_Version " ", url);
// xy_info (xy_2strjoin("chsrc: 测速 ", url));
FILE* fp = popen(curl_cmd, "r");
char buf[64] = {0};
while(NULL!=fgets(buf, 64, fp));
// puts(buf);
// 如果尾部有换行,删除
char* last_lf = strrchr(buf, '\n');
if (last_lf) *last_lf = '\0';
char* split = strchr(buf, ' ');
if (split) *split = '\0';
// puts(buf); puts(split+1);
int http_code = atoi(buf);
double speed = atof(split+1);
char* speedstr = to_human_readable_speed(speed);
if (200!=http_code) {
char* httpcodestr = xy_str_to_yellow(xy_2strjoin("HTTP码 ", buf));
puts (xy_strjoin(3, speedstr, " | ", httpcodestr));
} else {
puts (speedstr);
}
return speed;
}
#define lets_test_speed(s) lets_test_speed_(s##_sources, s##_sources_n, (char*)#s+3)
int
lets_test_speed_ (source_info* sources, size_t size, const char* target)
{
if (0==size) {
xy_error(xy_strjoin(3, "chsrc: 当前 ", target, " 无任何可用源,请联系维护者"));
exit(1);
}
bool onlyone = false;
if (1==size) onlyone = true;
double speeds[size];
double speed = 0.0;
for (int i=0;i<size;i++)
{
source_info src = sources[i];
const char* url = src.mirror->__bigfile_url;
if (NULL==url) {
xy_warn ("chsrc: 跳过该站点");
speed = 0;
} else {
printf ("%s",xy_strjoin(3, "chsrc: 测速 ", src.mirror->site , " ... "));
fflush(stdout);
speed = test_speed_url (url);
}
speeds[i] = speed;
}
int fastidx = dblary_maxidx (speeds, size);
if (onlyone)
xy_success(xy_strjoin(5, "chsrc: ", sources[fastidx].mirror->name, "", target, " 目前唯一可用镜像站,感谢你们的慷慨支持"));
else
xy_success (xy_2strjoin("chsrc: 最快镜像站: ", sources[fastidx].mirror->name));
return fastidx;
}
/***************************************** 换源 *********************************************/
void
pl_ruby_getsrc (char* option)
{

205
chsrc.h
View File

@ -13,9 +13,167 @@
#include "xy.h"
#include "sources.h"
/* 辅助函数 */
#define Chsrc_Version "v0.1.0-20230915.pre"
/**
*
*
* @param check_cmd `progname` `progname`
* 使 python Windows上
* Microsoft Store
*
* @param progname
*/
bool
does_the_program_exist (char* check_cmd, char* progname)
{
char* which = check_cmd;
int ret = system(which);
// char buf[32] = {0}; sprintf(buf, "错误码: %d", ret);
if (0!=ret) {
// xy_warn (xy_strjoin(4, "× 命令 ", progname, " 不存在,", buf));
xy_warn (xy_strjoin(3, "× 命令 ", progname, " 不存在"));
return false;
} else {
xy_success (xy_strjoin(3, "√ 命令 ", progname, " 存在"));
return true;
}
}
/**
* _setsrc codetarget可用源中
*
* @param target
* @param input default def
*/
#define lets_find_mirror(s, input) does_the_input_mirror_exist(s##_sources, s##_sources_n, (char*)#s+3, input)
int
dblary_maxidx(double* array, int size)
does_the_input_mirror_exist (source_info* sources, size_t size, char* target, char* input)
{
if (0==size) {
xy_error(xy_strjoin(3, "chsrc: 当前 ", target, " 无任何可用源,请联系维护者"));
exit(1);
}
if (1==size) {
xy_success(xy_strjoin(5, "chsrc: ", sources[0].mirror->name, "", target, " 目前唯一可用镜像站,感谢你们的慷慨支持"));
}
if (xy_streql("default", input) || xy_streql("def", input)) {
xy_info ("chsrc: 默认使用维护团队测速第一的源");
return 0;
}
int idx = 0;
source_info source = sources[0];
bool exist = false;
for (int i=0; i<size; i++)
{
source = sources[i];
if (xy_streql(source.mirror->code, input)) {
idx = i;
exist = true;
break;
}
}
if (!exist) {
xy_error (xy_strjoin(3, "chsrc: 镜像站 ", input, " 不存在"));
xy_error (xy_2strjoin("chsrc: 查看可使用源,请使用 chsrc list ", target));
exit(1);
}
return idx;
}
/**
* oh-my-mirrorz.py(@ccmywish)C语言
*/
char*
to_human_readable_speed (double speed)
{
char* scale[] = {"Byte/s", "KByte/s", "MByte/s", "GByte/s", "TByte/s"};
int i = 0;
while (speed > 1024.0)
{
i += 1;
speed /= 1024.0;
}
char* buf = xy_malloc0(64);
sprintf(buf, "%.2f %s", speed, scale[i]);
char* new = NULL;
if (i <= 1 ) new = xy_str_to_red(buf);
else
{
if (i == 2 && speed < 2.00) new = xy_str_to_yellow(buf);
else new = xy_str_to_green(buf);
}
return new;
}
/**
* https://github.com/mirrorz-org/oh-my-mirrorz/blob/master/oh-my-mirrorz.py
* (@ccmywish)C语言
*
* @return -1
*/
double
test_speed_url (const char* url)
{
char* time_sec = "6";
/* 现在我们切换至跳转后的链接来测速,不再使用下述判断
if (xy_str_start_with(url, "https://registry.npmmirror"))
{
// 这里 npmmirror 跳转非常慢,需要1~3秒,所以我们给它留够至少8秒测速时间,否则非常不准
time_sec = "10";
}
*/
// 我们用 —L,因为Ruby China源会跳转到其他地方
// npmmirror 也会跳转
char* curl_cmd = xy_strjoin(6, "curl -qsL -o ", xy_os_devnull,
" -w \"%{http_code} %{speed_download}\" -m", time_sec ,
" -A chsrc/" Chsrc_Version " ", url);
// xy_info (xy_2strjoin("chsrc: 测速 ", url));
FILE* fp = popen(curl_cmd, "r");
char buf[64] = {0};
while(NULL!=fgets(buf, 64, fp));
// puts(buf);
// 如果尾部有换行,删除
char* last_lf = strrchr(buf, '\n');
if (last_lf) *last_lf = '\0';
char* split = strchr(buf, ' ');
if (split) *split = '\0';
// puts(buf); puts(split+1);
int http_code = atoi(buf);
double speed = atof(split+1);
char* speedstr = to_human_readable_speed(speed);
if (200!=http_code) {
char* httpcodestr = xy_str_to_yellow(xy_2strjoin("HTTP码 ", buf));
puts (xy_strjoin(3, speedstr, " | ", httpcodestr));
} else {
puts (speedstr);
}
return speed;
}
int
dblary_maxidx_(double* array, int size)
{
double maxval = array[0];
int maxidx = 0;
@ -29,6 +187,46 @@ dblary_maxidx(double* array, int size)
return maxidx;
}
#define lets_test_speed(s) lets_test_speed_(s##_sources, s##_sources_n, (char*)#s+3)
int
lets_test_speed_ (source_info* sources, size_t size, const char* target)
{
if (0==size) {
xy_error(xy_strjoin(3, "chsrc: 当前 ", target, " 无任何可用源,请联系维护者"));
exit(1);
}
bool onlyone = false;
if (1==size) onlyone = true;
double speeds[size];
double speed = 0.0;
for (int i=0;i<size;i++)
{
source_info src = sources[i];
const char* url = src.mirror->__bigfile_url;
if (NULL==url) {
xy_warn ("chsrc: 跳过该站点");
speed = 0;
} else {
printf ("%s",xy_strjoin(3, "chsrc: 测速 ", src.mirror->site , " ... "));
fflush(stdout);
speed = test_speed_url (url);
}
speeds[i] = speed;
}
int fastidx = dblary_maxidx_ (speeds, size);
if (onlyone)
xy_success(xy_strjoin(5, "chsrc: ", sources[fastidx].mirror->name, "", target, " 目前唯一可用镜像站,感谢你们的慷慨支持"));
else
xy_success (xy_2strjoin("chsrc: 最快镜像站: ", sources[fastidx].mirror->name));
return fastidx;
}
/**
* chsrc
*/
@ -38,6 +236,7 @@ chsrc_logcmd (const char* cmd)
xy_info(xy_2strjoin("chsrc: 运行 ", cmd));
}
void
chsrc_runcmd (const char* cmd)
{
@ -45,6 +244,7 @@ chsrc_runcmd (const char* cmd)
system(cmd);
}
/**
* _setsrc
*/
@ -54,6 +254,7 @@ chsrc_say_selection (source_info* source)
xy_info (xy_strjoin(5, "chsrc: 选中镜像站: ", source->mirror->abbr, " (", source->mirror->code, ")"));
}
void
chsrc_say_thanks (source_info* source)
{