乱码三千 – 分享实用IT技术

乱码三千 – 码出一个新世界


  • 首页

  • 归档

  • 搜索

使用python利用第三方登录实现自动化简书发布文章

发表于 2020-09-07

话不多说 首先附上代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import time

from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait

import re

import linecache


class Main(object):
# init
def __init__(self, file):
self.title = ''
self.content = ''
self.category = ''
self.tags = ''
# OsChina的系统分类, 设个默认值
self.osChina_sys_category = '编程语言'
# CSDN的文章分类, 设个默认值
self.csdn_article_category = '原创'
# CSDN的博客分类, 设个默认值
self.csdn_blog_category = '后端'
self.read_file(file)

# 读取MD中的title, content, self_category, self_tags, osChina_sys_category, csdn_article_category, csdn_blog_category
def read_file(self, markdown_file):
self.title = linecache.getline(markdown_file, 2).split('title: ')[1].strip('\n')
with open(markdown_file, 'r', encoding='UTF-8') as f:
self.content = f.read().split('-->\n')[1]
# 重置文件指针偏移量
f.seek(0)
for line in f.readlines():
if re.search('self_category: ', line) is not None:
self.category = line.split('self_category: ')[1].strip('\n')
elif re.search('self_tags: ', line) is not None:
self.tags = line.split('self_tags: ')[1].strip('\n')
elif re.search('osChina_sys_category: ', line) is not None:
self.osChina_sys_category = line.split('osChina_sys_category: ')[1].strip('\n')
elif re.search('csdn_article_category: ', line) is not None:
self.csdn_article_category = line.split('csdn_article_category: ')[1].strip('\n')
elif re.search('csdn_blog_category: ', line) is not None:
self.csdn_blog_category = line.split('csdn_blog_category: ')[1].strip('\n')




# QQ授权登录, 使用前提是QQ客户端在线
def qq(driver, timeout):
# 切换到最新打开的窗口
window_handles = driver.window_handles
driver.switch_to.window(window_handles[-1])

print('qq authorize title is ', driver.title)

# 切换iframe
iframe = WebDriverWait(driver, timeout).until(lambda d: d.find_element_by_id('ptlogin_iframe'))
driver.switch_to.frame(iframe)

# 点击头像进行授权登录
login = WebDriverWait(driver, timeout).until(lambda d: d.find_element_by_xpath('//*[@id="qlogin_list"]/a[1]'))
login.click()
# 简书
class JianShu(object):
@staticmethod
def post(main, timeout, self_timeout=3):
# 1.跳转登陆
login = 'https://www.jianshu.com/sign_in'
driver = webdriver.Chrome()
driver.get(login)

# 2.窗口最大化
driver.maximize_window()

# 3.使用QQ授权登录
driver.find_element_by_xpath('/html/body/div[1]/div[2]/div/div/ul/li[3]/a/i').click()
driver.close()
qq(driver, timeout)

# 4.点击"写文章"
write_blog = WebDriverWait(driver, timeout).until(lambda d: d.find_element_by_xpath('/html/body/nav/div/a[2]'))
write_blog = WebDriverWait(driver, timeout).until(lambda d: d.find_elements_by_class_name('/html/body/nav/div/a[2]'))
write_blog.click()
driver.close()
time.sleep(3)
# window_handles = driver.window_handles
#driver.switch_to.window(window_handles[-1])

# 5.点击指定分类
classify = WebDriverWait(driver, timeout).until(lambda d: d.find_elements_by_class_name('_3DM7w'))
for c in classify:
html = c.get_attribute('innerHTML')
if main.category in html:
c.click()
else:
# TODO 如果分类不存在,还可以直接新建分类
pass

# 6.点击'新建文章'
time.sleep(self_timeout)
new_article = WebDriverWait(driver, timeout).until(
lambda d: d.find_element_by_xpath('//*[@id="root"]/div/div[2]/div[1]/div/div/div/div[1]/i'))
new_article.click()
article = WebDriverWait(driver, timeout).until(
lambda d: d.find_element_by_xpath('//*[@id="root"]/div/div[2]/div[1]/div/div/div/ul/li[1]'))
article.click()

# 7.填写标题, 内容
time.sleep(self_timeout)
title = driver.find_element_by_class_name('_24i7u')
title.clear()
title.send_keys(main.title)
content = driver.find_element_by_id('arthur-editor')
content.clear()
content.send_keys(main.content)

# 8.保存草稿
driver.find_element_by_xpath('//*[@id="root"]/div/div[2]/div[2]/div/div/div/div/ul/li[8]/a').click()
# 8.发布文章
# driver.find_element_by_xpath('//*[@id="root"]/div/div[2]/div[2]/div/div/div/div/ul/li[1]/a').click()


if __name__ == '__main__':
md_file = 'auto.md'
print("Markdown File is ", md_file)

timeout = 30
main = Main(md_file)

# 简书
jian_shu = JianShu()
jian_shu.post(main, timeout)

PS:Selenium操纵浏览器是依赖于浏览器驱动程序的,不同版本的浏览器需要下载不同版本的驱动, 否则程序无法运行, 下面贴出的是谷歌和火狐浏览器驱动程序的下载地址。

Chrome ( chromedriver ) Firefox ( geckodriver )
官方下载 官方下载
淘宝镜像 淘宝镜像
备用下载 备用下载

关于谷歌驱动的下载安装, 详情可参见文章《Web自动化框架selenium的介绍与使用》

本文为作者原创 转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

如何在浏览器中手动设置cookies值实现前端分离调试

发表于 2020-09-07

在前端开发中经常会碰到需要cookies调试的情况, 下面介绍一下如何在浏览器中手动设置cookies值

img

1.查看cookies值

1
document.cookie

2.设置cookies值

1
document.cookie='name=Jack';

3.给cookies设置有效时间 默认浏览器关闭失效

1
2
3
var oDate=new Date();
oDate.setDate(oDate.getDate()+7);//设置为当前时间起算7天后过期
document.cookie='name=Jack;expires='+oDate.toGMTString();

4.移除cookies

1
setCookie(key,"",-1);//把cookie设置为过期

