nextCloud ! 真香
What
因为一些不可描述的原因,dropbox能用但是速度感人
现在需要一款能够 在 android+Linux+iPadOS三端做同步的
iPad上的Documents配上ssh可以完成Linux+iPadOS的同步, // android似乎并不行
google drive就和dropbox是同样的问题
baiduYunPan ??? 如果你不怕你的个人资料有一天变成 “根据相关法律法规” 的话 // 不过值得一提的是 这玩意支持linux了哦 虽然目测是个 浏览器壳 当然也就没有自动备份同步功能
然后搜了搜开源的 ownCloud 和 nextCloud ,看介绍基本是一家的
还有人说 用svn/git来搞,你确定喜欢在手机和ipad上输命令?
开干
client就不说了,各个平台下下来安装就行,说说 server
我目前的电脑环境Ubuntu18.04 x86_64 Linux 4.15.0-65-generic , bash 4.4.20 , 15925MiB
警告第一条命令将会进入root,进入后你将有所有权限,请自重
sudo -s
apt install apache2
service apache2 start
apt install mariadb-server
mysql_secure_installation
apt install php libapache2-mod-php php-mysql php-gd php-json php-mysql php-curl php-mbstring php-intl php-imagick php-xml php-zip
apt install phpmyadmin
ln -s /etc/phpmyadmin/apache.conf /etc/apache2/conf-available/phpmyadmin.conf
a2enconf phpmyadmin
a2enmod ssl
a2ensite default-ssl
service apache2 reload
mariadb
MariaDB [(none)]> CREATE DATABASE nextcloud;
MariaDB [(none)]> CREATE USER nextcloud IDENTIFIED BY 'p@ssc0de';
MariaDB [(none)]> grant usage on *.* TO nextcloud@localhost IDENTIFIED BY 'p@ssc0de';
MariaDB [(none)]> GRANT ALL privileges ON nextcloud.* TO nextcloud@localhost;
MariaDB [(none)]> FLUSH PRIVILEGES;
访问 https://localhost/phpmyadmin/
(用户名,密码)=(nextcloud,p@ssc0de)
去https://download.nextcloud.com/server/releases/nextcloud-17.0.0.zip下载最新的zip包 解压到 /var/www/html/nextcloud里
chown -R www-data:www-data nextcloud/
通过https://localhost/nextcloud即可访问 设置admin 密码,填写刚刚的配置即可
手机连接会无权限,跟着提示修改/var/www/html/nextcloud/config/config.php的配置即可
失败的尝试
下载wget https://raw.githubusercontent.com/nextcloud/vm/master/nextcloud_install_production.sh
然后sudo bash nextcloud_install_production.sh
https://github.com/nextcloud/server 下源码或者下releases
nextCloud 额外的应用
把搜到的release包解压到/var/www/html/nextcloud/apps
在index.php/settings/apps中启用
例如
1 | calendar.tar.gz |
参考
https://github.com/nextcloud/server.git
https://nextcloud.com/install/#instructions-server
https://www.youtube.com/watch?v=QXfsi0pwgYw
总结
现在看来主要问题在于 直接snap的 会和当前本地开得一堆服务或多或少冲突?? 我查运行状态 都是在运行,查端口 没看到监听
另外一个就是 文件夹权限要搞成 www-data:www-data
在一个就是mysql的db和账户创建,只玩过CURD,很久没摸也忘了
客户端口没啥难度
emmmmmmmm 似乎也不能在ipados上搞… 只能网页勉强
Docker
- 本地建立文件夹
/data/nextcloudserver/给它存东西用 - 一条docker命令
docker run -d -p 8080:80 -v /data/nextcloudserver/:/var/www/html --name=nextcloudserver nextcloud,注意docker的习惯冒号左边是宿主机器的东西,右边是容器内的东西,这里映射了端口和磁盘
这样就可以跑了,本地访问都是ui操作,没啥好说的
- 配置
config/config.php中的trusted_domains(无脑的话root进,或者docker起个busybox连接一下),注意这里的写法是星号来匹配应该192.168.*.*,而不是192.168.0.0/24, 保存就行
或者官方的仓库下
https://github.com/nextcloud/docker/blob/master 文件夹.examples/docker-compose/insecure/mariadb/apache
执行docker-compose up -d
官方仓库自签https 证书
内网要用的话,可以考虑。毕竟没有CA中心,管内网的还是有办法搞你XD
.examples/docker-compose/with-nginx-proxy-self-signed-ssl/mariadb/fpm
sed玩得熟的可以sed替换哈
1 | diff --git a/.examples/docker-compose/with-nginx-proxy-self-signed-ssl/mariadb/fpm/db.env b/.examples/docker-compose/with-nginx-proxy-self-signed-ssl/mariadb/fpm/db.env |
然后你需要在要连接的电脑上把hosts文件增加 ip到nextcloud.cromarmot.com 的映射
执行docker-compose up -d
移除
执行docker-compose down
注意,只会移除container和network,不会移除volume, 如果要移除,要手动移除
throttle vs debounce
What
基本讲就是 throttle(截流)和debounce(去抖)
功能都是为了避免快速反复触发
比如 用户快速点击按钮
假设设置为1s
throttle相当于,执行的最小间隔为1s
debounce也是执行最小间隔为1s,但是假设用户持续的一直快速点击,函数不会执行,需要等到最后一次点击后过1s才执行
直接看lodash的
throttle:
1 | function throttle(func, wait, options) { |
debounce:
1 | function debounce(func, wait, options) { |
直接的参数区别
1 | throttle |
Vue 有一个官方教程中的使用方法如下
https://cn.vuejs.org/v2/guide/computed.html#%E4%BE%A6%E5%90%AC%E5%99%A8
之前我也写过一个 在methods中 计算出一个函数,但是那样的返回和计算不能使用箭头函数,因为运行函数和执行的this不同,ide也报错,XD 虽然可用
参考
adb
What
想看一下 某个包的文件
查看 usb连接/模拟器 的设备 adb devices
连接一个具体的设备 adb -s <设备id> shell
列出手机里的安装包pm list packages 当然 grep命令也可以用
比如你要查看的包为com.xxx.yyy那么 run-as com.xxx.yyy
cd ls grep cat这些命令是有的 并没有vi XD,不过有cat 基本能看文件了
// 搜到了 单个文件 cat 出来的 但没搜到文件夹的
// 也有间接先cat到sdcard再pull 再删sdcard
// 还搜到了一个 用 adb backup 把整个app搞出来,再 转换成tar的 [见下面链接]
// 当然 还有一堆说root的 emmm 告辞
// Stetho?
参考
https://stackoverflow.com/questions/53634246/android-get-all-installed-packages-using-adb
https://gist.github.com/davidnunez/1404789
https://stackoverflow.com/questions/7399028/android-adb-permission-denied
闪耀暖暖 耗材计算器 rxjs + angular2+
What
闪耀暖暖的设计师 材料耗材计算器
基于一个已经有的原生js 进行改造
原来生 http://www.spongem.com/ajglz/tools/evalLevelUpCost.html
重构内容
- 首先把这个的源码 搞下来,比较无脑的操作
- 然后开个module 配一下routing
- 搞个component 然后把函数数据都搬进来
- 把相关全局变量 改为
this. - 修改原来的一些
$方法 改为原生js,或者改为[(ngModel)]双向绑定,至此基本可以运行。 - 解构一下用户输入和计算输出分别叫做
Class: CardBasic/Card -> html:Card/CardOut// 好吧 这里变量名有点乱 现在看来 - 引入
https://material.angular.io的组件,稍微调整画风 - 尝试搞一个computed,移除计算按钮, 改为
get XXX的方法
这里遇到问题, 根据调试,页面上的调用会反复调用get方法, 大量重复不必要计算
- 解决方案1: 引入Ramda,建立两个cache 分别是计算结果 和 用户输入,用 Ramda的深比较和深拷贝完成少的计算次数
写着还好,行数不多,就能实现,性能也好,但是问题是,相当于你依然要去关心的是,输出值输入值直接的具体关系才能写。
- 解决方案2: 引入rxjs,用Observable搞
这里实践上有些问题
- 双向绑定如何和
BehaviorSubject绑定,最后用(ngModelChange)来 单向到 具体字段 - 能否监听整个Class
1 | import { of } from 'rxjs'; |
例如这样 并不会因为修改了a的子字段而自动发送next
搞了半天最后还是 感觉很 手工写依赖的输入
这一块的实现主要如下
1 | // 相当于所有用户输入的部分 都会对应一个emitter |
- 最后增加了一点 try catch,因为 不同的卡可选范围并不同,或者用户输入不合法会 爆红=.=只在 两个LevelVal里加了
最后结果
https://cromarmot.github.io/Debuq/#/nikki4/lvlup
如果打开看到404,保持页面,等待一会儿再刷新即可。因为有worker service
TODO
比如搞成动态拉取
计算函数再向纯函数靠拢啊
怎么json 转换 Class 甚至 Map // 搜了一会没搜到简洁的方案
更好的双向绑定+BehaviorSubject 绑定?
是否可能简化某部分代码
输入控制 比如 现在其实可以输入 小数 和 范围以外的数
比如因为还是有不少json 导致 typescript的 类型判断并不完整 虽然
别遵循RxJS的最佳实践
redhat7 + gitlab-ce版本更新 11.6->12.2
Why
模拟生产环境 尝试 升级 gitlab-ce 从 11.6 到 12.2, 以及尝试模拟之前产生的错误
官方说 先要到11.11.X再到12.X
物料准备
vmware on Ubuntu 18.04 LTS
gitlab-ce-11.6.5-ce.0.el6.x86_64.rpm
gitlab-ce-11.11.0-ce.0.el6.x86_64.rpm
gitlab-ce-12.2.5-ce.0.el7.x86_64.rpm
rhel-server-7.7-x86_64-dvd.iso
Install OS
https://access.redhat.com/downloads/content/69/ver=/rhel---7/7.7/x86_64/product-software
注册 下载 安装
需要注意的是 下4GB左右的 而不是boot.iso
为什么是7 不是8(当前最新)
因为想和某个生产环境保持一致 尝试 模拟某些操作
git 在历史版本中 完全移除文件
How
参考
https://www.cnblogs.com/amiezhang/p/11337095.html
上面链接都有讲
按照文件大小排序前100:
git rev-list --objects --all | grep "$(git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -100 | awk '{print$1}')"
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch 文件名' --prune-empty --tag-name-filter cat -- --all
git filter-branch --index-filter 让每个提交的文件都复制到索引(.git/index)中
然后运行过滤器命令:git rm --cached --ignore-unmatch 文件名 ,让每个提交都删除掉“文件名”文件
然后--prune-empty把空的提交“修剪”掉
然后--tag-name-filter cat把每个tag保持原名字,指向修改后的对应提交
最后-- --all将所有ref(包括branch、tag)都执行上面的重写
git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin
git reflog expire --expire=now --all
git gc --prune=now
注意
上面的文件名可以写通配符号
众所周知只要我加到git中过的,即使把分支删了,也可以从reflog中找到,但这里 有 清除reflog所以 想要这样做的,要么 单独开文件夹搞,要么 确定 reflog都不会再用
什么时候使用? 使用频率不应高,因为 这种操作无疑是会对 分支重写,也就完全不同的commit hash,所以最后push都会带上–force, 目前能想到场景,比如 不必要的大文件,如不小心提交的下下来的打包后文件,大zip.也有场景 比如 很多分支前 不小心提交了一个涉密的文件。 当然push force以后 所有用仓库的人要想继续用只有去新的分支里搞了,已经被别人下的还会在别人硬盘里
未来简史 阅读笔记
eleme vue msgbox 简单看看实现原理
依赖版本
element-ui 版本 10592d12ea981912165542920160669fd8874bd9
文档 https://element.eleme.io/#/zh-CN/component/message-box
要解决的问题
像是
1 | $msgbox(options) |
这样的api是怎么实现的
代码阅读
大概看一眼怎么搞的
src/index.js 看 这些方法 ,都是来自 import MessageBox from '../packages/message-box/index.js';
1 | Vue.prototype.$msgbox = MessageBox; |
那么看 packages/message-box/src文件夹
两个文件 main.js和 main.vue
main.vue瞄一眼,都是我们常见的写法
main.js,看这些方法 最后 都是 调用 MessageBox(配置参数)的形式调用
再看const MessageBox = function(options, callback) {的实现
都是 先msgQueue.push(配置参数) + showNextMsg()
msgQueue和 showNextMsg,分别是个数组,和从数组中shift() 取出值 进行具体展示执行
然后 看 showNextMsg()
1 | if (!instance) { |
然后
1 | const initInstance = () => { |
和
1 | const MessageBoxConstructor = Vue.extend(msgboxVue); |
说明了基本这就是 工厂模式+单例模式+Vue.extend来创建弹框单例,所以我们页面上不需要写什么,就能直接调用
然后这些confirm调用过程 也就是对这个单例的参数改动 比如控制样式 数据 显示之类的
总结
- 用户调用
$msgbox - 调用到
packages/message-box/src/main.js的MessageBox(options,callback) MessageBox(options,callback)通过 数组 + 数组.shift,依次提取数据展示- 对于展示的实例 是 通过
Vue.extend(packages/message-box/src/main.vue)+ 工厂单例来产生的一个实例 - 他们 搞了一个
element/examples/components/demo-block.vue可以在markdown写示例代码,并且在网页上查看 可以运行 66666
那常见的问题可能有说,连续调用2此带有回调函数的
$msgbox会怎样
我们可以看showNextMsg()实现
1 | //得到 instance |
意思就是如果我们同步调用两个,
- 因为我们visible设置为true是 异步里发生的,那么 这两个调用时 visible默认都是false,所以 只会最后一个生效
- 如果我们异步调用两次msgbox,那么 后一个调用 会在
!visible的地方为false,不会直接触发,但是因为设计了msgQueue,因此 会放在数组中,然后看到 上面的callback,会在调用oldCb以后 再调用showNextMsg,所以会在对话框回调以后 再回调 那个时刻,msgQueue里首个 并从数组中移除
总结
总流程实现
也就是方法是src/index.js: Vue.prototype.方法名 = 方法函数 来让全局可用
通过 document.createElement('div') 和 全局变量, 创建绑定维护对应的单例实例.
这样就实现了 任何页面,不需要写组件,就能this.方法名(参数) 来弹窗
适用场景,不需要业务定UI,否则需要页面v-slot之类插入业务内容
参数设计(核心参数与可选参数与回调)
核心参数是函数的直接参数
可选参数组合成一个对象,提供默认值
回调既有成功也有失败,随是promise,总觉得用reject来做取消和关闭其实不太好, 可以全resolve走自定义状态
提供一定的重载实现
内部具体
队列, 同步异步, callback持有