record all common commands

Windows 安装 typora

1
2
3
4
5
6
7
8
9
10
11
12
需要下载安装包文件
1. 安装文件版本 0.9.78 安装
https://fengfeng.lanzouj.com/i9xo1vi
2. 升级文件版本0.11.18 安装
https://fengfeng.lanzouj.com/itJ7R07nrytg

如果提示过期无法使用则重新下载2安装覆盖即可

3. 更换主题
https://fengfeng.lanzouj.com/i8HBb07s8isf
解压 将upc.css放到theme目录下重启应用即可

Linux 安装 screen 命令

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

# No match for argument: screen
# 未配置yum源

sudo yum install epel-release

sudo yum install screen

#2 利用screen 命令 ,重起一个新的screen.

#新screen的名字,可以任起

screen -S name

#3 开始训练.

#4 可以断开terminal,此时训练不受影响


#恢复
#1 启动terminal,查看存在的screen的命令.

screen -ls

screen -r 30362

#2 断开当前的screen.
按 Ctrl + A, 然后 K 键 然后 y 键

Linux 安装 jupyter lab

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

1. 安装miniconda 创建conda 环境
2. 进入conda环境 安装依赖
conda install -c conda-forge jupyterlab
# or pip install jupyterlab

3. 开放一个端口 比如8889 启动jypyter lab
# sudo firewall-cmd --zone=public --add-port=8889/tcp --permanent
jupyter-lab --ip 0.0.0.0 --port 8889 --no-browser

4. 设置一个screen 来保持jupyter的运行
screen -S jupyter
jupyter-lab --ip 0.0.0.0 --port 8889 --no-browser

退出就可以了

5. 添加内核
#在新conda环境里面
conda install ipykernel
#然后
python -m ipykernel install --user --name 环境名称 --display-name "前端展示的名称"
#exp:
python -m ipykernel install --user --name pytorch --display-name "Python 3 (pytorch)"
#然后重启jupyter服务就可以了

进阶 -端口转发

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
import socket
import threading
import sys,getopt

## 这个代码是用来做端口转发的 emmm 你问有什么用?没用,删了他吧 (摊手

# 错误
def l_w(s):
print("[!] {}".format(s))

# 信息
def l_i(s):
print("[+] {}".format(s))

# 毁灭性错误
def l_a(s):
print("[-] {}".format(s))
exit()

def help():
print("""
-h 提供帮助,就是你看到的这个
-s 指定监听的本地ip,默认为 127.0.0.1
-l 指定监听的端口号,必须指定
-d 指定转发的目的主机,默认为 127.0.0.1
-p 指定转发的目的端口,必须指定

本程序具有超级牛力! moo~~ moo~~~
""")
exit()

s_host = "0.0.0.0"
#s_port = 20000
s_port = 10001
d_host = "192.168.1.101"
#d_host = "192.168.1.102"
d_port = 8889

# 将来自s套接字的数据转发到d套接字(函数名 forward)
def fw(s,d):
try:
while True:
buf = s.recv(4096)
l_i("{} ====> {} {} 字节".format(s.getpeername(),d.getpeername(),len(buf)))
if(len(buf) == 0):
l_w("{} 断开连接".format(s.getpeername()))
return
d.send(buf)
except:
return

# 处理请求,每一个连接对应一个 (函数名 request thread)
def rt(request_socket):
des_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
des_socket.connect((d_host,int(d_port)))
except Exception as e:
l_a("连接目标 {}:{} 失败!err: {}".format(d_host,d_port,str(e)))
threading.Thread(target=fw,args=(request_socket,des_socket)).start()
fw(des_socket,request_socket)

l_i("这个程序由 Startu 开发 o_o | ^_^ ~~~")
# 获取参数
try:
opts,args = getopt.getopt(sys.argv[1:],"hs:l:d:p:")
except getopt.GetoptError:
l_w("参数不正确")
help()
for opt,arg in opts:
if opt == '-h':
help()
elif opt == '-s':
s_host = arg
elif opt == '-l':
s_port = arg
elif opt == '-d':
d_host = arg
elif opt == '-p':
d_port = arg
if s_host == "127.0.0.1":
l_w("将会监听: 127.0.0.1") # 因为可能你不想绑定 127.0.0.1 所以作出提示 (也许是0.0.0.0呢)
if s_port == 0 or d_port == 0:
l_a("没有指定端口号或指定为0 通过 -h 参数看帮助")

l_i("监听 {}:{}".format(s_host,s_port))
l_i("将会连接 {}:{}".format(d_host,d_port))

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
server_socket.bind((s_host,int(s_port)))
except Exception as e:
l_a("绑定 {}:{} 端口失败 {}".format(s_host,s_port,str(e)))
server_socket.listen(50) # 应该同时连接不会超过 50 个吧...
l_i("准备就绪")
while True:
request_socket,addr = server_socket.accept()
l_i("{} 已连接".format(request_socket.getpeername()))
threading.Thread(target=rt,args=(request_socket,)).start()

进阶 -使用

1
2
3
4
5
6

1. 提交任务 开启jupyterlab

jupyter-lab --ip 0.0.0.0 --port 8888 --no-browser

2. 运行端口转发 访问对应端口即可

如何更改linux下目录所属用户和用户组

1
2
3
4
5
6
7
8
9
1、更改目录所属的用户必须位于(/etc/passwd)目录下;
执行 chown [-R] 所属用户名 目录名
例: chown cx-root test
2、更改目录所属用户组必须位于(/etc/group)目录下;
执行 chgrp [-R] 所属用户组 目录名
例: chgrp -R cx-root test_dir
3、同时更改文件或目录的所有者和用户组
执行 chown [-R] 所属用户:所属用户组 文件或者目录名
例: chown -R cx-root:cx-root test_dir

ZIP

1
2
3
4
5
6
7
8
9
10
11
12
13

#1、把/home目录下面的data目录压缩为data.zip
zip -r data.zip data #压缩data目录
#2、把/home目录下面的data.zip解压到databak目录里面
unzip data.zip -d databak
#3、把/home目录下面的a文件夹和3.txt压缩成为a123.zip
zip -r a123.zip a 3.txt
#4、把/home目录下面的t.zip直接解压到/home目录里面
unzip t.zip
#5、把/home目录下面的a1.zip、a2.zip、a3.zip同时解压到/home目录里面
unzip a*.zip
#6、把/home目录下面w.zip里面的所有文件解压到第一级目录
unzip -j wt.zip
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

linux tar.gz命令是一个常见的文件解压缩命令,那么它具体用法是怎样的呢?下面由学习啦小编为大家整理了linux tar.gz命令的相关知识,希望对大家有帮助!

1.linux tar.gz压缩命令:

命令格式:tar -zcvf 压缩文件名.tar.gz 被压缩文件名

可先切换到当前目录下。压缩文件名和被压缩文件名都可加入路径。

2.linux tar.gz解压命令:

命令格式:tar -zxvf 压缩文件名.tar.gz

解压缩后的文件只能放在当前的目录

3.补充:其他linux tar解压缩命令

压缩

tar –cvf jpg.tar *.jpg //将目录里所有jpg文件打包成tar.jpg

tar –czf jpg.tar.gz *.jpg //将目录里所有jpg文件打包成jpg.tar后,并且将其用gzip压缩,生成一个gzip压缩过的包,命名为jpg.tar.gz

tar –cjf jpg.tar.bz2 *.jpg //将目录里所有jpg文件打包成jpg.tar后,并且将其用bzip2压缩,生成一个bzip2压缩过的包,命名为jpg.tar.bz2

tar –cZf jpg.tar.Z *.jpg //将目录里所有jpg文件打包成jpg.tar后,并且将其用compress压缩,生成一个umcompress压缩过的包,命名为jpg.tar.Z

rar a jpg.rar *.jpg //rar格式的压缩,需要先下载rar for Linux

zip jpg.zip *.jpg //zip格式的压缩,需要先下载zip for linux

解压

tar –xvf file.tar //解压 tar包

tar -xzvf file.tar.gz //解压tar.gz

tar -xjvf file.tar.bz2 //解压 tar.bz2

tar –xZvf file.tar.Z //解压tar.Z

unrar e file.rar //解压rar

unzip file.zip //解压zip

Linux clash

1
2
3
4
5
6
GitHub:https://github.com/bannedbook/fanqiang/wiki
Github: https://git.io/v2free
机场:https://cdn.v2free.net/user
每天签到送400M免费流量


配置Linux 环境

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
下载 clash:https://github.com/Dreamacro/clash/releases
# 我下载amd64 版本
wget -O clash.gz https://github.com/Dreamacro/clash/releases/download/v1.10.6/clash-linux-amd64-v1.10.6.gz
# 解压到当前文件夹
gzip -f clash.gz -d
# 授权可执行权限
chmod +x clash
# 初始化执行 clash
./clash
# 初始化执行 clash 会默认在 ~/.config/clash/ 目录下生成配置文件和全球IP地址库:config.yaml 和 Country.mmdb

下载 clash 配置文件
wget -U "Mozilla/6.0" -O ~/.config/clash/config.yaml 你的Clash订阅链接网址
./clash & exit

# 开放端口访问 clash 默认 http 端口默认监听 7890 , socks5 端口默认监听 7891

设置代理 ip 和端口号

Linux 开启网络控制台 RockyLinux

Activate the web console with: systemctl enable --now cockpit.socket

Linux 安装chrome

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 获取安装包

wget https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm

# 安装几个依赖
# yum install -y lsb
# yum install -y libXScrnSaver
# yum install liberation-fonts
# yum install vulkan

# 本地安装
yum localinstall google-chrome-stable_current_x86_64.rpm

# 打开google
google-chrome

用户名:xiaozhenniaini@gmail.com
密码:3wnCFk5Kw4s6

Linux 添加新的硬盘分区

1
2
3
4
5
6

#添加硬盘后 查看分区

lsblk -f

#此时只有sdb,因为没有分区,所有没有sdb1

image-20220624191031061

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

fdisk /dev/sdb

1:fdisk /dev/sdb

2:Command(m for help):m

3:Command(m for help):n(add a new partition)

4:Command action:e:extend(扩展分区)p(primary partition)(1-4)可输入p

5:partition number(1-4)输入1

6:然后Command(m for help):w(写入磁盘并退出)

#添加分区后 查看分区

lsblk -f


#但通过lsblk -f只能看到sdb1,看不到对应的uuid,不能正常使用,需要格式化

image-20220624191231645

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
#格式化
mkfs -t ext4 /dev/sdb1



# 挂载分区

#在配置文件 /etc/fstab下最后一行输入一下内容,这里将分区/dev/sdb1挂到 /home/data目录下

/dev/sdb1 /home/data ext4 defaults 0 0

# 保存

mount -a

# 挂载成功


#如果不想挂载想直接加入扩展分区
vgscan

#得到rl分区
vgextend rl /dev/sdb1

# 扩展想扩展的分区

lvextend -L +180G /dev/mapper/rl-root

# 重新识别分区

xfs_growfs /dev/mapper/rl-root

# 查看
df -h

Python 实现进度条

1
2
3
4
5
6
7
8
9
10


# pip install tqdm

# 在进行迭代训练时使用trange即可
from tqdm import trange
import time
for i in trange(10):
time.sleep(1)

Linux配置Samba共享磁盘

1 安装Samba服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#前期工作 关闭防火墙 关闭Selinux

#关闭防火墙
sudo systemctl stop firewalld.service

#禁止自启动
sudo systemctl disable firewalld.service

#关闭Selinux 设置为 SELINUX=disabled
sudo vi /etc/sysconfig/selinux


#centos
sudo yum -y install samba samba-common samba-client


#查看samba服务状态,启动服务
service smb status //查看samba服务状态
service smb start //启动samba服务
service smb restart //重启samba服务

#设置开机启动
sudo systemctl enable smb.service
sudo systemctl start smb

2 配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 备份配置文件
cp /etc/samba/smb.conf /etc/samba/smb.conf.bak

# 编辑
sudo vim /etc/samba/smb.conf

#找到cups options = raw 下面加上
map to guest = Bad User

#在最后一行加