函数封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function setCookie(key,value,t){
var oDate=new Date();
oDate.setDate(oDate.getDate()+t);
document.cookie=key+"="+value+"; expires="+oDate.toDateString();

}
function getCookie(key){
var arr1=document.cookie.split("; ");//由于cookie是通过一个分号+空格的形式串联起来的,所以这里需要先按分号空格截断,变成[name=Jack,pwd=123456,age=22]数组类型;
for(var i=0;i<arr1.length;i++){
var arr2=arr1[i].split("=");//通过=截断,把name=Jack截断成[name,Jack]数组;
if(arr2[0]==key){
return decodeURI(arr2[1]);
}
}

//封装一个移除cookie的函数
function removeCookie(key){
setCookie(key,"",-1);//把cookie设置为过期

}

本文为作者原创 转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

如何设置通过Postman实现API网关的请求签名与调试

发表于 2020-09-07

前言
Postman是一个非常强大的HTTP发包测试工具, 目前Postman已经提供了Windows/Mac/Linux系统的客户端的下载,使用很方便。不过API网关的调试,需要对HTTP请求进行签名才能调用,无法使用简单的curl等发包工具完成,但我们可以使用Postman工具提供的Pre-request Script脚本来实现API网关的签名功能,实现API的调试功能,本文主要介绍如何使用Postman调试API网关接口。

核心代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
var appKey = "<YOUR APP KEY>";
var appSecret = "<YOUR APP SECRET>";

var md5 = calcMd5();
var date = new Date().toString();
var nonce = createUuid();

var textToSign = "";
textToSign += request.method + "\n";
textToSign += request.headers["accept"] + "\n";
textToSign += md5 + "\n";
textToSign += request.headers["content-type"] + "\n";
textToSign += date + "\n";

var headers = headersToSign();
var signatureHeaders;
var sortedKeys = Array.from(headers.keys()).sort()
for (var headerName of sortedKeys) {
textToSign += headerName + ":" + headers.get(headerName) + "\n";
signatureHeaders = signatureHeaders ? signatureHeaders + "," + headerName : headerName;
}
textToSign += urlToSign();
console.log("textToSign\n" + textToSign.replace(/\n/g, "#"));
var hash = CryptoJS.HmacSHA256(textToSign, appSecret)
console.log("hash:" + hash)
var signature = hash.toString(CryptoJS.enc.Base64)
console.log("signature:" + signature)

pm.globals.set('AppKey', appKey);
pm.globals.set('Md5', md5);
pm.globals.set("Date", date);
pm.globals.set("Signature", signature);
pm.globals.set("SignatureHeaders", signatureHeaders);
pm.globals.set("Nonce", nonce);

function headersToSign() {
var headers = new Map();
for (var name in request.headers) {
name = name.toLowerCase();
if (!name.startsWith('x-ca-')) {
continue;
}
if (name === "x-ca-signature" || name === "x-ca-signature-headers" || name == "x-ca-key" || name === 'x-ca-nonce') {
continue;
}
var value = request.headers[name];
headers.set(name, value);
}
headers.set('x-ca-key', appKey);
headers.set('x-ca-nonce', nonce);
return headers;
}

function urlToSign() {
var params = new Map();
var contentType = request.headers["content-type"];
if (contentType && contentType.startsWith('application/x-www-form-urlencoded')) {
const formParams = request.data.split("&");
formParams.forEach((p) => {
const ss = p.split('=');
params.set(ss[0], ss[1]);
})
}
const ss = request.url.split('?');
if (ss.length > 1 && ss[1]) {
const queryParams = ss[1].split('&');
queryParams.forEach((p) => {
const ss = p.split('=');
params.set(ss[0], ss[1]);
})
}

var sortedKeys = Array.from(params.keys())
sortedKeys.sort();

var l1 = ss[0].lastIndexOf('/');
var url = ss[0].substring(l1);
var first = true;
var qs
for (var k of sortedKeys) {
var s = k + "=" + params.get(k);
qs = qs ? qs + "&" + s : s;
console.log("key=" + k + " value=" + params.get(k));
}
return qs ? url + "?" + qs : url;
}

function calcMd5() {
var contentType = request.headers["content-type"];
if (request.data && !contentType.startsWith('application/x-www-form-urlencoded')) {
var data = request.data;
var md5 = CryptoJS.MD5(data);
var md5String = md5.toString(CryptoJS.enc.Base64);
console.log("data:" + data + "\nmd5:" + md5String);
return md5String;
} else {
return "";
}
}

function createUuid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
return v.toString(16);
});
}

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

关于mv 移动文件时出现Argument list too long的解决方案

发表于 2020-09-03

移动所有文件到指定目录

