迁移wordpress到HTTPS

鸽了四个月之后我终于想起来配置HTTPS环境了

好的现在不止四个月了,一直以来都懒得写,这不是最近终于有时间了,所以补上。

第一步先把https证书扔上去


#
server {
    listen       80;
    server_name  wordpress.endercaster.com;
    rewrite ^(.*) https://$host$1 permanent;# 强制跳转
    # 这下面其实已经没有执行了
    location / {
        proxy_pass http://127.0.0.1:docker 暴露的端口;

        proxy_redirect off;
        proxy_set_header HOST $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
server {
    listen       443;# ssl默认端口
    server_name  wordpress.endercaster.com;
    ssl on;# 开启ssl
    ssl_certificate cert/wordpress.pem;# nginx下的cert目录
    ssl_certificate_key cert/wordpress.key; # nginx下的cert目录
    ssl_session_timeout 5m;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    #ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_protocols TLSv1.2;# 有个站长工具可以测ssl配置,设置成1.2是支付级安全
    location / {
        proxy_pass http://127.0.0.1:docker 暴露的端口;#下文会提到,因为这里用的是http

        proxy_redirect off;
        proxy_set_header HOST $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

由于我的站是用nginx反向代理+docker 实现的,所以访问后台的时候实际上用的还是http,又由于我在nginx里配置的所有http请求全部跳转到https ,因此需要加上下面的配置才不会出错


/** Absolute path to the WordPress directory. */
if ( !defined('ABSPATH') )
	define('ABSPATH', dirname(__FILE__) . '/');
// 这下面是加的
$_SERVER['HTTPS']='ON';// 强行开启https
define('FORCE_SSL_LOGIN',true);
define('FORCE_SSL_ADMIN',true);
define('CONCATENATE_SCRIPTS',false);
// 这上面是加的
/** Sets up WordPress vars and included files. */
require_once(ABSPATH . 'wp-settings.php');

然后是替换站点url和固定连接,这一步需要操作数据库,执行下面的sql把固定连接和文章内容中的http://wordpress.endercaster.com/换成https://wordpress.endercaster.com/


-- 替换内容
update wp_posts set post_content=replace(post_content,'http://wordpress.endercaster.com/','https://wordpress.endercaster.com/');
-- 替换固定连接
update wp_posts set guid=replace(guid,'http://wordpress.endercaster.com/','https://wordpress.endercaster.com/');
-- 更新站点URL
update wp_options set option_value=replace(option_value,'http://wordpress.endercaster.com','https://wordpress.endercaster.com');

我记得当时配置的时候挺麻烦的,这看上去好像也没那么麻烦

使用vmware搭建开发环境

前言

  • VBox的操作差不多
  • windows下docker操作太麻烦,所以没有采用全docker的解决方案

准备材料

  • Vmware Workstation
  • CentOS 8 (为了方便,选择的Desktop)
  • VS Code + remote插件

布置环境

先把系统装上,相信大家都会,这步略过

为了方便, 编辑/etc/selinux/config 关闭selinux,重启。相应的,我们这台机器不连外网。

安装服务器及其他需要的软件


sudo yum install -y nginx php php-cli php-fpm php-mysqlnd php-xml php-mbstring php-gd

“安装”Docker(可替换)


# centos自带的
which podman
# /usr/bin/podman
sudo ln -sf /usr/bin/podman /usr/bin/docker

安装Docker(可替换)


#卸载自带的podman
sudo yum remove podman
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# nobest 解决依赖问题
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install docker-ce docker-ce-cli containerd.io --nobest

配置Docker、镜像


# mysql
sudo docker run -itd --name mysql \
  -v /opt/mysql:/var/lib/mysql \
  -e MYSQL_ROOT_PASSWORD=nothing \
  --restart always \
  -p 3306:3306 \
  mysql:5.7
# redis
sudo docker -itd --name redis \
  -p 6379:6379 \
  --restart always \
  redis
# 开机自启
sudo systemctl enable docker.service

配置固定IP

点击桌面右上角-有线连接-设置-IPV4

挂载共享文件夹

vmware-设置-选项-共享文件夹


sudo vmhgfs-fuse -o allow_other .host:/ /mnt/hgfs/

配置nginx


upstream php-fpm {
        # 这里是安装完php-fpm自带的,默认的一个接口
        # 其他distro可能是通过HTTP监听9600端口
        server unix:/run/php-fpm/www.sock;
}
server{
    listen 80;
    server_name wordpress.endercaster.lan;
    root /mnt/hgfs/workspace/wordpress;
    index index.php;
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    location ~ \.php$ {
        fastcgi_pass php-fpm;
        fastcgi_index index.php;
        include fastcgi.conf;
    }
}

配置php-fpm


sudo yum install php-pear php-devel make
sudo pecl channel-update pecl.php.net
sudo pecl install redis
# 创建/etc/php.d/40-redis.ini
# 40这个数字只要比json插件的大即可
# 输入 extension=redis
# 重启php-fpm
sudo systemctl restart php-fpm.service


[www]
;找到下面两个键,修改
php_value[session.save_handler] = redis
php_value[session.save_path]    = tcp://127.0.0.1:6379

配置HOSTS

宿主机,也就是windows这边配置C:\Windows\System32\drivers\etc\hosts,格式如下


你刚才填写的固定IP wordpress.endercaster.lan

结语

原则上来讲到这里就已经能正常访问了,特别说明一下,因为.lan不是正经域名后缀,Chrome的默认选项是搜索,所以需要在前面手动添加http://前缀,这个流程上遇到了什么问题可以给我留言。

OpenCV从入门到放弃

开篇致谢最为致命,首先感谢大佬81页计算机视觉指南

最近公司比较闲,本来应该去刷LeetCode的,但是刷自闭了,于是技能树继续向广度发展,正巧前两天看到这个指南了,于是就学着玩玩。

第一步当然是搞一台linux虚拟机,这里我选择了ubuntu Desktop版,然后是安装python,OpenCV库。


sudo apt-get update && sudo apt-get install python3-pip
# 升级
python3 -m pip install --upgrade pip
# 换源
python3 -m pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
python3 -m pip install opencv-python imutils

给你们瞅一眼我的目录结构

然后就是跟着教程练习几个常用函数的使用,以下代码不保证可运行,这里我建议用python交互模式练习,用文件形式有点麻烦


import imutils
import cv2
# 这个图片是Pixiv找的,教程上的图我没找到,有一说一,这图画的很好
# 这张图目前没什么要求,有想要圈起来的东西就行
image=cv2.imread("78172570_p0.jpg")
(h,w,d)=image.shape
print("width={},height={},depth={}".format(w,h,d))

cv2.imshow("Image",image)
cv2.waitKey(0)
(B,G,R)=image[100,50]
print("RGB at 100,50:{},{},{}".format(R,G,B))

roi=image[300:450,450:600]
cv2.imshow("ROI",roi)
cv2.waitKey(0)

resized=cv2.resize(image,(720,720))
cv2.imshow("Fixed Resizing",resized)
cv2.waitKey(0)

r=720.0/w
dim=(720,int(h*r))
resized=cv2.resize(image,dim)
cv2.imshow("Aspect Ratio Resize",resized)
cv2.waitKey(0)
resized=imutils.resize(image,height=720)
(h_l,w_l,d_l)=resized.shape
cv2.imshow("Imutils Resize",resized)
cv2.waitKey(0)

center=(w_l//2,h_l//2)
M=cv2.getRotationMatrix2D(center,-45,1.0)
rotated=cv2.warpAffine(resized,M,(w_l,h_l))
cv2.imshow("OpenCV Rotation",rotated)
cv2.waitKey(0)

rotated=imutils.rotate_bound(resized,45)
cv2.imshow("Imutils Bound Rotation",rotated)
cv2.waitKey(0)
#高斯模糊……
blurred=cv2.GaussianBlur(resized,(11,11),0)
cv2.imshow("Blurred",blurred)
cv2.waitKey(0)

output=image.copy()
#output 左上(x,y),右下(x,y)
#我们最常在新闻上看到的长方形
cv2.rectangle(output,(450,300),(600,450),(0,0,255),2)
cv2.imshow("Rectangle",output)
cv2.waitKey(0)

output=image.copy()
#画圈
cv2.circle(output,(525,375),75,(255,0,0),1)1 for 1px,-1 for solid
cv2.imshow("Circle",output)
cv2.waitKey(0)

output=image.copy()
#划线
cv2.line(output,(725,0),(725,500),(0,0,255),3)
cv2.imshow("Line",output)
cv2.waitKey(0)

output=image.copy()
#写字
cv2.putText(output,"EnderCaster Exercise",(10,25),cv2.FONT_HERSHEY_SIMPLEX,0.7,(255,204,102),2)
cv2.imshow("Text",output)
cv2.waitKey(0)

第一部分的基础练习就完了,然后是抠图图像处理


import cv2
import imutils
import argparse
# 同样是Pixiv找的,这张图的要求是背景单一,角色没有关联
image=cv2.imread("split_test.jpg")
cv2.imshow("Image",image)
cv2.waitKey(0)

# 灰度图
gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
cv2.imshow("Gray",gray)
cv2.waitKey(0)
# 边缘查找
edge=cv2.Canny(gray,30,150)
cv2.imshow("Edge",edge)
cv2.waitKey(0)

# that not work well
# 阈值,用灰阶图处理效果比较好
thresh=cv2.threshold(gray,242,255,cv2.THRESH_BINARY_INV)[1]
cv2.imshow("Threshold",thresh)
cv2.waitKey(0)

# 看名称像是查找封闭区间,所以上一步没处理好这里可能会多出来一些无效的
cnts=cv2.findContours(thresh.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnts=imutils.grab_contours(cnts)
output=image.copy()
for c in cnts:
    cv2.drawContours(output,[c],-1,(240,0,159),3)
    cv2.imshow("Contours",output)
    cv2.waitKey(0)
# Rita 人名
text="I found {} Rita!".format(len(cnts))
cv2.putText(output,text,(20,25),cv2.FONT_HERSHEY_SIMPLEX,0.7,(240,0,159),2)
cv2.imshow("Contours",output)
cv2.waitKey(0)
# 去噪
## 腐蚀
## 裁切式...这个去的有点猛
mask=thresh.copy()
mask=cv2.erode(mask,None,iterations=1)
cv2.imshow("Eroded",mask)
cv2.waitKey(0)
## 膨胀
## 扩展式
mask=thresh.copy()
mask=cv2.dilate(mask,None,iterations=3)
cv2.imshow("Dilated",mask)
cv2.waitKey(0)
# 按位与,慎用,效果比较令人迷惑
mask=thresh.copy()
output=cv2.bitwise_and(image,image,mask=mask)
cv2.imshow("Output",output)
cv2.waitKey(0)

PHP文件无读写权限

平台:CentOS + nginx + php-fpm

首先说明出现场景:权限修改为777依旧提示没有权限/文件未找到

解决方案:


setenforce 0
# [/your/path/here] 支持正则表达式写法,想要递归的话请使用正则表达式 [/your/path/here(/.*)?]
semanage fcontext -a -t httpd_sys_rw_content_t [/your/path/here]
# 或
semanage fcontext -m -t httpd_sys_rw_content_t [/your/path/here]
restorecon
setenforce 1

事情是这样的,客户的服务器是CentOS,我上传图片的时候需要先存本地然后上传到云,测试站测没问题,预发布站出问题了(因为是新系统,预发布站和生产站这个时候都部署好了),我当时就惊了。

第一件事想到的就是权限问题,于是检查一下:
drwxrwxrwx
?????????小老弟你怎么回事
总之之后通过修改代码的方式定位到了是在复制文件的时候没有成功从/tmp复制到项目文件夹下,这个时候我已经怀疑是有其他权限控制这里了(是的,当时并没想到selinux,平常没接触过这层),但是时间比较紧急,所以先去确认了一下生产站上传功能是否正常,结果是正常的,这时候我就很迷惑,因为预发布和测试站结果不同很合理,毕竟操作系统和服务器(apache/nginx)都不一样,但是预发布和线上站应该是一样的啊?(作为开发人员我的原则是不碰线上站的东西,所以没见过线上站的服务器,结果它还真【此处自主规制】不一样,太打脸了)
由于线上没有问题,这个问题就先告一段落了

本来想着反正部署本来就不是我的活,就算了,然后上班路上突然想起来一件事:结合vmware的共享文件夹功能是不是可以实现windows下开发,生产环境调试?于是我准备了一个laravel项目,在虚拟机上打开共享,考虑到在Centos上踩过坑,系统就选用的CentOS 8,安装nginx+php-fpm,配置好之后,很好,访问404,查看nginx日志显示 *16 stat() “/mnt/hgfs/workspace/laravel/public/favicon.ico” failed (13: Permission denied) ,这个没跑了,肯定是权限问题,chmod,chown一气呵成,刷新网页一看,很好,根本没有效果,于是把代码文件复制到虚拟机磁盘上,修改配置文件重启nginx,至少php解析没问题了,但是提示写日志失败,没有权限,那就给权限呗,于是从455到777试了一遍还是不行,不行咋整啊?上网搜吧,转了一圈,基本都是在说权限没给够,都777了肯定不是权限没给够了,然后我看到了一篇文件无法写入的文[1],提到了selinux,我记得这是一个独立的权限系统,那事情就简单了,百度:selinux 配置

先看到了怎么配置关闭,我信了你的邪,我去服务器上还能把selinux关了是咋的,走你,下一个。

之后是selinux配置说明[2],很长,看到那个fcontext的命令,我就知道怎么整了 ,但是得有理有据是不是,比如那个-t后面的参数是怎么来的?

再之后看到了以Apache举例配置selinux的[3],都是服务器软件,理论上是一样的,既然能看进程的selinux context,那就好说了


ps -eZ | grep php
# 可以看到context是httpd_t
# 既然可以查看selinux 开放的端口列表,应该可以查看上下文列表吧,于是我试了一下
semanage fcontext --list
# 的确,输出了好多东西,我来找一下看看
semanage fcontext --list | grep :httpd_
# 出现了很多context,命名很有规则,可以看到httpd_sys_rw_content_t应该就是我想要的了
# httpd所属 rw权限
# 如果还没有context的话,添加
semanage fcontext -a -t httpd_sys_rw_content_t '/opt/endercaster/laravel(/.*)?'
# 如果有context的话,修改
semanage fcontext -m -t httpd_sys_rw_content_t '/opt/endercaster/laravel(/.*)?'
# 然后让设置立即生效
restorecon /opt/endercaster/laravel
# 记得确认一下
ls -Z /opt/endercaster/laravel

等等,刚才的vmhgfs的问题是不是也是这个导致的?于是我采用了最简单暴力的方法:把selinux关掉(编辑/etc/selinux/config)事实证明真的是selinux的问题,但是vmware共享不能修改标签……

你以为还有下文?至此两个问题都已经解决了。是的,都解决了

部署不会用vmware共享文件夹,而不用共享文件夹的selinux设置已经解决了。

而使用vmware共享文件夹做环境测试只需要关闭selinux即可。

[1] linux下文件权限777了,file_put_contents()却不能写入,为什么?

[2]如何配置selinux

[3]SELinux中Apache的配置

Tmux使用手记


# 更改默认socket路径
export TMUX_TMPDIR=~
echo 'export TMUX_TMPDIR='${TMUX_TMPDIR}'/tmux' >> ~/.bashrc
source ~/.bashrc
tmux -S ~/tmux/tmux-1000/default


# 自动化保存恢复session
mkdir -p ~/.tmux/plugins && cd ~/.tmux/plugins
git clone https://github.com/tmux-plugins/tmux-resurrect.git
git clone https://github.com/tmux-plugins/tmux-continuum.git
# .tmux.conf
run-shell ~/.tmux/plugins/tmux-resurrect/resurrect.tmux
set -g @continuum-save-interval 5
set -g @continuum-restore 'on'
set -g status-right 'Continuum status: #{continuum_status}'
run-shell ~/.tmux/plugins/tmux-continuum/continuum.tmux

外包三个月,学到了什么?

第一点:是写的项目多了,对于框架的文件结构越来越熟悉了,以及写代码写多了自然而然发生的我无法捕捉到的变化。

第二点:接触到了更多的框架,这样,对这门语言的一些用法也了解的更多(说明一下,这个可以通过书本知识了解到,而且更快,更准确,但是我是真看不进去……)

举个例子:今天用户提了个需求,emmm这个需求我看着好眼熟啊,对了,那个项目里用过【OneThink model,attribute表】

第三点:公司内部的比赛,还是有狠人啊,而且代码开源,虽然是面向测例编程,还是能看见一点设计思想的,高分作基本都是go+mongodb,MySQL的项目全军覆没,简单暴力的话MySQL还是吃不住的比如我虚拟了5000条数据,插入MySQL用了50+秒,插入mongodb用了1-3秒(单条数据插入,并非批量插入)

总之收获还可以,但是具体有什么收获还是要定时做总结和记录,比如这篇文章,还有持续更新分类的一些小技巧

《神魔大陆2》游玩体验

首先是结论:是一款非常不认真的游戏

一开始是突然想到了这个和同学约好一起玩的游戏,就下来玩玩

初期玩着还行,毕竟没有什么玩家之间的交互,很顺利,而且剧情也没有变

越往后越觉得不对,以前升级速度非常慢,满地图也都是活人,现在emmmmm除了主城我就没看见过人

今天是第三天,七十多级了,身上的装备:10级到40级不等……

为什么呢,因为装备本根本排!不!到!人!与其说是装备本不如说是所有的本都没有人,这就导致了一个很尴尬的问题,组队日常完成不了,组队支线完成不了,没有装备,没有宠物,今天终于连主线任务的BOSS都打不过了,嗯,很好。

如果说这是一个老区,那么这个现象也是很正常的,然而,这是官方推荐的新区啊KORRRRRRRRRRA!

一般来讲,为了应对这种活跃度降低的问题,官方都会选择在升级礼包里送一些说不上差,但也好不到哪去的装备,但最起码有的用,这种感觉嗯,吖屎啦!

有人可能要说:游戏要赚钱啊。充不充钱改变的应该是难易度,或者说是一个战力上限的问题,首先你得给我一个游戏体验,我才可能充钱以获得更好的游戏体验。嗯,糞game

最后:FF14,崩坏三,剑网三,抱歉,你们一点都不屑。

有关于求余数

昨天在久违的leetcode上做题(是个菜鸟,还在简单阶段卡着),在7-整数反转这一题的题解中看到了有关于不同语言求余数的不同结果

在python中 :-53除以10=-6 …7 所以python中 -53%10=7
在c语言中,-53除以10=-5 … -3 所以c语言中 -53%10=-3


aabathur@LeetCode

跟朋友讨论了一下这个问题,最后的结论是:python的计算方式是符合定义的

C语言这种方式是向零取整,而根据定义


取余数运算:
a mod b = c 表示 整数a除以整数b所得余数为c。
余数的计算公式:c = a -⌊ a/b⌋ * b
其中,⌊ ⌋为向下取整运算符,向下取整运算称为Floor,用数学符号⌊ ⌋表示

余数-百度百科

可以看出,商应为向下取整,例如 ⌊ -4.2⌋=-5,即-53 mod 10=-6…7

bilibili视频批量下载

!important 本文以讲述原理为主,不发布可直接执行的代码

由于经常出现我今天看了第二天视频就没了的情况,所以特别喜欢的视频我都会down下来保存到本地,当然三连给up是肯定的,网上已经有不少可以直接下载的插件了(特别是chrome插件,但是批量下载还是得手动来。

所以我们先来了解一下怎么手动下载B站视频

此处以我的一个视频为例(gank钓鱼网站)原料如下

  • Google Chrome/Firefox(PC端)
  • aria2c (是的,下载怎么能少了它呢
  • curl
  • 代码执行环境(如cmd/powershell/bash

首先打开页面,按F12打开调试窗口,刷新(因为我需要用到sources中的内容,不刷新通常拦截不到)此时打开“网络”选项卡,你会看见密密麻麻的一堆网络请求地址,像下面这样

网络请求

先排除掉资源文件,比如字体,css,js,因为视频音频数据基本不可能存在这些文件中,所以可疑的数据就只剩下两条了:那两个m4s的xhr请求(就是我们平常说的ajax请求)

接下来要做什么已经显而易见了,打开“源”选项卡,找到这个页面

看见这个index了吗?点它,这就是当前页面的源文件(并非你看到的这个页面,因为你看到的这个页面是经过js和css处理过的),顺便按一下左下角的大括号,美化代码,ctrl+f搜索刚才看见的那两个m4s,可以发现他们在一个__playinfo__的json里

第一次找到的时候我其实是很震惊的,B站这个播放器的音频和视频是分开的,这两条url也就是我们要找的下载地址了

你以为这就结束了?没有!

直接使用aria2c 下载会报错,用curl查看提示403forbidden,既然B站下载可以,那我们让请求参数更像B站的下载请求就行了啊,这里直接说结果:加上–refer参数,refer是指你在哪个页面请求的这个地址,对应的是网络请求的header中的refer,所以完整的命令是

aria2c –refer=’base_url’ ‘video/audio url’

至此,手动下载的部分说完了,下面的内容就简单很多了

批量下载适用于解放手工劳动的,如果批量也这么下那可太麻烦了,批量下载一般会在程序中直接下载,甚至连视频音频的合并都做了,但是我懒(

于是我采用的是类似于爬虫的思路,只爬取url,使用url生成下载命令并保存为文件,当前的批量下载针对多个分p的,分p的获取在查看源那一步搜索分P标题就可以找到一个名为 __INITIAL_STATE__ 的json,分p在pages数组里,其它参数这里暂时用不到

b站视频播放的url有一个p参数,就是分p序号,所以我们令max=len(pages),来循环获取每一p的url(p=i+1),把生成的command写到文件中就万事大吉了

为了方便区分文件内容,来认识一下aria2c的-o参数,指的是下载文件名,在生成下载命令的时候带上这个参数能够让文件更便于区分。

那么这篇文章到此结束,欢迎来B站找我@EnderCaster

有道智云文本翻译

最近需要用到在线翻译,就找了一个初期免费(送100初始资金)的站,而且有道这个网站主要就是做翻译的,质量应该还是信得过

请求示例:


import random, string, config

def randomword(length):
    letters = string.ascii_lowercase
    return ''.join(random.choice(letters) for i in range(length))

appSecret=config.appSecret

q="<待翻译文本>"
from="en"
to="zh-CHS"
appKey=config.appKey
salt=randomword(<任意长度>)
sign=md5(appKey+q+salt+appSecret) #格式要求:%32X

返回示例


{
    "tSpeakUrl": "",
    "web": [
        {
            "value": [
                "lunar eclipse",
                "Eclipse",
                "moon's eclipse"
            ],
            "key": "月食"
        },
        {
            "value": [
                "penumbral lunar eclipse",
                "penumbral eclipse",
                "appulse"
            ],
            "key": "半影月食"
        },
        {
            "value": [
                "moon phases"
            ],
            "key": "月食字体"
        }
    ],
    "query": "月食",
    "translation": [
        "Eclipse of the moon"
    ],
    "errorCode": "0",
    "dict": {
        "url": "yddict://m.youdao.com/dict?le=eng&q=%E6%9C%88%E9%A3%9F"
    },
    "webdict": {
        "url": "http://m.youdao.com/dict?le=eng&q=%E6%9C%88%E9%A3%9F"
    },
    "basic": {
        "phonetic": "yuè shí",
        "explains": [
            "[天] eclipse of the moon",
            "[天] lunar eclipse"
        ]
    },
    "l": "zh-CHS2en",
    "speakUrl": ""
}