[disk]
path = /home/peak/disk
public = yes
writable = yes
browseable = yes
guest ok = yes
valid users = peak
available = yes

3 创建访问用户

1
2
3
sudo smbpasswd -a peak   

sudo reboot

Linux中crontab 定时任务找不到命令问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14

#crontab 定时任务找不到命令问题
#!/bin/bash
#### Environments ####
. ~/.bash_profile
. /etc/profile
######################
# 下面是要执行的脚本文件,以及参数
绝对路径最好


#要执行的脚本一定要有执行权限。
#例如:要执行的脚本名称为:myShell.sh
chmod 777 myShell.sh

查看GPU显卡并发送给微信

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
# encoding:utf-8
import requests
import sys
import json
title1 = sys.argv[1]
txt1 = sys.argv[2]
title2 = sys.argv[3]
txt2 = sys.argv[4]

Secret = "Aly-JNu9VttOcY3wKx8m76IjqfzNtUJ98web-aQns4o"
corpid = 'ww41560323f54f5b7b'
url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={}&corpsecret={}'
getr = requests.get(url=url.format(corpid, Secret))
access_token = getr.json().get('access_token')

# 推送信息
# 微信推送
def weChatPush(title,txt):
#print(access_token)
data = {
"touser": "@all",
"msgtype": "text",
"agentid": 1000005,
"text": {
"content": title+ ":\n" + txt
},
"safe": 0,
}
c = requests.post(url="https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={}".format(access_token),data=json.dumps(data))
#print(c.json)
pass

if __name__ == '__main__':
weChatPush(title1,txt1)
weChatPush(title2,txt2)




# 查看显卡命令
#!/bin/bash
sleep 1
/apps/jhinno/unischeduler/bin/jsub </hpcfiles/users/qyf/workDir/sub1.sh

sleep 5

a=$(ls | grep output)
gpu1=$(cat $a | grep -A 30 'The output')
wx1=$(cat $a | grep 'MiB')

echo "*******************************************"
echo "****************GPU01**********************"
echo "*******************************************"
echo "$gpu1"
echo "*******************************************"
echo "*******************************************"

rm output.*
rm error.*

/apps/jhinno/unischeduler/bin/jsub </hpcfiles/users/qyf/workDir/sub2.sh

sleep 5

c=$(ls | grep output)
gpu2=$(cat $c | grep -A 30 'The output')
wx2=$(cat $c | grep 'MiB')

echo "*******************************************"
echo "****************GPU02**********************"
echo "*******************************************"
echo "$gpu2"
echo "*******************************************"
echo "*******************************************"

rm output.*
rm error.*

/apps/software/anaconda3/bin/python /hpcfiles/users/qyf/workDir/Mess.py "GPU01 Info" "$wx1" "GPU02 Info" "$wx2"




#!/bin/sh
#JSUB -q normal
#JSUB -n 1
#JSUB -m gpu01
#JSUB -e error.%J
#JSUB -o output.%J
#JSUB -J check_task
nvidia-smi

* * * * * bash /hpcfiles/users/qyf/workDir/checkGpu.sh >> /hpcfiles/users/qyf/workDir/GPU.log &
0 * * * * bash /hpcfiles/users/qyf/workDir/checkGpu.sh >> /hpcfiles/users/qyf/workDir/GPU.log &

20220628改进版本

1
2
3
4
5
6
7
8
9
10
checkGpu.sh

#!/bin/bash

gpu1=$(cat /hpcfiles/users/qyf/gpuInfo/gpu01Hour.log | grep 'MiB')
gpu2=$(cat /hpcfiles/users/qyf/gpuInfo/gpu02Hour.log | grep 'MiB')

/apps/software/anaconda3/bin/python /hpcfiles/users/qyf/gpuInfo/Mess.py "GPU01 Info" "$gpu1" "GPU02 Info" "$gpu2"

0 * * * * bash /hpcfiles/users/qyf/gpuInfo/checkGpu.sh

python传入参数

使用sys.argv

1
2
3
4
5
6
7
8

python script.py 0,1,2 10

import sys
gpus = sys.argv[1]
batch_size = sys.argv[2]
print(gpus)
print(batch_size)

Bash

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




#!/bin/bash
rm error.*
rm output.*
jsub -q normal -n 1 -e error.%J -o output.%J -J my_job -m gpu01 nvidia-smi
sleep 1
# a是后面命令返回得结果
a=$(ls | grep output)
# b中调用$a
b=$(cat $a | grep -A 30 'The output')
echo "*******************************************"
echo "****************GPU01**********************"
echo "*******************************************"
# 输出b
echo "$b"
echo "*******************************************"
echo "*******************************************"
rm output.*
rm error.*
jsub -q normal -n 1 -e error.%J -o output.%J -J my_job -m gpu02 nvidia-smi
sleep 1
c=$(ls | grep output)
d=$(cat $c | grep -A 30 'The output')
echo "*******************************************"
echo "****************GPU02**********************"
echo "*******************************************"
echo "$d"
echo "*******************************************"
echo "*******************************************"
rm output.*
rm error.*


为最小化安装linux配置VNC桌面

1
2
3
4
5
# 环境说明 CentOS 8

$ cat /etc/centos-release
Rocky Linux release 8.6 (Green Obsidian)

1 安装桌面

1
2
3
4
5
6
7
# 需要root权限
sudo dnf groupinstall "workstation"
# 耗时较长

# 安装桌面
sudo dnf groupinstall "Server with GUI"

2 设置默认启动桌面

1
2
3
4
# 设置后需要重启服务器
sudo systemctl set-default graphical

sudo reboot

3 安装VNC

1
2
3
# yum 安装VNC service
sudo dnf install tigervnc-server tigervnc-server-module

4 添加用户

1
2
3
4
5
6
7

#
sudo vim /etc/tigervnc/vncserver.users

:1=username
# :1表示5901端口 username表示用户名

5 拷贝模板

1
2
3
4
sudo cp /usr/lib/systemd/system/vncserver@.service /etc/systemd/system/vncserver@.service

# @1.service表示为:1端口创建
# 如果多用户,则@2.service

6 设置密码

1
2
3
vncpasswd

# 设置密码后 Would you like to enter a view-only password (y/n)? 输入n 意思是只读? 当然要操控所以用 n

7 设置开机启动

1
2
3
4
# :1对应1用户
sudo systemctl enable vncserver@:1.service
#启动
sudo systemctl start vncserver@:1.service

8 设置防火墙

1
2
3
4
# 配置后需要reload
sudo firewall-cmd --permanent --add-service vnc-server

sudo firewall-cmd --reload

9 测试

1
2
sudo systemctl start vncserver@:1.service
sudo systemctl status vncserver@:1.service

10 连接

配置vnc

https://www.cnblogs.com/xuanbjut/p/14289178.html

添加用户

1
2
3
sudo vim /etc/tigervnc/vncserver.users

:1=qyf #对应5901端口

拷贝模板

1
2
sudo cp /usr/lib/systemd/system/vncserver@.service /etc/systemd/system/vncserver@1.service
# @1.service 对应:1用户

设置密码

1
2
3
4
5
6
vncpasswd

sudo systemctl start vncserver@:1 #对应:1用户

设置开机启动
sudo systemctl enable vncserver@:1

开启服务

1
2
3
sudo systemctl start vncserver@:1

#sudo systemctl start vncserver@:1.service

查看端口

1
sudo netstat -tulpn | grep vnc

配置防火墙

1
2
sudo firewall-cmd --permanent --add-service vnc-server
sudo firewall-cmd --reload

配置青龙面板后 执行python脚本

1 进入青龙内部

1
2
# 进入docker
docker exec -it qinglong bash

2 安装依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
# 安装 一些看不懂的依赖
apk add --no-cache gcc g++ python python-dev py-pip mysql-dev linux-headers libffi-dev openssl-dev

# 安装 脚本 例如dailycheckin签到
pip3 install dailycheckin --upgrade


## 失败时
apk add --no-cache --virtual .build-deps gcc musl-dev python2-dev python3-dev libffi libffi-dev openssl openssl-dev
pip3 install pip setuptools --upgrade
pip3 install cryptography~=3.2.1


3 执行其他脚本时

将脚本文件放在 /ql/scripts/目录下,比如/ql/scripts/config.json

4 执行命令

1
2
3
4

task everphoto.py

15 8 * * *

签到文件

时光相册

来源:https://github.com/ICE99125/everphoto_checkin

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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
# encoding:utf-8
import requests
import json
import hashlib
import requests as req
from datetime import datetime

#import Demjson

# 时光相册签到领空间
# 登录信息 账户,密码
# fork in github : https://github.com/ICE99125/everphoto_checkin

# 用户登录信息
config = {
"multi": [
{
"account": "17156087896",
"password": "abc211314",
"push": "", # together 为 True 时失效, 不写不推送
},
{
"account": "17806275268",
"password": "abc211314",
"push": "", # together 为 True 时失效, 不写不推送
},
# {
# "account": "123",
# "password": "123",
# "push": "pushplus",
# },
],
"together": False, # 是否合并发送结果, 不写或 True 时合并发送
"push": "", # 推送类型, together 为 True 或者不写时必须有, 否则不推送
}

# 推送信息
def weChatPush(txt):
Secret = "GuabRMpWYTIeIkk_Dc-sX5LJi59M_7JfCk9KJrtn8Bs"
corpid = 'ww41560323f54f5b7b'
url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={}&corpsecret={}'
getr = requests.get(url=url.format(corpid, Secret))
access_token = getr.json().get('access_token')
data = {
"touser": "@all",
"msgtype": "text",
"agentid": 1000003,
"text": {
"content": "时光相册签到信息:\n\n" + txt
},
"safe": 0,
}
requests.post(url="https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={}".format(access_token),data=json.dumps(data))
pass

# 返回状态信息
#if res["status"]:
# return [
# {
# "h4": {
# "content": f"账号: {res['account']}",
# }
# },
# {
# "h4": {
# "content": f"用户名: {res['name']}",
# }
# },
# {
# "txt": {
# "content": res["message"],
# },
# "table": {
# "content": [
# ("描述", "内容"),
# ("今日获得", f"{res['reward']}M"),
# ("明日获得", f"{res['tomorrow']}M"),
# ("总共获得", f"{res['total']}M"),
# ("连续签到", f"{res['continuity']}天"),
# ("注册时间", f"{res['created']}"),
# ("注册天数", f"{res['day']}天"),
# ]
# },
# },
# ]




def handler(fn):
def inner(*args, **kwargs):
res = fn(*args, **kwargs)

if res["status"]:
return [
{
"h4": {
"content": f"账号: {res['account']}",
}
},
{
"txt": {
"content": res["message"],
},
"table": {
"content": [
("今日获得", f"{res['reward']}M"),
("明日获得", f"{res['tomorrow']}M"),
("总共获得", f"{res['total']}M"),
("连续签到", f"{res['continuity']}天"),
]
},
},
]
else:
# 登录失败 or 签到失败
return [
{
"h4": {
"content": f"账号: {res['account']}",
},
"txt": {
"content": res["message"],
},
}
]

return inner

# 日期字符串格式化
def dateTime_format(dt: str) -> str:
try:
dl = datetime.strptime(dt, "%Y-%m-%dT%H:%M:%S+08:00")

return dl.strftime("%Y-%m-%d %H:%M:%S")
except ValueError as e:
print(f"格式化日期时出错, 原因: {e}")

class Everphoto:
# 登录地址
LOGIN_URL = "https://web.everphoto.cn/api/auth"
# 签到地址
CHECKIN_URL = "https://openapi.everphoto.cn/sf/3/v4/PostCheckIn"

def __init__(self, account: str, password: str) -> None:
self.__account = account
self.__password = password
self.headers = {
"user-agent": "EverPhoto/4.5.0 (Android;4050002;MuMu;23;dev)",
"application": "tc.everphoto",
}
self.userInfo = {}

# 获取 md5 加密后的密码
def get_pwd_md5(self) -> str:
salt = "tc.everphoto."
pwd = salt + self.__password
md5 = hashlib.md5(pwd.encode())
return md5.hexdigest()