1
mv 需要移动的目录/* 目标目录/

当出现文件过多时报错:Argument list too long

解决方案:

移动文件:

1
find sourcePath/ -name "*.txt"  -exec mv {} targetPath/  \;

or:

1
find sourcePath/ -type f  -exec mv {} targetPath/  \;

查看所有行目录下所有txt文件的行:

1
find sourcePath/ -name "*.txt" |xargs cat |wc -l

只移动前5个文件

1
mv `ls |sed -n 1,5p  /post

只拷贝前5个文件

1
cp -R `ls |sed -n 1,5p /post

本文为作者原创 转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

关于linux指令sed的使用

发表于 2020-09-01

sed -i 主要作用就是操作文本 如下:

去掉 “行首” 带“@”的首字母@

1
sed -i 's/^@//' file

特定字符串的行前插入新行

1
sed -i '/特定字符串/i 新行字符串' file

特定字符串的行后插入新行

1
sed -i '/特定字符串/a 新行字符串' file

特定字符串的删除

1
sed -i '/字符串/d' file

提示: 以上斜杠可以换成~ 一样实现相同功能

问题场景:

在mac上,使用sed命令把当前目录的test.sql文件内容中的a替换为b,使用命令:sed -i “s/a/b/g” test.sql

遇到报错:sed: 1: “grep …”: extra characters at the end of g command

解决:

在mac中使用sed命令在-i参数后面需要带一对双引号””,正确格式如下:

1
sed -i "" "s/a/b/g" test.sql

原因

sed -i 后面的双引号中可写任意字符串或者为空,含义是用于生成源文件的备份文件的文件名。比如上面的例子:sed -i “_tmp” “s/a/b/g” test.sql,在替换test.sql的同时,还会生成test.sql_tmp的备份文件

本文为作者原创 转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

Git撤销&回滚操作(git reset 和 get revert)

发表于 2020-09-01

git的工作流

工作区:即自己当前分支所修改的代码,git add xx 之前的!不包括 git add xx 和 git commit xxx 之后的。

暂存区:已经 git add xxx 进去,且未 git commit xxx 的。

本地分支:已经git commit -m xxx 提交到本地分支的。
这里写图片描述


代码回滚

在上传代码到远程仓库的时候,不免会出现问题,任何过程都有可能要回滚代码:

1、在工作区的代码

git checkout – a.txt # 丢弃某个文件,或者
git checkout – . # 丢弃全部

注意:git checkout – . 丢弃全部,也包括:新增的文件会被删除、删除的文件会恢复回来、修改的文件会回去。这几个前提都说的是,回到暂存区之前的样子。对之前保存在暂存区里的代码不会有任何影响。对commit提交到本地分支的代码就更没影响了。当然,如果你之前压根都没有暂存或commit,那就是回到你上次pull下来的样子了。

2、代码git add到缓存区,并未commit提交

git reset HEAD . 或者
git reset HEAD a.txt

这个命令仅改变暂存区,并不改变工作区,这意味着在无任何其他操作的情况下,工作区中的实际文件同该命令运行之前无任何变化

3、git commit到本地分支、但没有git push到远程

git log # 得到你需要回退一次提交的commit id
git reset –hard # 回到其中你想要的某个版
或者
git reset –hard HEAD^ # 回到最新的一次提交
或者
git reset HEAD^ # 此时代码保留,回到 git add 之前

4、git push把修改提交到远程仓库
1)通过git reset是直接删除指定的commit

git log # 得到你需要回退一次提交的commit id
git reset –hard
git push origin HEAD –force # 强制提交一次,之前错误的提交就从远程仓库删除

2)通过git revert是用一次新的commit来回滚之前的commit

git log # 得到你需要回退一次提交的commit id
git revert # 撤销指定的版本,撤销也会作为一次提交进行保存

3) git revert 和 git reset的区别
- git revert是用一次新的commit来回滚之前的commit,此次提交之前的commit都会被保留;
- git reset是回到某次提交,提交及之前的commit都会被保留,但是此commit id之后的修改都会被删除

开发过程中,你肯定会遇到这样的场景:

场景一:

糟了,我刚把不想要的代码,commit到本地仓库中了,但是还没有做push操作!

场景二:

彻底完了,刚线上更新的代码出现问题了,需要还原这次提交的代码!

场景三:

刚才我发现之前的某次提交太愚蠢了,现在想要干掉它!

撤销

上述场景一,在未进行git push前的所有操作,都是在“本地仓库”中执行的。我们暂且将“本地仓库”的代码还原操作叫做“撤销”!

情况一:文件被修改了,但未执行git add操作(working tree内撤销)

1
2
3
4
5
git checkout fileName



git checkout .

情况二:同时对多个文件执行了git add操作,但本次只想提交其中一部分文件

1
2
3
4
5
6
7
8
9
10
11
12
13
$ git add *



$ git status



# 取消暂存



$ git reset HEAD <filename>

情况三:文件执行了git add操作,但想撤销对其的修改(index内回滚)

1
2
3
4
5
6
7
8
9
10
11
12
13
# 取消暂存



git reset HEAD fileName



# 撤销修改



git checkout fileName

情况四:修改的文件已被git commit,但想再次修改不再产生新的Commit

1
2
3
4
5
6
7
8
9
# 修改最后一次提交 



$ git add sample.txt



$ git commit --amend -m"说明"

情况五:已在本地进行了多次git commit操作,现在想撤销到其中某次Commit

1
git reset [--hard|soft|mixed|merge|keep] [commit|HEAD]

具体参数和使用说明,请查看:Git Pro深入浅出(二)中的重置揭秘部分

回滚

上述场景二,已进行git push,即已推送到“远程仓库”中。我们将已被提交到“远程仓库”的代码还原操作叫做“回滚”!注意:对远程仓库做回滚操作是有风险的,需提前做好备份和通知其他团队成员!

如果你每次更新线上,都会打tag,那恭喜你,你可以很快的处理上述场景二的情况

1
git checkout <tag>

如果你回到当前HEAD指向

1
git checkout <branch_name>

情况一:撤销指定文件到指定版本

1
2
3
4
5
6
7
8
9
10
11
12
13
# 查看指定文件的历史版本



git log <filename>



# 回滚到指定commitID



git checkout <commitID> <filename>

情况二:删除最后一次远程提交

方式一:使用revert

1
2
3
4
5
git revert HEAD



git push origin master

方式二:使用reset

1
2
3
4
5
git reset --hard HEAD^



git push origin master -f

二者区别:

  • revert是放弃指定提交的修改,但是会生成一次新的提交,需要填写提交注释,以前的历史记录都在;
  • reset是指将HEAD指针指到指定提交,历史记录中不会出现放弃的提交记录。

情况三:回滚某次提交

1
2
3
4
5
6
7
8
9
# 找到要回滚的commitID



git log



git revert commitID

删除某次提交

1
git log --oneline -n5

1
git rebase -i "commit id"^

注意:需要注意最后的^号,意思是commit id的前一次提交

1
git rebase -i "5b3ba7a"^

在编辑框中删除相关commit,如pick 5b3ba7a test2,然后保存退出(如果遇到冲突需要先解决冲突)!

1
git push origin master -f

通过上述操作,如果你想对历史多个commit进行处理或者,可以选择git rebase -i,只需删除对应的记录就好。rebase还可对 commit 消息进行编辑,以及合并多个commit。

本文为作者原创 转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

解决pip下载速度慢的问题

发表于 2020-09-01

在我们经常使用pip安装插件模块的时候,有没有发现下载速度很慢,但有些有强迫症的人面对几k几十k每秒的速度绝对忍不了,是不是,那么,方法来了。

问题描述

一句话就是使用pip下载过慢,想要快起来,起来,来。

解决过程

问题分析

pip下载速度过慢的原因就是pip默认使用的是国外的镜像源,那么,我使用国内的镜像源,问题不就解决了。

有两种方法,方法一临时有效,方法二永久生效。

方法一:下载时加入参数-i [镜像源地址]

1
2
3
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple jieba
或者
pip install jieba -i https://pypi.tuna.tsinghua.edu.cn/simple

方法二:设置源

使用方法一,需要每次在下载时都要带参数,不想麻烦的试试方法二吧。

1
2
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
pip config set install.trusted-host mirrors.aliyun.com

img

附: 国内镜像源地址

1
2
3
4
5
6
7
8
9
# pip国内镜像源。
#
# 阿里云 http://mirrors.aliyun.com/pypi/simple/
# 中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/
# 豆瓣 http://pypi.douban.com/simple
# Python官方 https://pypi.python.org/simple/
# v2ex http://pypi.v2ex.com/simple/
# 中国科学院 http://pypi.mirrors.opencas.cn/simple/
# 清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/

本文为作者原创 转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

解决homebrew长时间停在Updating Homebrew 这个步骤

发表于 2020-09-01

在国内的网络环境下使用 Homebrew 安装软件的过程中可能会长时间卡在 Updating Homebrew 这个步骤。

例:执行 brew install composer 命令

1
2
➜  ~ brew install composer
Updating Homebrew... # 如果碰到长时间卡在这里,参考以下 2 种处理方法

方法 1:按住 control + c 取消本次更新操作

1
2
3
➜  ~ brew install composer
Updating Homebrew...
^C

按住 control + c 之后命令行会显示 ^C,就代表已经取消了 Updating Homebrew 操作

大概不到 1 秒钟之后就会去执行我们真正需要的安装操作了

1
2
3
4
5
➜  ~ brew install composer
Updating Homebrew...
^C==> Satisfying dependencies
==> Downloading https://getcomposer.org/download/1.7.2/composer.phar
...

这个方法是临时的、一次性的

方法 2:使用 Alibaba 的 Homebrew 镜像源进行加速

平时我们执行 brew 命令安装软件的时候,跟以下 3 个仓库地址有关:

  1. brew.git
  2. homebrew-core.git
  3. homebrew-bottles

通过以下操作将这 3 个仓库地址全部替换为 Alibaba 提供的地址

1. 替换 / 还原 brew.git 仓库地址

1
2
3
4
5
6
7
8
9
# 替换成阿里巴巴的 brew.git 仓库地址:
cd "$(brew --repo)"
git remote set-url origin https://mirrors.aliyun.com/homebrew/brew.git

#=======================================================

# 还原为官方提供的 brew.git 仓库地址
cd "$(brew --repo)"
git remote set-url origin https://github.com/Homebrew/brew.git

2. 替换 / 还原 homebrew-core.git 仓库地址

1
2
3
4
5
6
7
8
9
# 替换成阿里巴巴的 homebrew-core.git 仓库地址:
cd "$(brew --repo)/Library/Taps/homebrew/homebrew-core"
git remote set-url origin https://mirrors.aliyun.com/homebrew/homebrew-core.git

#=======================================================

# 还原为官方提供的 homebrew-core.git 仓库地址
cd "$(brew --repo)/Library/Taps/homebrew/homebrew-core"
git remote set-url origin https://github.com/Homebrew/homebrew-core.git

3. 替换 / 还原 homebrew-bottles 访问地址

这个步骤跟你的 macOS 系统使用的 shell 版本有关系

所以,先来查看当前使用的 shell 版本

1
2
3
4
echo $SHELL

# 如果你的输出结果是 /bin/zsh,参考?的 zsh 终端操作方式
# 如果你的输出结果是 /bin/bash,参考?的 bash 终端操作方式

3.1 zsh 终端操作方式

1
2
3
4
5
6
7
8
9
10
# 替换成阿里巴巴的 homebrew-bottles 访问地址:
echo 'export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.aliyun.com/homebrew/homebrew-bottles' >> ~/.zshrc
source ~/.zshrc

#=======================================================

# 还原为官方提供的 homebrew-bottles 访问地址
vi ~/.zshrc
# 然后,删除 HOMEBREW_BOTTLE_DOMAIN 这一行配置
source ~/.zshrc

3.2 bash 终端操作方式

1
2
3
4
5
6
7
8
9
10
# 替换 homebrew-bottles 访问 URL:
echo 'export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.aliyun.com/homebrew/homebrew-bottles' >> ~/.bash_profile
source ~/.bash_profile

#=======================================================

# 还原为官方提供的 homebrew-bottles 访问地址
vi ~/.bash_profile
# 然后,删除 HOMEBREW_BOTTLE_DOMAIN 这一行配置
source ~/.bash_profile

HomeBrew快速安装

自动脚本(全部国内地址)(在Mac os终端中复制粘贴回车下面这句话)

1
/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"

这行命令就是这位大佬发布的:金牛肖马

本文为作者原创 转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

hexo 设置新建文章时自动打开md编辑器

发表于 2020-09-01

在Hexo中新建一篇博文非常简单,只需要在命令行中键入以下命令然后回车即可:

1
hexo new "The title of your blog"

然后hexo就会在hexo的根目录下的source目录下的_post目录下自动创建相对应的md文件。然后我们只需要找到刚刚生成的文件进行编辑就可以了。

但是一旦文章比较多的情况下,我们就需要在成堆的md文件中找刚刚创建的博文,这就比较麻烦。


好在hexo的github上有类似的issue,然后hexo作者也可给出了解决方法:

ou can try to listen to the new event. For example:

1
2
3
4
5
6
7
8
9
10
11
var exec = require('child_process').exec;


hexo.on('new', function(path){
exec('vi', [path]);
});

// Hexo 3
hexo.on('new', function(data){
exec('vi', [data.path]);
});

根据作者给的示例给出了下列的解决方法:

  • 首先在hexo目录下的script目录下创建一个js脚本(没有的这个目录的话自己创建一个)。

  • js脚本的命名自定义,然后在脚本中写入以下代码。

  • windows端:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var spawn = require('child_process').exec;

    // Hexo 2.x 用户复制这段
    hexo.on('new', function(path){
    spawn('start "markdown编辑器绝对路径.exe" ' + path);
    });

    // Hexo 3 用户复制这段
    hexo.on('new', function(data){
    spawn('start "markdown编辑器绝对路径.exe" ' + data.path);
    });
  • mac os端:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var exec = require('child_process').exec;

    // Hexo 2.x 用户复制这段
    hexo.on('new', function(path){
    exec('open -a "markdown编辑器绝对路径.app" ' + path);
    });
    // Hexo 3 用户复制这段
    hexo.on('new', function(data){
    exec('open -a "markdown编辑器绝对路径.app" ' + data.path);
    });

不过我在网上找了很久都没有发现有linux端的操作脚本,然后自己试着改了下,能在我的电脑(debian/ubuntu试过了没问题)上成功跑起来了,po下代码:

1
2
3
4
5
6
7
8
9
10
var exec = require('child_process').exec;

// Hexo 2.x 用户复制这段
hexo.on('new', function(path){
exec('vim ' + path);
});
// Hexo 3 用户复制这段
hexo.on('new', function(data){
exec('vim ' + data.path);
});

本文为作者原创 转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

idea最新激活码

发表于 2020-09-01

第一个激活码

1
7PNLXJPODN-eyJsaWNlbnNlSWQiOiI3UE5MWEpQT0ROIiwibGljZW5zZWVOYW1lIjoi6aOe6LGhIOeggeWGnCIsImFzc2lnbmVlTmFtZSI6IiIsImFzc2lnbmVlRW1haWwiOiIiLCJsaWNlbnNlUmVzdHJpY3Rpb24iOiIiLCJjaGVja0NvbmN1cnJlbnRVc2UiOmZhbHNlLCJwcm9kdWN0cyI6W3siY29kZSI6IklJIiwiZmFsbGJhY2tEYXRlIjoiMjAyMC0wMS0xNSIsInBhaWRVcFRvIjoiMjAyMS0wMS0xNCJ9LHsiY29kZSI6IkFDIiwiZmFsbGJhY2tEYXRlIjoiMjAyMC0wMS0xNSIsInBhaWRVcFRvIjoiMjAyMS0wMS0xNCJ9LHsiY29kZSI6IkRQTiIsImZhbGxiYWNrRGF0ZSI6IjIwMjAtMDEtMTUiLCJwYWlkVXBUbyI6IjIwMjEtMDEtMTQifSx7ImNvZGUiOiJQUyIsImZhbGxiYWNrRGF0ZSI6IjIwMjAtMDEtMTUiLCJwYWlkVXBUbyI6IjIwMjEtMDEtMTQifSx7ImNvZGUiOiJHTyIsImZhbGxiYWNrRGF0ZSI6IjIwMjAtMDEtMTUiLCJwYWlkVXBUbyI6IjIwMjEtMDEtMTQifSx7ImNvZGUiOiJETSIsImZhbGxiYWNrRGF0ZSI6IjIwMjAtMDEtMTUiLCJwYWlkVXBUbyI6IjIwMjEtMDEtMTQifSx7ImNvZGUiOiJDTCIsImZhbGxiYWNrRGF0ZSI6IjIwMjAtMDEtMTUiLCJwYWlkVXBUbyI6IjIwMjEtMDEtMTQifSx7ImNvZGUiOiJSUzAiLCJmYWxsYmFja0RhdGUiOiIyMDIwLTAxLTE1IiwicGFpZFVwVG8iOiIyMDIxLTAxLTE0In0seyJjb2RlIjoiUkMiLCJmYWxsYmFja0RhdGUiOiIyMDIwLTAxLTE1IiwicGFpZFVwVG8iOiIyMDIxLTAxLTE0In0seyJjb2RlIjoiUkQiLCJmYWxsYmFja0RhdGUiOiIyMDIwLTAxLTE1IiwicGFpZFVwVG8iOiIyMDIxLTAxLTE0In0seyJjb2RlIjoiUEMiLCJmYWxsYmFja0RhdGUiOiIyMDIwLTAxLTE1IiwicGFpZFVwVG8iOiIyMDIxLTAxLTE0In0seyJjb2RlIjoiUk0iLCJmYWxsYmFja0RhdGUiOiIyMDIwLTAxLTE1IiwicGFpZFVwVG8iOiIyMDIxLTAxLTE0In0seyJjb2RlIjoiV1MiLCJmYWxsYmFja0RhdGUiOiIyMDIwLTAxLTE1IiwicGFpZFVwVG8iOiIyMDIxLTAxLTE0In0seyJjb2RlIjoiREIiLCJmYWxsYmFja0RhdGUiOiIyMDIwLTAxLTE1IiwicGFpZFVwVG8iOiIyMDIxLTAxLTE0In0seyJjb2RlIjoiREMiLCJmYWxsYmFja0RhdGUiOiIyMDIwLTAxLTE1IiwicGFpZFVwVG8iOiIyMDIxLTAxLTE0In0seyJjb2RlIjoiUlNVIiwiZmFsbGJhY2tEYXRlIjoiMjAyMC0wMS0xNSIsInBhaWRVcFRvIjoiMjAyMS0wMS0xNCJ9XSwiaGFzaCI6IjE2MjYyNDE0LzAiLCJncmFjZVBlcmlvZERheXMiOjcsImF1dG9Qcm9sb25nYXRlZCI6ZmFsc2UsImlzQXV0b1Byb2xvbmdhdGVkIjpmYWxzZX0=-PPKBrTimCndddUn6boFzGrhkBW8JU7D4lQuuOxKq4rdA4U3IQix9gM+8UYYUaJCQMg8zPmE42QPSkSWneE5VAShaAwhfdu5/D2KbG9jv2uoy8deXu4YWYRHRmn6TdU1/fBhOsbI4EbqYoRDjQ6R+ibYQBanurdcdySH8wDx2kiEBOEbbHJ9ekkGG4YZysbxWVdnFDX3+s+3IanmZKqK/Lih/+XGK5rwp1QGr3+fFX6yAuI5gK78BOajkkEAq6RR9lzvaMDGt7t5wpYxSnEzN9UgkIhdf1zpg/OG1CB4hRsrQU9IG39r2W2IxqHXdipGkPDag+4MTEkwMuofgXFF9NQ==-MIIElTCCAn2gAwIBAgIBCTANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBMB4XDTE4MTEwMTEyMjk0NloXDTIwMTEwMjEyMjk0NlowaDELMAkGA1UEBhMCQ1oxDjAMBgNVBAgMBU51c2xlMQ8wDQYDVQQHDAZQcmFndWUxGTAXBgNVBAoMEEpldEJyYWlucyBzLnIuby4xHTAbBgNVBAMMFHByb2QzeS1mcm9tLTIwMTgxMTAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxcQkq+zdxlR2mmRYBPzGbUNdMN6OaXiXzxIWtMEkrJMO/5oUfQJbLLuMSMK0QHFmaI37WShyxZcfRCidwXjot4zmNBKnlyHodDij/78TmVqFl8nOeD5+07B8VEaIu7c3E1N+e1doC6wht4I4+IEmtsPAdoaj5WCQVQbrI8KeT8M9VcBIWX7fD0fhexfg3ZRt0xqwMcXGNp3DdJHiO0rCdU+Itv7EmtnSVq9jBG1usMSFvMowR25mju2JcPFp1+I4ZI+FqgR8gyG8oiNDyNEoAbsR3lOpI7grUYSvkB/xVy/VoklPCK2h0f0GJxFjnye8NT1PAywoyl7RmiAVRE/EKwIDAQABo4GZMIGWMAkGA1UdEwQCMAAwHQYDVR0OBBYEFGEpG9oZGcfLMGNBkY7SgHiMGgTcMEgGA1UdIwRBMD+AFKOetkhnQhI2Qb1t4Lm0oFKLl/GzoRykGjAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBggkA0myxg7KDeeEwEwYDVR0lBAwwCgYIKwYBBQUHAwEwCwYDVR0PBAQDAgWgMA0GCSqGSIb3DQEBCwUAA4ICAQAF8uc+YJOHHwOFcPzmbjcxNDuGoOUIP+2h1R75Lecswb7ru2LWWSUMtXVKQzChLNPn/72W0k+oI056tgiwuG7M49LXp4zQVlQnFmWU1wwGvVhq5R63Rpjx1zjGUhcXgayu7+9zMUW596Lbomsg8qVve6euqsrFicYkIIuUu4zYPndJwfe0YkS5nY72SHnNdbPhEnN8wcB2Kz+OIG0lih3yz5EqFhld03bGp222ZQCIghCTVL6QBNadGsiN/lWLl4JdR3lJkZzlpFdiHijoVRdWeSWqM4y0t23c92HXKrgppoSV18XMxrWVdoSM3nuMHwxGhFyde05OdDtLpCv+jlWf5REAHHA201pAU6bJSZINyHDUTB+Beo28rRXSwSh3OUIvYwKNVeoBY+KwOJ7WnuTCUq1meE6GkKc4D/cXmgpOyW/1SmBz3XjVIi/zprZ0zf3qH5mkphtg6ksjKgKjmx1cXfZAAX6wcDBNaCL+Ortep1Dh8xDUbqbBVNBL4jbiL3i3xsfNiyJgaZ5sX7i8tmStEpLbPwvHcByuf59qJhV/bZOl8KqJBETCDJcY6O2aqhTUy+9x93ThKs1GKrRPePrWPluud7ttlgtRveit/pcBrnQcXOl1rHq7ByB8CFAxNotRUYL9IF5n3wJOgkPojMy6jetQA5Ogc8Sm7RG6vg1yow==

第二个激活码

1
QYYBAC9D3J-eyJsaWNlbnNlSWQiOiJRWVlCQUM5RDNKIiwibGljZW5zZWVOYW1lIjoi6LaF57qnIOeoi+W6j+WRmCIsImFzc2lnbmVlTmFtZSI6IiIsImFzc2lnbmVlRW1haWwiOiIiLCJsaWNlbnNlUmVzdHJpY3Rpb24iOiIiLCJjaGVja0NvbmN1cnJlbnRVc2UiOmZhbHNlLCJwcm9kdWN0cyI6W3siY29kZSI6IklJIiwiZmFsbGJhY2tEYXRlIjoiMjAyMC0wMS0wNCIsInBhaWRVcFRvIjoiMjAyMS0wMS0wMyJ9LHsiY29kZSI6IkFDIiwiZmFsbGJhY2tEYXRlIjoiMjAyMC0wMS0wNCIsInBhaWRVcFRvIjoiMjAyMS0wMS0wMyJ9LHsiY29kZSI6IkRQTiIsImZhbGxiYWNrRGF0ZSI6IjIwMjAtMDEtMDQiLCJwYWlkVXBUbyI6IjIwMjEtMDEtMDMifSx7ImNvZGUiOiJQUyIsImZhbGxiYWNrRGF0ZSI6IjIwMjAtMDEtMDQiLCJwYWlkVXBUbyI6IjIwMjEtMDEtMDMifSx7ImNvZGUiOiJHTyIsImZhbGxiYWNrRGF0ZSI6IjIwMjAtMDEtMDQiLCJwYWlkVXBUbyI6IjIwMjEtMDEtMDMifSx7ImNvZGUiOiJETSIsImZhbGxiYWNrRGF0ZSI6IjIwMjAtMDEtMDQiLCJwYWlkVXBUbyI6IjIwMjEtMDEtMDMifSx7ImNvZGUiOiJDTCIsImZhbGxiYWNrRGF0ZSI6IjIwMjAtMDEtMDQiLCJwYWlkVXBUbyI6IjIwMjEtMDEtMDMifSx7ImNvZGUiOiJSUzAiLCJmYWxsYmFja0RhdGUiOiIyMDIwLTAxLTA0IiwicGFpZFVwVG8iOiIyMDIxLTAxLTAzIn0seyJjb2RlIjoiUkMiLCJmYWxsYmFja0RhdGUiOiIyMDIwLTAxLTA0IiwicGFpZFVwVG8iOiIyMDIxLTAxLTAzIn0seyJjb2RlIjoiUkQiLCJmYWxsYmFja0RhdGUiOiIyMDIwLTAxLTA0IiwicGFpZFVwVG8iOiIyMDIxLTAxLTAzIn0seyJjb2RlIjoiUEMiLCJmYWxsYmFja0RhdGUiOiIyMDIwLTAxLTA0IiwicGFpZFVwVG8iOiIyMDIxLTAxLTAzIn0seyJjb2RlIjoiUk0iLCJmYWxsYmFja0RhdGUiOiIyMDIwLTAxLTA0IiwicGFpZFVwVG8iOiIyMDIxLTAxLTAzIn0seyJjb2RlIjoiV1MiLCJmYWxsYmFja0RhdGUiOiIyMDIwLTAxLTA0IiwicGFpZFVwVG8iOiIyMDIxLTAxLTAzIn0seyJjb2RlIjoiREIiLCJmYWxsYmFja0RhdGUiOiIyMDIwLTAxLTA0IiwicGFpZFVwVG8iOiIyMDIxLTAxLTAzIn0seyJjb2RlIjoiREMiLCJmYWxsYmFja0RhdGUiOiIyMDIwLTAxLTA0IiwicGFpZFVwVG8iOiIyMDIxLTAxLTAzIn0seyJjb2RlIjoiUlNVIiwiZmFsbGJhY2tEYXRlIjoiMjAyMC0wMS0wNCIsInBhaWRVcFRvIjoiMjAyMS0wMS0wMyJ9XSwiaGFzaCI6IjE2MDgwOTA5LzAiLCJncmFjZVBlcmlvZERheXMiOjcsImF1dG9Qcm9sb25nYXRlZCI6ZmFsc2UsImlzQXV0b1Byb2xvbmdhdGVkIjpmYWxzZX0=-I7c5mu4hUCMxcldrwZEJMaT+qkrzrF1bjJi0i5QHcrRxk2LO0jqzUe2fBOUR4L+x+7n6kCwAoBBODm9wXst8dWLXdq179EtjU3rfJENr1wXGgtef//FNow+Id5iRufJ4W+p+3s5959GSFibl35YtbELELuCUH2IbCRly0PUBjitgA0r2y+9jV5YD/dmrd/p4C87MccC74NxtQfRdeUEGx87vnhsqTFH/sP4C2VljSo/F/Ft9JqsSlGfwSKjzU8BreYt1QleosdMnMK7a+fkfxh7n5zg4DskdVlNbfe6jvYgMVE16DMXd6F1Zhwq+lrmewJA2jPToc+H5304rcJfa9w==-MIIElTCCAn2gAwIBAgIBCTANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBMB4XDTE4MTEwMTEyMjk0NloXDTIwMTEwMjEyMjk0NlowaDELMAkGA1UEBhMCQ1oxDjAMBgNVBAgMBU51c2xlMQ8wDQYDVQQHDAZQcmFndWUxGTAXBgNVBAoMEEpldEJyYWlucyBzLnIuby4xHTAbBgNVBAMMFHByb2QzeS1mcm9tLTIwMTgxMTAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxcQkq+zdxlR2mmRYBPzGbUNdMN6OaXiXzxIWtMEkrJMO/5oUfQJbLLuMSMK0QHFmaI37WShyxZcfRCidwXjot4zmNBKnlyHodDij/78TmVqFl8nOeD5+07B8VEaIu7c3E1N+e1doC6wht4I4+IEmtsPAdoaj5WCQVQbrI8KeT8M9VcBIWX7fD0fhexfg3ZRt0xqwMcXGNp3DdJHiO0rCdU+Itv7EmtnSVq9jBG1usMSFvMowR25mju2JcPFp1+I4ZI+FqgR8gyG8oiNDyNEoAbsR3lOpI7grUYSvkB/xVy/VoklPCK2h0f0GJxFjnye8NT1PAywoyl7RmiAVRE/EKwIDAQABo4GZMIGWMAkGA1UdEwQCMAAwHQYDVR0OBBYEFGEpG9oZGcfLMGNBkY7SgHiMGgTcMEgGA1UdIwRBMD+AFKOetkhnQhI2Qb1t4Lm0oFKLl/GzoRykGjAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBggkA0myxg7KDeeEwEwYDVR0lBAwwCgYIKwYBBQUHAwEwCwYDVR0PBAQDAgWgMA0GCSqGSIb3DQEBCwUAA4ICAQAF8uc+YJOHHwOFcPzmbjcxNDuGoOUIP+2h1R75Lecswb7ru2LWWSUMtXVKQzChLNPn/72W0k+oI056tgiwuG7M49LXp4zQVlQnFmWU1wwGvVhq5R63Rpjx1zjGUhcXgayu7+9zMUW596Lbomsg8qVve6euqsrFicYkIIuUu4zYPndJwfe0YkS5nY72SHnNdbPhEnN8wcB2Kz+OIG0lih3yz5EqFhld03bGp222ZQCIghCTVL6QBNadGsiN/lWLl4JdR3lJkZzlpFdiHijoVRdWeSWqM4y0t23c92HXKrgppoSV18XMxrWVdoSM3nuMHwxGhFyde05OdDtLpCv+jlWf5REAHHA201pAU6bJSZINyHDUTB+Beo28rRXSwSh3OUIvYwKNVeoBY+KwOJ7WnuTCUq1meE6GkKc4D/cXmgpOyW/1SmBz3XjVIi/zprZ0zf3qH5mkphtg6ksjKgKjmx1cXfZAAX6wcDBNaCL+Ortep1Dh8xDUbqbBVNBL4jbiL3i3xsfNiyJgaZ5sX7i8tmStEpLbPwvHcByuf59qJhV/bZOl8KqJBETCDJcY6O2aqhTUy+9x93ThKs1GKrRPePrWPluud7ttlgtRveit/pcBrnQcXOl1rHq7ByB8CFAxNotRUYL9IF5n3wJOgkPojMy6jetQA5Ogc8Sm7RG6vg1yow==

第三个激活码

1
E70JHCOV2H-eyJsaWNlbnNlSWQiOiJFNzBKSENPVjJIIiwibGljZW5zZWVOYW1lIjoi5bGx5Lic55CG5bel5aSn5a2mIiwiYXNzaWduZWVOYW1lIjoiIiwiYXNzaWduZWVFbWFpbCI6IiIsImxpY2Vuc2VSZXN0cmljdGlvbiI6IkZvciBlZHVjYXRpb25hbCB1c2Ugb25seSIsImNoZWNrQ29uY3VycmVudFVzZSI6ZmFsc2UsInByb2R1Y3RzIjpbeyJjb2RlIjoiSUkiLCJwYWlkVXBUbyI6IjIwMjEtMDItMTgifSx7ImNvZGUiOiJBQyIsInBhaWRVcFRvIjoiMjAyMS0wMi0xOCJ9LHsiY29kZSI6IkRQTiIsInBhaWRVcFRvIjoiMjAyMS0wMi0xOCJ9LHsiY29kZSI6IlBTIiwicGFpZFVwVG8iOiIyMDIxLTAyLTE4In0seyJjb2RlIjoiR08iLCJwYWlkVXBUbyI6IjIwMjEtMDItMTgifSx7ImNvZGUiOiJETSIsInBhaWRVcFRvIjoiMjAyMS0wMi0xOCJ9LHsiY29kZSI6IkNMIiwicGFpZFVwVG8iOiIyMDIxLTAyLTE4In0seyJjb2RlIjoiUlMwIiwicGFpZFVwVG8iOiIyMDIxLTAyLTE4In0seyJjb2RlIjoiUkMiLCJwYWlkVXBUbyI6IjIwMjEtMDItMTgifSx7ImNvZGUiOiJSRCIsInBhaWRVcFRvIjoiMjAyMS0wMi0xOCJ9LHsiY29kZSI6IlBDIiwicGFpZFVwVG8iOiIyMDIxLTAyLTE4In0seyJjb2RlIjoiUk0iLCJwYWlkVXBUbyI6IjIwMjEtMDItMTgifSx7ImNvZGUiOiJXUyIsInBhaWRVcFRvIjoiMjAyMS0wMi0xOCJ9LHsiY29kZSI6IkRCIiwicGFpZFVwVG8iOiIyMDIxLTAyLTE4In0seyJjb2RlIjoiREMiLCJwYWlkVXBUbyI6IjIwMjEtMDItMTgifSx7ImNvZGUiOiJSU1UiLCJwYWlkVXBUbyI6IjIwMjEtMDItMTgifV0sImhhc2giOiIxNjc5MTgwMy8wIiwiZ3JhY2VQZXJpb2REYXlzIjo3LCJhdXRvUHJvbG9uZ2F0ZWQiOmZhbHNlLCJpc0F1dG9Qcm9sb25nYXRlZCI6ZmFsc2V9-qlgtO4xVGHX/r45fIKMaR6B9pWQtucrCYVsz0o00crcAiYN1k/kSMygggYl187B0u0jeXQCe4BmQIItKL79x6NwoPn43inreVhZ88f4+Cbl+V/KGeAYeybon+7YoTs8FY4+31ANW/LwBPxkPnlErxYdQ6oc/k6mnxIOm5Nf8WjKRfYYIl5Bhmdt1gHMGgFsocCcTLLiqDUGEcPj5tUIJXwwYaeKAR3YGXm/P73QpnYR/BcGaodBN3jprQRxsS5Ia5y06rrDAJcPSZuttAFpAit/4o/gq2XzhrjaBCtOMxNzk3XEAT82glTlWQOQx6KnRq6D7WUXzd81g44aP+Dca5Q==-MIIElTCCAn2gAwIBAgIBCTANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBMB4XDTE4MTEwMTEyMjk0NloXDTIwMTEwMjEyMjk0NlowaDELMAkGA1UEBhMCQ1oxDjAMBgNVBAgMBU51c2xlMQ8wDQYDVQQHDAZQcmFndWUxGTAXBgNVBAoMEEpldEJyYWlucyBzLnIuby4xHTAbBgNVBAMMFHByb2QzeS1mcm9tLTIwMTgxMTAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxcQkq+zdxlR2mmRYBPzGbUNdMN6OaXiXzxIWtMEkrJMO/5oUfQJbLLuMSMK0QHFmaI37WShyxZcfRCidwXjot4zmNBKnlyHodDij/78TmVqFl8nOeD5+07B8VEaIu7c3E1N+e1doC6wht4I4+IEmtsPAdoaj5WCQVQbrI8KeT8M9VcBIWX7fD0fhexfg3ZRt0xqwMcXGNp3DdJHiO0rCdU+Itv7EmtnSVq9jBG1usMSFvMowR25mju2JcPFp1+I4ZI+FqgR8gyG8oiNDyNEoAbsR3lOpI7grUYSvkB/xVy/VoklPCK2h0f0GJxFjnye8NT1PAywoyl7RmiAVRE/EKwIDAQABo4GZMIGWMAkGA1UdEwQCMAAwHQYDVR0OBBYEFGEpG9oZGcfLMGNBkY7SgHiMGgTcMEgGA1UdIwRBMD+AFKOetkhnQhI2Qb1t4Lm0oFKLl/GzoRykGjAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBggkA0myxg7KDeeEwEwYDVR0lBAwwCgYIKwYBBQUHAwEwCwYDVR0PBAQDAgWgMA0GCSqGSIb3DQEBCwUAA4ICAQAF8uc+YJOHHwOFcPzmbjcxNDuGoOUIP+2h1R75Lecswb7ru2LWWSUMtXVKQzChLNPn/72W0k+oI056tgiwuG7M49LXp4zQVlQnFmWU1wwGvVhq5R63Rpjx1zjGUhcXgayu7+9zMUW596Lbomsg8qVve6euqsrFicYkIIuUu4zYPndJwfe0YkS5nY72SHnNdbPhEnN8wcB2Kz+OIG0lih3yz5EqFhld03bGp222ZQCIghCTVL6QBNadGsiN/lWLl4JdR3lJkZzlpFdiHijoVRdWeSWqM4y0t23c92HXKrgppoSV18XMxrWVdoSM3nuMHwxGhFyde05OdDtLpCv+jlWf5REAHHA201pAU6bJSZINyHDUTB+Beo28rRXSwSh3OUIvYwKNVeoBY+KwOJ7WnuTCUq1meE6GkKc4D/cXmgpOyW/1SmBz3XjVIi/zprZ0zf3qH5mkphtg6ksjKgKjmx1cXfZAAX6wcDBNaCL+Ortep1Dh8xDUbqbBVNBL4jbiL3i3xsfNiyJgaZ5sX7i8tmStEpLbPwvHcByuf59qJhV/bZOl8KqJBETCDJcY6O2aqhTUy+9x93ThKs1GKrRPePrWPluud7ttlgtRveit/pcBrnQcXOl1rHq7ByB8CFAxNotRUYL9IF5n3wJOgkPojMy6jetQA5Ogc8Sm7RG6vg1yow==

本帖附件

点击下载

本文为作者原创 转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

1…383940…48

乱码三千

android程序员一枚,擅长java,kotlin,python,金融投资,欢迎交流~

479 日志
139 标签
RSS
© 2024 乱码三千
本站总访问量420997次
由 Hexo 强力驱动
|
主题 — NexT.Muse v5.1.4
0%