# 登陆
def login(self, country_code: str = "+86"):
try:
data = {
"mobile": f"{country_code}{self.__account}",
"password": self.get_pwd_md5(),
}
res = req.post(
Everphoto.LOGIN_URL,
data=data,
headers=self.headers,
).json()

if res.get("code") == 0:
print(f"🎉 登录账号 {self.__account} 成功")

data = res.get("data")

self.headers.update({"authorization": f"Bearer {data['token']}"})
self.userInfo.update({
"account": self.__account, # 账号
"name": data["user_profile"]["name"], # 用户名
"vip": data["user_profile"].get("vip_level"), # vip等级
"created": dateTime_format(data["user_profile"]["created_at"]), # 创建时间
"day": data["user_profile"]["days_from_created"], # 注册时长
})
return {
"status": True
}
else:
raise Exception(res.get("message"))
except Exception as e:
print(f"😭 登录账号 {self.__account} 时出现错误, 原因: {e}")

return {
"status": False,
"message": e,
}

# 签到
def checkin(self):
try:
headers = {
"content-type": "application/json",
"host": "openapi.everphoto.cn",
"connection": "Keep-Alive",
}

headers.update(self.headers)

res = req.post(
Everphoto.CHECKIN_URL,
headers=headers,
).json()

code = res.get('code')

if code == 0:
print(f"🎉 账号 {self.__account} 签到成功")

data = res.get('data')

if data.get("checkin_result") is True:
rwd = data["reward"] / (1024 * 1024) # 今日获得
msg = "签到成功"
else:
rwd = 0
msg = "今日已签到"

return {
"status": True,
"reward": rwd,
"message": msg,
"continuity": data.get("continuity"), # 连续签到天数
"total": data.get("total_reward") / (1024 * 1024), # 总计获得
"tomorrow": data.get("tomorrow_reward") / (1024 * 1024), # 明日可获得
}
elif code == 20104:
# 未登录
raise Exception(res.get('message'))
elif code == 30001:
# 服务器内部错误?
raise Exception(res.get('message'))
except Exception as e:
print(f"账号 {self.__account} 签到时出现错误, 原因: {e}")

return {
"status": False,
"message": f"签到失败, 原因: {e}",
}

@handler
def start(self):
r = self.login()
if r["status"]:
res = self.checkin()

result = {}
result.update(self.userInfo)
result.update(res)

return result
else:
return {
"status": False,
"message": f"登录失败, 原因: {r['message']}",
"account": self.__account,
}

def main(*arg):
together = config.get("together")
type = config.get("push")
multi = config.get("multi")
txt = ''
msg_list = []
for i in multi:
b = Everphoto(i["account"], i['password'])
res = b.start()
msg_list.extend(res)


for i in msg_list:
if 'h4' in i:
txt =txt + i['h4']['content']+ '\n'
if 'txt' in i:
txt =txt + i['txt']['content']+ '\n'
if 'table' in i:
for j in i['table']['content']:
txt =txt + j[0]+':'+ j[1]+'\n'
weChatPush(txt)
#print(txt)



if __name__ == '__main__':
main()

UPC
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146


# -*- coding: utf8 -*-

# coding=utf-8
import requests, time, json, configparser, random, os

# 模拟包头
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',
'X-Requested-With': 'XMLHttpRequest'
}


# 获取当前的时间
def get_time():
return time.strftime('%Y%m%d', time.localtime(time.time()))


# 帐号密码信息读取
def getUserInfo():
try:
usernames = ('Z20070031', )
passwords = ('Qyf9999.', )
emails = ('1490316377@qq.com', )

#print('get userdata success')
return list(zip(usernames, passwords, emails))

except Exception as e:
print('get userdata failed\n %s' % e)
return None


# 帐号密码信息读取
def getSMTPInfo():
try:
user = '1490316377@qq.com'
password = 'uujoaixwfcdkhdca'
host = 'smtp.qq.com'

#print('get SMTP info success')
return user, password, host

except Exception as e:
print('get userdata failed\n %s' % e)
return None


# 登录并获取old_info
def login(userdata):
login_url = "https://app.upc.edu.cn/uc/wap/login/check"
session = requests.session()
response = session.post(login_url, headers=headers, data=userdata, timeout=20)
response.encoding = "UTF-8"
# print(response.text,'\n')
info_url = "https://app.upc.edu.cn/ncov/wap/default/index"
html_info = session.get(info_url, headers=headers, timeout=20)
html_info.encoding = "UTF-8"
return session, html_info.text


# 企业号推送
def weChatPush(txt):
Secret = "GuabRMpWYTIeIkk_Dc-sX5LJi59M_7JfCk9KJrtn8Bs"
corpid = 'ww41560323f54f5b7b'
url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={}&corpsecret={}'
getr = requests.get(url=url.format(corpid, Secret))
access_token = getr.json().get('access_token')
data = {
"touser": "@all",
"msgtype": "text",
"agentid": 1000003,
"text": {
"content": "疫情防控\n" + txt
},
"safe": 0,
}
requests.post(url="https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={}".format(access_token),
data=json.dumps(data))

pass


def save_info(session, info):
save_url = "https://app.upc.edu.cn/ncov/wap/default/save"
save_response = session.post(url=save_url, data=info, headers=headers, timeout=20)
save_response.encoding = "UTF-8"
return save_response.text




def process(userdata, email_address):
# 登录返回old_info
session, html = login(userdata)
# print(html)
old_info = json.loads(html)['d']['oldInfo']

# 获取当前日期
today_date = get_time()

# 重构old_info
old_info['date'] = today_date
# print(old_info)

# 提交信息,对应的接口为save
save_res = save_info(session, old_info)
print(userdata.get("username"))
print(str(json.loads(save_res)['m']))
session.close()

if email_address:
# 结束后发送邮件
if json.loads(save_res)['m'] == '操作成功':
#send_email("信息填报成功!", "账号:" + userdata.get("username") + "\n结果:" + str(json.loads(save_res)['m']),
# email_address)
if (userdata.get("username") == 'Z20070031'):
weChatPush("信息填报成功!\n账号:" + userdata.get("username"))
else:
#send_email("信息填报失败!可能是已经提交过了!",
# "账号:" + userdata.get("username") + "\n" + str(json.loads(save_res)['m']) + "\n请看今天第一个邮件或手动签到!",
# email_address)
if (userdata.get("username") == 'Z20070031'):
weChatPush("信息填报失败!\n账号:" + userdata.get("username") + "\n请看今天第一条信息或手动签到!")




if __name__ == "__main__":
# 获取用户信息
userinfos = getUserInfo()
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
time.sleep(random.randint(300, 500))
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
for user in userinfos:
user_data = {
'username': user[0],
'password': user[1]
}

process(user_data, user[2])




网易云音乐
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096

# 需要在docke内导入几个包
# from Crypto.Cipher import AES
# from future.builtins import int, pow
# pip3 install future
# pip3 install pycrypto
#






# coding: utf-8
from __future__ import print_function, unicode_literals, division, absolute_import
import random, hashlib, math, re
import base64
import binascii
import os
import json
import platform
import time
import requests
from http.cookiejar import Cookie

from Crypto.Cipher import AES
from future.builtins import int, pow






# API
DEFAULT_TIMEOUT = 10

BASE_URL = "http://music.163.com"

class NetEase(object):
def __init__(self):
self.header = {
"Accept": "*/*",
"Accept-Encoding": "gzip,deflate,sdch",
"Accept-Language": "zh-CN,zh;q=0.8,gl;q=0.6,zh-TW;q=0.4",
"Connection": "keep-alive",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "music.163.com",
"Referer": "http://music.163.com",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36",
}
self.session = requests.Session()
@property
def toplists(self):
return [l[0] for l in TOP_LIST_ALL.values()]


def _raw_request(self, method, endpoint, data=None):
if method == "GET":
resp = self.session.get(
endpoint, params=data, headers=self.header, timeout=DEFAULT_TIMEOUT
)
elif method == "POST":
resp = self.session.post(
endpoint, data=data, headers=self.header, timeout=DEFAULT_TIMEOUT
)
return resp

# 生成Cookie对象
def make_cookie(self, name, value):
return Cookie(
version=0,
name=name,
value=value,
port=None,
port_specified=False,
domain="music.163.com",
domain_specified=True,
domain_initial_dot=False,
path="/",
path_specified=True,
secure=False,
expires=None,
discard=False,
comment=None,
comment_url=None,
rest={},
)

def request(self, method, path, params={}, default={"code": -1}, custom_cookies={'os':'pc'}):
endpoint = "{}{}".format(BASE_URL, path)
csrf_token = ""
for cookie in self.session.cookies:
if cookie.name == "__csrf":
csrf_token = cookie.value
break
params.update({"csrf_token": csrf_token})
data = default

for key, value in custom_cookies.items():
cookie = self.make_cookie(key, value)
self.session.cookies.set_cookie(cookie)

params = encrypted_request(params)
try:
resp = self._raw_request(method, endpoint, params)
data = resp.json()
except requests.exceptions.RequestException as e:
log.error(e)
except ValueError as e:
log.error("Path: {}, response: {}".format(path, resp.text[:200]))
finally:
return data

def login(self, username, password):
#self.session.cookies.load()
if username.isdigit():
path = "/weapi/login/cellphone"
params = dict(phone=username, password=password, rememberLogin="true")
else:
# magic token for login
# see https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/router/login.js#L15
client_token = (
"1_jVUMqWEPke0/1/Vu56xCmJpo5vP1grjn_SOVVDzOc78w8OKLVZ2JH7IfkjSXqgfmh"
)
path = "/weapi/login"
params = dict(
username=username,
password=password,
rememberLogin="true",
clientToken=client_token,
)
data = self.request("POST", path, params)
if data['code'] == 200:
self.uid = data['account']['id']
print(username+'登录成功!')
else:
self.uid = 0
return data

# 每日签到
def daily_task(self, is_mobile=True):
path = "/weapi/point/dailyTask"
params = dict(type=0 if is_mobile else 1)
return self.request("POST", path, params)

# 用户歌单
def user_playlist(self, uid, offset=0, limit=50):
path = "/weapi/user/playlist"
params = dict(uid=uid, offset=offset, limit=limit, csrf_token="")
return self.request("POST", path, params).get("playlist", [])

# 每日推荐歌单
def recommend_resource(self):
path = "/weapi/v1/discovery/recommend/resource"
return self.request("POST", path).get("recommend", [])

# 每日推荐歌曲
def recommend_playlist(self, total=True, offset=0, limit=20):
path = "/weapi/v1/discovery/recommend/songs" # NOQA
params = dict(total=total, offset=offset, limit=limit, csrf_token="")
return self.request("POST", path, params).get("recommend", [])

# 私人FM
def personal_fm(self):
path = "/weapi/v1/radio/get"
return self.request("POST", path).get("data", [])

# like
def fm_like(self, songid, like=True, time=25, alg="itembased"):
path = "/weapi/radio/like"
params = dict(
alg=alg, trackId=songid, like="true" if like else "false", time=time
)
return self.request("POST", path, params)["code"] == 200

# FM trash
def fm_trash(self, songid, time=25, alg="RT"):
path = "/weapi/radio/trash/add"
params = dict(songId=songid, alg=alg, time=time)
return self.request("POST", path, params)["code"] == 200

# 搜索单曲(1),歌手(100),专辑(10),歌单(1000),用户(1002) *(type)*
def search(self, keywords, stype=1, offset=0, total="true", limit=50):
path = "/weapi/search/get"
params = dict(s=keywords, type=stype, offset=offset, total=total, limit=limit)
return self.request("POST", path, params).get("result", {})

# 新碟上架
def new_albums(self, offset=0, limit=50):
path = "/weapi/album/new"
params = dict(area="ALL", offset=offset, total=True, limit=limit)
return self.request("POST", path, params).get("albums", [])

# 歌单(网友精选碟) hot||new http://music.163.com/#/discover/playlist/
def top_playlists(self, category="全部", order="hot", offset=0, limit=50):
path = "/weapi/playlist/list"
params = dict(
cat=category, order=order, offset=offset, total="true", limit=limit
)
return self.request("POST", path, params).get("playlists", [])

def playlist_catelogs(self):
path = "/weapi/playlist/catalogue"
return self.request("POST", path)

# 歌单详情
def playlist_detail(self, playlist_id):
path = "/weapi/v3/playlist/detail"
params = dict(id=playlist_id, total="true", limit=1000, n=1000, offest=0)
# cookie添加os字段
custom_cookies = dict(os=platform.system())
return (
self.request("POST", path, params, {"code": -1}, custom_cookies)
#.get("playlist", {})
#.get("tracks", [])
)

# 热门歌手 http://music.163.com/#/discover/artist/
def top_artists(self, offset=0, limit=100):
path = "/weapi/artist/top"
params = dict(offset=offset, total=True, limit=limit)
return self.request("POST", path, params).get("artists", [])

# 热门单曲 http://music.163.com/discover/toplist?id=
def top_songlist(self, idx=0, offset=0, limit=100):
playlist_id = TOP_LIST_ALL[idx][1]
return self.playlist_detail(playlist_id)

# 歌手热门歌曲
def artists(self, artist_id):
path = "/weapi/v1/artist/{}".format(artist_id)
return self.request("POST", path).get("hotSongs", [])

def get_artist_album(self, artist_id, offset=0, limit=50):
path = "/weapi/artist/albums/{}".format(artist_id)
params = dict(offset=offset, total=True, limit=limit)
return self.request("POST", path, params).get("hotAlbums", [])

# album id --> song id set
def album(self, album_id):
path = "/weapi/v1/album/{}".format(album_id)
return self.request("POST", path)#.get("songs", [])

def song_comments(self, music_id, offset=0, total="false", limit=100):
path = "/weapi/v1/resource/comments/R_SO_4_{}/".format(music_id)
params = dict(rid=music_id, offset=offset, total=total, limit=limit)
return self.request("POST", path, params)

# song ids --> song urls ( details )
def songs_detail(self, ids):
path = "/weapi/v3/song/detail"
params = dict(c=json.dumps([{"id": _id} for _id in ids]), ids=json.dumps(ids))
return self.request("POST", path, params).get("songs", [])

def songs_url(self, ids):
quality = Config().get("music_quality")
rate_map = {0: 320000, 1: 192000, 2: 128000}

path = "/weapi/song/enhance/player/url"
params = dict(ids=ids, br=rate_map[quality])
return self.request("POST", path, params).get("data", [])

# lyric http://music.163.com/api/song/lyric?os=osx&id= &lv=-1&kv=-1&tv=-1
def song_lyric(self, music_id):
path = "/weapi/song/lyric"
params = dict(os="osx", id=music_id, lv=-1, kv=-1, tv=-1)
lyric = self.request("POST", path, params).get("lrc", {}).get("lyric", [])
if not lyric:
return []
else:
return lyric.split("\n")

def song_tlyric(self, music_id):
path = "/weapi/song/lyric"
params = dict(os="osx", id=music_id, lv=-1, kv=-1, tv=-1)
lyric = self.request("POST", path, params).get("tlyric", {}).get("lyric", [])
if not lyric:
return []
else:
return lyric.split("\n")

# 今日最热(0), 本周最热(10),历史最热(20),最新节目(30)
def djchannels(self, offset=0, limit=50):
path = "/weapi/djradio/hot/v1"
params = dict(limit=limit, offset=offset)
channels = self.request("POST", path, params).get("djRadios", [])
return channels

def djprograms(self, radio_id, asc=False, offset=0, limit=50):
path = "/weapi/dj/program/byradio"
params = dict(asc=asc, radioId=radio_id, offset=offset, limit=limit)
programs = self.request("POST", path, params).get("programs", [])
return [p["mainSong"] for p in programs]

def yunpan_songlist(self, offset=0, limit=50):
path = "/weapi/v1/cloud/get" # NOQA
params = dict(offset=offset, limit=limit, csrf_token="")
return self.request("POST", path, params)#.get("data", [])
# 歌手信息
def artist_info(self, artist_id):
path = "/weapi/v1/artist/{}".format(artist_id)
return self.request("POST", path).get("artist", {})

def mv_url(self, id):
path = "/weapi/song/enhance/play/mv/url"
params = dict(id=id, r=1080)
return self.request("POST", path, params).get("data", [])

def artist_sublist(self, offset=0,limit=50,total=True):
path = "/weapi/artist/sublist"
params = dict(offset=offset,limit=limit,total=total)
return self.request("POST", path, params).get("data", [])
def album_sublist(self, offset=0,limit=50,total=True):
path = "/weapi/album/sublist"
params = dict(offset=offset,limit=limit,total=total)
return self.request("POST", path, params).get("data", [])
def video_sublist(self, offset=0,limit=50,total=True):
path = "/weapi/cloudvideo/allvideo/sublist"
params = dict(offset=offset,limit=limit,total=total)
return self.request("POST", path, params).get("data", [])

# 获取视频url
def video_url(self, id, resolution=1080):
path = "/weapi/cloudvideo/playurl"
params = dict(ids='["' + id + '"]',resolution = resolution)
return self.request("POST", path, params)#.get("urls", [])
# 我的数字专辑
def digitalAlbum_purchased(self, offset=0,limit=50,total=True):
path = "/api/digitalAlbum/purchased"
params = dict(offset=offset,limit=limit,total=total)
return self.request("POST", path, params).get("paidAlbums", [])

# 热门歌手
def artist_top(self, offset=0,limit=50,total=True):
path = "/weapi/artist/top"
params = dict(offset=offset,limit=limit,total=total)
return self.request("POST", path, params).get("artists", [])
# 歌手MV
def artist_mvs(self, id, offset=0,limit=50,total=True):
path = "/weapi/artist/mvs"
params = dict(artistId=id,offset=offset,limit=limit,total=total)
return self.request("POST", path, params).get("mvs", [])
# 新歌速递 全部:0 华语:7 欧美:96 日本:8 韩国:16
def new_songs(self, areaId=0, total=True):
path = "/weapi/v1/discovery/new/songs"
params = dict(areaId=areaId, total=total)
return self.request("POST", path, params).get("data", [])
# 相似歌手
def similar_artist(self, artistid):
path = "/weapi/discovery/simiArtist"
params = dict(artistid=artistid)
return self.request("POST", path, params).get("artists", [])
#关注用户
def user_follow(self, id):
path = "/weapi/user/follow/{}".format(id)
return self.request("POST", path)
# 用户关注列表
def user_getfollows(self, id, offset=0,limit=50,order=True):
path = "/weapi/user/getfollows/{}".format(id)
params = dict(offset=offset,limit=limit,order=order)
return self.request("POST", path, params).get("follow", [])
# 用户粉丝列表
def user_getfolloweds(self, id, time=-1,limit=50):
path = "/weapi/user/getfolloweds/{}".format(id)
params = dict(time=time,limit=limit)
return self.request("POST", path, params)#.get("followeds", [])
# 听歌排行 type: 0 全部时间 1最近一周
def play_record(self, uid, time_type=0,limit=1000,offset=0,total=True):
path = "/weapi/v1/play/record"
params = dict(uid=uid,type=time_type,limit=limit,offset=offset,total=total)
return self.request("POST", path, params)#.get("allData", []) #weekData
# 推荐mv
def recommend_mv(self):
path = "/weapi/personalized/mv"
return self.request("POST", path).get("result", [])

# MV排行榜 area: 地区,可选值为内地,港台,欧美,日本,韩国,不填则为全部
def top_mv(self, area='', limit=50, offset=0, total=True):
path = "/weapi/mv/toplist"
params = dict(area=area,limit=limit,offset=offset,total=total)
return self.request("POST", path, params).get("data", []) #weekData


# 创建歌单 privacy:0 为普通歌单,10 为隐私歌单;type:NORMAL|VIDEO
def playlist_creat(self, name, privacy=0, ptype='NORMAL'):
path = "/weapi/playlist/create"
params = dict(name=name,privacy=privacy,type=ptype)
return self.request("POST", path, params)

# 添加MV到视频歌单中
def playlist_add(self, pid, ids):
path = "/weapi/playlist/track/add"
ids = [{'type':3,'id':song_id} for song_id in ids]
params = {'id':pid,'tracks': json.dumps(ids)}
return self.request("POST", path, params)

# 添加/删除单曲到歌单
# op:'add'|'del'
def playlist_tracks(self, pid, ids,op='add'):
path = "/weapi/playlist/manipulate/tracks"
params = {'op':op,'pid':pid,'trackIds': json.dumps(ids),'imme':'true'}
return self.request("POST", path, params)

def artist_songs(self, id, limit=50, offset=0):
path = "/weapi/v1/artist/songs"
params = dict(id=id,limit=limit,offset=offset,private_cloud=True,work_type=1,order='hot')
return self.request("POST", path, params)

# 打卡
def daka(self, song_datas):
path = "/weapi/feedback/weblog"
songs = []
for i in range(len(song_datas)):
song = {
'action': 'play',
'json': song_datas[i]
}
songs.append(song)
params = {'logs': json.dumps(songs)}
return self.request("POST", path, params)
# 用户信息
def user_detail(self, uid):
path = "/weapi/v1/user/detail/{}".format(uid)
return self.request("POST", path)

def user_level(self):
path = "/weapi/user/level"
return self.request("POST", path)

# 连续签到天数、第二天可获得的云贝数
def yunbei(self):
path = "/weapi/point/today/get"
return self.request("POST", path).get("data", [])
#signed_days=resp['data']['days']
#yunbei=resp['data']['shells']

# 今日签到可获得的云贝数
def yunbei_today(self):
path = "/weapi/point/today/get"
return self.request("POST", path).get("data", [])
#yunbei=resp['data']['shells']

# 账号云贝数
def yunbei_info(self):
path = "/weapi/v1/user/info"
return self.request("POST", path).get("userPoint", [])
#yunbei=resp['userPoint']['balance']

# 云贝所有任务
def yunbei_task(self):
path = "/weapi/usertool/task/list/all"
return self.request("POST", path)#.get("data", [])
#tasks=[{'userTaskId':task['userTaskId'],'taskName':task['taskName'],'taskPoint':task['taskPoint'],'completed':task['completed'],'taskDescription':task['taskDescription']} for task in resp['data']]

# 云贝todo任务
def yunbei_task_todo(self):
path = "/weapi/usertool/task/todo/query"
return self.request("POST", path)#.get("data", [])

# 完成云贝任务
def yunbei_task_finish(self, userTaskId, depositCode):
path = "/weapi/usertool/task/point/receive"
params = dict(userTaskId=userTaskId,depositCode=depositCode)
return self.request("POST", path, params)
# {'code': 200, 'message': 'SUCCESS', 'data': True}

# 云贝收入
def yunbei_receipt(self, limit=10,offset=0):
path = "/store/api/point/receipt"
params = dict(limit=limit,offset=offset)
return self.request("POST", path, params)

# 云贝支出
def yunbei_expense(self, limit=10,offset=0):
path = "/store/api/point/expense"
params = dict(limit=limit,offset=offset)
return self.request("POST", path, params)

def share_resource(self, type='playlist',msg='',id=''):
path = "/weapi/share/friends/resource"
params = dict(type=type,msg=msg,id=id)
return self.request("POST", path, params)
# if resp['code'] == 200:
# event_id = resp['id']

# 获取用户动态
def user_event(self, uid,limit=30,time=-1):
path = "/weapi/event/get/{}".format(uid)
params = dict(getcounts=True,time=time,limit=limit,total=False)
return self.request("POST", path, params)
# event_ids = [event['id'] for event in resp['events']]

# 删除动态
def event_delete(self, id):
path = "/weapi/event/delete"
params = dict(id=id)
return self.request("POST", path, params)
# {'code': 200}

# 删除歌单
def playlist_delete(self, ids):
path = "/weapi/playlist/remove"
params = dict(ids=ids)
return self.request("POST", path, params)
# {'code': 200}

def user_homepage(self,userId):
path="/weapi/personal/home/page/user"
params=dict(userId=userId)
return self.request("POST", path,params)

###########################
# 音乐人

# 概况
def musician_data(self):
path='/weapi/creator/musician/statistic/data/overview/get'
return self.request("POST", path)

# 获取任务
def mission_cycle_get(self,actionType='',platform=''):
path='/weapi/nmusician/workbench/mission/cycle/list'
if actionType=='' and platform == '':
return self.request("POST", path)
else:
params=dict(actionType=actionType,platform=platform)
return self.request("POST", path,params)

# 领取云豆
def reward_obtain(self,userMissionId,period):
path='/weapi/nmusician/workbench/mission/reward/obtain/new'
params=dict(userMissionId=userMissionId,period=period)
return self.request("POST", path,params)

# 账号云豆数
def cloudbean(self):
path = "/weapi/cloudbean/get"
return self.request("POST", path)

def user_access(self):
path='/weapi/creator/user/access'
return self.request("POST", path)
# API end






# jiemi
__all__ = ["encrypted_id", "encrypted_request"]

MODULUS = (
"00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7"
"b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280"
"104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932"
"575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b"
"3ece0462db0a22b8e7"
)
PUBKEY = "010001"
NONCE = b"0CoJUm6Qyw8W8jud"


# 歌曲加密算法, 基于https://github.com/yanunon/NeteaseCloudMusic
def encrypted_id(id):
magic = bytearray("3go8&$8*3*3h0k(2)2", "u8")
song_id = bytearray(id, "u8")
magic_len = len(magic)
for i, sid in enumerate(song_id):
song_id[i] = sid ^ magic[i % magic_len]
m = hashlib.md5(song_id)
result = m.digest()
result = base64.b64encode(result).replace(b"/", b"_").replace(b"+", b"-")
return result.decode("utf-8")


# 登录加密算法, 基于https://github.com/stkevintan/nw_musicbox
def encrypted_request(text):
# type: (str) -> dict
data = json.dumps(text).encode("utf-8")
secret = create_key(16)
params = aes(aes(data, NONCE), secret)
encseckey = rsa(secret, PUBKEY, MODULUS)
return {"params": params, "encSecKey": encseckey}


def aes(text, key):
pad = 16 - len(text) % 16
text = text + bytearray([pad] * pad)
encryptor = AES.new(key, 2, b"0102030405060708")
ciphertext = encryptor.encrypt(text)
return base64.b64encode(ciphertext)


def rsa(text, pubkey, modulus):
text = text[::-1]
rs = pow(int(binascii.hexlify(text), 16), int(pubkey, 16), int(modulus, 16))
return format(rs, "x").zfill(256)


def create_key(size):
return binascii.hexlify(os.urandom(size))[:16]


# jiemi end

msg = ""

title = "网易云音乐"

# 账号信息
config = {
"users":[
{
"username":"17156087896",
"md5":False,
"password":"abc211314"

},{
"username":"17806275268",
"md5":False,
"password":"abc211314"
}
],

"setting":{

"serverChan":{
"on":False,
"SCKEY":"SCU155663T250c7c2cfb1ed174cfd9dfbb93f9edc4601166eb99dec"
},
"CoolPush":{
"on":False,
"method":["send"],
"Skey":""
},
"sign":True,
"musician_sign":True,
"daka":{
"on":True,
"full_stop":True,
"song_number":1000,
"sleep_time":15,
"upload_num":300
},
"yunbei":{
"share":{
"on":False,
"id":[],
"msg":["每日分享","今日分享","分享歌单"],
"delete":True,
"taskName":"发布动态"
}
},
"other":{
"play_playlists":{
"on":False,
"playlist_ids":[],
"times":1
},
"play_albums":{
"on":False,
"album_ids":[],
"times":1
},
"play_songs":{
"on":False,
"song_ids":[],
"times":30
}
},
"follow":True
}
}

#print(config)



def weChatPush(txt):
Secret = "GuabRMpWYTIeIkk_Dc-sX5LJi59M_7JfCk9KJrtn8Bs"
corpid = 'ww41560323f54f5b7b'
url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={}&corpsecret={}'
getr = requests.get(url=url.format(corpid, Secret))
access_token = getr.json().get('access_token')
data = {
"touser": "@all",
"msgtype": "text",
"agentid": 1000003,
"text": {
"content": "网易云音乐信息\n" + txt
},
"safe": 0,
}
requests.post(url="https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={}".format(access_token),data=json.dumps(data))
pass


def start():
global msg
global title
title = "网易云音乐"
msg = ''
print('开始登录:')
setting = config['setting']
#serverChan_url = 'https://sc.ftqq.com/'+setting['serverChan']['SCKEY']+'.send'
#serverChan_url2 = 'https://sctapi.ftqq.com/SCT10915TrbGLdfzI6Cwuy6HqOTS4JaW1.send'

user_count = 0

for user in config['users']:
user_count += 1
if "setting" in user:
user_setting = user['setting']
else:
user_setting = setting

username = user['username']
if user['md5']:
md5_pwd = user['password']
else:
pwd = user['password']
md5_pwd = hashlib.md5(pwd.encode(encoding='UTF-8')).hexdigest()

#登录
music = NetEase()
login = music.login(username,md5_pwd)

if login["code"] == 200:
music.user_setting = user_setting
userType = login['profile']['userType']
user_info(music)
if user_setting['follow']:
follow(music)
if user_setting['sign']:
sign(music)
if user_setting['musician_sign'] and userType == 4:
musician_sign(music)

if user_setting['daka']['on']:
daka(music,user_setting)

if user_setting['other']['play_playlists']['on']:
play_playlists(music,user_setting)
if user_setting['other']['play_albums']['on']:
play_albums(music,user_setting)
if user_setting['other']['play_songs']['on']:
play_songs(music,user_setting)

yunbei_task(music,user_setting)
get_yunbei(music)
else:
title += ': 登录失败,请检查账号、密码'
msg += '用户信息\n- 登录失败,请检查账号、密码\n\n'

#print(msg)
weChatPush(msg)

def user_info(music):
global msg
resp = music.user_detail(music.uid)
music.listenSongs = resp['listenSongs']
msg += '用户信息\n- 用户名称:'+resp['profile']['nickname']+'\n- 用户ID:'+str(music.uid)+'\n- 用户等级:'+str(resp['level'])+'\n- 云贝数量:'+str(resp['userPoint']['balance'])+'\n- 粉丝数量:'+str(resp['profile']['followeds'])+'\n- 听歌总数:'+str(music.listenSongs)
resp = music.user_level()
music.full=resp['full']
if not resp['full']:
msg += '\n- 距离下级还需'+str(resp['data']['nextPlayCount']-resp['data']['nowPlayCount'])+'首歌\n- 登录天数:'+str(resp['data']['nowLoginCount'])+'\n- 距离下级还需登录'+str(resp['data']['nextLoginCount']-resp['data']['nowLoginCount'])+'天\n\n'
else:
msg += '\n\n'
def daka(music,user_setting):
global msg
global title
msg += "打卡信息\n"
# msg += '- 预计打卡'+str(total)+'首\n'
resp = music.user_level()
if user_setting['daka']['full_stop'] and music.full:
msg += '- 您的等级已经爆表了,无需再打卡\n\n'
else:
#---------------开始打卡---------------
playlists = music.recommend_resource()
#推荐歌单id列表
playlist_ids = [playlist["id"] for playlist in playlists]

total = user_setting['daka']['song_number']

# for i in range(user_setting['daka']['loop_count']):
# msg += '- 第'+str(i+1)+'次打卡\n'
song_datas = []
#打乱歌单id
random.shuffle(playlist_ids)
for playlist_id in playlist_ids:
#获得歌单中歌曲的信息
songs = music.playlist_detail(playlist_id).get("playlist", {}).get("tracks", [])
for song in songs:
song_data={
"type": 'song',
"wifi": 0,
"download": 0,
"id": song['id'],
"time": math.ceil(song['dt']/1000),
"end": 'ui',#playend
"source":'list',
"sourceId": playlist_id,
}
song_datas.append(song_data)
if len(song_datas)>=total:
song_datas = song_datas[0:total]
break

num = music.user_setting['daka']['upload_num']
for i in range(0, len(song_datas), num):
music.daka(song_datas[i:i+num])
time.sleep(user_setting['daka']['sleep_time'])
resp = music.user_detail(music.uid)
if (resp['listenSongs']-music.listenSongs)>=300:
title = title + '本次听歌'+str(resp['listenSongs']-music.listenSongs)+'首,累计听歌'+str(resp['listenSongs'])+'首'
msg += '- 听歌总数:'+str(resp['listenSongs'])+'首\n- 本次打卡:'+str(resp['listenSongs']-music.listenSongs)+'首\n- 打卡数据更新有延时,请到网易云音乐APP中查看准确信息\n\n'
return

#---------------结束打卡---------------
time.sleep(user_setting['daka']['sleep_time']+5)
resp = music.user_detail(music.uid)
title = title + '本次听歌'+str(resp['listenSongs']-music.listenSongs)+'首,累计听歌'+str(resp['listenSongs'])+'首'
msg += '- 听歌总数:'+str(resp['listenSongs'])+'首\n- 本次打卡:'+str(resp['listenSongs']-music.listenSongs)+'首\n- 打卡数据更新有延时,请到网易云音乐APP中查看准确信息\n\n'

def play_playlists(music,user_setting):
global msg
msg += "播放歌单\n"
playlist_ids = user_setting['other']['play_playlists']['playlist_ids']
if len(playlist_ids) == 0:
msg += '- 无可播放歌单\n\n'
return
count = user_setting['other']['play_playlists']['times']

msg += '- 正在播放以下歌单\n'
song_datas = []
for playlist_id in playlist_ids:
#获得歌单中歌曲的信息
result = music.playlist_detail(playlist_id)
if result['code'] != 200:
msg += ' - 歌单id: {} 错误\n'.format(playlist_id)
break
songs = result.get("playlist", {}).get("tracks", [])

msg += ' - '+result["playlist"]['name']+'\n'

for song in songs:
song_data={
"type": 'song',
"wifi": 0,
"download": 0,
"id": song['id'],
"time": math.ceil(song['dt']/1000),
"end": 'ui',#playend
"source":'list',
"sourceId": playlist_id,
}
song_datas.append(song_data)
for i in range(count):
play(music,song_datas)
time.sleep(1)
#---------------结束播放---------------
msg += '- 歌单已播放'+str(count)+'次\n\n'

def play_albums(music,user_setting):
global msg
msg += "播放专辑\n"
album_ids = user_setting['other']['play_albums']['album_ids']
if len(album_ids) == 0:
msg += '- 无可播放专辑\n\n'
return

count = user_setting['other']['play_albums']['times']

msg += '- 正在播放以下专辑\n'
song_datas = []
for album_id in album_ids:
#获得专辑中歌曲的信息
result = music.album(album_id)
if result['code'] != 200:
msg += ' - 专辑id: {} 错误\n'.format(album_id)
break
songs = result.get("songs", [])

msg += ' - '+result['album']['name']+'\n'

for song in songs:
song_data={
"type": 'song',
"wifi": 0,
"download": 0,
"id": song['id'],
"time": math.ceil(song['dt']/1000),
"end": 'ui',#playend
"source":'album',
"sourceId": album_id,
}
song_datas.append(song_data)
for i in range(count):
play(music,song_datas)
time.sleep(0.1)
#---------------结束播放---------------
msg += '- 专辑已播放'+str(count)+'次\n\n'

def play_songs(music,user_setting):
global msg
msg += "播放歌曲\n"
song_ids = user_setting['other']['play_songs']['song_ids']
if len(song_ids) == 0:
msg += '- 无可播放歌曲\n\n'
return

count = user_setting['other']['play_songs']['times']

msg += '- 正在播放以下歌曲\n'
song_datas = []

temp_datas = []
#获得歌曲的信息
songs = music.songs_detail(song_ids)
for song in songs:
msg += ' - '+song['name']+'\n'
song_data={
"type": 'song',
"wifi": 0,
"download": 0,
"id": song['id'],
"time": math.ceil(song['dt']/1000),
"end": 'ui',#playend
}
temp_datas.append(song_data)
for i in range(count):
song_datas.extend(temp_datas)
play(music,song_datas)

#---------------结束播放---------------
#account_info = music.user_detail(uid)
msg += '- 歌曲已播放'+str(count)+'次\n\n'

def yunbei_task(music,user_setting):
global msg
msg += "云贝任务\n"
count = 0
resp = music.yunbei_task()
for task in resp['data']:
if task['userTaskId']==0:
if user_setting['yunbei']['share']['taskName']==task['taskName'] and user_setting['yunbei']['share']['on']:
count += 1
if len(user_setting['yunbei']['share']['id'])>0:
playlist_id = random.choice(user_setting['yunbei']['share']['id'])
else:
playlists = music.recommend_resource()
playlist_ids = [playlist["id"] for playlist in playlists]
playlist_id = random.choice(playlist_ids)

if len(user_setting['yunbei']['share']['msg'])>0:
event_msg = random.choice(user_setting['yunbei']['share']['msg'])
else:
event_msg = '每日分享'

result = music.share_resource(type='playlist',msg=event_msg,id=playlist_id)
if result['code']==200:
event_id = result['id']
if user_setting['yunbei']['share']['delete']:
time.sleep(0.5)
delete_result = music.event_delete(event_id)
msg += '- 分享成功,已删除动态\n'
else:
msg += '- 分享成功\n'
else:
msg += '- 分享失败:{}\n'.format(result)

time.sleep(2)

if count > 0:
msg += '\n'
else:
msg += '- 无可执行的任务\n\n'
def get_yunbei(music):
global msg
msg += "领取云贝\n"
resp = music.yunbei_task_todo()
count = 0
for task in resp['data']:
if task['userTaskId']>0:
music.yunbei_task_finish(task['userTaskId'], task['depositCode'])
msg += '- {}:云贝+{}\n'.format(task['taskName'],task['taskPoint'])
count += 1
if count > 0:
msg += '\n'
else:
msg += '- 无可领取的云贝\n\n'

def play(music,song_datas,sleep_time=0.4):
if "upload_num" in music.user_setting['daka']:
num = music.user_setting['daka']['upload_num']
else:
num = 300
for i in range(0, len(song_datas), num):
music.daka(song_datas[i:i+num])
time.sleep(sleep_time)


def follow(music):
author_uid = 347837981
result = music.user_detail(author_uid)
if music.uid != author_uid and not result['profile']['followed']:
print(music.user_follow(author_uid))


def sign(music):
global msg
msg+='签到信息\n'
#---------------开始签到---------------
#手机端签到
sign_phone = music.daily_task(True)
code_phone = sign_phone["code"]
if code_phone == 200:
msg += "- 手机端:签到成功,云贝+" + str(sign_phone["point"])
elif code_phone == -2:
msg += "- 手机端:重复签到"
else:
msg += "- 手机端:未登录"
msg += '\n'

#桌面端签到
sign_pc = music.daily_task(False)
code_pc = sign_pc["code"]
if code_pc == 200:
msg += "- PC端:签到成功,云贝+" + str(sign_pc["point"])
elif code_pc == -2:
msg += "- PC端:重复签到"
else:
msg += "- PC端:未登录"
msg += '\n\n'
#---------------结束签到---------------


def musician_sign(music):
global msg
msg+='音乐人信息\n'

access_result = music.user_access()
result = music.mission_cycle_get()
if result['code'] == 200:
mission_list = result.get('data',{}).get('list',[])
for mission in mission_list:
if mission['status'] == 20:
description = mission['description']
userMissionId = mission['userMissionId']
period = mission['period']
rewardWorth = mission['rewardWorth']

reward_result = music.reward_obtain(userMissionId=userMissionId,period=period)
if reward_result['code'] == 200:
msg += "- " + description + ":云豆+"+str(rewardWorth) + "\n"

elif mission['description'] == '每日登录音乐人中心' and mission['status'] == 100:
msg += "- 每日登录音乐人中心:已领取\n"

info_result = music.musician_data()
data = info_result.get('data',{})

if data['playCount'] is None:
msg += "- 昨日播放量: -- \n"
else:
msg += "- 昨日播放量:"+str(data['playCount']) + "\n"

if data['followerCountIncrement'] is None:
msg += "- 昨日新增粉丝(人): -- \n"
else:
msg += "- 昨日新增粉丝(人):"+str(data['followerCountIncrement']) + "\n"

if data['productionTotal'] is None:
msg += "- 作品(首): -- \n"
else:
msg += "- 作品(首):"+str(data['productionTotal']) + "\n"

if data['availableExtractIncomeTotal'] is None:
msg += "- 可提现余额: -- \n"
else:
msg += "- 可提现余额:"+str(data['availableExtractIncomeTotal']) + "\n"

if data['musicianLevelScore'] is None:
msg += "- 音乐人指数: -- \n"
else:
msg += "- 音乐人指数:"+str(data['musicianLevelScore']) + "\n"

msg += '\n'

if __name__ == '__main__':
start()




WPS
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
# -*- coding: utf8 -*-
#-*- codeing =utf-8 -*-
#@Time : 2021/2/8 10:42
#@File : wps签到领空间.py
#@Software : PyCharm
import requests
import json
import time
import random
wps_sid="wps_sid=V02SecH4GwO7-a9BOK7-INGAA04c1bo00aaefe2000435d4e79"
#SCKEY = 'SCU155663T250c7c2cfb1ed174cfd9dfbb93f9edc4601166eb99dec'
#SCKEY2 = 'SCT10915TrbGLdfzI6Cwuy6HqOTS4JaW1'

# 微信推送
def weChatPush(txt):
Secret = "GuabRMpWYTIeIkk_Dc-sX5LJi59M_7JfCk9KJrtn8Bs"
corpid = 'ww41560323f54f5b7b'
url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={}&corpsecret={}'
getr = requests.get(url=url.format(corpid, Secret))
access_token = getr.json().get('access_token')
data = {
"touser": "@all",
"msgtype": "text",
"agentid": 1000003,
"text": {
"content": "WPS签到领空间\n" + txt
},
"safe": 0,
}
requests.post(url="https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={}".format(access_token),data=json.dumps(data))
pass

def wps():
url="https://vip.wps.cn/sign/v2"
headers={
"Cookie":wps_sid,
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.10586"
}
data={"platform":"8",
"captcha_pos":"137.00431974731889, 36.00431593261568",
"img_witdh":"275.164",
"img_height":"69.184"
}
data0={"platform":"8"}
yz_url="https://vip.wps.cn/checkcode/signin/captcha.png?platform=8&encode=0&img_witdh=275.164&img_height=69.184"

req=requests.post(url=url,headers=headers,data=data0)
if not ("msg" in req.text):
print("wps_sid无效")
return "wps_sid无效"
else:
sus=json.loads(req.text)["result"]
print("免验证签到-->"+sus)
if sus == "error":
for n in range(60):
requests.get(url=yz_url,headers=headers)
req=requests.post(url=url,headers=headers,data=data)
sus=json.loads(req.text)["result"]
#print(str(n+1)+"尝试验证签到-->"+sus)
time.sleep(random.randint(0,5)/10)
if sus=="ok":
sus="成功!"
break
sus="失败,请手动签到!"
print("最终签到结果-->"+sus)
return "最终签到结果:"+sus

def main():
s=wps()
weChatPush(s)
print(s)

if __name__ == '__main__':
main()

GPU查看显卡显存

1
2
3
4
5
6
7
8
9
10


# 查看GPU01显卡状态
jsub -q normal -n 1 -e error.%J -o output.%J -J my_job -m gpu01 nvidia-smi
# cat output.作业号

# 查看GPU02显卡状态
jsub -q normal -n 1 -e error.%J -o output.%J -J my_job -m gpu02 nvidia-smi
# cat output.作业号

linux用户sudo不输密码 Linux sudo操作免密码

sudo是以管理员权限进行操作,但是需要输入密码,如果想在用sudo时不用输入密码,需要修改/etc/sudoers 文件。

https://www.jianshu.com/p/82f65fb1fde0

1
2
3
4
5
6

sudo vi /etc/sudoers

# 在最下面一行加上,下面的username需要改成自己的用户名:

username ALL=(ALL:ALL) NOPASSWD: ALL

Miniconda 安装

地址 https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/?C=M&O=D

限制root用户远程登录 只能登录普通用户在登录

1
2
3
4
5
6
7
8
9
10
11

vim /etc/ssh/sshd_config


#
#PermitRootLogin yes
#改为
#PermitRootLogin no

systemctl restart sshd

查看jhappform密码

1
2
3
4
5
6

cd /apps/jhinno/appform/etc/base/

cat /apps/jhinno/appform/conf/execproxy/jhlogon/jhlogon.qyf

./jhencrypt -d mima

为vscode配置LaTex

1
2
3
4
5
6
7
8
9

# 获取ISO文件
https://tug.org/texlive/acquire-iso.html

# 下载ISO文件后安装




image-20220520143728677

image-20220520143747575

image-20220520143926471

img

image-20220520144032928

安装VScode插件

输入**”latex workshop”**,选择第一个LaTeX Workshop插件;

Ctrl + ,进入设置页面。

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
{
"latex-workshop.latex.autoBuild.run": "never",
"latex-workshop.showContextMenu": true,
"latex-workshop.intellisense.package.enabled": true,
"latex-workshop.message.error.show": false,
"latex-workshop.message.warning.show": false,
"latex-workshop.latex.tools": [
{
"name": "xelatex",
"command": "xelatex",
"args": [
"-synctex=1",
"-interaction=nonstopmode",
"-file-line-error",
"%DOCFILE%"
]
},
{
"name": "pdflatex",
"command": "pdflatex",
"args": [
"-synctex=1",
"-interaction=nonstopmode",
"-file-line-error",
"%DOCFILE%"
]
},
{
"name": "latexmk",
"command": "latexmk",
"args": [
"-synctex=1",
"-interaction=nonstopmode",
"-file-line-error",
"-pdf",
"-outdir=%OUTDIR%",
"%DOCFILE%"
]
},
{
"name": "bibtex",
"command": "bibtex",
"args": [
"%DOCFILE%"
]
}
],
"latex-workshop.latex.recipes": [
{
"name": "XeLaTeX",
"tools": [
"xelatex"
]
},
{
"name": "PDFLaTeX",
"tools": [
"pdflatex"
]
},
{
"name": "BibTeX",
"tools": [
"bibtex"
]
},
{
"name": "LaTeXmk",
"tools": [
"latexmk"
]
},
{
"name": "xelatex -> bibtex -> xelatex*2",
"tools": [
"xelatex",
"bibtex",
"xelatex",
"xelatex"
]
},
{
"name": "pdflatex -> bibtex -> pdflatex*2",
"tools": [
"pdflatex",
"bibtex",
"pdflatex",
"pdflatex"
]
},
],
"latex-workshop.latex.clean.fileTypes": [
"*.aux",
"*.bbl",
"*.blg",
"*.idx",
"*.ind",
"*.lof",
"*.lot",
"*.out",
"*.toc",
"*.acn",
"*.acr",
"*.alg",
"*.glg",
"*.glo",
"*.gls",
"*.ist",
"*.fls",
"*.log",
"*.fdb_latexmk"
],
"latex-workshop.latex.autoClean.run": "onFailed",
"latex-workshop.latex.recipe.default": "lastUsed",
"latex-workshop.view.pdf.internal.synctex.keybinding": "double-click"
}

测试文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

\documentclass[a4paper]{article}
\usepackage[margin=1in]{geometry} % 设置边距,符合Word设定
\usepackage{ctex}
\usepackage{lipsum}
\title{\heiti\zihao{2} This is a test for vscode}
\author{\songti Ali-loner}
\date{2020.08.02}
\begin{document}
\maketitle
\begin{abstract}
\lipsum[2]
\end{abstract}
\tableofcontents
\section{This is a section}
Hello world! 你好,世界 !
\end{document}

服务器上安装配置jupyter

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
# 更新 pip 安装 jupyter
pip install --upgrade pip
pip install jupyter

# 配置一下 参数 生成一个配置文件 几下文件位置 ex:/home/peak/.jupyter/jupyter_notebook_config.py
jupyter notebook --generate-config

# 运行python 设置一个密码 登录密码 Qyf9999.
from notebook.auth import passwd
passwd()

# 输入2次密码用来登录你的jupyter notebook 此时会生成一个密钥 ex: 'sha1:43b95b731276:5d330ee6f6054613b3ab4cc59c5048ff7c70f549'
# 修改配置文件 删除前面的#注释
vim /home/peak/.jupyter/jupyter_notebook_config.py

# 修改项 允许所有IP访问 前面密码的密钥 默认启动时不打开浏览器 修改端口为8889
c.NotebookApp.ip='0.0.0.0'
c.NotebookApp.password = 'sha1:43b95b731276:5d330ee6f6054613b3ab4cc59c5048ff7c70f549'
c.NotebookApp.open_browser = False
c.NotebookApp.port = 8889

# 保存好后启动 加载配置文件 并把日志保存到指定位置 输入exit 退出即可
jupyter notebook --config /home/peak/.jupyter/jupyter_notebook_config.py --allow-root > /home/peak/log/log.log & exit

# 如果想要停止 查到进程号后 可以直接 kill -9 进程号
ps -ef | grep 'jupyter'
kill -9 进程号

Jupyter notebook 指定 Python 解释器

1
2
3
4
5
6
# 创建并进入conda环境 安装ipykernel
conda activate Dpt
pip install ipykernel

# 将当前conda环境加入到jupyter中 /opt/miniconda3/envs/Dpt/bin/python是Dpt环境的目录
sudo /opt/miniconda3/envs/Dpt/bin/python -m ipykernel install --name Dpt

Python 文件读写与动态输出

追加文件内容到文件中

1
2
3
4
5
6
7
8
9
10
11
12
import time

# 打开文件 以追加的形式打开
time1 = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
file = open("/home/abc.log", "a")
str = "the log file created in " + time1

# 写入文件缓冲区 + '\n'表示换行
file.write( str + '\n' )

# 写入文件中
file.flush()

读取文件并输出,监控文件变化并输出

1
2

tail -f -n 20 file.txt

建好的环境进行注册,通过gym的标准形式进行调用

  1. 将我们自己的环境文件(我创建的文件名为grid_mdp.py)拷贝到你的gym安装目录/gym/gym/envs/classic_control文件夹中。(拷贝在这个文件夹中因为要使用rendering模块。当然,也有其他办法。该方法不唯一)

    /opt/miniconda3/envs/Dpt/lib/python3.7/site-packages/gym

  2. 打开该文件夹(第一步中的文件夹)下的__init__.py文件,在文件末尾加入语句:

1
2
3

from gym.envs.classic_control.grid_mdp import GridEnv

  1. 进入文件夹你的gym安装目录/gym/gym/envs,打开该文件夹下的__init__.py文件,添加代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14

register(

id='GridWorld-v0',

entry_point='gym.envs.classic_control:GridEnv',

max_episode_steps=200,

reward_threshold=100.0,

)

# 可以通过该id 来调用该环境 env = gym.make('GridWorld-v0')

VSCode remote连接服务器

  1. 安装remote development插件

  2. 配置公玥登录

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    # 在本地的 user/xxx/.ssh/ 下执行生成公玥命令

    ssh-keygen -t rsa


    # 上传到服务器 并添加到密钥登录

    scp id_rs.pub 用户名@IP地址:/tmp

    # 配置 并修改权限

    cat /tmp/id_rs.pub >> ~/.ssh/authorized_keys
    chmod 600 ~/.ssh/authorized_keys
    sudo systemctl restart sshd

  3. 在VSCode中修改配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    Host 名称
    HostName IP
    User 用户名
    IdentityFile "C:\Users\yufen\.ssh\id_rsa" # 公玥文件地址


    Host 3090
    HostName 172.19.163.234
    User peak
    port 22
    IdentityFile "C:\\Users\\yufen\\.ssh\\id_rsa"

在VSCode中配置conda

  1. 安装 python 插件
  2. 按“shift+ctrl+p”,搜索 Select Interpreter: 选择并重启VS code 即可。

权限相关

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 创建用户组 
sudo groupadd 组名
#

# 更改文件的所属用户组
sudo chgrp -R 组名 目录



# 更改文件夹的权限 -R 递归
sudo chmod 770 -R 目录/文件名

# 为用户添加用户组
sudo usermod -a -G 用户名 用户组

# 新建用户并加入用户组
sudo adduser -u 用户名 -G 用户组

1
2
3
4
5
#查看torch版本,cuda是否可用

import torch
print(torch.__version__)
print(torch.cuda.is_available())

UPC GPU账号认证服务没有开启,

开启方法是:使用root登录master,

1
2
ssh -X io01
vmware

开启服务,关闭界面(后台运行vmware)

SH

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
133
134
135
136
137
138
139
140


# 亮屏状态下:screen=`dumpsys window policy | grep mIsShowing | grep 'false'` 亮屏下有返回值mIsShowing=false


#返回
input keyevent BACK





am force-stop com.eg.android.AlipayGphone
sleep 3
am start com.eg.android.AlipayGphone/.FastStartActivity
sleep 3
am startservice com.eg.android.AlipayGphone/com.alipay.android.launcher.service.LauncherService
sleep 1


#启动与停止服务
am startservice com.eg.android.AlipayGphone/com.alipay.android.launcher.service.LauncherService
am stopservice com.eg.android.AlipayGphone/com.alipay.android.launcher.service.LauncherService




#!/system/bin/sh
#唤醒屏幕的脚本
LogDir="/sdcard/Android/Peak/run.log"
startTime=$(date +%m/%d-%H:%M:%S)
echo $startTime" : Start Keep Screen ON " >> $LogDir
screen=`dumpsys window policy | grep mIsShowing | grep 'false'`

if [ -z $screen ]
then
echo " Now screen is OFF,try to start!" >> $LogDir
input keyevent 26
sleep 1
input swipe 800 2000 800 1200
sleep 1
else
echo " Now screen is On,it's OK! " >> $LogDir
fi



com.eg.android.AlipayGphone




#!/system/bin/sh
#唤起支付宝脚本
LogDir="/sdcard/Android/Peak/run.log"
startTime=$(date +%m/%d-%H:%M:%S)
echo $startTime" : Start Ali Now " >> $LogDir
COUNT=$(ps -ef |grep payGphone |grep -v "grep" |wc -l)
screen=`dumpsys window policy | grep mIsShowing | grep 'false'`

if [ -z $screen ]
then
echo " Now screen is OFF,try to start!" >> $LogDir
input keyevent 26
sleep 1
input swipe 800 2000 800 1200
sleep 1
else
echo " Now screen is On,it's OK! " >> $LogDir
fi

if [ $COUNT -ne 0 ] ;then
echo " Ali is runing!" >> $LogDir
am stopservice com.eg.android.AlipayGphone/com.alipay.android.launcher.service.LauncherService
sleep 1
am startservice com.eg.android.AlipayGphone/com.alipay.android.launcher.service.LauncherService
else
echo " Ali is not run, try to start!" >> $LogDir
am start com.eg.android.AlipayGphone/.FastStartActivity
sleep 1
input keyevent BACK
am startservice com.eg.android.AlipayGphone/com.alipay.android.launcher.service.LauncherService
sleep 1
fi







#!/system/bin/sh
#关闭耗电应用 准备睡觉 QQ 微信 音乐 支付宝 并清理垃圾
LogDir="/sdcard/Android/Peak/run.log"
startTime=$(date +%m/%d-%H:%M:%S)
echo $startTime" : Start Sleep to stop APP" >> $LogDir

am force-stop com.eg.android.AlipayGphone
am force-stop com.tencent.mm
am force-stop com.tencent.mobileqq
am force-stop com.netease.cloudmusic

LogDir="/sdcard/Android/Peak/run.log"
startTime=$(date +%m/%d-%H:%M:%S)
echo $startTime" : Fuck file" >> $LogDir
# 加载配置文件
source /data/adb/modules/CrondStart/sh/FUCK-XXX.conf
# 读取配置文件
for i in $sdcard $Download $Android $SelfDefinition; do
rm -rf $i ;
done



#!/system/bin/sh
#启动常用软件放到后台并锁屏
LogDir="/sdcard/Android/Peak/run.log"
startTime=$(date +%m/%d-%H:%M:%S)
echo $startTime" : Start some APP to background " >> $LogDir
screen=`dumpsys window policy | grep mIsShowing | grep 'false'`
am start com.tencent.mm/.ui.LauncherUI
sleep 10
input keyevent BACK
am start com.netease.cloudmusic/.activity.LoadingActivity
sleep 10
input keyevent BACK
am force-stop com.netease.cloudmusic
am force-stop com.eg.android.AlipayGphone


if [ -z $screen ]
then
echo " Now screen is OFF,done!" >> $LogDir
else
echo " Now screen is On,take it OFF! " >> $LogDir
input keyevent 26
fi



Win11关闭小组件

1
2
#管理员权限打开powershell,输入以下命令:
Get-AppxPackage -Name "MicrosoftWindows.Client.WebExperience" -AllUsers | Remove-AppxPackage -AllUsers

ssh远程链接服务器,避免因断网而中断训练de 方法


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#1 链接服务器.

#2 利用screen 命令 ,重起一个新的screen.

#新screen的名字,可以任起

screen -S name

#3 开始训练.

#4 可以断开terminal,此时训练不受影响


#恢复
#1 启动terminal,查看存在的screen的命令.

screen -ls

screen -r 30362

#2 断开当前的screen.
按 Ctrl + A, 然后 K 键 然后 y 键

杀掉端口

1
sudo fuser -k -n tcp 5000

Vmware workstation 16许可证

1
2
3
4
5
6
7
ZF3R0-FHED2-M80TY-8QYGC-NPKYF
YF390-0HF8P-M81RQ-2DXQE-M2UT6
ZF71R-DMX85-08DQY-8YMNC-PPHV8

前面的如果已经失效,用下面的

FA1M0-89YE3-081TQ-AFNX9-NKUC0

CentOS 8安装docker

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
#更新yum 安装依赖
yum install -y yum-utils device-mapper-persistent-data lvm2

#添加yum源
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

#安装
yum install docker-ce

#启动并设置开机自启动
systemctl start docker
systemctl enable docker

#验证
docker version

#安装青龙面板

#安装nvjdc 目录之间映射关系
docker run --name nvjdc -p 5702:80 -d -v /home/qyf/workspace/nvjdc/Config.json:/app/Config/Config.json:ro \-v /home/qyf/workspace/nvjdc/.local-chromium:/app/.local-chromium \-it --privileged=true nolanhzy/nvjdc:0.8


#安装chromium
docker container ls -a
yum install unzip
cd /home/qyf/workspace/nvjdc/
mkdir -p .local-chromium/Linux-884014 && cd .local-chromium/Linux-884014
wget https://mirrors.huaweicloud.com/chromium-browser-snapshots/Linux_x64/884014/chrome-linux.zip && unzip chrome-linux.zip
unzip chrome-linux.zip
docker restart nvjdc

#reboot后如何重新启用青龙面板
docker exec -it qinglong bash
cd /ql/ninja/backend
pm2 start


docker exec -it qinglong nginx -c /etc/nginx/nginx.conf


防火墙

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

#查看

防火墙某个端口是否开放

firewall-cmd --query-port=3306/tcp

#开放防火墙端口3306

firewall-cmd --zone=public --add-port=3306/tcp --permanent

firewall-cmd --zone=public --add-port=8889/tcp --permanent
firewall-cmd --zone=public --add-port=5000/tcp --permanent


#注意:开放端口后要重启防火墙生效

#重启防火墙

systemctl restart firewalld

#关闭防火墙端口

firewall-cmd --remove-port=3306/tcp --permanent

#查看防火墙状态

systemctl status firewalld

#关闭防火墙

systemctl stop firewalld

#打开防火墙

systemctl start firewalld

#开放一段端口

firewall-cmd --zone=public --add-port=40000-45000/tcp --permanent

#查看开放的端口列表

firewall-cmd --zone=public --list-ports

#查看被监听(Listen)的端口

netstat -lntp

#检查端口被哪个进程占用

netstat -lnp|grep 3306

UPC

1
2
#监控服务启动  status状态
/etc/init.d/jhinsight-jhdc start
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23


# 1 Linux 安装Conda环境

# https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/



#下载

# 2 上传到服务器



# 3 安装



# 查看torch版本,cuda是否可用

import torch
print(torch.__version__)
print(torch.cuda.is_available())

Conda 迁移

Step1:在想要迁移的虚拟环境sample中安装conda-pack工具包

1
2
3
source activate sample
conda install conda-pack
conda install -c conda-forge conda-pack

或者采用pip安装

1
pip install conda-pack  #pip install git+https://github.com/conda/conda-pack.git

Step2:将当前虚拟环境sample打包

1
2
3
4
conda-pack
ls
# example.tar.gz 即为打包完成的输出文件
source deactivate

Step3:将example.tar.gz迁移到其他路径或其他机器

1
mv example.tar.gz ~/computer_two

Step4:在另一台机器上解包

1
2
3
4
5
6
cd ~/computer_two/
# example.tar.gz 即为迁移过来的环境包
mkdir myenv
tar -xf example.tar.gz -C myenv
ls
# example.tar.gz myenv

Step5:激活虚拟环境

1
source myenv/bin/activate

修改IP地址

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
ip addr  #查看当前网卡名

# - 修改网卡配置文件

vi /etc/sysconfig/network-scripts/ifcfg-ens192


BOOTPROTO=static # 网络模式 -- 固定
ONBOOT=yes # 重启更新
IPADDR=192.168.8.75 # 配置当前节点 IP
NETMASK=255.255.255.0 # 子网掩码
GATEWAY=192.168.1.1 # 网关
DNS1=8.8.8.8 # dns






#创建用户加入用户组

sudo adduser user1
#为用户创建密码方法如下
sudo passwd user1
#删除用户
sudo userdel -r user1
#为用户添加sudo
sudo usermod -a -G wheel user1



#重启网卡

systemctl restart network

版本 内核

1
2
3
4
5
6
7
8
unme -a #查看内核版本

CentOS Linux release 8.4.2105

cat /etc/redhat-release

cat /etc/*release #查看系统版本

GPU运行

nvidia-smi

配置vnc

https://www.cnblogs.com/xuanbjut/p/14289178.html

添加用户

1
2
3
sudo vim /etc/tigervnc/vncserver.users

:1=qyf #对应5901端口

拷贝模板

1
2
sudo cp /usr/lib/systemd/system/vncserver@.service /etc/systemd/system/vncserver@1.service
# @1.service 对应:1用户

设置密码

1
2
3
4
5
6
vncpasswd

sudo systemctl start vncserver@:1 #对应:1用户

设置开机启动
sudo systemctl enable vncserver@:1

开启服务

1
2
3
sudo systemctl start vncserver@:1

#sudo systemctl start vncserver@:1.service

查看端口

1
sudo netstat -tulpn | grep vnc

配置防火墙

1
2
sudo firewall-cmd --permanent --add-service vnc-server
sudo firewall-cmd --reload

miniconda安装

https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/

下载conda

查看进程

jps

关闭防火墙

sudo systemctl stop firewalld

start开启

windows minconda安装

https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/

https://zhuanlan.zhihu.com/p/102564715

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

首先在conda的终端激活自己想要迁移的环境

conda activate your_env


然后生成自己的环境文件

conda env export > your_env.yaml


在另一台机器上的conda终端克隆迁移的环境即可

conda env create -f your_env.yaml
pip导出安装的库到requirements.txt

pip freeze > requirements.txt

GPU路径

1
2
3
import sys
currenth = '/hpcfiles/users/qyf/project/DeepRL_Algorithms-master'
sys.path.append(currenth)

快速跳转到上N层目录

1
2
3
4
5
6
7
8
9
10
vim /etc/profile
结尾添加别名
alias cd1='cd ..'
alias cd2='cd ../..'
alias cd3='cd ../../..'
alias cd4='cd ../../../..'
alias cd5='cd ../../../../..'
alias cd6='cd ../../../../../..'
使修改生效
source .bashrc 或 source /etc/profile

GPU任务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
jhosts attrib -l 查看到所有资源包含cpu、内存、显卡等资源
jjobs 不使用参数,显示目前正在排队或运行的作业 -a 显示最近完成的作业及正在运行或排队的作业 #-l 作业号 显示指定作业的详细信息
jctrl kill <作业号> 强制杀掉指定的作业
<jsub>: 提交作业
<-q normal>: 指定 normal 队列
<-n 1>: 指定该作业所需 1 核
<-e error.%J>: 错误信息输出到 error.%J 文件中
<-o output.%J>: 正确信息输出到 output.%J 文件中
<-J my_job>: 指定作业名字为 my_job
<test>: 执行的脚本
提交任务
#!/bin/sh
#JSUB -q normal
#JSUB -n 2
#JSUB -e error.%J
#JSUB -o output.%J
#JSUB -J qyf_task
source /apps/software/anaconda3/bin/activate torch
python /hpcfiles/users/qyf/project/DeepRL_Algorithms-master/Algorithms/pytorch/PPO/main.py >> train.log

jsub <./up.sh

gym环境

1
2
3
4
#安装box2d
pip install gym
conda install swig
pip install box2d box2d-kengz --user

HTML网页网课加速助手

document.querySelector(‘video’).playbackRate = 4.0;

防火墙

1
2
3
4
5
6
7
8
9
10
11
# 1.启动防火墙 
systemctl start firewalld
# 2.禁用防火墙
systemctl stop firewalld
# 3.设置开机启动
systemctl enable firewalld
# 4.停止并禁用开机启动
sytemctl disable firewalld
# 5.重启防火墙
firewall-cmd --reload
#end

安装JAVA

1
2
3
4
5
6
7
8
9
10
cd /usr/lib
sudo mkdir jvm #创建/usr/lib/jvm目录用来存放JDK文件
sudo tar -zxvf ./jdk-8u291-linux-x64.tar.gz -C /usr/lib/jvm #解压
vim ~/.bashrc #系统变量
export JAVA_HOME=/usr/lib/jvm/jdk1.8.0_291
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH
source ~/.bashrc #立即生效
#end

ssh 配置免密登录

1
2
3
4
5
6
7
8
9
10
11
12
13

cd ~/.ssh/
# 若没有该目录,请先执行一次ssh localhost
ssh-keygen -t rsa
# 会有提示,都按回车即可
cat ./id_rsa.pub >> ./authorized_keys
# 加入授权
chmod g-w ~
#修改权限SSH不希望home目录和~/.ssh目录对组有写权限
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
#结束

linux用户创建

1
2
3
4
5
6
7
8
sudo adduser user1
#为用户创建密码方法如下
sudo passwd user1
#删除用户
sudo userdel -r user1
#为用户添加sudo
sudo usermod -a -G wheel user1

1
2
3
4
5
6
7
8
9
10
11
mkdir a #创建文件夹
rmdir a #删除文件夹
mv a b #改名,移动
rm a #删除
cp a b #复制文件或目录
cat a #查看文件内容
touch a #修改文件时间或创建新文件
tac a #反向查看文件内容

grep -i 'user' ~/.bashrc #从文件内查找字符串

linux常用命令

1
2
3
4
5
6
7
8
nvcc -V #查看cuda版本
crontab -l #查看当前定时任务
crontab -e #编辑当前定时任务
conda create -n env-name python=2.7 #conda新建一个虚拟环境-n env-name是设置新建环境的名字,特定python版本
conda activate env-name #激活指定虚拟环境
conda deactivate #离开虚拟环境
conda env list #可以列出你所创建的所有环境conda info --envs
conda env remove -n env-name #删除指定的环境

使用如下Conda命令:

1
conda create -n env2 --clone conda-env1

这里conda-env2是新创建的Conda环境,conda-env1是被复制的Conda环境,
复制完成后,两个环境的Python配置是完全相同的;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
pip install package -i https://pypi.tuna.tsinghua.edu.cn/simple some-package #使用清华下载
conda config --remove-key channels # 换回默认源(清除所有用户添加的镜像源路径,只保留默认的路径)
#配置文件
#全局的是在/etc目录下(/etc/profile)/etc/profile
#用户个人的是在用户的家目录下(~/.profile)个人:cat ~/.bash_profile
#用户启动加载文件(~/.bashrc)cat ~/.bashrc
conda install --channel https://conda.anaconda.org/conda-forge pandas-alive=0.2.3conda install pandas_alive -c conda-forge

## 镜像源
conda config --remove channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/ #删除镜像源,命令
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
conda config --set show_channel_urls yes

## 找不到模块

ModuleNotFoundError: No module named 'XXX' https://www.cnblogs.com/dreamyu/p/7889959.html
import os,sys
curPath = os.path.abspath(os.path.dirname(__file__))
rootPath = os.path.split(curPath)[0]
sys.path.append(rootPath)
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
#GPU上传作业
jjobs -a #查看作业
jsub < ./task.sh #提交作业
#提交作业

#!/bin/sh
#JSUB -q normal
#JSUB -n 32
#JSUB -e error.%J
#JSUB -o output.%J
#JSUB -J qyf_test
python /hpcfiles/users/qyf/project/DC-DRL/common_modules/agent.py > log.log

#显示变量
echo $PATH
方法1
#配置完后可以通过echo $PATH查看配置结果。
#生效方法:立即生效
#有效期限:临时改变,只能在当前的终端窗口中有效,当前窗口关闭后就会恢#复原有的path配置
#用户局限:仅对当前用户
export PATH=/usr/local/bin:$PATH
方法2
#通过修改.bashrc文件:
vim ~/.bashrc
#在最后一行添上:
export PATH=/usr/local/eclipse:$PATH
#生效方法:(有以下两种)
#1、关闭当前终端窗口,重新打开一个新终端窗口就能生效
#2、输入“source ~/.bashrc”命令,立即生效
#有效期限:永久有效
#用户局限:仅对当前用户
方法3
#通过修改profile文件:
vim /etc/profile
export PATH=/usr/local/bin:$PATH
#生效方法:系统重启
#有效期限:永久有效
#用户局限:对所有用户
方法4
#通过修改environment文件:
vim /etc/environment
在PATH="/usr/local/sbin:/usr/sbin:/usr/bin:/sbin:/bin"中加入
":/usr/local/bin"
#生效方法:系统重启
#有效期限:永久有效
#用户局限:对所有用户

## 常使用的tar压缩命令为
tar -zcvf 压缩名.tar.gz 文件/目录

.tar.gz文件,这种文件是tar文件的压缩文件,可以使用tar命令进行解压。解压:
tar -zxvf pythontab.tar.gz
单纯的.gz文件解压,这种文件不可以使用tar命令解压,需要用gunzip解压,使用命令gzip
解压:gzip -d pythontab.gz

#使用zip进行压缩的时候命令格式为
zip -q -r 压缩包名.zip 目录/文件名
#解压
unzip
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
解压文件tgz
例如文件名为: yyyy.tgz
先使用GZIP解压为TAR文件
gzip -dv yyyy.tgz
同时解压后生成yyyy.tar文件
再使用tar解压yyyy.tar文件
tar xvf yyyy.tar
解压下边的命令:
gzip -dv R220-ESiVision-WebEnv-X86-Linux.tgz
tar xvf R220-ESiVision-WebEnv-X86-Linux.tar

压缩:tgz文件。
tar -czvf R220-ESiVision-WebEnv-X86-Linux.tgz apache-tomcat-5.5.23 jdk1.5.0_12 net-snmp-5.1.1
tar -czvf filename.tgz file


#修改文件权限
chmod 777 makePlus.sh

查看系统版本/os
cat /proc/version
cat /etc/redhat-release
uname -a 显示如下
uname -r

找不到包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# -- coding: utf-8 --

import os,sys
curPath = os.path.abspath(os.path.dirname(__file__))
sys.path.append(curPath)
rootPath = os.path.split(curPath)[0]
sys.path.append(rootPath)
#sys.path.append('./common')



import os,sys
curPath = os.path.abspath(os.path.dirname(__file__))
print(curPath)
rootPath1 = os.path.split(curPath)[0]
rootPath2 = os.path.split(rootPath1)[0]
print(rootPath2)
pathaa = '/hpcfiles/users/qyf/test/DeepRL_Algorithms-master'
sys.path.append(pathaa)#地址